diff options
309 files changed, 1303 insertions, 83691 deletions
diff --git a/doc/python_api/rst/gpu.rst b/doc/python_api/rst/gpu.rst index 0be4fae8c5a..d4860da4770 100644 --- a/doc/python_api/rst/gpu.rst +++ b/doc/python_api/rst/gpu.rst @@ -4,7 +4,7 @@ GPU functions (gpu) .. module:: gpu -This module provides access to materials GLSL shaders. +Functions for GPU offscreen rendering, matrix stacks and selection. Submodules: @@ -17,683 +17,4 @@ Submodules: Intro ===== -Module to provide functions concerning the GPU implementation in Blender, in particular -the GLSL shaders that blender generates automatically to render materials in the 3D view. - -.. warning:: - - The API provided by this module is subject to change. - The data exposed by the API are are closely related to Blender's internal GLSL code - and may change if the GLSL code is modified (e.g. new uniform type). - - -Constants -========= - -GLSL Data Type --------------- - -.. _data-type: - -Type of GLSL data. -For shader uniforms, the data type determines which ``glUniform`` function -variant to use to send the uniform value to the GPU. -For vertex attributes, the data type determines which ``glVertexAttrib`` function -variant to use to send the vertex attribute to the GPU. - -See export_shader_ - -.. data:: GPU_DATA_1I - - one integer - -.. data:: GPU_DATA_1F - - one float - -.. data:: GPU_DATA_2F - - two floats - -.. data:: GPU_DATA_3F - - three floats - -.. data:: GPU_DATA_4F - - four floats - -.. data:: GPU_DATA_9F - - matrix 3x3 in column-major order - -.. data:: GPU_DATA_16F - - matrix 4x4 in column-major order - -.. data:: GPU_DATA_4UB - - four unsigned byte - - -GLSL Uniform Types ------------------- - -.. _uniform-type: - -Constants that specify the type of uniform used in a GLSL shader. -The uniform type determines the data type, origin and method -of calculation used by Blender to compute the uniform value. - -The calculation of some of the uniforms is based on matrices available in the scene: - - .. _mat4_cam_to_world: - .. _mat4_world_to_cam: - - ``mat4_cam_to_world`` - Model matrix of the camera. OpenGL 4x4 matrix that converts - camera local coordinates to world coordinates. In blender this is obtained from the - 'matrix_world' attribute of the camera object. - - Some uniform will need the *mat4_world_to_cam* - matrix computed as the inverse of this matrix. - - .. _mat4_object_to_world: - .. _mat4_world_to_object: - - ``mat4_object_to_world`` - Model matrix of the object that is being rendered. OpenGL 4x4 matric that converts - object local coordinates to world coordinates. In blender this is obtained from the - 'matrix_world' attribute of the object. - - Some uniform will need the *mat4_world_to_object* matrix, computed as the inverse of this matrix. - - .. _mat4_lamp_to_world: - .. _mat4_world_to_lamp: - - ``mat4_lamp_to_world`` - Model matrix of the lamp lighting the object. OpenGL 4x4 matrix that converts lamp - local coordinates to world coordinates. In blender this is obtained from the - 'matrix_world' attribute of the lamp object. - - Some uniform will need the *mat4_world_to_lamp* matrix - computed as the inverse of this matrix. - - -.. note:: - - Any uniforms used for view projections or transformations (object, lamp matrices for eg), - can only be set once per frame. - - -GLSL Object Uniforms -^^^^^^^^^^^^^^^^^^^^ - -.. note:: - - - Object transformations and color must be set before drawing the object. - - There is at most one uniform of these types per shader. - -.. data:: GPU_DYNAMIC_OBJECT_VIEWMAT - - A matrix that converts world coordinates to camera coordinates (see mat4_world_to_cam_). - - :type: matrix4x4 - -.. data:: GPU_DYNAMIC_OBJECT_MAT - - A matrix that converts object coordinates to world coordinates (see mat4_object_to_world_). - - :type: matrix4x4 - -.. data:: GPU_DYNAMIC_OBJECT_VIEWIMAT - - The uniform is a 4x4 GL matrix that converts coordinates - in camera space to world coordinates (see mat4_cam_to_world_). - - :type: matrix4x4 - -.. data:: GPU_DYNAMIC_OBJECT_IMAT - - The uniform is a 4x4 GL matrix that converts world coodinates - to object coordinates (see mat4_world_to_object_). - - :type: matrix4x4 - -.. data:: GPU_DYNAMIC_OBJECT_COLOR - - An RGB color + alpha defined at object level. - Each values between 0.0 and 1.0. - - See :class:`bpy.types.Object.color`. - - :type: float4 - -.. data:: GPU_DYNAMIC_OBJECT_AUTOBUMPSCALE - - Multiplier for bump-map scaling. - - :type: float - - -GLSL Lamp Uniforms -^^^^^^^^^^^^^^^^^^ - -.. note:: - - There is one uniform of that type per lamp lighting the material. - -.. data:: GPU_DYNAMIC_LAMP_DYNVEC - - Represents the direction of light in camera space. - - Computed as: - mat4_world_to_cam_ * (-vec3_lamp_Z_axis) - - .. note:: - - - The lamp Z axis points to the opposite direction of light. - - The norm of the vector should be unit length. - - :type: float3 - -.. data:: GPU_DYNAMIC_LAMP_DYNCO - - Represents the position of the light in camera space. - - Computed as: - mat4_world_to_cam_ * vec3_lamp_pos - - :type: float3 - -.. data:: GPU_DYNAMIC_LAMP_DYNIMAT - - Matrix that converts vector in camera space to lamp space. - - Computed as: - mat4_world_to_lamp_ * mat4_cam_to_world_ - - :type: matrix4x4 - -.. data:: GPU_DYNAMIC_LAMP_DYNPERSMAT - - Matrix that converts a vector in camera space to shadow buffer depth space. - - Computed as: - mat4_perspective_to_depth_ * mat4_lamp_to_perspective_ * mat4_world_to_lamp_ * mat4_cam_to_world_. - - .. _mat4_perspective_to_depth: - - ``mat4_perspective_to_depth`` is a fixed matrix defined as follow:: - - 0.5 0.0 0.0 0.5 - 0.0 0.5 0.0 0.5 - 0.0 0.0 0.5 0.5 - 0.0 0.0 0.0 1.0 - - .. note:: - - - There is one uniform of that type per lamp casting shadow in the scene. - - :type: matrix4x4 - -.. data:: GPU_DYNAMIC_LAMP_DYNENERGY - - See :class:`bpy.types.Lamp.energy`. - - :type: float - -.. data:: GPU_DYNAMIC_LAMP_DYNCOL - - See :class:`bpy.types.Lamp.color`. - - :type: float3 - -.. data:: GPU_DYNAMIC_LAMP_DISTANCE - - See :class:`bpy.types.Lamp.distance`. - - :type: float - -.. data:: GPU_DYNAMIC_LAMP_ATT1 - - See - :class:`bpy.types.PointLamp.linear_attenuation`, - :class:`bpy.types.SpotLamp.linear_attenuation`. - - :type: float - -.. data:: GPU_DYNAMIC_LAMP_ATT2 - - See - :class:`bpy.types.PointLamp.quadratic_attenuation`, - :class:`bpy.types.SpotLamp.quadratic_attenuation`. - - :type: float - -.. data:: GPU_DYNAMIC_LAMP_SPOTSIZE - - See :class:`bpy.types.SpotLamp.spot_size`. - - :type: float - -.. data:: GPU_DYNAMIC_LAMP_SPOTBLEND - - See :class:`bpy.types.SpotLamp.spot_blend`. - - :type: float - -.. data:: GPU_DYNAMIC_LAMP_SPOTSCALE - - Represents the SpotLamp local scale. - - :type: float2 - - -GLSL Sampler Uniforms -^^^^^^^^^^^^^^^^^^^^^ - -.. data:: GPU_DYNAMIC_SAMPLER_2DBUFFER - - Represents an internal texture used for certain effect - (color band, etc). - - :type: integer - -.. data:: GPU_DYNAMIC_SAMPLER_2DIMAGE - - Represents a texture loaded from an image file. - - :type: integer - -.. data:: GPU_DYNAMIC_SAMPLER_2DSHADOW - - Represents a texture loaded from a shadow buffer file. - - :type: integer - - -GLSL Mist Uniforms -^^^^^^^^^^^^^^^^^^ - -.. data:: GPU_DYNAMIC_MIST_ENABLE: - - See :class:`bpy.types.WorldMistSettings.use_mist`. - - :type: float (0 or 1) - -.. data:: GPU_DYNAMIC_MIST_START - - See :class:`bpy.types.WorldMistSettings.start`. - - :type: float - - See :class:`bpy.types.WorldMistSettings.depth`. - -.. data:: GPU_DYNAMIC_MIST_DISTANCE - - :type: float - - See :class:`bpy.types.WorldMistSettings.intensity`. - -.. data:: GPU_DYNAMIC_MIST_INTENSITY - - :type: float - -.. data:: GPU_DYNAMIC_MIST_TYPE - - See :class:`bpy.types.WorldMistSettings.falloff`. - - :type: float (used as an index into the type) - -.. data:: GPU_DYNAMIC_MIST_COLOR - - -GLSL World Uniforms -^^^^^^^^^^^^^^^^^^^ - -.. data:: GPU_DYNAMIC_HORIZON_COLOR - - See :class:`bpy.types.World.horizon_color`. - - :type: float3 - -.. data:: GPU_DYNAMIC_AMBIENT_COLOR - - See :class:`bpy.types.World.ambient_color`. - - :type: float3 - - -GLSL Material Uniforms -^^^^^^^^^^^^^^^^^^^^^^ - -.. data:: GPU_DYNAMIC_MAT_DIFFRGB - - See :class:`bpy.types.Material.diffuse_color`. - - :type: float3 - -.. data:: GPU_DYNAMIC_MAT_REF - - See :class:`bpy.types.Material.diffuse_intensity`. - - :type: float - -.. data:: GPU_DYNAMIC_MAT_SPECRGB - - See :class:`bpy.types.Material.specular_color`. - - :type: float3 - -.. data:: GPU_DYNAMIC_MAT_SPEC - - See :class:`bpy.types.Material.specular_intensity`. - - :type: float - -.. data:: GPU_DYNAMIC_MAT_HARD - - See :class:`bpy.types.Material.specular_hardness`. - - :type: float - -.. data:: GPU_DYNAMIC_MAT_EMIT - - See :class:`bpy.types.Material.emit`. - - :type: float - -.. data:: GPU_DYNAMIC_MAT_AMB - - See :class:`bpy.types.Material.ambient`. - - :type: float - -.. data:: GPU_DYNAMIC_MAT_ALPHA - - See :class:`bpy.types.Material.alpha`. - - :type: float - - - -GLSL Attribute Type -------------------- - -.. _attribute-type: - -Type of the vertex attribute used in the GLSL shader. Determines the mesh custom data -layer that contains the vertex attribute. - -.. data:: CD_MTFACE - - Vertex attribute is a UV Map. Data type is vector of 2 float. - - There can be more than one attribute of that type, they are differenciated by name. - In blender, you can retrieve the attribute data with: - - .. code-block:: python - - mesh.uv_layers[attribute["name"]] - -.. data:: CD_MCOL - - Vertex attribute is color layer. Data type is vector 4 unsigned byte (RGBA). - - There can be more than one attribute of that type, they are differenciated by name. - In blender you can retrieve the attribute data with: - - .. code-block:: python - - mesh.vertex_colors[attribute["name"]] - -.. data:: CD_ORCO - - Vertex attribute is original coordinates. Data type is vector 3 float. - - There can be only 1 attribute of that type per shader. - In blender you can retrieve the attribute data with: - - .. code-block:: python - - mesh.vertices - -.. data:: CD_TANGENT - - Vertex attribute is the tangent vector. Data type is vector 4 float. - - There can be only 1 attribute of that type per shader. - There is currently no way to retrieve this attribute data via the RNA API but a standalone - C function to compute the tangent layer from the other layers can be obtained from - blender.org. - - -Functions -========= - -.. _export_shader: - -.. function:: export_shader(scene,material) - - Extracts the GLSL shader producing the visual effect of material in scene for the purpose of - reusing the shader in an external engine. - - This function is meant to be used in material exporter - so that the GLSL shader can be exported entirely. - - The return value is a dictionary containing the - shader source code and all associated data. - - :arg scene: the scene in which the material in rendered. - :type scene: :class:`bpy.types.Scene` - :arg material: the material that you want to export the GLSL shader - :type material: :class:`bpy.types.Material` - :return: the shader source code and all associated data in a dictionary - :rtype: dictionary - - The dictionary contains the following elements: - - - ``["fragment"]``: string - fragment shader source code. - - - ``["vertex"]``: string - vertex shader source code. - - - ``["uniforms"]``: sequence - list of uniforms used in fragment shader, can be empty list. Each element of the - sequence is a dictionary with the following elements: - - - ``["varname"]``: string - name of the uniform in the fragment shader. Always of the form 'unf<number>'. - - - ``["datatype"]``: integer - data type of the uniform variable. Can be one of the following: - - .. hlist:: - :columns: 2 - - - :data:`gpu.GPU_DATA_1I` : use ``glUniform1i`` - - :data:`gpu.GPU_DATA_1F` : use ``glUniform1fv`` - - :data:`gpu.GPU_DATA_2F` : use ``glUniform2fv`` - - :data:`gpu.GPU_DATA_3F` : use ``glUniform3fv`` - - :data:`gpu.GPU_DATA_4F` : use ``glUniform4fv`` - - :data:`gpu.GPU_DATA_9F` : use ``glUniformMatrix3fv`` - - :data:`gpu.GPU_DATA_16F` : use ``glUniformMatrix4fv`` - - - ``["type"]``: integer - type of uniform, determines the origin and method of calculation. See uniform-type_. - Depending on the type, more elements will be be present. - - - ``["lamp"]``: :class:`bpy.types.Object` - Reference to the lamp object from which the uniforms value are extracted. - Set for the following uniforms types: - - .. hlist:: - :columns: 2 - - - :data:`gpu.GPU_DYNAMIC_LAMP_DYNVEC` - - :data:`gpu.GPU_DYNAMIC_LAMP_DYNCO` - - :data:`gpu.GPU_DYNAMIC_LAMP_DYNIMAT` - - :data:`gpu.GPU_DYNAMIC_LAMP_DYNPERSMAT` - - :data:`gpu.GPU_DYNAMIC_LAMP_DYNENERGY` - - :data:`gpu.GPU_DYNAMIC_LAMP_DYNCOL` - - :data:`gpu.GPU_DYNAMIC_SAMPLER_2DSHADOW` - - Notes: - - - The uniforms - :data:`gpu.GPU_DYNAMIC_LAMP_DYNVEC`, - :data:`gpu.GPU_DYNAMIC_LAMP_DYNCO`, - :data:`gpu.GPU_DYNAMIC_LAMP_DYNIMAT` and - :data:`gpu.GPU_DYNAMIC_LAMP_DYNPERSMAT` - refer to the lamp object position and orientation, - both of can be derived from the object world matrix: - - .. code-block:: python - - obmat = uniform["lamp"].matrix_world - - where obmat is the mat4_lamp_to_world_ matrix of the lamp as a 2 dimensional array, - the lamp world location location is in ``obmat[3]``. - - - The uniform types - :data:`gpu.GPU_DYNAMIC_LAMP_DYNENERGY` and - :data:`gpu.GPU_DYNAMIC_LAMP_DYNCOL` - refer to the lamp data bloc that you get from: - - .. code-block:: python - - la = uniform["lamp"].data - - from which you get ``lamp.energy`` and ``lamp.color`` - - - Lamp duplication is not supported: if you have duplicated lamps in your scene - (i.e. lamp that are instantiated by dupligroup, etc), this element will only - give you a reference to the orignal lamp and you will not know which instance - of the lamp it is refering too. You can still handle that case in the exporter - by distributing the uniforms amongst the duplicated lamps. - - - ``["image"]``: :class:`bpy.types.Image` - Reference to the image databloc. - Set for uniform type - :data:`gpu.GPU_DYNAMIC_SAMPLER_2DIMAGE`. - You can get the image data from: - - .. code-block:: python - - # full path to image file - uniform["image"].filepath - # image size as a 2-dimensional array of int - uniform["image"].size - - - ``["texnumber"]``: integer - Channel number to which the texture is bound when drawing the object. - Set for uniform types - :data:`gpu.GPU_DYNAMIC_SAMPLER_2DBUFFER`, - :data:`gpu.GPU_DYNAMIC_SAMPLER_2DIMAGE` and - :data:`gpu.GPU_DYNAMIC_SAMPLER_2DSHADOW`. - - This is provided for information only: when reusing the shader outside blencer, - you are free to assign the textures to the channel of your choice and to pass - that number channel to the GPU in the uniform. - - - ``["texpixels"]``: byte array - texture data for uniform type :data:`gpu.GPU_DYNAMIC_SAMPLER_2DBUFFER`. - Although the corresponding uniform is a 2D sampler, - the texture is always a 1D texture of n x 1 pixel. - The texture size n is provided in ["texsize"] element. - These texture are only used for computer generated texture (colorband, etc). - The texture data is provided so that you can make a real image out of it in the exporter. - - - ``["texsize"]``: integer - horizontal size of texture for uniform type :data:`gpu.GPU_DYNAMIC_SAMPLER_2DBUFFER`. - The texture data is in ["texpixels"]. - - - ``["attributes"]``: sequence - list of attributes used in vertex shader, can be empty. Blender doesn't use - standard attributes except for vertex position and normal. All other vertex - attributes must be passed using the generic ``glVertexAttrib`` functions. - The attribute data can be found in the derived mesh custom data using RNA. - Each element of the sequence is a dictionary containing the following elements: - - - ``["varname"]``: string - name of the uniform in the vertex shader. Always of the form 'att<number>'. - - - ``["datatype"]``: integer - data type of vertex attribute, can be one of the following: - - - :data:`gpu.GPU_DATA_2F`: use ``glVertexAttrib2fv`` - - :data:`gpu.GPU_DATA_3F`: use ``glVertexAttrib3fv`` - - :data:`gpu.GPU_DATA_4F`: use ``glVertexAttrib4fv`` - - :data:`gpu.GPU_DATA_4UB`: use ``glVertexAttrib4ubv`` - - - ``["number"]``: integer - Generic attribute number. This is provided for information only. - Blender doesn't use ``glBindAttribLocation`` to place generic attributes at specific location, - it lets the shader compiler place the attributes automatically and query the - placement with ``glGetAttribLocation``. - The result of this placement is returned in this element. - - When using this shader in a render engine, you should either use - ``glBindAttribLocation`` to force the attribute at this location or use - ``glGetAttribLocation`` to get the placement chosen by the compiler of your GPU. - - - ``["type"]``: integer - type of the mesh custom data from which the vertex attribute is loaded. - See attribute-type_. - - - ``["name"]``: string or integer - custom data layer name, used for attribute type :data:`gpu.CD_MTFACE` and :data:`gpu.CD_MCOL`. - - Example: - - .. code-block:: python - - import gpu - # get GLSL shader of material Mat.001 in scene Scene.001 - scene = bpy.data.scenes["Scene.001"] - material = bpy.data.materials["Mat.001"] - shader = gpu.export_shader(scene,material) - # scan the uniform list and find the images used in the shader - for uniform in shader["uniforms"]: - if uniform["type"] == gpu.GPU_DYNAMIC_SAMPLER_2DIMAGE: - print("uniform {0} is using image {1}".format(uniform["varname"], uniform["image"].filepath)) - # scan the attribute list and find the UV Map used in the shader - for attribute in shader["attributes"]: - if attribute["type"] == gpu.CD_MTFACE: - print("attribute {0} is using UV Map {1}".format(attribute["varname"], attribute["name"])) - - -Notes -===== - -.. _mat4_lamp_to_perspective: - -#. Calculation of the ``mat4_lamp_to_perspective`` matrix for a spot lamp. - - The following pseudo code shows how the ``mat4_lamp_to_perspective`` matrix is computed - in blender for uniforms of :data:`gpu.GPU_DYNAMIC_LAMP_DYNPERSMAT` type: - - .. code-block:: python - - # Get the lamp datablock with: - lamp = bpy.data.objects[uniform["lamp"]].data - - # Compute the projection matrix: - # You will need these lamp attributes: - # lamp.clipsta : near clip plane in world unit - # lamp.clipend : far clip plane in world unit - # lamp.spotsize : angle in degree of the spot light - - # The size of the projection plane is computed with the usual formula: - wsize = lamp.clista * tan(lamp.spotsize/2) - - # And the projection matrix: - mat4_lamp_to_perspective = glFrustum(-wsize, wsize, -wsize, wsize, lamp.clista, lamp.clipend) - -#. Creation of the shadow map for a spot lamp. - - The shadow map is the depth buffer of a render performed by placing the camera at the - spot light position. The size of the shadow map is given by the attribute ``lamp.bufsize``: - shadow map size in pixel, same size in both dimensions. +Module to provide functions concerning the GPU implementation in Blender. diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 33fbcadec5a..76564287e3f 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -1313,167 +1313,6 @@ class CYCLES_MATERIAL_PT_viewport(CyclesButtonsPanel, Panel): col.prop(mat, "specular_hardness", text="Hardness") -class CYCLES_TEXTURE_PT_context(CyclesButtonsPanel, Panel): - bl_label = "" - bl_context = "texture" - bl_options = {'HIDE_HEADER'} - COMPAT_ENGINES = {'CYCLES'} - - def draw(self, context): - layout = self.layout - - tex = context.texture - space = context.space_data - pin_id = space.pin_id - use_pin_id = space.use_pin_id - user = context.texture_user - - space.use_limited_texture_context = False - - if not (use_pin_id and isinstance(pin_id, bpy.types.Texture)): - pin_id = None - - if not pin_id: - layout.template_texture_user() - - if user or pin_id: - layout.separator() - - split = layout.split(percentage=0.65) - col = split.column() - - if pin_id: - col.template_ID(space, "pin_id") - else: - propname = context.texture_user_property.identifier - col.template_ID(user, propname, new="texture.new") - - if tex: - split = layout.split(percentage=0.2) - split.label(text="Type:") - split.prop(tex, "type", text="") - - -class CYCLES_TEXTURE_PT_node(CyclesButtonsPanel, Panel): - bl_label = "Node" - bl_context = "texture" - - @classmethod - def poll(cls, context): - node = context.texture_node - return node and CyclesButtonsPanel.poll(context) - - def draw(self, context): - layout = self.layout - - node = context.texture_node - ntree = node.id_data - layout.template_node_view(ntree, node, None) - - -class CYCLES_TEXTURE_PT_mapping(CyclesButtonsPanel, Panel): - bl_label = "Mapping" - bl_context = "texture" - - @classmethod - def poll(cls, context): - node = context.texture_node - # TODO(sergey): perform a faster/nicer check? - return node and hasattr(node, 'texture_mapping') and CyclesButtonsPanel.poll(context) - - def draw(self, context): - layout = self.layout - - node = context.texture_node - - mapping = node.texture_mapping - - layout.prop(mapping, "vector_type", expand=True) - - row = layout.row() - - row.column().prop(mapping, "translation") - row.column().prop(mapping, "rotation") - row.column().prop(mapping, "scale") - - layout.label(text="Projection:") - - row = layout.row() - row.prop(mapping, "mapping_x", text="") - row.prop(mapping, "mapping_y", text="") - row.prop(mapping, "mapping_z", text="") - - -class CYCLES_TEXTURE_PT_colors(CyclesButtonsPanel, Panel): - bl_label = "Color" - bl_context = "texture" - bl_options = {'DEFAULT_CLOSED'} - - @classmethod - def poll(cls, context): - # node = context.texture_node - return False - # return node and CyclesButtonsPanel.poll(context) - - def draw(self, context): - layout = self.layout - - node = context.texture_node - - mapping = node.color_mapping - - split = layout.split() - - col = split.column() - col.label(text="Blend:") - col.prop(mapping, "blend_type", text="") - col.prop(mapping, "blend_factor", text="Factor") - col.prop(mapping, "blend_color", text="") - - col = split.column() - col.label(text="Adjust:") - col.prop(mapping, "brightness") - col.prop(mapping, "contrast") - col.prop(mapping, "saturation") - - layout.separator() - - layout.prop(mapping, "use_color_ramp", text="Ramp") - if mapping.use_color_ramp: - layout.template_color_ramp(mapping, "color_ramp", expand=True) - - -class CYCLES_PARTICLE_PT_textures(CyclesButtonsPanel, Panel): - bl_label = "Textures" - bl_context = "particle" - bl_options = {'DEFAULT_CLOSED'} - - @classmethod - def poll(cls, context): - psys = context.particle_system - return psys and CyclesButtonsPanel.poll(context) - - def draw(self, context): - layout = self.layout - - psys = context.particle_system - part = psys.settings - - row = layout.row() - row.template_list("TEXTURE_UL_texslots", "", part, "texture_slots", part, "active_texture_index", rows=2) - - col = row.column(align=True) - col.operator("texture.slot_move", text="", icon='TRIA_UP').type = 'UP' - col.operator("texture.slot_move", text="", icon='TRIA_DOWN').type = 'DOWN' - col.menu("TEXTURE_MT_specials", icon='DOWNARROW_HLT', text="") - - if not part.active_texture: - layout.template_ID(part, "active_texture", new="texture.new") - else: - slot = part.texture_slots[part.active_texture_index] - layout.template_ID(slot, "texture", new="texture.new") - - class CYCLES_RENDER_PT_bake(CyclesButtonsPanel, Panel): bl_label = "Bake" bl_context = "render" @@ -1486,66 +1325,83 @@ class CYCLES_RENDER_PT_bake(CyclesButtonsPanel, Panel): scene = context.scene cscene = scene.cycles cbk = scene.render.bake + rd = scene.render - layout.operator("object.bake", icon='RENDER_STILL').type = cscene.bake_type + if rd.use_bake_multires: + layout.operator("object.bake_image", icon='RENDER_STILL') + else: + layout.operator("object.bake", icon='RENDER_STILL').type = cscene.bake_type col = layout.column() - col.prop(cscene, "bake_type") + col.prop(rd, "use_bake_multires") + if rd.use_bake_multires: + col.prop(rd, "bake_type") - col = layout.column() + split = layout.split() - if cscene.bake_type == 'NORMAL': - col.prop(cbk, "normal_space", text="Space") + col = split.column() + col.prop(rd, "bake_margin") + col.prop(rd, "use_bake_clear") - row = col.row(align=True) - row.label(text="Swizzle:") - row.prop(cbk, "normal_r", text="") - row.prop(cbk, "normal_g", text="") - row.prop(cbk, "normal_b", text="") + col = split.column() + if rd.bake_type == 'DISPLACEMENT': + col.prop(rd, "use_bake_lores_mesh") + else: + col.prop(cscene, "bake_type") - elif cscene.bake_type == 'COMBINED': - row = col.row(align=True) - row.prop(cbk, "use_pass_direct", toggle=True) - row.prop(cbk, "use_pass_indirect", toggle=True) + col = layout.column() - split = col.split() - split.active = cbk.use_pass_direct or cbk.use_pass_indirect + if cscene.bake_type == 'NORMAL': + col.prop(cbk, "normal_space", text="Space") - col = split.column() - col.prop(cbk, "use_pass_diffuse") - col.prop(cbk, "use_pass_glossy") - col.prop(cbk, "use_pass_transmission") + row = col.row(align=True) + row.label(text="Swizzle:") + row.prop(cbk, "normal_r", text="") + row.prop(cbk, "normal_g", text="") + row.prop(cbk, "normal_b", text="") - col = split.column() - col.prop(cbk, "use_pass_subsurface") - col.prop(cbk, "use_pass_ambient_occlusion") - col.prop(cbk, "use_pass_emit") + elif cscene.bake_type == 'COMBINED': + row = col.row(align=True) + row.prop(cbk, "use_pass_direct", toggle=True) + row.prop(cbk, "use_pass_indirect", toggle=True) - elif cscene.bake_type in {'DIFFUSE', 'GLOSSY', 'TRANSMISSION', 'SUBSURFACE'}: - row = col.row(align=True) - row.prop(cbk, "use_pass_direct", toggle=True) - row.prop(cbk, "use_pass_indirect", toggle=True) - row.prop(cbk, "use_pass_color", toggle=True) + split = col.split() + split.active = cbk.use_pass_direct or cbk.use_pass_indirect - layout.separator() + col = split.column() + col.prop(cbk, "use_pass_diffuse") + col.prop(cbk, "use_pass_glossy") + col.prop(cbk, "use_pass_transmission") - split = layout.split() + col = split.column() + col.prop(cbk, "use_pass_subsurface") + col.prop(cbk, "use_pass_ambient_occlusion") + col.prop(cbk, "use_pass_emit") - col = split.column() - col.prop(cbk, "margin") - col.prop(cbk, "use_clear") + elif cscene.bake_type in {'DIFFUSE', 'GLOSSY', 'TRANSMISSION', 'SUBSURFACE'}: + row = col.row(align=True) + row.prop(cbk, "use_pass_direct", toggle=True) + row.prop(cbk, "use_pass_indirect", toggle=True) + row.prop(cbk, "use_pass_color", toggle=True) - col = split.column() - col.prop(cbk, "use_selected_to_active") - sub = col.column() - sub.active = cbk.use_selected_to_active - sub.prop(cbk, "use_cage", text="Cage") - if cbk.use_cage: - sub.prop(cbk, "cage_extrusion", text="Extrusion") - sub.prop_search(cbk, "cage_object", scene, "objects", text="") - else: - sub.prop(cbk, "cage_extrusion", text="Ray Distance") + layout.separator() + split = layout.split() + + col = split.column() + col.prop(cbk, "margin") + col.prop(cbk, "use_clear") + + col = split.column() + col.prop(cbk, "use_selected_to_active") + sub = col.column() + sub.active = cbk.use_selected_to_active + sub.prop(cbk, "use_cage", text="Cage") + if cbk.use_cage: + sub.prop(cbk, "cage_extrusion", text="Extrusion") + sub.prop_search(cbk, "cage_object", scene, "objects", text="") + else: + sub.prop(cbk, "cage_extrusion", text="Ray Distance") class CYCLES_RENDER_PT_debug(CyclesButtonsPanel, Panel): bl_label = "Debug" @@ -1727,47 +1583,14 @@ def get_panels(): 'DATA_PT_falloff_curve', 'DATA_PT_lamp', 'DATA_PT_preview', - 'DATA_PT_shadow', 'DATA_PT_spot', - 'DATA_PT_sunsky', 'MATERIAL_PT_context_material', - 'MATERIAL_PT_diffuse', - 'MATERIAL_PT_flare', - 'MATERIAL_PT_halo', - 'MATERIAL_PT_mirror', - 'MATERIAL_PT_options', - 'MATERIAL_PT_pipeline', 'MATERIAL_PT_preview', - 'MATERIAL_PT_shading', - 'MATERIAL_PT_shadow', - 'MATERIAL_PT_specular', - 'MATERIAL_PT_sss', - 'MATERIAL_PT_strand', - 'MATERIAL_PT_transp', - 'MATERIAL_PT_volume_density', - 'MATERIAL_PT_volume_integration', - 'MATERIAL_PT_volume_lighting', - 'MATERIAL_PT_volume_options', - 'MATERIAL_PT_volume_shading', - 'MATERIAL_PT_volume_transp', 'VIEWLAYER_PT_layer_options', 'VIEWLAYER_PT_layer_passes', 'VIEWLAYER_PT_views', - 'RENDER_PT_antialiasing', - 'RENDER_PT_bake', - 'RENDER_PT_motion_blur', - 'RENDER_PT_performance', 'RENDER_PT_post_processing', - 'RENDER_PT_shading', 'SCENE_PT_simplify', - 'TEXTURE_PT_context_texture', - 'WORLD_PT_ambient_occlusion', - 'WORLD_PT_environment_lighting', - 'WORLD_PT_gather', - 'WORLD_PT_indirect_lighting', - 'WORLD_PT_mist', - 'WORLD_PT_preview', - 'WORLD_PT_world' } panels = [] @@ -1815,11 +1638,6 @@ classes = ( CYCLES_MATERIAL_PT_displacement, CYCLES_MATERIAL_PT_settings, CYCLES_MATERIAL_PT_viewport, - CYCLES_TEXTURE_PT_context, - CYCLES_TEXTURE_PT_node, - CYCLES_TEXTURE_PT_mapping, - CYCLES_TEXTURE_PT_colors, - CYCLES_PARTICLE_PT_textures, CYCLES_RENDER_PT_bake, CYCLES_RENDER_PT_debug, CYCLES_PARTICLE_PT_curve_settings, diff --git a/release/scripts/freestyle/modules/parameter_editor.py b/release/scripts/freestyle/modules/parameter_editor.py index 2af6caac4f9..c2b23f017fe 100644 --- a/release/scripts/freestyle/modules/parameter_editor.py +++ b/release/scripts/freestyle/modules/parameter_editor.py @@ -1538,16 +1538,9 @@ def process(layer_name, lineset_name): raise RuntimeError("No Thickness modifier with type", type(m), m) # -- Textures -- # has_tex = False - if scene.render.use_shading_nodes: - if linestyle.use_nodes and linestyle.node_tree: - shaders_list.append(BlenderTextureShader(linestyle.node_tree)) - has_tex = True - else: - if linestyle.use_texture: - textures = tuple(BlenderTextureShader(slot) for slot in linestyle.texture_slots if slot is not None) - if textures: - shaders_list.extend(textures) - has_tex = True + if linestyle.use_nodes and linestyle.node_tree: + shaders_list.append(BlenderTextureShader(linestyle.node_tree)) + has_tex = True if has_tex: shaders_list.append(StrokeTextureStepShader(linestyle.texture_spacing)) diff --git a/release/scripts/startup/bl_operators/object_quick_effects.py b/release/scripts/startup/bl_operators/object_quick_effects.py index 24323b1554e..70334fb0f23 100644 --- a/release/scripts/startup/bl_operators/object_quick_effects.py +++ b/release/scripts/startup/bl_operators/object_quick_effects.py @@ -364,88 +364,38 @@ class QuickSmoke(Operator): # Setup material - # Cycles - if context.scene.render.use_shading_nodes or context.render.use_shading_nodes: - bpy.ops.object.material_slot_add() - - mat = bpy.data.materials.new("Smoke Domain Material") - obj.material_slots[0].material = mat - - # Make sure we use nodes - mat.use_nodes = True - - # Set node variables and clear the default nodes - tree = mat.node_tree - nodes = tree.nodes - links = tree.links - - nodes.clear() + # Cycles and Eevee + bpy.ops.object.material_slot_add() - # Create shader nodes + mat = bpy.data.materials.new("Smoke Domain Material") + obj.material_slots[0].material = mat - # Material output - node_out = nodes.new(type='ShaderNodeOutputMaterial') - node_out.location = grid_location(6, 1) + # Make sure we use nodes + mat.use_nodes = True - # Add Principled Volume - node_principled = nodes.new(type='ShaderNodeVolumePrincipled') - node_principled.location = grid_location(4, 1) - links.new(node_principled.outputs["Volume"], - node_out.inputs["Volume"]) + # Set node variables and clear the default nodes + tree = mat.node_tree + nodes = tree.nodes + links = tree.links - node_principled.inputs["Density"].default_value = 5.0 + nodes.clear() - if self.style in {'FIRE', 'BOTH'}: - node_principled.inputs["Blackbody Intensity"].default_value = 1.0 + # Create shader nodes - # Blender Internal - else: - # create a volume material with a voxel data texture for the domain - bpy.ops.object.material_slot_add() - - mat = bpy.data.materials.new("Smoke Domain Material") - obj.material_slots[0].material = mat - mat.type = 'VOLUME' - mat.volume.density = 0 - mat.volume.density_scale = 5 - mat.volume.step_size = 0.1 - - tex = bpy.data.textures.new("Smoke Density", 'VOXEL_DATA') - tex.voxel_data.domain_object = obj - tex.voxel_data.interpolation = 'TRICUBIC_BSPLINE' - - tex_slot = mat.texture_slots.add() - tex_slot.texture = tex - tex_slot.texture_coords = 'ORCO' - tex_slot.use_map_color_emission = False - tex_slot.use_map_density = True - tex_slot.use_map_color_reflection = True - - # for fire add a second texture for flame emission - mat.volume.emission_color = Vector((0.0, 0.0, 0.0)) - tex = bpy.data.textures.new("Flame", 'VOXEL_DATA') - tex.voxel_data.domain_object = obj - tex.voxel_data.smoke_data_type = 'SMOKEFLAME' - tex.voxel_data.interpolation = 'TRICUBIC_BSPLINE' - tex.use_color_ramp = True + # Material output + node_out = nodes.new(type='ShaderNodeOutputMaterial') + node_out.location = grid_location(6, 1) - tex_slot = mat.texture_slots.add() - tex_slot.texture = tex - tex_slot.texture_coords = 'ORCO' + # Add Principled Volume + node_principled = nodes.new(type='ShaderNodeVolumePrincipled') + node_principled.location = grid_location(4, 1) + links.new(node_principled.outputs["Volume"], + node_out.inputs["Volume"]) - # add color ramp for flame color - ramp = tex.color_ramp - # dark orange - elem = ramp.elements.new(0.333) - elem.color = (0.2, 0.03, 0.0, 1.0) + node_principled.inputs["Density"].default_value = 5.0 - # yellow glow - elem = ramp.elements.new(0.666) - elem.color = (1, 0.65, 0.25, 1.0) - - mat.texture_slots[1].use_map_density = True - mat.texture_slots[1].use_map_emission = True - mat.texture_slots[1].emission_factor = 5 + if self.style in {'FIRE', 'BOTH'}: + node_principled.inputs["Blackbody Intensity"].default_value = 1.0 return {'FINISHED'} @@ -547,13 +497,33 @@ class QuickFluid(Operator): mat = bpy.data.materials.new("Fluid Domain Material") obj.material_slots[0].material = mat - mat.specular_intensity = 1 - mat.specular_hardness = 100 - mat.use_transparency = True - mat.alpha = 0.0 - mat.transparency_method = 'RAYTRACE' - mat.raytrace_transparency.ior = 1.33 - mat.raytrace_transparency.depth = 4 + # Make sure we use nodes + mat.use_nodes = True + + # Set node variables and clear the default nodes + tree = mat.node_tree + nodes = tree.nodes + links = tree.links + + nodes.clear() + + # Create shader nodes + + # Material output + node_out = nodes.new(type='ShaderNodeOutputMaterial') + node_out.location = grid_location(6, 1) + + # Add Glass + node_glass = nodes.new(type='ShaderNodeBsdfGlass') + node_glass.location = grid_location(4, 1) + links.new(node_glass.outputs["BSDF"], node_out.inputs["Surface"]) + node_glass.inputs["IOR"].default_value = 1.33 + + # Add Absorption + node_absorption = nodes.new(type='ShaderNodeVolumeAbsorption') + node_absorption.location = grid_location(4, 2) + links.new(node_absorption.outputs["Volume"], node_out.inputs["Volume"]) + node_absorption.inputs["Color"].default_value = (0.8, 0.9, 1.0, 1.0) if self.start_baking: bpy.ops.fluid.bake('INVOKE_DEFAULT') diff --git a/release/scripts/startup/bl_operators/presets.py b/release/scripts/startup/bl_operators/presets.py index c696c38dac6..b06d054e15f 100644 --- a/release/scripts/startup/bl_operators/presets.py +++ b/release/scripts/startup/bl_operators/presets.py @@ -318,34 +318,6 @@ class AddPresetSafeAreas(AddPresetBase, Operator): preset_subdir = "safe_areas" -class AddPresetSSS(AddPresetBase, Operator): - """Add or remove a Subsurface Scattering Preset""" - bl_idname = "material.sss_preset_add" - bl_label = "Add SSS Preset" - preset_menu = "MATERIAL_MT_sss_presets" - - preset_defines = [ - ("material = " - "bpy.context.material.active_node_material " - "if bpy.context.material.active_node_material " - "else bpy.context.material") - ] - - preset_values = [ - "material.subsurface_scattering.back", - "material.subsurface_scattering.color", - "material.subsurface_scattering.color_factor", - "material.subsurface_scattering.error_threshold", - "material.subsurface_scattering.front", - "material.subsurface_scattering.ior", - "material.subsurface_scattering.radius", - "material.subsurface_scattering.scale", - "material.subsurface_scattering.texture_factor", - ] - - preset_subdir = "sss" - - class AddPresetCloth(AddPresetBase, Operator): """Add or remove a Cloth Preset""" bl_idname = "cloth.preset_add" @@ -695,7 +667,6 @@ classes = ( AddPresetNodeColor, AddPresetOperator, AddPresetRender, - AddPresetSSS, AddPresetSafeAreas, AddPresetSunSky, AddPresetTrackingCamera, diff --git a/release/scripts/startup/bl_ui/properties_data_lamp.py b/release/scripts/startup/bl_ui/properties_data_lamp.py index f3daf64b442..892ca26189d 100644 --- a/release/scripts/startup/bl_ui/properties_data_lamp.py +++ b/release/scripts/startup/bl_ui/properties_data_lamp.py @@ -55,16 +55,11 @@ class DATA_PT_context_lamp(DataButtonsPanel, Panel): split = layout.split(percentage=0.65) - texture_count = len(lamp.texture_slots.keys()) - if ob: split.template_ID(ob, "data") elif lamp: split.template_ID(space, "pin_id") - if texture_count != 0: - split.label(text=str(texture_count), icon='TEXTURE') - class DATA_PT_preview(DataButtonsPanel, Panel): bl_label = "Preview" @@ -111,17 +106,11 @@ class DATA_PT_lamp(DataButtonsPanel, Panel): sub.prop(lamp, "linear_coefficient", text="Linear") sub.prop(lamp, "quadratic_coefficient", text="Quadratic") - col.prop(lamp, "use_sphere") - if lamp.type == 'AREA': col.prop(lamp, "distance") - col.prop(lamp, "gamma") col = split.column() - col.prop(lamp, "use_negative") - col.prop(lamp, "use_own_layer", text="This Layer Only") - col.prop(lamp, "use_specular") - col.prop(lamp, "use_diffuse") + col.label() class DATA_PT_EEVEE_lamp(DataButtonsPanel, Panel): @@ -154,202 +143,7 @@ class DATA_PT_EEVEE_lamp(DataButtonsPanel, Panel): sub.prop(lamp, "size_y", text="Size Y") col = split.column() - col.prop(lamp, "use_specular") - col.prop(lamp, "use_diffuse") - col.separator() - - if lamp.type in {'POINT', 'SPOT', 'AREA'}: - col.prop(lamp, "use_sphere") - col = col.column() - col.active = lamp.use_sphere - col.prop(lamp, "distance") - - -class DATA_PT_sunsky(DataButtonsPanel, Panel): - bl_label = "Sky & Atmosphere" - COMPAT_ENGINES = {'BLENDER_RENDER'} - - @classmethod - def poll(cls, context): - lamp = context.lamp - engine = context.engine - return (lamp and lamp.type == 'SUN') and (engine in cls.COMPAT_ENGINES) - - def draw(self, context): - layout = self.layout - - lamp = context.lamp.sky - - row = layout.row(align=True) - row.prop(lamp, "use_sky") - row.menu("LAMP_MT_sunsky_presets", text=bpy.types.LAMP_MT_sunsky_presets.bl_label) - row.operator("lamp.sunsky_preset_add", text="", icon='ZOOMIN') - row.operator("lamp.sunsky_preset_add", text="", icon='ZOOMOUT').remove_active = True - - row = layout.row() - row.active = lamp.use_sky or lamp.use_atmosphere - row.prop(lamp, "atmosphere_turbidity", text="Turbidity") - - split = layout.split() - - col = split.column() - col.active = lamp.use_sky - col.label(text="Blending:") - sub = col.column() - sub.prop(lamp, "sky_blend_type", text="") - sub.prop(lamp, "sky_blend", text="Factor") - - col.label(text="Color Space:") - sub = col.column() - sub.row().prop(lamp, "sky_color_space", expand=True) - sub.prop(lamp, "sky_exposure", text="Exposure") - - col = split.column() - col.active = lamp.use_sky - col.label(text="Horizon:") - sub = col.column() - sub.prop(lamp, "horizon_brightness", text="Brightness") - sub.prop(lamp, "spread", text="Spread") - - col.label(text="Sun:") - sub = col.column() - sub.prop(lamp, "sun_brightness", text="Brightness") - sub.prop(lamp, "sun_size", text="Size") - sub.prop(lamp, "backscattered_light", slider=True, text="Back Light") - - layout.separator() - - layout.prop(lamp, "use_atmosphere") - - split = layout.split() - - col = split.column() - col.active = lamp.use_atmosphere - col.label(text="Intensity:") - col.prop(lamp, "sun_intensity", text="Sun") - col.prop(lamp, "atmosphere_distance_factor", text="Distance") - - col = split.column() - col.active = lamp.use_atmosphere - col.label(text="Scattering:") - sub = col.column(align=True) - sub.prop(lamp, "atmosphere_inscattering", slider=True, text="Inscattering") - sub.prop(lamp, "atmosphere_extinction", slider=True, text="Extinction") - - -class DATA_PT_shadow(DataButtonsPanel, Panel): - bl_label = "Shadow" - COMPAT_ENGINES = {'BLENDER_RENDER'} - - @classmethod - def poll(cls, context): - lamp = context.lamp - engine = context.engine - return (lamp and lamp.type in {'POINT', 'SUN', 'SPOT', 'AREA'}) and (engine in cls.COMPAT_ENGINES) - - def draw(self, context): - layout = self.layout - - lamp = context.lamp - - layout.row().prop(lamp, "shadow_method", expand=True) - - if lamp.shadow_method == 'NOSHADOW' and lamp.type == 'AREA': - split = layout.split() - - col = split.column() - col.label(text="Form Factor Sampling:") - - sub = col.row(align=True) - - if lamp.shape == 'SQUARE': - sub.prop(lamp, "shadow_ray_samples_x", text="Samples") - elif lamp.shape == 'RECTANGLE': - sub.prop(lamp, "shadow_ray_samples_x", text="Samples X") - sub.prop(lamp, "shadow_ray_samples_y", text="Samples Y") - - if lamp.shadow_method != 'NOSHADOW': - split = layout.split() - - col = split.column() - col.prop(lamp, "shadow_color", text="") - - col = split.column() - col.prop(lamp, "use_shadow_layer", text="This Layer Only") - col.prop(lamp, "use_only_shadow") - - if lamp.shadow_method == 'RAY_SHADOW': - split = layout.split() - - col = split.column() - col.label(text="Sampling:") - - if lamp.type in {'POINT', 'SUN', 'SPOT'}: - sub = col.row() - - sub.prop(lamp, "shadow_ray_samples", text="Samples") - sub.prop(lamp, "shadow_soft_size", text="Soft Size") - - elif lamp.type == 'AREA': - sub = col.row(align=True) - - if lamp.shape == 'SQUARE': - sub.prop(lamp, "shadow_ray_samples_x", text="Samples") - elif lamp.shape == 'RECTANGLE': - sub.prop(lamp, "shadow_ray_samples_x", text="Samples X") - sub.prop(lamp, "shadow_ray_samples_y", text="Samples Y") - - col.row().prop(lamp, "shadow_ray_sample_method", expand=True) - - if lamp.shadow_ray_sample_method == 'ADAPTIVE_QMC': - layout.prop(lamp, "shadow_adaptive_threshold", text="Threshold") - - if lamp.type == 'AREA' and lamp.shadow_ray_sample_method == 'CONSTANT_JITTERED': - row = layout.row() - row.prop(lamp, "use_umbra") - row.prop(lamp, "use_dither") - row.prop(lamp, "use_jitter") - - elif lamp.shadow_method == 'BUFFER_SHADOW': - col = layout.column() - col.label(text="Buffer Type:") - col.row().prop(lamp, "shadow_buffer_type", expand=True) - - if lamp.shadow_buffer_type in {'REGULAR', 'HALFWAY', 'DEEP'}: - split = layout.split() - - col = split.column() - col.label(text="Filter Type:") - col.prop(lamp, "shadow_filter_type", text="") - sub = col.column(align=True) - sub.prop(lamp, "shadow_buffer_soft", text="Soft") - sub.prop(lamp, "shadow_buffer_bias", text="Bias") - - col = split.column() - col.label(text="Sample Buffers:") - col.prop(lamp, "shadow_sample_buffers", text="") - sub = col.column(align=True) - sub.prop(lamp, "shadow_buffer_size", text="Size") - sub.prop(lamp, "shadow_buffer_samples", text="Samples") - if lamp.shadow_buffer_type == 'DEEP': - col.prop(lamp, "compression_threshold") - - elif lamp.shadow_buffer_type == 'IRREGULAR': - layout.prop(lamp, "shadow_buffer_bias", text="Bias") - - split = layout.split() - - col = split.column() - col.prop(lamp, "use_auto_clip_start", text="Autoclip Start") - sub = col.column() - sub.active = not lamp.use_auto_clip_start - sub.prop(lamp, "shadow_buffer_clip_start", text="Clip Start") - - col = split.column() - col.prop(lamp, "use_auto_clip_end", text="Autoclip End") - sub = col.column() - sub.active = not lamp.use_auto_clip_end - sub.prop(lamp, "shadow_buffer_clip_end", text="Clip End") + col.label() class DATA_PT_EEVEE_shadow(DataButtonsPanel, Panel): @@ -531,8 +325,6 @@ classes = ( DATA_PT_preview, DATA_PT_lamp, DATA_PT_EEVEE_lamp, - DATA_PT_sunsky, - DATA_PT_shadow, DATA_PT_EEVEE_shadow, DATA_PT_area, DATA_PT_spot, diff --git a/release/scripts/startup/bl_ui/properties_data_mesh.py b/release/scripts/startup/bl_ui/properties_data_mesh.py index 30690418e51..a9a47d268d2 100644 --- a/release/scripts/startup/bl_ui/properties_data_mesh.py +++ b/release/scripts/startup/bl_ui/properties_data_mesh.py @@ -241,7 +241,7 @@ class DATA_PT_vertex_groups(MeshButtonsPanel, Panel): class DATA_PT_face_maps(MeshButtonsPanel, Panel): bl_label = "Face Maps" - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py index bf8529959f4..28e39959c7e 100644 --- a/release/scripts/startup/bl_ui/properties_data_modifier.py +++ b/release/scripts/startup/bl_ui/properties_data_modifier.py @@ -1014,17 +1014,10 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): def UV_PROJECT(self, layout, ob, md): split = layout.split() - - col = split.column() - col.label(text="Image:") - col.prop(md, "image", text="") - col = split.column() - col.label(text="UV Map:") - col.prop_search(md, "uv_layer", ob.data, "uv_layers", text="") + col.prop_search(md, "uv_layer", ob.data, "uv_layers") + col.separator() - split = layout.split() - col = split.column() col.prop(md, "projector_count", text="Projectors") for proj in md.projectors: col.prop(proj, "object", text="") diff --git a/release/scripts/startup/bl_ui/properties_freestyle.py b/release/scripts/startup/bl_ui/properties_freestyle.py index b1992127932..84ebb21c703 100644 --- a/release/scripts/startup/bl_ui/properties_freestyle.py +++ b/release/scripts/startup/bl_ui/properties_freestyle.py @@ -39,7 +39,7 @@ class RenderFreestyleButtonsPanel: class RENDER_PT_freestyle(RenderFreestyleButtonsPanel, Panel): bl_label = "Freestyle" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw_header(self, context): rd = context.scene.render @@ -111,7 +111,7 @@ class RENDER_MT_lineset_specials(Menu): class VIEWLAYER_PT_freestyle(ViewLayerFreestyleButtonsPanel, Panel): bl_label = "Freestyle" - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -167,7 +167,7 @@ class VIEWLAYER_PT_freestyle(ViewLayerFreestyleButtonsPanel, Panel): class VIEWLAYER_PT_freestyle_lineset(ViewLayerFreestyleEditorButtonsPanel, Panel): bl_label = "Freestyle Line Set" - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw_edge_type_buttons(self, box, lineset, edge_type): # property names @@ -261,7 +261,7 @@ class VIEWLAYER_PT_freestyle_lineset(ViewLayerFreestyleEditorButtonsPanel, Panel class VIEWLAYER_PT_freestyle_linestyle(ViewLayerFreestyleEditorButtonsPanel, Panel): bl_label = "Freestyle Line Style" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw_modifier_box_header(self, box, modifier): row = box.row() @@ -781,10 +781,7 @@ class VIEWLAYER_PT_freestyle_linestyle(ViewLayerFreestyleEditorButtonsPanel, Pan layout.separator() row = layout.row() - if scene.render.use_shading_nodes: - row.prop(linestyle, "use_nodes") - else: - row.prop(linestyle, "use_texture") + row.prop(linestyle, "use_nodes") row.prop(linestyle, "texture_spacing", text="Spacing Along Stroke") row = layout.row() @@ -818,7 +815,7 @@ class MaterialFreestyleButtonsPanel: class MATERIAL_PT_freestyle_line(MaterialFreestyleButtonsPanel, Panel): bl_label = "Freestyle Line" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout diff --git a/release/scripts/startup/bl_ui/properties_material.py b/release/scripts/startup/bl_ui/properties_material.py index 233a1c4369e..13c783ad024 100644 --- a/release/scripts/startup/bl_ui/properties_material.py +++ b/release/scripts/startup/bl_ui/properties_material.py @@ -23,42 +23,6 @@ from rna_prop_ui import PropertyPanel from bpy.app.translations import pgettext_iface as iface_ from bpy_extras.node_utils import find_node_input, find_output_node -def active_node_mat(mat): - # TODO, 2.4x has a pipeline section, for 2.5 we need to communicate - # which settings from node-materials are used - if mat is not None: - mat_node = mat.active_node_material - if mat_node: - return mat_node - else: - return mat - - return None - - -def check_material(mat): - if mat is not None: - if mat.use_nodes: - if mat.active_node_material is not None: - return True - return False - return True - return False - - -def simple_material(mat): - if (mat is not None) and (not mat.use_nodes): - return True - return False - - -class MATERIAL_MT_sss_presets(Menu): - bl_label = "SSS Presets" - preset_subdir = "sss" - preset_operator = "script.execute_preset" - draw = Menu.draw_preset - - class MATERIAL_MT_specials(Menu): bl_label = "Material Specials" @@ -82,12 +46,6 @@ class MATERIAL_UL_matslots(UIList): layout.prop(ma, "name", text="", emboss=False, icon_value=icon) else: layout.label(text="", icon_value=icon) - if ma and not context.scene.render.use_shading_nodes: - manode = ma.active_node_material - if manode: - layout.label(text=iface_("Node %s") % manode.name, translate=False, icon_value=layout.icon(manode)) - elif ma.use_nodes: - layout.label(text="Node <none>") elif self.layout_type == 'GRID': layout.alignment = 'CENTER' layout.label(text="", icon_value=icon) @@ -104,859 +62,16 @@ class MaterialButtonsPanel: return context.material and (context.engine in cls.COMPAT_ENGINES) -class MATERIAL_PT_context_material(MaterialButtonsPanel, Panel): - bl_label = "" - bl_options = {'HIDE_HEADER'} - COMPAT_ENGINES = {'BLENDER_RENDER'} - - @classmethod - def poll(cls, context): - # An exception, don't call the parent poll func because - # this manages materials for all engine types - - engine = context.engine - return (context.material or context.object) and (engine in cls.COMPAT_ENGINES) - - def draw(self, context): - layout = self.layout - - mat = context.material - ob = context.object - slot = context.material_slot - space = context.space_data - - if ob: - is_sortable = (len(ob.material_slots) > 1) - - rows = 1 - if is_sortable: - rows = 4 - - row = layout.row() - - row.template_list("MATERIAL_UL_matslots", "", ob, "material_slots", ob, "active_material_index", rows=rows) - - col = row.column(align=True) - col.operator("object.material_slot_add", icon='ZOOMIN', text="") - col.operator("object.material_slot_remove", icon='ZOOMOUT', text="") - - col.menu("MATERIAL_MT_specials", icon='DOWNARROW_HLT', text="") - - if is_sortable: - col.separator() - - col.operator("object.material_slot_move", icon='TRIA_UP', text="").direction = 'UP' - col.operator("object.material_slot_move", icon='TRIA_DOWN', text="").direction = 'DOWN' - - if ob.mode == 'EDIT': - row = layout.row(align=True) - row.operator("object.material_slot_assign", text="Assign") - row.operator("object.material_slot_select", text="Select") - row.operator("object.material_slot_deselect", text="Deselect") - - split = layout.split(percentage=0.65) - - if ob: - split.template_ID(ob, "active_material", new="material.new") - row = split.row() - if mat: - row.prop(mat, "use_nodes", icon='NODETREE', text="") - - if slot: - row.prop(slot, "link", text="") - else: - row.label() - elif mat: - split.template_ID(space, "pin_id") - split.separator() - - if mat: - layout.row().prop(mat, "type", expand=True) - if mat.use_nodes: - row = layout.row() - row.label(text="", icon='NODETREE') - if mat.active_node_material: - row.prop(mat.active_node_material, "name", text="") - else: - row.label(text="No material node selected") - - class MATERIAL_PT_preview(MaterialButtonsPanel, Panel): bl_label = "Preview" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_EEVEE'} def draw(self, context): self.layout.template_preview(context.material) -class MATERIAL_PT_pipeline(MaterialButtonsPanel, Panel): - bl_label = "Render Pipeline Options" - bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} - - @classmethod - def poll(cls, context): - mat = context.material - engine = context.engine - return mat and (not simple_material(mat)) and (mat.type in {'SURFACE', 'WIRE', 'VOLUME'}) and (engine in cls.COMPAT_ENGINES) - - def draw(self, context): - layout = self. layout - - mat = context.material - mat_type = mat.type in {'SURFACE', 'WIRE'} - - row = layout.row() - row.active = mat_type - row.prop(mat, "use_transparency") - sub = row.column() - sub.prop(mat, "offset_z") - - sub.active = mat_type and mat.use_transparency and mat.transparency_method == 'Z_TRANSPARENCY' - - row = layout.row() - row.active = mat.use_transparency or not mat_type - row.prop(mat, "transparency_method", expand=True) - - layout.separator() - - split = layout.split() - col = split.column() - - col.prop(mat, "use_raytrace") - col.prop(mat, "use_full_oversampling") - sub = col.column() - sub.active = mat_type - sub.prop(mat, "use_sky") - sub.prop(mat, "invert_z") - col.prop(mat, "pass_index") - - col = split.column() - col.active = mat_type - - col.prop(mat, "use_cast_shadows", text="Cast") - col.prop(mat, "use_cast_shadows_only", text="Cast Only") - col.prop(mat, "use_cast_buffer_shadows") - sub = col.column() - sub.active = mat.use_cast_buffer_shadows - sub.prop(mat, "shadow_cast_alpha", text="Casting Alpha") - col.prop(mat, "use_cast_approximate") - - -class MATERIAL_PT_diffuse(MaterialButtonsPanel, Panel): - bl_label = "Diffuse" - COMPAT_ENGINES = {'BLENDER_RENDER'} - - @classmethod - def poll(cls, context): - mat = context.material - engine = context.engine - return check_material(mat) and (mat.type in {'SURFACE', 'WIRE'}) and (engine in cls.COMPAT_ENGINES) - - def draw(self, context): - layout = self.layout - - mat = active_node_mat(context.material) - - split = layout.split() - - col = split.column() - col.prop(mat, "diffuse_color", text="") - sub = col.column() - sub.active = (not mat.use_shadeless) - sub.prop(mat, "diffuse_intensity", text="Intensity") - - col = split.column() - col.active = (not mat.use_shadeless) - col.prop(mat, "diffuse_shader", text="") - col.prop(mat, "use_diffuse_ramp", text="Ramp") - - col = layout.column() - col.active = (not mat.use_shadeless) - if mat.diffuse_shader == 'OREN_NAYAR': - col.prop(mat, "roughness") - elif mat.diffuse_shader == 'MINNAERT': - col.prop(mat, "darkness") - elif mat.diffuse_shader == 'TOON': - row = col.row() - row.prop(mat, "diffuse_toon_size", text="Size") - row.prop(mat, "diffuse_toon_smooth", text="Smooth") - elif mat.diffuse_shader == 'FRESNEL': - row = col.row() - row.prop(mat, "diffuse_fresnel", text="Fresnel") - row.prop(mat, "diffuse_fresnel_factor", text="Factor") - - if mat.use_diffuse_ramp: - col = layout.column() - col.active = (not mat.use_shadeless) - col.separator() - col.template_color_ramp(mat, "diffuse_ramp", expand=True) - col.separator() - - row = col.row() - row.prop(mat, "diffuse_ramp_input", text="Input") - row.prop(mat, "diffuse_ramp_blend", text="Blend") - - col.prop(mat, "diffuse_ramp_factor", text="Factor") - - -class MATERIAL_PT_specular(MaterialButtonsPanel, Panel): - bl_label = "Specular" - COMPAT_ENGINES = {'BLENDER_RENDER'} - - @classmethod - def poll(cls, context): - mat = context.material - engine = context.engine - return check_material(mat) and (mat.type in {'SURFACE', 'WIRE'}) and (engine in cls.COMPAT_ENGINES) - - def draw(self, context): - layout = self.layout - - mat = active_node_mat(context.material) - - layout.active = (not mat.use_shadeless) - - split = layout.split() - - col = split.column() - col.prop(mat, "specular_color", text="") - col.prop(mat, "specular_intensity", text="Intensity") - - col = split.column() - col.prop(mat, "specular_shader", text="") - col.prop(mat, "use_specular_ramp", text="Ramp") - - col = layout.column() - if mat.specular_shader in {'COOKTORR', 'PHONG'}: - col.prop(mat, "specular_hardness", text="Hardness") - elif mat.specular_shader == 'BLINN': - row = col.row() - row.prop(mat, "specular_hardness", text="Hardness") - row.prop(mat, "specular_ior", text="IOR") - elif mat.specular_shader == 'WARDISO': - col.prop(mat, "specular_slope", text="Slope") - elif mat.specular_shader == 'TOON': - row = col.row() - row.prop(mat, "specular_toon_size", text="Size") - row.prop(mat, "specular_toon_smooth", text="Smooth") - - if mat.use_specular_ramp: - layout.separator() - layout.template_color_ramp(mat, "specular_ramp", expand=True) - layout.separator() - - row = layout.row() - row.prop(mat, "specular_ramp_input", text="Input") - row.prop(mat, "specular_ramp_blend", text="Blend") - - layout.prop(mat, "specular_ramp_factor", text="Factor") - - -class MATERIAL_PT_shading(MaterialButtonsPanel, Panel): - bl_label = "Shading" - COMPAT_ENGINES = {'BLENDER_RENDER'} - - @classmethod - def poll(cls, context): - mat = context.material - engine = context.engine - return check_material(mat) and (mat.type in {'SURFACE', 'WIRE'}) and (engine in cls.COMPAT_ENGINES) - - def draw(self, context): - layout = self.layout - - mat = active_node_mat(context.material) - - if mat.type in {'SURFACE', 'WIRE'}: - split = layout.split() - - col = split.column() - sub = col.column() - sub.active = not mat.use_shadeless - sub.prop(mat, "emit") - sub.prop(mat, "ambient") - sub = col.column() - sub.prop(mat, "translucency") - - col = split.column() - col.prop(mat, "use_shadeless") - sub = col.column() - sub.active = not mat.use_shadeless - sub.prop(mat, "use_tangent_shading") - sub.prop(mat, "use_cubic") - - -class MATERIAL_PT_transp(MaterialButtonsPanel, Panel): - bl_label = "Transparency" - COMPAT_ENGINES = {'BLENDER_RENDER'} - - @classmethod - def poll(cls, context): - mat = context.material - engine = context.engine - return check_material(mat) and (mat.type in {'SURFACE', 'WIRE'}) and (engine in cls.COMPAT_ENGINES) - - def draw_header(self, context): - mat = context.material - - if simple_material(mat): - self.layout.prop(mat, "use_transparency", text="") - - def draw(self, context): - layout = self.layout - - base_mat = context.material - mat = active_node_mat(context.material) - rayt = mat.raytrace_transparency - - if simple_material(base_mat): - row = layout.row() - row.active = mat.use_transparency - row.prop(mat, "transparency_method", expand=True) - - split = layout.split() - split.active = base_mat.use_transparency - - col = split.column() - col.prop(mat, "alpha") - row = col.row() - row.active = (base_mat.transparency_method != 'MASK') and (not mat.use_shadeless) - row.prop(mat, "specular_alpha", text="Specular") - - col = split.column() - col.active = (not mat.use_shadeless) - col.prop(rayt, "fresnel") - sub = col.column() - sub.active = (rayt.fresnel > 0.0) - sub.prop(rayt, "fresnel_factor", text="Blend") - - if base_mat.transparency_method == 'RAYTRACE': - layout.separator() - split = layout.split() - split.active = base_mat.use_transparency - - col = split.column() - col.prop(rayt, "ior") - col.prop(rayt, "filter") - col.prop(rayt, "falloff") - col.prop(rayt, "depth_max") - col.prop(rayt, "depth") - - col = split.column() - col.label(text="Gloss:") - col.prop(rayt, "gloss_factor", text="Amount") - sub = col.column() - sub.active = rayt.gloss_factor < 1.0 - sub.prop(rayt, "gloss_threshold", text="Threshold") - sub.prop(rayt, "gloss_samples", text="Samples") - - -class MATERIAL_PT_mirror(MaterialButtonsPanel, Panel): - bl_label = "Mirror" - bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} - - @classmethod - def poll(cls, context): - mat = context.material - engine = context.engine - return check_material(mat) and (mat.type in {'SURFACE', 'WIRE'}) and (engine in cls.COMPAT_ENGINES) - - def draw_header(self, context): - raym = active_node_mat(context.material).raytrace_mirror - - self.layout.prop(raym, "use", text="") - - def draw(self, context): - layout = self.layout - - mat = active_node_mat(context.material) - raym = mat.raytrace_mirror - - layout.active = raym.use - - split = layout.split() - - col = split.column() - col.prop(raym, "reflect_factor") - col.prop(mat, "mirror_color", text="") - - col = split.column() - col.prop(raym, "fresnel") - sub = col.column() - sub.active = (raym.fresnel > 0.0) - sub.prop(raym, "fresnel_factor", text="Blend") - - split = layout.split() - - col = split.column() - col.separator() - col.prop(raym, "depth") - col.prop(raym, "distance", text="Max Dist") - col.separator() - sub = col.split(percentage=0.4) - sub.active = (raym.distance > 0.0) - sub.label(text="Fade To:") - sub.prop(raym, "fade_to", text="") - - col = split.column() - col.label(text="Gloss:") - col.prop(raym, "gloss_factor", text="Amount") - sub = col.column() - sub.active = (raym.gloss_factor < 1.0) - sub.prop(raym, "gloss_threshold", text="Threshold") - sub.prop(raym, "gloss_samples", text="Samples") - sub.prop(raym, "gloss_anisotropic", text="Anisotropic") - - -class MATERIAL_PT_sss(MaterialButtonsPanel, Panel): - bl_label = "Subsurface Scattering" - bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} - - @classmethod - def poll(cls, context): - mat = context.material - engine = context.engine - return check_material(mat) and (mat.type in {'SURFACE', 'WIRE'}) and (engine in cls.COMPAT_ENGINES) - - def draw_header(self, context): - mat = active_node_mat(context.material) - sss = mat.subsurface_scattering - - self.layout.active = (not mat.use_shadeless) - self.layout.prop(sss, "use", text="") - - def draw(self, context): - layout = self.layout - - mat = active_node_mat(context.material) - sss = mat.subsurface_scattering - - layout.active = (sss.use) and (not mat.use_shadeless) - - row = layout.row().split() - sub = row.row(align=True).split(align=True, percentage=0.75) - sub.menu("MATERIAL_MT_sss_presets", text=bpy.types.MATERIAL_MT_sss_presets.bl_label) - sub.operator("material.sss_preset_add", text="", icon='ZOOMIN') - sub.operator("material.sss_preset_add", text="", icon='ZOOMOUT').remove_active = True - - split = layout.split() - - col = split.column() - col.prop(sss, "ior") - col.prop(sss, "scale") - col.prop(sss, "color", text="") - col.prop(sss, "radius", text="RGB Radius", expand=True) - - col = split.column() - sub = col.column(align=True) - sub.label(text="Blend:") - sub.prop(sss, "color_factor", text="Color") - sub.prop(sss, "texture_factor", text="Texture") - sub.label(text="Scattering Weight:") - sub.prop(sss, "front") - sub.prop(sss, "back") - col.separator() - col.prop(sss, "error_threshold", text="Error") - - -class MATERIAL_PT_halo(MaterialButtonsPanel, Panel): - bl_label = "Halo" - COMPAT_ENGINES = {'BLENDER_RENDER'} - - @classmethod - def poll(cls, context): - mat = context.material - engine = context.engine - return mat and (mat.type == 'HALO') and (engine in cls.COMPAT_ENGINES) - - def draw(self, context): - layout = self.layout - - mat = context.material # don't use node material - halo = mat.halo - - def number_but(layout, toggle, number, name, color): - row = layout.row(align=True) - row.prop(halo, toggle, text="") - sub = row.column(align=True) - sub.active = getattr(halo, toggle) - sub.prop(halo, number, text=name, translate=False) - if not color == "": - sub.prop(mat, color, text="") - - split = layout.split() - - col = split.column() - col.prop(mat, "alpha") - col.prop(mat, "diffuse_color", text="") - col.prop(halo, "seed") - - col = split.column() - col.prop(halo, "size") - col.prop(halo, "hardness") - col.prop(halo, "add") - - layout.label(text="Options:") - - split = layout.split() - col = split.column() - col.prop(halo, "use_texture") - col.prop(halo, "use_vertex_normal") - col.prop(halo, "use_extreme_alpha") - col.prop(halo, "use_shaded") - col.prop(halo, "use_soft") - - col = split.column() - number_but(col, "use_ring", "ring_count", iface_("Rings"), "mirror_color") - number_but(col, "use_lines", "line_count", iface_("Lines"), "specular_color") - number_but(col, "use_star", "star_tip_count", iface_("Star Tips"), "") - - -class MATERIAL_PT_flare(MaterialButtonsPanel, Panel): - bl_label = "Flare" - COMPAT_ENGINES = {'BLENDER_RENDER'} - - @classmethod - def poll(cls, context): - mat = context.material - engine = context.engine - return mat and (mat.type == 'HALO') and (engine in cls.COMPAT_ENGINES) - - def draw_header(self, context): - halo = context.material.halo - - self.layout.prop(halo, "use_flare_mode", text="") - - def draw(self, context): - layout = self.layout - - mat = context.material # don't use node material - halo = mat.halo - - layout.active = halo.use_flare_mode - - split = layout.split() - - col = split.column() - col.prop(halo, "flare_size", text="Size") - col.prop(halo, "flare_boost", text="Boost") - col.prop(halo, "flare_seed", text="Seed") - - col = split.column() - col.prop(halo, "flare_subflare_count", text="Subflares") - col.prop(halo, "flare_subflare_size", text="Subsize") - - -class MATERIAL_PT_strand(MaterialButtonsPanel, Panel): - bl_label = "Strand" - bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} - - @classmethod - def poll(cls, context): - mat = context.material - engine = context.engine - return mat and (mat.type in {'SURFACE', 'WIRE', 'HALO'}) and (engine in cls.COMPAT_ENGINES) - - def draw(self, context): - layout = self.layout - - mat = context.material # don't use node material - tan = mat.strand - - split = layout.split() - - col = split.column() - sub = col.column(align=True) - sub.label(text="Size:") - sub.prop(tan, "root_size", text="Root") - sub.prop(tan, "tip_size", text="Tip") - sub.prop(tan, "size_min", text="Minimum") - sub.prop(tan, "use_blender_units") - sub = col.column() - sub.active = (not mat.use_shadeless) - sub.prop(tan, "use_tangent_shading") - col.prop(tan, "shape") - - col = split.column() - col.label(text="Shading:") - col.prop(tan, "width_fade") - ob = context.object - if ob and ob.type == 'MESH': - col.prop_search(tan, "uv_layer", ob.data, "uv_layers", text="") - else: - col.prop(tan, "uv_layer", text="") - col.separator() - sub = col.column() - sub.active = (not mat.use_shadeless) - sub.label("Surface diffuse:") - sub = col.column() - sub.prop(tan, "blend_distance", text="Distance") - - -class MATERIAL_PT_options(MaterialButtonsPanel, Panel): - bl_label = "Options" - COMPAT_ENGINES = {'BLENDER_RENDER'} - - @classmethod - def poll(cls, context): - mat = context.material - engine = context.engine - return check_material(mat) and (mat.type in {'SURFACE', 'WIRE'}) and (engine in cls.COMPAT_ENGINES) - - def draw(self, context): - layout = self.layout - - base_mat = context.material - mat = active_node_mat(base_mat) - - split = layout.split() - - col = split.column() - if simple_material(base_mat): - col.prop(mat, "use_raytrace") - col.prop(mat, "use_full_oversampling") - col.prop(mat, "use_sky") - col.prop(mat, "use_mist") - if simple_material(base_mat): - col.prop(mat, "invert_z") - sub = col.row() - sub.prop(mat, "offset_z") - sub.active = mat.use_transparency and mat.transparency_method == 'Z_TRANSPARENCY' - sub = col.column(align=True) - sub.label(text="Light Group:") - sub.prop(mat, "light_group", text="") - row = sub.row(align=True) - row.active = bool(mat.light_group) - row.prop(mat, "use_light_group_exclusive", text="Exclusive") - row.prop(mat, "use_light_group_local", text="Local") - - col = split.column() - col.prop(mat, "use_vertex_color_paint") - col.prop(mat, "use_vertex_color_light") - col.prop(mat, "use_object_color") - col.prop(mat, "use_uv_project") - if simple_material(base_mat): - col.prop(mat, "pass_index") - - col.label("Edit Image") - col.template_ID(mat, "edit_image") - - -class MATERIAL_PT_shadow(MaterialButtonsPanel, Panel): - bl_label = "Shadow" - bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} - - @classmethod - def poll(cls, context): - mat = context.material - engine = context.engine - return check_material(mat) and (mat.type in {'SURFACE', 'WIRE'}) and (engine in cls.COMPAT_ENGINES) - - def draw(self, context): - layout = self.layout - - base_mat = context.material - mat = active_node_mat(base_mat) - - split = layout.split() - - col = split.column() - col.prop(mat, "use_shadows", text="Receive") - col.prop(mat, "use_transparent_shadows", text="Receive Transparent") - col.prop(mat, "use_only_shadow", text="Shadows Only") - sub = col.column() - sub.active = mat.use_only_shadow - sub.prop(mat, "shadow_only_type", text="") - - if not simple_material(base_mat): - col = split.column() - - col.prop(mat, "use_ray_shadow_bias", text="Auto Ray Bias") - sub = col.column() - sub.active = (not mat.use_ray_shadow_bias) - sub.prop(mat, "shadow_ray_bias", text="Ray Bias") - - if simple_material(base_mat): - col = split.column() - - col.prop(mat, "use_cast_shadows", text="Cast") - col.prop(mat, "use_cast_shadows_only", text="Cast Only") - col.prop(mat, "use_cast_buffer_shadows") - sub = col.column() - sub.active = mat.use_cast_buffer_shadows - if simple_material(base_mat): - sub.prop(mat, "shadow_cast_alpha", text="Casting Alpha") - sub.prop(mat, "shadow_buffer_bias", text="Buffer Bias") - if simple_material(base_mat): - col.prop(mat, "use_cast_approximate") - - -class VolumeButtonsPanel: - bl_space_type = 'PROPERTIES' - bl_region_type = 'WINDOW' - bl_context = "material" - COMPAT_ENGINES = {'BLENDER_RENDER'} - - @classmethod - def poll(cls, context): - mat = context.material - engine = context.engine - return mat and (mat.type == 'VOLUME') and (engine in cls.COMPAT_ENGINES) - - -class MATERIAL_PT_volume_density(VolumeButtonsPanel, Panel): - bl_label = "Density" - COMPAT_ENGINES = {'BLENDER_RENDER'} - - def draw(self, context): - layout = self.layout - - vol = context.material.volume # don't use node material - - row = layout.row() - row.prop(vol, "density") - row.prop(vol, "density_scale") - - -class MATERIAL_PT_volume_shading(VolumeButtonsPanel, Panel): - bl_label = "Shading" - COMPAT_ENGINES = {'BLENDER_RENDER'} - - def draw(self, context): - layout = self.layout - - vol = context.material.volume # don't use node material - - split = layout.split() - - col = split.column() - col.prop(vol, "scattering") - col.prop(vol, "asymmetry") - col.prop(vol, "transmission_color") - - col = split.column() - sub = col.column(align=True) - sub.prop(vol, "emission") - sub.prop(vol, "emission_color", text="") - sub = col.column(align=True) - sub.prop(vol, "reflection") - sub.prop(vol, "reflection_color", text="") - - -class MATERIAL_PT_volume_lighting(VolumeButtonsPanel, Panel): - bl_label = "Lighting" - COMPAT_ENGINES = {'BLENDER_RENDER'} - - def draw(self, context): - layout = self.layout - - vol = context.material.volume # don't use node material - - split = layout.split() - - col = split.column() - col.prop(vol, "light_method", text="") - - col = split.column() - - if vol.light_method == 'SHADED': - col.prop(vol, "use_external_shadows") - col.prop(vol, "use_light_cache") - sub = col.column() - sub.active = vol.use_light_cache - sub.prop(vol, "cache_resolution") - elif vol.light_method in {'MULTIPLE_SCATTERING', 'SHADED_PLUS_MULTIPLE_SCATTERING'}: - sub = col.column() - sub.enabled = True - sub.active = False - sub.label("Light Cache Enabled") - col.prop(vol, "cache_resolution") - - sub = col.column(align=True) - sub.prop(vol, "ms_diffusion") - sub.prop(vol, "ms_spread") - sub.prop(vol, "ms_intensity") - - -class MATERIAL_PT_volume_transp(VolumeButtonsPanel, Panel): - bl_label = "Transparency" - COMPAT_ENGINES = {'BLENDER_RENDER'} - - @classmethod - def poll(cls, context): - mat = context.material - engine = context.engine - return mat and simple_material(mat) and (mat.type == 'VOLUME') and (engine in cls.COMPAT_ENGINES) - - def draw(self, context): - layout = self.layout - - mat = context.material # don't use node material - - layout.row().prop(mat, "transparency_method", expand=True) - - -class MATERIAL_PT_volume_integration(VolumeButtonsPanel, Panel): - bl_label = "Integration" - COMPAT_ENGINES = {'BLENDER_RENDER'} - - def draw(self, context): - layout = self.layout - - vol = context.material.volume # don't use node material - - split = layout.split() - - col = split.column() - col.label(text="Step Calculation:") - col.prop(vol, "step_method", text="") - col = col.column(align=True) - col.prop(vol, "step_size") - - col = split.column() - col.label() - col.prop(vol, "depth_threshold") - - -class MATERIAL_PT_volume_options(VolumeButtonsPanel, Panel): - bl_label = "Options" - COMPAT_ENGINES = {'BLENDER_RENDER'} - bl_options = {'DEFAULT_CLOSED'} - - @classmethod - def poll(cls, context): - mat = context.material - engine = context.engine - return check_material(mat) and (mat.type == 'VOLUME') and (engine in cls.COMPAT_ENGINES) - - def draw(self, context): - layout = self.layout - - mat = active_node_mat(context.material) - - split = layout.split() - - col = split.column() - if simple_material(context.material): - col.prop(mat, "use_raytrace") - col.prop(mat, "use_full_oversampling") - col.prop(mat, "use_mist") - - col = split.column() - col.label(text="Light Group:") - col.prop(mat, "light_group", text="") - row = col.row() - row.active = bool(mat.light_group) - row.prop(mat, "use_light_group_exclusive", text="Exclusive") - - class MATERIAL_PT_custom_props(MaterialButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_EEVEE'} _context_path = "material" _property_type = bpy.types.Material @@ -1101,29 +216,9 @@ class EEVEE_MATERIAL_PT_options(MaterialButtonsPanel, Panel): classes = ( - MATERIAL_MT_sss_presets, MATERIAL_MT_specials, MATERIAL_UL_matslots, - MATERIAL_PT_context_material, MATERIAL_PT_preview, - MATERIAL_PT_pipeline, - MATERIAL_PT_diffuse, - MATERIAL_PT_specular, - MATERIAL_PT_shading, - MATERIAL_PT_transp, - MATERIAL_PT_mirror, - MATERIAL_PT_sss, - MATERIAL_PT_halo, - MATERIAL_PT_flare, - MATERIAL_PT_strand, - MATERIAL_PT_options, - MATERIAL_PT_shadow, - MATERIAL_PT_volume_density, - MATERIAL_PT_volume_shading, - MATERIAL_PT_volume_lighting, - MATERIAL_PT_volume_transp, - MATERIAL_PT_volume_integration, - MATERIAL_PT_volume_options, MATERIAL_PT_custom_props, EEVEE_MATERIAL_PT_context_material, EEVEE_MATERIAL_PT_surface, diff --git a/release/scripts/startup/bl_ui/properties_particle.py b/release/scripts/startup/bl_ui/properties_particle.py index 4a446ac5f48..b6f7cfe3e84 100644 --- a/release/scripts/startup/bl_ui/properties_particle.py +++ b/release/scripts/startup/bl_ui/properties_particle.py @@ -1396,6 +1396,38 @@ class PARTICLE_PT_vertexgroups(ParticleButtonsPanel, Panel): # row.prop(psys, "invert_vertex_group_field", text="") +class PARTICLE_PT_textures(ParticleButtonsPanel, Panel): + bl_label = "Textures" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} + + @classmethod + def poll(cls, context): + if context.particle_system is None: + return False + return particle_panel_poll(cls, context) + + def draw(self, context): + layout = self.layout + + psys = context.particle_system + part = psys.settings + + row = layout.row() + row.template_list("TEXTURE_UL_texslots", "", part, "texture_slots", part, "active_texture_index", rows=2) + + col = row.column(align=True) + col.operator("texture.slot_move", text="", icon='TRIA_UP').type = 'UP' + col.operator("texture.slot_move", text="", icon='TRIA_DOWN').type = 'DOWN' + col.menu("TEXTURE_MT_specials", icon='DOWNARROW_HLT', text="") + + if not part.active_texture: + layout.template_ID(part, "active_texture", new="texture.new") + else: + slot = part.texture_slots[part.active_texture_index] + layout.template_ID(slot, "texture", new="texture.new") + + class PARTICLE_PT_custom_props(ParticleButtonsPanel, PropertyPanel, Panel): COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'} _context_path = "particle_system.settings" @@ -1420,6 +1452,7 @@ classes = ( PARTICLE_PT_field_weights, PARTICLE_PT_force_fields, PARTICLE_PT_vertexgroups, + PARTICLE_PT_textures, PARTICLE_PT_custom_props, ) diff --git a/release/scripts/startup/bl_ui/properties_physics_cloth.py b/release/scripts/startup/bl_ui/properties_physics_cloth.py index 1528899a4de..e0d0327324b 100644 --- a/release/scripts/startup/bl_ui/properties_physics_cloth.py +++ b/release/scripts/startup/bl_ui/properties_physics_cloth.py @@ -50,7 +50,7 @@ class PhysicButtonsPanel: class PHYSICS_PT_cloth(PhysicButtonsPanel, Panel): bl_label = "Cloth" - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -134,7 +134,7 @@ class PHYSICS_PT_cloth(PhysicButtonsPanel, Panel): class PHYSICS_PT_cloth_cache(PhysicButtonsPanel, Panel): bl_label = "Cloth Cache" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw(self, context): md = context.cloth @@ -144,7 +144,7 @@ class PHYSICS_PT_cloth_cache(PhysicButtonsPanel, Panel): class PHYSICS_PT_cloth_collision(PhysicButtonsPanel, Panel): bl_label = "Cloth Collision" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw_header(self, context): cloth = context.cloth.collision_settings @@ -184,7 +184,7 @@ class PHYSICS_PT_cloth_collision(PhysicButtonsPanel, Panel): class PHYSICS_PT_cloth_stiffness(PhysicButtonsPanel, Panel): bl_label = "Cloth Stiffness Scaling" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw_header(self, context): cloth = context.cloth.settings @@ -217,7 +217,7 @@ class PHYSICS_PT_cloth_stiffness(PhysicButtonsPanel, Panel): class PHYSICS_PT_cloth_sewing(PhysicButtonsPanel, Panel): bl_label = "Cloth Sewing Springs" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw_header(self, context): cloth = context.cloth.settings @@ -251,7 +251,7 @@ class PHYSICS_PT_cloth_sewing(PhysicButtonsPanel, Panel): class PHYSICS_PT_cloth_field_weights(PhysicButtonsPanel, Panel): bl_label = "Cloth Field Weights" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw(self, context): cloth = context.cloth.settings diff --git a/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py b/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py index e1c0606c493..476a448f978 100644 --- a/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py +++ b/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py @@ -60,7 +60,7 @@ class PhysicButtonsPanel: class PHYSICS_PT_dynamic_paint(PhysicButtonsPanel, Panel): bl_label = "Dynamic Paint" - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -108,7 +108,6 @@ class PHYSICS_PT_dynamic_paint(PhysicButtonsPanel, Panel): elif md.ui_type == 'BRUSH': brush = md.brush_settings - use_shading_nodes = context.scene.render.use_shading_nodes if brush is None: layout.operator("dpaint.type_toggle", text="Add Brush").type = 'BRUSH' @@ -123,21 +122,13 @@ class PHYSICS_PT_dynamic_paint(PhysicButtonsPanel, Panel): col.prop(brush, "paint_wetness", text="Wetness") col = split.column() - if not use_shading_nodes: - sub = col.column() - sub.active = (brush.paint_source != 'PARTICLE_SYSTEM') - sub.prop(brush, "use_material") - if brush.use_material and brush.paint_source != 'PARTICLE_SYSTEM' and not use_shading_nodes: - col.prop(brush, "material", text="") - col.prop(brush, "paint_alpha", text="Alpha Factor") - else: - col.prop(brush, "paint_color", text="") - col.prop(brush, "paint_alpha", text="Alpha") + col.prop(brush, "paint_color", text="") + col.prop(brush, "paint_alpha", text="Alpha") class PHYSICS_PT_dp_advanced_canvas(PhysicButtonsPanel, Panel): bl_label = "Dynamic Paint Advanced" - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): @@ -213,7 +204,7 @@ class PHYSICS_PT_dp_advanced_canvas(PhysicButtonsPanel, Panel): class PHYSICS_PT_dp_canvas_output(PhysicButtonsPanel, Panel): bl_label = "Dynamic Paint Output" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): @@ -306,7 +297,7 @@ class PHYSICS_PT_dp_canvas_output(PhysicButtonsPanel, Panel): class PHYSICS_PT_dp_canvas_initial_color(PhysicButtonsPanel, Panel): bl_label = "Dynamic Paint Initial Color" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): @@ -342,7 +333,7 @@ class PHYSICS_PT_dp_canvas_initial_color(PhysicButtonsPanel, Panel): class PHYSICS_PT_dp_effects(PhysicButtonsPanel, Panel): bl_label = "Dynamic Paint Effects" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): @@ -391,7 +382,7 @@ class PHYSICS_PT_dp_effects(PhysicButtonsPanel, Panel): class PHYSICS_PT_dp_cache(PhysicButtonsPanel, Panel): bl_label = "Dynamic Paint Cache" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): @@ -412,7 +403,7 @@ class PHYSICS_PT_dp_cache(PhysicButtonsPanel, Panel): class PHYSICS_PT_dp_brush_source(PhysicButtonsPanel, Panel): bl_label = "Dynamic Paint Source" - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): @@ -465,7 +456,7 @@ class PHYSICS_PT_dp_brush_source(PhysicButtonsPanel, Panel): class PHYSICS_PT_dp_brush_velocity(PhysicButtonsPanel, Panel): bl_label = "Dynamic Paint Velocity" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): @@ -501,7 +492,7 @@ class PHYSICS_PT_dp_brush_velocity(PhysicButtonsPanel, Panel): class PHYSICS_PT_dp_brush_wave(PhysicButtonsPanel, Panel): bl_label = "Dynamic Paint Waves" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): diff --git a/release/scripts/startup/bl_ui/properties_physics_fluid.py b/release/scripts/startup/bl_ui/properties_physics_fluid.py index 80ad9e358c3..93f1d28e536 100644 --- a/release/scripts/startup/bl_ui/properties_physics_fluid.py +++ b/release/scripts/startup/bl_ui/properties_physics_fluid.py @@ -42,7 +42,7 @@ class PhysicButtonsPanel: class PHYSICS_PT_fluid(PhysicButtonsPanel, Panel): bl_label = "Fluid" - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -205,7 +205,7 @@ class PHYSICS_PT_fluid(PhysicButtonsPanel, Panel): class PHYSICS_PT_domain_gravity(PhysicButtonsPanel, Panel): bl_label = "Fluid World" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): @@ -258,7 +258,7 @@ class PHYSICS_PT_domain_gravity(PhysicButtonsPanel, Panel): class PHYSICS_PT_domain_boundary(PhysicButtonsPanel, Panel): bl_label = "Fluid Boundary" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): @@ -288,7 +288,7 @@ class PHYSICS_PT_domain_boundary(PhysicButtonsPanel, Panel): class PHYSICS_PT_domain_particles(PhysicButtonsPanel, Panel): bl_label = "Fluid Particles" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): diff --git a/release/scripts/startup/bl_ui/properties_physics_rigidbody.py b/release/scripts/startup/bl_ui/properties_physics_rigidbody.py index 21453ff3642..817b0ab76ed 100644 --- a/release/scripts/startup/bl_ui/properties_physics_rigidbody.py +++ b/release/scripts/startup/bl_ui/properties_physics_rigidbody.py @@ -29,7 +29,7 @@ class PHYSICS_PT_rigidbody_panel: class PHYSICS_PT_rigid_body(PHYSICS_PT_rigidbody_panel, Panel): bl_label = "Rigid Body" - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): @@ -56,7 +56,7 @@ class PHYSICS_PT_rigid_body(PHYSICS_PT_rigidbody_panel, Panel): class PHYSICS_PT_rigid_body_collisions(PHYSICS_PT_rigidbody_panel, Panel): bl_label = "Rigid Body Collisions" - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): @@ -101,7 +101,7 @@ class PHYSICS_PT_rigid_body_collisions(PHYSICS_PT_rigidbody_panel, Panel): class PHYSICS_PT_rigid_body_dynamics(PHYSICS_PT_rigidbody_panel, Panel): bl_label = "Rigid Body Dynamics" bl_default_closed = True - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): diff --git a/release/scripts/startup/bl_ui/properties_physics_rigidbody_constraint.py b/release/scripts/startup/bl_ui/properties_physics_rigidbody_constraint.py index 90d3b3da057..aca989fd0ba 100644 --- a/release/scripts/startup/bl_ui/properties_physics_rigidbody_constraint.py +++ b/release/scripts/startup/bl_ui/properties_physics_rigidbody_constraint.py @@ -29,7 +29,7 @@ class PHYSICS_PT_rigidbody_constraint_panel: class PHYSICS_PT_rigid_body_constraint(PHYSICS_PT_rigidbody_constraint_panel, Panel): bl_label = "Rigid Body Constraint" - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): diff --git a/release/scripts/startup/bl_ui/properties_physics_softbody.py b/release/scripts/startup/bl_ui/properties_physics_softbody.py index 101a1528c7e..86b9a95e294 100644 --- a/release/scripts/startup/bl_ui/properties_physics_softbody.py +++ b/release/scripts/startup/bl_ui/properties_physics_softbody.py @@ -46,7 +46,7 @@ class PhysicButtonsPanel: class PHYSICS_PT_softbody(PhysicButtonsPanel, Panel): bl_label = "Soft Body" - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -76,7 +76,7 @@ class PHYSICS_PT_softbody(PhysicButtonsPanel, Panel): class PHYSICS_PT_softbody_cache(PhysicButtonsPanel, Panel): bl_label = "Soft Body Cache" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw(self, context): md = context.soft_body @@ -86,7 +86,7 @@ class PHYSICS_PT_softbody_cache(PhysicButtonsPanel, Panel): class PHYSICS_PT_softbody_goal(PhysicButtonsPanel, Panel): bl_label = "Soft Body Goal" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw_header(self, context): softbody = context.soft_body.settings @@ -126,7 +126,7 @@ class PHYSICS_PT_softbody_goal(PhysicButtonsPanel, Panel): class PHYSICS_PT_softbody_edge(PhysicButtonsPanel, Panel): bl_label = "Soft Body Edges" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw_header(self, context): softbody = context.soft_body.settings @@ -176,7 +176,7 @@ class PHYSICS_PT_softbody_edge(PhysicButtonsPanel, Panel): class PHYSICS_PT_softbody_collision(PhysicButtonsPanel, Panel): bl_label = "Soft Body Self Collision" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw_header(self, context): softbody = context.soft_body.settings @@ -205,7 +205,7 @@ class PHYSICS_PT_softbody_collision(PhysicButtonsPanel, Panel): class PHYSICS_PT_softbody_solver(PhysicButtonsPanel, Panel): bl_label = "Soft Body Solver" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -238,7 +238,7 @@ class PHYSICS_PT_softbody_solver(PhysicButtonsPanel, Panel): class PHYSICS_PT_softbody_field_weights(PhysicButtonsPanel, Panel): bl_label = "Soft Body Field Weights" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw(self, context): md = context.soft_body diff --git a/release/scripts/startup/bl_ui/properties_render.py b/release/scripts/startup/bl_ui/properties_render.py index 779a77cf7ca..10c823cc0a0 100644 --- a/release/scripts/startup/bl_ui/properties_render.py +++ b/release/scripts/startup/bl_ui/properties_render.py @@ -193,129 +193,6 @@ class RENDER_PT_dimensions(RenderButtonsPanel, Panel): subrow.prop(rd, "frame_map_new", text="New") -class RENDER_PT_antialiasing(RenderButtonsPanel, Panel): - bl_label = "Anti-Aliasing" - COMPAT_ENGINES = {'BLENDER_RENDER'} - - def draw_header(self, context): - rd = context.scene.render - - self.layout.prop(rd, "use_antialiasing", text="") - - def draw(self, context): - layout = self.layout - - rd = context.scene.render - layout.active = rd.use_antialiasing - - split = layout.split() - - col = split.column() - col.row().prop(rd, "antialiasing_samples", expand=True) - sub = col.row() - sub.prop(rd, "use_full_sample") - - col = split.column() - col.prop(rd, "pixel_filter_type", text="") - col.prop(rd, "filter_size", text="Size") - - -class RENDER_PT_motion_blur(RenderButtonsPanel, Panel): - bl_label = "Sampled Motion Blur" - bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} - - @classmethod - def poll(cls, context): - rd = context.scene.render - return not rd.use_full_sample and (context.engine in cls.COMPAT_ENGINES) - - def draw_header(self, context): - rd = context.scene.render - - self.layout.prop(rd, "use_motion_blur", text="") - - def draw(self, context): - layout = self.layout - - rd = context.scene.render - layout.active = rd.use_motion_blur - - row = layout.row() - row.prop(rd, "motion_blur_samples") - row.prop(rd, "motion_blur_shutter") - - -class RENDER_PT_shading(RenderButtonsPanel, Panel): - bl_label = "Shading" - bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} - - def draw(self, context): - layout = self.layout - - rd = context.scene.render - - split = layout.split() - - col = split.column() - col.prop(rd, "use_textures", text="Textures") - col.prop(rd, "use_shadows", text="Shadows") - col.prop(rd, "use_sss", text="Subsurface Scattering") - col.prop(rd, "use_envmaps", text="Environment Map") - - col = split.column() - col.prop(rd, "use_raytrace", text="Ray Tracing") - col.prop(rd, "alpha_mode", text="Alpha") - col.prop(rd, "use_world_space_shading", text="World Space Shading") - - -class RENDER_PT_performance(RenderButtonsPanel, Panel): - bl_label = "Performance" - bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} - - def draw(self, context): - layout = self.layout - - rd = context.scene.render - - split = layout.split() - - col = split.column(align=True) - col.label(text="Threads:") - col.row(align=True).prop(rd, "threads_mode", expand=True) - sub = col.column(align=True) - sub.enabled = rd.threads_mode == 'FIXED' - sub.prop(rd, "threads") - - col.label(text="Tile Size:") - col.prop(rd, "tile_x", text="X") - col.prop(rd, "tile_y", text="Y") - - col.separator() - col.prop(rd, "preview_start_resolution") - col.prop(rd, "preview_pixel_size", text="") - - col = split.column() - col.label(text="Memory:") - sub = col.column() - sub.enabled = not rd.use_full_sample - sub.prop(rd, "use_save_buffers") - sub = col.column() - sub.active = rd.use_compositing - sub.prop(rd, "use_free_image_textures") - sub = col.column() - sub.active = rd.use_raytrace - sub.label(text="Acceleration Structure:") - sub.prop(rd, "raytrace_method", text="") - if rd.raytrace_method == 'OCTREE': - sub.prop(rd, "octree_resolution", text="Resolution") - else: - sub.prop(rd, "use_instances", text="Instances") - sub.prop(rd, "use_local_coords", text="Local Coordinates") - - class RENDER_PT_post_processing(RenderButtonsPanel, Panel): bl_label = "Post Processing" bl_options = {'DEFAULT_CLOSED'} @@ -438,7 +315,7 @@ class RENDER_PT_output(RenderButtonsPanel, Panel): class RENDER_PT_encoding(RenderButtonsPanel, Panel): bl_label = "Encoding" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): @@ -517,77 +394,6 @@ class RENDER_PT_encoding(RenderButtonsPanel, Panel): col.prop(ffmpeg, "packetsize", text="Packet Size") -class RENDER_PT_bake(RenderButtonsPanel, Panel): - bl_label = "Bake" - bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} - - def draw(self, context): - layout = self.layout - - rd = context.scene.render - - layout.operator("object.bake_image", icon='RENDER_STILL') - - layout.prop(rd, "bake_type") - - multires_bake = False - if rd.bake_type in ['NORMALS', 'DISPLACEMENT', 'DERIVATIVE', 'AO']: - layout.prop(rd, "use_bake_multires") - multires_bake = rd.use_bake_multires - - if not multires_bake: - if rd.bake_type == 'NORMALS': - layout.prop(rd, "bake_normal_space") - elif rd.bake_type in {'DISPLACEMENT', 'AO'}: - layout.prop(rd, "use_bake_normalize") - - # col.prop(rd, "bake_aa_mode") - # col.prop(rd, "use_bake_antialiasing") - - layout.separator() - - split = layout.split() - - col = split.column() - col.prop(rd, "use_bake_to_vertex_color") - sub = col.column() - sub.active = not rd.use_bake_to_vertex_color - sub.prop(rd, "use_bake_clear") - sub.prop(rd, "bake_margin") - sub.prop(rd, "bake_quad_split", text="Split") - - col = split.column() - col.prop(rd, "use_bake_selected_to_active") - sub = col.column() - sub.active = rd.use_bake_selected_to_active - sub.prop(rd, "bake_distance") - sub.prop(rd, "bake_bias") - else: - split = layout.split() - - col = split.column() - col.prop(rd, "use_bake_clear") - col.prop(rd, "bake_margin") - - if rd.bake_type == 'DISPLACEMENT': - col = split.column() - col.prop(rd, "use_bake_lores_mesh") - - if rd.bake_type == 'AO': - col = split.column() - col.prop(rd, "bake_bias") - col.prop(rd, "bake_samples") - - if rd.bake_type == 'DERIVATIVE': - row = layout.row() - row.prop(rd, "use_bake_user_scale", text="") - - sub = row.column() - sub.active = rd.use_bake_user_scale - sub.prop(rd, "bake_user_scale", text="User Scale") - - class RENDER_PT_clay_layer_settings(RenderButtonsPanel, Panel): bl_label = "Clay Layer Settings" COMPAT_ENGINES = {'BLENDER_CLAY'} @@ -905,15 +711,10 @@ classes = ( RENDER_PT_context, RENDER_PT_render, RENDER_PT_dimensions, - RENDER_PT_antialiasing, - RENDER_PT_motion_blur, - RENDER_PT_shading, - RENDER_PT_performance, RENDER_PT_post_processing, RENDER_PT_stamp, RENDER_PT_output, RENDER_PT_encoding, - RENDER_PT_bake, RENDER_PT_clay_layer_settings, RENDER_PT_clay_collection_settings, RENDER_PT_eevee_sampling, diff --git a/release/scripts/startup/bl_ui/properties_scene.py b/release/scripts/startup/bl_ui/properties_scene.py index 79a7113374b..094f2a9dc31 100644 --- a/release/scripts/startup/bl_ui/properties_scene.py +++ b/release/scripts/startup/bl_ui/properties_scene.py @@ -308,7 +308,7 @@ class SCENE_PT_audio(SceneButtonsPanel, Panel): class SCENE_PT_physics(SceneButtonsPanel, Panel): bl_label = "Gravity" - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw_header(self, context): self.layout.prop(context.scene, "use_gravity", text="") @@ -325,7 +325,7 @@ class SCENE_PT_physics(SceneButtonsPanel, Panel): class SCENE_PT_rigid_body_world(SceneButtonsPanel, Panel): bl_label = "Rigid Body World" - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): @@ -370,7 +370,7 @@ class SCENE_PT_rigid_body_world(SceneButtonsPanel, Panel): class SCENE_PT_rigid_body_cache(SceneButtonsPanel, Panel): bl_label = "Rigid Body Cache" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): @@ -387,7 +387,7 @@ class SCENE_PT_rigid_body_cache(SceneButtonsPanel, Panel): class SCENE_PT_rigid_body_field_weights(SceneButtonsPanel, Panel): bl_label = "Rigid Body Field Weights" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): @@ -427,9 +427,6 @@ class SCENE_PT_simplify(SceneButtonsPanel, Panel): col.label(text="Render:") col.prop(rd, "simplify_subdivision_render", text="Subdivision") col.prop(rd, "simplify_child_particles_render", text="Child Particles") - col.prop(rd, "simplify_shadow_samples", text="Shadow Samples") - col.prop(rd, "simplify_ao_sss", text="AO and SSS") - col.prop(rd, "use_simplify_triangulate") class SCENE_PT_custom_props(SceneButtonsPanel, PropertyPanel, Panel): diff --git a/release/scripts/startup/bl_ui/properties_texture.py b/release/scripts/startup/bl_ui/properties_texture.py index 8f2c3085881..aa3227e0b72 100644 --- a/release/scripts/startup/bl_ui/properties_texture.py +++ b/release/scripts/startup/bl_ui/properties_texture.py @@ -23,12 +23,9 @@ from bpy.types import Menu, Panel, UIList from bpy.types import ( Brush, FreestyleLineStyle, - Lamp, - Material, Object, ParticleSettings, Texture, - World, ) from rna_prop_ui import PropertyPanel @@ -47,22 +44,9 @@ class TEXTURE_MT_specials(Menu): layout.operator("texture.slot_paste", icon='PASTEDOWN') -class TEXTURE_MT_envmap_specials(Menu): - bl_label = "Environment Map Specials" - COMPAT_ENGINES = {'BLENDER_RENDER'} - - def draw(self, context): - layout = self.layout - - layout.operator("texture.envmap_save", icon='IMAGEFILE') - layout.operator("texture.envmap_clear", icon='FILE_REFRESH') - layout.operator("texture.envmap_clear_all", icon='FILE_REFRESH') - - class TEXTURE_UL_texslots(UIList): def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index): - # assert(isinstance(item, bpy.types.MaterialTextureSlot) ma = data slot = item tex = slot.texture if slot else None @@ -71,29 +55,11 @@ class TEXTURE_UL_texslots(UIList): layout.prop(tex, "name", text="", emboss=False, icon_value=icon) else: layout.label(text="", icon_value=icon) - if tex and isinstance(item, bpy.types.MaterialTextureSlot): - layout.prop(ma, "use_textures", text="", index=index) elif self.layout_type == 'GRID': layout.alignment = 'CENTER' layout.label(text="", icon_value=icon) - -from .properties_material import active_node_mat - - def context_tex_datablock(context): - idblock = context.material - if idblock: - return active_node_mat(idblock) - - idblock = context.lamp - if idblock: - return idblock - - idblock = context.world - if idblock: - return idblock - idblock = context.brush if idblock: return idblock @@ -108,151 +74,138 @@ def context_tex_datablock(context): return idblock -def id_tex_datablock(bid): - if isinstance(bid, Object): - if bid.type == 'LAMP': - return bid.data - return bid.active_material - - return bid - - class TextureButtonsPanel: bl_space_type = 'PROPERTIES' bl_region_type = 'WINDOW' bl_context = "texture" + +class TEXTURE_PT_preview(TextureButtonsPanel, Panel): + bl_label = "Preview" + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + @classmethod def poll(cls, context): tex = context.texture return tex and (tex.type != 'NONE' or tex.use_nodes) and (context.engine in cls.COMPAT_ENGINES) + def draw(self, context): + layout = self.layout + + tex = context.texture + slot = getattr(context, "texture_slot", None) + idblock = context_tex_datablock(context) + + if idblock: + layout.template_preview(tex, parent=idblock, slot=slot) + else: + layout.template_preview(tex, slot=slot) + + # Show Alpha Button for Brush Textures, see #29502 + idblock = context_tex_datablock(context) + if isinstance(idblock, Brush): + layout.prop(tex, "use_preview_alpha") -class TEXTURE_PT_context_texture(TextureButtonsPanel, Panel): +class TEXTURE_PT_context(TextureButtonsPanel, Panel): bl_label = "" + bl_context = "texture" bl_options = {'HIDE_HEADER'} - COMPAT_ENGINES = {'BLENDER_RENDER'} - - @classmethod - def poll(cls, context): - engine = context.engine - # if not (hasattr(context, "texture_slot") or hasattr(context, "texture_node")): - # return False - return ((context.material or - context.world or - context.lamp or - context.texture or - context.line_style or - context.particle_system or - isinstance(context.space_data.pin_id, ParticleSettings) or - context.texture_user) and - (engine in cls.COMPAT_ENGINES)) + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout - slot = getattr(context, "texture_slot", None) - node = getattr(context, "texture_node", None) - space = context.space_data tex = context.texture - idblock = context_tex_datablock(context) + space = context.space_data pin_id = space.pin_id + use_pin_id = space.use_pin_id + user = context.texture_user - space.use_limited_texture_context = True - - if space.use_pin_id and not isinstance(pin_id, Texture): - idblock = id_tex_datablock(pin_id) - pin_id = None - - if not space.use_pin_id: - layout.row().prop(space, "texture_context", expand=True) + if not (use_pin_id and isinstance(pin_id, bpy.types.Texture)): pin_id = None - if space.texture_context == 'OTHER': - if not pin_id: - layout.template_texture_user() - user = context.texture_user - if user or pin_id: - layout.separator() + if not pin_id: + layout.template_texture_user() - row = layout.row() + if user or pin_id: + layout.separator() - if pin_id: - row.template_ID(space, "pin_id") - else: - propname = context.texture_user_property.identifier - row.template_ID(user, propname, new="texture.new") - - if tex: - split = layout.split(percentage=0.2) - if tex.use_nodes: - if slot: - split.label(text="Output:") - split.prop(slot, "output_node", text="") - else: - split.label(text="Type:") - split.prop(tex, "type", text="") - return - - tex_collection = (pin_id is None) and (node is None) and (not isinstance(idblock, Brush)) - - if tex_collection: - row = layout.row() + split = layout.split(percentage=0.65) + col = split.column() - row.template_list("TEXTURE_UL_texslots", "", idblock, "texture_slots", - idblock, "active_texture_index", rows=2) - - col = row.column(align=True) - col.operator("texture.slot_move", text="", icon='TRIA_UP').type = 'UP' - col.operator("texture.slot_move", text="", icon='TRIA_DOWN').type = 'DOWN' - col.menu("TEXTURE_MT_specials", icon='DOWNARROW_HLT', text="") - - if tex_collection: - layout.template_ID(idblock, "active_texture", new="texture.new") - elif node: - layout.template_ID(node, "texture", new="texture.new") - elif idblock: - layout.template_ID(idblock, "texture", new="texture.new") - - if pin_id: - layout.template_ID(space, "pin_id") - - if tex: - split = layout.split(percentage=0.2) - if tex.use_nodes: - if slot: - split.label(text="Output:") - split.prop(slot, "output_node", text="") + if pin_id: + col.template_ID(space, "pin_id") else: + propname = context.texture_user_property.identifier + col.template_ID(user, propname, new="texture.new") + + if tex: + split = layout.split(percentage=0.2) split.label(text="Type:") split.prop(tex, "type", text="") -class TEXTURE_PT_preview(TextureButtonsPanel, Panel): - bl_label = "Preview" - COMPAT_ENGINES = {'BLENDER_RENDER'} +class TEXTURE_PT_node(TextureButtonsPanel, Panel): + bl_label = "Node" + bl_context = "texture" + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + + @classmethod + def poll(cls, context): + node = context.texture_node + return node and (context.engine in cls.COMPAT_ENGINES) def draw(self, context): layout = self.layout - tex = context.texture - slot = getattr(context, "texture_slot", None) - idblock = context_tex_datablock(context) + node = context.texture_node + ntree = node.id_data + layout.template_node_view(ntree, node, None) - if idblock: - layout.template_preview(tex, parent=idblock, slot=slot) - else: - layout.template_preview(tex, slot=slot) - # Show Alpha Button for Brush Textures, see #29502 - if context.space_data.texture_context == 'BRUSH': - layout.prop(tex, "use_preview_alpha") +class TEXTURE_PT_node_mapping(TextureButtonsPanel, Panel): + bl_label = "Mapping" + bl_context = "texture" + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + + @classmethod + def poll(cls, context): + node = context.texture_node + # TODO(sergey): perform a faster/nicer check? + return node and hasattr(node, 'texture_mapping') and (context.engine in cls.COMPAT_ENGINES) + + def draw(self, context): + layout = self.layout + + node = context.texture_node + + mapping = node.texture_mapping + + layout.prop(mapping, "vector_type", expand=True) + + row = layout.row() + + row.column().prop(mapping, "translation") + row.column().prop(mapping, "rotation") + row.column().prop(mapping, "scale") + + layout.label(text="Projection:") + + row = layout.row() + row.prop(mapping, "mapping_x", text="") + row.prop(mapping, "mapping_y", text="") + row.prop(mapping, "mapping_z", text="") class TEXTURE_PT_colors(TextureButtonsPanel, Panel): bl_label = "Colors" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + + @classmethod + def poll(cls, context): + tex = context.texture + return tex and (tex.type != 'NONE' or tex.use_nodes) and (context.engine in cls.COMPAT_ENGINES) def draw(self, context): layout = self.layout @@ -281,23 +234,6 @@ class TEXTURE_PT_colors(TextureButtonsPanel, Panel): col = layout.column() col.prop(tex, "use_clamp", text="Clamp") -# Texture Slot Panels # - - -class TextureSlotPanel(TextureButtonsPanel): - COMPAT_ENGINES = {'BLENDER_RENDER'} - - @classmethod - def poll(cls, context): - if not hasattr(context, "texture_slot"): - return False - - engine = context.engine - return TextureButtonsPanel.poll(cls, context) and (engine in cls.COMPAT_ENGINES) - - -# Texture Type Panels # - class TextureTypePanel(TextureButtonsPanel): @@ -311,7 +247,7 @@ class TextureTypePanel(TextureButtonsPanel): class TEXTURE_PT_clouds(TextureTypePanel, Panel): bl_label = "Clouds" tex_type = 'CLOUDS' - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -335,7 +271,7 @@ class TEXTURE_PT_clouds(TextureTypePanel, Panel): class TEXTURE_PT_wood(TextureTypePanel, Panel): bl_label = "Wood" tex_type = 'WOOD' - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -364,7 +300,7 @@ class TEXTURE_PT_wood(TextureTypePanel, Panel): class TEXTURE_PT_marble(TextureTypePanel, Panel): bl_label = "Marble" tex_type = 'MARBLE' - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -391,7 +327,7 @@ class TEXTURE_PT_marble(TextureTypePanel, Panel): class TEXTURE_PT_magic(TextureTypePanel, Panel): bl_label = "Magic" tex_type = 'MAGIC' - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -406,7 +342,7 @@ class TEXTURE_PT_magic(TextureTypePanel, Panel): class TEXTURE_PT_blend(TextureTypePanel, Panel): bl_label = "Blend" tex_type = 'BLEND' - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -424,7 +360,7 @@ class TEXTURE_PT_blend(TextureTypePanel, Panel): class TEXTURE_PT_stucci(TextureTypePanel, Panel): bl_label = "Stucci" tex_type = 'STUCCI' - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -444,7 +380,7 @@ class TEXTURE_PT_stucci(TextureTypePanel, Panel): class TEXTURE_PT_image(TextureTypePanel, Panel): bl_label = "Image" tex_type = 'IMAGE' - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -471,7 +407,7 @@ class TEXTURE_PT_image_sampling(TextureTypePanel, Panel): bl_label = "Image Sampling" bl_options = {'DEFAULT_CLOSED'} tex_type = 'IMAGE' - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -494,17 +430,6 @@ class TEXTURE_PT_image_sampling(TextureTypePanel, Panel): col = split.column() - # Only for Material based textures, not for Lamp/World... - if slot and isinstance(idblock, Material): - col.prop(tex, "use_normal_map") - row = col.row() - row.active = tex.use_normal_map - row.prop(slot, "normal_map_space", text="") - - row = col.row() - row.active = not tex.use_normal_map - row.prop(tex, "use_derivative_map") - col.prop(tex, "use_mipmap") row = col.row() row.active = tex.use_mipmap @@ -518,7 +443,7 @@ class TEXTURE_PT_image_mapping(TextureTypePanel, Panel): bl_label = "Image Mapping" bl_options = {'DEFAULT_CLOSED'} tex_type = 'IMAGE' - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -570,62 +495,10 @@ class TEXTURE_PT_image_mapping(TextureTypePanel, Panel): col.prop(tex, "crop_max_y", text="Y") -class TEXTURE_PT_envmap(TextureTypePanel, Panel): - bl_label = "Environment Map" - tex_type = 'ENVIRONMENT_MAP' - COMPAT_ENGINES = {'BLENDER_RENDER'} - - def draw(self, context): - layout = self.layout - - tex = context.texture - env = tex.environment_map - - row = layout.row() - row.prop(env, "source", expand=True) - row.menu("TEXTURE_MT_envmap_specials", icon='DOWNARROW_HLT', text="") - - if env.source == 'IMAGE_FILE': - layout.template_ID(tex, "image", open="image.open") - layout.template_image(tex, "image", tex.image_user, compact=True) - else: - layout.prop(env, "mapping") - if env.mapping == 'PLANE': - layout.prop(env, "zoom") - layout.prop(env, "viewpoint_object") - - split = layout.split() - - col = split.column() - col.prop(env, "layers_ignore") - col.prop(env, "resolution") - col.prop(env, "depth") - - col = split.column(align=True) - - col.label(text="Clipping:") - col.prop(env, "clip_start", text="Start") - col.prop(env, "clip_end", text="End") - - -class TEXTURE_PT_envmap_sampling(TextureTypePanel, Panel): - bl_label = "Environment Map Sampling" - bl_options = {'DEFAULT_CLOSED'} - tex_type = 'ENVIRONMENT_MAP' - COMPAT_ENGINES = {'BLENDER_RENDER'} - - def draw(self, context): - layout = self.layout - - tex = context.texture - - texture_filter_common(tex, layout) - - class TEXTURE_PT_musgrave(TextureTypePanel, Panel): bl_label = "Musgrave" tex_type = 'MUSGRAVE' - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -661,7 +534,7 @@ class TEXTURE_PT_musgrave(TextureTypePanel, Panel): class TEXTURE_PT_voronoi(TextureTypePanel, Panel): bl_label = "Voronoi" tex_type = 'VORONOI' - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -697,7 +570,7 @@ class TEXTURE_PT_voronoi(TextureTypePanel, Panel): class TEXTURE_PT_distortednoise(TextureTypePanel, Panel): bl_label = "Distorted Noise" tex_type = 'DISTORTED_NOISE' - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -716,180 +589,20 @@ class TEXTURE_PT_distortednoise(TextureTypePanel, Panel): split.prop(tex, "nabla") -class TEXTURE_PT_voxeldata(TextureButtonsPanel, Panel): - bl_label = "Voxel Data" - COMPAT_ENGINES = {'BLENDER_RENDER'} - - @classmethod - def poll(cls, context): - tex = context.texture - engine = context.engine - return tex and (tex.type == 'VOXEL_DATA' and (engine in cls.COMPAT_ENGINES)) - - def draw(self, context): - layout = self.layout - - tex = context.texture - vd = tex.voxel_data - - layout.prop(vd, "file_format") - if vd.file_format in {'BLENDER_VOXEL', 'RAW_8BIT'}: - layout.prop(vd, "filepath") - if vd.file_format == 'RAW_8BIT': - layout.prop(vd, "resolution") - elif vd.file_format == 'SMOKE': - layout.prop(vd, "domain_object") - layout.prop(vd, "smoke_data_type") - elif vd.file_format == 'HAIR': - layout.prop(vd, "domain_object") - layout.prop(vd, "hair_data_type") - elif vd.file_format == 'IMAGE_SEQUENCE': - layout.template_ID(tex, "image", open="image.open") - layout.template_image(tex, "image", tex.image_user, compact=True) - # layout.prop(vd, "frame_duration") - - if vd.file_format in {'BLENDER_VOXEL', 'RAW_8BIT'}: - layout.prop(vd, "use_still_frame") - row = layout.row() - row.active = vd.use_still_frame - row.prop(vd, "still_frame") - - layout.prop(vd, "interpolation") - layout.prop(vd, "extension") - layout.prop(vd, "intensity") - - -class TEXTURE_PT_pointdensity(TextureButtonsPanel, Panel): - bl_label = "Point Density" - COMPAT_ENGINES = {'BLENDER_RENDER'} - - @classmethod - def poll(cls, context): - tex = context.texture - engine = context.engine - return tex and (tex.type == 'POINT_DENSITY' and (engine in cls.COMPAT_ENGINES)) - - def draw(self, context): - layout = self.layout - - tex = context.texture - pd = tex.point_density - - layout.row().prop(pd, "point_source", expand=True) - - split = layout.split() - - col = split.column() - if pd.point_source == 'PARTICLE_SYSTEM': - col.label(text="Object:") - col.prop(pd, "object", text="") - - sub = col.column() - sub.enabled = bool(pd.object) - if pd.object: - sub.label(text="System:") - sub.prop_search(pd, "particle_system", pd.object, "particle_systems", text="") - sub.label(text="Cache:") - sub.prop(pd, "particle_cache_space", text="") - else: - col.label(text="Object:") - col.prop(pd, "object", text="") - col.label(text="Cache:") - col.prop(pd, "vertex_cache_space", text="") - - col.separator() - - col.label(text="Color Source:") - if pd.point_source == 'PARTICLE_SYSTEM': - col.prop(pd, "particle_color_source", text="") - if pd.particle_color_source in {'PARTICLE_SPEED', 'PARTICLE_VELOCITY'}: - col.prop(pd, "speed_scale") - if pd.particle_color_source in {'PARTICLE_SPEED', 'PARTICLE_AGE'}: - layout.template_color_ramp(pd, "color_ramp", expand=True) - else: - col.prop(pd, "vertex_color_source", text="") - if pd.vertex_color_source == 'VERTEX_COLOR': - if pd.object and pd.object.data: - col.prop_search(pd, "vertex_attribute_name", pd.object.data, "vertex_colors", text="") - if pd.vertex_color_source == 'VERTEX_WEIGHT': - if pd.object: - col.prop_search(pd, "vertex_attribute_name", pd.object, "vertex_groups", text="") - layout.template_color_ramp(pd, "color_ramp", expand=True) - - col = split.column() - col.label() - col.prop(pd, "radius") - col.label(text="Falloff:") - col.prop(pd, "falloff", text="") - if pd.falloff == 'SOFT': - col.prop(pd, "falloff_soft") - if pd.falloff == 'PARTICLE_VELOCITY': - col.prop(pd, "falloff_speed_scale") - - col.prop(pd, "use_falloff_curve") - - if pd.use_falloff_curve: - col = layout.column() - col.label(text="Falloff Curve") - col.template_curve_mapping(pd, "falloff_curve", brush=False) - - -class TEXTURE_PT_pointdensity_turbulence(TextureButtonsPanel, Panel): - bl_label = "Turbulence" - COMPAT_ENGINES = {'BLENDER_RENDER'} +class TextureSlotPanel(TextureButtonsPanel): + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): - tex = context.texture - engine = context.engine - return tex and (tex.type == 'POINT_DENSITY' and (engine in cls.COMPAT_ENGINES)) - - def draw_header(self, context): - pd = context.texture.point_density - - self.layout.prop(pd, "use_turbulence", text="") - - def draw(self, context): - layout = self.layout - - tex = context.texture - pd = tex.point_density - layout.active = pd.use_turbulence - - split = layout.split() - - col = split.column() - col.label(text="Influence:") - col.prop(pd, "turbulence_influence", text="") - col.label(text="Noise Basis:") - col.prop(pd, "noise_basis", text="") - - col = split.column() - col.label() - col.prop(pd, "turbulence_scale") - col.prop(pd, "turbulence_depth") - col.prop(pd, "turbulence_strength") - - -class TEXTURE_PT_ocean(TextureTypePanel, Panel): - bl_label = "Ocean" - tex_type = 'OCEAN' - COMPAT_ENGINES = {'BLENDER_RENDER'} - - def draw(self, context): - layout = self.layout - - tex = context.texture - ot = tex.ocean + if not hasattr(context, "texture_slot"): + return False - col = layout.column() - col.prop(ot, "ocean_object") - col.prop(ot, "output") + return (context.engine in cls.COMPAT_ENGINES) class TEXTURE_PT_mapping(TextureSlotPanel, Panel): bl_label = "Mapping" - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): @@ -960,31 +673,6 @@ class TEXTURE_PT_mapping(TextureSlotPanel, Panel): row.prop(tex, "mapping_y", text="") row.prop(tex, "mapping_z", text="") - elif isinstance(idblock, Material): - split = layout.split(percentage=0.3) - split.label(text="Projection:") - split.prop(tex, "mapping", text="") - - split = layout.split() - - col = split.column() - if tex.texture_coords in {'ORCO', 'UV'}: - col.prop(tex, "use_from_dupli") - if (idblock.type == 'VOLUME' and tex.texture_coords == 'ORCO'): - col.prop(tex, "use_map_to_bounds") - elif tex.texture_coords == 'OBJECT': - col.prop(tex, "use_from_original") - if (idblock.type == 'VOLUME'): - col.prop(tex, "use_map_to_bounds") - else: - col.label() - - col = split.column() - row = col.row() - row.prop(tex, "mapping_x", text="") - row.prop(tex, "mapping_y", text="") - row.prop(tex, "mapping_z", text="") - row = layout.row() row.column().prop(tex, "offset") row.column().prop(tex, "scale") @@ -992,7 +680,7 @@ class TEXTURE_PT_mapping(TextureSlotPanel, Panel): class TEXTURE_PT_influence(TextureSlotPanel, Panel): bl_label = "Influence" - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} @classmethod def poll(cls, context): @@ -1022,101 +710,7 @@ class TEXTURE_PT_influence(TextureSlotPanel, Panel): sub.prop(tex, factor, text=name, slider=True) return sub # XXX, temp. use_map_normal needs to override. - if isinstance(idblock, Material): - if idblock.type in {'SURFACE', 'WIRE'}: - split = layout.split() - - col = split.column() - col.label(text="Diffuse:") - factor_but(col, "use_map_diffuse", "diffuse_factor", "Intensity") - factor_but(col, "use_map_color_diffuse", "diffuse_color_factor", "Color") - factor_but(col, "use_map_alpha", "alpha_factor", "Alpha") - factor_but(col, "use_map_translucency", "translucency_factor", "Translucency") - - col.label(text="Specular:") - factor_but(col, "use_map_specular", "specular_factor", "Intensity") - factor_but(col, "use_map_color_spec", "specular_color_factor", "Color") - factor_but(col, "use_map_hardness", "hardness_factor", "Hardness") - - col = split.column() - col.label(text="Shading:") - factor_but(col, "use_map_ambient", "ambient_factor", "Ambient") - factor_but(col, "use_map_emit", "emit_factor", "Emit") - factor_but(col, "use_map_mirror", "mirror_factor", "Mirror") - factor_but(col, "use_map_raymir", "raymir_factor", "Ray Mirror") - - col.label(text="Geometry:") - # XXX replace 'or' when displacement is fixed to not rely on normal influence value. - sub_tmp = factor_but(col, "use_map_normal", "normal_factor", "Normal") - sub_tmp.active = (tex.use_map_normal or tex.use_map_displacement) - # END XXX - - factor_but(col, "use_map_warp", "warp_factor", "Warp") - factor_but(col, "use_map_displacement", "displacement_factor", "Displace") - - #~ sub = col.column() - #~ sub.active = tex.use_map_translucency or tex.map_emit or tex.map_alpha or tex.map_raymir or tex.map_hardness or tex.map_ambient or tex.map_specularity or tex.map_reflection or tex.map_mirror - #~ sub.prop(tex, "default_value", text="Amount", slider=True) - elif idblock.type == 'HALO': - layout.label(text="Halo:") - - split = layout.split() - - col = split.column() - factor_but(col, "use_map_color_diffuse", "diffuse_color_factor", "Color") - factor_but(col, "use_map_alpha", "alpha_factor", "Alpha") - - col = split.column() - factor_but(col, "use_map_raymir", "raymir_factor", "Size") - factor_but(col, "use_map_hardness", "hardness_factor", "Hardness") - factor_but(col, "use_map_translucency", "translucency_factor", "Add") - elif idblock.type == 'VOLUME': - layout.label(text="Volume:") - - split = layout.split() - - col = split.column() - factor_but(col, "use_map_density", "density_factor", "Density") - factor_but(col, "use_map_emission", "emission_factor", "Emission") - factor_but(col, "use_map_scatter", "scattering_factor", "Scattering") - factor_but(col, "use_map_reflect", "reflection_factor", "Reflection") - - col = split.column() - col.label(text=" ") - factor_but(col, "use_map_color_emission", "emission_color_factor", "Emission Color") - factor_but(col, "use_map_color_transmission", "transmission_color_factor", "Transmission Color") - factor_but(col, "use_map_color_reflection", "reflection_color_factor", "Reflection Color") - - layout.label(text="Geometry:") - - split = layout.split() - - col = split.column() - factor_but(col, "use_map_warp", "warp_factor", "Warp") - - col = split.column() - factor_but(col, "use_map_displacement", "displacement_factor", "Displace") - - elif isinstance(idblock, Lamp): - split = layout.split() - - col = split.column() - factor_but(col, "use_map_color", "color_factor", "Color") - - col = split.column() - factor_but(col, "use_map_shadow", "shadow_factor", "Shadow") - - elif isinstance(idblock, World): - split = layout.split() - - col = split.column() - factor_but(col, "use_map_blend", "blend_factor", "Blend") - factor_but(col, "use_map_horizon", "horizon_factor", "Horizon") - - col = split.column() - factor_but(col, "use_map_zenith_up", "zenith_up_factor", "Zenith Up") - factor_but(col, "use_map_zenith_down", "zenith_down_factor", "Zenith Down") - elif isinstance(idblock, ParticleSettings): + if isinstance(idblock, ParticleSettings): split = layout.split() col = split.column() @@ -1170,47 +764,26 @@ class TEXTURE_PT_influence(TextureSlotPanel, Panel): col.prop(tex, "invert", text="Negative") col.prop(tex, "use_stencil") - if isinstance(idblock, Material) or isinstance(idblock, World): - col.prop(tex, "default_value", text="DVar", slider=True) - - if isinstance(idblock, Material): - layout.label(text="Bump Mapping:") - - # only show bump settings if activated but not for normal-map images - row = layout.row() - - sub = row.row() - sub.active = ( - (tex.use_map_normal or tex.use_map_warp) and - not (tex.texture.type == 'IMAGE' and - (tex.texture.use_normal_map or tex.texture.use_derivative_map)) - ) - sub.prop(tex, "bump_method", text="Method") - - # the space setting is supported for: derivative-maps + bump-maps - # (DEFAULT,BEST_QUALITY), not for normal-maps - sub = row.row() - sub.active = ( - (tex.use_map_normal or tex.use_map_warp) and - not (tex.texture.type == 'IMAGE' and tex.texture.use_normal_map) and - ((tex.bump_method in {'BUMP_LOW_QUALITY', 'BUMP_MEDIUM_QUALITY', 'BUMP_BEST_QUALITY'}) or - (tex.texture.type == 'IMAGE' and tex.texture.use_derivative_map)) - ) - sub.prop(tex, "bump_objectspace", text="Space") - class TEXTURE_PT_custom_props(TextureButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} _context_path = "texture" _property_type = Texture + @classmethod + def poll(cls, context): + return context.texture and (context.engine in cls.COMPAT_ENGINES) + classes = ( TEXTURE_MT_specials, - TEXTURE_MT_envmap_specials, TEXTURE_UL_texslots, - TEXTURE_PT_context_texture, TEXTURE_PT_preview, + TEXTURE_PT_context, + TEXTURE_PT_node, + TEXTURE_PT_node_mapping, + TEXTURE_PT_mapping, + TEXTURE_PT_influence, TEXTURE_PT_colors, TEXTURE_PT_clouds, TEXTURE_PT_wood, @@ -1221,17 +794,9 @@ classes = ( TEXTURE_PT_image, TEXTURE_PT_image_sampling, TEXTURE_PT_image_mapping, - TEXTURE_PT_envmap, - TEXTURE_PT_envmap_sampling, TEXTURE_PT_musgrave, TEXTURE_PT_voronoi, TEXTURE_PT_distortednoise, - TEXTURE_PT_voxeldata, - TEXTURE_PT_pointdensity, - TEXTURE_PT_pointdensity_turbulence, - TEXTURE_PT_ocean, - TEXTURE_PT_mapping, - TEXTURE_PT_influence, TEXTURE_PT_custom_props, ) diff --git a/release/scripts/startup/bl_ui/properties_world.py b/release/scripts/startup/bl_ui/properties_world.py index 045ddc0aa59..1ec2d4774e8 100644 --- a/release/scripts/startup/bl_ui/properties_world.py +++ b/release/scripts/startup/bl_ui/properties_world.py @@ -50,197 +50,12 @@ class WORLD_PT_context_world(WorldButtonsPanel, Panel): world = context.world space = context.space_data - texture_count = world and len(world.texture_slots.keys()) - split = layout.split(percentage=0.85) if scene: split.template_ID(scene, "world", new="world.new") elif world: split.template_ID(space, "pin_id") - if texture_count: - split.label(text=str(texture_count), icon='TEXTURE') - - -class WORLD_PT_preview(WorldButtonsPanel, Panel): - bl_label = "Preview" - COMPAT_ENGINES = {'BLENDER_RENDER'} - - @classmethod - def poll(cls, context): - return (context.world) and (context.engine in cls.COMPAT_ENGINES) - - def draw(self, context): - self.layout.template_preview(context.world) - - -class WORLD_PT_world(WorldButtonsPanel, Panel): - bl_label = "World" - COMPAT_ENGINES = {'BLENDER_RENDER'} - - def draw(self, context): - layout = self.layout - - world = context.world - - row = layout.row() - row.prop(world, "use_sky_paper") - row.prop(world, "use_sky_blend") - row.prop(world, "use_sky_real") - - row = layout.row() - row.column().prop(world, "horizon_color") - col = row.column() - col.prop(world, "zenith_color") - col.active = world.use_sky_blend - row.column().prop(world, "ambient_color") - - row = layout.row() - row.prop(world, "exposure") - row.prop(world, "color_range") - - -class WORLD_PT_ambient_occlusion(WorldButtonsPanel, Panel): - bl_label = "Ambient Occlusion" - COMPAT_ENGINES = {'BLENDER_RENDER'} - - def draw_header(self, context): - light = context.world.light_settings - self.layout.prop(light, "use_ambient_occlusion", text="") - - def draw(self, context): - layout = self.layout - - light = context.world.light_settings - - layout.active = light.use_ambient_occlusion - - split = layout.split() - split.prop(light, "ao_factor", text="Factor") - split.prop(light, "ao_blend_type", text="") - - -class WORLD_PT_environment_lighting(WorldButtonsPanel, Panel): - bl_label = "Environment Lighting" - COMPAT_ENGINES = {'BLENDER_RENDER'} - - def draw_header(self, context): - light = context.world.light_settings - self.layout.prop(light, "use_environment_light", text="") - - def draw(self, context): - layout = self.layout - - light = context.world.light_settings - - layout.active = light.use_environment_light - - split = layout.split() - split.prop(light, "environment_energy", text="Energy") - split.prop(light, "environment_color", text="") - - -class WORLD_PT_indirect_lighting(WorldButtonsPanel, Panel): - bl_label = "Indirect Lighting" - COMPAT_ENGINES = {'BLENDER_RENDER'} - - def draw_header(self, context): - light = context.world.light_settings - self.layout.prop(light, "use_indirect_light", text="") - - def draw(self, context): - layout = self.layout - - light = context.world.light_settings - - layout.active = light.use_indirect_light and light.gather_method == 'APPROXIMATE' - - split = layout.split() - split.prop(light, "indirect_factor", text="Factor") - split.prop(light, "indirect_bounces", text="Bounces") - - if light.gather_method == 'RAYTRACE': - layout.label(text="Only works with Approximate gather method") - - -class WORLD_PT_gather(WorldButtonsPanel, Panel): - bl_label = "Gather" - COMPAT_ENGINES = {'BLENDER_RENDER'} - - def draw(self, context): - layout = self.layout - - light = context.world.light_settings - - layout.active = light.use_ambient_occlusion or light.use_environment_light or light.use_indirect_light - - layout.row().prop(light, "gather_method", expand=True) - - split = layout.split() - - col = split.column() - col.label(text="Attenuation:") - if light.gather_method == 'RAYTRACE': - col.prop(light, "distance") - col.prop(light, "use_falloff") - sub = col.row() - sub.active = light.use_falloff - sub.prop(light, "falloff_strength", text="Strength") - - if light.gather_method == 'RAYTRACE': - col = split.column() - - col.label(text="Sampling:") - col.prop(light, "sample_method", text="") - - sub = col.column() - sub.prop(light, "samples") - - if light.sample_method == 'ADAPTIVE_QMC': - sub.prop(light, "threshold") - sub.prop(light, "adapt_to_speed", slider=True) - elif light.sample_method == 'CONSTANT_JITTERED': - sub.prop(light, "bias") - - if light.gather_method == 'APPROXIMATE': - col = split.column() - - col.label(text="Sampling:") - col.prop(light, "passes") - col.prop(light, "error_threshold", text="Error") - col.prop(light, "use_cache") - col.prop(light, "correction") - - -class WORLD_PT_mist(WorldButtonsPanel, Panel): - bl_label = "Mist" - bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} - - def draw_header(self, context): - world = context.world - - self.layout.prop(world.mist_settings, "use_mist", text="") - - def draw(self, context): - layout = self.layout - - world = context.world - - layout.active = world.mist_settings.use_mist - - split = layout.split() - - col = split.column() - col.prop(world.mist_settings, "intensity") - col.prop(world.mist_settings, "start") - - col = split.column() - col.prop(world.mist_settings, "depth") - col.prop(world.mist_settings, "height") - - layout.prop(world.mist_settings, "falloff") - class EEVEE_WORLD_PT_mist(WorldButtonsPanel, Panel): bl_label = "Mist Pass" @@ -311,13 +126,6 @@ class EEVEE_WORLD_PT_surface(WorldButtonsPanel, Panel): classes = ( WORLD_PT_context_world, - WORLD_PT_preview, - WORLD_PT_world, - WORLD_PT_ambient_occlusion, - WORLD_PT_environment_lighting, - WORLD_PT_indirect_lighting, - WORLD_PT_gather, - WORLD_PT_mist, WORLD_PT_custom_props, EEVEE_WORLD_PT_surface, EEVEE_WORLD_PT_mist, diff --git a/release/scripts/startup/bl_ui/space_node.py b/release/scripts/startup/bl_ui/space_node.py index 8b199d7eef1..f97c88be0ad 100644 --- a/release/scripts/startup/bl_ui/space_node.py +++ b/release/scripts/startup/bl_ui/space_node.py @@ -51,14 +51,12 @@ class NODE_HT_header(Header): NODE_MT_editor_menus.draw_collapsible(context, layout) layout.prop(snode, "tree_type", text="", expand=True) - use_shading_nodes = scene.render.use_shading_nodes if snode.tree_type == 'ShaderNodeTree': - if use_shading_nodes: - layout.prop(snode, "shader_type", text="", expand=True) + layout.prop(snode, "shader_type", text="", expand=True) ob = context.object - if (not use_shading_nodes or snode.shader_type == 'OBJECT') and ob: + if snode.shader_type == 'OBJECT' and ob: row = layout.row() # disable material slot buttons when pinned, cannot find correct slot within id_from (#36589) row.enabled = not snode.pin @@ -69,18 +67,18 @@ class NODE_HT_header(Header): if id_from and ob.type != 'LAMP': row.template_ID(id_from, "active_material", new="material.new") - # Don't show "Use Nodes" Button when Engine is BI for Lamps - if snode_id and not (use_shading_nodes == 0 and ob.type == 'LAMP'): + # No shader nodes for Eevee lamps + if snode_id and not (context.engine == 'BLENDER_EEVEE' and ob.type == 'LAMP'): layout.prop(snode_id, "use_nodes") - if use_shading_nodes and snode.shader_type == 'WORLD': + if snode.shader_type == 'WORLD': row = layout.row() row.enabled = not snode.pin row.template_ID(scene, "world", new="world.new") if snode_id: row.prop(snode_id, "use_nodes") - if use_shading_nodes and snode.shader_type == 'LINESTYLE': + if snode.shader_type == 'LINESTYLE': view_layer = context.scene.view_layers.active lineset = view_layer.freestyle_settings.linesets.active if lineset is not None: diff --git a/release/scripts/startup/bl_ui/space_sequencer.py b/release/scripts/startup/bl_ui/space_sequencer.py index 5d6964ef758..ca9c4465116 100644 --- a/release/scripts/startup/bl_ui/space_sequencer.py +++ b/release/scripts/startup/bl_ui/space_sequencer.py @@ -1288,7 +1288,7 @@ class SEQUENCER_PT_grease_pencil_tools(GreasePencilToolsPanel, SequencerButtonsP class SEQUENCER_PT_custom_props(SequencerButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} _context_path = "scene.sequence_editor.active_strip" _property_type = (bpy.types.Sequence,) bl_category = "Strip" diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 731295ed330..d211d8bb6fe 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -1547,54 +1547,40 @@ class VIEW3D_MT_object_specials(Menu): lamp = obj.data layout.operator_context = 'INVOKE_REGION_WIN' - use_shading_nodes = scene.render.use_shading_nodes - - if use_shading_nodes: - emission_node = None - if lamp.node_tree: - for node in lamp.node_tree.nodes: - if getattr(node, "type", None) == 'EMISSION': - emission_node = node - break - - if emission_node is not None: - props = layout.operator("wm.context_modal_mouse", text="Strength") - props.data_path_iter = "selected_editable_objects" - props.data_path_item = "data.node_tree" \ - ".nodes[\"" + emission_node.name + "\"]" \ - ".inputs[\"Strength\"].default_value" - props.header_text = "Lamp Strength: %.3f" - props.input_scale = 0.1 - - if lamp.type == 'AREA': - props = layout.operator("wm.context_modal_mouse", text="Size X") - props.data_path_iter = "selected_editable_objects" - props.data_path_item = "data.size" - props.header_text = "Lamp Size X: %.3f" - if lamp.shape == 'RECTANGLE': - props = layout.operator("wm.context_modal_mouse", text="Size Y") - props.data_path_iter = "selected_editable_objects" - props.data_path_item = "data.size_y" - props.header_text = "Lamp Size Y: %.3f" + emission_node = None + if lamp.node_tree: + for node in lamp.node_tree.nodes: + if getattr(node, "type", None) == 'EMISSION': + emission_node = node + break - elif lamp.type in {'SPOT', 'POINT', 'SUN'}: - props = layout.operator("wm.context_modal_mouse", text="Size") - props.data_path_iter = "selected_editable_objects" - props.data_path_item = "data.shadow_soft_size" - props.header_text = "Lamp Size: %.3f" - else: - props = layout.operator("wm.context_modal_mouse", text="Energy") + if emission_node is not None: + props = layout.operator("wm.context_modal_mouse", text="Strength") + props.data_path_iter = "selected_editable_objects" + props.data_path_item = "data.node_tree" \ + ".nodes[\"" + emission_node.name + "\"]" \ + ".inputs[\"Strength\"].default_value" + props.header_text = "Lamp Strength: %.3f" + props.input_scale = 0.1 + + if lamp.type == 'AREA': + props = layout.operator("wm.context_modal_mouse", text="Size X") props.data_path_iter = "selected_editable_objects" - props.data_path_item = "data.energy" - props.header_text = "Lamp Energy: %.3f" + props.data_path_item = "data.size" + props.header_text = "Lamp Size X: %.3f" - if lamp.type in {'SPOT', 'AREA', 'POINT'}: - props = layout.operator("wm.context_modal_mouse", text="Falloff Distance") + if lamp.shape == 'RECTANGLE': + props = layout.operator("wm.context_modal_mouse", text="Size Y") props.data_path_iter = "selected_editable_objects" - props.data_path_item = "data.distance" - props.input_scale = 0.1 - props.header_text = "Lamp Falloff Distance: %.1f" + props.data_path_item = "data.size_y" + props.header_text = "Lamp Size Y: %.3f" + + elif lamp.type in {'SPOT', 'POINT', 'SUN'}: + props = layout.operator("wm.context_modal_mouse", text="Size") + props.data_path_iter = "selected_editable_objects" + props.data_path_item = "data.shadow_soft_size" + props.header_text = "Lamp Size: %.3f" if lamp.type == 'SPOT': layout.separator() @@ -1610,19 +1596,6 @@ class VIEW3D_MT_object_specials(Menu): props.input_scale = -0.01 props.header_text = "Spot Blend: %.2f" - if not use_shading_nodes: - props = layout.operator("wm.context_modal_mouse", text="Clip Start") - props.data_path_iter = "selected_editable_objects" - props.data_path_item = "data.shadow_buffer_clip_start" - props.input_scale = 0.05 - props.header_text = "Clip Start: %.2f" - - props = layout.operator("wm.context_modal_mouse", text="Clip End") - props.data_path_iter = "selected_editable_objects" - props.data_path_item = "data.shadow_buffer_clip_end" - props.input_scale = 0.05 - props.header_text = "Clip End: %.2f" - layout.separator() props = layout.operator("object.isolate_type_render") diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py index d7c23e460a0..e56fb362bef 100644 --- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -341,7 +341,6 @@ class VIEW3D_PT_tools_meshedit(View3DPanel, Panel): row = col.row(align=True) row.operator("transform.edge_slide", text="Slide Edge") row.operator("transform.vert_slide", text="Vertex") - col.operator("mesh.noise") col.operator("mesh.vertices_smooth") col.operator("transform.vertex_random") @@ -1199,9 +1198,6 @@ class TEXTURE_UL_texpaintslots(UIList): if self.layout_type in {'DEFAULT', 'COMPACT'}: layout.prop(item, "name", text="", emboss=False, icon_value=icon) - if (not mat.use_nodes) and context.engine == 'BLENDER_RENDER': - mtex_index = mat.texture_paint_slots[index].index - layout.prop(mat, "use_textures", text="", index=mtex_index) elif self.layout_type == 'GRID': layout.alignment = 'CENTER' layout.label(text="") @@ -1262,16 +1258,7 @@ class VIEW3D_PT_slots_projectpaint(View3DPanel, Panel): else: slot = None - if (not mat.use_nodes) and context.engine == 'BLENDER_RENDER': - row = col.row(align=True) - row.operator_menu_enum("paint.add_texture_paint_slot", "type") - row.operator("paint.delete_texture_paint_slot", text="", icon='X') - - if slot: - col.prop(mat.texture_slots[slot.index], "blend_type") - col.separator() - - if slot and slot.index != -1: + if slot and slot.valid: col.label("UV Map:") col.prop_search(slot, "uv_layer", ob.data, "uv_layers", text="") diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py index a92b25670fc..0d283d39af7 100644 --- a/release/scripts/startup/nodeitems_builtins.py +++ b/release/scripts/startup/nodeitems_builtins.py @@ -43,18 +43,10 @@ class CompositorNodeCategory(SortedNodeCategory): return (context.space_data.tree_type == 'CompositorNodeTree') -class ShaderNewNodeCategory(SortedNodeCategory): +class ShaderNodeCategory(SortedNodeCategory): @classmethod def poll(cls, context): - return (context.space_data.tree_type == 'ShaderNodeTree' and - context.scene.render.use_shading_nodes) - - -class ShaderOldNodeCategory(SortedNodeCategory): - @classmethod - def poll(cls, context): - return (context.space_data.tree_type == 'ShaderNodeTree' and - not context.scene.render.use_shading_nodes) + return (context.space_data.tree_type == 'ShaderNodeTree') class TextureNodeCategory(SortedNodeCategory): @@ -172,59 +164,8 @@ def object_eevee_cycles_shader_nodes_poll(context): # All standard node categories currently used in nodes. shader_node_categories = [ - # Shader Nodes - ShaderOldNodeCategory("SH_INPUT", "Input", items=[ - NodeItem("ShaderNodeMaterial"), - NodeItem("ShaderNodeCameraData"), - NodeItem("ShaderNodeFresnel"), - NodeItem("ShaderNodeLayerWeight"), - NodeItem("ShaderNodeLampData"), - NodeItem("ShaderNodeValue"), - NodeItem("ShaderNodeRGB"), - NodeItem("ShaderNodeTexture"), - NodeItem("ShaderNodeGeometry"), - NodeItem("ShaderNodeExtendedMaterial"), - NodeItem("ShaderNodeParticleInfo"), - NodeItem("ShaderNodeObjectInfo"), - NodeItem("NodeGroupInput", poll=group_input_output_item_poll), - ]), - ShaderOldNodeCategory("SH_OUTPUT", "Output", items=[ - NodeItem("ShaderNodeOutput"), - NodeItem("NodeGroupOutput", poll=group_input_output_item_poll), - ]), - ShaderOldNodeCategory("SH_OP_COLOR", "Color", items=[ - NodeItem("ShaderNodeMixRGB"), - NodeItem("ShaderNodeRGBCurve"), - NodeItem("ShaderNodeInvert"), - NodeItem("ShaderNodeHueSaturation"), - NodeItem("ShaderNodeGamma"), - ]), - ShaderOldNodeCategory("SH_OP_VECTOR", "Vector", items=[ - NodeItem("ShaderNodeNormal"), - NodeItem("ShaderNodeMapping"), - NodeItem("ShaderNodeVectorCurve"), - NodeItem("ShaderNodeVectorTransform"), - NodeItem("ShaderNodeNormalMap"), - ]), - ShaderOldNodeCategory("SH_CONVERTOR", "Converter", items=[ - NodeItem("ShaderNodeValToRGB"), - NodeItem("ShaderNodeRGBToBW"), - NodeItem("ShaderNodeMath"), - NodeItem("ShaderNodeVectorMath"), - NodeItem("ShaderNodeSqueeze"), - NodeItem("ShaderNodeSeparateRGB"), - NodeItem("ShaderNodeCombineRGB"), - NodeItem("ShaderNodeSeparateHSV"), - NodeItem("ShaderNodeCombineHSV"), - ]), - ShaderOldNodeCategory("SH_GROUP", "Group", items=node_group_items), - ShaderOldNodeCategory("SH_LAYOUT", "Layout", items=[ - NodeItem("NodeFrame"), - NodeItem("NodeReroute"), - ]), - - # New Shader Nodes (Cycles) - ShaderNewNodeCategory("SH_NEW_INPUT", "Input", items=[ + # Shader Nodes (Cycles and Eevee) + ShaderNodeCategory("SH_NEW_INPUT", "Input", items=[ NodeItem("ShaderNodeTexCoord"), NodeItem("ShaderNodeAttribute"), NodeItem("ShaderNodeLightPath"), @@ -244,14 +185,14 @@ shader_node_categories = [ NodeItem("ShaderNodeUVAlongStroke", poll=line_style_shader_nodes_poll), NodeItem("NodeGroupInput", poll=group_input_output_item_poll), ]), - ShaderNewNodeCategory("SH_NEW_OUTPUT", "Output", items=[ + ShaderNodeCategory("SH_NEW_OUTPUT", "Output", items=[ NodeItem("ShaderNodeOutputMaterial", poll=object_eevee_cycles_shader_nodes_poll), NodeItem("ShaderNodeOutputLamp", poll=object_cycles_shader_nodes_poll), NodeItem("ShaderNodeOutputWorld", poll=world_shader_nodes_poll), NodeItem("ShaderNodeOutputLineStyle", poll=line_style_shader_nodes_poll), NodeItem("NodeGroupOutput", poll=group_input_output_item_poll), ]), - ShaderNewNodeCategory("SH_NEW_SHADER", "Shader", items=[ + ShaderNodeCategory("SH_NEW_SHADER", "Shader", items=[ NodeItem("ShaderNodeMixShader", poll=eevee_cycles_shader_nodes_poll), NodeItem("ShaderNodeAddShader", poll=eevee_cycles_shader_nodes_poll), NodeItem("ShaderNodeBsdfDiffuse", poll=object_eevee_cycles_shader_nodes_poll), @@ -275,7 +216,7 @@ shader_node_categories = [ NodeItem("ShaderNodeVolumePrincipled"), NodeItem("ShaderNodeEeveeSpecular", poll=object_eevee_shader_nodes_poll), ]), - ShaderNewNodeCategory("SH_NEW_TEXTURE", "Texture", items=[ + ShaderNodeCategory("SH_NEW_TEXTURE", "Texture", items=[ NodeItem("ShaderNodeTexImage"), NodeItem("ShaderNodeTexEnvironment"), NodeItem("ShaderNodeTexSky"), @@ -289,7 +230,7 @@ shader_node_categories = [ NodeItem("ShaderNodeTexBrick"), NodeItem("ShaderNodeTexPointDensity"), ]), - ShaderNewNodeCategory("SH_NEW_OP_COLOR", "Color", items=[ + ShaderNodeCategory("SH_NEW_OP_COLOR", "Color", items=[ NodeItem("ShaderNodeMixRGB"), NodeItem("ShaderNodeRGBCurve"), NodeItem("ShaderNodeInvert"), @@ -298,7 +239,7 @@ shader_node_categories = [ NodeItem("ShaderNodeGamma"), NodeItem("ShaderNodeBrightContrast"), ]), - ShaderNewNodeCategory("SH_NEW_OP_VECTOR", "Vector", items=[ + ShaderNodeCategory("SH_NEW_OP_VECTOR", "Vector", items=[ NodeItem("ShaderNodeMapping"), NodeItem("ShaderNodeBump"), NodeItem("ShaderNodeDisplacement"), @@ -308,7 +249,7 @@ shader_node_categories = [ NodeItem("ShaderNodeVectorCurve"), NodeItem("ShaderNodeVectorTransform"), ]), - ShaderNewNodeCategory("SH_NEW_CONVERTOR", "Converter", items=[ + ShaderNodeCategory("SH_NEW_CONVERTOR", "Converter", items=[ NodeItem("ShaderNodeMath"), NodeItem("ShaderNodeValToRGB"), NodeItem("ShaderNodeRGBToBW"), @@ -322,11 +263,11 @@ shader_node_categories = [ NodeItem("ShaderNodeWavelength"), NodeItem("ShaderNodeBlackbody"), ]), - ShaderNewNodeCategory("SH_NEW_SCRIPT", "Script", items=[ + ShaderNodeCategory("SH_NEW_SCRIPT", "Script", items=[ NodeItem("ShaderNodeScript"), ]), - ShaderNewNodeCategory("SH_NEW_GROUP", "Group", items=node_group_items), - ShaderNewNodeCategory("SH_NEW_LAYOUT", "Layout", items=[ + ShaderNodeCategory("SH_NEW_GROUP", "Group", items=node_group_items), + ShaderNodeCategory("SH_NEW_LAYOUT", "Layout", items=[ NodeItem("NodeFrame"), NodeItem("NodeReroute"), ]), diff --git a/release/scripts/templates_py/ui_list_simple.py b/release/scripts/templates_py/ui_list_simple.py index e911a0dd236..79c14c17c7e 100644 --- a/release/scripts/templates_py/ui_list_simple.py +++ b/release/scripts/templates_py/ui_list_simple.py @@ -28,18 +28,6 @@ class MATERIAL_UL_matslots_example(bpy.types.UIList): layout.prop(ma, "name", text="", emboss=False, icon_value=icon) else: layout.label(text="", translate=False, icon_value=icon) - # And now we can add other UI stuff... - # Here, we add nodes info if this material uses (old!) shading nodes. - if ma and not context.scene.render.use_shading_nodes: - manode = ma.active_node_material - if manode: - # The static method UILayout.icon returns the integer value of the icon ID "computed" for the given - # RNA object. - layout.label(text="Node %s" % manode.name, translate=False, icon_value=layout.icon(manode)) - elif ma.use_nodes: - layout.label(text="Node <none>", translate=False) - else: - layout.label(text="") # 'GRID' layout type should be as compact as possible (typically a single icon!). elif self.layout_type in {'GRID'}: layout.alignment = 'CENTER' diff --git a/source/blender/alembic/intern/abc_hair.cc b/source/blender/alembic/intern/abc_hair.cc index 70ca7a1a929..b31a185e39b 100644 --- a/source/blender/alembic/intern/abc_hair.cc +++ b/source/blender/alembic/intern/abc_hair.cc @@ -165,7 +165,7 @@ void AbcHairWriter::write_hair_sample(DerivedMesh *dm, psys_interpolate_uvs(tface, face->v4, pa->fuv, r_uv); uv_values.push_back(Imath::V2f(r_uv[0], r_uv[1])); - psys_interpolate_face(mverts, face, tface, NULL, mapfw, vec, normal, NULL, NULL, NULL, NULL); + psys_interpolate_face(mverts, face, tface, NULL, mapfw, vec, normal, NULL, NULL, NULL); copy_yup_from_zup(tmp_nor.getValue(), normal); norm_values.push_back(tmp_nor); @@ -273,7 +273,7 @@ void AbcHairWriter::write_hair_child_sample(DerivedMesh *dm, psys_interpolate_uvs(tface, face->v4, pc->fuv, r_uv); uv_values.push_back(Imath::V2f(r_uv[0], r_uv[1])); - psys_interpolate_face(mverts, face, tface, NULL, mapfw, vec, tmpnor, NULL, NULL, NULL, NULL); + psys_interpolate_face(mverts, face, tface, NULL, mapfw, vec, tmpnor, NULL, NULL, NULL); /* Convert Z-up to Y-up. */ norm_values.push_back(Imath::V3f(tmpnor[0], tmpnor[2], -tmpnor[1])); diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h index b038559e717..74416bcd18f 100644 --- a/source/blender/blenkernel/BKE_DerivedMesh.h +++ b/source/blender/blenkernel/BKE_DerivedMesh.h @@ -97,7 +97,6 @@ struct MCol; struct ColorBand; struct Depsgraph; struct GPUVertexAttribs; -struct GPUDrawObject; struct PBVH; /* number of sub-elements each mesh element has (for interpolation) */ @@ -127,34 +126,6 @@ typedef enum DerivedMeshType { DM_TYPE_CCGDM } DerivedMeshType; -typedef enum DMDrawOption { - /* the element is hidden or otherwise non-drawable */ - DM_DRAW_OPTION_SKIP = 0, - /* normal drawing */ - DM_DRAW_OPTION_NORMAL = 1, - /* draw, but don't set the color from mcol */ - DM_DRAW_OPTION_NO_MCOL = 2, - /* used in drawMappedFaces, use GL stipple for the face */ - DM_DRAW_OPTION_STIPPLE = 3, -} DMDrawOption; - -/* Drawing callback types */ -typedef int (*DMSetMaterial)(int mat_nr, void *attribs); -typedef int (*DMCompareDrawOptions)(void *userData, int cur_index, int next_index); -typedef void (*DMSetDrawInterpOptions)(void *userData, int index, float t); -typedef DMDrawOption (*DMSetDrawOptions)(void *userData, int index); - -typedef enum DMDrawFlag { - DM_DRAW_USE_COLORS = (1 << 0), - DM_DRAW_ALWAYS_SMOOTH = (1 << 1), - DM_DRAW_USE_ACTIVE_UV = (1 << 2), - DM_DRAW_USE_TEXPAINT_UV = (1 << 3), - DM_DRAW_SKIP_HIDDEN = (1 << 4), - DM_DRAW_SKIP_SELECT = (1 << 5), - DM_DRAW_SELECT_USE_EDITMODE = (1 << 6), - DM_DRAW_NEED_NORMALS = (1 << 7) -} DMDrawFlag; - typedef enum DMForeachFlag { DM_FOREACH_NOP = 0, DM_FOREACH_USE_NORMAL = (1 << 0), /* foreachMappedVert, foreachMappedLoop, foreachMappedFaceCenter */ @@ -163,14 +134,9 @@ typedef enum DMForeachFlag { typedef enum DMDirtyFlag { /* dm has valid tessellated faces, but tessellated CDDATA need to be updated. */ DM_DIRTY_TESS_CDLAYERS = 1 << 0, - /* One of the MCOL layers have been updated, force updating of GPUDrawObject's colors buffer. - * This is necessary with modern, VBO draw code, as e.g. in vpaint mode me->mcol may be updated - * without actually rebuilding dm (hence by default keeping same GPUDrawObject, and same colors - * buffer, which prevents update during a stroke!). */ - DM_DIRTY_MCOL_UPDATE_DRAW = 1 << 1, /* check this with modifier dependsOnNormals callback to see if normals need recalculation */ - DM_DIRTY_NORMALS = 1 << 2, + DM_DIRTY_NORMALS = 1 << 1, } DMDirtyFlag; typedef struct DerivedMesh DerivedMesh; @@ -181,9 +147,7 @@ struct DerivedMesh { int needsFree; /* checked on ->release, is set to 0 for cached results */ int deformedOnly; /* set by modifier stack if only deformed from original */ BVHCache *bvhCache; - struct GPUDrawObject *drawObject; DerivedMeshType type; - float auto_bump_scale; DMDirtyFlag dirty; int totmat; /* total materials. Will be valid only before object drawing. */ struct Material **mat; /* material array. Will be valid only before object drawing */ @@ -383,98 +347,6 @@ struct DerivedMesh { */ struct PBVH *(*getPBVH)(struct Object *ob, DerivedMesh *dm); - /* Drawing Operations */ - - /** Draw all vertices as bgl points (no options) */ - void (*drawVerts)(DerivedMesh *dm); - - /** Draw all edges as lines (no options) - * - * Also called for *final* editmode DerivedMeshes - */ - void (*drawEdges)(DerivedMesh *dm, bool drawLooseEdges, bool drawAllEdges); - - /** Draw all loose edges (edges w/ no adjoining faces) */ - void (*drawLooseEdges)(DerivedMesh *dm); - - /** Draw all faces - * o Set face normal or vertex normal based on inherited face flag - * o Use inherited face material index to call setMaterial - * o Only if setMaterial returns true - * - * Also called for *final* editmode DerivedMeshes - */ - void (*drawFacesSolid)(DerivedMesh *dm, float (*partial_redraw_planes)[4], - bool fast, DMSetMaterial setMaterial); - - /** Draw all faces with GLSL materials - * o setMaterial is called for every different material nr - * o Only if setMaterial returns true - */ - void (*drawFacesGLSL)(DerivedMesh *dm, DMSetMaterial setMaterial); - - /** Draw mapped faces (no color, or texture) - * - Only if !setDrawOptions or - * setDrawOptions(userData, mapped-face-index, r_drawSmooth) - * returns true - * - * If drawSmooth is set to true then vertex normals should be set and - * glShadeModel called with GL_SMOOTH. Otherwise the face normal should - * be set and glShadeModel called with GL_FLAT. - * - * The setDrawOptions is allowed to not set drawSmooth (for example, when - * lighting is disabled), in which case the implementation should draw as - * smooth shaded. - */ - void (*drawMappedFaces)(DerivedMesh *dm, - DMSetDrawOptions setDrawOptions, - DMSetMaterial setMaterial, - DMCompareDrawOptions compareDrawOptions, - void *userData, - DMDrawFlag flag); - - /** Draw mapped faces with GLSL materials - * - setMaterial is called for every different material nr - * - setDrawOptions is called for every face - * - Only if setMaterial and setDrawOptions return true - */ - void (*drawMappedFacesGLSL)(DerivedMesh *dm, - DMSetMaterial setMaterial, - DMSetDrawOptions setDrawOptions, - void *userData); - - /** Draw mapped edges as lines - * - Only if !setDrawOptions or setDrawOptions(userData, mapped-edge) - * returns true - */ - void (*drawMappedEdges)(DerivedMesh *dm, - DMSetDrawOptions setDrawOptions, - void *userData); - - /** Draw mapped edges as lines with interpolation values - * - Only if !setDrawOptions or - * setDrawOptions(userData, mapped-edge, mapped-v0, mapped-v1, t) - * returns true - * - * NOTE: This routine is optional! - */ - void (*drawMappedEdgesInterp)(DerivedMesh *dm, - DMSetDrawOptions setDrawOptions, - DMSetDrawInterpOptions setDrawInterpOptions, - void *userData); - - /** Draw all faces with materials - * - setMaterial is called for every different material nr - * - setFace is called to verify if a face must be hidden - */ - void (*drawMappedFacesMat)(DerivedMesh *dm, - void (*setMaterial)(void *userData, int matnr, void *attribs), - bool (*setFace)(void *userData, int index), void *userData); - - struct GPUDrawObject *(*gpuObjectNew)(DerivedMesh *dm); - void (*copy_gpu_data)(DerivedMesh *dm, int type, void *varray_p, - const int *mat_orig_to_new, const void *user_data); - /** Release reference to the DerivedMesh. This function decides internally * if the DerivedMesh will be freed, or cached for later use. */ void (*release)(DerivedMesh *dm); @@ -756,9 +628,6 @@ void DM_vertex_attributes_from_gpu( DerivedMesh *dm, struct GPUVertexAttribs *gattribs, DMVertexAttribs *attribs); -void DM_draw_attrib_vertex(DMVertexAttribs *attribs, int a, int index, int vert, int loop); -void DM_draw_attrib_vertex_uniforms(const DMVertexAttribs *attribs); - void DM_calc_tangents_names_from_gpu( const struct GPUVertexAttribs *gattribs, char (*tangent_names)[MAX_NAME], int *tangent_names_count); diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h index 0c22edc5430..a16bdbb0683 100644 --- a/source/blender/blenkernel/BKE_blender_version.h +++ b/source/blender/blenkernel/BKE_blender_version.h @@ -28,7 +28,7 @@ * and keep comment above the defines. * Use STRINGIFY() rather than defining with quotes */ #define BLENDER_VERSION 280 -#define BLENDER_SUBVERSION 7 +#define BLENDER_SUBVERSION 8 /* Several breakages with 270, e.g. constraint deg vs rad */ #define BLENDER_MINVERSION 270 #define BLENDER_MINSUBVERSION 6 diff --git a/source/blender/blenkernel/BKE_camera.h b/source/blender/blenkernel/BKE_camera.h index 5e79f641c97..c647dd3cc0f 100644 --- a/source/blender/blenkernel/BKE_camera.h +++ b/source/blender/blenkernel/BKE_camera.h @@ -93,11 +93,6 @@ typedef struct CameraParams { float clipsta; float clipend; - /* fields */ - int use_fields; - int field_second; - int field_odd; - /* computed viewplane */ float ycor; float viewdx; diff --git a/source/blender/blenkernel/BKE_material.h b/source/blender/blenkernel/BKE_material.h index d57d0ea1a97..43f36618c19 100644 --- a/source/blender/blenkernel/BKE_material.h +++ b/source/blender/blenkernel/BKE_material.h @@ -87,10 +87,6 @@ short BKE_object_material_slot_find_index(struct Object *ob, struct Material *ma bool BKE_object_material_slot_add(struct Object *ob); bool BKE_object_material_slot_remove(struct Object *ob); -struct Image *BKE_object_material_edit_image_get(struct Object *ob, short mat_nr); -struct Image **BKE_object_material_edit_image_get_array(struct Object *ob); -bool BKE_object_material_edit_image_set(struct Object *ob, short mat_nr, struct Image *image); - void BKE_texpaint_slot_refresh_cache(struct Scene *scene, struct Material *ma); void BKE_texpaint_slots_refresh_object(struct Scene *scene, struct Object *ob); @@ -101,13 +97,6 @@ struct Material *BKE_material_pop_id(struct Main *bmain, struct ID *id, int inde void BKE_material_clear_id(struct Main *bmain, struct ID *id, bool update_data); /* rendering */ -void init_render_material(struct Material *, int, float *); -void init_render_materials(struct Main *, int r_mode, float *amd, bool do_default_material); -void end_render_material(struct Material *); -void end_render_materials(struct Main *); - -bool material_in_material(struct Material *parmat, struct Material *mat); - void ramp_blend(int type, float r_col[3], const float fac, const float col[3]); /* copy/paste */ diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 2907b568c00..d85f4095eb9 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -498,7 +498,6 @@ struct bNode *nodeGetActiveTexture(struct bNodeTree *ntree); void nodeUpdate(struct bNodeTree *ntree, struct bNode *node); bool nodeUpdateID(struct bNodeTree *ntree, struct ID *id); void nodeUpdateInternalLinks(struct bNodeTree *ntree, struct bNode *node); -void nodeSynchronizeID(struct bNode *node, bool copy_to_id); int nodeSocketIsHidden(struct bNodeSocket *sock); void ntreeTagUsedSockets(struct bNodeTree *ntree); @@ -702,24 +701,22 @@ void BKE_nodetree_remove_layer_n(struct bNodeTree *ntree, struct Scene *scene, c /* -------------------------------------------------------------------- */ /** \name Shader Nodes * \{ */ -struct ShadeInput; -struct ShadeResult; /* note: types are needed to restore callbacks, don't change values */ /* range 1 - 100 is reserved for common nodes */ /* using toolbox, we add node groups by assuming the values below don't exceed NODE_GROUP_MENU for now */ -#define SH_NODE_OUTPUT 1 +//#define SH_NODE_OUTPUT 1 -#define SH_NODE_MATERIAL 100 +//#define SH_NODE_MATERIAL 100 #define SH_NODE_RGB 101 #define SH_NODE_VALUE 102 #define SH_NODE_MIX_RGB 103 #define SH_NODE_VALTORGB 104 #define SH_NODE_RGBTOBW 105 -#define SH_NODE_TEXTURE 106 +//#define SH_NODE_TEXTURE 106 #define SH_NODE_NORMAL 107 -#define SH_NODE_GEOMETRY 108 +//#define SH_NODE_GEOMETRY 108 #define SH_NODE_MAPPING 109 #define SH_NODE_CURVE_VEC 110 #define SH_NODE_CURVE_RGB 111 @@ -727,7 +724,7 @@ struct ShadeResult; #define SH_NODE_MATH 115 #define SH_NODE_VECT_MATH 116 #define SH_NODE_SQUEEZE 117 -#define SH_NODE_MATERIAL_EXT 118 +//#define SH_NODE_MATERIAL_EXT 118 #define SH_NODE_INVERT 119 #define SH_NODE_SEPRGB 120 #define SH_NODE_COMBRGB 121 @@ -813,12 +810,7 @@ struct ShadeResult; struct bNodeTreeExec *ntreeShaderBeginExecTree(struct bNodeTree *ntree); void ntreeShaderEndExecTree(struct bNodeTreeExec *exec); -bool ntreeShaderExecTree(struct bNodeTree *ntree, struct ShadeInput *shi, struct ShadeResult *shr); -void ntreeShaderGetTexcoMode(struct bNodeTree *ntree, int osa, short *texco, int *mode); - -/* switch material render loop */ -extern void (*node_shader_lamp_loop)(struct ShadeInput *, struct ShadeResult *); -void set_node_shader_lamp_loop(void (*lamp_loop_func)(struct ShadeInput *, struct ShadeResult *)); +bool ntreeShaderExecTree(struct bNodeTree *ntree, int thread); void ntreeGPUMaterialNodes(struct bNodeTree *ntree, struct GPUMaterial *mat, short compatibility); void ntreeGPUMaterialDomain(struct bNodeTree *ntree, bool *has_surface_output, bool *has_volume_output); @@ -1051,7 +1043,7 @@ struct bNodeTreeExec *ntreeTexBeginExecTree(struct bNodeTree *ntree); void ntreeTexEndExecTree(struct bNodeTreeExec *exec); int ntreeTexExecTree(struct bNodeTree *ntree, struct TexResult *target, float coord[3], float dxt[3], float dyt[3], int osatex, const short thread, - struct Tex *tex, short which_output, int cfra, int preview, struct ShadeInput *shi, struct MTex *mtex); + struct Tex *tex, short which_output, int cfra, int preview, struct MTex *mtex); /** \} */ void init_nodesystem(void); diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h index 05082ed1a70..0c8d00e16a3 100644 --- a/source/blender/blenkernel/BKE_particle.h +++ b/source/blender/blenkernel/BKE_particle.h @@ -324,7 +324,7 @@ void copy_particle_key(struct ParticleKey *to, struct ParticleKey *from, int tim CustomDataMask psys_emitter_customdata_mask(struct ParticleSystem *psys); void psys_particle_on_emitter(struct ParticleSystemModifierData *psmd, int distr, int index, int index_dmcache, float fuv[4], float foffset, float vec[3], float nor[3], - float utan[3], float vtan[3], float orco[3], float ornor[3]); + float utan[3], float vtan[3], float orco[3]); struct ParticleSystemModifierData *psys_get_modifier(struct Object *ob, struct ParticleSystem *psys); struct ModifierData *object_add_particle_system(struct Scene *scene, struct Object *ob, const char *name); @@ -356,7 +356,7 @@ void BKE_particlesettings_clump_curve_init(struct ParticleSettings *part); void BKE_particlesettings_rough_curve_init(struct ParticleSettings *part); void BKE_particlesettings_twist_curve_init(struct ParticleSettings *part); void psys_apply_child_modifiers(struct ParticleThreadContext *ctx, struct ListBase *modifiers, - struct ChildParticle *cpa, struct ParticleTexture *ptex, const float orco[3], const float ornor[3], float hairmat[4][4], + struct ChildParticle *cpa, struct ParticleTexture *ptex, const float orco[3], float hairmat[4][4], struct ParticleCacheKey *keys, struct ParticleCacheKey *parent_keys, const float parent_orco[3]); void psys_sph_init(struct ParticleSimulationData *sim, struct SPHData *sphdata); @@ -422,7 +422,7 @@ float *psys_cache_vgroup(struct DerivedMesh *dm, struct ParticleSystem *psys, in void psys_get_texture(struct ParticleSimulationData *sim, struct ParticleData *pa, struct ParticleTexture *ptex, int event, float cfra); void psys_interpolate_face(struct MVert *mvert, struct MFace *mface, struct MTFace *tface, float (*orcodata)[3], float w[4], float vec[3], float nor[3], float utan[3], float vtan[3], - float orco[3], float ornor[3]); + float orco[3]); float psys_particle_value_from_verts(struct DerivedMesh *dm, short from, struct ParticleData *pa, float *values); void psys_get_from_key(struct ParticleKey *key, float loc[3], float vel[3], float rot[4], float *time); @@ -430,7 +430,7 @@ void psys_get_from_key(struct ParticleKey *key, float loc[3], float vel[3], floa void BKE_psys_collision_neartest_cb(void *userdata, int index, const struct BVHTreeRay *ray, struct BVHTreeRayHit *hit); void psys_particle_on_dm(struct DerivedMesh *dm_final, int from, int index, int index_dmcache, const float fw[4], float foffset, float vec[3], float nor[3], float utan[3], float vtan[3], - float orco[3], float ornor[3]); + float orco[3]); /* particle_system.c */ void distribute_particles(struct ParticleSimulationData *sim, int from); diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h index 5f37aa25de7..c18288de1bc 100644 --- a/source/blender/blenkernel/BKE_pbvh.h +++ b/source/blender/blenkernel/BKE_pbvh.h @@ -129,10 +129,6 @@ bool BKE_pbvh_node_find_nearest_to_ray( /* Drawing */ -void BKE_pbvh_node_draw(PBVHNode *node, void *data); -void BKE_pbvh_draw(PBVH *bvh, float (*planes)[4], float (*face_nors)[3], - int (*setMaterial)(int matnr, void *attribs), bool wireframe, bool fast); -void BKE_pbvh_draw_BB(PBVH *bvh); void BKE_pbvh_draw_cb( PBVH *bvh, float (*planes)[4], float (*fnors)[3], bool fast, void (*draw_fn)(void *user_data, struct Gwn_Batch *batch), void *user_data); @@ -225,7 +221,7 @@ struct GSet *BKE_pbvh_bmesh_node_faces(PBVHNode *node); void BKE_pbvh_bmesh_node_save_orig(PBVHNode *node); void BKE_pbvh_bmesh_after_stroke(PBVH *bvh); -/* Update Normals/Bounding Box/Draw Buffers/Redraw and clear flags */ +/* Update Normals/Bounding Box/Redraw and clear flags */ void BKE_pbvh_update(PBVH *bvh, int flags, float (*face_nors)[3]); void BKE_pbvh_redraw_BB(PBVH *bvh, float bb_min[3], float bb_max[3]); diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h index 75392c42bf3..bdbed9ab6aa 100644 --- a/source/blender/blenkernel/BKE_scene.h +++ b/source/blender/blenkernel/BKE_scene.h @@ -151,16 +151,12 @@ bool BKE_scene_remove_render_view(struct Scene *scene, struct SceneRenderView *s /* render profile */ int get_render_subsurf_level(const struct RenderData *r, int level, bool for_render); int get_render_child_particle_number(const struct RenderData *r, int num, bool for_render); -int get_render_shadow_samples(const struct RenderData *r, int samples); -float get_render_aosss_error(const struct RenderData *r, float error); -bool BKE_scene_use_new_shading_nodes(const struct Scene *scene); bool BKE_scene_use_shading_nodes_custom(struct Scene *scene); -bool BKE_scene_use_world_space_shading(struct Scene *scene); bool BKE_scene_use_spherical_stereo(struct Scene *scene); -bool BKE_scene_uses_blender_internal(const struct Scene *scene); bool BKE_scene_uses_blender_eevee(const struct Scene *scene); +bool BKE_scene_uses_cycles(const struct Scene *scene); void BKE_scene_disable_color_management(struct Scene *scene); bool BKE_scene_check_color_management_enabled(const struct Scene *scene); diff --git a/source/blender/blenkernel/BKE_sequencer.h b/source/blender/blenkernel/BKE_sequencer.h index c0116f6dd56..cd173ef33ce 100644 --- a/source/blender/blenkernel/BKE_sequencer.h +++ b/source/blender/blenkernel/BKE_sequencer.h @@ -437,7 +437,7 @@ enum { typedef struct ImBuf *(*SequencerDrawView)( struct Depsgraph *depsgraph, struct Scene *scene, - struct ViewLayer *view_layer, int drawtype, + int drawtype, struct Object *camera, int width, int height, unsigned int flag, unsigned int draw_flags, int alpha_mode, int samples, const char *viewname, diff --git a/source/blender/blenkernel/BKE_texture.h b/source/blender/blenkernel/BKE_texture.h index 4e98852c995..ed6aa3f6af9 100644 --- a/source/blender/blenkernel/BKE_texture.h +++ b/source/blender/blenkernel/BKE_texture.h @@ -40,7 +40,6 @@ extern "C" { struct bNode; struct Brush; struct ColorBand; -struct EnvMap; struct FreestyleLineStyle; struct ImagePool; struct Lamp; @@ -53,7 +52,6 @@ struct PointDensity; struct Tex; struct TexMapping; struct TexResult; -struct VoxelData; struct World; /* in ColorBand struct */ @@ -76,27 +74,17 @@ struct MTex *BKE_texture_mtex_add_id(struct ID *id, int slot); // void autotexname(struct Tex *tex); struct Tex *give_current_object_texture(struct Object *ob); -struct Tex *give_current_material_texture(struct Material *ma); -struct Tex *give_current_lamp_texture(struct Lamp *la); struct Tex *give_current_linestyle_texture(struct FreestyleLineStyle *linestyle); -struct Tex *give_current_world_texture(struct World *world); struct Tex *give_current_brush_texture(struct Brush *br); struct Tex *give_current_particle_texture(struct ParticleSettings *part); -struct bNode *give_current_material_texture_node(struct Material *ma); - bool give_active_mtex(struct ID *id, struct MTex ***mtex_ar, short *act); void set_active_mtex(struct ID *id, short act); void set_current_brush_texture(struct Brush *br, struct Tex *tex); -void set_current_world_texture(struct World *wo, struct Tex *tex); -void set_current_material_texture(struct Material *ma, struct Tex *tex); -void set_current_lamp_texture(struct Lamp *la, struct Tex *tex); void set_current_linestyle_texture(struct FreestyleLineStyle *linestyle, struct Tex *tex); void set_current_particle_texture(struct ParticleSettings *part, struct Tex *tex); -bool has_current_material_texture(struct Material *ma); - struct TexMapping *BKE_texture_mapping_add(int type); void BKE_texture_mapping_default(struct TexMapping *texmap, int type); void BKE_texture_mapping_init(struct TexMapping *texmap); @@ -104,26 +92,12 @@ void BKE_texture_mapping_init(struct TexMapping *texmap); struct ColorMapping *BKE_texture_colormapping_add(void); void BKE_texture_colormapping_default(struct ColorMapping *colormap); -void BKE_texture_envmap_free_data(struct EnvMap *env); -void BKE_texture_envmap_free(struct EnvMap *env); -struct EnvMap *BKE_texture_envmap_add(void); -struct EnvMap *BKE_texture_envmap_copy(const struct EnvMap *env, const int flag); - void BKE_texture_pointdensity_init_data(struct PointDensity *pd); void BKE_texture_pointdensity_free_data(struct PointDensity *pd); void BKE_texture_pointdensity_free(struct PointDensity *pd); struct PointDensity *BKE_texture_pointdensity_add(void); struct PointDensity *BKE_texture_pointdensity_copy(const struct PointDensity *pd, const int flag); -void BKE_texture_voxeldata_free_data(struct VoxelData *vd); -void BKE_texture_voxeldata_free(struct VoxelData *vd); -struct VoxelData *BKE_texture_voxeldata_add(void); -struct VoxelData *BKE_texture_voxeldata_copy(struct VoxelData *vd); - -void BKE_texture_ocean_free(struct OceanTex *ot); -struct OceanTex *BKE_texture_ocean_add(void); -struct OceanTex *BKE_texture_ocean_copy(const struct OceanTex *ot, const int flag); - bool BKE_texture_dependsOnTime(const struct Tex *texture); bool BKE_texture_is_image_user(const struct Tex *tex); diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index bcdcdaa30cc..648af413bbe 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -72,10 +72,6 @@ #include "BLI_sys_types.h" /* for intptr_t support */ -#include "GPU_buffers.h" -#include "GPU_shader.h" -#include "GPU_immediate.h" - #include "DEG_depsgraph.h" #include "DEG_depsgraph_query.h" @@ -348,7 +344,6 @@ void DM_init( DM_init_funcs(dm); dm->needsFree = 1; - dm->auto_bump_scale = -1.0f; dm->dirty = 0; /* don't use CustomData_reset(...); because we dont want to touch customdata */ @@ -405,7 +400,6 @@ int DM_release(DerivedMesh *dm) { if (dm->needsFree) { bvhcache_free(&dm->bvhCache); - GPU_drawobject_free(dm); CustomData_free(&dm->vertData, dm->numVertData); CustomData_free(&dm->edgeData, dm->numEdgeData); CustomData_free(&dm->faceData, dm->numTessFaceData); @@ -3002,21 +2996,6 @@ void mesh_get_mapped_verts_coords(DerivedMesh *dm, float (*r_cos)[3], const int } } -/* ******************* GLSL ******************** */ - -void DM_calc_tangents_names_from_gpu( - const GPUVertexAttribs *gattribs, - char (*tangent_names)[MAX_NAME], int *r_tangent_names_count) -{ - int count = 0; - for (int b = 0; b < gattribs->totlayer; b++) { - if (gattribs->layer[b].type == CD_TANGENT) { - strcpy(tangent_names[count++], gattribs->layer[b].name); - } - } - *r_tangent_names_count = count; -} - void DM_add_named_tangent_layer_for_uv( CustomData *uv_data, CustomData *tan_data, int numLoopData, const char *layer_name) @@ -3050,397 +3029,6 @@ void DM_calc_loop_tangents( &dm->tangent_mask); } -void DM_calc_auto_bump_scale(DerivedMesh *dm) -{ - /* int totvert = dm->getNumVerts(dm); */ /* UNUSED */ - int totface = dm->getNumTessFaces(dm); - - MVert *mvert = dm->getVertArray(dm); - MFace *mface = dm->getTessFaceArray(dm); - MTFace *mtface = dm->getTessFaceDataArray(dm, CD_MTFACE); - - if (mtface) { - double dsum = 0.0; - int nr_accumulated = 0; - int f; - - for (f = 0; f < totface; f++) { - { - float *verts[4], *tex_coords[4]; - const int nr_verts = mface[f].v4 != 0 ? 4 : 3; - bool is_degenerate; - int i; - - verts[0] = mvert[mface[f].v1].co; verts[1] = mvert[mface[f].v2].co; verts[2] = mvert[mface[f].v3].co; - tex_coords[0] = mtface[f].uv[0]; tex_coords[1] = mtface[f].uv[1]; tex_coords[2] = mtface[f].uv[2]; - if (nr_verts == 4) { - verts[3] = mvert[mface[f].v4].co; - tex_coords[3] = mtface[f].uv[3]; - } - - /* discard degenerate faces */ - is_degenerate = 0; - if (equals_v3v3(verts[0], verts[1]) || - equals_v3v3(verts[0], verts[2]) || - equals_v3v3(verts[1], verts[2]) || - equals_v2v2(tex_coords[0], tex_coords[1]) || - equals_v2v2(tex_coords[0], tex_coords[2]) || - equals_v2v2(tex_coords[1], tex_coords[2])) - { - is_degenerate = 1; - } - - /* verify last vertex as well if this is a quad */ - if (is_degenerate == 0 && nr_verts == 4) { - if (equals_v3v3(verts[3], verts[0]) || - equals_v3v3(verts[3], verts[1]) || - equals_v3v3(verts[3], verts[2]) || - equals_v2v2(tex_coords[3], tex_coords[0]) || - equals_v2v2(tex_coords[3], tex_coords[1]) || - equals_v2v2(tex_coords[3], tex_coords[2])) - { - is_degenerate = 1; - } - - /* verify the winding is consistent */ - if (is_degenerate == 0) { - float prev_edge[2]; - bool is_signed = 0; - sub_v2_v2v2(prev_edge, tex_coords[0], tex_coords[3]); - - i = 0; - while (is_degenerate == 0 && i < 4) { - float cur_edge[2], signed_area; - sub_v2_v2v2(cur_edge, tex_coords[(i + 1) & 0x3], tex_coords[i]); - signed_area = cross_v2v2(prev_edge, cur_edge); - - if (i == 0) { - is_signed = (signed_area < 0.0f) ? 1 : 0; - } - else if ((is_signed != 0) != (signed_area < 0.0f)) { - is_degenerate = 1; - } - - if (is_degenerate == 0) { - copy_v2_v2(prev_edge, cur_edge); - i++; - } - } - } - } - - /* proceed if not a degenerate face */ - if (is_degenerate == 0) { - int nr_tris_to_pile = 0; - /* quads split at shortest diagonal */ - int offs = 0; /* initial triangulation is 0,1,2 and 0, 2, 3 */ - if (nr_verts == 4) { - float pos_len_diag0, pos_len_diag1; - - pos_len_diag0 = len_squared_v3v3(verts[2], verts[0]); - pos_len_diag1 = len_squared_v3v3(verts[3], verts[1]); - - if (pos_len_diag1 < pos_len_diag0) { - offs = 1; // alter split - } - else if (pos_len_diag0 == pos_len_diag1) { /* do UV check instead */ - float tex_len_diag0, tex_len_diag1; - - tex_len_diag0 = len_squared_v2v2(tex_coords[2], tex_coords[0]); - tex_len_diag1 = len_squared_v2v2(tex_coords[3], tex_coords[1]); - - if (tex_len_diag1 < tex_len_diag0) { - offs = 1; /* alter split */ - } - } - } - nr_tris_to_pile = nr_verts - 2; - if (nr_tris_to_pile == 1 || nr_tris_to_pile == 2) { - const int indices[6] = {offs + 0, offs + 1, offs + 2, offs + 0, offs + 2, (offs + 3) & 0x3 }; - int t; - for (t = 0; t < nr_tris_to_pile; t++) { - float f2x_area_uv; - const float *p0 = verts[indices[t * 3 + 0]]; - const float *p1 = verts[indices[t * 3 + 1]]; - const float *p2 = verts[indices[t * 3 + 2]]; - - float edge_t0[2], edge_t1[2]; - sub_v2_v2v2(edge_t0, tex_coords[indices[t * 3 + 1]], tex_coords[indices[t * 3 + 0]]); - sub_v2_v2v2(edge_t1, tex_coords[indices[t * 3 + 2]], tex_coords[indices[t * 3 + 0]]); - - f2x_area_uv = fabsf(cross_v2v2(edge_t0, edge_t1)); - if (f2x_area_uv > FLT_EPSILON) { - float norm[3], v0[3], v1[3], f2x_surf_area, fsurf_ratio; - sub_v3_v3v3(v0, p1, p0); - sub_v3_v3v3(v1, p2, p0); - cross_v3_v3v3(norm, v0, v1); - - f2x_surf_area = len_v3(norm); - fsurf_ratio = f2x_surf_area / f2x_area_uv; /* tri area divided by texture area */ - - nr_accumulated++; - dsum += (double)(fsurf_ratio); - } - } - } - } - } - } - - /* finalize */ - { - const float avg_area_ratio = (nr_accumulated > 0) ? ((float)(dsum / nr_accumulated)) : 1.0f; - const float use_as_render_bump_scale = sqrtf(avg_area_ratio); // use width of average surface ratio as your bump scale - dm->auto_bump_scale = use_as_render_bump_scale; - } - } - else { - dm->auto_bump_scale = 1.0f; - } -} - -void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs, DMVertexAttribs *attribs) -{ - CustomData *vdata, *ldata; - int a, b, layer; - const bool is_editmesh = (dm->type == DM_TYPE_EDITBMESH); - - /* From the layers requested by the GLSL shader, figure out which ones are - * actually available for this derivedmesh, and retrieve the pointers */ - - memset(attribs, 0, sizeof(DMVertexAttribs)); - - vdata = &dm->vertData; - ldata = dm->getLoopDataLayout(dm); - - /* calc auto bump scale if necessary */ - if (dm->auto_bump_scale <= 0.0f) - DM_calc_auto_bump_scale(dm); - - char tangent_names[MAX_MTFACE][MAX_NAME]; - int tangent_names_count; - /* Add a tangent layer/layers. */ - DM_calc_tangents_names_from_gpu(gattribs, tangent_names, &tangent_names_count); - - if (tangent_names_count) - dm->calcLoopTangents(dm, false, (const char (*)[MAX_NAME])tangent_names, tangent_names_count); - - for (b = 0; b < gattribs->totlayer; b++) { - int type = gattribs->layer[b].type; - layer = -1; - if (type == CD_AUTO_FROM_NAME) { - /* We need to deduct what exact layer is used. - * - * We do it based on the specified name. - */ - if (gattribs->layer[b].name[0]) { - layer = CustomData_get_named_layer_index(ldata, CD_MLOOPUV, gattribs->layer[b].name); - type = CD_MTFACE; - if (layer == -1) { - layer = CustomData_get_named_layer_index(ldata, CD_MLOOPCOL, gattribs->layer[b].name); - type = CD_MCOL; - } - if (layer == -1) { - layer = CustomData_get_named_layer_index(&dm->loopData, CD_TANGENT, gattribs->layer[b].name); - type = CD_TANGENT; - } - if (layer == -1) { - continue; - } - } - else { - /* Fall back to the UV layer, which matches old behavior. */ - type = CD_MTFACE; - } - } - if (type == CD_MTFACE) { - /* uv coordinates */ - if (layer == -1) { - if (gattribs->layer[b].name[0]) - layer = CustomData_get_named_layer_index(ldata, CD_MLOOPUV, gattribs->layer[b].name); - else - layer = CustomData_get_active_layer_index(ldata, CD_MLOOPUV); - } - - a = attribs->tottface++; - - if (layer != -1) { - attribs->tface[a].array = is_editmesh ? NULL : ldata->layers[layer].data; - attribs->tface[a].em_offset = ldata->layers[layer].offset; - } - else { - attribs->tface[a].array = NULL; - attribs->tface[a].em_offset = -1; - } - - attribs->tface[a].gl_index = gattribs->layer[b].glindex; - attribs->tface[a].gl_info_index = gattribs->layer[b].glinfoindoex; - attribs->tface[a].gl_texco = gattribs->layer[b].gltexco; - } - else if (type == CD_MCOL) { - if (layer == -1) { - if (gattribs->layer[b].name[0]) - layer = CustomData_get_named_layer_index(ldata, CD_MLOOPCOL, gattribs->layer[b].name); - else - layer = CustomData_get_active_layer_index(ldata, CD_MLOOPCOL); - } - - a = attribs->totmcol++; - - if (layer != -1) { - attribs->mcol[a].array = is_editmesh ? NULL : ldata->layers[layer].data; - /* odd, store the offset for a different layer type here, but editmode draw code expects it */ - attribs->mcol[a].em_offset = ldata->layers[layer].offset; - } - else { - attribs->mcol[a].array = NULL; - attribs->mcol[a].em_offset = -1; - } - - attribs->mcol[a].gl_index = gattribs->layer[b].glindex; - attribs->mcol[a].gl_info_index = gattribs->layer[b].glinfoindoex; - } - else if (type == CD_TANGENT) { - /* note, even with 'is_editmesh' this uses the derived-meshes loop data */ - if (layer == -1) { - if (gattribs->layer[b].name[0]) - layer = CustomData_get_named_layer_index(&dm->loopData, CD_TANGENT, gattribs->layer[b].name); - else - layer = CustomData_get_active_layer_index(&dm->loopData, CD_TANGENT); - } - - a = attribs->tottang++; - - if (layer != -1) { - attribs->tang[a].array = dm->loopData.layers[layer].data; - attribs->tang[a].em_offset = dm->loopData.layers[layer].offset; - } - else { - attribs->tang[a].array = NULL; - attribs->tang[a].em_offset = -1; - } - - attribs->tang[a].gl_index = gattribs->layer[b].glindex; - attribs->tang[a].gl_info_index = gattribs->layer[b].glinfoindoex; - } - else if (type == CD_ORCO) { - /* original coordinates */ - if (layer == -1) { - layer = CustomData_get_layer_index(vdata, CD_ORCO); - } - attribs->totorco = 1; - - if (layer != -1) { - attribs->orco.array = vdata->layers[layer].data; - attribs->orco.em_offset = vdata->layers[layer].offset; - } - else { - attribs->orco.array = NULL; - attribs->orco.em_offset = -1; - } - - attribs->orco.gl_index = gattribs->layer[b].glindex; - attribs->orco.gl_texco = gattribs->layer[b].gltexco; - attribs->orco.gl_info_index = gattribs->layer[b].glinfoindoex; - } - } -} - -/** - * Set vertex shader attribute inputs for a particular tessface vert - * - * \param a: tessface index - * \param index: vertex index - * \param vert: corner index (0, 1, 2, 3) - * \param loop: absolute loop corner index - */ -void DM_draw_attrib_vertex(DMVertexAttribs *attribs, int a, int index, int vert, int loop) -{ - const float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f}; - int b; - - UNUSED_VARS(a, vert); - - /* orco texture coordinates */ - if (attribs->totorco) { - /*const*/ float (*array)[3] = attribs->orco.array; - const float *orco = (array) ? array[index] : zero; - - if (attribs->orco.gl_texco) - glTexCoord3fv(orco); - else - glVertexAttrib3fv(attribs->orco.gl_index, orco); - } - - /* uv texture coordinates */ - for (b = 0; b < attribs->tottface; b++) { - const float *uv; - - if (attribs->tface[b].array) { - const MLoopUV *mloopuv = &attribs->tface[b].array[loop]; - uv = mloopuv->uv; - } - else { - uv = zero; - } - - if (attribs->tface[b].gl_texco) - glTexCoord2fv(uv); - else - glVertexAttrib2fv(attribs->tface[b].gl_index, uv); - } - - /* vertex colors */ - for (b = 0; b < attribs->totmcol; b++) { - GLfloat col[4]; - - if (attribs->mcol[b].array) { - const MLoopCol *cp = &attribs->mcol[b].array[loop]; - rgba_uchar_to_float(col, &cp->r); - } - else { - zero_v4(col); - } - - glVertexAttrib4fv(attribs->mcol[b].gl_index, col); - } - - /* tangent for normal mapping */ - for (b = 0; b < attribs->tottang; b++) { - if (attribs->tang[b].array) { - /*const*/ float (*array)[4] = attribs->tang[b].array; - const float *tang = (array) ? array[loop] : zero; - glVertexAttrib4fv(attribs->tang[b].gl_index, tang); - } - } -} - -void DM_draw_attrib_vertex_uniforms(const DMVertexAttribs *attribs) -{ - int i; - if (attribs->totorco) { - if (attribs->orco.gl_info_index != -1) { - glUniform1i(attribs->orco.gl_info_index, 0); - } - } - for (i = 0; i < attribs->tottface; i++) { - if (attribs->tface[i].gl_info_index != -1) { - glUniform1i(attribs->tface[i].gl_info_index, 0); - } - } - for (i = 0; i < attribs->totmcol; i++) { - if (attribs->mcol[i].gl_info_index != -1) { - glUniform1i(attribs->mcol[i].gl_info_index, GPU_ATTR_INFO_SRGB); - } - } - - for (i = 0; i < attribs->tottang; i++) { - if (attribs->tang[i].gl_info_index != -1) { - glUniform1i(attribs->tang[i].gl_info_index, 0); - } - } -} - /* Set object's bounding box based on DerivedMesh min/max data */ void DM_set_object_boundbox(Object *ob, DerivedMesh *dm) { diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index aa8fd6f3870..924179d5b83 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -602,36 +602,8 @@ char *BKE_animdata_driver_path_hack(bContext *C, PointerRNA *ptr, PropertyRNA *p Object *ob = CTX_data_active_object(C); if (ob && id) { - /* only id-types which can be remapped to go through objects should be considered */ - switch (GS(id->name)) { - case ID_TE: /* textures */ - { - Material *ma = give_current_material(ob, ob->actcol); - Tex *tex = give_current_material_texture(ma); - - /* assumes: texture will only be shown if it is active material's active texture it's ok */ - if ((ID *)tex == id) { - char name_esc_ma[(sizeof(ma->id.name) - 2) * 2]; - char name_esc_tex[(sizeof(tex->id.name) - 2) * 2]; - - BLI_strescape(name_esc_ma, ma->id.name + 2, sizeof(name_esc_ma)); - BLI_strescape(name_esc_tex, tex->id.name + 2, sizeof(name_esc_tex)); - - /* create new path */ - // TODO: use RNA path functions to construct step by step instead? - // FIXME: maybe this isn't even needed anymore... - path = BLI_sprintfN("material_slots[\"%s\"].material.texture_slots[\"%s\"].texture.%s", - name_esc_ma, name_esc_tex, basepath); - - /* free old one */ - if (basepath != base_path) - MEM_freeN(basepath); - } - break; - } - default: - break; - } + /* TODO: after material textures were removed, this function serves + * no purpose anymore, but could be used again so was not removed. */ /* fix RNA pointer, as we've now changed the ID root by changing the paths */ if (basepath != path) { diff --git a/source/blender/blenkernel/intern/bpath.c b/source/blender/blenkernel/intern/bpath.c index e9a8de4469d..259c5189896 100644 --- a/source/blender/blenkernel/intern/bpath.c +++ b/source/blender/blenkernel/intern/bpath.c @@ -580,14 +580,6 @@ void BKE_bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int } break; } - case ID_TE: - { - Tex *tex = (Tex *)id; - if (tex->type == TEX_VOXELDATA && TEX_VD_IS_SOURCE_PATH(tex->vd->file_format)) { - rewrite_path_fixed(tex->vd->source_path, visit_cb, absbase, bpath_user_data); - } - break; - } case ID_SCE: { Scene *scene = (Scene *)id; diff --git a/source/blender/blenkernel/intern/camera.c b/source/blender/blenkernel/intern/camera.c index 7676baa9dba..2c5cdc39ebc 100644 --- a/source/blender/blenkernel/intern/camera.c +++ b/source/blender/blenkernel/intern/camera.c @@ -304,10 +304,7 @@ void BKE_camera_params_compute_viewplane(CameraParams *params, int winx, int win float pixsize, viewfac, sensor_size, dx, dy; int sensor_fit; - /* fields rendering */ params->ycor = yasp / xasp; - if (params->use_fields) - params->ycor *= 2.0f; if (params->is_ortho) { /* orthographic camera */ @@ -349,18 +346,6 @@ void BKE_camera_params_compute_viewplane(CameraParams *params, int winx, int win viewplane.xmax += dx; viewplane.ymax += dy; - /* fields offset */ - if (params->field_second) { - if (params->field_odd) { - viewplane.ymin -= 0.5f * params->ycor; - viewplane.ymax -= 0.5f * params->ycor; - } - else { - viewplane.ymin += 0.5f * params->ycor; - viewplane.ymax += 0.5f * params->ycor; - } - } - /* the window matrix is used for clipping, and not changed during OSA steps */ /* using an offset of +0.5 here would give clip errors on edges */ viewplane.xmin *= pixsize; diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index a6c6d360769..33540c8746b 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -57,13 +57,6 @@ #include "MEM_guardedalloc.h" -#include "GPU_buffers.h" -#include "GPU_draw.h" -#include "GPU_glew.h" -#include "GPU_immediate.h" -#include "GPU_shader.h" -#include "GPU_basic_shader.h" - #include <string.h> #include <limits.h> #include <math.h> @@ -339,1329 +332,6 @@ static PBVH *cdDM_getPBVH(Object *ob, DerivedMesh *dm) return cddm->pbvh; } -/* update vertex normals so that drawing smooth faces works during sculpt - * TODO: proper fix is to support the pbvh in all drawing modes */ -static void cdDM_update_normals_from_pbvh(DerivedMesh *dm) -{ - CDDerivedMesh *cddm = (CDDerivedMesh *) dm; - float (*face_nors)[3]; - - /* Some callbacks do not use optimal PBVH draw, so needs all the - * possible data (like normals) to be copied from PBVH back to DM. - * - * This is safe to do if PBVH and DM are representing the same mesh, - * which could be wrong when modifiers are enabled for sculpt. - * So here we only doing update when there's no modifiers applied - * during sculpt. - * - * It's safe to do nothing if there are modifiers, because in this - * case modifier stack is re-constructed from scratch on every - * update. - */ - if (!cddm->pbvh_draw) { - return; - } - - face_nors = CustomData_get_layer(&dm->polyData, CD_NORMAL); - - BKE_pbvh_update(cddm->pbvh, PBVH_UpdateNormals, face_nors); -} - -static void cdDM_drawVerts(DerivedMesh *dm) -{ - GPU_vertex_setup(dm); - if (dm->drawObject->tot_loop_verts) - glDrawArrays(GL_POINTS, 0, dm->drawObject->tot_loop_verts); - else - glDrawArrays(GL_POINTS, 0, dm->drawObject->tot_loose_point); - GPU_buffers_unbind(); -} - -static void cdDM_drawEdges(DerivedMesh *dm, bool UNUSED(drawLooseEdges), bool UNUSED(drawAllEdges)) -{ - CDDerivedMesh *cddm = (CDDerivedMesh *) dm; - - if (cddm->pbvh && cddm->pbvh_draw && - BKE_pbvh_type(cddm->pbvh) == PBVH_BMESH) - { - BKE_pbvh_draw(cddm->pbvh, NULL, NULL, NULL, true, false); - - return; - } - - MVert *vert = cddm->mvert; - MEdge *edge = cddm->medge; - - Gwn_VertFormat *format = immVertexFormat(); - unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - - /* NOTE: This is active object color, which is not really perfect. - * But we can't query color set by glColor() :( - */ - float color[4] = {1.0f, 0.667f, 0.251f, 1.0f}; - - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - immUniformColor4fv(color); - - const int chunk_size = 1024; - const int num_chunks = (dm->numEdgeData + chunk_size - 1) / chunk_size; - - for (int chunk = 0; chunk < num_chunks; ++chunk) { - const int num_current_edges = (chunk < num_chunks - 1) - ? chunk_size - : dm->numEdgeData - chunk_size * (num_chunks - 1); - immBeginAtMost(GWN_PRIM_LINES, num_current_edges * 2); - for (int i = 0; i < num_current_edges; i++, edge++) { - immVertex3fv(pos, vert[edge->v1].co); - immVertex3fv(pos, vert[edge->v2].co); - } - immEnd(); - } - - immUnbindProgram(); -} - -static void cdDM_drawLooseEdges(DerivedMesh *dm) -{ - int start; - int count; - - GPU_edge_setup(dm); - - start = (dm->drawObject->loose_edge_offset * 2); - count = (dm->drawObject->totedge - dm->drawObject->loose_edge_offset) * 2; - - if (count) { - GPU_buffer_draw_elements(dm->drawObject->edges, GL_LINES, start, count); - } - - GPU_buffers_unbind(); -} - -static void cdDM_drawFacesSolid( - DerivedMesh *dm, - float (*partial_redraw_planes)[4], - bool fast, DMSetMaterial setMaterial) -{ - UNUSED_VARS(partial_redraw_planes, fast, setMaterial); - CDDerivedMesh *cddm = (CDDerivedMesh *) dm; - int a; - - if (cddm->pbvh) { - if (cddm->pbvh_draw && BKE_pbvh_has_faces(cddm->pbvh)) { - float (*face_nors)[3] = CustomData_get_layer(&dm->polyData, CD_NORMAL); - - BKE_pbvh_draw(cddm->pbvh, partial_redraw_planes, face_nors, - setMaterial, false, false); - return; - } - } - - const MVert *mvert = cddm->mvert; - const MLoop *mloop = cddm->mloop; - const MPoly *mpoly = cddm->mpoly; - const int num_looptris = dm->getNumLoopTri(dm); - const MLoopTri *looptri = dm->getLoopTriArray(dm); - const float (*nors)[3] = dm->getPolyDataArray(dm, CD_NORMAL); - const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL); - - Gwn_VertFormat *format = immVertexFormat(); - unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - unsigned int nor = GWN_vertformat_attr_add(format, "nor", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - - float color[4] = {0.8f, 0.8f, 0.8f, 1.0f}; - const float light_vec[3] = {0.0f, 0.0f, 1.0f}; - - immBindBuiltinProgram(GPU_SHADER_SIMPLE_LIGHTING); - immUniformColor4fv(color); - immUniform3fv("light", light_vec); - - const int chunk_size = 1024; - const int num_chunks = (num_looptris + chunk_size - 1) / chunk_size; - - for (int chunk = 0; chunk < num_chunks; ++chunk) { - const int num_current_looptris = (chunk < num_chunks - 1) - ? chunk_size - : num_looptris - chunk_size * (num_chunks - 1); - - immBeginAtMost(GWN_PRIM_TRIS, num_current_looptris * 3); - - for (a = 0; a < num_current_looptris; a++, looptri++) { - const MPoly *mp = &mpoly[looptri->poly]; - const bool smoothnormal = (lnors != NULL) || (mp->flag & ME_SMOOTH); - const unsigned int vtri[3] = {mloop[looptri->tri[0]].v, - mloop[looptri->tri[1]].v, - mloop[looptri->tri[2]].v}; - const unsigned int *ltri = looptri->tri; - float normals[3][3]; - if (!smoothnormal) { - if (nors != NULL) { - copy_v3_v3(normals[0], nors[looptri->poly]); - } - else { - normal_tri_v3(normals[0], - mvert[vtri[0]].co, - mvert[vtri[1]].co, - mvert[vtri[2]].co); - } - copy_v3_v3(normals[1], normals[0]); - copy_v3_v3(normals[2], normals[0]); - } - else if (lnors != NULL) { - copy_v3_v3(normals[0], lnors[ltri[0]]); - copy_v3_v3(normals[1], lnors[ltri[1]]); - copy_v3_v3(normals[2], lnors[ltri[2]]); - } - else { - normal_short_to_float_v3(normals[0], mvert[vtri[0]].no); - normal_short_to_float_v3(normals[1], mvert[vtri[1]].no); - normal_short_to_float_v3(normals[2], mvert[vtri[2]].no); - } - - immAttrib3fv(nor, normals[0]); - immVertex3fv(pos, mvert[vtri[0]].co); - immAttrib3fv(nor, normals[1]); - immVertex3fv(pos, mvert[vtri[1]].co); - immAttrib3fv(nor, normals[2]); - immVertex3fv(pos, mvert[vtri[2]].co); - } - immEnd(); - } - - immUnbindProgram(); -} - -static void cdDM_drawMappedFaces( - DerivedMesh *dm, - DMSetDrawOptions setDrawOptions, - DMSetMaterial setMaterial, - DMCompareDrawOptions compareDrawOptions, - void *userData, DMDrawFlag flag) -{ - CDDerivedMesh *cddm = (CDDerivedMesh *) dm; - const MPoly *mpoly = cddm->mpoly; - const MLoopCol *mloopcol = NULL; - const bool use_colors = (flag & DM_DRAW_USE_COLORS) != 0; - const bool use_hide = (flag & DM_DRAW_SKIP_HIDDEN) != 0; - int colType; - int i, j; - int start_element = 0, tot_element, tot_drawn; - int totpoly; - int tot_tri_elem; - int mat_index; - GPUBuffer *findex_buffer = NULL; - - const int *index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX); - - if (cddm->pbvh) { - if (G.debug_value == 14) - BKE_pbvh_draw_BB(cddm->pbvh); - } - - /* fist, setup common buffers */ - GPU_vertex_setup(dm); - GPU_triangle_setup(dm); - - totpoly = dm->getNumPolys(dm); - - /* if we do selection, fill the selection buffer color */ - if (G.f & G_BACKBUFSEL) { - if (!(flag & DM_DRAW_SKIP_SELECT)) { - Mesh *me = NULL; - BMesh *bm = NULL; - unsigned int *fi_map; - - if (flag & DM_DRAW_SELECT_USE_EDITMODE) - bm = userData; - else - me = userData; - - findex_buffer = GPU_buffer_alloc(dm->drawObject->tot_loop_verts * sizeof(int)); - fi_map = GPU_buffer_lock(findex_buffer, GPU_BINDING_ARRAY); - - if (fi_map) { - for (i = 0; i < totpoly; i++, mpoly++) { - int selcol = 0xFFFFFFFF; - const int orig = (index_mp_to_orig) ? index_mp_to_orig[i] : i; - bool is_hidden; - - if (orig != ORIGINDEX_NONE) { - if (use_hide) { - if (flag & DM_DRAW_SELECT_USE_EDITMODE) { - BMFace *efa = BM_face_at_index(bm, orig); - is_hidden = BM_elem_flag_test(efa, BM_ELEM_HIDDEN) != 0; - } - else { - is_hidden = (me->mpoly[orig].flag & ME_HIDE) != 0; - } - - if (!is_hidden) { - GPU_select_index_get(orig + 1, &selcol); - } - } - else { - GPU_select_index_get(orig + 1, &selcol); - } - } - - for (j = 0; j < mpoly->totloop; j++) - fi_map[start_element++] = selcol; - } - - start_element = 0; - mpoly = cddm->mpoly; - - GPU_buffer_unlock(findex_buffer, GPU_BINDING_ARRAY); - GPU_buffer_bind_as_color(findex_buffer); - } - } - } - else { - GPU_normal_setup(dm); - - if (use_colors) { - colType = CD_TEXTURE_MLOOPCOL; - mloopcol = DM_get_loop_data_layer(dm, colType); - if (!mloopcol) { - colType = CD_PREVIEW_MLOOPCOL; - mloopcol = DM_get_loop_data_layer(dm, colType); - } - if (!mloopcol) { - colType = CD_MLOOPCOL; - mloopcol = DM_get_loop_data_layer(dm, colType); - } - - if (use_colors && mloopcol) { - GPU_color_setup(dm, colType); - } - } - } - - tot_tri_elem = dm->drawObject->tot_triangle_point; - - if (tot_tri_elem == 0) { - /* avoid buffer problems in following code */ - } - else if (setDrawOptions == NULL) { - /* just draw the entire face array */ - GPU_buffer_draw_elements(dm->drawObject->triangles, GL_TRIANGLES, 0, tot_tri_elem); - } - else { - for (mat_index = 0; mat_index < dm->drawObject->totmaterial; mat_index++) { - GPUBufferMaterial *bufmat = dm->drawObject->materials + mat_index; - DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL; - int next_actualFace = bufmat->polys[0]; - totpoly = use_hide ? bufmat->totvisiblepolys : bufmat->totpolys; - - tot_element = 0; - start_element = 0; - tot_drawn = 0; - - if (setMaterial) - draw_option = setMaterial(bufmat->mat_nr + 1, NULL); - - if (draw_option != DM_DRAW_OPTION_SKIP) { - DMDrawOption last_draw_option = DM_DRAW_OPTION_NORMAL; - - for (i = 0; i < totpoly; i++) { - int actualFace = next_actualFace; - int flush = 0; - int tot_tri_verts; - - draw_option = DM_DRAW_OPTION_NORMAL; - - if (i != totpoly - 1) - next_actualFace = bufmat->polys[i + 1]; - - if (setDrawOptions) { - const int orig = (index_mp_to_orig) ? index_mp_to_orig[actualFace] : actualFace; - - if (orig != ORIGINDEX_NONE) { - draw_option = setDrawOptions(userData, orig); - } - } - - /* Goal is to draw as long of a contiguous triangle - * array as possible, so draw when we hit either an - * invisible triangle or at the end of the array */ - - /* flush buffer if current triangle isn't drawable or it's last triangle... */ - flush = (draw_option != last_draw_option) || (i == totpoly - 1); - - if (!flush && compareDrawOptions) { - flush |= compareDrawOptions(userData, actualFace, next_actualFace) == 0; - } - - tot_tri_verts = ME_POLY_TRI_TOT(&mpoly[actualFace]) * 3; - tot_element += tot_tri_verts; - - if (flush) { - if (draw_option != DM_DRAW_OPTION_SKIP) { - tot_drawn += tot_tri_verts; - - if (last_draw_option != draw_option) { - if (draw_option == DM_DRAW_OPTION_STIPPLE) { - GPU_basic_shader_bind(GPU_SHADER_STIPPLE | GPU_SHADER_USE_COLOR); - GPU_basic_shader_stipple(GPU_SHADER_STIPPLE_QUARTTONE); - } - else { - GPU_basic_shader_bind(GPU_SHADER_USE_COLOR); - } - } - } - - if (tot_drawn) { - GPU_buffer_draw_elements(dm->drawObject->triangles, GL_TRIANGLES, bufmat->start + start_element, tot_drawn); - tot_drawn = 0; - } - - last_draw_option = draw_option; - start_element = tot_element; - } - else { - if (draw_option != DM_DRAW_OPTION_SKIP) { - tot_drawn += tot_tri_verts; - } - else { - start_element = tot_element; - } - } - } - } - } - } - - GPU_basic_shader_bind(GPU_SHADER_USE_COLOR); - - GPU_buffers_unbind(); - - if (findex_buffer) - GPU_buffer_free(findex_buffer); - -} - -static void cddm_draw_attrib_vertex( - DMVertexAttribs *attribs, const MVert *mvert, int a, int index, int loop, int vert, - const float *lnor, const bool smoothnormal) -{ - DM_draw_attrib_vertex(attribs, a, index, vert, loop); - - /* vertex normal */ - if (lnor) { - glNormal3fv(lnor); - } - else if (smoothnormal) { - glNormal3sv(mvert[index].no); - } - - /* vertex coordinate */ - glVertex3fv(mvert[index].co); -} - -typedef struct { - DMVertexAttribs attribs; - int numdata; - - GPUAttrib datatypes[GPU_MAX_ATTRIB]; /* TODO, messing up when switching materials many times - [#21056]*/ -} GPUMaterialConv; - -static void cdDM_drawMappedFacesGLSL( - DerivedMesh *dm, - DMSetMaterial setMaterial, - DMSetDrawOptions setDrawOptions, - void *userData) -{ - CDDerivedMesh *cddm = (CDDerivedMesh *) dm; - GPUVertexAttribs gattribs; - const MVert *mvert = cddm->mvert; - const MPoly *mpoly = cddm->mpoly; - const MLoop *mloop = cddm->mloop; - const MLoopTri *lt = dm->getLoopTriArray(dm); - const int tottri = dm->getNumLoopTri(dm); - /* MTFace *tf = dm->getTessFaceDataArray(dm, CD_MTFACE); */ /* UNUSED */ - const float (*nors)[3] = dm->getPolyDataArray(dm, CD_NORMAL); - const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL); - const int totpoly = dm->getNumPolys(dm); - const short dm_totmat = dm->totmat; - int a, b, matnr, new_matnr; - bool do_draw; - int orig; - - const int *index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX); - - /* TODO: same as for solid draw, not entirely correct, but works fine for now, - * will skip using textures (dyntopo currently destroys UV anyway) and - * works fine for matcap - */ - if (cddm->pbvh) { - if (cddm->pbvh_draw && - BKE_pbvh_type(cddm->pbvh) == PBVH_BMESH && - BKE_pbvh_has_faces(cddm->pbvh)) - { - setMaterial(1, &gattribs); - BKE_pbvh_draw(cddm->pbvh, NULL, NULL, NULL, false, false); - return; - } - else { - cdDM_update_normals_from_pbvh(dm); - } - } - - matnr = -1; - do_draw = false; - - if (setDrawOptions != NULL) { - DMVertexAttribs attribs; - DEBUG_VBO("Using legacy code. cdDM_drawMappedFacesGLSL\n"); - memset(&attribs, 0, sizeof(attribs)); - - glBegin(GL_TRIANGLES); - - for (a = 0; a < tottri; a++, lt++) { - const MPoly *mp = &mpoly[lt->poly]; - const unsigned int vtri[3] = {mloop[lt->tri[0]].v, mloop[lt->tri[1]].v, mloop[lt->tri[2]].v}; - const unsigned int *ltri = lt->tri; - const float *ln1 = NULL, *ln2 = NULL, *ln3 = NULL; - const bool smoothnormal = lnors || (mp->flag & ME_SMOOTH); - new_matnr = mp->mat_nr; - - if (new_matnr != matnr) { - glEnd(); - - matnr = new_matnr; - do_draw = setMaterial(matnr + 1, &gattribs); - if (do_draw) { - DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs); - DM_draw_attrib_vertex_uniforms(&attribs); - } - - glBegin(GL_TRIANGLES); - } - - if (!do_draw) { - continue; - } - else /* if (setDrawOptions) */ { - orig = (index_mp_to_orig) ? index_mp_to_orig[lt->poly] : lt->poly; - - if (orig == ORIGINDEX_NONE) { - /* since the material is set by setMaterial(), faces with no - * origin can be assumed to be generated by a modifier */ - - /* continue */ - } - else if (setDrawOptions(userData, orig) == DM_DRAW_OPTION_SKIP) - continue; - } - - if (!smoothnormal) { - if (nors) { - glNormal3fv(nors[lt->poly]); - } - else { - /* TODO ideally a normal layer should always be available */ - float nor[3]; - normal_tri_v3(nor, mvert[vtri[0]].co, mvert[vtri[1]].co, mvert[vtri[2]].co); - glNormal3fv(nor); - } - } - else if (lnors) { - ln1 = lnors[ltri[0]]; - ln2 = lnors[ltri[1]]; - ln3 = lnors[ltri[2]]; - } - - cddm_draw_attrib_vertex(&attribs, mvert, a, vtri[0], ltri[0], 0, ln1, smoothnormal); - cddm_draw_attrib_vertex(&attribs, mvert, a, vtri[1], ltri[1], 1, ln2, smoothnormal); - cddm_draw_attrib_vertex(&attribs, mvert, a, vtri[2], ltri[2], 2, ln3, smoothnormal); - } - glEnd(); - } - else { - GPUMaterialConv *matconv; - int offset; - int *mat_orig_to_new; - int tot_active_mat; - GPUBuffer *buffer = NULL; - unsigned char *varray; - size_t max_element_size = 0; - int tot_loops = 0; - - GPU_vertex_setup(dm); - GPU_normal_setup(dm); - GPU_triangle_setup(dm); - - tot_active_mat = dm->drawObject->totmaterial; - - matconv = MEM_calloc_arrayN(tot_active_mat, sizeof(*matconv), - "cdDM_drawMappedFacesGLSL.matconv"); - mat_orig_to_new = MEM_malloc_arrayN(dm->totmat, sizeof(*mat_orig_to_new), - "cdDM_drawMappedFacesGLSL.mat_orig_to_new"); - - /* part one, check what attributes are needed per material */ - for (a = 0; a < tot_active_mat; a++) { - new_matnr = dm->drawObject->materials[a].mat_nr; - - /* map from original material index to new - * GPUBufferMaterial index */ - mat_orig_to_new[new_matnr] = a; - do_draw = setMaterial(new_matnr + 1, &gattribs); - - if (do_draw) { - int numdata = 0; - DM_vertex_attributes_from_gpu(dm, &gattribs, &matconv[a].attribs); - - if (matconv[a].attribs.totorco && matconv[a].attribs.orco.array) { - matconv[a].datatypes[numdata].index = matconv[a].attribs.orco.gl_index; - matconv[a].datatypes[numdata].info_index = matconv[a].attribs.orco.gl_info_index; - matconv[a].datatypes[numdata].size = 3; - matconv[a].datatypes[numdata].type = GL_FLOAT; - numdata++; - } - for (b = 0; b < matconv[a].attribs.tottface; b++) { - if (matconv[a].attribs.tface[b].array) { - matconv[a].datatypes[numdata].index = matconv[a].attribs.tface[b].gl_index; - matconv[a].datatypes[numdata].info_index = matconv[a].attribs.tface[b].gl_info_index; - matconv[a].datatypes[numdata].size = 2; - matconv[a].datatypes[numdata].type = GL_FLOAT; - numdata++; - } - } - for (b = 0; b < matconv[a].attribs.totmcol; b++) { - if (matconv[a].attribs.mcol[b].array) { - matconv[a].datatypes[numdata].index = matconv[a].attribs.mcol[b].gl_index; - matconv[a].datatypes[numdata].info_index = matconv[a].attribs.mcol[b].gl_info_index; - matconv[a].datatypes[numdata].size = 4; - matconv[a].datatypes[numdata].type = GL_UNSIGNED_BYTE; - numdata++; - } - } - for (b = 0; b < matconv[a].attribs.tottang; b++) { - if (matconv[a].attribs.tang[b].array) { - matconv[a].datatypes[numdata].index = matconv[a].attribs.tang[b].gl_index; - matconv[a].datatypes[numdata].info_index = matconv[a].attribs.tang[b].gl_info_index; - matconv[a].datatypes[numdata].size = 4; - matconv[a].datatypes[numdata].type = GL_FLOAT; - numdata++; - } - } - if (numdata != 0) { - matconv[a].numdata = numdata; - max_element_size = max_ii(GPU_attrib_element_size(matconv[a].datatypes, numdata), max_element_size); - } - } - } - - /* part two, generate and fill the arrays with the data */ - if (max_element_size > 0) { - buffer = GPU_buffer_alloc(max_element_size * dm->drawObject->tot_loop_verts); - - varray = GPU_buffer_lock_stream(buffer, GPU_BINDING_ARRAY); - if (varray == NULL) { - GPU_buffers_unbind(); - GPU_buffer_free(buffer); - MEM_freeN(mat_orig_to_new); - MEM_freeN(matconv); - fprintf(stderr, "Out of memory, can't draw object\n"); - return; - } - - for (a = 0; a < totpoly; a++, mpoly++) { - const short mat_nr = ME_MAT_NR_TEST(mpoly->mat_nr, dm_totmat); - int j; - int i = mat_orig_to_new[mat_nr]; - offset = tot_loops * max_element_size; - - if (matconv[i].numdata != 0) { - if (matconv[i].attribs.totorco && matconv[i].attribs.orco.array) { - for (j = 0; j < mpoly->totloop; j++) - copy_v3_v3((float *)&varray[offset + j * max_element_size], - (float *)matconv[i].attribs.orco.array[mloop[mpoly->loopstart + j].v]); - offset += sizeof(float) * 3; - } - for (b = 0; b < matconv[i].attribs.tottface; b++) { - if (matconv[i].attribs.tface[b].array) { - const MLoopUV *mloopuv = matconv[i].attribs.tface[b].array; - for (j = 0; j < mpoly->totloop; j++) - copy_v2_v2((float *)&varray[offset + j * max_element_size], mloopuv[mpoly->loopstart + j].uv); - offset += sizeof(float) * 2; - } - } - for (b = 0; b < matconv[i].attribs.totmcol; b++) { - if (matconv[i].attribs.mcol[b].array) { - const MLoopCol *mloopcol = matconv[i].attribs.mcol[b].array; - for (j = 0; j < mpoly->totloop; j++) - copy_v4_v4_uchar(&varray[offset + j * max_element_size], &mloopcol[mpoly->loopstart + j].r); - offset += sizeof(unsigned char) * 4; - } - } - for (b = 0; b < matconv[i].attribs.tottang; b++) { - if (matconv[i].attribs.tottang && matconv[i].attribs.tang[b].array) { - const float (*looptang)[4] = (const float (*)[4])matconv[i].attribs.tang[b].array; - for (j = 0; j < mpoly->totloop; j++) - copy_v4_v4((float *)&varray[offset + j * max_element_size], looptang[mpoly->loopstart + j]); - offset += sizeof(float) * 4; - } - } - } - - tot_loops += mpoly->totloop; - } - GPU_buffer_unlock(buffer, GPU_BINDING_ARRAY); - } - - for (a = 0; a < tot_active_mat; a++) { - new_matnr = dm->drawObject->materials[a].mat_nr; - - do_draw = setMaterial(new_matnr + 1, &gattribs); - - if (do_draw) { - if (matconv[a].numdata) { - GPU_interleaved_attrib_setup(buffer, matconv[a].datatypes, matconv[a].numdata, max_element_size); - } - GPU_buffer_draw_elements(dm->drawObject->triangles, GL_TRIANGLES, - dm->drawObject->materials[a].start, dm->drawObject->materials[a].totelements); - if (matconv[a].numdata) { - GPU_interleaved_attrib_unbind(); - } - } - } - - GPU_buffers_unbind(); - if (buffer) - GPU_buffer_free(buffer); - - MEM_freeN(mat_orig_to_new); - MEM_freeN(matconv); - } -} - -static void cdDM_drawFacesGLSL(DerivedMesh *dm, DMSetMaterial setMaterial) -{ - dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL); -} - -static void cdDM_drawMappedFacesMat( - DerivedMesh *dm, - void (*setMaterial)(void *userData, int matnr, void *attribs), - bool (*setFace)(void *userData, int index), void *userData) -{ - CDDerivedMesh *cddm = (CDDerivedMesh *) dm; - GPUVertexAttribs gattribs; - DMVertexAttribs attribs; - MVert *mvert = cddm->mvert; - const MPoly *mpoly = cddm->mpoly; - const MLoop *mloop = cddm->mloop; - const MLoopTri *lt = dm->getLoopTriArray(dm); - const int tottri = dm->getNumLoopTri(dm); - const float (*nors)[3] = dm->getPolyDataArray(dm, CD_NORMAL); - const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL); - int a, matnr, new_matnr; - int orig; - - const int *index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX); - - /* TODO: same as for solid draw, not entirely correct, but works fine for now, - * will skip using textures (dyntopo currently destroys UV anyway) and - * works fine for matcap - */ - - if (cddm->pbvh) { - if (cddm->pbvh_draw && - BKE_pbvh_type(cddm->pbvh) == PBVH_BMESH && - BKE_pbvh_has_faces(cddm->pbvh)) - { - setMaterial(userData, 1, &gattribs); - BKE_pbvh_draw(cddm->pbvh, NULL, NULL, NULL, false, false); - return; - } - else { - cdDM_update_normals_from_pbvh(dm); - } - } - - matnr = -1; - - memset(&attribs, 0, sizeof(attribs)); - - glBegin(GL_TRIANGLES); - - for (a = 0; a < tottri; a++, lt++) { - const MPoly *mp = &mpoly[lt->poly]; - const unsigned int vtri[3] = {mloop[lt->tri[0]].v, mloop[lt->tri[1]].v, mloop[lt->tri[2]].v}; - const unsigned int *ltri = lt->tri; - const bool smoothnormal = lnors || (mp->flag & ME_SMOOTH); - const float *ln1 = NULL, *ln2 = NULL, *ln3 = NULL; - - /* material */ - new_matnr = mp->mat_nr + 1; - - if (new_matnr != matnr) { - glEnd(); - - setMaterial(userData, matnr = new_matnr, &gattribs); - DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs); - DM_draw_attrib_vertex_uniforms(&attribs); - - glBegin(GL_TRIANGLES); - } - - /* skipping faces */ - if (setFace) { - orig = (index_mp_to_orig) ? index_mp_to_orig[lt->poly] : lt->poly; - - if (orig != ORIGINDEX_NONE && !setFace(userData, orig)) - continue; - } - - /* smooth normal */ - if (!smoothnormal) { - if (nors) { - glNormal3fv(nors[lt->poly]); - } - else { - /* TODO ideally a normal layer should always be available */ - float nor[3]; - normal_tri_v3(nor, mvert[vtri[0]].co, mvert[vtri[1]].co, mvert[vtri[2]].co); - glNormal3fv(nor); - } - } - else if (lnors) { - ln1 = lnors[ltri[0]]; - ln2 = lnors[ltri[1]]; - ln3 = lnors[ltri[2]]; - } - - /* vertices */ - cddm_draw_attrib_vertex(&attribs, mvert, a, vtri[0], ltri[0], 0, ln1, smoothnormal); - cddm_draw_attrib_vertex(&attribs, mvert, a, vtri[1], ltri[1], 1, ln2, smoothnormal); - cddm_draw_attrib_vertex(&attribs, mvert, a, vtri[2], ltri[2], 2, ln3, smoothnormal); - } - glEnd(); -} - -static void cdDM_drawMappedEdges(DerivedMesh *dm, DMSetDrawOptions setDrawOptions, void *userData) -{ - CDDerivedMesh *cddm = (CDDerivedMesh *) dm; - MVert *vert = cddm->mvert; - MEdge *edge = cddm->medge; - int i, orig, *index = DM_get_edge_data_layer(dm, CD_ORIGINDEX); - - glBegin(GL_LINES); - for (i = 0; i < dm->numEdgeData; i++, edge++) { - if (index) { - orig = *index++; - if (setDrawOptions && orig == ORIGINDEX_NONE) continue; - } - else - orig = i; - - if (!setDrawOptions || (setDrawOptions(userData, orig) != DM_DRAW_OPTION_SKIP)) { - glVertex3fv(vert[edge->v1].co); - glVertex3fv(vert[edge->v2].co); - } - } - glEnd(); -} - -typedef struct FaceCount { - unsigned int i_visible; - unsigned int i_hidden; - unsigned int i_tri_visible; - unsigned int i_tri_hidden; -} FaceCount; - -static void cdDM_buffer_copy_triangles( - DerivedMesh *dm, unsigned int *varray, - const int *mat_orig_to_new) -{ - GPUBufferMaterial *gpumat, *gpumaterials = dm->drawObject->materials; - int i, j, start; - - const int gpu_totmat = dm->drawObject->totmaterial; - const short dm_totmat = dm->totmat; - const MPoly *mpoly = dm->getPolyArray(dm); - const MLoopTri *lt = dm->getLoopTriArray(dm); - const int totpoly = dm->getNumPolys(dm); - - FaceCount *fc = MEM_malloc_arrayN(gpu_totmat, sizeof(*fc), "gpumaterial.facecount"); - - for (i = 0; i < gpu_totmat; i++) { - fc[i].i_visible = 0; - fc[i].i_tri_visible = 0; - fc[i].i_hidden = gpumaterials[i].totpolys - 1; - fc[i].i_tri_hidden = gpumaterials[i].totelements - 1; - } - - for (i = 0; i < totpoly; i++) { - const short mat_nr = ME_MAT_NR_TEST(mpoly[i].mat_nr, dm_totmat); - int tottri = ME_POLY_TRI_TOT(&mpoly[i]); - int mati = mat_orig_to_new[mat_nr]; - gpumat = gpumaterials + mati; - - if (mpoly[i].flag & ME_HIDE) { - for (j = 0; j < tottri; j++, lt++) { - start = gpumat->start + fc[mati].i_tri_hidden; - /* v1 v2 v3 */ - varray[start--] = lt->tri[2]; - varray[start--] = lt->tri[1]; - varray[start--] = lt->tri[0]; - fc[mati].i_tri_hidden -= 3; - } - gpumat->polys[fc[mati].i_hidden--] = i; - } - else { - for (j = 0; j < tottri; j++, lt++) { - start = gpumat->start + fc[mati].i_tri_visible; - /* v1 v2 v3 */ - varray[start++] = lt->tri[0]; - varray[start++] = lt->tri[1]; - varray[start++] = lt->tri[2]; - fc[mati].i_tri_visible += 3; - } - gpumat->polys[fc[mati].i_visible++] = i; - } - } - - /* set the visible polygons */ - for (i = 0; i < gpu_totmat; i++) { - gpumaterials[i].totvisiblepolys = fc[i].i_visible; - } - - MEM_freeN(fc); -} - -static void cdDM_buffer_copy_vertex( - DerivedMesh *dm, float *varray) -{ - const MVert *mvert; - const MPoly *mpoly; - const MLoop *mloop; - - int i, j, start, totpoly; - - mvert = dm->getVertArray(dm); - mpoly = dm->getPolyArray(dm); - mloop = dm->getLoopArray(dm); - totpoly = dm->getNumPolys(dm); - - start = 0; - - for (i = 0; i < totpoly; i++, mpoly++) { - for (j = 0; j < mpoly->totloop; j++) { - copy_v3_v3(&varray[start], mvert[mloop[mpoly->loopstart + j].v].co); - start += 3; - } - } - - /* copy loose points */ - j = dm->drawObject->tot_loop_verts * 3; - for (i = 0; i < dm->drawObject->totvert; i++) { - if (dm->drawObject->vert_points[i].point_index >= dm->drawObject->tot_loop_verts) { - copy_v3_v3(&varray[j], mvert[i].co); - j += 3; - } - } -} - -static void cdDM_buffer_copy_normal( - DerivedMesh *dm, short *varray) -{ - CDDerivedMesh *cddm = (CDDerivedMesh *)dm; - int i, j, totpoly; - int start; - - const float (*nors)[3] = dm->getPolyDataArray(dm, CD_NORMAL); - const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL); - - const MVert *mvert; - const MPoly *mpoly; - const MLoop *mloop; - - mvert = dm->getVertArray(dm); - mpoly = dm->getPolyArray(dm); - mloop = dm->getLoopArray(dm); - totpoly = dm->getNumPolys(dm); - - /* we are in sculpt mode, disable loop normals (since they won't get updated) */ - if (cddm->pbvh) - lnors = NULL; - - start = 0; - for (i = 0; i < totpoly; i++, mpoly++) { - const bool smoothnormal = (mpoly->flag & ME_SMOOTH) != 0; - - if (lnors) { - /* Copy loop normals */ - for (j = 0; j < mpoly->totloop; j++, start += 4) { - normal_float_to_short_v3(&varray[start], lnors[mpoly->loopstart + j]); - } - } - else if (smoothnormal) { - /* Copy vertex normal */ - for (j = 0; j < mpoly->totloop; j++, start += 4) { - copy_v3_v3_short(&varray[start], mvert[mloop[mpoly->loopstart + j].v].no); - } - } - else { - /* Copy cached OR calculated face normal */ - short f_no_s[3]; - - if (nors) { - normal_float_to_short_v3(f_no_s, nors[i]); - } - else { - float f_no[3]; - BKE_mesh_calc_poly_normal(mpoly, &mloop[mpoly->loopstart], mvert, f_no); - normal_float_to_short_v3(f_no_s, f_no); - } - - for (j = 0; j < mpoly->totloop; j++, start += 4) { - copy_v3_v3_short(&varray[start], f_no_s); - } - } - } -} - -static void cdDM_buffer_copy_uv( - DerivedMesh *dm, float *varray) -{ - int i, j, totpoly; - int start; - - const MPoly *mpoly; - const MLoopUV *mloopuv; - - if ((mloopuv = DM_get_loop_data_layer(dm, CD_MLOOPUV)) == NULL) { - return; - } - - mpoly = dm->getPolyArray(dm); - totpoly = dm->getNumPolys(dm); - - start = 0; - for (i = 0; i < totpoly; i++, mpoly++) { - for (j = 0; j < mpoly->totloop; j++) { - copy_v2_v2(&varray[start], mloopuv[mpoly->loopstart + j].uv); - start += 2; - } - } -} - -static void cdDM_buffer_copy_uv_texpaint( - DerivedMesh *dm, float *varray) -{ - int i, j, totpoly; - int start; - - const MPoly *mpoly; - - int totmaterial = dm->totmat; - const MLoopUV **uv_base; - const MLoopUV *uv_stencil_base; - int stencil; - - totpoly = dm->getNumPolys(dm); - - /* should have been checked for before, reassert */ - BLI_assert(DM_get_loop_data_layer(dm, CD_MLOOPUV)); - uv_base = MEM_malloc_arrayN(totmaterial, sizeof(*uv_base), "texslots"); - - for (i = 0; i < totmaterial; i++) { - uv_base[i] = DM_paint_uvlayer_active_get(dm, i); - } - - stencil = CustomData_get_stencil_layer(&dm->loopData, CD_MLOOPUV); - uv_stencil_base = CustomData_get_layer_n(&dm->loopData, CD_MLOOPUV, stencil); - - mpoly = dm->getPolyArray(dm); - start = 0; - - for (i = 0; i < totpoly; i++, mpoly++) { - int mat_i = mpoly->mat_nr; - - for (j = 0; j < mpoly->totloop; j++) { - copy_v2_v2(&varray[start], uv_base[mat_i][mpoly->loopstart + j].uv); - copy_v2_v2(&varray[start + 2], uv_stencil_base[mpoly->loopstart + j].uv); - start += 4; - } - } - - MEM_freeN((void *)uv_base); -} - -/* treat varray_ as an array of MCol, four MCol's per face */ -static void cdDM_buffer_copy_mcol( - DerivedMesh *dm, unsigned char *varray, - const void *user_data) -{ - int i, j, totpoly; - int start; - - const MLoopCol *mloopcol = user_data; - const MPoly *mpoly = dm->getPolyArray(dm); - - totpoly = dm->getNumPolys(dm); - - start = 0; - - for (i = 0; i < totpoly; i++, mpoly++) { - for (j = 0; j < mpoly->totloop; j++) { - copy_v4_v4_uchar(&varray[start], &mloopcol[mpoly->loopstart + j].r); - start += 4; - } - } -} - -static void cdDM_buffer_copy_edge( - DerivedMesh *dm, unsigned int *varray) -{ - MEdge *medge, *medge_base; - int i, totedge, iloose, inorm, iloosehidden, inormhidden; - int tot_loose_hidden = 0, tot_loose = 0; - int tot_hidden = 0, tot = 0; - - medge_base = medge = dm->getEdgeArray(dm); - totedge = dm->getNumEdges(dm); - - for (i = 0; i < totedge; i++, medge++) { - if (medge->flag & ME_EDGEDRAW) { - if (medge->flag & ME_LOOSEEDGE) tot_loose++; - else tot++; - } - else { - if (medge->flag & ME_LOOSEEDGE) tot_loose_hidden++; - else tot_hidden++; - } - } - - inorm = 0; - inormhidden = tot; - iloose = tot + tot_hidden; - iloosehidden = iloose + tot_loose; - - medge = medge_base; - for (i = 0; i < totedge; i++, medge++) { - if (medge->flag & ME_EDGEDRAW) { - if (medge->flag & ME_LOOSEEDGE) { - varray[iloose * 2] = dm->drawObject->vert_points[medge->v1].point_index; - varray[iloose * 2 + 1] = dm->drawObject->vert_points[medge->v2].point_index; - iloose++; - } - else { - varray[inorm * 2] = dm->drawObject->vert_points[medge->v1].point_index; - varray[inorm * 2 + 1] = dm->drawObject->vert_points[medge->v2].point_index; - inorm++; - } - } - else { - if (medge->flag & ME_LOOSEEDGE) { - varray[iloosehidden * 2] = dm->drawObject->vert_points[medge->v1].point_index; - varray[iloosehidden * 2 + 1] = dm->drawObject->vert_points[medge->v2].point_index; - iloosehidden++; - } - else { - varray[inormhidden * 2] = dm->drawObject->vert_points[medge->v1].point_index; - varray[inormhidden * 2 + 1] = dm->drawObject->vert_points[medge->v2].point_index; - inormhidden++; - } - } - } - - dm->drawObject->tot_loose_edge_drawn = tot_loose; - dm->drawObject->loose_edge_offset = tot + tot_hidden; - dm->drawObject->tot_edge_drawn = tot; -} - -static void cdDM_buffer_copy_uvedge( - DerivedMesh *dm, float *varray) -{ - int i, j, totpoly; - int start; - const MLoopUV *mloopuv; - const MPoly *mpoly = dm->getPolyArray(dm); - - if ((mloopuv = DM_get_loop_data_layer(dm, CD_MLOOPUV)) == NULL) { - return; - } - - totpoly = dm->getNumPolys(dm); - start = 0; - - for (i = 0; i < totpoly; i++, mpoly++) { - for (j = 0; j < mpoly->totloop; j++) { - copy_v2_v2(&varray[start], mloopuv[mpoly->loopstart + j].uv); - copy_v2_v2(&varray[start + 2], mloopuv[mpoly->loopstart + (j + 1) % mpoly->totloop].uv); - start += 4; - } - } -} - -static void cdDM_copy_gpu_data( - DerivedMesh *dm, int type, void *varray_p, - const int *mat_orig_to_new, const void *user_data) -{ - /* 'varray_p' cast is redundant but include for self-documentation */ - switch (type) { - case GPU_BUFFER_VERTEX: - cdDM_buffer_copy_vertex(dm, (float *)varray_p); - break; - case GPU_BUFFER_NORMAL: - cdDM_buffer_copy_normal(dm, (short *)varray_p); - break; - case GPU_BUFFER_COLOR: - cdDM_buffer_copy_mcol(dm, (unsigned char *)varray_p, user_data); - break; - case GPU_BUFFER_UV: - cdDM_buffer_copy_uv(dm, (float *)varray_p); - break; - case GPU_BUFFER_UV_TEXPAINT: - cdDM_buffer_copy_uv_texpaint(dm, (float *)varray_p); - break; - case GPU_BUFFER_EDGE: - cdDM_buffer_copy_edge(dm, (unsigned int *)varray_p); - break; - case GPU_BUFFER_UVEDGE: - cdDM_buffer_copy_uvedge(dm, (float *)varray_p); - break; - case GPU_BUFFER_TRIANGLES: - cdDM_buffer_copy_triangles(dm, (unsigned int *)varray_p, mat_orig_to_new); - break; - default: - break; - } -} - -/* add a new point to the list of points related to a particular - * vertex */ -#ifdef USE_GPU_POINT_LINK - -static void cdDM_drawobject_add_vert_point(GPUDrawObject *gdo, int vert_index, int point_index) -{ - GPUVertPointLink *lnk; - - lnk = &gdo->vert_points[vert_index]; - - /* if first link is in use, add a new link at the end */ - if (lnk->point_index != -1) { - /* get last link */ - for (; lnk->next; lnk = lnk->next) ; - - /* add a new link from the pool */ - lnk = lnk->next = &gdo->vert_points_mem[gdo->vert_points_usage]; - gdo->vert_points_usage++; - } - - lnk->point_index = point_index; -} - -#else - -static void cdDM_drawobject_add_vert_point(GPUDrawObject *gdo, int vert_index, int point_index) -{ - GPUVertPointLink *lnk; - lnk = &gdo->vert_points[vert_index]; - if (lnk->point_index == -1) { - lnk->point_index = point_index; - } -} - -#endif /* USE_GPU_POINT_LINK */ - -/* for each vertex, build a list of points related to it; these lists - * are stored in an array sized to the number of vertices */ -static void cdDM_drawobject_init_vert_points( - GPUDrawObject *gdo, - const MPoly *mpoly, const MLoop *mloop, - int tot_poly) -{ - int i; - int tot_loops = 0; - - /* allocate the array and space for links */ - gdo->vert_points = MEM_malloc_arrayN(gdo->totvert, sizeof(GPUVertPointLink), - "GPUDrawObject.vert_points"); -#ifdef USE_GPU_POINT_LINK - gdo->vert_points_mem = MEM_calloc_arrayN(gdo->totvert, sizeof(GPUVertPointLink), - "GPUDrawObject.vert_points_mem"); - gdo->vert_points_usage = 0; -#endif - - /* -1 indicates the link is not yet used */ - for (i = 0; i < gdo->totvert; i++) { -#ifdef USE_GPU_POINT_LINK - gdo->vert_points[i].link = NULL; -#endif - gdo->vert_points[i].point_index = -1; - } - - for (i = 0; i < tot_poly; i++) { - int j; - const MPoly *mp = &mpoly[i]; - - /* assign unique indices to vertices of the mesh */ - for (j = 0; j < mp->totloop; j++) { - cdDM_drawobject_add_vert_point(gdo, mloop[mp->loopstart + j].v, tot_loops + j); - } - tot_loops += mp->totloop; - } - - /* map any unused vertices to loose points */ - for (i = 0; i < gdo->totvert; i++) { - if (gdo->vert_points[i].point_index == -1) { - gdo->vert_points[i].point_index = gdo->tot_loop_verts + gdo->tot_loose_point; - gdo->tot_loose_point++; - } - } -} - -/* see GPUDrawObject's structure definition for a description of the - * data being initialized here */ -static GPUDrawObject *cdDM_GPUobject_new(DerivedMesh *dm) -{ - GPUDrawObject *gdo; - const MPoly *mpoly; - const MLoop *mloop; - const short dm_totmat = dm->totmat; - GPUBufferMaterial *mat_info; - int i, totloops, totpolys; - - /* object contains at least one material (default included) so zero means uninitialized dm */ - BLI_assert(dm_totmat != 0); - - mpoly = dm->getPolyArray(dm); - mloop = dm->getLoopArray(dm); - - totpolys = dm->getNumPolys(dm); - totloops = dm->getNumLoops(dm); - - /* get the number of points used by each material, treating - * each quad as two triangles */ - mat_info = MEM_calloc_arrayN(dm_totmat, sizeof(*mat_info), "GPU_drawobject_new.mat_orig_to_new"); - - for (i = 0; i < totpolys; i++) { - const short mat_nr = ME_MAT_NR_TEST(mpoly[i].mat_nr, dm_totmat); - mat_info[mat_nr].totpolys++; - mat_info[mat_nr].totelements += 3 * ME_POLY_TRI_TOT(&mpoly[i]); - mat_info[mat_nr].totloops += mpoly[i].totloop; - } - /* create the GPUDrawObject */ - gdo = MEM_callocN(sizeof(GPUDrawObject), "GPUDrawObject"); - gdo->totvert = dm->getNumVerts(dm); - gdo->totedge = dm->getNumEdges(dm); - - GPU_buffer_material_finalize(gdo, mat_info, dm_totmat); - - gdo->tot_loop_verts = totloops; - - /* store total number of points used for triangles */ - gdo->tot_triangle_point = poly_to_tri_count(totpolys, totloops) * 3; - - cdDM_drawobject_init_vert_points(gdo, mpoly, mloop, totpolys); - - return gdo; -} - static void cdDM_foreachMappedVert( DerivedMesh *dm, void (*func)(void *userData, int index, const float co[3], const float no_f[3], const short no_s[3]), @@ -1885,21 +555,6 @@ static CDDerivedMesh *cdDM_create(const char *desc) dm->getPBVH = cdDM_getPBVH; dm->getPolyMap = cdDM_getPolyMap; - dm->drawVerts = cdDM_drawVerts; - - dm->drawEdges = cdDM_drawEdges; - dm->drawLooseEdges = cdDM_drawLooseEdges; - dm->drawMappedEdges = cdDM_drawMappedEdges; - - dm->drawFacesSolid = cdDM_drawFacesSolid; - dm->drawFacesGLSL = cdDM_drawFacesGLSL; - dm->drawMappedFaces = cdDM_drawMappedFaces; - dm->drawMappedFacesGLSL = cdDM_drawMappedFacesGLSL; - dm->drawMappedFacesMat = cdDM_drawMappedFacesMat; - - dm->gpuObjectNew = cdDM_GPUobject_new; - dm->copy_gpu_data = cdDM_copy_gpu_data; - dm->foreachMappedVert = cdDM_foreachMappedVert; dm->foreachMappedEdge = cdDM_foreachMappedEdge; dm->foreachMappedLoop = cdDM_foreachMappedLoop; diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c index 6f0135616f0..27840af291b 100644 --- a/source/blender/blenkernel/intern/dynamicpaint.c +++ b/source/blender/blenkernel/intern/dynamicpaint.c @@ -531,11 +531,6 @@ static int surface_getBrushFlags(DynamicPaintSurface *surface, const ViewLayer * return flags; } -static int brush_usesMaterial(const DynamicPaintBrushSettings *brush, const Scene *scene) -{ - return ((brush->flags & MOD_DPAINT_USE_MATERIAL) && (!BKE_scene_use_new_shading_nodes(scene))); -} - /* check whether two bounds intersect */ static bool boundsIntersect(Bounds3D *b1, Bounds3D *b2) { @@ -1096,7 +1091,6 @@ bool dynamicPaint_createType(struct DynamicPaintModifierData *pmd, int type, str brush->flags = MOD_DPAINT_ABS_ALPHA | MOD_DPAINT_RAMP_ALPHA; brush->collision = MOD_DPAINT_COL_VOLUME; - brush->mat = NULL; brush->r = 0.15f; brush->g = 0.4f; brush->b = 0.8f; @@ -1236,7 +1230,6 @@ void dynamicPaint_Modifier_copy(struct DynamicPaintModifierData *pmd, struct Dyn t_brush->flags = brush->flags; t_brush->collision = brush->collision; - t_brush->mat = brush->mat; t_brush->r = brush->r; t_brush->g = brush->g; t_brush->b = brush->b; @@ -3336,91 +3329,6 @@ void dynamicPaint_outputSurfaceImage(DynamicPaintSurface *surface, char *filenam } -/***************************** Material / Texture Sampling ******************************/ - -/* stores a copy of required materials to allow doing adjustments - * without interfering the render/preview */ -typedef struct BrushMaterials { - Material *mat; - Material **ob_mats; - int tot; -} BrushMaterials; - -/* Initialize materials for brush object: - * Calculates inverse matrices for linked objects, updates - * volume caches etc. */ -static void dynamicPaint_updateBrushMaterials(Depsgraph *depsgraph, Object *brushOb, Material *ui_mat, Scene *scene, BrushMaterials *bMats) -{ - /* Calculate inverse transformation matrix - * for this object */ - invert_m4_m4(brushOb->imat, brushOb->obmat); - copy_m4_m4(brushOb->imat_ren, brushOb->imat); - - /* Now process every material linked to this brush object */ - if ((ui_mat == NULL) && brushOb->mat && brushOb->totcol) { - int i, tot = (*give_totcolp(brushOb)); - - /* allocate material pointer array */ - if (tot) { - bMats->ob_mats = MEM_callocN(sizeof(Material *) * (tot), "BrushMaterials"); - for (i = 0; i < tot; i++) { - bMats->ob_mats[i] = RE_sample_material_init(depsgraph, give_current_material(brushOb, (i + 1)), scene); - } - } - bMats->tot = tot; - } - else { - bMats->mat = RE_sample_material_init(depsgraph, ui_mat, scene); - } -} - -/* free all data allocated by dynamicPaint_updateBrushMaterials() */ -static void dynamicPaint_freeBrushMaterials(BrushMaterials *bMats) -{ - /* Now process every material linked to this brush object */ - if (bMats->ob_mats) { - int i; - for (i = 0; i < bMats->tot; i++) { - RE_sample_material_free(bMats->ob_mats[i]); - } - MEM_freeN(bMats->ob_mats); - } - else if (bMats->mat) { - RE_sample_material_free(bMats->mat); - } -} - -/* - * Get material diffuse color and alpha (including linked textures) in given coordinates - */ -static void dynamicPaint_doMaterialTex( - const BrushMaterials *bMats, float color[3], float *alpha, Object *brushOb, - const float volume_co[3], const float surface_co[3], - int triIndex, DerivedMesh *orcoDm) -{ - Material *mat = bMats->mat; - - const MLoopTri *mlooptri = orcoDm->getLoopTriArray(orcoDm); - const MPoly *mpoly = orcoDm->getPolyArray(orcoDm); - - /* If no material defined, use the one assigned to the mesh face */ - if (mat == NULL) { - if (bMats->ob_mats) { - int mat_nr = mpoly[mlooptri[triIndex].poly].mat_nr; - if (mat_nr >= (*give_totcolp(brushOb))) - return; - mat = bMats->ob_mats[mat_nr]; - if (mat == NULL) - return; /* No material assigned */ - } - else { - return; - } - } - RE_sample_material_color(mat, color, alpha, volume_co, surface_co, triIndex, orcoDm, brushOb); -} - - /***************************** Ray / Nearest Point Utils ******************************/ @@ -3846,7 +3754,6 @@ typedef struct DynamicPaintPaintData { const DynamicPaintSurface *surface; const DynamicPaintBrushSettings *brush; Object *brushOb; - const BrushMaterials *bMats; const Scene *scene; const float timescale; const int c_index; @@ -3883,14 +3790,10 @@ static void dynamic_paint_paint_mesh_cell_point_cb_ex( VolumeGrid *grid = bData->grid; const DynamicPaintBrushSettings *brush = data->brush; - Object *brushOb = data->brushOb; - const BrushMaterials *bMats = data->bMats; - const Scene *scene = data->scene; const float timescale = data->timescale; const int c_index = data->c_index; - DerivedMesh *dm = data->dm; const MVert *mvert = data->mvert; const MLoop *mloop = data->mloop; const MLoopTri *mlooptri = data->mlooptri; @@ -4150,13 +4053,6 @@ static void dynamic_paint_paint_mesh_cell_point_cb_ex( sampleColor[1] = brush->g; sampleColor[2] = brush->b; - /* Get material+textures color on hit point if required */ - if (brush_usesMaterial(brush, scene)) { - dynamicPaint_doMaterialTex(bMats, sampleColor, &alpha_factor, brushOb, - bData->realCoord[bData->s_pos[index] + ss].v, - hitCoord, hitTri, dm); - } - /* Sample proximity colorband if required */ if ((hit_found == HIT_PROXIMITY) && (brush->proximity_falloff == MOD_DPAINT_PRFALL_RAMP)) @@ -4207,7 +4103,6 @@ static void dynamic_paint_paint_mesh_cell_point_cb_ex( static int dynamicPaint_paintMesh(struct Depsgraph *depsgraph, DynamicPaintSurface *surface, DynamicPaintBrushSettings *brush, Object *brushOb, - BrushMaterials *bMats, Scene *scene, float timescale) { @@ -4285,7 +4180,7 @@ static int dynamicPaint_paintMesh(struct Depsgraph *depsgraph, DynamicPaintSurfa /* loop through cell points and process brush */ DynamicPaintPaintData data = { .surface = surface, - .brush = brush, .brushOb = brushOb, .bMats = bMats, + .brush = brush, .brushOb = brushOb, .scene = scene, .timescale = timescale, .c_index = c_index, .dm = dm, .mvert = mvert, .mloop = mloop, .mlooptri = mlooptri, .brush_radius = brush_radius, .avg_brushNor = avg_brushNor, .brushVelocity = brushVelocity, @@ -4610,13 +4505,9 @@ static void dynamic_paint_paint_single_point_cb_ex( const PaintBakeData *bData = sData->bData; const DynamicPaintBrushSettings *brush = data->brush; - Object *brushOb = data->brushOb; - const BrushMaterials *bMats = data->bMats; - const Scene *scene = data->scene; const float timescale = data->timescale; - const MVert *mvert = data->mvert; const float brush_radius = data->brush_radius; const Vec3f *brushVelocity = data->brushVelocity; @@ -4645,17 +4536,6 @@ static void dynamic_paint_paint_single_point_cb_ex( float depth = 0.0f; float velocity_val = 0.0f; - /* material */ - if (brush_usesMaterial(brush, scene)) { - float alpha_factor = 1.0f; - float hit_coord[3]; - /* use dummy coord of first vertex */ - mul_v3_m4v3(hit_coord, brushOb->obmat, mvert[0].co); - - dynamicPaint_doMaterialTex(bMats, paintColor, &alpha_factor, brushOb, - bData->realCoord[bData->s_pos[index]].v, hit_coord, 0, brush->dm); - } - /* color ramp */ if (brush->proximity_falloff == MOD_DPAINT_PRFALL_RAMP && BKE_colorband_evaluate(brush->paint_ramp, (1.0f - strength), colorband)) @@ -4693,11 +4573,9 @@ static void dynamic_paint_paint_single_point_cb_ex( paintColor[2] = colorband[2]; } else { - if (!brush_usesMaterial(brush, scene)) { - paintColor[0] = brush->r; - paintColor[1] = brush->g; - paintColor[2] = brush->b; - } + paintColor[0] = brush->r; + paintColor[1] = brush->g; + paintColor[2] = brush->b; } } else if (ELEM(surface->type, MOD_DPAINT_SURFACE_T_DISPLACE, MOD_DPAINT_SURFACE_T_WAVE)) { @@ -4711,7 +4589,7 @@ static void dynamic_paint_paint_single_point_cb_ex( static int dynamicPaint_paintSinglePoint( struct Depsgraph *depsgraph, DynamicPaintSurface *surface, float *pointCoord, DynamicPaintBrushSettings *brush, - Object *brushOb, BrushMaterials *bMats, Scene *scene, float timescale) + Object *brushOb, Scene *scene, float timescale) { PaintSurfaceData *sData = surface->data; float brush_radius = brush->paint_distance * surface->radius_scale; @@ -4727,7 +4605,7 @@ static int dynamicPaint_paintSinglePoint( */ DynamicPaintPaintData data = { .surface = surface, - .brush = brush, .brushOb = brushOb, .bMats = bMats, + .brush = brush, .brushOb = brushOb, .scene = scene, .timescale = timescale, .mvert = mvert, .brush_radius = brush_radius, .brushVelocity = &brushVel, @@ -6068,7 +5946,6 @@ static int dynamicPaint_doStep(struct Depsgraph *depsgraph, Scene *scene, Object /* make sure we're dealing with a brush */ if (pmd2->brush) { DynamicPaintBrushSettings *brush = pmd2->brush; - BrushMaterials bMats = {NULL}; /* calculate brush speed vectors if required */ if (surface->type == MOD_DPAINT_SURFACE_T_PAINT && brush->flags & MOD_DPAINT_DO_SMUDGE) { @@ -6086,32 +5963,27 @@ static int dynamicPaint_doStep(struct Depsgraph *depsgraph, Scene *scene, Object BKE_object_modifier_update_subframe(depsgraph, scene, brushObj, true, SUBFRAME_RECURSION, BKE_scene_frame_get(scene), eModifierType_DynamicPaint); } - /* Prepare materials if required */ - if (brush_usesMaterial(brush, scene)) - dynamicPaint_updateBrushMaterials(depsgraph, brushObj, brush->mat, scene, &bMats); + /* Apply brush on the surface depending on it's collision type */ - if (brush->psys && brush->psys->part && - ELEM(brush->psys->part->type, PART_EMITTER, PART_FLUID) && - psys_check_enabled(brushObj, brush->psys, G.is_rendering)) - { - /* Paint a particle system */ - BKE_animsys_evaluate_animdata(scene, &brush->psys->part->id, brush->psys->part->adt, - BKE_scene_frame_get(scene), ADT_RECALC_ANIM); - dynamicPaint_paintParticles(surface, brush->psys, brush, timescale); - } + if (brush->psys && brush->psys->part && + ELEM(brush->psys->part->type, PART_EMITTER, PART_FLUID) && + psys_check_enabled(brushObj, brush->psys, G.is_rendering)) + { + /* Paint a particle system */ + BKE_animsys_evaluate_animdata(scene, &brush->psys->part->id, brush->psys->part->adt, + BKE_scene_frame_get(scene), ADT_RECALC_ANIM); + dynamicPaint_paintParticles(surface, brush->psys, brush, timescale); + } /* Object center distance: */ if (brush->collision == MOD_DPAINT_COL_POINT && brushObj != ob) { - dynamicPaint_paintSinglePoint(depsgraph, surface, brushObj->loc, brush, brushObj, &bMats, scene, timescale); + dynamicPaint_paintSinglePoint(depsgraph, surface, brushObj->loc, brush, brushObj, scene, timescale); } /* Mesh volume/proximity: */ else if (brushObj != ob) { - dynamicPaint_paintMesh(depsgraph, surface, brush, brushObj, &bMats, scene, timescale); + dynamicPaint_paintMesh(depsgraph, surface, brush, brushObj, scene, timescale); } - /* free temp material data */ - if (brush_usesMaterial(brush, scene)) - dynamicPaint_freeBrushMaterials(&bMats); /* reset object to it's original state */ if (subframe) { scene->r.cfra = scene_frame; diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c index 4281443220d..3b9d5c47ad2 100644 --- a/source/blender/blenkernel/intern/editderivedmesh.c +++ b/source/blender/blenkernel/intern/editderivedmesh.c @@ -59,11 +59,6 @@ #include "MEM_guardedalloc.h" -#include "GPU_glew.h" -#include "GPU_buffers.h" -#include "GPU_shader.h" -#include "GPU_basic_shader.h" - static void bmdm_get_tri_colpreview(BMLoop *ls[3], MLoopCol *lcol[3], unsigned char(*color_vert_array)[4]); typedef struct EditDerivedBMesh { @@ -370,90 +365,6 @@ static void emDM_foreachMappedEdge( } } -static void emDM_drawMappedEdges( - DerivedMesh *dm, - DMSetDrawOptions setDrawOptions, - void *userData) -{ - EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm; - BMesh *bm = bmdm->em->bm; - BMEdge *eed; - BMIter iter; - int i; - - if (bmdm->vertexCos) { - - BM_mesh_elem_index_ensure(bm, BM_VERT); - - glBegin(GL_LINES); - BM_ITER_MESH_INDEX (eed, &iter, bm, BM_EDGES_OF_MESH, i) { - if (!setDrawOptions || (setDrawOptions(userData, i) != DM_DRAW_OPTION_SKIP)) { - glVertex3fv(bmdm->vertexCos[BM_elem_index_get(eed->v1)]); - glVertex3fv(bmdm->vertexCos[BM_elem_index_get(eed->v2)]); - } - } - glEnd(); - } - else { - glBegin(GL_LINES); - BM_ITER_MESH_INDEX (eed, &iter, bm, BM_EDGES_OF_MESH, i) { - if (!setDrawOptions || (setDrawOptions(userData, i) != DM_DRAW_OPTION_SKIP)) { - glVertex3fv(eed->v1->co); - glVertex3fv(eed->v2->co); - } - } - glEnd(); - } -} -static void emDM_drawEdges( - DerivedMesh *dm, - bool UNUSED(drawLooseEdges), - bool UNUSED(drawAllEdges)) -{ - emDM_drawMappedEdges(dm, NULL, NULL); -} - -static void emDM_drawMappedEdgesInterp( - DerivedMesh *dm, - DMSetDrawOptions setDrawOptions, - DMSetDrawInterpOptions setDrawInterpOptions, - void *userData) -{ - EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm; - BMesh *bm = bmdm->em->bm; - BMEdge *eed; - BMIter iter; - int i; - - if (bmdm->vertexCos) { - - BM_mesh_elem_index_ensure(bm, BM_VERT); - - glBegin(GL_LINES); - BM_ITER_MESH_INDEX (eed, &iter, bm, BM_EDGES_OF_MESH, i) { - if (!setDrawOptions || (setDrawOptions(userData, i) != DM_DRAW_OPTION_SKIP)) { - setDrawInterpOptions(userData, i, 0.0); - glVertex3fv(bmdm->vertexCos[BM_elem_index_get(eed->v1)]); - setDrawInterpOptions(userData, i, 1.0); - glVertex3fv(bmdm->vertexCos[BM_elem_index_get(eed->v2)]); - } - } - glEnd(); - } - else { - glBegin(GL_LINES); - BM_ITER_MESH_INDEX (eed, &iter, bm, BM_EDGES_OF_MESH, i) { - if (!setDrawOptions || (setDrawOptions(userData, i) != DM_DRAW_OPTION_SKIP)) { - setDrawInterpOptions(userData, i, 0.0); - glVertex3fv(eed->v1->co); - setDrawInterpOptions(userData, i, 1.0); - glVertex3fv(eed->v2->co); - } - } - glEnd(); - } -} - static void emDM_foreachMappedLoop( DerivedMesh *dm, void (*func)(void *userData, int vertex_index, int face_index, const float co[3], const float no[3]), @@ -526,571 +437,6 @@ static void emDM_foreachMappedFaceCenter( } } -static void emDM_drawMappedFaces( - DerivedMesh *dm, - DMSetDrawOptions setDrawOptions, - DMSetMaterial setMaterial, - /* currently unused -- each original face is handled separately */ - DMCompareDrawOptions UNUSED(compareDrawOptions), - void *userData, - DMDrawFlag flag) -{ - EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm; - BMEditMesh *em = bmdm->em; - BMesh *bm = em->bm; - BMFace *efa; - struct BMLoop *(*looptris)[3] = bmdm->em->looptris; - const int tottri = bmdm->em->tottri; - DMDrawOption draw_option; - int i; - const int skip_normals = !(flag & DM_DRAW_NEED_NORMALS); - const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL); - MLoopCol *lcol[3] = {NULL} /* , dummylcol = {0} */; - unsigned char(*color_vert_array)[4] = em->derivedVertColor; - unsigned char(*color_face_array)[4] = em->derivedFaceColor; - bool has_vcol_preview = (color_vert_array != NULL) && !skip_normals; - bool has_fcol_preview = (color_face_array != NULL) && !skip_normals; - bool has_vcol_any = has_vcol_preview; - - /* GL_ZERO is used to detect if drawing has started or not */ - GLenum poly_prev = GL_ZERO; - GLenum shade_prev = GL_ZERO; - DMDrawOption draw_option_prev = DM_DRAW_OPTION_SKIP; - - /* call again below is ok */ - if (has_vcol_preview) { - BM_mesh_elem_index_ensure(bm, BM_VERT); - } - if (has_fcol_preview) { - BM_mesh_elem_index_ensure(bm, BM_FACE); - } - if (has_vcol_preview || has_fcol_preview) { - flag |= DM_DRAW_ALWAYS_SMOOTH; - /* weak, this logic should really be moved higher up */ - setMaterial = NULL; - } - - if (bmdm->vertexCos) { - short prev_mat_nr = -1; - - /* add direct access */ - const float (*vertexCos)[3] = bmdm->vertexCos; - const float (*vertexNos)[3]; - const float (*polyNos)[3]; - - if (skip_normals) { - vertexNos = NULL; - polyNos = NULL; - } - else { - emDM_ensureVertNormals(bmdm); - emDM_ensurePolyNormals(bmdm); - vertexNos = bmdm->vertexNos; - polyNos = bmdm->polyNos; - } - - BM_mesh_elem_index_ensure(bm, lnors ? BM_VERT | BM_FACE | BM_LOOP : BM_VERT | BM_FACE); - - for (i = 0; i < tottri; i++) { - BMLoop **ltri = looptris[i]; - int drawSmooth; - - efa = ltri[0]->f; - drawSmooth = lnors || ((flag & DM_DRAW_ALWAYS_SMOOTH) ? 1 : BM_elem_flag_test(efa, BM_ELEM_SMOOTH)); - - draw_option = (!setDrawOptions ? - DM_DRAW_OPTION_NORMAL : - setDrawOptions(userData, BM_elem_index_get(efa))); - if (draw_option != DM_DRAW_OPTION_SKIP) { - const GLenum poly_type = GL_TRIANGLES; /* BMESH NOTE, this is odd but keep it for now to match trunk */ - - if (draw_option_prev != draw_option) { - if (draw_option_prev == DM_DRAW_OPTION_STIPPLE) { - if (poly_prev != GL_ZERO) glEnd(); - poly_prev = GL_ZERO; /* force glBegin */ - - GPU_basic_shader_bind(GPU_SHADER_USE_COLOR); - } - draw_option_prev = draw_option; - } - - - if (efa->mat_nr != prev_mat_nr) { - if (setMaterial) { - if (poly_prev != GL_ZERO) glEnd(); - poly_prev = GL_ZERO; /* force glBegin */ - - setMaterial(efa->mat_nr + 1, NULL); - } - prev_mat_nr = efa->mat_nr; - } - - if (draw_option == DM_DRAW_OPTION_STIPPLE) { /* enabled with stipple */ - - if (poly_prev != GL_ZERO) glEnd(); - poly_prev = GL_ZERO; /* force glBegin */ - - GPU_basic_shader_bind(GPU_SHADER_STIPPLE | GPU_SHADER_USE_COLOR); - GPU_basic_shader_stipple(GPU_SHADER_STIPPLE_QUARTTONE); - } - - if (has_vcol_preview) bmdm_get_tri_colpreview(ltri, lcol, color_vert_array); - else if (has_fcol_preview) glColor3ubv((const GLubyte *)&(color_face_array[BM_elem_index_get(efa)])); - if (skip_normals) { - if (poly_type != poly_prev) { - if (poly_prev != GL_ZERO) glEnd(); - glBegin((poly_prev = poly_type)); /* BMesh: will always be GL_TRIANGLES */ - } - if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[0]->r)); - glVertex3fv(vertexCos[BM_elem_index_get(ltri[0]->v)]); - if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[1]->r)); - glVertex3fv(vertexCos[BM_elem_index_get(ltri[1]->v)]); - if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[2]->r)); - glVertex3fv(vertexCos[BM_elem_index_get(ltri[2]->v)]); - } - else { - const GLenum shade_type = drawSmooth ? GL_SMOOTH : GL_FLAT; - if (shade_type != shade_prev) { - if (poly_prev != GL_ZERO) glEnd(); - glShadeModel((shade_prev = shade_type)); /* same as below but switch shading */ - glBegin((poly_prev = poly_type)); /* BMesh: will always be GL_TRIANGLES */ - } - if (poly_type != poly_prev) { - if (poly_prev != GL_ZERO) glEnd(); - glBegin((poly_prev = poly_type)); /* BMesh: will always be GL_TRIANGLES */ - } - - if (!drawSmooth) { - glNormal3fv(polyNos[BM_elem_index_get(efa)]); - if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[0]->r)); - glVertex3fv(vertexCos[BM_elem_index_get(ltri[0]->v)]); - if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[1]->r)); - glVertex3fv(vertexCos[BM_elem_index_get(ltri[1]->v)]); - if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[2]->r)); - glVertex3fv(vertexCos[BM_elem_index_get(ltri[2]->v)]); - } - else { - if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[0]->r)); - if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[0])]); - else glNormal3fv(vertexNos[BM_elem_index_get(ltri[0]->v)]); - glVertex3fv(vertexCos[BM_elem_index_get(ltri[0]->v)]); - if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[1]->r)); - if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[1])]); - else glNormal3fv(vertexNos[BM_elem_index_get(ltri[1]->v)]); - glVertex3fv(vertexCos[BM_elem_index_get(ltri[1]->v)]); - if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[2]->r)); - if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[2])]); - else glNormal3fv(vertexNos[BM_elem_index_get(ltri[2]->v)]); - glVertex3fv(vertexCos[BM_elem_index_get(ltri[2]->v)]); - } - } - } - } - } - else { - short prev_mat_nr = -1; - - BM_mesh_elem_index_ensure(bm, lnors ? BM_FACE | BM_LOOP : BM_FACE); - - for (i = 0; i < tottri; i++) { - BMLoop **ltri = looptris[i]; - int drawSmooth; - - efa = ltri[0]->f; - drawSmooth = lnors || ((flag & DM_DRAW_ALWAYS_SMOOTH) ? 1 : BM_elem_flag_test(efa, BM_ELEM_SMOOTH)); - - draw_option = (setDrawOptions ? - setDrawOptions(userData, BM_elem_index_get(efa)) : - DM_DRAW_OPTION_NORMAL); - - if (draw_option != DM_DRAW_OPTION_SKIP) { - const GLenum poly_type = GL_TRIANGLES; /* BMESH NOTE, this is odd but keep it for now to match trunk */ - - if (draw_option_prev != draw_option) { - if (draw_option_prev == DM_DRAW_OPTION_STIPPLE) { - if (poly_prev != GL_ZERO) glEnd(); - poly_prev = GL_ZERO; /* force glBegin */ - - GPU_basic_shader_bind(GPU_SHADER_USE_COLOR); - } - draw_option_prev = draw_option; - } - - if (efa->mat_nr != prev_mat_nr) { - if (setMaterial) { - if (poly_prev != GL_ZERO) glEnd(); - poly_prev = GL_ZERO; /* force glBegin */ - - setMaterial(efa->mat_nr + 1, NULL); - } - prev_mat_nr = efa->mat_nr; - } - - if (draw_option == DM_DRAW_OPTION_STIPPLE) { /* enabled with stipple */ - - if (poly_prev != GL_ZERO) glEnd(); - poly_prev = GL_ZERO; /* force glBegin */ - - GPU_basic_shader_bind(GPU_SHADER_STIPPLE | GPU_SHADER_USE_COLOR); - GPU_basic_shader_stipple(GPU_SHADER_STIPPLE_QUARTTONE); - } - - if (has_vcol_preview) bmdm_get_tri_colpreview(ltri, lcol, color_vert_array); - else if (has_fcol_preview) glColor3ubv((const GLubyte *)&(color_face_array[BM_elem_index_get(efa)])); - - if (skip_normals) { - if (poly_type != poly_prev) { - if (poly_prev != GL_ZERO) glEnd(); - glBegin((poly_prev = poly_type)); /* BMesh: will always be GL_TRIANGLES */ - } - if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[0]->r)); - glVertex3fv(ltri[0]->v->co); - if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[1]->r)); - glVertex3fv(ltri[1]->v->co); - if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[2]->r)); - glVertex3fv(ltri[2]->v->co); - } - else { - const GLenum shade_type = drawSmooth ? GL_SMOOTH : GL_FLAT; - if (shade_type != shade_prev) { - if (poly_prev != GL_ZERO) glEnd(); - glShadeModel((shade_prev = shade_type)); /* same as below but switch shading */ - glBegin((poly_prev = poly_type)); /* BMesh: will always be GL_TRIANGLES */ - } - if (poly_type != poly_prev) { - if (poly_prev != GL_ZERO) glEnd(); - glBegin((poly_prev = poly_type)); /* BMesh: will always be GL_TRIANGLES */ - } - - if (!drawSmooth) { - glNormal3fv(efa->no); - if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[0]->r)); - glVertex3fv(ltri[0]->v->co); - if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[1]->r)); - glVertex3fv(ltri[1]->v->co); - if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[2]->r)); - glVertex3fv(ltri[2]->v->co); - } - else { - if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[0]->r)); - if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[0])]); - else glNormal3fv(ltri[0]->v->no); - glVertex3fv(ltri[0]->v->co); - if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[1]->r)); - if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[1])]); - else glNormal3fv(ltri[1]->v->no); - glVertex3fv(ltri[1]->v->co); - if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[2]->r)); - if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[2])]); - else glNormal3fv(ltri[2]->v->no); - glVertex3fv(ltri[2]->v->co); - } - } - } - } - } - - /* if non zero we know a face was rendered */ - if (poly_prev != GL_ZERO) glEnd(); - - if (draw_option_prev == DM_DRAW_OPTION_STIPPLE) { - GPU_basic_shader_bind(GPU_SHADER_USE_COLOR); - } - - if (shade_prev == GL_FLAT) { - glShadeModel(GL_SMOOTH); - } -} - -static void bmdm_get_tri_colpreview(BMLoop *ls[3], MLoopCol *lcol[3], unsigned char(*color_vert_array)[4]) -{ - lcol[0] = (MLoopCol *)color_vert_array[BM_elem_index_get(ls[0]->v)]; - lcol[1] = (MLoopCol *)color_vert_array[BM_elem_index_get(ls[1]->v)]; - lcol[2] = (MLoopCol *)color_vert_array[BM_elem_index_get(ls[2]->v)]; -} - -/** - * \note - * - * For UV's: - * const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(loop, attribs->tface[i].em_offset); - * - * This is intentionally different to calling: - * CustomData_bmesh_get_n(&bm->ldata, loop->head.data, CD_MLOOPUV, i); - * - * ... because the material may use layer names to select different UV's - * see: [#34378] - */ -static void emdm_pass_attrib_vertex_glsl(const DMVertexAttribs *attribs, const BMLoop *loop) -{ - BMVert *eve = loop->v; - int i; - const float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f}; - - if (attribs->totorco) { - int index = BM_elem_index_get(eve); - const float *orco = (attribs->orco.array) ? attribs->orco.array[index] : zero; - - if (attribs->orco.gl_texco) - glTexCoord3fv(orco); - else - glVertexAttrib3fv(attribs->orco.gl_index, orco); - } - for (i = 0; i < attribs->tottface; i++) { - const float *uv; - - if (attribs->tface[i].em_offset != -1) { - const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(loop, attribs->tface[i].em_offset); - uv = luv->uv; - } - else { - uv = zero; - } - - if (attribs->tface[i].gl_texco) - glTexCoord2fv(uv); - else - glVertexAttrib2fv(attribs->tface[i].gl_index, uv); - } - for (i = 0; i < attribs->totmcol; i++) { - float col[4]; - if (attribs->mcol[i].em_offset != -1) { - const MLoopCol *cp = BM_ELEM_CD_GET_VOID_P(loop, attribs->mcol[i].em_offset); - rgba_uchar_to_float(col, &cp->r); - } - else { - col[0] = 0.0f; col[1] = 0.0f; col[2] = 0.0f; col[3] = 0.0f; - } - glVertexAttrib4fv(attribs->mcol[i].gl_index, col); - } - - for (i = 0; i < attribs->tottang; i++) { - const float *tang; - if (attribs->tang[i].em_offset != -1) { - tang = attribs->tang[i].array[BM_elem_index_get(loop)]; - } - else { - tang = zero; - } - glVertexAttrib4fv(attribs->tang[i].gl_index, tang); - } -} - -static void emDM_drawMappedFacesGLSL( - DerivedMesh *dm, - DMSetMaterial setMaterial, - DMSetDrawOptions setDrawOptions, - void *userData) -{ - EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm; - BMEditMesh *em = bmdm->em; - BMesh *bm = em->bm; - struct BMLoop *(*looptris)[3] = em->looptris; - /* add direct access */ - const float (*vertexCos)[3] = bmdm->vertexCos; - const float (*vertexNos)[3]; - const float (*polyNos)[3]; - const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL); - - BMFace *efa; - DMVertexAttribs attribs; - GPUVertexAttribs gattribs; - - int i, matnr, new_matnr, fi; - bool do_draw; - - do_draw = false; - matnr = -1; - - memset(&attribs, 0, sizeof(attribs)); - - emDM_ensureVertNormals(bmdm); - emDM_ensurePolyNormals(bmdm); - vertexNos = bmdm->vertexNos; - polyNos = bmdm->polyNos; - - BM_mesh_elem_index_ensure(bm, (BM_VERT | BM_FACE) | (lnors ? BM_LOOP : 0)); - - for (i = 0; i < em->tottri; i++) { - BMLoop **ltri = looptris[i]; - int drawSmooth; - - efa = ltri[0]->f; - - if (setDrawOptions && (setDrawOptions(userData, BM_elem_index_get(efa)) == DM_DRAW_OPTION_SKIP)) - continue; - - /* material */ - new_matnr = efa->mat_nr + 1; - if (new_matnr != matnr) { - if (matnr != -1) - glEnd(); - - do_draw = setMaterial(matnr = new_matnr, &gattribs); - if (do_draw) { - DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs); - DM_draw_attrib_vertex_uniforms(&attribs); - if (UNLIKELY(attribs.tottang && bm->elem_index_dirty & BM_LOOP)) { - BM_mesh_elem_index_ensure(bm, BM_LOOP); - } - } - - glBegin(GL_TRIANGLES); - } - - if (do_draw) { - - /* draw face */ - drawSmooth = lnors || BM_elem_flag_test(efa, BM_ELEM_SMOOTH); - - if (!drawSmooth) { - if (vertexCos) { - glNormal3fv(polyNos[BM_elem_index_get(efa)]); - for (fi = 0; fi < 3; fi++) { - emdm_pass_attrib_vertex_glsl(&attribs, ltri[fi]); - glVertex3fv(vertexCos[BM_elem_index_get(ltri[fi]->v)]); - } - } - else { - glNormal3fv(efa->no); - for (fi = 0; fi < 3; fi++) { - emdm_pass_attrib_vertex_glsl(&attribs, ltri[fi]); - glVertex3fv(ltri[fi]->v->co); - } - } - } - else { - if (vertexCos) { - for (fi = 0; fi < 3; fi++) { - const int j = BM_elem_index_get(ltri[fi]->v); - emdm_pass_attrib_vertex_glsl(&attribs, ltri[fi]); - if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[fi])]); - else glNormal3fv(vertexNos[j]); - glVertex3fv(vertexCos[j]); - } - } - else { - for (fi = 0; fi < 3; fi++) { - emdm_pass_attrib_vertex_glsl(&attribs, ltri[fi]); - if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[fi])]); - else glNormal3fv(ltri[fi]->v->no); - glVertex3fv(ltri[fi]->v->co); - } - } - } - } - } - - if (matnr != -1) { - glEnd(); - } -} - -static void emDM_drawFacesGLSL( - DerivedMesh *dm, - int (*setMaterial)(int matnr, void *attribs)) -{ - dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL); -} - -static void emDM_drawMappedFacesMat( - DerivedMesh *dm, - void (*setMaterial)(void *userData, int matnr, void *attribs), - bool (*setFace)(void *userData, int index), void *userData) -{ - EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm; - BMEditMesh *em = bmdm->em; - BMesh *bm = em->bm; - struct BMLoop *(*looptris)[3] = em->looptris; - const float (*vertexCos)[3] = bmdm->vertexCos; - const float (*vertexNos)[3]; - const float (*polyNos)[3]; - const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL); - BMFace *efa; - DMVertexAttribs attribs = {{{NULL}}}; - GPUVertexAttribs gattribs; - int i, matnr, new_matnr, fi; - - matnr = -1; - - emDM_ensureVertNormals(bmdm); - emDM_ensurePolyNormals(bmdm); - - vertexNos = bmdm->vertexNos; - polyNos = bmdm->polyNos; - - BM_mesh_elem_index_ensure(bm, (BM_VERT | BM_FACE) | (lnors ? BM_LOOP : 0)); - - for (i = 0; i < em->tottri; i++) { - BMLoop **ltri = looptris[i]; - int drawSmooth; - - efa = ltri[0]->f; - - /* face hiding */ - if (setFace && !setFace(userData, BM_elem_index_get(efa))) - continue; - - /* material */ - new_matnr = efa->mat_nr + 1; - if (new_matnr != matnr) { - if (matnr != -1) - glEnd(); - - setMaterial(userData, matnr = new_matnr, &gattribs); - DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs); - if (UNLIKELY(attribs.tottang && bm->elem_index_dirty & BM_LOOP)) { - BM_mesh_elem_index_ensure(bm, BM_LOOP); - } - - glBegin(GL_TRIANGLES); - } - - /* draw face */ - drawSmooth = lnors || BM_elem_flag_test(efa, BM_ELEM_SMOOTH); - - if (!drawSmooth) { - if (vertexCos) { - glNormal3fv(polyNos[BM_elem_index_get(efa)]); - for (fi = 0; fi < 3; fi++) { - emdm_pass_attrib_vertex_glsl(&attribs, ltri[fi]); - glVertex3fv(vertexCos[BM_elem_index_get(ltri[fi]->v)]); - } - } - else { - glNormal3fv(efa->no); - for (fi = 0; fi < 3; fi++) { - emdm_pass_attrib_vertex_glsl(&attribs, ltri[fi]); - glVertex3fv(ltri[fi]->v->co); - } - } - } - else { - if (vertexCos) { - for (fi = 0; fi < 3; fi++) { - const int j = BM_elem_index_get(ltri[fi]->v); - emdm_pass_attrib_vertex_glsl(&attribs, ltri[fi]); - if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[fi])]); - else glNormal3fv(vertexNos[j]); - glVertex3fv(vertexCos[j]); - } - } - else { - for (fi = 0; fi < 3; fi++) { - emdm_pass_attrib_vertex_glsl(&attribs, ltri[fi]); - if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[fi])]); - else glNormal3fv(ltri[fi]->v->no); - glVertex3fv(ltri[fi]->v->co); - } - } - } - } - - if (matnr != -1) { - glEnd(); - } -} - static void emDM_getMinMax(DerivedMesh *dm, float r_min[3], float r_max[3]) { EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm; @@ -1660,14 +1006,6 @@ DerivedMesh *getEditDerivedBMesh( bmdm->dm.foreachMappedEdge = emDM_foreachMappedEdge; bmdm->dm.foreachMappedFaceCenter = emDM_foreachMappedFaceCenter; - bmdm->dm.drawEdges = emDM_drawEdges; - bmdm->dm.drawMappedEdges = emDM_drawMappedEdges; - bmdm->dm.drawMappedEdgesInterp = emDM_drawMappedEdgesInterp; - bmdm->dm.drawMappedFaces = emDM_drawMappedFaces; - bmdm->dm.drawMappedFacesGLSL = emDM_drawMappedFacesGLSL; - bmdm->dm.drawMappedFacesMat = emDM_drawMappedFacesMat; - bmdm->dm.drawFacesGLSL = emDM_drawFacesGLSL; - bmdm->dm.release = emDM_release; bmdm->vertexCos = (const float (*)[3])vertexCos; diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c index c2e9af685a6..941c7eb2a87 100644 --- a/source/blender/blenkernel/intern/ipo.c +++ b/source/blender/blenkernel/intern/ipo.c @@ -145,17 +145,6 @@ static AdrBit2Path ob_layer_bits[] = { {(1 << 19), "layers", 19} }; -/* Material mode */ -static AdrBit2Path ma_mode_bits[] = { -// {MA_TRACEBLE, "traceable", 0}, -// {MA_SHADOW, "shadow", 0}, -// {MA_SHLESS, "shadeless", 0}, -// ... - {MA_RAYTRANSP, "transparency", 0}, - {MA_RAYMIRROR, "raytrace_mirror.enabled", 0}, -// {MA_HALO, "type", MA_TYPE_HALO} -}; - /* ----------------- */ /* quick macro for returning the appropriate array for adrcode_bitmaps_to_paths() */ @@ -172,9 +161,6 @@ static AdrBit2Path *adrcode_bitmaps_to_paths(int blocktype, int adrcode, int *to if ((blocktype == ID_OB) && (adrcode == OB_LAY)) { RET_ABP(ob_layer_bits); } - else if ((blocktype == ID_MA) && (adrcode == MA_MODE)) { - RET_ABP(ma_mode_bits); - } // XXX TODO: add other types... /* Normal curve */ diff --git a/source/blender/blenkernel/intern/lamp.c b/source/blender/blenkernel/intern/lamp.c index bf36c437d60..75abd10f52d 100644 --- a/source/blender/blenkernel/intern/lamp.c +++ b/source/blender/blenkernel/intern/lamp.c @@ -72,35 +72,14 @@ void BKE_lamp_init(Lamp *la) la->samp = 3; la->bias = 1.0f; la->soft = 3.0f; - la->compressthresh = 0.05f; - la->ray_samp = la->ray_sampy = la->ray_sampz = 1; la->area_size = la->area_sizey = la->area_sizez = 0.1f; la->buffers = 1; - la->buftype = LA_SHADBUF_HALFWAY; - la->ray_samp_method = LA_SAMP_HALTON; - la->adapt_thresh = 0.001f; la->preview = NULL; la->falloff_type = LA_FALLOFF_INVSQUARE; la->coeff_const = 1.0f; la->coeff_lin = 0.0f; la->coeff_quad = 0.0f; la->curfalloff = curvemapping_add(1, 0.0f, 1.0f, 1.0f, 0.0f); - la->sun_effect_type = 0; - la->horizon_brightness = 1.0; - la->spread = 1.0; - la->sun_brightness = 1.0; - la->sun_size = 1.0; - la->backscattered_light = 1.0f; - la->atm_turbidity = 2.0f; - la->atm_inscattering_factor = 1.0f; - la->atm_extinction_factor = 1.0f; - la->atm_distance_factor = 1.0f; - la->sun_intensity = 1.0f; - la->skyblendtype = MA_RAMP_ADD; - la->skyblendfac = 1.0f; - la->sky_colorspace = BLI_XYZ_CIE; - la->sky_exposure = 1.0f; - la->shadow_frustum_size = 10.0f; la->cascade_max_dist = 1000.0f; la->cascade_count = 4; la->cascade_exponent = 0.8f; @@ -134,13 +113,6 @@ Lamp *BKE_lamp_add(Main *bmain, const char *name) */ void BKE_lamp_copy_data(Main *bmain, Lamp *la_dst, const Lamp *la_src, const int flag) { - for (int a = 0; a < MAX_MTEX; a++) { - if (la_dst->mtex[a]) { - la_dst->mtex[a] = MEM_mallocN(sizeof(*la_dst->mtex[a]), __func__); - *la_dst->mtex[a] = *la_src->mtex[a]; - } - } - la_dst->curfalloff = curvemapping_copy(la_src->curfalloff); if (la_src->nodetree) { @@ -173,18 +145,8 @@ Lamp *BKE_lamp_localize(Lamp *la) * * ... Once f*** nodes are fully converted to that too :( */ - Lamp *lan; - int a; - - lan = BKE_libblock_copy_nolib(&la->id, false); + Lamp *lan = BKE_libblock_copy_nolib(&la->id, false); - for (a = 0; a < MAX_MTEX; a++) { - if (lan->mtex[a]) { - lan->mtex[a] = MEM_mallocN(sizeof(MTex), __func__); - memcpy(lan->mtex[a], la->mtex[a], sizeof(MTex)); - } - } - lan->curfalloff = curvemapping_copy(la->curfalloff); if (la->nodetree) @@ -202,12 +164,6 @@ void BKE_lamp_make_local(Main *bmain, Lamp *la, const bool lib_local) void BKE_lamp_free(Lamp *la) { - int a; - - for (a = 0; a < MAX_MTEX; a++) { - MEM_SAFE_FREE(la->mtex[a]); - } - BKE_animdata_free((ID *)la, false); curvemapping_free(la->curfalloff); diff --git a/source/blender/blenkernel/intern/library_query.c b/source/blender/blenkernel/intern/library_query.c index 28e2201ccfa..9c015cea225 100644 --- a/source/blender/blenkernel/intern/library_query.c +++ b/source/blender/blenkernel/intern/library_query.c @@ -625,17 +625,10 @@ void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback call case ID_MA: { Material *material = (Material *) id; - for (i = 0; i < MAX_MTEX; i++) { - if (material->mtex[i]) { - library_foreach_mtex(&data, material->mtex[i]); - } - } if (material->nodetree) { /* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */ library_foreach_ID_as_subdata_link((ID **)&material->nodetree, callback, user_data, flag, &data); } - CALLBACK_INVOKE(material->group, IDWALK_CB_USER); - CALLBACK_INVOKE(material->edit_image, IDWALK_CB_USER); if (material->texpaintslot != NULL) { CALLBACK_INVOKE(material->texpaintslot->ima, IDWALK_CB_NOP); } @@ -650,16 +643,6 @@ void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback call library_foreach_ID_as_subdata_link((ID **)&texture->nodetree, callback, user_data, flag, &data); } CALLBACK_INVOKE(texture->ima, IDWALK_CB_USER); - if (texture->env) { - CALLBACK_INVOKE(texture->env->object, IDWALK_CB_NOP); - CALLBACK_INVOKE(texture->env->ima, IDWALK_CB_USER); - } - if (texture->pd) - CALLBACK_INVOKE(texture->pd->object, IDWALK_CB_NOP); - if (texture->vd) - CALLBACK_INVOKE(texture->vd->object, IDWALK_CB_NOP); - if (texture->ot) - CALLBACK_INVOKE(texture->ot->object, IDWALK_CB_NOP); break; } @@ -673,11 +656,6 @@ void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback call case ID_LA: { Lamp *lamp = (Lamp *) id; - for (i = 0; i < MAX_MTEX; i++) { - if (lamp->mtex[i]) { - library_foreach_mtex(&data, lamp->mtex[i]); - } - } if (lamp->nodetree) { /* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */ library_foreach_ID_as_subdata_link((ID **)&lamp->nodetree, callback, user_data, flag, &data); @@ -702,11 +680,6 @@ void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback call case ID_WO: { World *world = (World *) id; - for (i = 0; i < MAX_MTEX; i++) { - if (world->mtex[i]) { - library_foreach_mtex(&data, world->mtex[i]); - } - } if (world->nodetree) { /* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */ library_foreach_ID_as_subdata_link((ID **)&world->nodetree, callback, user_data, flag, &data); diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index fee91865d35..39ad95e9183 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -89,17 +89,8 @@ void init_def_material(void) /** Free (or release) any data used by this material (does not free the material itself). */ void BKE_material_free(Material *ma) { - int a; - BKE_animdata_free((ID *)ma, false); - for (a = 0; a < MAX_MTEX; a++) { - MEM_SAFE_FREE(ma->mtex[a]); - } - - MEM_SAFE_FREE(ma->ramp_col); - MEM_SAFE_FREE(ma->ramp_spec); - /* Free gpu material before the ntree */ GPU_material_free(&ma->gpumaterial); @@ -120,90 +111,16 @@ void BKE_material_init(Material *ma) { BLI_assert(MEMCMP_STRUCT_OFS_IS_ZERO(ma, id)); - ma->r = ma->g = ma->b = ma->ref = 0.8; + ma->r = ma->g = ma->b = 0.8; ma->specr = ma->specg = ma->specb = 1.0; - ma->mirr = ma->mirg = ma->mirb = 1.0; - ma->spectra = 1.0; - ma->amb = 1.0; ma->alpha = 1.0; - ma->spec = ma->hasize = 0.5; - ma->har = 50; - ma->starc = ma->ringc = 4; - ma->linec = 12; - ma->flarec = 1; - ma->flaresize = ma->subsize = 1.0; - ma->flareboost = 1; - ma->seed2 = 6; - ma->friction = 0.5; - ma->refrac = 4.0; - ma->roughness = 0.5; - ma->param[0] = 0.5; - ma->param[1] = 0.1; - ma->param[2] = 0.5; - ma->param[3] = 0.1; - ma->rms = 0.1; - ma->darkness = 1.0; - - ma->strand_sta = ma->strand_end = 1.0f; - - ma->ang = 1.0; - ma->ray_depth = 2; - ma->ray_depth_tra = 2; - ma->fresnel_mir = 0.0; - ma->fresnel_tra = 0.0; - ma->fresnel_tra_i = 1.25; - ma->fresnel_mir_i = 1.25; - ma->tx_limit = 0.0; - ma->tx_falloff = 1.0; - ma->shad_alpha = 1.0f; - ma->vcol_alpha = 0; - - ma->gloss_mir = ma->gloss_tra = 1.0; - ma->samp_gloss_mir = ma->samp_gloss_tra = 18; - ma->adapt_thresh_mir = ma->adapt_thresh_tra = 0.005; - ma->dist_mir = 0.0; - ma->fadeto_mir = MA_RAYMIR_FADETOSKY; + ma->spec = 0.5; + + ma->gloss_mir = 1.0; - ma->rampfac_col = 1.0; - ma->rampfac_spec = 1.0; ma->pr_lamp = 3; /* two lamps, is bits */ ma->pr_type = MA_SPHERE; - ma->sss_radius[0] = 1.0f; - ma->sss_radius[1] = 1.0f; - ma->sss_radius[2] = 1.0f; - ma->sss_col[0] = 1.0f; - ma->sss_col[1] = 1.0f; - ma->sss_col[2] = 1.0f; - ma->sss_error = 0.05f; - ma->sss_scale = 0.1f; - ma->sss_ior = 1.3f; - ma->sss_colfac = 1.0f; - ma->sss_texfac = 0.0f; - ma->sss_front = 1.0f; - ma->sss_back = 1.0f; - - ma->vol.density = 1.0f; - ma->vol.emission = 0.0f; - ma->vol.scattering = 1.0f; - ma->vol.reflection = 1.0f; - ma->vol.transmission_col[0] = ma->vol.transmission_col[1] = ma->vol.transmission_col[2] = 1.0f; - ma->vol.reflection_col[0] = ma->vol.reflection_col[1] = ma->vol.reflection_col[2] = 1.0f; - ma->vol.emission_col[0] = ma->vol.emission_col[1] = ma->vol.emission_col[2] = 1.0f; - ma->vol.density_scale = 1.0f; - ma->vol.depth_cutoff = 0.01f; - ma->vol.stepsize_type = MA_VOL_STEP_RANDOMIZED; - ma->vol.stepsize = 0.2f; - ma->vol.shade_type = MA_VOL_SHADE_SHADED; - ma->vol.shadeflag |= MA_VOL_PRECACHESHADING; - ma->vol.precache_resolution = 50; - ma->vol.ms_spread = 0.2f; - ma->vol.ms_diff = 1.f; - ma->vol.ms_intensity = 1.f; - - ma->mode = MA_TRACEBLE | MA_SHADBUF | MA_SHADOW | MA_RAYBIAS | MA_TANGENT_STR | MA_ZTRANSP; - ma->mode2 = MA_CASTSHADOW; - ma->shade_flag = MA_APPROX_OCCLUSION; ma->preview = NULL; ma->alpha_threshold = 0.5f; @@ -230,20 +147,6 @@ Material *BKE_material_add(Main *bmain, const char *name) */ void BKE_material_copy_data(Main *bmain, Material *ma_dst, const Material *ma_src, const int flag) { - for (int a = 0; a < MAX_MTEX; a++) { - if (ma_src->mtex[a]) { - ma_dst->mtex[a] = MEM_mallocN(sizeof(*ma_dst->mtex[a]), __func__); - *ma_dst->mtex[a] = *ma_src->mtex[a]; - } - } - - if (ma_src->ramp_col) { - ma_dst->ramp_col = MEM_dupallocN(ma_src->ramp_col); - } - if (ma_src->ramp_spec) { - ma_dst->ramp_spec = MEM_dupallocN(ma_src->ramp_spec); - } - if (ma_src->nodetree) { /* Note: nodetree is *not* in bmain, however this specific case is handled at lower level * (see BKE_libblock_copy_ex()). */ @@ -284,21 +187,9 @@ Material *BKE_material_localize(Material *ma) * ... Once f*** nodes are fully converted to that too :( */ Material *man; - int a; man = BKE_libblock_copy_nolib(&ma->id, false); - /* no increment for texture ID users, in previewrender.c it prevents decrement */ - for (a = 0; a < MAX_MTEX; a++) { - if (ma->mtex[a]) { - man->mtex[a] = MEM_mallocN(sizeof(MTex), "copymaterial"); - memcpy(man->mtex[a], ma->mtex[a], sizeof(MTex)); - } - } - - if (ma->ramp_col) man->ramp_col = MEM_dupallocN(ma->ramp_col); - if (ma->ramp_spec) man->ramp_spec = MEM_dupallocN(ma->ramp_spec); - man->texpaintslot = NULL; man->preview = NULL; @@ -941,221 +832,6 @@ bool BKE_object_material_slot_add(Object *ob) return true; } -static void do_init_render_material(Material *ma, int r_mode, float *amb) -{ - MTex *mtex; - int a, needuv = 0, needtang = 0; - - if (ma->flarec == 0) ma->flarec = 1; - - /* add all texcoflags from mtex, texco and mapto were cleared in advance */ - for (a = 0; a < MAX_MTEX; a++) { - - /* separate tex switching */ - if (ma->septex & (1 << a)) continue; - - mtex = ma->mtex[a]; - if (mtex && mtex->tex && (mtex->tex->type | (mtex->tex->use_nodes && mtex->tex->nodetree) )) { - - ma->texco |= mtex->texco; - ma->mapto |= mtex->mapto; - - /* always get derivatives for these textures */ - if (ELEM(mtex->tex->type, TEX_IMAGE, TEX_ENVMAP)) ma->texco |= TEXCO_OSA; - else if (mtex->texflag & (MTEX_COMPAT_BUMP | MTEX_3TAP_BUMP | MTEX_5TAP_BUMP | MTEX_BICUBIC_BUMP)) ma->texco |= TEXCO_OSA; - - if (ma->texco & (TEXCO_ORCO | TEXCO_REFL | TEXCO_NORM | TEXCO_STRAND | TEXCO_STRESS)) needuv = 1; - else if (ma->texco & (TEXCO_GLOB | TEXCO_UV | TEXCO_OBJECT | TEXCO_SPEED)) needuv = 1; - else if (ma->texco & (TEXCO_LAVECTOR | TEXCO_VIEW)) needuv = 1; - - if ((ma->mapto & MAP_NORM) && (mtex->normapspace == MTEX_NSPACE_TANGENT)) - needtang = 1; - } - } - - if (needtang) ma->mode |= MA_NORMAP_TANG; - else ma->mode &= ~MA_NORMAP_TANG; - - if (ma->mode & (MA_VERTEXCOL | MA_VERTEXCOLP)) { - needuv = 1; - if (r_mode & R_OSA) ma->texco |= TEXCO_OSA; /* for texfaces */ - } - if (needuv) ma->texco |= NEED_UV; - - /* since the raytracer doesnt recalc O structs for each ray, we have to preset them all */ - if (r_mode & R_RAYTRACE) { - if ((ma->mode & (MA_RAYMIRROR | MA_SHADOW_TRA)) || ((ma->mode & MA_TRANSP) && (ma->mode & MA_RAYTRANSP))) { - ma->texco |= NEED_UV | TEXCO_ORCO | TEXCO_REFL | TEXCO_NORM; - if (r_mode & R_OSA) ma->texco |= TEXCO_OSA; - } - } - - if (amb) { - ma->ambr = ma->amb * amb[0]; - ma->ambg = ma->amb * amb[1]; - ma->ambb = ma->amb * amb[2]; - } - - /* local group override */ - if ((ma->shade_flag & MA_GROUP_LOCAL) && ma->id.lib && ma->group && ma->group->id.lib) { - Group *group; - - for (group = G.main->group.first; group; group = group->id.next) { - if (!ID_IS_LINKED(group) && STREQ(group->id.name, ma->group->id.name)) { - ma->group = group; - } - } - } -} - -static void init_render_nodetree(bNodeTree *ntree, Material *basemat, int r_mode, float *amb) -{ - bNode *node; - - /* parses the geom+tex nodes */ - ntreeShaderGetTexcoMode(ntree, r_mode, &basemat->texco, &basemat->mode_l); - for (node = ntree->nodes.first; node; node = node->next) { - if (node->id) { - if (GS(node->id->name) == ID_MA) { - Material *ma = (Material *)node->id; - if (ma != basemat) { - do_init_render_material(ma, r_mode, amb); - basemat->texco |= ma->texco; - } - - basemat->mode_l |= ma->mode & ~(MA_MODE_PIPELINE | MA_SHLESS); - basemat->mode2_l |= ma->mode2 & ~MA_MODE2_PIPELINE; - /* basemat only considered shadeless if all node materials are too */ - if (!(ma->mode & MA_SHLESS)) - basemat->mode_l &= ~MA_SHLESS; - - if (ma->strand_surfnor > 0.0f) - basemat->mode_l |= MA_STR_SURFDIFF; - } - else if (node->type == NODE_GROUP) - init_render_nodetree((bNodeTree *)node->id, basemat, r_mode, amb); - } - else if (node->typeinfo->type == SH_NODE_NORMAL_MAP) { - basemat->mode2_l |= MA_TANGENT_CONCRETE; - NodeShaderNormalMap *nm = node->storage; - bool taken_into_account = false; - for (int i = 0; i < basemat->nmap_tangent_names_count; i++) { - if (STREQ(basemat->nmap_tangent_names[i], nm->uv_map)) { - taken_into_account = true; - break; - } - } - if (!taken_into_account) { - BLI_assert(basemat->nmap_tangent_names_count < MAX_MTFACE + 1); - strcpy(basemat->nmap_tangent_names[basemat->nmap_tangent_names_count++], nm->uv_map); - } - } - } -} - -void init_render_material(Material *mat, int r_mode, float *amb) -{ - - do_init_render_material(mat, r_mode, amb); - - if (mat->nodetree && mat->use_nodes) { - /* mode_l will take the pipeline options from the main material, and the or-ed - * result of non-pipeline options from the nodes. shadeless is an exception, - * mode_l will have it set when all node materials are shadeless. */ - mat->mode_l = (mat->mode & MA_MODE_PIPELINE) | MA_SHLESS; - mat->mode2_l = mat->mode2 & MA_MODE2_PIPELINE; - mat->nmap_tangent_names_count = 0; - init_render_nodetree(mat->nodetree, mat, r_mode, amb); - - if (!mat->nodetree->execdata) - mat->nodetree->execdata = ntreeShaderBeginExecTree(mat->nodetree); - } - else { - mat->mode_l = mat->mode; - mat->mode2_l = mat->mode2; - - if (mat->strand_surfnor > 0.0f) - mat->mode_l |= MA_STR_SURFDIFF; - } -} - -void init_render_materials(Main *bmain, int r_mode, float *amb, bool do_default_material) -{ - Material *ma; - - /* clear these flags before going over materials, to make sure they - * are cleared only once, otherwise node materials contained in other - * node materials can go wrong */ - for (ma = bmain->mat.first; ma; ma = ma->id.next) { - if (ma->id.us) { - ma->texco = 0; - ma->mapto = 0; - } - } - - /* two steps, first initialize, then or the flags for layers */ - for (ma = bmain->mat.first; ma; ma = ma->id.next) { - /* is_used flag comes back in convertblender.c */ - ma->flag &= ~MA_IS_USED; - if (ma->id.us) - init_render_material(ma, r_mode, amb); - } - - if (do_default_material) { - init_render_material(&defmaterial, r_mode, amb); - } -} - -/* only needed for nodes now */ -void end_render_material(Material *mat) -{ - if (mat && mat->nodetree && mat->use_nodes) { - if (mat->nodetree->execdata) - ntreeShaderEndExecTree(mat->nodetree->execdata); - } -} - -void end_render_materials(Main *bmain) -{ - Material *ma; - for (ma = bmain->mat.first; ma; ma = ma->id.next) - if (ma->id.us) - end_render_material(ma); -} - -static bool material_in_nodetree(bNodeTree *ntree, Material *mat) -{ - bNode *node; - - for (node = ntree->nodes.first; node; node = node->next) { - if (node->id) { - if (GS(node->id->name) == ID_MA) { - if (node->id == (ID *)mat) { - return true; - } - } - else if (node->type == NODE_GROUP) { - if (material_in_nodetree((bNodeTree *)node->id, mat)) { - return true; - } - } - } - } - - return false; -} - -bool material_in_material(Material *parmat, Material *mat) -{ - if (parmat == mat) - return true; - else if (parmat->nodetree && parmat->use_nodes) - return material_in_nodetree(parmat->nodetree, mat); - else - return false; -} - - /* ****************** */ bool BKE_object_material_slot_remove(Object *ob) @@ -1247,13 +923,6 @@ bool BKE_object_material_slot_remove(Object *ob) return true; } -static bool get_mtex_slot_valid_texpaint(struct MTex *mtex) -{ - return (mtex && (mtex->texco == TEXCO_UV) && - mtex->tex && (mtex->tex->type == TEX_IMAGE) && - mtex->tex->ima); -} - static bNode *nodetree_uv_node_recursive(bNode *node) { bNode *inode; @@ -1276,21 +945,9 @@ static bNode *nodetree_uv_node_recursive(bNode *node) void BKE_texpaint_slot_refresh_cache(Scene *scene, Material *ma) { - MTex **mtex; short count = 0; - short index = 0, i; - - bool use_nodes = BKE_scene_use_new_shading_nodes(scene); - bool is_bi = BKE_scene_uses_blender_internal(scene); + short index = 0; - /* XXX, for 2.8 testing & development its useful to have non Cycles/BI engines use material nodes - * In the future we may have some way to check this which each engine can define. - * For now use material slots for Clay/Eevee. - * - Campbell */ - if (!(use_nodes || is_bi)) { - is_bi = true; - } - if (!ma) return; @@ -1306,88 +963,50 @@ void BKE_texpaint_slot_refresh_cache(Scene *scene, Material *ma) return; } - if (use_nodes || ma->use_nodes) { - bNode *node, *active_node; + bNode *node, *active_node; - if (!(ma->nodetree)) { - ma->paint_active_slot = 0; - ma->paint_clone_slot = 0; - return; - } - - for (node = ma->nodetree->nodes.first; node; node = node->next) { - if (node->typeinfo->nclass == NODE_CLASS_TEXTURE && node->typeinfo->type == SH_NODE_TEX_IMAGE && node->id) - count++; - } + if (!(ma->nodetree)) { + ma->paint_active_slot = 0; + ma->paint_clone_slot = 0; + return; + } - if (count == 0) { - ma->paint_active_slot = 0; - ma->paint_clone_slot = 0; - return; - } - ma->texpaintslot = MEM_callocN(sizeof(*ma->texpaintslot) * count, "texpaint_slots"); - - active_node = nodeGetActiveTexture(ma->nodetree); - - for (node = ma->nodetree->nodes.first; node; node = node->next) { - if (node->typeinfo->nclass == NODE_CLASS_TEXTURE && node->typeinfo->type == SH_NODE_TEX_IMAGE && node->id) { - if (active_node == node) - ma->paint_active_slot = index; - ma->texpaintslot[index].ima = (Image *)node->id; - - /* for new renderer, we need to traverse the treeback in search of a UV node */ - if (use_nodes) { - bNode *uvnode = nodetree_uv_node_recursive(node); - - if (uvnode) { - NodeShaderUVMap *storage = (NodeShaderUVMap *)uvnode->storage; - ma->texpaintslot[index].uvname = storage->uv_map; - /* set a value to index so UI knows that we have a valid pointer for the mesh */ - ma->texpaintslot[index].index = 0; - } - else { - /* just invalidate the index here so UV map does not get displayed on the UI */ - ma->texpaintslot[index].index = -1; - } - } - else { - ma->texpaintslot[index].index = -1; - } - index++; - } - } + for (node = ma->nodetree->nodes.first; node; node = node->next) { + if (node->typeinfo->nclass == NODE_CLASS_TEXTURE && node->typeinfo->type == SH_NODE_TEX_IMAGE && node->id) + count++; } - else if (is_bi) { - for (mtex = ma->mtex, i = 0; i < MAX_MTEX; i++, mtex++) { - if (get_mtex_slot_valid_texpaint(*mtex)) { - count++; - } - } - if (count == 0) { - ma->paint_active_slot = 0; - ma->paint_clone_slot = 0; - return; - } + if (count == 0) { + ma->paint_active_slot = 0; + ma->paint_clone_slot = 0; + return; + } + ma->texpaintslot = MEM_callocN(sizeof(*ma->texpaintslot) * count, "texpaint_slots"); - ma->texpaintslot = MEM_callocN(sizeof(*ma->texpaintslot) * count, "texpaint_slots"); + active_node = nodeGetActiveTexture(ma->nodetree); - for (mtex = ma->mtex, i = 0; i < MAX_MTEX; i++, mtex++) { - if (get_mtex_slot_valid_texpaint(*mtex)) { - ma->texpaintslot[index].ima = (*mtex)->tex->ima; - ma->texpaintslot[index].uvname = (*mtex)->uvname; - ma->texpaintslot[index].index = i; - - index++; + for (node = ma->nodetree->nodes.first; node; node = node->next) { + if (node->typeinfo->nclass == NODE_CLASS_TEXTURE && node->typeinfo->type == SH_NODE_TEX_IMAGE && node->id) { + if (active_node == node) + ma->paint_active_slot = index; + ma->texpaintslot[index].ima = (Image *)node->id; + + /* for new renderer, we need to traverse the treeback in search of a UV node */ + bNode *uvnode = nodetree_uv_node_recursive(node); + + if (uvnode) { + NodeShaderUVMap *storage = (NodeShaderUVMap *)uvnode->storage; + ma->texpaintslot[index].uvname = storage->uv_map; + /* set a value to index so UI knows that we have a valid pointer for the mesh */ + ma->texpaintslot[index].valid = true; + } + else { + /* just invalidate the index here so UV map does not get displayed on the UI */ + ma->texpaintslot[index].valid = false; } + index++; } } - else { - ma->paint_active_slot = 0; - ma->paint_clone_slot = 0; - return; - } - ma->tot_slots = count; @@ -1643,21 +1262,6 @@ void clear_matcopybuf(void) void free_matcopybuf(void) { - int a; - - for (a = 0; a < MAX_MTEX; a++) { - if (matcopybuf.mtex[a]) { - MEM_freeN(matcopybuf.mtex[a]); - matcopybuf.mtex[a] = NULL; - } - } - - if (matcopybuf.ramp_col) MEM_freeN(matcopybuf.ramp_col); - if (matcopybuf.ramp_spec) MEM_freeN(matcopybuf.ramp_spec); - - matcopybuf.ramp_col = NULL; - matcopybuf.ramp_spec = NULL; - if (matcopybuf.nodetree) { ntreeFreeTree(matcopybuf.nodetree); MEM_freeN(matcopybuf.nodetree); @@ -1669,22 +1273,11 @@ void free_matcopybuf(void) void copy_matcopybuf(Material *ma) { - int a; - MTex *mtex; - if (matcopied) free_matcopybuf(); memcpy(&matcopybuf, ma, sizeof(Material)); - if (matcopybuf.ramp_col) matcopybuf.ramp_col = MEM_dupallocN(matcopybuf.ramp_col); - if (matcopybuf.ramp_spec) matcopybuf.ramp_spec = MEM_dupallocN(matcopybuf.ramp_spec); - for (a = 0; a < MAX_MTEX; a++) { - mtex = matcopybuf.mtex[a]; - if (mtex) { - matcopybuf.mtex[a] = MEM_dupallocN(mtex); - } - } matcopybuf.nodetree = ntreeCopyTree_ex(ma->nodetree, G.main, false); matcopybuf.preview = NULL; BLI_listbase_clear(&matcopybuf.gpumaterial); @@ -1694,22 +1287,10 @@ void copy_matcopybuf(Material *ma) void paste_matcopybuf(Material *ma) { - int a; - MTex *mtex; ID id; if (matcopied == 0) return; - /* free current mat */ - if (ma->ramp_col) MEM_freeN(ma->ramp_col); - if (ma->ramp_spec) MEM_freeN(ma->ramp_spec); - for (a = 0; a < MAX_MTEX; a++) { - mtex = ma->mtex[a]; - if (mtex && mtex->tex) - id_us_min(&mtex->tex->id); - if (mtex) - MEM_freeN(mtex); - } /* Free gpu material before the ntree */ GPU_material_free(&ma->gpumaterial); @@ -1723,56 +1304,9 @@ void paste_matcopybuf(Material *ma) memcpy(ma, &matcopybuf, sizeof(Material)); (ma->id) = id; - if (matcopybuf.ramp_col) ma->ramp_col = MEM_dupallocN(matcopybuf.ramp_col); - if (matcopybuf.ramp_spec) ma->ramp_spec = MEM_dupallocN(matcopybuf.ramp_spec); - - for (a = 0; a < MAX_MTEX; a++) { - mtex = ma->mtex[a]; - if (mtex) { - ma->mtex[a] = MEM_dupallocN(mtex); - if (mtex->tex) { - /* first check this is in main (we may have loaded another file) [#35500] */ - if (BLI_findindex(&G.main->tex, mtex->tex) != -1) { - id_us_plus((ID *)mtex->tex); - } - else { - ma->mtex[a]->tex = NULL; - } - } - } - } - ma->nodetree = ntreeCopyTree_ex(matcopybuf.nodetree, G.main, false); } -struct Image *BKE_object_material_edit_image_get(Object *ob, short mat_nr) -{ - Material *ma = give_current_material(ob, mat_nr + 1); - return ma ? ma->edit_image : NULL; -} - -struct Image **BKE_object_material_edit_image_get_array(Object *ob) -{ - Image **image_array = MEM_mallocN(sizeof(Material *) * ob->totcol, __func__); - for (int i = 0; i < ob->totcol; i++) { - image_array[i] = BKE_object_material_edit_image_get(ob, i); - } - return image_array; -} - -bool BKE_object_material_edit_image_set(Object *ob, short mat_nr, Image *image) -{ - Material *ma = give_current_material(ob, mat_nr + 1); - if (ma) { - /* both may be NULL */ - id_us_min((ID *)ma->edit_image); - ma->edit_image = image; - id_us_plus((ID *)ma->edit_image); - return true; - } - return false; -} - void BKE_material_eval(struct Depsgraph *UNUSED(depsgraph), Material *material) { DEG_debug_print_eval(__func__, material->id.name, material); diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 845880fb60d..def8ea1d239 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -3120,77 +3120,6 @@ void nodeUpdateInternalLinks(bNodeTree *ntree, bNode *node) } -/* nodes that use ID data get synced with local data */ -void nodeSynchronizeID(bNode *node, bool copy_to_id) -{ - if (node->id == NULL) return; - - if (ELEM(node->type, SH_NODE_MATERIAL, SH_NODE_MATERIAL_EXT)) { - bNodeSocket *sock; - Material *ma = (Material *)node->id; - int a; - short check_flags = SOCK_UNAVAIL; - - if (!copy_to_id) - check_flags |= SOCK_HIDDEN; - - /* hrmf, case in loop isn't super fast, but we don't edit 100s of material at same time either! */ - for (a = 0, sock = node->inputs.first; sock; sock = sock->next, a++) { - if (!(sock->flag & check_flags)) { - if (copy_to_id) { - switch (a) { - case MAT_IN_COLOR: - copy_v3_v3(&ma->r, ((bNodeSocketValueRGBA *)sock->default_value)->value); break; - case MAT_IN_SPEC: - copy_v3_v3(&ma->specr, ((bNodeSocketValueRGBA *)sock->default_value)->value); break; - case MAT_IN_REFL: - ma->ref = ((bNodeSocketValueFloat *)sock->default_value)->value; break; - case MAT_IN_MIR: - copy_v3_v3(&ma->mirr, ((bNodeSocketValueRGBA *)sock->default_value)->value); break; - case MAT_IN_AMB: - ma->amb = ((bNodeSocketValueFloat *)sock->default_value)->value; break; - case MAT_IN_EMIT: - ma->emit = ((bNodeSocketValueFloat *)sock->default_value)->value; break; - case MAT_IN_SPECTRA: - ma->spectra = ((bNodeSocketValueFloat *)sock->default_value)->value; break; - case MAT_IN_RAY_MIRROR: - ma->ray_mirror = ((bNodeSocketValueFloat *)sock->default_value)->value; break; - case MAT_IN_ALPHA: - ma->alpha = ((bNodeSocketValueFloat *)sock->default_value)->value; break; - case MAT_IN_TRANSLUCENCY: - ma->translucency = ((bNodeSocketValueFloat *)sock->default_value)->value; break; - } - } - else { - switch (a) { - case MAT_IN_COLOR: - copy_v3_v3(((bNodeSocketValueRGBA *)sock->default_value)->value, &ma->r); break; - case MAT_IN_SPEC: - copy_v3_v3(((bNodeSocketValueRGBA *)sock->default_value)->value, &ma->specr); break; - case MAT_IN_REFL: - ((bNodeSocketValueFloat *)sock->default_value)->value = ma->ref; break; - case MAT_IN_MIR: - copy_v3_v3(((bNodeSocketValueRGBA *)sock->default_value)->value, &ma->mirr); break; - case MAT_IN_AMB: - ((bNodeSocketValueFloat *)sock->default_value)->value = ma->amb; break; - case MAT_IN_EMIT: - ((bNodeSocketValueFloat *)sock->default_value)->value = ma->emit; break; - case MAT_IN_SPECTRA: - ((bNodeSocketValueFloat *)sock->default_value)->value = ma->spectra; break; - case MAT_IN_RAY_MIRROR: - ((bNodeSocketValueFloat *)sock->default_value)->value = ma->ray_mirror; break; - case MAT_IN_ALPHA: - ((bNodeSocketValueFloat *)sock->default_value)->value = ma->alpha; break; - case MAT_IN_TRANSLUCENCY: - ((bNodeSocketValueFloat *)sock->default_value)->value = ma->translucency; break; - } - } - } - } - } -} - - /* ************* node type access ********** */ void nodeLabel(bNodeTree *ntree, bNode *node, char *label, int maxlen) @@ -3555,10 +3484,7 @@ static void registerShaderNodes(void) { register_node_type_sh_group(); - register_node_type_sh_output(); - register_node_type_sh_material(); register_node_type_sh_camera(); - register_node_type_sh_lamp(); register_node_type_sh_gamma(); register_node_type_sh_brightcontrast(); register_node_type_sh_value(); @@ -3569,9 +3495,7 @@ static void registerShaderNodes(void) register_node_type_sh_mix_rgb(); register_node_type_sh_valtorgb(); register_node_type_sh_rgbtobw(); - register_node_type_sh_texture(); register_node_type_sh_normal(); - register_node_type_sh_geom(); register_node_type_sh_mapping(); register_node_type_sh_curve_vec(); register_node_type_sh_curve_rgb(); @@ -3579,7 +3503,6 @@ static void registerShaderNodes(void) register_node_type_sh_vect_math(); register_node_type_sh_vect_transform(); register_node_type_sh_squeeze(); - register_node_type_sh_material_ext(); register_node_type_sh_invert(); register_node_type_sh_seprgb(); register_node_type_sh_combrgb(); diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 53ca20e3c2a..1798515658d 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -132,8 +132,6 @@ #include "CCGSubSurf.h" #include "atomic_ops.h" -#include "GPU_lamp.h" - /* Vertex parent modifies original BMesh which is not safe for threading. * Ideally such a modification should be handled as a separate DAG update * callback for mesh datablock, but for until it is actually supported use @@ -435,7 +433,6 @@ void BKE_object_free(Object *ob) sbFree(ob->soft); ob->soft = NULL; } - GPU_lamp_free(ob); for (ObjectEngineData *oed = ob->drawdata.first; oed; oed = oed->next) { if (oed->free != NULL) { diff --git a/source/blender/blenkernel/intern/object_dupli.c b/source/blender/blenkernel/intern/object_dupli.c index 35f86cd0c81..eafd2d95cf1 100644 --- a/source/blender/blenkernel/intern/object_dupli.c +++ b/source/blender/blenkernel/intern/object_dupli.c @@ -858,7 +858,6 @@ static void make_duplis_particle_system(const DupliContext *ctx, ParticleSystem float (*obmat)[4]; int a, b, hair = 0; int totpart, totchild, totgroup = 0 /*, pa_num */; - const bool dupli_type_hack = !BKE_scene_use_new_shading_nodes(scene); int no_draw_flag = PARS_UNEXIST; @@ -1132,10 +1131,6 @@ static void make_duplis_particle_system(const DupliContext *ctx, ParticleSystem dob->particle_system = psys; if (use_texcoords) psys_get_dupli_texture(psys, part, sim.psmd, pa, cpa, dob->uv, dob->orco); - /* XXX blender internal needs this to be set to dupligroup to render - * groups correctly, but we don't want this hack for cycles */ - if (dupli_type_hack && ctx->group) - dob->type = OB_DUPLIGROUP; } } diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 07c8735f108..ae6028c742a 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -1031,7 +1031,7 @@ static void interpolate_pathcache(ParticleCacheKey *first, float t, ParticleCach /* interpolate a location on a face based on face coordinates */ void psys_interpolate_face(MVert *mvert, MFace *mface, MTFace *tface, float (*orcodata)[3], float w[4], float vec[3], float nor[3], float utan[3], float vtan[3], - float orco[3], float ornor[3]) + float orco[3]) { float *v1 = 0, *v2 = 0, *v3 = 0, *v4 = 0; float e1[3], e2[3], s1, s2, t1, t2; @@ -1129,21 +1129,13 @@ void psys_interpolate_face(MVert *mvert, MFace *mface, MTFace *tface, float (*or o4 = orcodata[mface->v4]; interp_v3_v3v3v3v3(orco, o1, o2, o3, o4, w); - - if (ornor) - normal_quad_v3(ornor, o1, o2, o3, o4); } else { interp_v3_v3v3v3(orco, o1, o2, o3, w); - - if (ornor) - normal_tri_v3(ornor, o1, o2, o3); } } else { copy_v3_v3(orco, vec); - if (ornor && nor) - copy_v3_v3(ornor, nor); } } } @@ -1423,7 +1415,7 @@ static int psys_map_index_on_dm(DerivedMesh *dm, int from, int index, int index_ /* interprets particle data to get a point on a mesh in object space */ void psys_particle_on_dm(DerivedMesh *dm_final, int from, int index, int index_dmcache, const float fw[4], float foffset, float vec[3], float nor[3], float utan[3], float vtan[3], - float orco[3], float ornor[3]) + float orco[3]) { float tmpnor[3], mapfw[4]; float (*orcodata)[3]; @@ -1433,7 +1425,6 @@ void psys_particle_on_dm(DerivedMesh *dm_final, int from, int index, int index_d if (vec) { vec[0] = vec[1] = vec[2] = 0.0; } if (nor) { nor[0] = nor[1] = 0.0; nor[2] = 1.0; } if (orco) { orco[0] = orco[1] = orco[2] = 0.0; } - if (ornor) { ornor[0] = ornor[1] = 0.0; ornor[2] = 1.0; } if (utan) { utan[0] = utan[1] = utan[2] = 0.0; } if (vtan) { vtan[0] = vtan[1] = vtan[2] = 0.0; } @@ -1459,11 +1450,6 @@ void psys_particle_on_dm(DerivedMesh *dm_final, int from, int index, int index_d } } - if (ornor) { - dm_final->getVertNo(dm_final, mapindex, ornor); - normalize_v3(ornor); - } - if (utan && vtan) { utan[0] = utan[1] = utan[2] = 0.0f; vtan[0] = vtan[1] = vtan[2] = 0.0f; @@ -1482,7 +1468,7 @@ void psys_particle_on_dm(DerivedMesh *dm_final, int from, int index, int index_d mtface += mapindex; if (from == PART_FROM_VOLUME) { - psys_interpolate_face(mvert, mface, mtface, orcodata, mapfw, vec, tmpnor, utan, vtan, orco, ornor); + psys_interpolate_face(mvert, mface, mtface, orcodata, mapfw, vec, tmpnor, utan, vtan, orco); if (nor) copy_v3_v3(nor, tmpnor); @@ -1491,7 +1477,7 @@ void psys_particle_on_dm(DerivedMesh *dm_final, int from, int index, int index_d add_v3_v3(vec, tmpnor); } else - psys_interpolate_face(mvert, mface, mtface, orcodata, mapfw, vec, nor, utan, vtan, orco, ornor); + psys_interpolate_face(mvert, mface, mtface, orcodata, mapfw, vec, nor, utan, vtan, orco); } } @@ -1527,7 +1513,7 @@ ParticleSystemModifierData *psys_get_modifier(Object *ob, ParticleSystem *psys) /* ready for future use */ static void psys_particle_on_shape(int UNUSED(distr), int UNUSED(index), float *UNUSED(fuv), float vec[3], float nor[3], float utan[3], float vtan[3], - float orco[3], float ornor[3]) + float orco[3]) { /* TODO */ float zerovec[3] = {0.0f, 0.0f, 0.0f}; @@ -1546,9 +1532,6 @@ static void psys_particle_on_shape(int UNUSED(distr), int UNUSED(index), if (orco) { copy_v3_v3(orco, zerovec); } - if (ornor) { - copy_v3_v3(ornor, zerovec); - } } /************************************************/ /* Particles on emitter */ @@ -1591,7 +1574,7 @@ CustomDataMask psys_emitter_customdata_mask(ParticleSystem *psys) void psys_particle_on_emitter(ParticleSystemModifierData *psmd, int from, int index, int index_dmcache, float fuv[4], float foffset, float vec[3], float nor[3], float utan[3], float vtan[3], - float orco[3], float ornor[3]) + float orco[3]) { if (psmd && psmd->dm_final) { if (psmd->psys->part->distr == PART_DISTR_GRID && psmd->psys->part->from != PART_FROM_VERT) { @@ -1603,10 +1586,10 @@ void psys_particle_on_emitter(ParticleSystemModifierData *psmd, int from, int in return; } /* we cant use the num_dmcache */ - psys_particle_on_dm(psmd->dm_final, from, index, index_dmcache, fuv, foffset, vec, nor, utan, vtan, orco, ornor); + psys_particle_on_dm(psmd->dm_final, from, index, index_dmcache, fuv, foffset, vec, nor, utan, vtan, orco); } else - psys_particle_on_shape(from, index, fuv, vec, nor, utan, vtan, orco, ornor); + psys_particle_on_shape(from, index, fuv, vec, nor, utan, vtan, orco); } /************************************************/ @@ -1628,7 +1611,7 @@ void precalc_guides(ParticleSimulationData *sim, ListBase *effectors) return; LOOP_PARTICLES { - psys_particle_on_emitter(sim->psmd, sim->psys->part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, state.co, 0, 0, 0, 0, 0); + psys_particle_on_emitter(sim->psmd, sim->psys->part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, state.co, 0, 0, 0, 0); mul_m4_v3(sim->ob->obmat, state.co); mul_mat3_m4_v3(sim->ob->obmat, state.vel); @@ -1867,7 +1850,7 @@ void psys_find_parents(ParticleSimulationData *sim, const bool use_render_params tree = BLI_kdtree_new(totparent); for (p = 0, cpa = sim->psys->child; p < totparent; p++, cpa++) { - psys_particle_on_emitter(sim->psmd, from, cpa->num, DMCACHE_ISCHILD, cpa->fuv, cpa->foffset, co, 0, 0, 0, orco, 0); + psys_particle_on_emitter(sim->psmd, from, cpa->num, DMCACHE_ISCHILD, cpa->fuv, cpa->foffset, co, 0, 0, 0, orco); /* Check if particle doesn't exist because of texture influence. Insert only existing particles into kdtree. */ get_cpa_texture(sim->psmd->dm_final, psys, part, psys->particles + cpa->pa[0], p, cpa->num, cpa->fuv, orco, &ptex, PAMAP_DENS | PAMAP_CHILD, psys->cfra); @@ -1880,7 +1863,7 @@ void psys_find_parents(ParticleSimulationData *sim, const bool use_render_params BLI_kdtree_balance(tree); for (; p < totchild; p++, cpa++) { - psys_particle_on_emitter(sim->psmd, from, cpa->num, DMCACHE_ISCHILD, cpa->fuv, cpa->foffset, co, 0, 0, 0, orco, 0); + psys_particle_on_emitter(sim->psmd, from, cpa->num, DMCACHE_ISCHILD, cpa->fuv, cpa->foffset, co, 0, 0, 0, orco); cpa->parent = BLI_kdtree_find_nearest(tree, orco, NULL); } @@ -2001,7 +1984,7 @@ static void psys_thread_create_path(ParticleTask *task, struct ChildParticle *cp ParticleCacheKey *child, *key[4]; ParticleTexture ptex; float *cpa_fuv = 0, *par_rot = 0, rot[4]; - float orco[3], ornor[3], hairmat[4][4], dvec[3], off1[4][3], off2[4][3]; + float orco[3], hairmat[4][4], dvec[3], off1[4][3], off2[4][3]; float eff_length, eff_vec[3], weight[4]; int k, cpa_num; short cpa_from; @@ -2097,7 +2080,7 @@ static void psys_thread_create_path(ParticleTask *task, struct ChildParticle *cp cpa_fuv = cpa->fuv; cpa_from = PART_FROM_FACE; - psys_particle_on_emitter(ctx->sim.psmd, cpa_from, cpa_num, DMCACHE_ISCHILD, cpa->fuv, foffset, co, ornor, 0, 0, orco, 0); + psys_particle_on_emitter(ctx->sim.psmd, cpa_from, cpa_num, DMCACHE_ISCHILD, cpa->fuv, foffset, co, 0, 0, orco, 0); mul_m4_v3(ob->obmat, co); @@ -2139,7 +2122,7 @@ static void psys_thread_create_path(ParticleTask *task, struct ChildParticle *cp cpa_num = 0; cpa_fuv = pa->fuv; - psys_particle_on_emitter(ctx->sim.psmd, cpa_from, cpa_num, DMCACHE_ISCHILD, cpa_fuv, pa->foffset, co, ornor, 0, 0, orco, 0); + psys_particle_on_emitter(ctx->sim.psmd, cpa_from, cpa_num, DMCACHE_ISCHILD, cpa_fuv, pa->foffset, co, 0, 0, orco, 0); psys_mat_hair_to_global(ob, ctx->sim.psmd->dm_final, psys->part->from, pa, hairmat); } @@ -2247,9 +2230,9 @@ static void psys_thread_create_path(ParticleTask *task, struct ChildParticle *cp BLI_listbase_clear(&modifiers); psys_particle_on_emitter(ctx->sim.psmd, part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, - par_co, NULL, NULL, NULL, par_orco, NULL); + par_co, NULL, NULL, NULL, par_orco); - psys_apply_child_modifiers(ctx, &modifiers, cpa, &ptex, orco, ornor, hairmat, child_keys, par, par_orco); + psys_apply_child_modifiers(ctx, &modifiers, cpa, &ptex, orco, hairmat, child_keys, par, par_orco); } else zero_v3(par_orco); @@ -2928,7 +2911,7 @@ void psys_mat_hair_to_object(Object *UNUSED(ob), DerivedMesh *dm, short from, Pa } psys_face_mat(0, dm, pa, hairmat, 0); - psys_particle_on_dm(dm, from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, vec, 0, 0, 0, 0, 0); + psys_particle_on_dm(dm, from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, vec, 0, 0, 0, 0); copy_v3_v3(hairmat[3], vec); } @@ -2937,7 +2920,7 @@ void psys_mat_hair_to_orco(Object *ob, DerivedMesh *dm, short from, ParticleData float vec[3], orco[3]; psys_face_mat(ob, dm, pa, hairmat, 1); - psys_particle_on_dm(dm, from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, vec, 0, 0, 0, orco, 0); + psys_particle_on_dm(dm, from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, vec, 0, 0, 0, orco); /* see psys_face_mat for why this function is called */ if (DM_get_vert_data_layer(dm, CD_ORIGINDEX)) @@ -3442,7 +3425,7 @@ void psys_get_texture(ParticleSimulationData *sim, ParticleData *pa, ParticleTex /* no break, failed to get uv's, so let's try orco's */ ATTR_FALLTHROUGH; case TEXCO_ORCO: - psys_particle_on_emitter(sim->psmd, sim->psys->part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, co, 0, 0, 0, texvec, 0); + psys_particle_on_emitter(sim->psmd, sim->psys->part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, co, 0, 0, 0, texvec); if (me->bb == NULL || (me->bb->flag & BOUNDBOX_DIRTY)) { BKE_mesh_texspace_calc(me); @@ -3704,7 +3687,7 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, int p, ParticleKey * cpa_fuv = cpa->fuv; cpa_from = PART_FROM_FACE; - psys_particle_on_emitter(psmd, cpa_from, cpa_num, DMCACHE_ISCHILD, cpa->fuv, foffset, co, 0, 0, 0, orco, 0); + psys_particle_on_emitter(psmd, cpa_from, cpa_num, DMCACHE_ISCHILD, cpa->fuv, foffset, co, 0, 0, 0, orco); /* we need to save the actual root position of the child for positioning it accurately to the surface of the emitter */ //copy_v3_v3(cpa_1st, co); @@ -3713,7 +3696,7 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, int p, ParticleKey * pa = psys->particles + cpa->parent; - psys_particle_on_emitter(psmd, part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, par_co, 0, 0, 0, par_orco, 0); + psys_particle_on_emitter(psmd, part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, par_co, 0, 0, 0, par_orco); if (part->type == PART_HAIR) psys_mat_hair_to_global(sim->ob, sim->psmd->dm_final, psys->part->from, pa, hairmat); else @@ -3733,9 +3716,9 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, int p, ParticleKey * cpa_num = pa->num; cpa_fuv = pa->fuv; - psys_particle_on_emitter(psmd, part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, par_co, 0, 0, 0, par_orco, 0); + psys_particle_on_emitter(psmd, part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, par_co, 0, 0, 0, par_orco); if (part->type == PART_HAIR) { - psys_particle_on_emitter(psmd, cpa_from, cpa_num, DMCACHE_ISCHILD, cpa_fuv, pa->foffset, co, 0, 0, 0, orco, 0); + psys_particle_on_emitter(psmd, cpa_from, cpa_num, DMCACHE_ISCHILD, cpa_fuv, pa->foffset, co, 0, 0, 0, orco); psys_mat_hair_to_global(sim->ob, sim->psmd->dm_final, psys->part->from, pa, hairmat); } else { @@ -4020,7 +4003,7 @@ void psys_get_dupli_texture(ParticleSystem *psys, ParticleSettings *part, psys_interpolate_uvs(mtface, mface->v4, cpa->fuv, uv); } - psys_particle_on_emitter(psmd, PART_FROM_FACE, cpa->num, DMCACHE_ISCHILD, cpa->fuv, cpa->foffset, loc, 0, 0, 0, orco, 0); + psys_particle_on_emitter(psmd, PART_FROM_FACE, cpa->num, DMCACHE_ISCHILD, cpa->fuv, cpa->foffset, loc, 0, 0, 0, orco); return; } else { @@ -4051,7 +4034,7 @@ void psys_get_dupli_texture(ParticleSystem *psys, ParticleSettings *part, } } - psys_particle_on_emitter(psmd, part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, loc, 0, 0, 0, orco, 0); + psys_particle_on_emitter(psmd, part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, loc, 0, 0, 0, orco); } void psys_get_dupli_path_transform(ParticleSimulationData *sim, ParticleData *pa, ChildParticle *cpa, ParticleCacheKey *cache, float mat[4][4], float *scale) @@ -4069,9 +4052,9 @@ void psys_get_dupli_path_transform(ParticleSimulationData *sim, ParticleData *pa pa = psys->particles + cpa->pa[0]; if (pa) - psys_particle_on_emitter(psmd, sim->psys->part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, loc, nor, 0, 0, 0, 0); + psys_particle_on_emitter(psmd, sim->psys->part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, loc, nor, 0, 0, 0); else - psys_particle_on_emitter(psmd, PART_FROM_FACE, cpa->num, DMCACHE_ISCHILD, cpa->fuv, cpa->foffset, loc, nor, 0, 0, 0, 0); + psys_particle_on_emitter(psmd, PART_FROM_FACE, cpa->num, DMCACHE_ISCHILD, cpa->fuv, cpa->foffset, loc, nor, 0, 0, 0); if (psys->part->rotmode == PART_ROT_VEL) { transpose_m3_m4(nmat, ob->imat); diff --git a/source/blender/blenkernel/intern/particle_child.c b/source/blender/blenkernel/intern/particle_child.c index 8d42f2a9b84..7cfad93224d 100644 --- a/source/blender/blenkernel/intern/particle_child.c +++ b/source/blender/blenkernel/intern/particle_child.c @@ -39,40 +39,6 @@ #include "particle_private.h" -struct Material; - -static void get_strand_normal(Material *ma, const float surfnor[3], float surfdist, float nor[3]) -{ - float cross[3], nstrand[3], vnor[3], blend; - - if (!((ma->mode & MA_STR_SURFDIFF) || (ma->strand_surfnor > 0.0f))) - return; - - if (ma->mode & MA_STR_SURFDIFF) { - cross_v3_v3v3(cross, surfnor, nor); - cross_v3_v3v3(nstrand, nor, cross); - - blend = dot_v3v3(nstrand, surfnor); - CLAMP(blend, 0.0f, 1.0f); - - interp_v3_v3v3(vnor, nstrand, surfnor, blend); - normalize_v3(vnor); - } - else { - copy_v3_v3(vnor, nor); - } - - if (ma->strand_surfnor > 0.0f) { - if (ma->strand_surfnor > surfdist) { - blend = (ma->strand_surfnor - surfdist) / ma->strand_surfnor; - interp_v3_v3v3(vnor, vnor, surfnor, blend); - normalize_v3(vnor); - } - } - - copy_v3_v3(nor, vnor); -} - /* ------------------------------------------------------------------------- */ typedef struct ParticlePathIterator { @@ -320,7 +286,7 @@ static bool check_path_length(int k, ParticleCacheKey *keys, ParticleCacheKey *k } void psys_apply_child_modifiers(ParticleThreadContext *ctx, struct ListBase *modifiers, - ChildParticle *cpa, ParticleTexture *ptex, const float orco[3], const float ornor[3], float hairmat[4][4], + ChildParticle *cpa, ParticleTexture *ptex, const float orco[3], float hairmat[4][4], ParticleCacheKey *keys, ParticleCacheKey *parent_keys, const float parent_orco[3]) { struct ParticleSettings *part = ctx->sim.psys->part; @@ -389,9 +355,6 @@ void psys_apply_child_modifiers(ParticleThreadContext *ctx, struct ListBase *mod if (k >= 2) { sub_v3_v3v3((key-1)->vel, key->co, (key-2)->co); mul_v3_fl((key-1)->vel, 0.5); - - if (ma && draw_col_ma) - get_strand_normal(ma, ornor, cur_length, (key-1)->vel); } if (use_length_check && k > 0) { @@ -413,7 +376,6 @@ void psys_apply_child_modifiers(ParticleThreadContext *ctx, struct ListBase *mod if (ma && draw_col_ma) { copy_v3_v3(key->col, &ma->r); - get_strand_normal(ma, ornor, cur_length, key->vel); } } } diff --git a/source/blender/blenkernel/intern/particle_distribute.c b/source/blender/blenkernel/intern/particle_distribute.c index 87fa86977e6..bf21e18f4b9 100644 --- a/source/blender/blenkernel/intern/particle_distribute.c +++ b/source/blender/blenkernel/intern/particle_distribute.c @@ -574,7 +574,7 @@ static void distribute_from_volume_exec(ParticleTask *thread, ParticleData *pa, /* experimental */ tot=dm->getNumTessFaces(dm); - psys_interpolate_face(mvert,mface,0,0,pa->fuv,co,nor,0,0,0,0); + psys_interpolate_face(mvert,mface,0,0,pa->fuv,co,nor,0,0,0); normalize_v3(nor); negate_v3(nor); @@ -661,7 +661,7 @@ static void distribute_children_exec(ParticleTask *thread, ChildParticle *cpa, i int parent[10]; float pweight[10]; - psys_particle_on_dm(dm,cfrom,cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,co1,nor1,NULL,NULL,orco1,NULL); + psys_particle_on_dm(dm,cfrom,cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,co1,nor1,NULL,NULL,orco1); BKE_mesh_orco_verts_transform((Mesh*)ob->data, &orco1, 1, 1); maxw = BLI_kdtree_find_nearest_n(ctx->tree,orco1,ptn,3); @@ -890,7 +890,7 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, Parti tree=BLI_kdtree_new(totpart); for (p=0,pa=psys->particles; p<totpart; p++,pa++) { - psys_particle_on_dm(dm,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,nor,0,0,orco,NULL); + psys_particle_on_dm(dm,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,nor,0,0,orco); BKE_mesh_orco_verts_transform((Mesh*)ob->data, &orco, 1, 1); BLI_kdtree_insert(tree, p, orco); } diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 812f8c80328..af1fa74b25f 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -705,9 +705,9 @@ void psys_get_birth_coords(ParticleSimulationData *sim, ParticleData *pa, Partic /* get birth location from object */ if (use_tangents) - psys_particle_on_emitter(sim->psmd, part->from,pa->num, pa->num_dmcache, pa->fuv,pa->foffset,loc,nor,utan,vtan,0,0); + psys_particle_on_emitter(sim->psmd, part->from,pa->num, pa->num_dmcache, pa->fuv,pa->foffset,loc,nor,utan,vtan,0); else - psys_particle_on_emitter(sim->psmd, part->from,pa->num, pa->num_dmcache, pa->fuv,pa->foffset,loc,nor,0,0,0,0); + psys_particle_on_emitter(sim->psmd, part->from,pa->num, pa->num_dmcache, pa->fuv,pa->foffset,loc,nor,0,0,0); /* get possible textural influence */ psys_get_texture(sim, pa, &ptex, PAMAP_IVEL, cfra); diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c index 14e0cfa75b5..7b53c5f8811 100644 --- a/source/blender/blenkernel/intern/pbvh.c +++ b/source/blender/blenkernel/intern/pbvh.c @@ -1186,20 +1186,6 @@ static void pbvh_update_draw_buffers(PBVH *bvh, PBVHNode **nodes, int totnode) } } -void BKE_pbvh_draw_BB(PBVH *bvh) -{ - unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - - for (int a = 0; a < bvh->totnode; a++) { - PBVHNode *node = &bvh->nodes[a]; - - GPU_pbvh_BB_draw(node->vb.bmin, node->vb.bmax, ((node->flag & PBVH_Leaf) != 0), pos); - } - - immUnbindProgram(); -} - static int pbvh_flush_bb(PBVH *bvh, PBVHNode *node, int flag) { int update = 0; @@ -2008,24 +1994,6 @@ bool BKE_pbvh_node_find_nearest_to_ray( return hit; } -typedef struct { - DMSetMaterial setMaterial; - bool wireframe; - bool fast; -} PBVHNodeDrawData; - -void BKE_pbvh_node_draw(PBVHNode *node, void *data_v) -{ - PBVHNodeDrawData *data = data_v; - - if (!(node->flag & PBVH_FullyHidden)) { - GPU_pbvh_buffers_draw(node->draw_buffers, - data->setMaterial, - data->wireframe, - data->fast); - } -} - typedef enum { ISECT_INSIDE, ISECT_OUTSIDE, @@ -2094,6 +2062,8 @@ static void pbvh_node_check_diffuse_changed(PBVH *bvh, PBVHNode *node) node->flag |= PBVH_UpdateDrawBuffers; } +/* TODO: not needed anymore in 2.8? */ +#if 0 static void pbvh_node_check_mask_changed(PBVH *bvh, PBVHNode *node) { if (!node->draw_buffers) { @@ -2103,38 +2073,7 @@ static void pbvh_node_check_mask_changed(PBVH *bvh, PBVHNode *node) node->flag |= PBVH_UpdateDrawBuffers; } } - -void BKE_pbvh_draw(PBVH *bvh, float (*planes)[4], float (*fnors)[3], - DMSetMaterial setMaterial, bool wireframe, bool fast) -{ - PBVHNodeDrawData draw_data = {setMaterial, wireframe, fast}; - PBVHNode **nodes; - int totnode; - - for (int a = 0; a < bvh->totnode; a++) { - pbvh_node_check_diffuse_changed(bvh, &bvh->nodes[a]); - pbvh_node_check_mask_changed(bvh, &bvh->nodes[a]); - } - - BKE_pbvh_search_gather(bvh, update_search_cb, SET_INT_IN_POINTER(PBVH_UpdateNormals | PBVH_UpdateDrawBuffers), - &nodes, &totnode); - - pbvh_update_normals(bvh, nodes, totnode, fnors); - pbvh_update_draw_buffers(bvh, nodes, totnode); - - if (nodes) MEM_freeN(nodes); - - if (planes) { - BKE_pbvh_search_callback(bvh, BKE_pbvh_node_planes_contain_AABB, - planes, BKE_pbvh_node_draw, &draw_data); - } - else { - BKE_pbvh_search_callback(bvh, NULL, NULL, BKE_pbvh_node_draw, &draw_data); - } - - if (G.debug_value == 14) - BKE_pbvh_draw_BB(bvh); -} +#endif struct PBVHNodeDrawCallbackData { diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 51a4e8bfd66..27ebbad6660 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -111,7 +111,6 @@ #include "bmesh.h" -const char *RE_engine_id_BLENDER_RENDER = "BLENDER_RENDER"; const char *RE_engine_id_BLENDER_CLAY = "BLENDER_CLAY"; const char *RE_engine_id_BLENDER_EEVEE = "BLENDER_EEVEE"; const char *RE_engine_id_BLENDER_WORKBENCH = "BLENDER_WORKBENCH"; @@ -554,7 +553,7 @@ void BKE_scene_init(Scene *sce) sce->lay = sce->layact = 1; - sce->r.mode = R_GAMMA | R_OSA | R_SHADOW | R_SSS | R_ENVMAP | R_RAYTRACE; + sce->r.mode = R_OSA; sce->r.cfra = 1; sce->r.sfra = 1; sce->r.efra = 250; @@ -565,8 +564,6 @@ void BKE_scene_init(Scene *sce) sce->r.yasp = 1; sce->r.tilex = 256; sce->r.tiley = 256; - sce->r.mblur_samples = 1; - sce->r.filtertype = R_FILTER_MITCH; sce->r.size = 50; sce->r.im_format.planes = R_IMF_PLANES_RGBA; @@ -582,8 +579,6 @@ void BKE_scene_init(Scene *sce) sce->r.blurfac = 0.5; sce->r.frs_sec = 24; sce->r.frs_sec_base = 1; - sce->r.edgeint = 10; - sce->r.ocres = 128; /* OCIO_TODO: for forwards compatibility only, so if no tonecurve are used, * images would look in the same way as in current blender @@ -592,18 +587,9 @@ void BKE_scene_init(Scene *sce) */ sce->r.color_mgt_flag |= R_COLOR_MANAGEMENT; - sce->r.gauss = 1.5f; - - /* deprecated but keep for upwards compat */ - sce->r.postgamma = 1.0; - sce->r.posthue = 0.0; - sce->r.postsat = 1.0; - - sce->r.bake_mode = 1; /* prevent to include render stuff here */ + sce->r.bake_mode = 0; sce->r.bake_filter = 16; - sce->r.bake_osa = 5; sce->r.bake_flag = R_BAKE_CLEAR; - sce->r.bake_normal_space = R_BAKE_SPACE_TANGENT; sce->r.bake_samples = 256; sce->r.bake_biasdist = 0.001; @@ -631,7 +617,6 @@ void BKE_scene_init(Scene *sce) sce->r.fg_stamp[3] = 1.0f; sce->r.bg_stamp[0] = sce->r.bg_stamp[1] = sce->r.bg_stamp[2] = 0.0f; sce->r.bg_stamp[3] = 0.25f; - sce->r.raytrace_options = R_RAYTRACE_USE_INSTANCES; sce->r.seq_prev_type = OB_SOLID; sce->r.seq_rend_type = OB_SOLID; @@ -641,8 +626,6 @@ void BKE_scene_init(Scene *sce) sce->r.simplify_subsurf = 6; sce->r.simplify_particles = 1.0f; - sce->r.simplify_shadowsamples = 16; - sce->r.simplify_aosss = 1.0f; sce->r.border.xmin = 0.0f; sce->r.border.ymin = 0.0f; @@ -1472,22 +1455,6 @@ int get_render_child_particle_number(const RenderData *r, int num, bool for_rend } } -int get_render_shadow_samples(const RenderData *r, int samples) -{ - if ((r->mode & R_SIMPLIFY) && samples > 0) - return min_ii(r->simplify_shadowsamples, samples); - else - return samples; -} - -float get_render_aosss_error(const RenderData *r, float error) -{ - if (r->mode & R_SIMPLIFY) - return ((1.0f - r->simplify_aosss) * 10.0f + 1.0f) * error; - else - return error; -} - /** * Helper function for the SETLOOPER and SETLOOPER_VIEW_LAYER macros * @@ -1525,39 +1492,26 @@ next_set: return NULL; } -bool BKE_scene_use_new_shading_nodes(const Scene *scene) -{ - const RenderEngineType *type = RE_engines_find(scene->r.engine); - return (type && type->flag & RE_USE_SHADING_NODES); -} - bool BKE_scene_use_shading_nodes_custom(Scene *scene) { RenderEngineType *type = RE_engines_find(scene->r.engine); return (type && type->flag & RE_USE_SHADING_NODES_CUSTOM); } -bool BKE_scene_use_world_space_shading(Scene *scene) -{ - const RenderEngineType *type = RE_engines_find(scene->r.engine); - return ((scene->r.mode & R_USE_WS_SHADING) || - (type && (type->flag & RE_USE_SHADING_NODES))); -} - bool BKE_scene_use_spherical_stereo(Scene *scene) { RenderEngineType *type = RE_engines_find(scene->r.engine); return (type && type->flag & RE_USE_SPHERICAL_STEREO); } -bool BKE_scene_uses_blender_internal(const Scene *scene) +bool BKE_scene_uses_blender_eevee(const Scene *scene) { - return STREQ(scene->r.engine, RE_engine_id_BLENDER_RENDER); + return STREQ(scene->r.engine, RE_engine_id_BLENDER_EEVEE); } -bool BKE_scene_uses_blender_eevee(const Scene *scene) +bool BKE_scene_uses_cycles(const Scene *scene) { - return STREQ(scene->r.engine, RE_engine_id_BLENDER_EEVEE); + return STREQ(scene->r.engine, RE_engine_id_CYCLES); } void BKE_scene_base_flag_to_objects(ViewLayer *view_layer) diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index f7871c0fa0b..974c2faeadf 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -2758,17 +2758,12 @@ static ImBuf *seq_render_effect_strip_impl( if (seq->flag & SEQ_USE_EFFECT_DEFAULT_FADE) { sh.get_default_fac(seq, cfra, &fac, &facf); - - if ((scene->r.mode & R_FIELDS) == 0) - facf = fac; + facf = fac; } else { fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "effect_fader", 0, NULL); if (fcu) { fac = facf = evaluate_fcurve(fcu, cfra); - if (scene->r.mode & R_FIELDS) { - facf = evaluate_fcurve(fcu, cfra + 0.5f); - } } else { fac = facf = seq->effect_fader; @@ -3337,7 +3332,7 @@ static ImBuf *seq_render_scene_strip(const SeqRenderData *context, Sequence *seq BKE_scene_graph_update_for_newframe(depsgraph, context->bmain); ibuf = sequencer_view3d_cb( /* set for OpenGL render (NULL when scrubbing) */ - depsgraph, scene, view_layer, + depsgraph, scene, context->scene->r.seq_prev_type, camera, width, height, IB_rect, draw_flags, diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index 9280341b4e4..ec6a558cd14 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -77,12 +77,6 @@ # include "BLI_array.h" #endif -#include "GPU_draw.h" -#include "GPU_glew.h" -#include "GPU_buffers.h" -#include "GPU_shader.h" -#include "GPU_basic_shader.h" - #include "CCGSubSurf.h" #ifdef WITH_OPENSUBDIV @@ -1775,46 +1769,6 @@ static void ccgDM_foreachMappedLoop( } } -static void ccgDM_drawVerts(DerivedMesh *dm) -{ - CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; - CCGSubSurf *ss = ccgdm->ss; - int edgeSize = ccgSubSurf_getEdgeSize(ss); - int gridSize = ccgSubSurf_getGridSize(ss); - CCGVertIterator vi; - CCGEdgeIterator ei; - CCGFaceIterator fi; - - glBegin(GL_POINTS); - for (ccgSubSurf_initVertIterator(ss, &vi); !ccgVertIterator_isStopped(&vi); ccgVertIterator_next(&vi)) { - CCGVert *v = ccgVertIterator_getCurrent(&vi); - glVertex3fv(ccgSubSurf_getVertData(ss, v)); - } - - for (ccgSubSurf_initEdgeIterator(ss, &ei); !ccgEdgeIterator_isStopped(&ei); ccgEdgeIterator_next(&ei)) { - CCGEdge *e = ccgEdgeIterator_getCurrent(&ei); - int x; - - for (x = 1; x < edgeSize - 1; x++) - glVertex3fv(ccgSubSurf_getEdgeData(ss, e, x)); - } - - for (ccgSubSurf_initFaceIterator(ss, &fi); !ccgFaceIterator_isStopped(&fi); ccgFaceIterator_next(&fi)) { - CCGFace *f = ccgFaceIterator_getCurrent(&fi); - int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f); - - glVertex3fv(ccgSubSurf_getFaceCenterData(f)); - for (S = 0; S < numVerts; S++) - for (x = 1; x < gridSize - 1; x++) - glVertex3fv(ccgSubSurf_getFaceGridEdgeData(ss, f, S, x)); - for (S = 0; S < numVerts; S++) - for (y = 1; y < gridSize - 1; y++) - for (x = 1; x < gridSize - 1; x++) - glVertex3fv(ccgSubSurf_getFaceGridData(ss, f, S, x, y)); - } - glEnd(); -} - static void ccgdm_pbvh_update(CCGDerivedMesh *ccgdm) { if (ccgdm->pbvh && ccgDM_use_grid_pbvh(ccgdm)) { @@ -1830,1925 +1784,6 @@ static void ccgdm_pbvh_update(CCGDerivedMesh *ccgdm) } } -static void ccgDM_drawEdges(DerivedMesh *dm, bool drawLooseEdges, bool drawAllEdges) -{ - GPUDrawObject *gdo; - CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; - -#ifdef WITH_OPENSUBDIV - if (ccgdm->useGpuBackend) { - /* TODO(sergey): We currently only support all edges drawing. */ - if (ccgSubSurf_prepareGLMesh(ccgdm->ss, true, -1)) { - ccgSubSurf_drawGLMesh(ccgdm->ss, false, -1, -1); - } - return; - } -#endif - - ccgdm_pbvh_update(ccgdm); - -/* old debug feature for edges, unsupported for now */ -#if 0 - int useAging = 0; - - if (!(G.f & G_BACKBUFSEL)) { - CCGSubSurf *ss = ccgdm->ss; - ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL); - - /* it needs some way to upload this to VBO now */ - if (useAging) { - int ageCol = 255 - ccgSubSurf_getEdgeAge(ss, e) * 4; - glColor3ub(0, ageCol > 0 ? ageCol : 0, 0); - } - } -#endif - - GPU_edge_setup(dm); - gdo = dm->drawObject; - if (gdo->edges && gdo->points) { - if (drawAllEdges && drawLooseEdges) { - GPU_buffer_draw_elements(gdo->edges, GL_LINES, 0, (gdo->totedge - gdo->totinterior) * 2); - } - else if (drawAllEdges) { - GPU_buffer_draw_elements(gdo->edges, GL_LINES, 0, gdo->loose_edge_offset * 2); - } - else { - GPU_buffer_draw_elements(gdo->edges, GL_LINES, 0, gdo->tot_edge_drawn * 2); - GPU_buffer_draw_elements(gdo->edges, GL_LINES, gdo->loose_edge_offset * 2, gdo->tot_loose_edge_drawn * 2); - } - } - - if (gdo->edges && ccgdm->drawInteriorEdges) { - GPU_buffer_draw_elements(gdo->edges, GL_LINES, gdo->interior_offset * 2, gdo->totinterior * 2); - } - GPU_buffers_unbind(); -} - -static void ccgDM_drawLooseEdges(DerivedMesh *dm) -{ - int start; - int count; - -#ifdef WITH_OPENSUBDIV - CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; - if (ccgdm->useGpuBackend) { - /* TODO(sergey): Needs implementation. */ - return; - } -#endif - - GPU_edge_setup(dm); - - start = (dm->drawObject->loose_edge_offset * 2); - count = (dm->drawObject->interior_offset - dm->drawObject->loose_edge_offset) * 2; - - if (count) { - GPU_buffer_draw_elements(dm->drawObject->edges, GL_LINES, start, count); - } - - GPU_buffers_unbind(); -} - -static void ccgDM_NormalFast(float *a, float *b, float *c, float *d, float no[3]) -{ - float a_cX = c[0] - a[0], a_cY = c[1] - a[1], a_cZ = c[2] - a[2]; - float b_dX = d[0] - b[0], b_dY = d[1] - b[1], b_dZ = d[2] - b[2]; - - no[0] = b_dY * a_cZ - b_dZ * a_cY; - no[1] = b_dZ * a_cX - b_dX * a_cZ; - no[2] = b_dX * a_cY - b_dY * a_cX; - - normalize_v3(no); -} - - -static void ccgDM_glNormalFast(float *a, float *b, float *c, float *d) -{ - float a_cX = c[0] - a[0], a_cY = c[1] - a[1], a_cZ = c[2] - a[2]; - float b_dX = d[0] - b[0], b_dY = d[1] - b[1], b_dZ = d[2] - b[2]; - float no[3]; - - no[0] = b_dY * a_cZ - b_dZ * a_cY; - no[1] = b_dZ * a_cX - b_dX * a_cZ; - no[2] = b_dX * a_cY - b_dY * a_cX; - - normalize_v3(no); /* we no longer rely on GL_NORMALIZE */ - - glNormal3fv(no); -} - -/* Only used by non-editmesh types */ -static void ccgDM_buffer_copy_normal( - DerivedMesh *dm, short *varray) -{ - CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; - CCGSubSurf *ss = ccgdm->ss; - CCGKey key; - const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL); - int gridSize = ccgSubSurf_getGridSize(ss); - int gridFaces = gridSize - 1; - DMFlagMat *faceFlags = ccgdm->faceFlags; - int i, totface = ccgSubSurf_getNumFaces(ss); - int shademodel; - int start = 0; - - /* we are in sculpt mode, disable loop normals (since they won't get updated) */ - if (ccgdm->pbvh) - lnors = NULL; - - CCG_key_top_level(&key, ss); - - for (i = 0; i < totface; i++) { - CCGFace *f = ccgdm->faceMap[i].face; - int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f); - int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f)); - const float (*ln)[3] = NULL; - - if (faceFlags) { - shademodel = (lnors || (faceFlags[index].flag & ME_SMOOTH)) ? GL_SMOOTH : GL_FLAT; - } - else { - shademodel = GL_SMOOTH; - } - - if (lnors) { - ln = lnors; - lnors += gridFaces * gridFaces * numVerts * 4; - } - - for (S = 0; S < numVerts; S++) { - CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S); - - if (ln) { - /* Can't use quad strips here... */ - for (y = 0; y < gridFaces; y ++) { - for (x = 0; x < gridFaces; x ++) { - normal_float_to_short_v3(&varray[start + 0], ln[0]); - normal_float_to_short_v3(&varray[start + 4], ln[3]); - normal_float_to_short_v3(&varray[start + 8], ln[2]); - normal_float_to_short_v3(&varray[start + 12], ln[1]); - - start += 16; - ln += 4; - } - } - } - else if (shademodel == GL_SMOOTH) { - for (y = 0; y < gridFaces; y ++) { - for (x = 0; x < gridFaces; x ++) { - float *a = CCG_grid_elem_no(&key, faceGridData, x, y ); - float *b = CCG_grid_elem_no(&key, faceGridData, x + 1, y); - float *c = CCG_grid_elem_no(&key, faceGridData, x + 1, y + 1); - float *d = CCG_grid_elem_no(&key, faceGridData, x, y + 1); - - normal_float_to_short_v3(&varray[start], a); - normal_float_to_short_v3(&varray[start + 4], b); - normal_float_to_short_v3(&varray[start + 8], c); - normal_float_to_short_v3(&varray[start + 12], d); - - start += 16; - } - } - } - else { - for (y = 0; y < gridFaces; y ++) { - for (x = 0; x < gridFaces; x ++) { - float f_no[3]; - short f_no_s[3]; - - float *a = CCG_grid_elem_co(&key, faceGridData, x, y ); - float *b = CCG_grid_elem_co(&key, faceGridData, x + 1, y ); - float *c = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 1); - float *d = CCG_grid_elem_co(&key, faceGridData, x, y + 1); - - ccgDM_NormalFast(a, b, c, d, f_no); - normal_float_to_short_v3(f_no_s, f_no); - - copy_v3_v3_short(&varray[start], f_no_s); - copy_v3_v3_short(&varray[start + 4], f_no_s); - copy_v3_v3_short(&varray[start + 8], f_no_s); - copy_v3_v3_short(&varray[start + 12], f_no_s); - - start += 16; - } - } - } - } - } -} - -typedef struct FaceCount { - unsigned int i_visible; - unsigned int i_hidden; - unsigned int i_tri_visible; - unsigned int i_tri_hidden; -} FaceCount; - - -/* Only used by non-editmesh types */ -static void ccgDM_buffer_copy_triangles( - DerivedMesh *dm, unsigned int *varray, - const int *mat_orig_to_new) -{ - GPUBufferMaterial *gpumat, *gpumaterials = dm->drawObject->materials; - const int gpu_totmat = dm->drawObject->totmaterial; - const short dm_totmat = dm->totmat; - CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; - CCGSubSurf *ss = ccgdm->ss; - CCGKey key; - int gridSize = ccgSubSurf_getGridSize(ss); - int gridFaces = gridSize - 1; - DMFlagMat *faceFlags = ccgdm->faceFlags; - int i, totface = ccgSubSurf_getNumFaces(ss); - short mat_nr = -1; - int start; - int totloops = 0; - FaceCount *fc = MEM_mallocN(sizeof(*fc) * gpu_totmat, "gpumaterial.facecount"); - - CCG_key_top_level(&key, ss); - - for (i = 0; i < gpu_totmat; i++) { - fc[i].i_visible = 0; - fc[i].i_tri_visible = 0; - fc[i].i_hidden = gpumaterials[i].totpolys - 1; - fc[i].i_tri_hidden = gpumaterials[i].totelements - 1; - } - - for (i = 0; i < totface; i++) { - CCGFace *f = ccgdm->faceMap[i].face; - int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f); - int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f)); - bool is_hidden; - int mati; - - if (faceFlags) { - mat_nr = ME_MAT_NR_TEST(faceFlags[index].mat_nr, dm_totmat); - is_hidden = (faceFlags[index].flag & ME_HIDE) != 0; - } - else { - mat_nr = 0; - is_hidden = false; - } - mati = mat_orig_to_new[mat_nr]; - gpumat = dm->drawObject->materials + mati; - - if (is_hidden) { - for (S = 0; S < numVerts; S++) { - for (y = 0; y < gridFaces; y++) { - for (x = 0; x < gridFaces; x++) { - start = gpumat->start + fc[mati].i_tri_hidden; - - varray[start--] = totloops; - varray[start--] = totloops + 2; - varray[start--] = totloops + 3; - - varray[start--] = totloops; - varray[start--] = totloops + 1; - varray[start--] = totloops + 2; - - fc[mati].i_tri_hidden -= 6; - - totloops += 4; - } - } - } - gpumat->polys[fc[mati].i_hidden--] = i; - } - else { - for (S = 0; S < numVerts; S++) { - for (y = 0; y < gridFaces; y++) { - for (x = 0; x < gridFaces; x++) { - start = gpumat->start + fc[mati].i_tri_visible; - - varray[start++] = totloops + 3; - varray[start++] = totloops + 2; - varray[start++] = totloops; - - varray[start++] = totloops + 2; - varray[start++] = totloops + 1; - varray[start++] = totloops; - - fc[mati].i_tri_visible += 6; - - totloops += 4; - } - } - } - gpumat->polys[fc[mati].i_visible++] = i; - } - } - - /* set the visible polygons */ - for (i = 0; i < gpu_totmat; i++) { - gpumaterials[i].totvisiblepolys = fc[i].i_visible; - } - - MEM_freeN(fc); -} - - -/* Only used by non-editmesh types */ -static void ccgDM_buffer_copy_vertex( - DerivedMesh *dm, void *varray_p) -{ - float *varray = varray_p; - CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; - CCGSubSurf *ss = ccgdm->ss; - CCGKey key; - int gridSize = ccgSubSurf_getGridSize(ss); - int gridFaces = gridSize - 1; - int i, totface = ccgSubSurf_getNumFaces(ss); - int totedge = ccgSubSurf_getNumEdges(ss); - int start = 0; - int edgeSize = ccgSubSurf_getEdgeSize(ss); - - CCG_key_top_level(&key, ss); - - for (i = 0; i < totface; i++) { - CCGFace *f = ccgdm->faceMap[i].face; - int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f); - - for (S = 0; S < numVerts; S++) { - CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S); - for (y = 0; y < gridFaces; y++) { - for (x = 0; x < gridFaces; x++) { - float *a = CCG_grid_elem_co(&key, faceGridData, x, y); - float *b = CCG_grid_elem_co(&key, faceGridData, x + 1, y); - float *c = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 1); - float *d = CCG_grid_elem_co(&key, faceGridData, x, y + 1); - - copy_v3_v3(&varray[start], a); - copy_v3_v3(&varray[start + 3], b); - copy_v3_v3(&varray[start + 6], c); - copy_v3_v3(&varray[start + 9], d); - - start += 12; - } - } - } - } - - /* upload loose points */ - for (i = 0; i < totedge; i++) { - CCGEdge *e = ccgdm->edgeMap[i].edge; - CCGElem *edgeData = ccgSubSurf_getEdgeDataArray(ss, e); - - if (!ccgSubSurf_getEdgeNumFaces(e)) { - int j = 0; - for (j = 0; j < edgeSize; j++) { - copy_v3_v3(&varray[start], CCG_elem_offset_co(&key, edgeData, j)); - start += 3; - } - } - } -} - -/* Only used by non-editmesh types */ -static void ccgDM_buffer_copy_color( - DerivedMesh *dm, unsigned char *varray, - const void *user_data) -{ - CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; - CCGSubSurf *ss = ccgdm->ss; - CCGKey key; - const unsigned char *mloopcol = user_data; - int gridSize = ccgSubSurf_getGridSize(ss); - int gridFaces = gridSize - 1; - int i, totface = ccgSubSurf_getNumFaces(ss); - int start = 0; - int iface = 0; - - CCG_key_top_level(&key, ss); - - - for (i = 0; i < totface; i++) { - CCGFace *f = ccgdm->faceMap[i].face; - int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f); - - for (S = 0; S < numVerts; S++) { - for (y = 0; y < gridFaces; y++) { - for (x = 0; x < gridFaces; x++) { - copy_v4_v4_uchar(&varray[start + 0], &mloopcol[iface * 16 + 0]); - copy_v4_v4_uchar(&varray[start + 4], &mloopcol[iface * 16 + 12]); - copy_v4_v4_uchar(&varray[start + 8], &mloopcol[iface * 16 + 8]); - copy_v4_v4_uchar(&varray[start + 12], &mloopcol[iface * 16 + 4]); - - start += 16; - iface++; - } - } - } - } -} - -static void ccgDM_buffer_copy_uv( - DerivedMesh *dm, void *varray_p) -{ - float *varray = varray_p; - CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; - CCGSubSurf *ss = ccgdm->ss; - CCGKey key; - MLoopUV *mloopuv = DM_get_loop_data_layer(dm, CD_MLOOPUV); - int gridSize = ccgSubSurf_getGridSize(ss); - int gridFaces = gridSize - 1; - int i, totface = ccgSubSurf_getNumFaces(ss); - int start = 0; - - CCG_key_top_level(&key, ss); - - for (i = 0; i < totface; i++) { - CCGFace *f = ccgdm->faceMap[i].face; - int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f); - - for (S = 0; S < numVerts; S++) { - for (y = 0; y < gridFaces; y++) { - for (x = 0; x < gridFaces; x++) { - copy_v2_v2(&varray[start + 0], mloopuv[0].uv); - copy_v2_v2(&varray[start + 2], mloopuv[3].uv); - copy_v2_v2(&varray[start + 4], mloopuv[2].uv); - copy_v2_v2(&varray[start + 6], mloopuv[1].uv); - - mloopuv += 4; - start += 8; - } - } - } - } -} - -static void ccgDM_buffer_copy_uv_texpaint( - DerivedMesh *dm, float *varray) -{ - CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; - CCGSubSurf *ss = ccgdm->ss; - CCGKey key; - int gridSize = ccgSubSurf_getGridSize(ss); - int gridFaces = gridSize - 1; - int i, totface = ccgSubSurf_getNumFaces(ss); - int start = 0; - DMFlagMat *faceFlags = ccgdm->faceFlags; - int dm_totmat = dm->totmat; - MLoopUV **mloopuv_base; - MLoopUV *stencil_base; - int stencil; - - CCG_key_top_level(&key, ss); - - /* should have been checked for before, reassert */ - BLI_assert(DM_get_loop_data_layer(dm, CD_MLOOPUV)); - mloopuv_base = MEM_mallocN(dm_totmat * sizeof(*mloopuv_base), "texslots"); - - for (i = 0; i < dm_totmat; i++) { - mloopuv_base[i] = DM_paint_uvlayer_active_get(dm, i); - } - - stencil = CustomData_get_stencil_layer(&dm->loopData, CD_MLOOPUV); - stencil_base = CustomData_get_layer_n(&dm->loopData, CD_MLOOPUV, stencil); - - start = 0; - - for (i = 0; i < totface; i++) { - CCGFace *f = ccgdm->faceMap[i].face; - int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f); - int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f)); - int matnr; - - if (faceFlags) { - matnr = faceFlags[index].mat_nr; - } - else { - matnr = 0; - } - - for (S = 0; S < numVerts; S++) { - for (y = 0; y < gridFaces; y++) { - for (x = 0; x < gridFaces; x++) { - /* divide by 4, gives us current loop-index */ - unsigned int i_ml = start / 4; - copy_v2_v2(&varray[start + 0], mloopuv_base[matnr][i_ml + 0].uv); - copy_v2_v2(&varray[start + 2], stencil_base[i_ml + 0].uv); - copy_v2_v2(&varray[start + 4], mloopuv_base[matnr][i_ml + 3].uv); - copy_v2_v2(&varray[start + 6], stencil_base[i_ml + 3].uv); - copy_v2_v2(&varray[start + 8], mloopuv_base[matnr][i_ml + 2].uv); - copy_v2_v2(&varray[start + 10], stencil_base[i_ml + 2].uv); - copy_v2_v2(&varray[start + 12], mloopuv_base[matnr][i_ml + 1].uv); - copy_v2_v2(&varray[start + 14], stencil_base[i_ml + 1].uv); - start += 16; - } - } - } - } - - MEM_freeN(mloopuv_base); -} - -static void ccgDM_buffer_copy_uvedge( - DerivedMesh *dm, float *varray) -{ - int i, totpoly; - int start; - const MLoopUV *mloopuv; -#ifndef USE_LOOP_LAYOUT_FAST - const MPoly *mpoly = dm->getPolyArray(dm); -#endif - - if ((mloopuv = DM_get_loop_data_layer(dm, CD_MLOOPUV)) == NULL) { - return; - } - - totpoly = dm->getNumPolys(dm); - start = 0; - -#ifndef USE_LOOP_LAYOUT_FAST - for (i = 0; i < totpoly; i++, mpoly++) { - for (j = 0; j < mpoly->totloop; j++) { - copy_v2_v2(&varray[start], mloopuv[mpoly->loopstart + j].uv); - copy_v2_v2(&varray[start + 2], mloopuv[mpoly->loopstart + (j + 1) % mpoly->totloop].uv); - start += 4; - } - } -#else - for (i = 0; i < totpoly; i++) { - copy_v2_v2(&varray[start + 0], mloopuv[(i * 4) + 0].uv); - copy_v2_v2(&varray[start + 2], mloopuv[(i * 4) + 1].uv); - - copy_v2_v2(&varray[start + 4], mloopuv[(i * 4) + 1].uv); - copy_v2_v2(&varray[start + 6], mloopuv[(i * 4) + 2].uv); - - copy_v2_v2(&varray[start + 8], mloopuv[(i * 4) + 2].uv); - copy_v2_v2(&varray[start + 10], mloopuv[(i * 4) + 3].uv); - - copy_v2_v2(&varray[start + 12], mloopuv[(i * 4) + 3].uv); - copy_v2_v2(&varray[start + 14], mloopuv[(i * 4) + 0].uv); - - start += 16; - } -#endif -} - -static void ccgDM_buffer_copy_edge( - DerivedMesh *dm, unsigned int *varray) -{ - CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; - CCGSubSurf *ss = ccgdm->ss; - /* getEdgeSuze returns num of verts, edges is one less */ - int i, j, edgeSize = ccgSubSurf_getEdgeSize(ss) - 1; - int totedge = ccgSubSurf_getNumEdges(ss); - int grid_face_side = ccgSubSurf_getGridSize(ss) - 1; - int totface = ccgSubSurf_getNumFaces(ss); - unsigned int index_start; - unsigned int tot_interior = 0; - unsigned int grid_tot_face = grid_face_side * grid_face_side; - - unsigned int iloose, inorm, iloosehidden, inormhidden; - unsigned int tot_loose_hidden = 0, tot_loose = 0; - unsigned int tot_hidden = 0, tot = 0; - unsigned int iloosevert; - /* int tot_interior = 0; */ - - /* first, handle hidden/loose existing edges, then interior edges */ - for (j = 0; j < totedge; j++) { - CCGEdge *e = ccgdm->edgeMap[j].edge; - - if (ccgdm->edgeFlags && !(ccgdm->edgeFlags[j] & ME_EDGEDRAW)) { - if (!ccgSubSurf_getEdgeNumFaces(e)) tot_loose_hidden++; - else tot_hidden++; - } - else { - if (!ccgSubSurf_getEdgeNumFaces(e)) tot_loose++; - else tot++; - } - } - - inorm = 0; - inormhidden = tot * edgeSize; - iloose = (tot + tot_hidden) * edgeSize; - iloosehidden = (tot + tot_hidden + tot_loose) * edgeSize; - iloosevert = dm->drawObject->tot_loop_verts; - - /* part one, handle all normal edges */ - for (j = 0; j < totedge; j++) { - CCGFace *f; - int fhandle = 0; - int totvert = 0; - unsigned int S = 0; - CCGEdge *e = ccgdm->edgeMap[j].edge; - bool isloose = !ccgSubSurf_getEdgeNumFaces(e); - - if (!isloose) { - CCGVert *v1, *v2; - CCGVert *ev1 = ccgSubSurf_getEdgeVert0(e); - CCGVert *ev2 = ccgSubSurf_getEdgeVert1(e); - - f = ccgSubSurf_getEdgeFace(e, 0); - fhandle = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f)); - totvert = ccgSubSurf_getFaceNumVerts(f); - - /* find the index of vertices in the face */ - for (i = 0; i < totvert; i++) { - v1 = ccgSubSurf_getFaceVert(f, i); - v2 = ccgSubSurf_getFaceVert(f, (i + 1) % totvert); - - if ((ev1 == v1 && ev2 == v2) || (ev1 == v2 && ev2 == v1)) { - S = i; - break; - } - } - } - - if (ccgdm->edgeFlags && !(ccgdm->edgeFlags[j] & ME_EDGEDRAW)) { - if (isloose) { - for (i = 0; i < edgeSize; i++) { - varray[iloosehidden * 2] = iloosevert; - varray[iloosehidden * 2 + 1] = iloosevert + 1; - iloosehidden++; - iloosevert++; - } - /* we are through with this loose edge and moving to the next, so increase by one */ - iloosevert++; - } - else { - index_start = ccgdm->faceMap[fhandle].startFace; - - for (i = 0; i < grid_face_side; i++) { - varray[inormhidden * 2] = (index_start + S * grid_tot_face + i * grid_face_side + grid_face_side - 1) * 4 + 1; - varray[inormhidden * 2 + 1] = (index_start + S * grid_tot_face + i * grid_face_side + grid_face_side - 1) * 4 + 2; - varray[inormhidden * 2 + 2] = (index_start + ((S + 1) % totvert) * grid_tot_face + grid_face_side * (grid_face_side - 1) + i) * 4 + 2; - varray[inormhidden * 2 + 3] = (index_start + ((S + 1) % totvert) * grid_tot_face + grid_face_side * (grid_face_side - 1) + i) * 4 + 3; - inormhidden += 2; - } - } - } - else { - if (isloose) { - for (i = 0; i < edgeSize; i++) { - varray[iloose * 2] = iloosevert; - varray[iloose * 2 + 1] = iloosevert + 1; - iloose++; - iloosevert++; - } - /* we are through with this loose edge and moving to the next, so increase by one */ - iloosevert++; - } - else { - index_start = ccgdm->faceMap[fhandle].startFace; - - for (i = 0; i < grid_face_side; i++) { - varray[inorm * 2] = (index_start + S * grid_tot_face + i * grid_face_side + grid_face_side - 1) * 4 + 1; - varray[inorm * 2 + 1] = (index_start + S * grid_tot_face + i * grid_face_side + grid_face_side - 1) * 4 + 2; - varray[inorm * 2 + 2] = (index_start + ((S + 1) % totvert) * grid_tot_face + grid_face_side * (grid_face_side - 1) + i) * 4 + 2; - varray[inorm * 2 + 3] = (index_start + ((S + 1) % totvert) * grid_tot_face + grid_face_side * (grid_face_side - 1) + i) * 4 + 3; - inorm += 2; - } - } - } - } - - /* part two, handle interior edges */ - inorm = totedge * grid_face_side * 2; - - index_start = 0; - for (i = 0; i < totface; i++) { - CCGFace *f = ccgdm->faceMap[i].face; - unsigned int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f); - - for (S = 0; S < numVerts; S++) { - for (x = 1; x < grid_face_side; x++) { - for (y = 0; y < grid_face_side; y++) { - unsigned int tmp = (index_start + x * grid_face_side + y) * 4; - varray[inorm * 2] = tmp; - varray[inorm * 2 + 1] = tmp + 1; - inorm++; - } - } - for (x = 0; x < grid_face_side; x++) { - for (y = 0; y < grid_face_side; y++) { - unsigned int tmp = (index_start + x * grid_face_side + y) * 4; - varray[inorm * 2] = tmp + 3; - varray[inorm * 2 + 1] = tmp; - inorm++; - } - } - - tot_interior += grid_face_side * (2 * grid_face_side - 1); - index_start += grid_tot_face; - } - } - - dm->drawObject->tot_loose_edge_drawn = tot_loose * edgeSize; - dm->drawObject->loose_edge_offset = (tot + tot_hidden) * edgeSize; - dm->drawObject->tot_edge_drawn = tot * edgeSize; - - dm->drawObject->interior_offset = totedge * edgeSize; - dm->drawObject->totinterior = tot_interior; -} - -static void ccgDM_copy_gpu_data( - DerivedMesh *dm, int type, void *varray_p, - const int *mat_orig_to_new, const void *user_data) -{ - /* 'varray_p' cast is redundant but include for self-documentation */ - switch (type) { - case GPU_BUFFER_VERTEX: - ccgDM_buffer_copy_vertex(dm, (float *)varray_p); - break; - case GPU_BUFFER_NORMAL: - ccgDM_buffer_copy_normal(dm, (short *)varray_p); - break; - case GPU_BUFFER_UV: - ccgDM_buffer_copy_uv(dm, (float *)varray_p); - break; - case GPU_BUFFER_UV_TEXPAINT: - ccgDM_buffer_copy_uv_texpaint(dm, (float *)varray_p); - break; - case GPU_BUFFER_COLOR: - ccgDM_buffer_copy_color(dm, (unsigned char *)varray_p, user_data); - break; - case GPU_BUFFER_UVEDGE: - ccgDM_buffer_copy_uvedge(dm, (float *)varray_p); - break; - case GPU_BUFFER_EDGE: - ccgDM_buffer_copy_edge(dm, (unsigned int *)varray_p); - break; - case GPU_BUFFER_TRIANGLES: - ccgDM_buffer_copy_triangles(dm, (unsigned int *)varray_p, mat_orig_to_new); - break; - default: - break; - } -} - -static GPUDrawObject *ccgDM_GPUObjectNew(DerivedMesh *dm) -{ - CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; - CCGSubSurf *ss = ccgdm->ss; - GPUDrawObject *gdo; - DMFlagMat *faceFlags = ccgdm->faceFlags; - int gridFaces = ccgSubSurf_getGridSize(ss) - 1; - const short dm_totmat = (faceFlags) ? dm->totmat : 1; - GPUBufferMaterial *matinfo; - int i; - unsigned int tot_internal_edges = 0; - int edgeVerts = ccgSubSurf_getEdgeSize(ss); - int edgeSize = edgeVerts - 1; - - int totedge = ccgSubSurf_getNumEdges(ss); - int totface = ccgSubSurf_getNumFaces(ss); - - /* object contains at least one material (default included) so zero means uninitialized dm */ - BLI_assert(dm_totmat != 0); - - matinfo = MEM_callocN(sizeof(*matinfo) * dm_totmat, "GPU_drawobject_new.mat_orig_to_new"); - - if (faceFlags) { - for (i = 0; i < totface; i++) { - CCGFace *f = ccgdm->faceMap[i].face; - int numVerts = ccgSubSurf_getFaceNumVerts(f); - int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f)); - const short new_matnr = ME_MAT_NR_TEST(faceFlags[index].mat_nr, dm_totmat); - matinfo[new_matnr].totelements += numVerts * gridFaces * gridFaces * 6; - matinfo[new_matnr].totloops += numVerts * gridFaces * gridFaces * 4; - matinfo[new_matnr].totpolys++; - tot_internal_edges += numVerts * gridFaces * (2 * gridFaces - 1); - } - } - else { - for (i = 0; i < totface; i++) { - CCGFace *f = ccgdm->faceMap[i].face; - int numVerts = ccgSubSurf_getFaceNumVerts(f); - matinfo[0].totelements += numVerts * gridFaces * gridFaces * 6; - matinfo[0].totloops += numVerts * gridFaces * gridFaces * 4; - matinfo[0].totpolys++; - tot_internal_edges += numVerts * gridFaces * (2 * gridFaces - 1); - } - } - - /* create the GPUDrawObject */ - gdo = MEM_callocN(sizeof(GPUDrawObject), "GPUDrawObject"); - gdo->totvert = 0; /* used to count indices, doesn't really matter for ccgsubsurf */ - gdo->totedge = (totedge * edgeSize + tot_internal_edges); - - GPU_buffer_material_finalize(gdo, matinfo, dm_totmat); - - /* store total number of points used for triangles */ - gdo->tot_triangle_point = ccgSubSurf_getNumFinalFaces(ss) * 6; - gdo->tot_loop_verts = ccgSubSurf_getNumFinalFaces(ss) * 4; - - /* finally, count loose points */ - for (i = 0; i < totedge; i++) { - CCGEdge *e = ccgdm->edgeMap[i].edge; - - if (!ccgSubSurf_getEdgeNumFaces(e)) - gdo->tot_loose_point += edgeVerts; - } - - return gdo; -} - -/* Only used by non-editmesh types */ -static void ccgDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes)[4], bool fast, DMSetMaterial setMaterial) -{ - int a; - CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; - - ccgdm_pbvh_update(ccgdm); - - if (ccgdm->pbvh && ccgdm->multires.mmd) { - if (BKE_pbvh_has_faces(ccgdm->pbvh)) { - BKE_pbvh_draw(ccgdm->pbvh, partial_redraw_planes, NULL, - setMaterial, false, fast); - } - - return; - } - -#ifdef WITH_OPENSUBDIV - if (ccgdm->useGpuBackend) { - CCGSubSurf *ss = ccgdm->ss; - const DMFlagMat *faceFlags = ccgdm->faceFlags; - const int level = ccgSubSurf_getSubdivisionLevels(ss); - const int face_side = 1 << level; - const int grid_side = 1 << (level - 1); - const int face_patches = face_side * face_side; - const int grid_patches = grid_side * grid_side; - const int num_base_faces = ccgSubSurf_getNumGLMeshBaseFaces(ss); - int i, current_patch = 0; - int mat_nr = -1; - bool draw_smooth = false; - int start_draw_patch = -1, num_draw_patches = 0; - if (UNLIKELY(ccgSubSurf_prepareGLMesh(ss, setMaterial != NULL, -1) == false)) { - return; - } - if (setMaterial == NULL) { - ccgSubSurf_drawGLMesh(ss, - true, - -1, - -1); - return; - } - for (i = 0; i < num_base_faces; ++i) { - const int num_face_verts = ccgSubSurf_getNumGLMeshBaseFaceVerts(ss, i); - const int num_patches = (num_face_verts == 4) ? face_patches - : num_face_verts * grid_patches; - int new_matnr; - bool new_draw_smooth; - if (faceFlags) { - new_draw_smooth = (faceFlags[i].flag & ME_SMOOTH); - new_matnr = (faceFlags[i].mat_nr + 1); - } - else { - new_draw_smooth = true; - new_matnr = 1; - } - if (new_draw_smooth != draw_smooth || new_matnr != mat_nr) { - if (num_draw_patches != 0) { - bool do_draw = setMaterial(mat_nr, NULL); - if (do_draw) { - glShadeModel(draw_smooth ? GL_SMOOTH : GL_FLAT); - ccgSubSurf_drawGLMesh(ss, - true, - start_draw_patch, - num_draw_patches); - } - } - start_draw_patch = current_patch; - num_draw_patches = num_patches; - mat_nr = new_matnr; - draw_smooth = new_draw_smooth; - } - else { - num_draw_patches += num_patches; - } - current_patch += num_patches; - } - if (num_draw_patches != 0) { - bool do_draw = setMaterial(mat_nr, NULL); - if (do_draw) { - glShadeModel(draw_smooth ? GL_SMOOTH : GL_FLAT); - ccgSubSurf_drawGLMesh(ss, - true, - start_draw_patch, - num_draw_patches); - } - } - glShadeModel(GL_SMOOTH); - return; - } -#endif - - GPU_vertex_setup(dm); - GPU_normal_setup(dm); - GPU_triangle_setup(dm); - for (a = 0; a < dm->drawObject->totmaterial; a++) { - if (!setMaterial || setMaterial(dm->drawObject->materials[a].mat_nr + 1, NULL)) { - GPU_buffer_draw_elements(dm->drawObject->triangles, GL_TRIANGLES, dm->drawObject->materials[a].start, - dm->drawObject->materials[a].totelements); - } - } - GPU_buffers_unbind(); -} - -typedef struct { - DMVertexAttribs attribs; - int numdata; - - GPUAttrib datatypes[GPU_MAX_ATTRIB]; /* TODO, messing up when switching materials many times - [#21056]*/ -} GPUMaterialConv; - -/* Only used by non-editmesh types */ -static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm, - DMSetMaterial setMaterial, - DMSetDrawOptions setDrawOptions, - void *userData) -{ - CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; - CCGSubSurf *ss = ccgdm->ss; - CCGKey key; - GPUVertexAttribs gattribs; - int a, b; - const DMFlagMat *faceFlags = ccgdm->faceFlags; - unsigned char *varray; - size_t max_element_size = 0; - int tot_loops = 0; - int totpoly = ccgSubSurf_getNumFaces(ss); - int gridSize = ccgSubSurf_getGridSize(ss); - int gridFaces = gridSize - 1; - int edgeSize = ccgSubSurf_getEdgeSize(ss); - -#ifdef WITH_OPENSUBDIV - if (ccgdm->useGpuBackend) { - const int level = ccgSubSurf_getSubdivisionLevels(ss); - const int face_side = 1 << level; - const int grid_side = 1 << (level - 1); - const int face_patches = face_side * face_side; - const int grid_patches = grid_side * grid_side; - const int num_base_faces = ccgSubSurf_getNumGLMeshBaseFaces(ss); - int i, current_patch = 0; - int mat_nr = -1; - bool draw_smooth = false; - int start_draw_patch = -1, num_draw_patches = 0; - GPU_draw_update_fvar_offset(dm); - if (UNLIKELY(ccgSubSurf_prepareGLMesh(ss, false, -1) == false)) { - return; - } - for (i = 0; i < num_base_faces; ++i) { - const int num_face_verts = ccgSubSurf_getNumGLMeshBaseFaceVerts(ss, i); - const int num_patches = (num_face_verts == 4) ? face_patches - : num_face_verts * grid_patches; - int new_matnr; - bool new_draw_smooth; - - if (faceFlags) { - new_draw_smooth = (faceFlags[i].flag & ME_SMOOTH); - new_matnr = (faceFlags[i].mat_nr + 1); - } - else { - new_draw_smooth = true; - new_matnr = 1; - } - if (new_draw_smooth != draw_smooth || new_matnr != mat_nr) { - if (num_draw_patches != 0) { - bool do_draw = setMaterial(mat_nr, &gattribs); - if (do_draw) { - glShadeModel(draw_smooth ? GL_SMOOTH : GL_FLAT); - ccgSubSurf_drawGLMesh(ss, - true, - start_draw_patch, - num_draw_patches); - } - } - start_draw_patch = current_patch; - num_draw_patches = num_patches; - mat_nr = new_matnr; - draw_smooth = new_draw_smooth; - } - else { - num_draw_patches += num_patches; - } - current_patch += num_patches; - } - if (num_draw_patches != 0) { - bool do_draw = setMaterial(mat_nr, &gattribs); - if (do_draw) { - glShadeModel(draw_smooth ? GL_SMOOTH : GL_FLAT); - ccgSubSurf_drawGLMesh(ss, - true, - start_draw_patch, - num_draw_patches); - } - } - glShadeModel(GL_SMOOTH); - return; - } -#endif - - CCG_key_top_level(&key, ss); - ccgdm_pbvh_update(ccgdm); - - if (setDrawOptions != NULL) { - const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL); - DMVertexAttribs attribs = {{{NULL}}}; - int i; - int matnr = -1; - int do_draw = 0; - -#define PASSATTRIB(dx, dy, vert) { \ - if (attribs.totorco) \ - index = getFaceIndex(ss, f, S, x + dx, y + dy, edgeSize, gridSize); \ - else \ - index = 0; \ - DM_draw_attrib_vertex(&attribs, a, index, vert, ((a) * 4) + vert); \ - DM_draw_attrib_vertex_uniforms(&attribs); \ -} (void)0 - - totpoly = ccgSubSurf_getNumFaces(ss); - for (a = 0, i = 0; i < totpoly; i++) { - CCGFace *f = ccgdm->faceMap[i].face; - const float (*ln)[3] = NULL; - int S, x, y, drawSmooth; - int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f)); - int origIndex = ccgDM_getFaceMapIndex(ss, f); - - int numVerts = ccgSubSurf_getFaceNumVerts(f); - int new_matnr; - - if (faceFlags) { - drawSmooth = (lnors || (faceFlags[index].flag & ME_SMOOTH)); - new_matnr = faceFlags[index].mat_nr + 1; - } - else { - drawSmooth = 1; - new_matnr = 1; - } - - if (lnors) { - ln = lnors; - lnors += (gridFaces * gridFaces * numVerts) * 4; - } - - if (new_matnr != matnr) { - do_draw = setMaterial(matnr = new_matnr, &gattribs); - if (do_draw) - DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs); - } - - if (!do_draw || (setDrawOptions && (origIndex != ORIGINDEX_NONE) && - (setDrawOptions(userData, origIndex) == DM_DRAW_OPTION_SKIP))) - { - a += gridFaces * gridFaces * numVerts; - continue; - } - - glShadeModel(drawSmooth ? GL_SMOOTH : GL_FLAT); - for (S = 0; S < numVerts; S++) { - CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S); - CCGElem *vda, *vdb; - - if (ln) { - glBegin(GL_QUADS); - for (y = 0; y < gridFaces; y++) { - for (x = 0; x < gridFaces; x++) { - float *aco = CCG_grid_elem_co(&key, faceGridData, x, y); - float *bco = CCG_grid_elem_co(&key, faceGridData, x + 1, y); - float *cco = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 1); - float *dco = CCG_grid_elem_co(&key, faceGridData, x, y + 1); - - PASSATTRIB(0, 1, 1); - glNormal3fv(ln[1]); - glVertex3fv(dco); - PASSATTRIB(1, 1, 2); - glNormal3fv(ln[2]); - glVertex3fv(cco); - PASSATTRIB(1, 0, 3); - glNormal3fv(ln[3]); - glVertex3fv(bco); - PASSATTRIB(0, 0, 0); - glNormal3fv(ln[0]); - glVertex3fv(aco); - - ln += 4; - a++; - } - } - glEnd(); - } - else if (drawSmooth) { - for (y = 0; y < gridFaces; y++) { - glBegin(GL_QUAD_STRIP); - for (x = 0; x < gridFaces; x++) { - vda = CCG_grid_elem(&key, faceGridData, x, y + 0); - vdb = CCG_grid_elem(&key, faceGridData, x, y + 1); - - PASSATTRIB(0, 0, 0); - glNormal3fv(CCG_elem_no(&key, vda)); - glVertex3fv(CCG_elem_co(&key, vda)); - - PASSATTRIB(0, 1, 1); - glNormal3fv(CCG_elem_no(&key, vdb)); - glVertex3fv(CCG_elem_co(&key, vdb)); - - if (x != gridFaces - 1) - a++; - } - - vda = CCG_grid_elem(&key, faceGridData, x, y + 0); - vdb = CCG_grid_elem(&key, faceGridData, x, y + 1); - - PASSATTRIB(0, 0, 3); - glNormal3fv(CCG_elem_no(&key, vda)); - glVertex3fv(CCG_elem_co(&key, vda)); - - PASSATTRIB(0, 1, 2); - glNormal3fv(CCG_elem_no(&key, vdb)); - glVertex3fv(CCG_elem_co(&key, vdb)); - - glEnd(); - - a++; - } - } - else { - glBegin(GL_QUADS); - for (y = 0; y < gridFaces; y++) { - for (x = 0; x < gridFaces; x++) { - float *aco = CCG_grid_elem_co(&key, faceGridData, x, y); - float *bco = CCG_grid_elem_co(&key, faceGridData, x + 1, y); - float *cco = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 1); - float *dco = CCG_grid_elem_co(&key, faceGridData, x, y + 1); - - ccgDM_glNormalFast(aco, bco, cco, dco); - - PASSATTRIB(0, 1, 1); - glVertex3fv(dco); - PASSATTRIB(1, 1, 2); - glVertex3fv(cco); - PASSATTRIB(1, 0, 3); - glVertex3fv(bco); - PASSATTRIB(0, 0, 0); - glVertex3fv(aco); - - a++; - } - } - glEnd(); - } - } - } - - glShadeModel(GL_SMOOTH); -#undef PASSATTRIB - } - else { - GPUMaterialConv *matconv; - size_t offset; - int *mat_orig_to_new; - int tot_active_mat; - GPUBuffer *buffer = NULL; - - GPU_vertex_setup(dm); - GPU_normal_setup(dm); - GPU_triangle_setup(dm); - - tot_active_mat = dm->drawObject->totmaterial; - - matconv = MEM_callocN(sizeof(*matconv) * tot_active_mat, - "cdDM_drawMappedFacesGLSL.matconv"); - mat_orig_to_new = MEM_mallocN(sizeof(*mat_orig_to_new) * dm->totmat, - "cdDM_drawMappedFacesGLSL.mat_orig_to_new"); - - /* part one, check what attributes are needed per material */ - for (a = 0; a < tot_active_mat; a++) { - int new_matnr; - int do_draw; - - new_matnr = dm->drawObject->materials[a].mat_nr; - - /* map from original material index to new - * GPUBufferMaterial index */ - mat_orig_to_new[new_matnr] = a; - do_draw = setMaterial(new_matnr + 1, &gattribs); - - if (do_draw) { - int numdata = 0; - DM_vertex_attributes_from_gpu(dm, &gattribs, &matconv[a].attribs); - - if (matconv[a].attribs.totorco && matconv[a].attribs.orco.array) { - matconv[a].datatypes[numdata].index = matconv[a].attribs.orco.gl_index; - matconv[a].datatypes[numdata].info_index = matconv[a].attribs.orco.gl_info_index; - matconv[a].datatypes[numdata].size = 3; - matconv[a].datatypes[numdata].type = GL_FLOAT; - numdata++; - } - for (b = 0; b < matconv[a].attribs.tottface; b++) { - if (matconv[a].attribs.tface[b].array) { - matconv[a].datatypes[numdata].index = matconv[a].attribs.tface[b].gl_index; - matconv[a].datatypes[numdata].info_index = matconv[a].attribs.tface[b].gl_info_index; - matconv[a].datatypes[numdata].size = 2; - matconv[a].datatypes[numdata].type = GL_FLOAT; - numdata++; - } - } - for (b = 0; b < matconv[a].attribs.totmcol; b++) { - if (matconv[a].attribs.mcol[b].array) { - matconv[a].datatypes[numdata].index = matconv[a].attribs.mcol[b].gl_index; - matconv[a].datatypes[numdata].info_index = matconv[a].attribs.mcol[b].gl_info_index; - matconv[a].datatypes[numdata].size = 4; - matconv[a].datatypes[numdata].type = GL_UNSIGNED_BYTE; - numdata++; - } - } - for (b = 0; b < matconv[a].attribs.tottang; b++) { - if (matconv[a].attribs.tottang && matconv[a].attribs.tang[b].array) { - matconv[a].datatypes[numdata].index = matconv[a].attribs.tang[b].gl_index; - matconv[a].datatypes[numdata].info_index = matconv[a].attribs.tang[b].gl_info_index; - matconv[a].datatypes[numdata].size = 4; - matconv[a].datatypes[numdata].type = GL_FLOAT; - numdata++; - } - } - if (numdata != 0) { - matconv[a].numdata = numdata; - max_element_size = max_ii(GPU_attrib_element_size(matconv[a].datatypes, numdata), max_element_size); - } - } - } - - /* part two, generate and fill the arrays with the data */ - if (max_element_size > 0) { - buffer = GPU_buffer_alloc(max_element_size * dm->drawObject->tot_loop_verts); - - varray = GPU_buffer_lock_stream(buffer, GPU_BINDING_ARRAY); - if (varray == NULL) { - GPU_buffers_unbind(); - GPU_buffer_free(buffer); - MEM_freeN(mat_orig_to_new); - MEM_freeN(matconv); - fprintf(stderr, "Out of memory, can't draw object\n"); - return; - } - - for (a = 0; a < totpoly; a++) { - CCGFace *f = ccgdm->faceMap[a].face; - int orig_index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f)); - int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f); - int i; - - if (faceFlags) { - i = mat_orig_to_new[faceFlags[orig_index].mat_nr]; - } - else { - i = mat_orig_to_new[0]; - } - - if (matconv[i].numdata != 0) { - for (S = 0; S < numVerts; S++) { - for (y = 0; y < gridFaces; y++) { - for (x = 0; x < gridFaces; x++) { - - offset = tot_loops * max_element_size; - - if (matconv[i].attribs.totorco && matconv[i].attribs.orco.array) { - int index; - - index = getFaceIndex(ss, f, S, x, y, edgeSize, gridSize); - copy_v3_v3((float *)&varray[offset], - (float *)matconv[i].attribs.orco.array[index]); - index = getFaceIndex(ss, f, S, x + 1, y, edgeSize, gridSize); - copy_v3_v3((float *)&varray[offset + max_element_size], - (float *)matconv[i].attribs.orco.array[index]); - index = getFaceIndex(ss, f, S, x + 1, y + 1, edgeSize, gridSize); - copy_v3_v3((float *)&varray[offset + 2 * max_element_size], - (float *)matconv[i].attribs.orco.array[index]); - index = getFaceIndex(ss, f, S, x, y + 1, edgeSize, gridSize); - copy_v3_v3((float *)&varray[offset + 3 * max_element_size], - (float *)matconv[i].attribs.orco.array[index]); - - offset += sizeof(float) * 3; - } - for (b = 0; b < matconv[i].attribs.tottface; b++) { - if (matconv[i].attribs.tface[b].array) { - const MLoopUV *mloopuv = matconv[i].attribs.tface[b].array + tot_loops; - - copy_v2_v2((float *)&varray[offset], mloopuv[0].uv); - copy_v2_v2((float *)&varray[offset + max_element_size], mloopuv[3].uv); - copy_v2_v2((float *)&varray[offset + 2 * max_element_size], mloopuv[2].uv); - copy_v2_v2((float *)&varray[offset + 3 * max_element_size], mloopuv[1].uv); - - offset += sizeof(float) * 2; - } - } - for (b = 0; b < matconv[i].attribs.totmcol; b++) { - if (matconv[i].attribs.mcol[b].array) { - const MLoopCol *mloopcol = matconv[i].attribs.mcol[b].array + tot_loops; - - copy_v4_v4_uchar(&varray[offset], &mloopcol[0].r); - copy_v4_v4_uchar(&varray[offset + max_element_size], &mloopcol[3].r); - copy_v4_v4_uchar(&varray[offset + 2 * max_element_size], &mloopcol[2].r); - copy_v4_v4_uchar(&varray[offset + 3 * max_element_size], &mloopcol[1].r); - - offset += sizeof(unsigned char) * 4; - } - } - for (b = 0; b < matconv[i].attribs.tottang; b++) { - if (matconv[i].attribs.tottang && matconv[i].attribs.tang[b].array) { - const float (*looptang)[4] = (const float (*)[4])matconv[i].attribs.tang[b].array + tot_loops; - - copy_v4_v4((float *)&varray[offset], looptang[0]); - copy_v4_v4((float *)&varray[offset + max_element_size], looptang[3]); - copy_v4_v4((float *)&varray[offset + 2 * max_element_size], looptang[2]); - copy_v4_v4((float *)&varray[offset + 3 * max_element_size], looptang[1]); - - offset += sizeof(float) * 4; - } - } - - tot_loops += 4; - } - } - } - } - else { - tot_loops += 4 * numVerts * gridFaces * gridFaces; - } - } - GPU_buffer_unlock(buffer, GPU_BINDING_ARRAY); - } - - for (a = 0; a < tot_active_mat; a++) { - int new_matnr; - int do_draw; - - new_matnr = dm->drawObject->materials[a].mat_nr; - - do_draw = setMaterial(new_matnr + 1, &gattribs); - - if (do_draw) { - if (matconv[a].numdata) { - GPU_interleaved_attrib_setup(buffer, matconv[a].datatypes, matconv[a].numdata, max_element_size); - } - GPU_buffer_draw_elements(dm->drawObject->triangles, GL_TRIANGLES, - dm->drawObject->materials[a].start, dm->drawObject->materials[a].totelements); - if (matconv[a].numdata) { - GPU_interleaved_attrib_unbind(); - } - } - } - - GPU_buffers_unbind(); - if (buffer) - GPU_buffer_free(buffer); - - MEM_freeN(mat_orig_to_new); - MEM_freeN(matconv); - } -} - -static void ccgDM_drawFacesGLSL(DerivedMesh *dm, DMSetMaterial setMaterial) -{ - dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL); -} - -/* Only used by non-editmesh types */ -static void ccgDM_drawMappedFacesMat(DerivedMesh *dm, - void (*setMaterial)(void *userData, int matnr, void *attribs), - bool (*setFace)(void *userData, int index), void *userData) -{ - CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; - CCGSubSurf *ss = ccgdm->ss; - CCGKey key; - GPUVertexAttribs gattribs; - DMVertexAttribs attribs = {{{NULL}}}; - int gridSize = ccgSubSurf_getGridSize(ss); - int gridFaces = gridSize - 1; - int edgeSize = ccgSubSurf_getEdgeSize(ss); - DMFlagMat *faceFlags = ccgdm->faceFlags; - const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL); - int a, i, numVerts, matnr, totface; - -#ifdef WITH_OPENSUBDIV - if (ccgdm->useGpuBackend) { - const int level = ccgSubSurf_getSubdivisionLevels(ss); - const int face_side = 1 << level; - const int grid_side = 1 << (level - 1); - const int face_patches = face_side * face_side; - const int grid_patches = grid_side * grid_side; - const int num_base_faces = ccgSubSurf_getNumGLMeshBaseFaces(ss); - int current_patch = 0; - int mat_nr = -1; - bool draw_smooth = false; - int start_draw_patch = -1, num_draw_patches = 0; - GPU_draw_update_fvar_offset(dm); - if (UNLIKELY(ccgSubSurf_prepareGLMesh(ss, true, -1) == false)) { - return; - } - for (i = 0; i < num_base_faces; ++i) { - const int num_face_verts = ccgSubSurf_getNumGLMeshBaseFaceVerts(ss, i); - const int num_patches = (num_face_verts == 4) ? face_patches - : num_face_verts * grid_patches; - int new_matnr; - bool new_draw_smooth; - - if (faceFlags) { - new_draw_smooth = (faceFlags[i].flag & ME_SMOOTH); - new_matnr = (faceFlags[i].mat_nr + 1); - } - else { - new_draw_smooth = true; - new_matnr = 1; - } - if (new_draw_smooth != draw_smooth || new_matnr != mat_nr) { - if (num_draw_patches != 0) { - setMaterial(userData, mat_nr, &gattribs); - glShadeModel(draw_smooth ? GL_SMOOTH : GL_FLAT); - ccgSubSurf_drawGLMesh(ss, - true, - start_draw_patch, - num_draw_patches); - } - start_draw_patch = current_patch; - num_draw_patches = num_patches; - mat_nr = new_matnr; - draw_smooth = new_draw_smooth; - } - else { - num_draw_patches += num_patches; - } - current_patch += num_patches; - } - if (num_draw_patches != 0) { - setMaterial(userData, mat_nr, &gattribs); - glShadeModel(draw_smooth ? GL_SMOOTH : GL_FLAT); - ccgSubSurf_drawGLMesh(ss, - true, - start_draw_patch, - num_draw_patches); - } - glShadeModel(GL_SMOOTH); - return; - } -#endif - - CCG_key_top_level(&key, ss); - ccgdm_pbvh_update(ccgdm); - - matnr = -1; - -#define PASSATTRIB(dx, dy, vert) { \ - if (attribs.totorco) \ - index = getFaceIndex(ss, f, S, x + dx, y + dy, edgeSize, gridSize); \ - else \ - index = 0; \ - DM_draw_attrib_vertex(&attribs, a, index, vert, ((a) * 4) + vert); \ - DM_draw_attrib_vertex_uniforms(&attribs); \ -} (void)0 - - totface = ccgSubSurf_getNumFaces(ss); - for (a = 0, i = 0; i < totface; i++) { - CCGFace *f = ccgdm->faceMap[i].face; - const float (*ln)[3] = NULL; - int S, x, y, drawSmooth; - int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f)); - int origIndex = ccgDM_getFaceMapIndex(ss, f); - int new_matnr; - - numVerts = ccgSubSurf_getFaceNumVerts(f); - - /* get flags */ - if (faceFlags) { - drawSmooth = (lnors || (faceFlags[index].flag & ME_SMOOTH)); - new_matnr = faceFlags[index].mat_nr + 1; - } - else { - drawSmooth = 1; - new_matnr = 1; - } - - if (lnors) { - ln = lnors; - lnors += (gridFaces * gridFaces * numVerts) * 4; - } - - /* material */ - if (new_matnr != matnr) { - setMaterial(userData, matnr = new_matnr, &gattribs); - DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs); - } - - /* face hiding */ - if ((setFace && (origIndex != ORIGINDEX_NONE) && !setFace(userData, origIndex))) { - a += gridFaces * gridFaces * numVerts; - continue; - } - - /* draw face*/ - glShadeModel(drawSmooth ? GL_SMOOTH : GL_FLAT); - for (S = 0; S < numVerts; S++) { - CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S); - CCGElem *vda, *vdb; - - if (ln) { - glBegin(GL_QUADS); - for (y = 0; y < gridFaces; y++) { - for (x = 0; x < gridFaces; x++) { - float *aco = CCG_grid_elem_co(&key, faceGridData, x, y + 0); - float *bco = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 0); - float *cco = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 1); - float *dco = CCG_grid_elem_co(&key, faceGridData, x, y + 1); - - PASSATTRIB(0, 1, 1); - glNormal3fv(ln[1]); - glVertex3fv(dco); - PASSATTRIB(1, 1, 2); - glNormal3fv(ln[2]); - glVertex3fv(cco); - PASSATTRIB(1, 0, 3); - glNormal3fv(ln[3]); - glVertex3fv(bco); - PASSATTRIB(0, 0, 0); - glNormal3fv(ln[0]); - glVertex3fv(aco); - - ln += 4; - a++; - } - } - glEnd(); - } - else if (drawSmooth) { - for (y = 0; y < gridFaces; y++) { - glBegin(GL_QUAD_STRIP); - for (x = 0; x < gridFaces; x++) { - vda = CCG_grid_elem(&key, faceGridData, x, y); - vdb = CCG_grid_elem(&key, faceGridData, x, y + 1); - - PASSATTRIB(0, 0, 0); - glNormal3fv(CCG_elem_no(&key, vda)); - glVertex3fv(CCG_elem_co(&key, vda)); - - PASSATTRIB(0, 1, 1); - glNormal3fv(CCG_elem_no(&key, vdb)); - glVertex3fv(CCG_elem_co(&key, vdb)); - - if (x != gridFaces - 1) - a++; - } - - vda = CCG_grid_elem(&key, faceGridData, x, y + 0); - vdb = CCG_grid_elem(&key, faceGridData, x, y + 1); - - PASSATTRIB(0, 0, 3); - glNormal3fv(CCG_elem_no(&key, vda)); - glVertex3fv(CCG_elem_co(&key, vda)); - - PASSATTRIB(0, 1, 2); - glNormal3fv(CCG_elem_no(&key, vdb)); - glVertex3fv(CCG_elem_co(&key, vdb)); - - glEnd(); - - a++; - } - } - else { - glBegin(GL_QUADS); - for (y = 0; y < gridFaces; y++) { - for (x = 0; x < gridFaces; x++) { - float *aco = CCG_grid_elem_co(&key, faceGridData, x, y + 0); - float *bco = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 0); - float *cco = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 1); - float *dco = CCG_grid_elem_co(&key, faceGridData, x, y + 1); - - ccgDM_glNormalFast(aco, bco, cco, dco); - - PASSATTRIB(0, 1, 1); - glVertex3fv(dco); - PASSATTRIB(1, 1, 2); - glVertex3fv(cco); - PASSATTRIB(1, 0, 3); - glVertex3fv(bco); - PASSATTRIB(0, 0, 0); - glVertex3fv(aco); - - a++; - } - } - glEnd(); - } - } - } - - glShadeModel(GL_SMOOTH); -#undef PASSATTRIB -} - -static void ccgDM_drawMappedFaces(DerivedMesh *dm, - DMSetDrawOptions setDrawOptions, - DMSetMaterial setMaterial, - DMCompareDrawOptions compareDrawOptions, - void *userData, DMDrawFlag flag) -{ - CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; - CCGSubSurf *ss = ccgdm->ss; - CCGKey key; - MLoopCol *mloopcol = NULL; - const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL); - int i, gridSize = ccgSubSurf_getGridSize(ss); - DMFlagMat *faceFlags = ccgdm->faceFlags; - int useColors = flag & DM_DRAW_USE_COLORS; - int gridFaces = gridSize - 1, totface; - int prev_mat_nr = -1; - - if (ccgdm->pbvh) { - if (G.debug_value == 14) - BKE_pbvh_draw_BB(ccgdm->pbvh); - } - -#ifdef WITH_OPENSUBDIV - if (ccgdm->useGpuBackend) { - int new_matnr; - bool draw_smooth, do_draw = true; - if (setDrawOptions == NULL) { - /* TODO(sergey): This is for cases when vertex colors or weights - * are visualising. Currently we don't have CD layers for this data - * and here we only make it so there's no garbage displayed. - * - * In the future we'll either need to have CD for this data or pass - * this data as face-varying or vertex-varying data in OSD mesh. - */ - glColor3f(0.8f, 0.8f, 0.8f); - } - if (UNLIKELY(ccgSubSurf_prepareGLMesh(ss, true, -1) == false)) { - return; - } - if (faceFlags) { - draw_smooth = (faceFlags[0].flag & ME_SMOOTH); - new_matnr = (faceFlags[0].mat_nr + 1); - } - else { - draw_smooth = true; - new_matnr = 1; - } - if (setMaterial) { - setMaterial(new_matnr, NULL); - } - if (setDrawOptions) { - if (setDrawOptions(userData, 0) == DM_DRAW_OPTION_SKIP) { - do_draw = false; - } - } - if (do_draw) { - glShadeModel(draw_smooth ? GL_SMOOTH : GL_FLAT); - ccgSubSurf_drawGLMesh(ss, true, -1, -1); - glShadeModel(GL_SMOOTH); - } - return; - } -#endif - - CCG_key_top_level(&key, ss); - - /* currently unused -- each original face is handled separately */ - (void)compareDrawOptions; - - if (useColors) { - mloopcol = dm->getLoopDataArray(dm, CD_PREVIEW_MLOOPCOL); - if (!mloopcol) - mloopcol = dm->getLoopDataArray(dm, CD_MLOOPCOL); - } - - totface = ccgSubSurf_getNumFaces(ss); - for (i = 0; i < totface; i++) { - CCGFace *f = ccgdm->faceMap[i].face; - int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f); - int drawSmooth, index = ccgDM_getFaceMapIndex(ss, f); - int origIndex; - unsigned char *cp = NULL; - const float (*ln)[3] = NULL; - - origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f)); - - if (flag & DM_DRAW_ALWAYS_SMOOTH) drawSmooth = 1; - else if (faceFlags) drawSmooth = (lnors || (faceFlags[origIndex].flag & ME_SMOOTH)); - else drawSmooth = 1; - - if (mloopcol) { - cp = (unsigned char *)mloopcol; - mloopcol += gridFaces * gridFaces * numVerts * 4; - } - - if (lnors) { - ln = lnors; - lnors += (gridFaces * gridFaces * numVerts) * 4; - } - - { - DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL; - - if (setMaterial) { - int mat_nr = faceFlags ? faceFlags[origIndex].mat_nr + 1 : 1; - - if (mat_nr != prev_mat_nr) { - setMaterial(mat_nr, NULL); /* XXX, no faceFlags no material */ - prev_mat_nr = mat_nr; - } - } - - if (setDrawOptions && (index != ORIGINDEX_NONE)) - draw_option = setDrawOptions(userData, index); - - if (draw_option != DM_DRAW_OPTION_SKIP) { - if (draw_option == DM_DRAW_OPTION_STIPPLE) { - GPU_basic_shader_bind(GPU_SHADER_STIPPLE | GPU_SHADER_USE_COLOR); - GPU_basic_shader_stipple(GPU_SHADER_STIPPLE_QUARTTONE); - } - - for (S = 0; S < numVerts; S++) { - CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S); - if (ln) { - glBegin(GL_QUADS); - for (y = 0; y < gridFaces; y++) { - for (x = 0; x < gridFaces; x++) { - float *a = CCG_grid_elem_co(&key, faceGridData, x, y + 0); - float *b = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 0); - float *c = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 1); - float *d = CCG_grid_elem_co(&key, faceGridData, x, y + 1); - - if (cp) glColor4ubv(&cp[4]); - glNormal3fv(ln[1]); - glVertex3fv(d); - if (cp) glColor4ubv(&cp[8]); - glNormal3fv(ln[2]); - glVertex3fv(c); - if (cp) glColor4ubv(&cp[12]); - glNormal3fv(ln[3]); - glVertex3fv(b); - if (cp) glColor4ubv(&cp[0]); - glNormal3fv(ln[0]); - glVertex3fv(a); - - if (cp) cp += 16; - ln += 4; - } - } - glEnd(); - } - else if (drawSmooth) { - for (y = 0; y < gridFaces; y++) { - CCGElem *a, *b; - glBegin(GL_QUAD_STRIP); - for (x = 0; x < gridFaces; x++) { - a = CCG_grid_elem(&key, faceGridData, x, y + 0); - b = CCG_grid_elem(&key, faceGridData, x, y + 1); - - if (cp) glColor4ubv(&cp[0]); - glNormal3fv(CCG_elem_no(&key, a)); - glVertex3fv(CCG_elem_co(&key, a)); - if (cp) glColor4ubv(&cp[4]); - glNormal3fv(CCG_elem_no(&key, b)); - glVertex3fv(CCG_elem_co(&key, b)); - - if (x != gridFaces - 1) { - if (cp) cp += 16; - } - } - - a = CCG_grid_elem(&key, faceGridData, x, y + 0); - b = CCG_grid_elem(&key, faceGridData, x, y + 1); - - if (cp) glColor4ubv(&cp[12]); - glNormal3fv(CCG_elem_no(&key, a)); - glVertex3fv(CCG_elem_co(&key, a)); - if (cp) glColor4ubv(&cp[8]); - glNormal3fv(CCG_elem_no(&key, b)); - glVertex3fv(CCG_elem_co(&key, b)); - - if (cp) cp += 16; - - glEnd(); - } - } - else { - glBegin(GL_QUADS); - for (y = 0; y < gridFaces; y++) { - for (x = 0; x < gridFaces; x++) { - float *a = CCG_grid_elem_co(&key, faceGridData, x, y + 0); - float *b = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 0); - float *c = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 1); - float *d = CCG_grid_elem_co(&key, faceGridData, x, y + 1); - - ccgDM_glNormalFast(a, b, c, d); - - if (cp) glColor4ubv(&cp[4]); - glVertex3fv(d); - if (cp) glColor4ubv(&cp[8]); - glVertex3fv(c); - if (cp) glColor4ubv(&cp[12]); - glVertex3fv(b); - if (cp) glColor4ubv(&cp[0]); - glVertex3fv(a); - - if (cp) cp += 16; - } - } - glEnd(); - } - } - if (draw_option == DM_DRAW_OPTION_STIPPLE) - GPU_basic_shader_bind(GPU_SHADER_USE_COLOR); - } - } - } -} - -static void ccgDM_drawMappedEdges(DerivedMesh *dm, - DMSetDrawOptions setDrawOptions, - void *userData) -{ - CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; - CCGSubSurf *ss = ccgdm->ss; - CCGEdgeIterator ei; - CCGKey key; - int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss); - -#ifdef WITH_OPENSUBDIV - if (ccgdm->useGpuBackend) { - /* TODO(sergey): Only draw edges from base mesh. */ - if (ccgSubSurf_prepareGLMesh(ccgdm->ss, true, -1)) { - if (!setDrawOptions || (setDrawOptions(userData, 0) != DM_DRAW_OPTION_SKIP)) { - ccgSubSurf_drawGLMesh(ccgdm->ss, false, -1, -1); - } - } - return; - } -#endif - - CCG_key_top_level(&key, ss); - ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL); - - for (ccgSubSurf_initEdgeIterator(ss, &ei); !ccgEdgeIterator_isStopped(&ei); ccgEdgeIterator_next(&ei)) { - CCGEdge *e = ccgEdgeIterator_getCurrent(&ei); - CCGElem *edgeData = ccgSubSurf_getEdgeDataArray(ss, e); - int index = ccgDM_getEdgeMapIndex(ss, e); - - glBegin(GL_LINE_STRIP); - if (index != -1 && (!setDrawOptions || (setDrawOptions(userData, index) != DM_DRAW_OPTION_SKIP))) { - if (useAging && !(G.f & G_BACKBUFSEL)) { - int ageCol = 255 - ccgSubSurf_getEdgeAge(ss, e) * 4; - glColor3ub(0, ageCol > 0 ? ageCol : 0, 0); - } - - for (i = 0; i < edgeSize - 1; i++) { - glVertex3fv(CCG_elem_offset_co(&key, edgeData, i)); - glVertex3fv(CCG_elem_offset_co(&key, edgeData, i + 1)); - } - } - glEnd(); - } -} - -static void ccgDM_drawMappedEdgesInterp(DerivedMesh *dm, - DMSetDrawOptions setDrawOptions, - DMSetDrawInterpOptions setDrawInterpOptions, - void *userData) -{ - CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; - CCGSubSurf *ss = ccgdm->ss; - CCGKey key; - CCGEdgeIterator ei; - int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss); - -#ifdef WITH_OPENSUBDIV - if (ccgdm->useGpuBackend) { - BLI_assert(!"Not currently supported"); - return; - } -#endif - - CCG_key_top_level(&key, ss); - ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL); - - for (ccgSubSurf_initEdgeIterator(ss, &ei); !ccgEdgeIterator_isStopped(&ei); ccgEdgeIterator_next(&ei)) { - CCGEdge *e = ccgEdgeIterator_getCurrent(&ei); - CCGElem *edgeData = ccgSubSurf_getEdgeDataArray(ss, e); - int index = ccgDM_getEdgeMapIndex(ss, e); - - glBegin(GL_LINE_STRIP); - if (index != -1 && (!setDrawOptions || (setDrawOptions(userData, index) != DM_DRAW_OPTION_SKIP))) { - for (i = 0; i < edgeSize; i++) { - setDrawInterpOptions(userData, index, (float) i / (edgeSize - 1)); - - if (useAging && !(G.f & G_BACKBUFSEL)) { - int ageCol = 255 - ccgSubSurf_getEdgeAge(ss, e) * 4; - glColor3ub(0, ageCol > 0 ? ageCol : 0, 0); - } - - glVertex3fv(CCG_elem_offset_co(&key, edgeData, i)); - } - } - glEnd(); - } -} - static void ccgDM_foreachMappedFaceCenter( DerivedMesh *dm, void (*func)(void *userData, int index, const float co[3], const float no[3]), @@ -4433,20 +2468,6 @@ static void set_default_ccgdm_callbacks(CCGDerivedMesh *ccgdm) ccgdm->dm.foreachMappedLoop = ccgDM_foreachMappedLoop; ccgdm->dm.foreachMappedFaceCenter = ccgDM_foreachMappedFaceCenter; - ccgdm->dm.drawVerts = ccgDM_drawVerts; - ccgdm->dm.drawEdges = ccgDM_drawEdges; - ccgdm->dm.drawLooseEdges = ccgDM_drawLooseEdges; - ccgdm->dm.drawFacesSolid = ccgDM_drawFacesSolid; - ccgdm->dm.drawFacesGLSL = ccgDM_drawFacesGLSL; - ccgdm->dm.drawMappedFaces = ccgDM_drawMappedFaces; - ccgdm->dm.drawMappedFacesGLSL = ccgDM_drawMappedFacesGLSL; - ccgdm->dm.drawMappedFacesMat = ccgDM_drawMappedFacesMat; - - ccgdm->dm.drawMappedEdgesInterp = ccgDM_drawMappedEdgesInterp; - ccgdm->dm.drawMappedEdges = ccgDM_drawMappedEdges; - ccgdm->dm.gpuObjectNew = ccgDM_GPUObjectNew; - ccgdm->dm.copy_gpu_data = ccgDM_copy_gpu_data; - ccgdm->dm.release = ccgDM_release; } diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c index 250408642bb..2bf2fa7807b 100644 --- a/source/blender/blenkernel/intern/texture.c +++ b/source/blender/blenkernel/intern/texture.c @@ -44,9 +44,7 @@ #include "DNA_key_types.h" #include "DNA_object_types.h" -#include "DNA_lamp_types.h" #include "DNA_material_types.h" -#include "DNA_world_types.h" #include "DNA_brush_types.h" #include "DNA_node_types.h" #include "DNA_color_types.h" @@ -213,22 +211,6 @@ void BKE_texture_free(Tex *tex) } MEM_SAFE_FREE(tex->coba); - if (tex->env) { - BKE_texture_envmap_free(tex->env); - tex->env = NULL; - } - if (tex->pd) { - BKE_texture_pointdensity_free(tex->pd); - tex->pd = NULL; - } - if (tex->vd) { - BKE_texture_voxeldata_free(tex->vd); - tex->vd = NULL; - } - if (tex->ot) { - BKE_texture_ocean_free(tex->ot); - tex->ot = NULL; - } BKE_icon_id_delete((ID *)tex); BKE_previewimg_free(&tex->preview); @@ -285,30 +267,6 @@ void BKE_texture_default(Tex *tex) tex->vn_distm = 0; tex->vn_coltype = 0; - if (tex->env) { - tex->env->stype = ENV_ANIM; - tex->env->clipsta = 0.1; - tex->env->clipend = 100; - tex->env->cuberes = 512; - tex->env->depth = 0; - } - - if (tex->pd) { - tex->pd->radius = 0.3f; - tex->pd->falloff_type = TEX_PD_FALLOFF_STD; - } - - if (tex->vd) { - tex->vd->resol[0] = tex->vd->resol[1] = tex->vd->resol[2] = 0; - tex->vd->interp_type = TEX_VD_LINEAR; - tex->vd->file_format = TEX_VD_SMOKE; - } - - if (tex->ot) { - tex->ot->output = TEX_OCN_DISPLACEMENT; - tex->ot->object = NULL; - } - tex->iuser.fie_ima = 2; tex->iuser.ok = 1; tex->iuser.frames = 100; @@ -319,26 +277,6 @@ void BKE_texture_default(Tex *tex) void BKE_texture_type_set(Tex *tex, int type) { - switch (type) { - - case TEX_VOXELDATA: - if (tex->vd == NULL) - tex->vd = BKE_texture_voxeldata_add(); - break; - case TEX_POINTDENSITY: - if (tex->pd == NULL) - tex->pd = BKE_texture_pointdensity_add(); - break; - case TEX_ENVMAP: - if (tex->env == NULL) - tex->env = BKE_texture_envmap_add(); - break; - case TEX_OCEAN: - if (tex->ot == NULL) - tex->ot = BKE_texture_ocean_add(); - break; - } - tex->type = type; } @@ -476,10 +414,6 @@ MTex *BKE_texture_mtex_add_id(ID *id, int slot) MEM_freeN(mtex_ar[slot]); mtex_ar[slot] = NULL; } - else if (GS(id->name) == ID_MA) { - /* Reset this slot's ON/OFF toggle, for materials, when slot was empty. */ - ((Material *)id)->septex &= ~(1 << slot); - } mtex_ar[slot] = BKE_texture_mtex_add(); @@ -498,9 +432,6 @@ MTex *BKE_texture_mtex_add_id(ID *id, int slot) */ void BKE_texture_copy_data(Main *bmain, Tex *tex_dst, const Tex *tex_src, const int flag) { - /* We never handle usercount here for own data. */ - const int flag_subdata = flag | LIB_ID_CREATE_NO_USER_REFCOUNT; - if (!BKE_texture_is_image_user(tex_src)) { tex_dst->ima = NULL; } @@ -508,19 +439,6 @@ void BKE_texture_copy_data(Main *bmain, Tex *tex_dst, const Tex *tex_src, const if (tex_dst->coba) { tex_dst->coba = MEM_dupallocN(tex_dst->coba); } - if (tex_dst->env) { - tex_dst->env = BKE_texture_envmap_copy(tex_dst->env, flag_subdata); - } - if (tex_dst->pd) { - tex_dst->pd = BKE_texture_pointdensity_copy(tex_dst->pd, flag_subdata); - } - if (tex_dst->vd) { - tex_dst->vd = MEM_dupallocN(tex_dst->vd); - } - if (tex_dst->ot) { - tex_dst->ot = BKE_texture_ocean_copy(tex_dst->ot, flag_subdata); - } - if (tex_src->nodetree) { if (tex_src->nodetree->execdata) { ntreeTexEndExecTree(tex_src->nodetree->execdata); @@ -562,19 +480,6 @@ Tex *BKE_texture_localize(Tex *tex) /* image texture: BKE_texture_free also doesn't decrease */ if (texn->coba) texn->coba = MEM_dupallocN(texn->coba); - if (texn->env) { - texn->env = BKE_texture_envmap_copy(texn->env, LIB_ID_CREATE_NO_USER_REFCOUNT); - id_us_min(&texn->env->ima->id); - } - if (texn->pd) texn->pd = BKE_texture_pointdensity_copy(texn->pd, LIB_ID_CREATE_NO_USER_REFCOUNT); - if (texn->vd) { - texn->vd = MEM_dupallocN(texn->vd); - if (texn->vd->dataset) - texn->vd->dataset = MEM_dupallocN(texn->vd->dataset); - } - if (texn->ot) { - texn->ot = BKE_texture_ocean_copy(tex->ot, LIB_ID_CREATE_NO_USER_REFCOUNT); - } texn->preview = NULL; @@ -593,64 +498,6 @@ void BKE_texture_make_local(Main *bmain, Tex *tex, const bool lib_local) BKE_id_make_local_generic(bmain, &tex->id, true, lib_local); } -Tex *give_current_object_texture(Object *ob) -{ - Material *ma, *node_ma; - Tex *tex = NULL; - - if (ob == NULL) return NULL; - if (ob->totcol == 0 && !(ob->type == OB_LAMP)) return NULL; - - if (ob->type == OB_LAMP) { - tex = give_current_lamp_texture(ob->data); - } - else { - ma = give_current_material(ob, ob->actcol); - - if ((node_ma = give_node_material(ma))) - ma = node_ma; - - tex = give_current_material_texture(ma); - } - - return tex; -} - -Tex *give_current_lamp_texture(Lamp *la) -{ - MTex *mtex = NULL; - Tex *tex = NULL; - - if (la) { - mtex = la->mtex[(int)(la->texact)]; - if (mtex) tex = mtex->tex; - } - - return tex; -} - -void set_current_lamp_texture(Lamp *la, Tex *newtex) -{ - int act = la->texact; - - if (la->mtex[act] && la->mtex[act]->tex) - id_us_min(&la->mtex[act]->tex->id); - - if (newtex) { - if (!la->mtex[act]) { - la->mtex[act] = BKE_texture_mtex_add(); - la->mtex[act]->texco = TEXCO_GLOB; - } - - la->mtex[act]->tex = newtex; - id_us_plus(&newtex->id); - } - else if (la->mtex[act]) { - MEM_freeN(la->mtex[act]); - la->mtex[act] = NULL; - } -} - Tex *give_current_linestyle_texture(FreestyleLineStyle *linestyle) { MTex *mtex = NULL; @@ -686,55 +533,9 @@ void set_current_linestyle_texture(FreestyleLineStyle *linestyle, Tex *newtex) } } -bNode *give_current_material_texture_node(Material *ma) -{ - if (ma && ma->use_nodes && ma->nodetree) - return nodeGetActiveID(ma->nodetree, ID_TE); - - return NULL; -} - -Tex *give_current_material_texture(Material *ma) -{ - MTex *mtex = NULL; - Tex *tex = NULL; - bNode *node; - - if (ma && ma->use_nodes && ma->nodetree) { - /* first check texture, then material, this works together - * with a hack that clears the active ID flag for textures on - * making a material node active */ - node = nodeGetActiveID(ma->nodetree, ID_TE); - - if (node) { - tex = (Tex *)node->id; - ma = NULL; - } - } - - if (ma) { - mtex = ma->mtex[(int)(ma->texact)]; - if (mtex) tex = mtex->tex; - } - - return tex; -} - bool give_active_mtex(ID *id, MTex ***mtex_ar, short *act) { switch (GS(id->name)) { - case ID_MA: - *mtex_ar = ((Material *)id)->mtex; - if (act) *act = (((Material *)id)->texact); - break; - case ID_WO: - *mtex_ar = ((World *)id)->mtex; - if (act) *act = (((World *)id)->texact); - break; - case ID_LA: - *mtex_ar = ((Lamp *)id)->mtex; - if (act) *act = (((Lamp *)id)->texact); - break; case ID_LS: *mtex_ar = ((FreestyleLineStyle *)id)->mtex; if (act) *act = (((FreestyleLineStyle *)id)->texact); @@ -758,15 +559,6 @@ void set_active_mtex(ID *id, short act) else if (act >= MAX_MTEX) act = MAX_MTEX - 1; switch (GS(id->name)) { - case ID_MA: - ((Material *)id)->texact = act; - break; - case ID_WO: - ((World *)id)->texact = act; - break; - case ID_LA: - ((Lamp *)id)->texact = act; - break; case ID_LS: ((FreestyleLineStyle *)id)->texact = act; break; @@ -778,100 +570,6 @@ void set_active_mtex(ID *id, short act) } } -void set_current_material_texture(Material *ma, Tex *newtex) -{ - Tex *tex = NULL; - bNode *node; - - if ((ma->use_nodes && ma->nodetree) && - (node = nodeGetActiveID(ma->nodetree, ID_TE))) - { - tex = (Tex *)node->id; - id_us_min(&tex->id); - if (newtex) { - node->id = &newtex->id; - id_us_plus(&newtex->id); - } - else { - node->id = NULL; - } - } - else { - int act = (int)ma->texact; - - tex = (ma->mtex[act]) ? ma->mtex[act]->tex : NULL; - id_us_min(&tex->id); - - if (newtex) { - if (!ma->mtex[act]) { - ma->mtex[act] = BKE_texture_mtex_add(); - /* Reset this slot's ON/OFF toggle, for materials, when slot was empty. */ - ma->septex &= ~(1 << act); - /* For volumes the default UV texture coordinates are not available. */ - if (ma->material_type == MA_TYPE_VOLUME) { - ma->mtex[act]->texco = TEXCO_ORCO; - } - } - - ma->mtex[act]->tex = newtex; - id_us_plus(&newtex->id); - } - else if (ma->mtex[act]) { - MEM_freeN(ma->mtex[act]); - ma->mtex[act] = NULL; - } - } -} - -bool has_current_material_texture(Material *ma) -{ - bNode *node; - - if (ma && ma->use_nodes && ma->nodetree) { - node = nodeGetActiveID(ma->nodetree, ID_TE); - - if (node) - return true; - } - - return (ma != NULL); -} - -Tex *give_current_world_texture(World *world) -{ - MTex *mtex = NULL; - Tex *tex = NULL; - - if (!world) return NULL; - - mtex = world->mtex[(int)(world->texact)]; - if (mtex) tex = mtex->tex; - - return tex; -} - -void set_current_world_texture(World *wo, Tex *newtex) -{ - int act = wo->texact; - - if (wo->mtex[act] && wo->mtex[act]->tex) - id_us_min(&wo->mtex[act]->tex->id); - - if (newtex) { - if (!wo->mtex[act]) { - wo->mtex[act] = BKE_texture_mtex_add(); - wo->mtex[act]->texco = TEXCO_VIEW; - } - - wo->mtex[act]->tex = newtex; - id_us_plus(&newtex->id); - } - else if (wo->mtex[act]) { - MEM_freeN(wo->mtex[act]); - wo->mtex[act] = NULL; - } -} - Tex *give_current_brush_texture(Brush *br) { return br->mtex.tex; @@ -926,65 +624,6 @@ void set_current_particle_texture(ParticleSettings *part, Tex *newtex) /* ------------------------------------------------------------------------- */ -EnvMap *BKE_texture_envmap_add(void) -{ - EnvMap *env; - - env = MEM_callocN(sizeof(EnvMap), "envmap"); - env->type = ENV_CUBE; - env->stype = ENV_ANIM; - env->clipsta = 0.1; - env->clipend = 100.0; - env->cuberes = 512; - env->viewscale = 0.5; - - return env; -} - -/* ------------------------------------------------------------------------- */ - -EnvMap *BKE_texture_envmap_copy(const EnvMap *env, const int flag) -{ - EnvMap *envn; - int a; - - envn = MEM_dupallocN(env); - envn->ok = 0; - for (a = 0; a < 6; a++) { - envn->cube[a] = NULL; - } - if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) { - id_us_plus((ID *)envn->ima); - } - - return envn; -} - -/* ------------------------------------------------------------------------- */ - -void BKE_texture_envmap_free_data(EnvMap *env) -{ - unsigned int part; - - for (part = 0; part < 6; part++) { - if (env->cube[part]) - IMB_freeImBuf(env->cube[part]); - env->cube[part] = NULL; - } - env->ok = 0; -} - -/* ------------------------------------------------------------------------- */ - -void BKE_texture_envmap_free(EnvMap *env) -{ - - BKE_texture_envmap_free_data(env); - MEM_freeN(env); - -} - -/* ------------------------------------------------------------------------- */ void BKE_texture_pointdensity_init_data(PointDensity *pd) { @@ -1057,77 +696,8 @@ void BKE_texture_pointdensity_free(PointDensity *pd) BKE_texture_pointdensity_free_data(pd); MEM_freeN(pd); } - /* ------------------------------------------------------------------------- */ -void BKE_texture_voxeldata_free_data(VoxelData *vd) -{ - if (vd->dataset) { - MEM_freeN(vd->dataset); - vd->dataset = NULL; - } - -} - -void BKE_texture_voxeldata_free(VoxelData *vd) -{ - BKE_texture_voxeldata_free_data(vd); - MEM_freeN(vd); -} - -VoxelData *BKE_texture_voxeldata_add(void) -{ - VoxelData *vd; - - vd = MEM_callocN(sizeof(VoxelData), "voxeldata"); - vd->dataset = NULL; - vd->resol[0] = vd->resol[1] = vd->resol[2] = 1; - vd->interp_type = TEX_VD_LINEAR; - vd->file_format = TEX_VD_SMOKE; - vd->int_multiplier = 1.0; - vd->extend = TEX_CLIP; - vd->object = NULL; - vd->cachedframe = -1; - vd->ok = 0; - - return vd; -} - -VoxelData *BKE_texture_voxeldata_copy(VoxelData *vd) -{ - VoxelData *vdn; - - vdn = MEM_dupallocN(vd); - vdn->dataset = NULL; - - return vdn; -} - -/* ------------------------------------------------------------------------- */ - -OceanTex *BKE_texture_ocean_add(void) -{ - OceanTex *ot; - - ot = MEM_callocN(sizeof(struct OceanTex), "ocean texture"); - ot->output = TEX_OCN_DISPLACEMENT; - ot->object = NULL; - - return ot; -} - -OceanTex *BKE_texture_ocean_copy(const OceanTex *ot, const int UNUSED(flag)) -{ - OceanTex *otn = MEM_dupallocN(ot); - - return otn; -} - -void BKE_texture_ocean_free(struct OceanTex *ot) -{ - MEM_freeN(ot); -} - /** * \returns true if this texture can use its #Texture.ima (even if its NULL) */ @@ -1138,15 +708,6 @@ bool BKE_texture_is_image_user(const struct Tex *tex) { return true; } - case TEX_ENVMAP: - { - if (tex->env) { - if (tex->env->stype == ENV_LOAD) { - return true; - } - } - break; - } } return false; diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c index 167ee6b4018..15bf01d2049 100644 --- a/source/blender/blenkernel/intern/world.c +++ b/source/blender/blenkernel/intern/world.c @@ -58,14 +58,8 @@ /** Free (or release) any data used by this world (does not free the world itself). */ void BKE_world_free(World *wrld) { - int a; - BKE_animdata_free((ID *)wrld, false); - for (a = 0; a < MAX_MTEX; a++) { - MEM_SAFE_FREE(wrld->mtex[a]); - } - /* is no lib link block, but world extension */ if (wrld->nodetree) { ntreeFreeTree(wrld->nodetree); @@ -86,23 +80,9 @@ void BKE_world_init(World *wrld) wrld->horr = 0.05f; wrld->horg = 0.05f; wrld->horb = 0.05f; - wrld->zenr = 0.01f; - wrld->zeng = 0.01f; - wrld->zenb = 0.01f; - wrld->skytype = 0; - - wrld->exp = 0.0f; - wrld->exposure = wrld->range = 1.0f; wrld->aodist = 10.0f; - wrld->aosamp = 5; wrld->aoenergy = 1.0f; - wrld->ao_env_energy = 1.0f; - wrld->ao_indirect_energy = 1.0f; - wrld->ao_indirect_bounces = 1; - wrld->aobias = 0.05f; - wrld->ao_samp_method = WO_AOSAMP_HAMMERSLEY; - wrld->ao_approx_error = 0.25f; wrld->preview = NULL; wrld->miststa = 5.0f; @@ -130,12 +110,6 @@ World *BKE_world_add(Main *bmain, const char *name) */ void BKE_world_copy_data(Main *bmain, World *wrld_dst, const World *wrld_src, const int flag) { - for (int a = 0; a < MAX_MTEX; a++) { - if (wrld_src->mtex[a]) { - wrld_dst->mtex[a] = MEM_dupallocN(wrld_src->mtex[a]); - } - } - if (wrld_src->nodetree) { /* Note: nodetree is *not* in bmain, however this specific case is handled at lower level * (see BKE_libblock_copy_ex()). */ @@ -169,17 +143,9 @@ World *BKE_world_localize(World *wrld) * ... Once f*** nodes are fully converted to that too :( */ World *wrldn; - int a; wrldn = BKE_libblock_copy_nolib(&wrld->id, false); - for (a = 0; a < MAX_MTEX; a++) { - if (wrld->mtex[a]) { - wrldn->mtex[a] = MEM_mallocN(sizeof(MTex), __func__); - memcpy(wrldn->mtex[a], wrld->mtex[a], sizeof(MTex)); - } - } - if (wrld->nodetree) wrldn->nodetree = ntreeLocalize(wrld->nodetree); diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c index 0a2527bafd2..39174620961 100644 --- a/source/blender/blenkernel/intern/writeffmpeg.c +++ b/source/blender/blenkernel/intern/writeffmpeg.c @@ -326,10 +326,6 @@ static int write_video_frame(FFMpegContext *context, RenderData *rd, int cfra, A frame->pts = cfra; - if (rd->mode & R_FIELDS) { - frame->top_field_first = ((rd->mode & R_ODDFIELD) != 0); - } - ret = avcodec_encode_video2(c, &packet, frame, &got_output); if (ret >= 0 && got_output) { @@ -685,13 +681,6 @@ static AVStream *alloc_video_stream(FFMpegContext *context, RenderData *rd, int c->flags |= CODEC_FLAG_GLOBAL_HEADER; } - /* Determine whether we are encoding interlaced material or not */ - if (rd->mode & R_FIELDS) { - PRINT("Encoding interlaced video\n"); - c->flags |= CODEC_FLAG_INTERLACED_DCT; - c->flags |= CODEC_FLAG_INTERLACED_ME; - } - /* xasp & yasp got float lately... */ st->sample_aspect_ratio = c->sample_aspect_ratio = av_d2q(((double) rd->xasp / (double) rd->yasp), 255); diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 4ec4f43fb1e..82994eb0bc4 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -3614,14 +3614,6 @@ static void lib_link_lamp(FileData *fd, Main *main) IDP_LibLinkProperty(la->id.properties, fd); lib_link_animdata(fd, &la->id, la->adt); - for (int a = 0; a < MAX_MTEX; a++) { - MTex *mtex = la->mtex[a]; - if (mtex) { - mtex->tex = newlibadr_us(fd, la->id.lib, mtex->tex); - mtex->object = newlibadr(fd, la->id.lib, mtex->object); - } - } - la->ipo = newlibadr_us(fd, la->id.lib, la->ipo); // XXX deprecated - old animation system if (la->nodetree) { @@ -3636,15 +3628,9 @@ static void lib_link_lamp(FileData *fd, Main *main) static void direct_link_lamp(FileData *fd, Lamp *la) { - int a; - la->adt = newdataadr(fd, la->adt); direct_link_animdata(fd, la->adt); - for (a=0; a<MAX_MTEX; a++) { - la->mtex[a] = newdataadr(fd, la->mtex[a]); - } - la->curfalloff = newdataadr(fd, la->curfalloff); if (la->curfalloff) direct_link_curvemapping(fd, la->curfalloff); @@ -3783,14 +3769,6 @@ static void lib_link_world(FileData *fd, Main *main) wrld->ipo = newlibadr_us(fd, wrld->id.lib, wrld->ipo); // XXX deprecated - old animation system - for (int a = 0; a < MAX_MTEX; a++) { - MTex *mtex = wrld->mtex[a]; - if (mtex) { - mtex->tex = newlibadr_us(fd, wrld->id.lib, mtex->tex); - mtex->object = newlibadr(fd, wrld->id.lib, mtex->object); - } - } - if (wrld->nodetree) { lib_link_ntree(fd, &wrld->id, wrld->nodetree); wrld->nodetree->id.lib = wrld->id.lib; @@ -3803,15 +3781,9 @@ static void lib_link_world(FileData *fd, Main *main) static void direct_link_world(FileData *fd, World *wrld) { - int a; - wrld->adt = newdataadr(fd, wrld->adt); direct_link_animdata(fd, wrld->adt); - for (a = 0; a < MAX_MTEX; a++) { - wrld->mtex[a] = newdataadr(fd, wrld->mtex[a]); - } - wrld->nodetree = newdataadr(fd, wrld->nodetree); if (wrld->nodetree) { direct_link_id(fd, &wrld->nodetree->id); @@ -4063,14 +4035,6 @@ static void lib_link_texture(FileData *fd, Main *main) tex->ima = newlibadr_us(fd, tex->id.lib, tex->ima); tex->ipo = newlibadr_us(fd, tex->id.lib, tex->ipo); // XXX deprecated - old animation system - if (tex->env) - tex->env->object = newlibadr(fd, tex->id.lib, tex->env->object); - if (tex->pd) - tex->pd->object = newlibadr(fd, tex->id.lib, tex->pd->object); - if (tex->vd) - tex->vd->object = newlibadr(fd, tex->id.lib, tex->vd->object); - if (tex->ot) - tex->ot->object = newlibadr(fd, tex->id.lib, tex->ot->object); if (tex->nodetree) { lib_link_ntree(fd, &tex->id, tex->nodetree); @@ -4088,35 +4052,7 @@ static void direct_link_texture(FileData *fd, Tex *tex) direct_link_animdata(fd, tex->adt); tex->coba = newdataadr(fd, tex->coba); - tex->env = newdataadr(fd, tex->env); - if (tex->env) { - tex->env->ima = NULL; - memset(tex->env->cube, 0, 6 * sizeof(void *)); - tex->env->ok= 0; - } - tex->pd = newdataadr(fd, tex->pd); - if (tex->pd) { - tex->pd->point_tree = NULL; - tex->pd->coba = newdataadr(fd, tex->pd->coba); - tex->pd->falloff_curve = newdataadr(fd, tex->pd->falloff_curve); - if (tex->pd->falloff_curve) { - direct_link_curvemapping(fd, tex->pd->falloff_curve); - } - tex->pd->point_data = NULL; /* runtime data */ - } - - tex->vd = newdataadr(fd, tex->vd); - if (tex->vd) { - tex->vd->dataset = NULL; - tex->vd->ok = 0; - } - else { - if (tex->type == TEX_VOXELDATA) - tex->vd = MEM_callocN(sizeof(VoxelData), "direct_link_texture VoxelData"); - } - - tex->ot = newdataadr(fd, tex->ot); - + tex->nodetree = newdataadr(fd, tex->nodetree); if (tex->nodetree) { direct_link_id(fd, &tex->nodetree->id); @@ -4140,15 +4076,6 @@ static void lib_link_material(FileData *fd, Main *main) lib_link_animdata(fd, &ma->id, ma->adt); ma->ipo = newlibadr_us(fd, ma->id.lib, ma->ipo); // XXX deprecated - old animation system - ma->group = newlibadr_us(fd, ma->id.lib, ma->group); - - for (int a = 0; a < MAX_MTEX; a++) { - MTex *mtex = ma->mtex[a]; - if (mtex) { - mtex->tex = newlibadr_us(fd, ma->id.lib, mtex->tex); - mtex->object = newlibadr(fd, ma->id.lib, mtex->object); - } - } if (ma->nodetree) { lib_link_ntree(fd, &ma->id, ma->nodetree); @@ -4162,18 +4089,10 @@ static void lib_link_material(FileData *fd, Main *main) static void direct_link_material(FileData *fd, Material *ma) { - int a; - ma->adt = newdataadr(fd, ma->adt); direct_link_animdata(fd, ma->adt); - for (a = 0; a < MAX_MTEX; a++) { - ma->mtex[a] = newdataadr(fd, ma->mtex[a]); - } ma->texpaintslot = NULL; - - ma->ramp_col = newdataadr(fd, ma->ramp_col); - ma->ramp_spec = newdataadr(fd, ma->ramp_spec); ma->nodetree = newdataadr(fd, ma->nodetree); if (ma->nodetree) { @@ -9383,15 +9302,6 @@ static void expand_brush(FileData *fd, Main *mainvar, Brush *brush) static void expand_material(FileData *fd, Main *mainvar, Material *ma) { - int a; - - for (a = 0; a < MAX_MTEX; a++) { - if (ma->mtex[a]) { - expand_doit(fd, mainvar, ma->mtex[a]->tex); - expand_doit(fd, mainvar, ma->mtex[a]->object); - } - } - expand_doit(fd, mainvar, ma->ipo); // XXX deprecated - old animation system if (ma->adt) @@ -9399,26 +9309,10 @@ static void expand_material(FileData *fd, Main *mainvar, Material *ma) if (ma->nodetree) expand_nodetree(fd, mainvar, ma->nodetree); - - if (ma->group) - expand_doit(fd, mainvar, ma->group); - - if (ma->edit_image) { - expand_doit(fd, mainvar, ma->edit_image); - } } static void expand_lamp(FileData *fd, Main *mainvar, Lamp *la) { - int a; - - for (a = 0; a < MAX_MTEX; a++) { - if (la->mtex[a]) { - expand_doit(fd, mainvar, la->mtex[a]->tex); - expand_doit(fd, mainvar, la->mtex[a]->object); - } - } - expand_doit(fd, mainvar, la->ipo); // XXX deprecated - old animation system if (la->adt) @@ -9440,15 +9334,6 @@ static void expand_lattice(FileData *fd, Main *mainvar, Lattice *lt) static void expand_world(FileData *fd, Main *mainvar, World *wrld) { - int a; - - for (a = 0; a < MAX_MTEX; a++) { - if (wrld->mtex[a]) { - expand_doit(fd, mainvar, wrld->mtex[a]->tex); - expand_doit(fd, mainvar, wrld->mtex[a]->object); - } - } - expand_doit(fd, mainvar, wrld->ipo); // XXX deprecated - old animation system if (wrld->adt) diff --git a/source/blender/blenloader/intern/versioning_250.c b/source/blender/blenloader/intern/versioning_250.c index e7f448f6a86..cc8073c67a7 100644 --- a/source/blender/blenloader/intern/versioning_250.c +++ b/source/blender/blenloader/intern/versioning_250.c @@ -515,70 +515,6 @@ static void do_versions_gpencil_2_50(Main *main, bScreen *screen) } } -static void do_version_mtex_factor_2_50(MTex **mtex_array, short idtype) -{ - MTex *mtex; - float varfac, colfac; - int a, neg; - - if (!mtex_array) - return; - - for (a = 0; a < MAX_MTEX; a++) { - if (mtex_array[a]) { - mtex = mtex_array[a]; - - neg = mtex->maptoneg; - varfac = mtex->varfac; - colfac = mtex->colfac; - - if (neg & MAP_DISP) mtex->dispfac = -mtex->dispfac; - if (neg & MAP_NORM) mtex->norfac = -mtex->norfac; - if (neg & MAP_WARP) mtex->warpfac = -mtex->warpfac; - - mtex->colspecfac = (neg & MAP_COLSPEC)? -colfac: colfac; - mtex->mirrfac = (neg & MAP_COLMIR)? -colfac: colfac; - mtex->alphafac = (neg & MAP_ALPHA)? -varfac: varfac; - mtex->difffac = (neg & MAP_REF)? -varfac: varfac; - mtex->specfac = (neg & MAP_SPEC)? -varfac: varfac; - mtex->emitfac = (neg & MAP_EMIT)? -varfac: varfac; - mtex->hardfac = (neg & MAP_HAR)? -varfac: varfac; - mtex->raymirrfac = (neg & MAP_RAYMIRR)? -varfac: varfac; - mtex->translfac = (neg & MAP_TRANSLU)? -varfac: varfac; - mtex->ambfac = (neg & MAP_AMB)? -varfac: varfac; - mtex->colemitfac = (neg & MAP_EMISSION_COL)? -colfac: colfac; - mtex->colreflfac = (neg & MAP_REFLECTION_COL)? -colfac: colfac; - mtex->coltransfac = (neg & MAP_TRANSMISSION_COL)? -colfac: colfac; - mtex->densfac = (neg & MAP_DENSITY)? -varfac: varfac; - mtex->scatterfac = (neg & MAP_SCATTERING)? -varfac: varfac; - mtex->reflfac = (neg & MAP_REFLECTION)? -varfac: varfac; - - mtex->timefac = (neg & MAP_PA_TIME)? -varfac: varfac; - mtex->lengthfac = (neg & MAP_PA_LENGTH)? -varfac: varfac; - mtex->clumpfac = (neg & MAP_PA_CLUMP)? -varfac: varfac; - mtex->kinkfac = (neg & MAP_PA_KINK)? -varfac: varfac; - mtex->roughfac = (neg & MAP_PA_ROUGH)? -varfac: varfac; - mtex->padensfac = (neg & MAP_PA_DENS)? -varfac: varfac; - mtex->lifefac = (neg & MAP_PA_LIFE)? -varfac: varfac; - mtex->sizefac = (neg & MAP_PA_SIZE)? -varfac: varfac; - mtex->ivelfac = (neg & MAP_PA_IVEL)? -varfac: varfac; - - mtex->shadowfac = (neg & LAMAP_SHAD)? -colfac: colfac; - - mtex->zenupfac = (neg & WOMAP_ZENUP)? -colfac: colfac; - mtex->zendownfac = (neg & WOMAP_ZENDOWN)? -colfac: colfac; - mtex->blendfac = (neg & WOMAP_BLEND)? -varfac: varfac; - - if (idtype == ID_MA) - mtex->colfac = (neg & MAP_COL)? -colfac: colfac; - else if (idtype == ID_LA) - mtex->colfac = (neg & LAMAP_COL)? -colfac: colfac; - else if (idtype == ID_WO) - mtex->colfac = (neg & WOMAP_HORIZ)? -colfac: colfac; - } - } -} - static void do_version_mdef_250(Main *main) { Object *ob; @@ -742,7 +678,6 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main) bSound *sound; Sequence *seq; - int a; for (sound = main->sound.first; sound; sound = sound->id.next) { if (sound->newpackedfile) { @@ -787,15 +722,6 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main) for (ma = main->mat.first; ma; ma = ma->id.next) { if (ma->nodetree && ma->nodetree->id.name[0] == '\0') strcpy(ma->nodetree->id.name, "NTShader Nodetree"); - - /* which_output 0 is now "not specified" */ - for (a = 0; a < MAX_MTEX; a++) { - if (ma->mtex[a]) { - tx = blo_do_versions_newlibadr(fd, lib, ma->mtex[a]->tex); - if (tx && tx->use_nodes) - ma->mtex[a]->which_output++; - } - } } /* and composite trees */ @@ -881,7 +807,6 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main) if (main->versionfile < 250 || (main->versionfile == 250 && main->subversionfile < 1)) { Object *ob; - Material *ma; Tex *tex; Scene *sce; ToolSettings *ts; @@ -927,61 +852,6 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main) tex->afmax = 8; } - for (ma = main->mat.first; ma; ma = ma->id.next) { - int a; - - if (ma->mode & MA_WIRE) { - ma->material_type = MA_TYPE_WIRE; - ma->mode &= ~MA_WIRE; - } - - if (ma->mode & MA_HALO) { - ma->material_type = MA_TYPE_HALO; - ma->mode &= ~MA_HALO; - } - - if (ma->mode & (MA_ZTRANSP|MA_RAYTRANSP)) { - ma->mode |= MA_TRANSP; - } - else { - /* ma->mode |= MA_ZTRANSP; */ /* leave ztransp as is even if its not used [#28113] */ - ma->mode &= ~MA_TRANSP; - } - - /* set new bump for unused slots */ - for (a = 0; a < MAX_MTEX; a++) { - if (ma->mtex[a]) { - tex = ma->mtex[a]->tex; - if (!tex) { - ma->mtex[a]->texflag |= MTEX_3TAP_BUMP; - ma->mtex[a]->texflag |= MTEX_BUMP_OBJECTSPACE; - } - else { - tex = (Tex*) blo_do_versions_newlibadr(fd, ma->id.lib, tex); - if (tex && tex->type == 0) { /* invalid type */ - ma->mtex[a]->texflag |= MTEX_3TAP_BUMP; - ma->mtex[a]->texflag |= MTEX_BUMP_OBJECTSPACE; - } - } - } - } - - /* volume rendering settings */ - if (ma->vol.stepsize < 0.0001f) { - ma->vol.density = 1.0f; - ma->vol.emission = 0.0f; - ma->vol.scattering = 1.0f; - ma->vol.emission_col[0] = ma->vol.emission_col[1] = ma->vol.emission_col[2] = 1.0f; - ma->vol.density_scale = 1.0f; - ma->vol.depth_cutoff = 0.01f; - ma->vol.stepsize_type = MA_VOL_STEP_RANDOMIZED; - ma->vol.stepsize = 0.2f; - ma->vol.shade_type = MA_VOL_SHADE_SHADED; - ma->vol.shadeflag |= MA_VOL_PRECACHESHADING; - ma->vol.precache_resolution = 50; - } - } - for (sce = main->scene.first; sce; sce = sce->id.next) { ts = sce->toolsettings; if (ts->normalsize == 0.0f || !ts->uv_selectmode || ts->vgroup_weight == 0.0f) { @@ -1013,10 +883,6 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main) if (main->versionfile < 250 || (main->versionfile == 250 && main->subversionfile < 4)) { Scene *sce; Object *ob; - Material *ma; - Lamp *la; - World *wo; - Tex *tex; ParticleSettings *part; bool do_gravity = false; @@ -1034,27 +900,6 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main) ob->rotmode = ROT_MODE_EUL; } - for (ma = main->mat.first; ma; ma = ma->id.next) { - if (ma->vol.reflection == 0.f) { - ma->vol.reflection = 1.f; - ma->vol.transmission_col[0] = ma->vol.transmission_col[1] = ma->vol.transmission_col[2] = 1.0f; - ma->vol.reflection_col[0] = ma->vol.reflection_col[1] = ma->vol.reflection_col[2] = 1.0f; - } - - do_version_mtex_factor_2_50(ma->mtex, ID_MA); - } - - for (la = main->lamp.first; la; la = la->id.next) - do_version_mtex_factor_2_50(la->mtex, ID_LA); - - for (wo = main->world.first; wo; wo = wo->id.next) - do_version_mtex_factor_2_50(wo->mtex, ID_WO); - - for (tex = main->tex.first; tex; tex = tex->id.next) - if (tex->vd) - if (tex->vd->extend == 0) - tex->vd->extend = TEX_CLIP; - for (sce = main->scene.first; sce; sce = sce->id.next) { if (sce->audio.main == 0.0f) sce->audio.main = 1.0f; @@ -1115,7 +960,6 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main) if (main->versionfile < 250 || (main->versionfile == 250 && main->subversionfile < 6)) { Object *ob; - Lamp *la; /* New variables for axis-angle rotations and/or quaternion rotations were added, and need proper initialization */ for (ob = main->object.first; ob; ob = ob->id.next) { @@ -1133,9 +977,6 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main) } } } - - for (la = main->lamp.first; la; la = la->id.next) - la->compressthresh = 0.05f; } if (main->versionfile < 250 || (main->versionfile == 250 && main->subversionfile < 7)) { @@ -1204,8 +1045,6 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main) while (sce) { if (sce->r.frame_step == 0) sce->r.frame_step = 1; - if (sce->r.mblur_samples == 0) - sce->r.mblur_samples = sce->r.osa; if (sce->ed && sce->ed->seqbase.first) { do_versions_seq_unique_name_all_strips(sce, &sce->ed->seqbase); @@ -1262,7 +1101,6 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main) if (main->versionfile == 250) { Scene *sce = main->scene.first; Material *ma = main->mat.first; - World *wo = main->world.first; Tex *tex = main->tex.first; int i, convert = 0; @@ -1280,26 +1118,8 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main) if (convert) { while (ma) { - if (ma->ramp_col) { - ColorBand *band = (ColorBand *)ma->ramp_col; - for (i = 0; i < band->tot; i++) { - CBData *data = band->data + i; - srgb_to_linearrgb_v3_v3(&data->r, &data->r); - } - } - - if (ma->ramp_spec) { - ColorBand *band = (ColorBand *)ma->ramp_spec; - for (i = 0; i < band->tot; i++) { - CBData *data = band->data + i; - srgb_to_linearrgb_v3_v3(&data->r, &data->r); - } - } - srgb_to_linearrgb_v3_v3(&ma->r, &ma->r); srgb_to_linearrgb_v3_v3(&ma->specr, &ma->specr); - srgb_to_linearrgb_v3_v3(&ma->mirr, &ma->mirr); - srgb_to_linearrgb_v3_v3(ma->sss_col, ma->sss_col); ma = ma->id.next; } @@ -1313,13 +1133,6 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main) } tex = tex->id.next; } - - while (wo) { - srgb_to_linearrgb_v3_v3(&wo->ambr, &wo->ambr); - srgb_to_linearrgb_v3_v3(&wo->horr, &wo->horr); - srgb_to_linearrgb_v3_v3(&wo->zenr, &wo->zenr); - wo = wo->id.next; - } } } } @@ -1450,7 +1263,6 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main) if (main->versionfile < 250 || (main->versionfile == 250 && main->subversionfile < 12)) { Object *ob; Brush *brush; - Material *ma; /* anim viz changes */ for (ob = main->object.first; ob; ob = ob->id.next) { @@ -1532,14 +1344,6 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main) BKE_texture_mtex_default(&brush->mtex); BKE_texture_mtex_default(&brush->mask_mtex); } - - for (ma = main->mat.first; ma; ma = ma->id.next) { - if (ma->vol.ms_spread < 0.0001f) { - ma->vol.ms_spread = 0.2f; - ma->vol.ms_diff = 1.f; - ma->vol.ms_intensity = 1.f; - } - } } if (main->versionfile < 250 || (main->versionfile == 250 && main->subversionfile < 13)) { @@ -1598,41 +1402,9 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main) } } - if (main->versionfile < 250 || (main->versionfile == 250 && main->subversionfile < 15)) { - World *wo; - Material *ma; - - /* ambient default from 0.5f to 1.0f */ - for (ma = main->mat.first; ma; ma = ma->id.next) - ma->amb *= 2.0f; - - for (wo = main->world.first; wo; wo = wo->id.next) { - /* ao splitting into ao/env/indirect */ - wo->ao_env_energy = wo->aoenergy; - wo->aoenergy = 1.0f; - - if (wo->ao_indirect_bounces == 0) - wo->ao_indirect_bounces = 1; - else - wo->mode |= WO_INDIRECT_LIGHT; - - if (wo->aomix == WO_AOSUB) - wo->ao_env_energy = -wo->ao_env_energy; - else if (wo->aomix == WO_AOADDSUB) - wo->mode |= WO_AMB_OCC; - - wo->aomix = WO_AOMUL; - - /* ambient default from 0.5f to 1.0f */ - mul_v3_fl(&wo->ambr, 0.5f); - wo->ao_env_energy *= 0.5f; - } - } - if (main->versionfile < 250 || (main->versionfile == 250 && main->subversionfile < 17)) { Scene *sce; Sequence *seq; - Material *ma; /* initialize to sane default so toggling on border shows something */ for (sce = main->scene.first; sce; sce = sce->id.next) { @@ -1664,10 +1436,6 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main) pset->brush[a].strength /= 100.0f; } - for (ma = main->mat.first; ma; ma = ma->id.next) - if (ma->mode & MA_TRACEBLE) - ma->shade_flag |= MA_APPROX_OCCLUSION; - /* sequencer changes */ { bScreen *screen; @@ -2269,27 +2037,6 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main) Brush *brush; Object *ob; ParticleSettings *part; - Material *mat; - int tex_nr, transp_tex; - - for (mat = main->mat.first; mat; mat = mat->id.next) { - if (!(mat->mode & MA_TRANSP) && !(mat->material_type & MA_TYPE_VOLUME)) { - transp_tex = 0; - - for (tex_nr = 0; tex_nr < MAX_MTEX; tex_nr++) { - if (!mat->mtex[tex_nr]) - continue; - if (mat->mtex[tex_nr]->mapto & MAP_ALPHA) - transp_tex = 1; - } - - /* weak! material alpha could be animated */ - if (mat->alpha < 1.0f || mat->fresnel_tra > 0.0f || transp_tex) { - mat->mode |= MA_TRANSP; - mat->mode &= ~(MA_ZTRANSP|MA_RAYTRANSP); - } - } - } /* redraws flag in SpaceTime has been moved to Screen level */ for (sc = main->screen.first; sc; sc = sc->id.next) { @@ -2383,26 +2130,6 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main) } { - /* Initialize texture point density curve falloff */ - Tex *tex; - for (tex = main->tex.first; tex; tex = tex->id.next) { - if (tex->pd) { - if (tex->pd->falloff_speed_scale == 0.0f) - tex->pd->falloff_speed_scale = 100.0f; - - if (!tex->pd->falloff_curve) { - tex->pd->falloff_curve = curvemapping_add(1, 0, 0, 1, 1); - - tex->pd->falloff_curve->preset = CURVE_PRESET_LINE; - tex->pd->falloff_curve->cm->flag &= ~CUMA_EXTEND_EXTRAPOLATE; - curvemap_reset(tex->pd->falloff_curve->cm, &tex->pd->falloff_curve->clipr, tex->pd->falloff_curve->preset, CURVEMAP_SLOPE_POSITIVE); - curvemapping_changed(tex->pd->falloff_curve, false); - } - } - } - } - - { ParticleSettings *part; for (part = main->particle.first; part; part = part->id.next) { /* Initialize particle billboard scale */ diff --git a/source/blender/blenloader/intern/versioning_260.c b/source/blender/blenloader/intern/versioning_260.c index 89577c7b7d1..4049912b586 100644 --- a/source/blender/blenloader/intern/versioning_260.c +++ b/source/blender/blenloader/intern/versioning_260.c @@ -1156,15 +1156,9 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main) } if (main->versionfile < 263 || (main->versionfile == 263 && main->subversionfile < 4)) { - Lamp *la; Camera *cam; Curve *cu; - for (la = main->lamp.first; la; la = la->id.next) { - if (la->shadow_frustum_size == 0.0f) - la->shadow_frustum_size = 10.0f; - } - for (cam = main->camera.first; cam; cam = cam->id.next) { if (cam->flag & CAM_PANORAMA) { cam->type = CAM_PANO; @@ -1341,14 +1335,6 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main) } } - if (main->versionfile < 263 || (main->versionfile == 263 && main->subversionfile < 12)) { - Material *ma; - - for (ma = main->mat.first; ma; ma = ma->id.next) - if (ma->strand_widthfade == 2.0f) - ma->strand_widthfade = 0.0f; - } - if (main->versionfile < 263 || (main->versionfile == 263 && main->subversionfile < 13)) { FOREACH_NODETREE(main, ntree, id) { if (ntree->type == NTREE_COMPOSIT) { @@ -1495,20 +1481,7 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main) } } - /* remove texco */ if (main->versionfile < 263 || (main->versionfile == 263 && main->subversionfile < 21)) { - Material *ma; - for (ma = main->mat.first; ma; ma = ma->id.next) { - int a; - for (a = 0; a < MAX_MTEX; a++) { - if (ma->mtex[a]) { - if (ma->mtex[a]->texco == TEXCO_STICKY_) { - ma->mtex[a]->texco = TEXCO_UV; - } - } - } - } - { Mesh *me; for (me = main->mesh.first; me; me = me->id.next) { @@ -1666,17 +1639,7 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main) for (scene = main->scene.first; scene; scene = scene->id.next) { if (scene->r.tilex == 0 || scene->r.tiley == 1) { - if (scene->r.xparts && scene->r.yparts) { - /* scene could be set for panoramic rendering, so clamp with the - * lowest possible tile size value - */ - scene->r.tilex = max_ii(scene->r.xsch * scene->r.size / scene->r.xparts / 100, 8); - scene->r.tiley = max_ii(scene->r.ysch * scene->r.size / scene->r.yparts / 100, 8); - } - else { - /* happens when mixing using current trunk and previous release */ - scene->r.tilex = scene->r.tiley = 64; - } + scene->r.tilex = scene->r.tiley = 64; } } } @@ -1762,7 +1725,6 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main) for (scene = main->scene.first; scene; scene = scene->id.next) { Sequence *seq; - bool set_premul = false; SEQ_BEGIN (scene->ed, seq) { @@ -1777,24 +1739,6 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main) if (scene->r.bake_samples == 0) scene->r.bake_samples = 256; - - if (scene->world) { - World *world = blo_do_versions_newlibadr(fd, scene->id.lib, scene->world); - - if (world && is_zero_v3(&world->horr)) { - if ((world->skytype & WO_SKYBLEND) == 0 || is_zero_v3(&world->zenr)) { - set_premul = true; - } - } - } - else - set_premul = true; - - if (set_premul) { - printf("2.66 versioning fix: replacing black sky with premultiplied alpha for scene %s\n", - scene->id.name + 2); - scene->r.alphamode = R_ALPHAPREMUL; - } } for (Image *image = main->image.first; image; image = image->id.next) { diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c index 7097fe656b6..cd34f10d8a9 100644 --- a/source/blender/blenloader/intern/versioning_270.c +++ b/source/blender/blenloader/intern/versioning_270.c @@ -405,7 +405,6 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main) } if (!MAIN_VERSION_ATLEAST(main, 270, 1)) { - Scene *sce; Object *ob; /* Update Transform constraint (another deg -> rad stuff). */ @@ -420,12 +419,6 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main) } } } - - for (sce = main->scene.first; sce; sce = sce->id.next) { - if (sce->r.raytrace_structure == R_RAYSTRUCTURE_BLIBVH) { - sce->r.raytrace_structure = R_RAYSTRUCTURE_AUTO; - } - } } if (!MAIN_VERSION_ATLEAST(main, 270, 2)) { @@ -488,13 +481,6 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main) } if (!MAIN_VERSION_ATLEAST(main, 271, 0)) { - if (!DNA_struct_elem_find(fd->filesdna, "Material", "int", "mode2")) { - Material *ma; - - for (ma = main->mat.first; ma; ma = ma->id.next) - ma->mode2 = MA_CASTSHADOW; - } - if (!DNA_struct_elem_find(fd->filesdna, "RenderData", "BakeData", "bake")) { Scene *sce; @@ -835,33 +821,6 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main) } } - if (!MAIN_VERSION_ATLEAST(main, 274, 2)) { - FOREACH_NODETREE(main, ntree, id) { - bNode *node; - bNodeSocket *sock; - - for (node = ntree->nodes.first; node; node = node->next) { - if (node->type == SH_NODE_MATERIAL) { - for (sock = node->inputs.first; sock; sock = sock->next) { - if (STREQ(sock->name, "Refl")) { - BLI_strncpy(sock->name, "DiffuseIntensity", sizeof(sock->name)); - } - } - } - else if (node->type == SH_NODE_MATERIAL_EXT) { - for (sock = node->outputs.first; sock; sock = sock->next) { - if (STREQ(sock->name, "Refl")) { - BLI_strncpy(sock->name, "DiffuseIntensity", sizeof(sock->name)); - } - else if (STREQ(sock->name, "Ray Mirror")) { - BLI_strncpy(sock->name, "Reflectivity", sizeof(sock->name)); - } - } - } - } - } FOREACH_NODETREE_END - } - if (!MAIN_VERSION_ATLEAST(main, 274, 4)) { SceneRenderView *srv; wmWindowManager *wm; diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c index d6cf411c31c..0d781322d4f 100644 --- a/source/blender/blenloader/intern/versioning_280.c +++ b/source/blender/blenloader/intern/versioning_280.c @@ -667,16 +667,6 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *main) { if (!MAIN_VERSION_ATLEAST(main, 280, 0)) { - for (Scene *scene = main->scene.first; scene; scene = scene->id.next) { - if (STREQ(scene->r.engine, RE_engine_id_BLENDER_RENDER)) { -#ifdef WITH_CLAY_ENGINE - BLI_strncpy(scene->r.engine, RE_engine_id_BLENDER_CLAY, sizeof(scene->r.engine)); -#else - BLI_strncpy(scene->r.engine, RE_engine_id_BLENDER_EEVEE, sizeof(scene->r.engine)); -#endif - } - } - if (!DNA_struct_elem_find(fd->filesdna, "Scene", "ListBase", "view_layers")) { for (Scene *scene = main->scene.first; scene; scene = scene->id.next) { /* Master Collection */ @@ -937,4 +927,23 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *main) } } } + + if (!MAIN_VERSION_ATLEAST(main, 280, 8)) { + /* Blender Internal removal */ + for (Scene *scene = main->scene.first; scene; scene = scene->id.next) { + if (STREQ(scene->r.engine, "BLENDER_RENDER") || + STREQ(scene->r.engine, "BLENDER_GAME")) { + BLI_strncpy(scene->r.engine, RE_engine_id_BLENDER_EEVEE, sizeof(scene->r.engine)); + } + + scene->r.bake_mode = 0; + } + + for (Tex *tex = main->tex.first; tex; tex = tex->id.next) { + /* Removed envmap, pointdensity, voxeldata, ocean textures. */ + if (ELEM(tex->type, 10, 14, 15, 16)) { + tex->type = 0; + } + } + } } diff --git a/source/blender/blenloader/intern/versioning_legacy.c b/source/blender/blenloader/intern/versioning_legacy.c index e16cc122414..9ac2f926da6 100644 --- a/source/blender/blenloader/intern/versioning_legacy.c +++ b/source/blender/blenloader/intern/versioning_legacy.c @@ -212,12 +212,6 @@ static void ntree_version_242(bNodeTree *ntree) } } } - else if (ntree->type == NTREE_SHADER) { - for (node = ntree->nodes.first; node; node = node->next) - if (node->type == SH_NODE_GEOMETRY && node->storage == NULL) - node->storage = MEM_callocN(sizeof(NodeGeometry), "NodeGeometry"); - } - } static void ntree_version_245(FileData *fd, Library *lib, bNodeTree *ntree) @@ -525,15 +519,6 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main) } } - if (main->versionfile <= 102) { - /* init halo's at 1.0 */ - Material *ma = main->mat.first; - while (ma) { - ma->add = 1.0; - ma = ma->id.next; - } - } - if (main->versionfile <= 103) { /* new variable in object: colbits */ Object *ob = main->object.first; @@ -585,11 +570,6 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main) if (main->versionfile <= 107) { Object *ob; - Scene *sce = main->scene.first; - while (sce) { - sce->r.mode |= R_GAMMA; - sce = sce->id.next; - } ob = main->object.first; while (ob) { if (ob->dt == 0) @@ -621,17 +601,6 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main) } } - if (main->versionfile <= 113) { - Material *ma = main->mat.first; - while (ma) { - if (ma->flaresize == 0.0f) - ma->flaresize = 1.0f; - ma->subsize = 1.0f; - ma->flareboost = 1.0f; - ma = ma->id.next; - } - } - if (main->versionfile <= 134) { Tex *tex = main->tex.first; while (tex) { @@ -796,17 +765,6 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main) } } - if (main->versionfile <= 191) { - Material *ma = main->mat.first; - - /* let faces have default add factor of 0.0 */ - while (ma) { - if (!(ma->mode & MA_HALO)) - ma->add = 0.0; - ma = ma->id.next; - } - } - if (main->versionfile <= 204) { bSound *sound; @@ -890,31 +848,6 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main) } } - if (main->versionfile <= 221) { - Scene *sce = main->scene.first; - - /* new variables for std-alone player and runtime */ - while (sce) { - sce->r.xplay = 640; - sce->r.yplay = 480; - sce->r.freqplay = 60; - - sce = sce->id.next; - } - - } - - if (main->versionfile <= 222) { - Scene *sce = main->scene.first; - - /* new variables for std-alone player and runtime */ - while (sce) { - sce->r.depth = 32; - - sce = sce->id.next; - } - } - if (main->versionfile <= 223) { VFont *vf; for (vf = main->vfont.first; vf; vf = vf->id.next) { @@ -967,7 +900,6 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main) if (main->versionfile <= 227) { Scene *sce; - Material *ma; bScreen *sc; Object *ob; @@ -1020,17 +952,6 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main) for (sce = main->scene.first; sce; sce = sce->id.next) { sce->audio.mixrate = 48000; sce->audio.flag |= AUDIO_SCRUB; - sce->r.mode |= R_ENVMAP; - } - - /* init new shader vars */ - for (ma = main->mat.first; ma; ma = ma->id.next) { - ma->refrac = 4.0f; - ma->roughness = 0.5f; - ma->param[0] = 0.5f; - ma->param[1] = 0.1f; - ma->param[2] = 0.1f; - ma->param[3] = 0.05f; } /* patch for old wrong max view2d settings, allows zooming out more */ @@ -1055,7 +976,6 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main) } if (main->versionfile <= 228) { - Scene *sce; bScreen *sc; Object *ob; @@ -1101,10 +1021,6 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main) ob = ob->id.next; } - for (sce = main->scene.first; sce; sce = sce->id.next) { - sce->r.mode |= R_ENVMAP; - } - /* convert old mainb values for new button panels */ for (sc = main->screen.first; sc; sc = sc->id.next) { ScrArea *sa; @@ -1224,57 +1140,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main) } if (main->versionfile <= 231) { - Material *ma = main->mat.first; bScreen *sc = main->screen.first; - Scene *sce; - Lamp *la; - World *wrld; - - /* introduction of raytrace */ - while (ma) { - if (ma->fresnel_tra_i == 0.0f) - ma->fresnel_tra_i = 1.25f; - if (ma->fresnel_mir_i == 0.0f) - ma->fresnel_mir_i = 1.25f; - - ma->ang = 1.0; - ma->ray_depth = 2; - ma->ray_depth_tra = 2; - ma->fresnel_tra = 0.0; - ma->fresnel_mir = 0.0; - - ma = ma->id.next; - } - sce = main->scene.first; - while (sce) { - if (sce->r.gauss == 0.0f) - sce->r.gauss = 1.0f; - sce = sce->id.next; - } - la = main->lamp.first; - while (la) { - if (la->k == 0.0f) la->k = 1.0; - if (la->ray_samp == 0) - la->ray_samp = 1; - if (la->ray_sampy == 0) - la->ray_sampy = 1; - if (la->ray_sampz == 0) - la->ray_sampz = 1; - if (la->area_size == 0.0f) - la->area_size = 1.0f; - if (la->area_sizey == 0.0f) - la->area_sizey = 1.0f; - if (la->area_sizez == 0.0f) - la->area_sizez = 1.0f; - la = la->id.next; - } - wrld = main->world.first; - while (wrld) { - if (wrld->range == 0.0f) { - wrld->range = 1.0f / wrld->exposure; - } - wrld = wrld->id.next; - } /* new bit flags for showing/hiding grid floor and axes */ @@ -1305,7 +1171,6 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main) Tex *tex = main->tex.first; World *wrld = main->world.first; bScreen *sc; - Scene *sce; while (tex) { if ((tex->flag & (TEX_CHECKER_ODD+TEX_CHECKER_EVEN))==0) { @@ -1332,10 +1197,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main) while (wrld) { if (wrld->aodist == 0.0f) { wrld->aodist = 10.0f; - wrld->aobias = 0.05f; } - if (wrld->aosamp == 0) - wrld->aosamp = 5; if (wrld->aoenergy == 0.0f) wrld->aoenergy = 1.0f; wrld = wrld->id.next; @@ -1360,13 +1222,6 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main) } } } - sce = main->scene.first; - while (sce) { - if (sce->r.ocres == 0) - sce->r.ocres = 64; - sce = sce->id.next; - } - } if (main->versionfile <= 233) { @@ -1375,10 +1230,6 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main) /* Object *ob = main->object.first; */ while (ma) { - if (ma->rampfac_col == 0.0f) - ma->rampfac_col = 1.0; - if (ma->rampfac_spec == 0.0f) - ma->rampfac_spec = 1.0; if (ma->pr_lamp == 0) ma->pr_lamp = 3; ma = ma->id.next; @@ -1449,7 +1300,6 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main) if (main->versionfile <= 236) { Object *ob; Camera *cam = main->camera.first; - Material *ma; bScreen *sc; while (cam) { @@ -1476,13 +1326,6 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main) } } } - /* init new shader vars */ - for (ma = main->mat.first; ma; ma = ma->id.next) { - if (ma->darkness == 0.0f) { - ma->rms = 0.1f; - ma->darkness = 1.0f; - } - } /* softbody init new vars */ for (ob = main->object.first; ob; ob = ob->id.next) { @@ -1711,7 +1554,6 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main) Object *ob; Scene *sce = main->scene.first; Camera *cam = main->camera.first; - Material *ma = main->mat.first; int set_passepartout = 0; /* deformflag is local in modifier now */ @@ -1744,11 +1586,6 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main) set_passepartout = 1; sce->r.scemode &= ~R_PASSEPARTOUT; } - /* gauss is filter variable now */ - if (sce->r.mode & R_GAUSS) { - sce->r.filtertype = R_FILTER_GAUSS; - sce->r.mode &= ~R_GAUSS; - } } for (; cam; cam = cam->id.next) { @@ -1763,32 +1600,15 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main) if (!(cam->passepartalpha)) cam->passepartalpha = 0.2f; } - - for (; ma; ma = ma->id.next) { - if (ma->strand_sta == 0.0f) { - ma->strand_sta = ma->strand_end = 1.0f; - ma->mode |= MA_TANGENT_STR; - } - if (ma->mode & MA_TRACEBLE) - ma->mode |= MA_SHADBUF; - } } if (main->versionfile <= 241) { Object *ob; - Tex *tex; Scene *sce; - World *wo; Lamp *la; - Material *ma; bArmature *arm; bNodeTree *ntree; - for (wo = main->world.first; wo; wo = wo->id.next) { - if (WO_AODIST == wo->aomode) - wo->aocolor = WO_AOPLAIN; - } - /* updating layers still */ for (arm = main->armature.first; arm; arm = arm->id.next) { bone_version_239(&arm->bonebase); @@ -1799,11 +1619,6 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main) if (sce->audio.mixrate == 0) sce->audio.mixrate = 48000; - if (sce->r.xparts <2 ) - sce->r.xparts = 4; - if (sce->r.yparts < 2) - sce->r.yparts = 4; - /* We don't add default layer since blender2.8 because the layers * are now in Scene->view_layers and a default layer is created in * the doversion later on. @@ -1825,20 +1640,6 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main) sce->toolsettings->uvcalc_flag = UVCALC_FILLHOLES; sce->toolsettings->unwrapper = 1; } - - if (sce->r.mode & R_PANORAMA) { - /* all these checks to ensure saved files between released versions keep working... */ - if (sce->r.xsch < sce->r.ysch) { - Object *obc = blo_do_versions_newlibadr(fd, lib, sce->camera); - if (obc && obc->type == OB_CAMERA) { - Camera *cam = blo_do_versions_newlibadr(fd, lib, obc->data); - if (cam->lens >= 10.0f) { - sce->r.xsch *= sce->r.xparts; - cam->lens *= (float)sce->r.ysch / (float)sce->r.xsch; - } - } - } - } } for (ntree = main->nodetree.first; ntree; ntree = ntree->id.next) @@ -1848,12 +1649,6 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main) if (la->buffers == 0) la->buffers = 1; - for (tex = main->tex.first; tex; tex = tex->id.next) { - if (tex->env && tex->env->viewscale == 0.0f) - tex->env->viewscale = 1.0f; - //tex->imaflag |= TEX_GAUSS_MIP; - } - /* for empty drawsize and drawtype */ for (ob = main->object.first; ob; ob = ob->id.next) { if (ob->empty_drawsize == 0.0f) { @@ -1862,21 +1657,6 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main) } } - for (ma = main->mat.first; ma; ma = ma->id.next) { - /* stucci returns intensity from now on */ - int a; - for (a = 0; a < MAX_MTEX; a++) { - if (ma->mtex[a] && ma->mtex[a]->tex) { - tex = blo_do_versions_newlibadr(fd, lib, ma->mtex[a]->tex); - if (tex && tex->type == TEX_STUCCI) - ma->mtex[a]->mapto &= ~(MAP_COL|MAP_SPEC|MAP_REF); - } - } - /* transmissivity defaults */ - if (ma->tx_falloff == 0.0f) - ma->tx_falloff = 1.0f; - } - /* during 2.41 images with this name were used for viewer node output, lets fix that */ if (main->versionfile == 241) { Image *ima; @@ -2046,8 +1826,6 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main) } for (ma = main->mat.first; ma; ma = ma->id.next) { - if (ma->shad_alpha == 0.0f) - ma->shad_alpha = 1.0f; if (ma->nodetree) ntree_version_242(ma->nodetree); } @@ -2125,7 +1903,6 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main) for (sce = main->scene.first; sce; sce = sce->id.next) { sce->r.bake_mode = 1; /* prevent to include render stuff here */ sce->r.bake_filter = 16; - sce->r.bake_osa = 5; sce->r.bake_flag = R_BAKE_CLEAR; } } @@ -2133,32 +1910,6 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main) if (main->versionfile <= 243) { Object *ob = main->object.first; - Material *ma; - - for (ma = main->mat.first; ma; ma = ma->id.next) { - if (ma->sss_scale == 0.0f) { - ma->sss_radius[0] = 1.0f; - ma->sss_radius[1] = 1.0f; - ma->sss_radius[2] = 1.0f; - ma->sss_col[0] = 0.8f; - ma->sss_col[1] = 0.8f; - ma->sss_col[2] = 0.8f; - ma->sss_error = 0.05f; - ma->sss_scale = 0.1f; - ma->sss_ior = 1.3f; - ma->sss_colfac = 1.0f; - ma->sss_texfac = 0.0f; - } - if (ma->sss_front == 0 && ma->sss_back == 0) { - ma->sss_front = 1.0f; - ma->sss_back = 1.0f; - } - if (ma->sss_col[0] == 0 && ma->sss_col[1] == 0 && ma->sss_col[2] == 0) { - ma->sss_col[0] = ma->r; - ma->sss_col[1] = ma->g; - ma->sss_col[2] = ma->b; - } - } for (; ob; ob = ob->id.next) { bDeformGroup *curdef; @@ -2206,15 +1957,9 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main) } if (main->versionfile <= 244) { - Scene *sce; bScreen *sc; - Lamp *la; - World *wrld; if (main->versionfile != 244 || main->subversionfile < 2) { - for (sce = main->scene.first; sce; sce = sce->id.next) - sce->r.mode |= R_SSS; - /* correct older action editors - incorrect scrolling */ for (sc = main->screen.first; sc; sc = sc->id.next) { ScrArea *sa; @@ -2237,28 +1982,6 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main) } } } - - if (main->versionfile != 244 || main->subversionfile < 3) { - /* constraints recode version patch used to be here. Moved to 245 now... */ - - for (wrld = main->world.first; wrld; wrld = wrld->id.next) { - if (wrld->mode & WO_AMB_OCC) - wrld->ao_samp_method = WO_AOSAMP_CONSTANT; - else - wrld->ao_samp_method = WO_AOSAMP_HAMMERSLEY; - - wrld->ao_adapt_thresh = 0.005f; - } - - for (la = main->lamp.first; la; la = la->id.next) { - if (la->type == LA_AREA) - la->ray_samp_method = LA_SAMP_CONSTANT; - else - la->ray_samp_method = LA_SAMP_HALTON; - - la->adapt_thresh = 0.001f; - } - } } if (main->versionfile <= 245) { @@ -2268,7 +1991,6 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main) Lamp *la; Material *ma; ParticleSettings *part; - World *wrld; Mesh *me; bNodeTree *ntree; Tex *tex; @@ -2400,10 +2122,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main) if (main->versionfile != 245 || main->subversionfile < 1) { for (la = main->lamp.first; la; la = la->id.next) { - if (la->mode & LA_QUAD) - la->falloff_type = LA_FALLOFF_SLIDERS; - else - la->falloff_type = LA_FALLOFF_INVLINEAR; + la->falloff_type = LA_FALLOFF_INVLINEAR; if (la->curfalloff == NULL) { la->curfalloff = curvemapping_add(1, 0.0f, 1.0f, 1.0f, 0.0f); @@ -2413,17 +2132,9 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main) } for (ma = main->mat.first; ma; ma = ma->id.next) { - if (ma->samp_gloss_mir == 0) { - ma->gloss_mir = ma->gloss_tra = 1.0f; - ma->aniso_gloss_mir = 1.0f; - ma->samp_gloss_mir = ma->samp_gloss_tra = 18; - ma->adapt_thresh_mir = ma->adapt_thresh_tra = 0.005f; - ma->dist_mir = 0.0f; - ma->fadeto_mir = MA_RAYMIR_FADETOSKY; + if (ma->gloss_mir == 0.0f) { + ma->gloss_mir = 1.0f; } - - if (ma->strand_min == 0.0f) - ma->strand_min = 1.0f; } for (part = main->particle.first; part; part = part->id.next) { @@ -2431,26 +2142,13 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main) part->ren_child_nbr = part->child_nbr; } - for (wrld = main->world.first; wrld; wrld = wrld->id.next) { - if (wrld->ao_approx_error == 0.0f) - wrld->ao_approx_error = 0.25f; - } - for (sce = main->scene.first; sce; sce = sce->id.next) { if (sce->nodetree) ntree_version_245(fd, lib, sce->nodetree); - if (sce->r.simplify_shadowsamples == 0) { + if (sce->r.simplify_subsurf == 0) { sce->r.simplify_subsurf = 6; sce->r.simplify_particles = 1.0f; - sce->r.simplify_shadowsamples = 16; - sce->r.simplify_aosss = 1.0f; - } - - if (sce->r.cineongamma == 0) { - sce->r.cineonblack = 95; - sce->r.cineonwhite = 685; - sce->r.cineongamma = 1.7f; } } @@ -2730,16 +2428,6 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main) } } } - if ((main->versionfile < 245) || (main->versionfile == 245 && main->subversionfile < 9)) { - Material *ma; - int a; - - for (ma = main->mat.first; ma; ma = ma->id.next) - if (ma->mode & MA_NORMAP_TANG) - for (a = 0; a < MAX_MTEX; a++) - if (ma->mtex[a] && ma->mtex[a]->tex) - ma->mtex[a]->normapspace = MTEX_NSPACE_TANGENT; - } if ((main->versionfile < 245) || (main->versionfile == 245 && main->subversionfile < 10)) { Object *ob; @@ -2851,14 +2539,6 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main) } } - if (main->versionfile < 247 || (main->versionfile == 247 && main->subversionfile < 5)) { - Lamp *la = main->lamp.first; - for (; la; la = la->id.next) { - la->skyblendtype = MA_RAMP_ADD; - la->skyblendfac = 1.0f; - } - } - /* set the curve radius interpolation to 2.47 default - easy */ if (main->versionfile < 247 || (main->versionfile == 247 && main->subversionfile < 6)) { Curve *cu; @@ -2882,33 +2562,6 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main) } } - if (main->versionfile < 247 || (main->versionfile == 247 && main->subversionfile < 9)) { - Lamp *la = main->lamp.first; - for (; la; la = la->id.next) { - la->sky_exposure = 1.0f; - } - } - - if (main->versionfile < 248) { - Lamp *la; - - for (la = main->lamp.first; la; la = la->id.next) { - if (la->atm_turbidity == 0.0f) { - la->sun_effect_type = 0; - la->horizon_brightness = 1.0f; - la->spread = 1.0f; - la->sun_brightness = 1.0f; - la->sun_size = 1.0f; - la->backscattered_light = 1.0f; - la->atm_turbidity = 2.0f; - la->atm_inscattering_factor = 1.0f; - la->atm_extinction_factor = 1.0f; - la->atm_distance_factor = 1.0f; - la->sun_intensity = 1.0f; - } - } - } - if (main->versionfile < 248 || (main->versionfile == 248 && main->subversionfile < 2)) { Scene *sce; diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index ab71676b3df..7722013fbbf 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -2277,24 +2277,6 @@ static void write_texture(WriteData *wd, Tex *tex) if (tex->coba) { writestruct(wd, DATA, ColorBand, 1, tex->coba); } - if (tex->type == TEX_ENVMAP && tex->env) { - writestruct(wd, DATA, EnvMap, 1, tex->env); - } - if (tex->type == TEX_POINTDENSITY && tex->pd) { - writestruct(wd, DATA, PointDensity, 1, tex->pd); - if (tex->pd->coba) { - writestruct(wd, DATA, ColorBand, 1, tex->pd->coba); - } - if (tex->pd->falloff_curve) { - write_curvemapping(wd, tex->pd->falloff_curve); - } - } - if (tex->type == TEX_VOXELDATA) { - writestruct(wd, DATA, VoxelData, 1, tex->vd); - } - if (tex->type == TEX_OCEAN && tex->ot) { - writestruct(wd, DATA, OceanTex, 1, tex->ot); - } /* nodetree is integral part of texture, no libdata */ if (tex->nodetree) { @@ -2317,19 +2299,6 @@ static void write_material(WriteData *wd, Material *ma) write_animdata(wd, ma->adt); } - for (int a = 0; a < MAX_MTEX; a++) { - if (ma->mtex[a]) { - writestruct(wd, DATA, MTex, 1, ma->mtex[a]); - } - } - - if (ma->ramp_col) { - writestruct(wd, DATA, ColorBand, 1, ma->ramp_col); - } - if (ma->ramp_spec) { - writestruct(wd, DATA, ColorBand, 1, ma->ramp_spec); - } - /* nodetree is integral part of material, no libdata */ if (ma->nodetree) { writestruct(wd, DATA, bNodeTree, 1, ma->nodetree); @@ -2351,12 +2320,6 @@ static void write_world(WriteData *wd, World *wrld) write_animdata(wd, wrld->adt); } - for (int a = 0; a < MAX_MTEX; a++) { - if (wrld->mtex[a]) { - writestruct(wd, DATA, MTex, 1, wrld->mtex[a]); - } - } - /* nodetree is integral part of world, no libdata */ if (wrld->nodetree) { writestruct(wd, DATA, bNodeTree, 1, wrld->nodetree); @@ -2378,13 +2341,6 @@ static void write_lamp(WriteData *wd, Lamp *la) write_animdata(wd, la->adt); } - /* direct data */ - for (int a = 0; a < MAX_MTEX; a++) { - if (la->mtex[a]) { - writestruct(wd, DATA, MTex, 1, la->mtex[a]); - } - } - if (la->curfalloff) { write_curvemapping(wd, la->curfalloff); } diff --git a/source/blender/collada/DocumentExporter.cpp b/source/blender/collada/DocumentExporter.cpp index 0b70b73887f..a66c4db7b4d 100644 --- a/source/blender/collada/DocumentExporter.cpp +++ b/source/blender/collada/DocumentExporter.cpp @@ -71,7 +71,6 @@ extern "C" #include "DNA_mesh_types.h" #include "DNA_image_types.h" #include "DNA_material_types.h" -#include "DNA_texture_types.h" #include "DNA_anim_types.h" #include "DNA_action_types.h" #include "DNA_curve_types.h" diff --git a/source/blender/collada/DocumentImporter.cpp b/source/blender/collada/DocumentImporter.cpp index 97b11f72509..d50c4bb23c4 100644 --- a/source/blender/collada/DocumentImporter.cpp +++ b/source/blender/collada/DocumentImporter.cpp @@ -62,7 +62,6 @@ extern "C" { #include "BKE_layer.h" #include "BKE_lamp.h" #include "BKE_library.h" -#include "BKE_texture.h" #include "BKE_fcurve.h" #include "BKE_scene.h" #include "BKE_global.h" @@ -544,8 +543,7 @@ std::vector<Object *> *DocumentImporter::write_node(COLLADAFW::Node *node, COLLA // maybe join multiple <instance_...> meshes into 1, and link object with it? not sure... // <instance_geometry> while (geom_done < geom.getCount()) { - ob = mesh_importer.create_mesh_object(node, geom[geom_done], false, uid_material_map, - material_texture_mapping_map); + ob = mesh_importer.create_mesh_object(node, geom[geom_done], false, uid_material_map); if (ob == NULL) { report_unknown_reference(*node, "instance_mesh"); } @@ -585,7 +583,7 @@ std::vector<Object *> *DocumentImporter::write_node(COLLADAFW::Node *node, COLLA } while (controller_done < controller.getCount()) { COLLADAFW::InstanceGeometry *geometry = (COLLADAFW::InstanceGeometry *)controller[controller_done]; - ob = mesh_importer.create_mesh_object(node, geometry, true, uid_material_map, material_texture_mapping_map); + ob = mesh_importer.create_mesh_object(node, geometry, true, uid_material_map); if (ob == NULL) { report_unknown_reference(*node, "instance_controller"); } @@ -765,102 +763,74 @@ bool DocumentImporter::writeMaterial(const COLLADAFW::Material *cmat) return true; } -// create mtex, create texture, set texture image -MTex *DocumentImporter::create_texture(COLLADAFW::EffectCommon *ef, COLLADAFW::Texture &ctex, Material *ma, - int i, TexIndexTextureArrayMap &texindex_texarray_map) -{ - COLLADAFW::SamplerPointerArray& samp_array = ef->getSamplerPointerArray(); - COLLADAFW::Sampler *sampler = samp_array[ctex.getSamplerId()]; - - const COLLADAFW::UniqueId& ima_uid = sampler->getSourceImage(); - - if (uid_image_map.find(ima_uid) == uid_image_map.end()) { - fprintf(stderr, "Couldn't find an image by UID.\n"); - return NULL; - } - - ma->mtex[i] = BKE_texture_mtex_add(); - ma->mtex[i]->texco = TEXCO_UV; - ma->mtex[i]->tex = BKE_texture_add(G.main, "Texture"); - ma->mtex[i]->tex->type = TEX_IMAGE; - ma->mtex[i]->tex->ima = uid_image_map[ima_uid]; - - texindex_texarray_map[ctex.getTextureMapId()].push_back(ma->mtex[i]); - - return ma->mtex[i]; -} - void DocumentImporter::write_profile_COMMON(COLLADAFW::EffectCommon *ef, Material *ma) { COLLADAFW::EffectCommon::ShaderType shader = ef->getShaderType(); + + // TODO: add back texture and extended material parameter support // blinn if (shader == COLLADAFW::EffectCommon::SHADER_BLINN) { +#if 0 ma->spec_shader = MA_SPEC_BLINN; ma->spec = ef->getShininess().getFloatValue(); +#endif } // phong else if (shader == COLLADAFW::EffectCommon::SHADER_PHONG) { +#if 0 ma->spec_shader = MA_SPEC_PHONG; ma->har = ef->getShininess().getFloatValue(); +#endif } // lambert else if (shader == COLLADAFW::EffectCommon::SHADER_LAMBERT) { +#if 0 ma->diff_shader = MA_DIFF_LAMBERT; +#endif } // default - lambert else { +#if 0 ma->diff_shader = MA_DIFF_LAMBERT; fprintf(stderr, "Current shader type is not supported, default to lambert.\n"); +#endif } // reflectivity ma->ray_mirror = ef->getReflectivity().getFloatValue(); // index of refraction +#if 0 ma->ang = ef->getIndexOfRefraction().getFloatValue(); +#endif - int i = 0; COLLADAFW::Color col; - MTex *mtex = NULL; - TexIndexTextureArrayMap texindex_texarray_map; // DIFFUSE // color if (ef->getDiffuse().isColor()) { - /* too high intensity can create artefacts (fireflies) - So here we take care that intensity is set to 0.8 wherever possible - */ col = ef->getDiffuse().getColor(); - ma->ref = max_ffff(col.getRed(), col.getGreen(), col.getBlue(), 0.8); - ma->r = col.getRed() / ma->ref; - ma->g = col.getGreen() / ma->ref; - ma->b = col.getBlue() / ma->ref; + ma->r = col.getRed(); + ma->g = col.getGreen(); + ma->b = col.getBlue(); } // texture else if (ef->getDiffuse().isTexture()) { +#if 0 COLLADAFW::Texture ctex = ef->getDiffuse().getTexture(); - mtex = create_texture(ef, ctex, ma, i, texindex_texarray_map); - if (mtex != NULL) { - mtex->mapto = MAP_COL; - ma->texact = (int)i; - i++; - } +#endif } // AMBIENT // color if (ef->getAmbient().isColor()) { +#if 0 col = ef->getAmbient().getColor(); - ma->ambr = col.getRed(); - ma->ambg = col.getGreen(); - ma->ambb = col.getBlue(); +#endif } // texture else if (ef->getAmbient().isTexture()) { +#if 0 COLLADAFW::Texture ctex = ef->getAmbient().getTexture(); - mtex = create_texture(ef, ctex, ma, i, texindex_texarray_map); - if (mtex != NULL) { - mtex->mapto = MAP_AMB; - i++; - } +#endif } // SPECULAR // color @@ -872,29 +842,22 @@ void DocumentImporter::write_profile_COMMON(COLLADAFW::EffectCommon *ef, Materia } // texture else if (ef->getSpecular().isTexture()) { +#if 0 COLLADAFW::Texture ctex = ef->getSpecular().getTexture(); - mtex = create_texture(ef, ctex, ma, i, texindex_texarray_map); - if (mtex != NULL) { - mtex->mapto = MAP_SPEC; - i++; - } +#endif } // REFLECTIVE // color if (ef->getReflective().isColor()) { +#if 0 col = ef->getReflective().getColor(); - ma->mirr = col.getRed(); - ma->mirg = col.getGreen(); - ma->mirb = col.getBlue(); +#endif } // texture else if (ef->getReflective().isTexture()) { +#if 0 COLLADAFW::Texture ctex = ef->getReflective().getTexture(); - mtex = create_texture(ef, ctex, ma, i, texindex_texarray_map); - if (mtex != NULL) { - mtex->mapto = MAP_REF; - i++; - } +#endif } // EMISSION @@ -905,40 +868,31 @@ void DocumentImporter::write_profile_COMMON(COLLADAFW::EffectCommon *ef, Materia } // texture else if (ef->getEmission().isTexture()) { +#if 0 COLLADAFW::Texture ctex = ef->getEmission().getTexture(); - mtex = create_texture(ef, ctex, ma, i, texindex_texarray_map); - if (mtex != NULL) { - mtex->mapto = MAP_EMIT; - i++; - } +#endif } // TRANSPARENT // color if (ef->getOpacity().isColor()) { +#if 0 col = ef->getTransparent().getColor(); float alpha = ef->getTransparency().getFloatValue(); if (col.isValid()) { alpha *= col.getAlpha(); // Assuming A_ONE opaque mode } if (col.isValid() || alpha < 1.0) { - ma->alpha = alpha; - ma->mode |= MA_ZTRANSP | MA_TRANSP; + ... } +#endif } // texture else if (ef->getOpacity().isTexture()) { +#if 0 COLLADAFW::Texture ctex = ef->getOpacity().getTexture(); - mtex = create_texture(ef, ctex, ma, i, texindex_texarray_map); - if (mtex != NULL) { - mtex->mapto = MAP_ALPHA; - i++; - ma->spectra = ma->alpha = 0; - ma->mode |= MA_ZTRANSP | MA_TRANSP; - } +#endif } - - material_texture_mapping_map[ma] = texindex_texarray_map; } /** When this method is called, the writer must write the effect. @@ -1185,7 +1139,6 @@ bool DocumentImporter::writeLight(const COLLADAFW::Light *light) et->setData("spotsize", &(lamp->spotsize)); lamp->spotsize = DEG2RADF(lamp->spotsize); et->setData("spotblend", &(lamp->spotblend)); - et->setData("halo_intensity", &(lamp->haint)); et->setData("att1", &(lamp->att1)); et->setData("att2", &(lamp->att2)); et->setData("falloff_type", &(lamp->falloff_type)); @@ -1193,38 +1146,12 @@ bool DocumentImporter::writeLight(const COLLADAFW::Light *light) et->setData("clipend", &(lamp->clipend)); et->setData("bias", &(lamp->bias)); et->setData("soft", &(lamp->soft)); - et->setData("compressthresh", &(lamp->compressthresh)); et->setData("bufsize", &(lamp->bufsize)); - et->setData("samp", &(lamp->samp)); et->setData("buffers", &(lamp->buffers)); - et->setData("filtertype", &(lamp->filtertype)); - et->setData("bufflag", &(lamp->bufflag)); - et->setData("buftype", &(lamp->buftype)); - et->setData("ray_samp", &(lamp->ray_samp)); - et->setData("ray_sampy", &(lamp->ray_sampy)); - et->setData("ray_sampz", &(lamp->ray_sampz)); - et->setData("ray_samp_type", &(lamp->ray_samp_type)); et->setData("area_shape", &(lamp->area_shape)); et->setData("area_size", &(lamp->area_size)); et->setData("area_sizey", &(lamp->area_sizey)); et->setData("area_sizez", &(lamp->area_sizez)); - et->setData("adapt_thresh", &(lamp->adapt_thresh)); - et->setData("ray_samp_method", &(lamp->ray_samp_method)); - et->setData("shadhalostep", &(lamp->shadhalostep)); - et->setData("sun_effect_type", &(lamp->shadhalostep)); - et->setData("skyblendtype", &(lamp->skyblendtype)); - et->setData("horizon_brightness", &(lamp->horizon_brightness)); - et->setData("spread", &(lamp->spread)); - et->setData("sun_brightness", &(lamp->sun_brightness)); - et->setData("sun_size", &(lamp->sun_size)); - et->setData("backscattered_light", &(lamp->backscattered_light)); - et->setData("sun_intensity", &(lamp->sun_intensity)); - et->setData("atm_turbidity", &(lamp->atm_turbidity)); - et->setData("atm_extinction_factor", &(lamp->atm_extinction_factor)); - et->setData("atm_distance_factor", &(lamp->atm_distance_factor)); - et->setData("skyblendfac", &(lamp->skyblendfac)); - et->setData("sky_exposure", &(lamp->sky_exposure)); - et->setData("sky_colorspace", &(lamp->sky_colorspace)); } else { float constatt = light->getConstantAttenuation().getValue(); @@ -1288,7 +1215,6 @@ bool DocumentImporter::writeLight(const COLLADAFW::Light *light) { /* our sun is very strong, so pick a smaller energy level */ lamp->type = LA_SUN; - lamp->mode |= LA_NO_SPEC; } break; case COLLADAFW::Light::POINT_LIGHT: diff --git a/source/blender/collada/DocumentImporter.h b/source/blender/collada/DocumentImporter.h index fd61f3a68da..758caef7e60 100644 --- a/source/blender/collada/DocumentImporter.h +++ b/source/blender/collada/DocumentImporter.h @@ -77,7 +77,6 @@ public: Object* create_instance_node(Object*, COLLADAFW::Node*, COLLADAFW::Node*, Scene*, bool); void create_constraints(ExtraTags *et, Object *ob); std::vector<Object *> *write_node(COLLADAFW::Node*, COLLADAFW::Node*, Scene*, Object*, bool); - MTex* create_texture(COLLADAFW::EffectCommon*, COLLADAFW::Texture&, Material*, int, TexIndexTextureArrayMap&); void write_profile_COMMON(COLLADAFW::EffectCommon*, Material*); void translate_anim_recursive(COLLADAFW::Node*, COLLADAFW::Node*, Object*); diff --git a/source/blender/collada/EffectExporter.cpp b/source/blender/collada/EffectExporter.cpp index 66f3f81f71f..dbcdfd01a9c 100644 --- a/source/blender/collada/EffectExporter.cpp +++ b/source/blender/collada/EffectExporter.cpp @@ -41,7 +41,6 @@ extern "C" { #include "DNA_mesh_types.h" - #include "DNA_texture_types.h" #include "DNA_world_types.h" #include "BKE_collection.h" @@ -95,128 +94,27 @@ void EffectsExporter::exportEffects(Scene *sce) } } -void EffectsExporter::writeBlinn(COLLADASW::EffectProfile &ep, Material *ma) -{ - COLLADASW::ColorOrTexture cot; - ep.setShaderType(COLLADASW::EffectProfile::BLINN); - // shininess - ep.setShininess(ma->har, false, "shininess"); - // specular - cot = getcol(ma->specr, ma->specg, ma->specb, 1.0f); - ep.setSpecular(cot, false, "specular"); -} - void EffectsExporter::writeLambert(COLLADASW::EffectProfile &ep, Material *ma) { COLLADASW::ColorOrTexture cot; ep.setShaderType(COLLADASW::EffectProfile::LAMBERT); } -void EffectsExporter::writePhong(COLLADASW::EffectProfile &ep, Material *ma) -{ - COLLADASW::ColorOrTexture cot; - ep.setShaderType(COLLADASW::EffectProfile::PHONG); - // shininess - ep.setShininess(ma->har, false, "shininess"); - // specular - cot = getcol(ma->specr, ma->specg, ma->specb, 1.0f); - ep.setSpecular(cot, false, "specular"); -} - -void EffectsExporter::writeTextures( - COLLADASW::EffectProfile &ep, - std::string &key, - COLLADASW::Sampler *sampler, - MTex *t, Image *ima, - std::string &uvname ) -{ - // Image not set for texture - if (!ima) return; - - // color - if (t->mapto & MAP_COL) { - ep.setDiffuse(createTexture(ima, uvname, sampler), false, "diffuse"); - } - // ambient - if (t->mapto & MAP_AMB) { - ep.setAmbient(createTexture(ima, uvname, sampler), false, "ambient"); - } - // specular - if (t->mapto & (MAP_SPEC | MAP_COLSPEC)) { - ep.setSpecular(createTexture(ima, uvname, sampler), false, "specular"); - } - // emission - if (t->mapto & MAP_EMIT) { - ep.setEmission(createTexture(ima, uvname, sampler), false, "emission"); - } - // reflective - if (t->mapto & MAP_REF) { - ep.setReflective(createTexture(ima, uvname, sampler)); - } - // alpha - if (t->mapto & MAP_ALPHA) { - ep.setTransparent(createTexture(ima, uvname, sampler)); - } - // extension: - // Normal map --> Must be stored with <extra> tag as different technique, - // since COLLADA doesn't support normal maps, even in current COLLADA 1.5. - if (t->mapto & MAP_NORM) { - COLLADASW::Texture texture(key); - texture.setTexcoord(uvname); - texture.setSampler(*sampler); - // technique FCOLLADA, with the <bump> tag, is most likely the best understood, - // most widespread de-facto standard. - texture.setProfileName("FCOLLADA"); - texture.setChildElementName("bump"); - ep.addExtraTechniqueColorOrTexture(COLLADASW::ColorOrTexture(texture)); - } -} - void EffectsExporter::operator()(Material *ma, Object *ob) { - // create a list of indices to textures of type TEX_IMAGE - std::vector<int> tex_indices; - if (this->export_settings->include_material_textures) - createTextureIndices(ma, tex_indices); + // TODO: add back texture and extended material parameter support openEffect(translate_id(id_name(ma)) + "-effect"); COLLADASW::EffectProfile ep(mSW); ep.setProfileType(COLLADASW::EffectProfile::COMMON); ep.openProfile(); - // set shader type - one of three blinn, phong or lambert - if (ma->spec > 0.0f) { - if (ma->spec_shader == MA_SPEC_BLINN) { - writeBlinn(ep, ma); - } - else { - // \todo figure out handling of all spec+diff shader combos blender has, for now write phong - // for now set phong in case spec shader is not blinn - writePhong(ep, ma); - } - } - else { - if (ma->diff_shader == MA_DIFF_LAMBERT) { - writeLambert(ep, ma); - } - else { - // \todo figure out handling of all spec+diff shader combos blender has, for now write phong - writePhong(ep, ma); - } - } + writeLambert(ep, ma); - // index of refraction - if (ma->mode & MA_RAYTRANSP) { - ep.setIndexOfRefraction(ma->ang, false, "index_of_refraction"); - } - else { - ep.setIndexOfRefraction(1.0f, false, "index_of_refraction"); - } - COLLADASW::ColorOrTexture cot; // transparency - if (ma->mode & MA_TRANSP) { + if (ma->alpha != 1.0f) { // Tod: because we are in A_ONE mode transparency is calculated like this: cot = getcol(1.0f, 1.0f, 1.0f, ma->alpha); ep.setTransparent(cot); @@ -224,34 +122,14 @@ void EffectsExporter::operator()(Material *ma, Object *ob) } // emission +#if 0 cot = getcol(ma->emit, ma->emit, ma->emit, 1.0f); - ep.setEmission(cot, false, "emission"); +#endif - // diffuse multiplied by diffuse intensity - cot = getcol(ma->r * ma->ref, ma->g * ma->ref, ma->b * ma->ref, 1.0f); + // diffuse + cot = getcol(ma->r, ma->g, ma->b, 1.0f); ep.setDiffuse(cot, false, "diffuse"); - // ambient - /* ma->ambX is calculated only on render, so lets do it here manually and not rely on ma->ambX. */ - if (this->scene->world) - cot = getcol(this->scene->world->ambr * ma->amb, this->scene->world->ambg * ma->amb, this->scene->world->ambb * ma->amb, 1.0f); - else - cot = getcol(ma->amb, ma->amb, ma->amb, 1.0f); - - ep.setAmbient(cot, false, "ambient"); - - // reflective, reflectivity - if (ma->mode & MA_RAYMIRROR) { - cot = getcol(ma->mirr, ma->mirg, ma->mirb, 1.0f); - ep.setReflective(cot); - ep.setReflectivity(ma->ray_mirror); - } - // else { - // cot = getcol(ma->specr, ma->specg, ma->specb, 1.0f); - // ep.setReflective(cot); - // ep.setReflectivity(ma->spec); - // } - // specular if (ep.getShaderType() != COLLADASW::EffectProfile::LAMBERT) { cot = getcol(ma->specr * ma->spec, ma->specg * ma->spec, ma->specb * ma->spec, 1.0f); @@ -260,6 +138,7 @@ void EffectsExporter::operator()(Material *ma, Object *ob) // XXX make this more readable if possible +#if 0 // create <sampler> and <surface> for each image COLLADASW::Sampler samplers[MAX_MTEX]; //COLLADASW::Surface surfaces[MAX_MTEX]; @@ -310,6 +189,7 @@ void EffectsExporter::operator()(Material *ma, Object *ob) b++; } } +#endif // used as fallback when MTex->uvname is "" (this is pretty common) // it is indeed the correct value to use in that case @@ -317,6 +197,7 @@ void EffectsExporter::operator()(Material *ma, Object *ob) // write textures // XXX very slow +#if 0 for (a = 0; a < tex_indices.size(); a++) { MTex *t = ma->mtex[tex_indices[a]]; Image *ima = t->tex->ima; @@ -332,6 +213,7 @@ void EffectsExporter::operator()(Material *ma, Object *ob) COLLADASW::Sampler *sampler = (COLLADASW::Sampler *)samp_surf[i]; writeTextures(ep, key, sampler, t, ima, uvname); } +#endif // performs the actual writing ep.addProfileElements(); @@ -372,20 +254,3 @@ COLLADASW::ColorOrTexture EffectsExporter::getcol(float r, float g, float b, flo COLLADASW::ColorOrTexture cot(color); return cot; } - -//returns the array of mtex indices which have image -//need this for exporting textures -void EffectsExporter::createTextureIndices(Material *ma, std::vector<int> &indices) -{ - indices.clear(); - - for (int a = 0; a < MAX_MTEX; a++) { - if (ma->mtex[a] && - ma->mtex[a]->tex && - ma->mtex[a]->tex->type == TEX_IMAGE && - ma->mtex[a]->texco == TEXCO_UV) - { - indices.push_back(a); - } - } -} diff --git a/source/blender/collada/EffectExporter.h b/source/blender/collada/EffectExporter.h index d20cbfdfe0b..eac428ae330 100644 --- a/source/blender/collada/EffectExporter.h +++ b/source/blender/collada/EffectExporter.h @@ -58,12 +58,7 @@ public: COLLADASW::ColorOrTexture getcol(float r, float g, float b, float a); private: - /** Fills the array of mtex indices which have image. Used for exporting images. */ - void createTextureIndices(Material *ma, std::vector<int> &indices); - - void writeBlinn(COLLADASW::EffectProfile &ep, Material *ma); void writeLambert(COLLADASW::EffectProfile &ep, Material *ma); - void writePhong(COLLADASW::EffectProfile &ep, Material *ma); void writeTextures(COLLADASW::EffectProfile &ep, std::string &key, COLLADASW::Sampler *sampler, diff --git a/source/blender/collada/ImageExporter.cpp b/source/blender/collada/ImageExporter.cpp index 3cdc013c137..657037a869a 100644 --- a/source/blender/collada/ImageExporter.cpp +++ b/source/blender/collada/ImageExporter.cpp @@ -164,12 +164,7 @@ bool ImagesExporter::hasImages(Scene *sce) // no material, but check all of the slots if (!ma) continue; - int b; - for (b = 0; b < MAX_MTEX; b++) { - MTex *mtex = ma->mtex[b]; - if (mtex && mtex->tex && mtex->tex->ima) return true; - } - + // TODO: find image textures in shader nodes } } return false; @@ -191,13 +186,6 @@ void ImagesExporter::exportImages(Scene *sce) void ImagesExporter::operator()(Material *ma, Object *ob) { - int a; - bool use_texture_copies = this->export_settings->use_texture_copies; - for (a = 0; a < MAX_MTEX; a++) { - MTex *mtex = ma->mtex[a]; - if (mtex && mtex->tex && mtex->tex->ima) { - Image *image = mtex->tex->ima; - export_UV_Image(image, use_texture_copies); - } - } + // bool use_texture_copies = this->export_settings->use_texture_copies; + // TODO call export_UV_Image for every image in shader nodes } diff --git a/source/blender/collada/LightExporter.cpp b/source/blender/collada/LightExporter.cpp index ff50abfedae..d17941574d7 100644 --- a/source/blender/collada/LightExporter.cpp +++ b/source/blender/collada/LightExporter.cpp @@ -149,7 +149,6 @@ bool LightsExporter::exportBlenderProfile(COLLADASW::Light &cla, Lamp *la) cla.addExtraTechniqueParameter("blender", "dist", la->dist, "blender_dist"); cla.addExtraTechniqueParameter("blender", "spotsize", RAD2DEGF(la->spotsize)); cla.addExtraTechniqueParameter("blender", "spotblend", la->spotblend); - cla.addExtraTechniqueParameter("blender", "halo_intensity", la->haint, "blnder_halo_intensity"); cla.addExtraTechniqueParameter("blender", "att1", la->att1); cla.addExtraTechniqueParameter("blender", "att2", la->att2); // \todo figure out how we can have falloff curve supported here @@ -158,38 +157,13 @@ bool LightsExporter::exportBlenderProfile(COLLADASW::Light &cla, Lamp *la) cla.addExtraTechniqueParameter("blender", "clipend", la->clipend); cla.addExtraTechniqueParameter("blender", "bias", la->bias); cla.addExtraTechniqueParameter("blender", "soft", la->soft); - cla.addExtraTechniqueParameter("blender", "compressthresh", la->compressthresh); cla.addExtraTechniqueParameter("blender", "bufsize", la->bufsize); cla.addExtraTechniqueParameter("blender", "samp", la->samp); cla.addExtraTechniqueParameter("blender", "buffers", la->buffers); - cla.addExtraTechniqueParameter("blender", "filtertype", la->filtertype); - cla.addExtraTechniqueParameter("blender", "bufflag", la->bufflag); - cla.addExtraTechniqueParameter("blender", "buftype", la->buftype); - cla.addExtraTechniqueParameter("blender", "ray_samp", la->ray_samp); - cla.addExtraTechniqueParameter("blender", "ray_sampy", la->ray_sampy); - cla.addExtraTechniqueParameter("blender", "ray_sampz", la->ray_sampz); - cla.addExtraTechniqueParameter("blender", "ray_samp_type", la->ray_samp_type); cla.addExtraTechniqueParameter("blender", "area_shape", la->area_shape); cla.addExtraTechniqueParameter("blender", "area_size", la->area_size); cla.addExtraTechniqueParameter("blender", "area_sizey", la->area_sizey); cla.addExtraTechniqueParameter("blender", "area_sizez", la->area_sizez); - cla.addExtraTechniqueParameter("blender", "adapt_thresh", la->adapt_thresh); - cla.addExtraTechniqueParameter("blender", "ray_samp_method", la->ray_samp_method); - cla.addExtraTechniqueParameter("blender", "shadhalostep", la->shadhalostep); - cla.addExtraTechniqueParameter("blender", "sun_effect_type", la->shadhalostep); - cla.addExtraTechniqueParameter("blender", "skyblendtype", la->skyblendtype); - cla.addExtraTechniqueParameter("blender", "horizon_brightness", la->horizon_brightness); - cla.addExtraTechniqueParameter("blender", "spread", la->spread); - cla.addExtraTechniqueParameter("blender", "sun_brightness", la->sun_brightness); - cla.addExtraTechniqueParameter("blender", "sun_size", la->sun_size); - cla.addExtraTechniqueParameter("blender", "backscattered_light", la->backscattered_light); - cla.addExtraTechniqueParameter("blender", "sun_intensity", la->sun_intensity); - cla.addExtraTechniqueParameter("blender", "atm_turbidity", la->atm_turbidity); - cla.addExtraTechniqueParameter("blender", "atm_extinction_factor", la->atm_extinction_factor); - cla.addExtraTechniqueParameter("blender", "atm_distance_factor", la->atm_distance_factor); - cla.addExtraTechniqueParameter("blender", "skyblendfac", la->skyblendfac); - cla.addExtraTechniqueParameter("blender", "sky_exposure", la->sky_exposure); - cla.addExtraTechniqueParameter("blender", "sky_colorspace", la->sky_colorspace); return true; } diff --git a/source/blender/collada/MeshImporter.cpp b/source/blender/collada/MeshImporter.cpp index 339c8cec191..10b9745a6b9 100644 --- a/source/blender/collada/MeshImporter.cpp +++ b/source/blender/collada/MeshImporter.cpp @@ -879,48 +879,6 @@ std::string *MeshImporter::get_geometry_name(const std::string &mesh_name) return NULL; } -MTex *MeshImporter::assign_textures_to_uvlayer(COLLADAFW::TextureCoordinateBinding &ctexture, - Mesh *me, TexIndexTextureArrayMap& texindex_texarray_map, - MTex *color_texture) -{ - const COLLADAFW::TextureMapId texture_index = ctexture.getTextureMapId(); - size_t setindex = ctexture.getSetIndex(); - std::string uvname = ctexture.getSemantic(); - - if (setindex == -1) return NULL; - - const CustomData *data = &me->fdata; - int layer_index = CustomData_get_layer_index(data, CD_MTFACE); - - if (layer_index == -1) return NULL; - - CustomDataLayer *cdl = &data->layers[layer_index + setindex]; - - /* set uvname to bind_vertex_input semantic */ - BLI_strncpy(cdl->name, uvname.c_str(), sizeof(cdl->name)); - - if (texindex_texarray_map.find(texture_index) == texindex_texarray_map.end()) { - - fprintf(stderr, "Cannot find texture array by texture index.\n"); - return color_texture; - } - - std::vector<MTex *> textures = texindex_texarray_map[texture_index]; - - std::vector<MTex *>::iterator it; - - for (it = textures.begin(); it != textures.end(); it++) { - - MTex *texture = *it; - - if (texture) { - BLI_strncpy(texture->uvname, uvname.c_str(), sizeof(texture->uvname)); - if (texture->mapto == MAP_COL) color_texture = texture; - } - } - return color_texture; -} - /** * this function checks if both objects have the same * materials assigned to Object (in the same order) @@ -1058,10 +1016,8 @@ void MeshImporter::assign_material_to_geom( COLLADAFW::MaterialBinding cmaterial, std::map<COLLADAFW::UniqueId, Material *>& uid_material_map, Object *ob, const COLLADAFW::UniqueId *geom_uid, - std::map<Material *, TexIndexTextureArrayMap>& material_texture_mapping_map, short mat_index) + short mat_index) { - MTex *color_texture = NULL; - Mesh *me = (Mesh *)ob->data; const COLLADAFW::UniqueId& ma_uid = cmaterial.getReferencedMaterial(); // do we know this material? @@ -1081,17 +1037,6 @@ void MeshImporter::assign_material_to_geom( ob->actcol=0; assign_material(ob, ma, mat_index + 1, BKE_MAT_ASSIGN_OBJECT); - COLLADAFW::TextureCoordinateBindingArray& tex_array = - cmaterial.getTextureCoordinateBindingArray(); - TexIndexTextureArrayMap texindex_texarray_map = material_texture_mapping_map[ma]; - unsigned int i; - // loop through <bind_vertex_inputs> - for (i = 0; i < tex_array.getCount(); i++) { - - color_texture = assign_textures_to_uvlayer(tex_array[i], me, texindex_texarray_map, - color_texture); - } - MaterialIdPrimitiveArrayMap& mat_prim_map = geom_uid_mat_mapping_map[*geom_uid]; COLLADAFW::MaterialId mat_id = cmaterial.getMaterialId(); @@ -1106,7 +1051,7 @@ void MeshImporter::assign_material_to_geom( Primitive& prim = *it; MPoly *mpoly = prim.mpoly; - for (i = 0; i < prim.totpoly; i++, mpoly++) { + for (int i = 0; i < prim.totpoly; i++, mpoly++) { mpoly->mat_nr = mat_index; } } @@ -1115,8 +1060,7 @@ void MeshImporter::assign_material_to_geom( Object *MeshImporter::create_mesh_object(COLLADAFW::Node *node, COLLADAFW::InstanceGeometry *geom, bool isController, - std::map<COLLADAFW::UniqueId, Material *>& uid_material_map, - std::map<Material *, TexIndexTextureArrayMap>& material_texture_mapping_map) + std::map<COLLADAFW::UniqueId, Material *>& uid_material_map) { const COLLADAFW::UniqueId *geom_uid = &geom->getInstanciatedObjectId(); @@ -1173,7 +1117,7 @@ Object *MeshImporter::create_mesh_object(COLLADAFW::Node *node, COLLADAFW::Insta if (mat_array[i].getReferencedMaterial().isValid()) { assign_material_to_geom( mat_array[i], uid_material_map, ob, geom_uid, - material_texture_mapping_map, i); + i); } else { fprintf(stderr, "invalid referenced material for %s\n", mat_array[i].getName().c_str()); diff --git a/source/blender/collada/MeshImporter.h b/source/blender/collada/MeshImporter.h index f57f57e07a7..09b3005d795 100644 --- a/source/blender/collada/MeshImporter.h +++ b/source/blender/collada/MeshImporter.h @@ -51,7 +51,6 @@ extern "C" { #include "DNA_meshdata_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" -#include "DNA_texture_types.h" } @@ -167,23 +166,18 @@ public: virtual Mesh *get_mesh_by_geom_uid(const COLLADAFW::UniqueId& geom_uid); - MTex *assign_textures_to_uvlayer(COLLADAFW::TextureCoordinateBinding &ctexture, - Mesh *me, TexIndexTextureArrayMap& texindex_texarray_map, - MTex *color_texture); - void optimize_material_assignements(); void assign_material_to_geom( COLLADAFW::MaterialBinding cmaterial, std::map<COLLADAFW::UniqueId, Material*>& uid_material_map, Object *ob, const COLLADAFW::UniqueId *geom_uid, - std::map<Material*, TexIndexTextureArrayMap>& material_texture_mapping_map, short mat_index); + short mat_index); Object *create_mesh_object(COLLADAFW::Node *node, COLLADAFW::InstanceGeometry *geom, bool isController, - std::map<COLLADAFW::UniqueId, Material*>& uid_material_map, - std::map<Material*, TexIndexTextureArrayMap>& material_texture_mapping_map); + std::map<COLLADAFW::UniqueId, Material*>& uid_material_map); // create a mesh storing a pointer in a map so it can be retrieved later by geometry UID bool write_geometry(const COLLADAFW::Geometry* geom); diff --git a/source/blender/collada/collada_utils.cpp b/source/blender/collada/collada_utils.cpp index 670dcba0a24..778ead55c8d 100644 --- a/source/blender/collada/collada_utils.cpp +++ b/source/blender/collada/collada_utils.cpp @@ -952,127 +952,3 @@ std::string bc_get_uvlayer_name(Mesh *me, int layer) } return ""; } - -#if 0 -/********************************************************************** -* -* Return the list of Mesh objects with assigned UVtextures and Images -* Note: We need to create artificaial materials for each of them -* -***********************************************************************/ -std::set<Object *> bc_getUVTexturedObjects(Scene *sce, bool all_uv_layers) -{ - std::set <Object *> UVObjects; - Base *base = (Base *)sce->base.first; - - while (base) { - Object *ob = base->object; - bool has_uvimage = false; - if (ob->type == OB_MESH) { - Mesh *me = (Mesh *)ob->data; - int active_uv_layer = CustomData_get_active_layer_index(&me->pdata, CD_MTEXPOLY); - - for (int i = 0; i < me->pdata.totlayer && !has_uvimage; i++) { - if (all_uv_layers || active_uv_layer == i) - { - if (me->pdata.layers[i].type == CD_MTEXPOLY) { - MTexPoly *txface = (MTexPoly *)me->pdata.layers[i].data; - MPoly *mpoly = me->mpoly; - for (int j = 0; j < me->totpoly; j++, mpoly++, txface++) { - - Image *ima = txface->tpage; - if (ima != NULL) { - has_uvimage = true; - break; - } - } - } - } - } - - if (has_uvimage) { - UVObjects.insert(ob); - } - } - base = base->next; - } - return UVObjects; -} - -/********************************************************************** -* -* Return the list of UV Texture images from all exported Mesh Items -* Note: We need to create one artificial material for each Image. -* -***********************************************************************/ -std::set<Image *> bc_getUVImages(Scene *sce, bool all_uv_layers) -{ - std::set <Image *> UVImages; - Base *base = (Base *)sce->base.first; - - while (base) { - Object *ob = base->object; - bool has_uvimage = false; - if (ob->type == OB_MESH) { - Mesh *me = (Mesh *)ob->data; - int active_uv_layer = CustomData_get_active_layer_index(&me->pdata, CD_MTEXPOLY); - - for (int i = 0; i < me->pdata.totlayer && !has_uvimage; i++) { - if (all_uv_layers || active_uv_layer == i) - { - if (me->pdata.layers[i].type == CD_MTEXPOLY) { - MTexPoly *txface = (MTexPoly *)me->pdata.layers[i].data; - MPoly *mpoly = me->mpoly; - for (int j = 0; j < me->totpoly; j++, mpoly++, txface++) { - - Image *ima = txface->tpage; - if (ima != NULL) { - if (UVImages.find(ima) == UVImages.end()) - UVImages.insert(ima); - } - } - } - } - } - } - base = base->next; - } - return UVImages; -} - -/********************************************************************** -* -* Return the list of UV Texture images for the given Object -* Note: We need to create one artificial material for each Image. -* -***********************************************************************/ -std::set<Image *> bc_getUVImages(Object *ob, bool all_uv_layers) -{ - std::set <Image *> UVImages; - - bool has_uvimage = false; - if (ob->type == OB_MESH) { - Mesh *me = (Mesh *)ob->data; - int active_uv_layer = CustomData_get_active_layer_index(&me->pdata, CD_MTEXPOLY); - - for (int i = 0; i < me->pdata.totlayer && !has_uvimage; i++) { - if (all_uv_layers || active_uv_layer == i) - { - if (me->pdata.layers[i].type == CD_MTEXPOLY) { - MTexPoly *txface = (MTexPoly *)me->pdata.layers[i].data; - MPoly *mpoly = me->mpoly; - for (int j = 0; j < me->totpoly; j++, mpoly++, txface++) { - - Image *ima = txface->tpage; - if (ima != NULL) { - if (UVImages.find(ima) == UVImages.end()) - UVImages.insert(ima); - } - } - } - } - } - } - return UVImages; -} -#endif diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc index 2e251c84fda..cbe11f8d7fa 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc @@ -786,8 +786,6 @@ void DepsgraphNodeBuilder::build_world(World *world) _1, get_cow_datablock(world)), DEG_OPCODE_WORLD_UPDATE); - /* textures */ - build_texture_stack(world->mtex); /* world's nodetree */ if (world->nodetree != NULL) { build_nodetree(world->nodetree); @@ -1192,8 +1190,6 @@ void DepsgraphNodeBuilder::build_lamp(Object *object) DEG_OPCODE_PARAMETERS_EVAL); /* lamp's nodetree */ build_nodetree(lamp->nodetree); - /* textures */ - build_texture_stack(lamp->mtex); } void DepsgraphNodeBuilder::build_nodetree(bNodeTree *ntree) @@ -1281,24 +1277,10 @@ void DepsgraphNodeBuilder::build_material(Material *material) DEG_OPCODE_MATERIAL_UPDATE); /* Material animation. */ build_animdata(&material->id); - /* Textures. */ - build_texture_stack(material->mtex); /* Material's nodetree. */ build_nodetree(material->nodetree); } -/* Texture-stack attached to some shading datablock */ -void DepsgraphNodeBuilder::build_texture_stack(MTex **texture_stack) -{ - /* for now assume that all texture-stacks have same number of max items */ - for (int i = 0; i < MAX_MTEX; i++) { - MTex *mtex = texture_stack[i]; - if (mtex && mtex->tex) { - build_texture(mtex->tex); - } - } -} - /* Recursively build graph for texture */ void DepsgraphNodeBuilder::build_texture(Tex *texture) { diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h index 0180aa3b734..0ed3f5e334f 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h @@ -195,7 +195,6 @@ struct DepsgraphNodeBuilder { void build_nodetree(bNodeTree *ntree); void build_material(Material *ma); void build_texture(Tex *tex); - void build_texture_stack(MTex **texture_stack); void build_image(Image *image); void build_world(World *world); void build_compositor(Scene *scene); diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index ff1728eb89f..9577702e4bd 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -1259,8 +1259,6 @@ void DepsgraphRelationBuilder::build_world(World *world) } build_animdata(&world->id); /* TODO: other settings? */ - /* textures */ - build_texture_stack(world->mtex); /* world's nodetree */ if (world->nodetree != NULL) { build_nodetree(world->nodetree); @@ -1799,8 +1797,6 @@ void DepsgraphRelationBuilder::build_lamp(Object *object) ComponentKey nodetree_key(&lamp->nodetree->id, DEG_NODE_TYPE_SHADING); add_relation(nodetree_key, lamp_parameters_key, "NTree->Lamp Parameters"); } - /* textures */ - build_texture_stack(lamp->mtex); if (DEG_depsgraph_use_copy_on_write()) { /* Make sure copy on write of lamp data is always properly updated for @@ -1882,8 +1878,6 @@ void DepsgraphRelationBuilder::build_material(Material *material) } /* animation */ build_animdata(&material->id); - /* textures */ - build_texture_stack(material->mtex); /* material's nodetree */ if (material->nodetree != NULL) { build_nodetree(material->nodetree); @@ -1909,17 +1903,6 @@ void DepsgraphRelationBuilder::build_texture(Tex *texture) build_nodetree(texture->nodetree); } -/* Texture-stack attached to some shading datablock */ -void DepsgraphRelationBuilder::build_texture_stack(MTex **texture_stack) -{ - /* for now assume that all texture-stacks have same number of max items */ - for (int i = 0; i < MAX_MTEX; i++) { - MTex *mtex = texture_stack[i]; - if (mtex && mtex->tex) - build_texture(mtex->tex); - } -} - void DepsgraphRelationBuilder::build_compositor(Scene *scene) { /* For now, just a plain wrapper? */ diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.h b/source/blender/depsgraph/intern/builder/deg_builder_relations.h index df6fb100d22..ed2d4b1162f 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.h @@ -243,7 +243,6 @@ struct DepsgraphRelationBuilder void build_nodetree(bNodeTree *ntree); void build_material(Material *ma); void build_texture(Tex *tex); - void build_texture_stack(MTex **texture_stack); void build_compositor(Scene *scene); void build_gpencil(bGPdata *gpd); void build_cachefile(CacheFile *cache_file); diff --git a/source/blender/draw/intern/draw_manager_shader.c b/source/blender/draw/intern/draw_manager_shader.c index a0c8cd4195a..06a579c2208 100644 --- a/source/blender/draw/intern/draw_manager_shader.c +++ b/source/blender/draw/intern/draw_manager_shader.c @@ -352,8 +352,7 @@ GPUMaterial *DRW_shader_create_from_world( if (mat == NULL) { mat = GPU_material_from_nodetree( - scene, wo->nodetree, &wo->gpumaterial, engine_type, options, - vert, geom, frag_lib, defines, true); + scene, wo->nodetree, &wo->gpumaterial, engine_type, options); } drw_deferred_shader_add(mat, vert, geom, frag_lib, defines); @@ -372,8 +371,7 @@ GPUMaterial *DRW_shader_create_from_material( if (mat == NULL) { mat = GPU_material_from_nodetree( - scene, ma->nodetree, &ma->gpumaterial, engine_type, options, - vert, geom, frag_lib, defines, true); + scene, ma->nodetree, &ma->gpumaterial, engine_type, options); } drw_deferred_shader_add(mat, vert, geom, frag_lib, defines); diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c index b7d20fd48d1..d7419dd4717 100644 --- a/source/blender/draw/modes/object_mode.c +++ b/source/blender/draw/modes/object_mode.c @@ -1367,11 +1367,9 @@ static void DRW_shgroup_lamp(OBJECT_StorageList *stl, Object *ob, ViewLayer *vie /* First circle */ DRW_shgroup_call_dynamic_add(stl->g_data->lamp_circle, ob->obmat[3], color); - /* draw dashed outer circle if shadow is on. remember some lamps can't have certain shadows! */ + /* draw dashed outer circle for shadow */ if (la->type != LA_HEMI) { - if ((la->mode & LA_SHAD_RAY) || ((la->mode & LA_SHAD_BUF) && (la->type == LA_SPOT))) { - DRW_shgroup_call_dynamic_add(stl->g_data->lamp_circle_shadow, ob->obmat[3], color); - } + DRW_shgroup_call_dynamic_add(stl->g_data->lamp_circle_shadow, ob->obmat[3], color); } /* Distance */ diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index 85bcfb603cd..2a5c01fc671 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -2062,24 +2062,6 @@ static size_t animdata_filter_ds_textures(bAnimContext *ac, ListBase *anim_data, return 0; switch (GS(owner_id->name)) { - case ID_MA: - { - Material *ma = (Material *)owner_id; - mtex = (MTex **)(&ma->mtex); - break; - } - case ID_LA: - { - Lamp *la = (Lamp *)owner_id; - mtex = (MTex **)(&la->mtex); - break; - } - case ID_WO: - { - World *wo = (World *)owner_id; - mtex = (MTex **)(&wo->mtex); - break; - } case ID_PA: { ParticleSettings *part = (ParticleSettings *)owner_id; diff --git a/source/blender/editors/include/ED_buttons.h b/source/blender/editors/include/ED_buttons.h index 64c16605dec..5cc695b6ce8 100644 --- a/source/blender/editors/include/ED_buttons.h +++ b/source/blender/editors/include/ED_buttons.h @@ -27,14 +27,4 @@ #ifndef __ED_BUTTONS_H__ #define __ED_BUTTONS_H__ -#include "BLI_utildefines.h" - -/* Used to check whether a given texture context is valid in current context. */ -bool ED_texture_context_check_world(const struct bContext *C); -bool ED_texture_context_check_material(const struct bContext *C); -bool ED_texture_context_check_lamp(const struct bContext *C); -bool ED_texture_context_check_particles(const struct bContext *C); -bool ED_texture_context_check_linestyle(const struct bContext *C); -bool ED_texture_context_check_others(const struct bContext *C); - #endif /* __ED_BUTTONS_H__ */ diff --git a/source/blender/editors/include/ED_render.h b/source/blender/editors/include/ED_render.h index b7317d75cd4..2615847e90a 100644 --- a/source/blender/editors/include/ED_render.h +++ b/source/blender/editors/include/ED_render.h @@ -54,7 +54,6 @@ void ED_render_engine_area_exit(struct Main *bmain, struct ScrArea *sa); void ED_render_id_flush_update(const struct DEGEditorUpdateContext *update_ctx, struct ID *id); void ED_render_scene_update(const struct DEGEditorUpdateContext *update_ctx, int updated); -void ED_viewport_render_kill_jobs(struct wmWindowManager *wm, struct Main *bmain, bool free_database); struct Scene *ED_render_job_get_scene(const struct bContext *C); struct Scene *ED_render_job_get_current_scene(const struct bContext *C); diff --git a/source/blender/editors/include/ED_uvedit.h b/source/blender/editors/include/ED_uvedit.h index fd532e70478..d6e8b6e9504 100644 --- a/source/blender/editors/include/ED_uvedit.h +++ b/source/blender/editors/include/ED_uvedit.h @@ -50,8 +50,6 @@ struct wmKeyConfig; void ED_operatortypes_uvedit(void); void ED_keymap_uvedit(struct wmKeyConfig *keyconf); -void ED_uvedit_assign_image( - struct Main *bmain, struct Scene *scene, struct Object *obedit, struct Image *ima, struct Image *previma); bool ED_uvedit_minmax(struct Scene *scene, struct Image *ima, struct Object *obedit, float min[2], float max[2]); bool ED_uvedit_center(Scene *scene, Image *ima, struct Object *obedit, float cent[2], char mode); void ED_uvedit_select_all(struct BMesh *bm); diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index 9cc4cb692e3..3ab08967a0d 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -382,15 +382,11 @@ void ED_draw_object_facemap(struct Depsgraph *depsgraph, struct Scene *scene, s struct RenderEngineType *ED_view3d_engine_type(struct Scene *scene, int drawtype); bool ED_view3d_context_activate(struct bContext *C); -void ED_view3d_draw_offscreen_init( - struct Depsgraph *depsgraph, struct Scene *scene, - struct ViewLayer *view_layer, struct View3D *v3d, - int drawtype); void ED_view3d_draw_offscreen( struct Depsgraph *depsgraph, struct Scene *scene, - struct ViewLayer *view_layer, int drawtype, + int drawtype, struct View3D *v3d, struct ARegion *ar, int winx, int winy, float viewmat[4][4], - float winmat[4][4], bool do_bgpic, bool do_sky, bool is_persp, const char *viewname, + float winmat[4][4], bool do_sky, bool is_persp, const char *viewname, struct GPUFXSettings *fx_settings, struct GPUOffScreen *ofs, struct GPUViewport *viewport); void ED_view3d_draw_setup_view( @@ -400,25 +396,24 @@ void ED_view3d_draw_setup_view( enum { V3D_OFSDRAW_NONE = (0), - V3D_OFSDRAW_USE_BACKGROUND = (1 << 0), - V3D_OFSDRAW_USE_FULL_SAMPLE = (1 << 1), + V3D_OFSDRAW_USE_FULL_SAMPLE = (1 << 0), /* Only works with ED_view3d_draw_offscreen_imbuf_simple(). */ - V3D_OFSDRAW_USE_GPENCIL = (1 << 2), + V3D_OFSDRAW_USE_GPENCIL = (1 << 1), V3D_OFSDRAW_USE_SOLID_TEX = (1 << 2), V3D_OFSDRAW_USE_CAMERA_DOF = (1 << 3), }; struct ImBuf *ED_view3d_draw_offscreen_imbuf( struct Depsgraph *depsgraph, struct Scene *scene, - struct ViewLayer *view_layer, int drawtype, + int drawtype, struct View3D *v3d, struct ARegion *ar, int sizex, int sizey, unsigned int flag, unsigned int draw_flags, int alpha_mode, int samples, const char *viewname, struct GPUOffScreen *ofs, char err_out[256]); struct ImBuf *ED_view3d_draw_offscreen_imbuf_simple( struct Depsgraph *depsgraph, struct Scene *scene, - struct ViewLayer *view_layer, int drawtype, + int drawtype, struct Object *camera, int width, int height, unsigned int flag, unsigned int draw_flags, int alpha_mode, int samples, const char *viewname, diff --git a/source/blender/editors/io/io_collada.c b/source/blender/editors/io/io_collada.c index 576b24ed4b4..a3cbdb57fed 100644 --- a/source/blender/editors/io/io_collada.c +++ b/source/blender/editors/io/io_collada.c @@ -184,6 +184,7 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op) export_settings.sampling_rate = sampling_rate; export_settings.active_uv_only = active_uv_only != 0; + export_settings.include_material_textures = include_material_textures != 0; export_settings.use_texture_copies = use_texture_copies != 0; export_settings.triangulate = triangulate != 0; diff --git a/source/blender/editors/mesh/editface.c b/source/blender/editors/mesh/editface.c index 53f21a1e32f..6d1f478249a 100644 --- a/source/blender/editors/mesh/editface.c +++ b/source/blender/editors/mesh/editface.c @@ -51,7 +51,6 @@ #include "WM_types.h" #include "GPU_draw.h" -#include "GPU_buffers.h" /* own include */ @@ -99,11 +98,6 @@ void paintface_flush_flags(Object *ob, short flag) } } - if (flag & ME_HIDE) { - /* draw-object caches hidden faces, force re-generation T46867 */ - GPU_drawobject_free(dm); - } - BKE_mesh_batch_cache_dirty(me, BKE_MESH_BATCH_DIRTY_ALL); } diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 94365be6b2e..dbf38864730 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -5605,84 +5605,6 @@ void MESH_OT_sort_elements(wmOperatorType *ot) /** \} */ /* -------------------------------------------------------------------- */ -/** \name Noise (Deform Vertices) Operator - * \{ */ - -static int edbm_noise_exec(bContext *C, wmOperator *op) -{ - Object *obedit = CTX_data_edit_object(C); - BMEditMesh *em = BKE_editmesh_from_object(obedit); - Material *ma; - Tex *tex; - BMVert *eve; - BMIter iter; - const float fac = RNA_float_get(op->ptr, "factor"); - - if (em == NULL) { - return OPERATOR_FINISHED; - } - - if ((ma = give_current_material(obedit, obedit->actcol)) == NULL || - (tex = give_current_material_texture(ma)) == NULL) - { - BKE_report(op->reports, RPT_WARNING, "Mesh has no material or texture assigned"); - return OPERATOR_FINISHED; - } - - if (tex->type == TEX_STUCCI) { - float b2, vec[3]; - float ofs = tex->turbul / 200.0f; - BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) { - if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { - b2 = BLI_hnoise(tex->noisesize, eve->co[0], eve->co[1], eve->co[2]); - if (tex->stype) ofs *= (b2 * b2); - vec[0] = fac * (b2 - BLI_hnoise(tex->noisesize, eve->co[0] + ofs, eve->co[1], eve->co[2])); - vec[1] = fac * (b2 - BLI_hnoise(tex->noisesize, eve->co[0], eve->co[1] + ofs, eve->co[2])); - vec[2] = fac * (b2 - BLI_hnoise(tex->noisesize, eve->co[0], eve->co[1], eve->co[2] + ofs)); - - add_v3_v3(eve->co, vec); - } - } - } - else { - BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) { - if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { - float tin = 0.0f, dum; - if (ma->mtex[ma->texact] != NULL) { - externtex(ma->mtex[ma->texact], eve->co, &tin, &dum, &dum, &dum, &dum, 0, NULL, false, false); - } - eve->co[2] += fac * tin; - } - } - } - - EDBM_mesh_normals_update(em); - - EDBM_update_generic(em, true, false); - - return OPERATOR_FINISHED; -} - -void MESH_OT_noise(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Noise"; - ot->description = "Use vertex coordinate as texture coordinate"; - ot->idname = "MESH_OT_noise"; - - /* api callbacks */ - ot->exec = edbm_noise_exec; - ot->poll = ED_operator_editmesh; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - RNA_def_float(ot->srna, "factor", 0.1f, -1e4f, 1e4f, "Factor", "", 0.0f, 1.0f); -} - -/** \} */ - -/* -------------------------------------------------------------------- */ /** \name Bridge Operator * \{ */ diff --git a/source/blender/editors/mesh/mesh_data.c b/source/blender/editors/mesh/mesh_data.c index 69e265f7315..676af4fea5b 100644 --- a/source/blender/editors/mesh/mesh_data.c +++ b/source/blender/editors/mesh/mesh_data.c @@ -538,7 +538,6 @@ void MESH_OT_uv_texture_add(wmOperatorType *ot) static int drop_named_image_invoke(bContext *C, wmOperator *op, const wmEvent *event) { - Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); Base *base; @@ -578,8 +577,6 @@ static int drop_named_image_invoke(bContext *C, wmOperator *op, const wmEvent *e if (me->edit_btmesh == NULL) return OPERATOR_CANCELLED; - ED_uvedit_assign_image(bmain, scene, obedit, ima, NULL); - if (exitmode) { EDBM_mesh_load(obedit); EDBM_mesh_free(me->edit_btmesh); diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h index 788887e872a..87a17eb8fd4 100644 --- a/source/blender/editors/mesh/mesh_intern.h +++ b/source/blender/editors/mesh/mesh_intern.h @@ -210,7 +210,6 @@ void MESH_OT_hide(struct wmOperatorType *ot); void MESH_OT_reveal(struct wmOperatorType *ot); void MESH_OT_mark_seam(struct wmOperatorType *ot); void MESH_OT_mark_sharp(struct wmOperatorType *ot); -void MESH_OT_noise(struct wmOperatorType *ot); void MESH_OT_flip_normals(struct wmOperatorType *ot); void MESH_OT_solidify(struct wmOperatorType *ot); void MESH_OT_knife_cut(struct wmOperatorType *ot); diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c index a2c996c7f42..6f663ddbf14 100644 --- a/source/blender/editors/mesh/mesh_ops.c +++ b/source/blender/editors/mesh/mesh_ops.c @@ -141,7 +141,6 @@ void ED_operatortypes_mesh(void) #endif WM_operatortype_append(MESH_OT_vertices_smooth); WM_operatortype_append(MESH_OT_vertices_smooth_laplacian); - WM_operatortype_append(MESH_OT_noise); WM_operatortype_append(MESH_OT_flip_normals); WM_operatortype_append(MESH_OT_rip); WM_operatortype_append(MESH_OT_rip_edge); diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index 6f9f18d301e..7327c563104 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -115,8 +115,6 @@ #include "UI_resources.h" -#include "GPU_lamp.h" - #include "object_intern.h" /* this is an exact copy of the define in rna_lamp.c @@ -1019,7 +1017,7 @@ static int object_lamp_add_exec(bContext *C, wmOperator *op) la = (Lamp *)ob->data; la->type = type; - if (BKE_scene_use_new_shading_nodes(scene)) { + if (BKE_scene_uses_cycles(scene)) { ED_node_shader_default(C, &la->id); la->use_nodes = true; } @@ -1184,17 +1182,6 @@ void OBJECT_OT_speaker_add(wmOperatorType *ot) /**************************** Delete Object *************************/ -static void object_delete_check_glsl_update(Object *ob) -{ - /* some objects could affect on GLSL shading, make sure GLSL settings - * are being tagged to be updated when object is removing from scene - */ - if (ob->type == OB_LAMP) { - if (ob->gpulamp.first) - GPU_lamp_free(ob); - } -} - /* remove base from a specific scene */ /* note: now unlinks constraints as well */ void ED_object_base_free_and_unlink(Main *bmain, Scene *scene, Object *ob) @@ -1210,7 +1197,6 @@ void ED_object_base_free_and_unlink(Main *bmain, Scene *scene, Object *ob) DEG_id_tag_update_ex(bmain, &ob->id, DEG_TAG_BASE_FLAGS_UPDATE); - object_delete_check_glsl_update(ob); BKE_collections_object_remove(bmain, &scene->id, ob, true); } diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c index a38b9959dab..b10b35618fb 100644 --- a/source/blender/editors/object/object_bake.c +++ b/source/blender/editors/object/object_bake.c @@ -79,9 +79,26 @@ #include "ED_object.h" #include "ED_screen.h" +#include "ED_uvedit.h" #include "object_intern.h" +static Image *bake_object_image_get(Object *ob, int mat_nr) +{ + Image *image = NULL; + ED_object_get_active_image(ob, mat_nr + 1, &image, NULL, NULL, NULL); + return image; +} + +static Image **bake_object_image_get_array(Object *ob) +{ + Image **image_array = MEM_mallocN(sizeof(Material *) * ob->totcol, __func__); + for (int i = 0; i < ob->totcol; i++) { + image_array[i] = bake_object_image_get(ob, i); + } + return image_array; +} + /* ****************** multires BAKING ********************** */ /* holder of per-object data needed for bake job @@ -108,8 +125,6 @@ typedef struct { bool use_lores_mesh; /* Use low-resolution mesh when baking displacement maps */ int number_of_rays; /* Number of rays to be cast when doing AO baking */ float bias; /* Bias between object and start ray point when doing AO baking */ - int raytrace_structure; /* Optimization structure to be used for AO baking */ - int octree_resolution; /* Reslution of octotree when using octotree optimization structure */ int threads; /* Number of threads to be used for baking */ float user_scale; /* User scale used to scale displacement when baking derivative map. */ } MultiresBakeJob; @@ -167,7 +182,7 @@ static bool multiresbake_check(bContext *C, wmOperator *op) else { a = me->totpoly; while (ok && a--) { - Image *ima = BKE_object_material_edit_image_get(ob, me->mpoly[a].mat_nr); + Image *ima = bake_object_image_get(ob, me->mpoly[a].mat_nr); if (!ima) { BKE_report(op->reports, RPT_ERROR, "You should have active texture to use multires baker"); @@ -334,12 +349,12 @@ static int multiresbake_image_exec_locked(bContext *C, wmOperator *op) if (scene->r.bake_mode == RE_BAKE_NORMALS) { clear_flag = CLEAR_TANGENT_NORMAL; } - else if (ELEM(scene->r.bake_mode, RE_BAKE_DISPLACEMENT, RE_BAKE_DERIVATIVE)) { + else if (scene->r.bake_mode == RE_BAKE_DISPLACEMENT) { clear_flag = CLEAR_DISPLACEMENT; } { - Image **ob_image_array = BKE_object_material_edit_image_get_array(ob); + Image **ob_image_array = bake_object_image_get_array(ob); clear_images_poly(ob_image_array, ob->totcol, clear_flag); MEM_freeN(ob_image_array); } @@ -361,14 +376,12 @@ static int multiresbake_image_exec_locked(bContext *C, wmOperator *op) bkr.use_lores_mesh = scene->r.bake_flag & R_BAKE_LORES_MESH; bkr.bias = scene->r.bake_biasdist; bkr.number_of_rays = scene->r.bake_samples; - bkr.raytrace_structure = scene->r.raytrace_structure; - bkr.octree_resolution = scene->r.ocres; bkr.threads = BKE_scene_num_threads(scene); bkr.user_scale = (scene->r.bake_flag & R_BAKE_USERSCALE) ? scene->r.bake_user_scale : -1.0f; //bkr.reports= op->reports; /* create low-resolution DM (to bake to) and hi-resolution DM (to bake from) */ - bkr.ob_image.array = BKE_object_material_edit_image_get_array(ob); + bkr.ob_image.array = bake_object_image_get_array(ob); bkr.ob_image.len = ob->totcol; bkr.hires_dm = multiresbake_create_hiresdm(scene, ob, &bkr.tot_lvl, &bkr.simple); @@ -406,8 +419,6 @@ static void init_multiresbake_job(bContext *C, MultiresBakeJob *bkj) bkj->bake_clear = scene->r.bake_flag & R_BAKE_CLEAR; bkj->bias = scene->r.bake_biasdist; bkj->number_of_rays = scene->r.bake_samples; - bkj->raytrace_structure = scene->r.raytrace_structure; - bkj->octree_resolution = scene->r.ocres; bkj->threads = BKE_scene_num_threads(scene); bkj->user_scale = (scene->r.bake_flag & R_BAKE_USERSCALE) ? scene->r.bake_user_scale : -1.0f; //bkj->reports = op->reports; @@ -423,7 +434,7 @@ static void init_multiresbake_job(bContext *C, MultiresBakeJob *bkj) data = MEM_callocN(sizeof(MultiresBakerJobData), "multiresBaker derivedMesh_data"); - data->ob_image.array = BKE_object_material_edit_image_get_array(ob); + data->ob_image.array = bake_object_image_get_array(ob); data->ob_image.len = ob->totcol; /* create low-resolution DM (to bake to) and hi-resolution DM (to bake from) */ @@ -451,7 +462,7 @@ static void multiresbake_startjob(void *bkv, short *stop, short *do_update, floa if (bkj->mode == RE_BAKE_NORMALS) { clear_flag = CLEAR_TANGENT_NORMAL; } - else if (ELEM(bkj->mode, RE_BAKE_DISPLACEMENT, RE_BAKE_DERIVATIVE)) { + else if (bkj->mode == RE_BAKE_DISPLACEMENT) { clear_flag = CLEAR_DISPLACEMENT; } @@ -488,8 +499,6 @@ static void multiresbake_startjob(void *bkv, short *stop, short *do_update, floa bkr.bias = bkj->bias; bkr.number_of_rays = bkj->number_of_rays; - bkr.raytrace_structure = bkj->raytrace_structure; - bkr.octree_resolution = bkj->octree_resolution; bkr.threads = bkj->threads; RE_multires_bake_images(&bkr); @@ -566,203 +575,6 @@ static int multiresbake_image_exec(bContext *C, wmOperator *op) /* ****************** render BAKING ********************** */ -/* threaded break test */ -static int thread_break(void *UNUSED(arg)) -{ - return G.is_break; -} - -typedef struct BakeRender { - Render *re; - Main *main; - Scene *scene; - ViewLayer *view_layer; - struct Object *actob; - int result, ready; - - ReportList *reports; - - short *stop; - short *do_update; - float *progress; - - ListBase threads; - - /* backup */ - short prev_wo_amb_occ; - short prev_r_raytrace; - - /* for redrawing */ - ScrArea *sa; -} BakeRender; - -/* use by exec and invoke */ -static int test_bake_internal(bContext *C, ReportList *reports) -{ - Scene *scene = CTX_data_scene(C); - - if ((scene->r.bake_flag & R_BAKE_TO_ACTIVE) && CTX_data_active_object(C) == NULL) { - BKE_report(reports, RPT_ERROR, "No active object"); - } - else if (scene->r.bake_mode == RE_BAKE_AO && scene->world == NULL) { - BKE_report(reports, RPT_ERROR, "No world set up"); - } - else { - return 1; - } - - return 0; -} - -static void init_bake_internal(BakeRender *bkr, bContext *C) -{ - Scene *scene = CTX_data_scene(C); - ViewLayer *view_layer = CTX_data_view_layer(C); - bScreen *sc = CTX_wm_screen(C); - - /* get editmode results */ - ED_object_editmode_load(CTX_data_edit_object(C)); - - bkr->sa = sc ? BKE_screen_find_big_area(sc, SPACE_IMAGE, 10) : NULL; /* can be NULL */ - bkr->main = CTX_data_main(C); - bkr->scene = scene; - bkr->view_layer = view_layer; - bkr->actob = (scene->r.bake_flag & R_BAKE_TO_ACTIVE) ? OBACT(view_layer) : NULL; - bkr->re = RE_NewRender("_Bake View_"); - - if (scene->r.bake_mode == RE_BAKE_AO) { - /* If raytracing or AO is disabled, switch it on temporarily for baking. */ - bkr->prev_wo_amb_occ = (scene->world->mode & WO_AMB_OCC) != 0; - scene->world->mode |= WO_AMB_OCC; - } - if (scene->r.bake_mode == RE_BAKE_AO || bkr->actob) { - bkr->prev_r_raytrace = (scene->r.mode & R_RAYTRACE) != 0; - scene->r.mode |= R_RAYTRACE; - } -} - -static void finish_bake_internal(BakeRender *bkr) -{ - Image *ima; - - RE_Database_Free(bkr->re); - - /* restore raytrace and AO */ - if (bkr->scene->r.bake_mode == RE_BAKE_AO) - if (bkr->prev_wo_amb_occ == 0) - bkr->scene->world->mode &= ~WO_AMB_OCC; - - if (bkr->scene->r.bake_mode == RE_BAKE_AO || bkr->actob) - if (bkr->prev_r_raytrace == 0) - bkr->scene->r.mode &= ~R_RAYTRACE; - - /* force OpenGL reload and mipmap recalc */ - if ((bkr->scene->r.bake_flag & R_BAKE_VCOL) == 0) { - for (ima = G.main->image.first; ima; ima = ima->id.next) { - ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL); - - /* some of the images could have been changed during bake, - * so recreate mipmaps regardless bake result status - */ - if (ima->ok == IMA_OK_LOADED) { - if (ibuf) { - if (ibuf->userflags & IB_BITMAPDIRTY) { - GPU_free_image(ima); - imb_freemipmapImBuf(ibuf); - } - - /* invalidate display buffers for changed images */ - if (ibuf->userflags & IB_BITMAPDIRTY) - ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID; - } - } - - /* freed when baking is done, but if its canceled we need to free here */ - if (ibuf) { - if (ibuf->userdata) { - BakeImBufuserData *userdata = (BakeImBufuserData *) ibuf->userdata; - if (userdata->mask_buffer) - MEM_freeN(userdata->mask_buffer); - if (userdata->displacement_buffer) - MEM_freeN(userdata->displacement_buffer); - MEM_freeN(userdata); - ibuf->userdata = NULL; - } - } - - BKE_image_release_ibuf(ima, ibuf, NULL); - DEG_id_tag_update(&ima->id, 0); - } - } - - if (bkr->scene->r.bake_flag & R_BAKE_VCOL) { - /* update all tagged meshes */ - Mesh *me; - BLI_assert(BLI_thread_is_main()); - for (me = G.main->mesh.first; me; me = me->id.next) { - if (me->id.tag & LIB_TAG_DOIT) { - DEG_id_tag_update(&me->id, OB_RECALC_DATA); - BKE_mesh_tessface_clear(me); - } - } - } - -} - -static void *do_bake_render(void *bake_v) -{ - BakeRender *bkr = bake_v; - - bkr->result = RE_bake_shade_all_selected(bkr->re, bkr->scene->r.bake_mode, bkr->actob, NULL, bkr->progress); - bkr->ready = 1; - - return NULL; -} - -static void bake_startjob(void *bkv, short *stop, short *do_update, float *progress) -{ - BakeRender *bkr = bkv; - Scene *scene = bkr->scene; - Main *bmain = bkr->main; - - bkr->stop = stop; - bkr->do_update = do_update; - bkr->progress = progress; - - RE_test_break_cb(bkr->re, NULL, thread_break); - G.is_break = false; /* BKE_blender_test_break uses this global */ - - RE_Database_Baking(bkr->re, bmain, scene, bkr->view_layer, scene->lay, scene->r.bake_mode, bkr->actob); - - /* baking itself is threaded, cannot use test_break in threads. we also update optional imagewindow */ - bkr->result = RE_bake_shade_all_selected(bkr->re, scene->r.bake_mode, bkr->actob, bkr->do_update, bkr->progress); -} - -static void bake_update(void *bkv) -{ - BakeRender *bkr = bkv; - - if (bkr->sa && bkr->sa->spacetype == SPACE_IMAGE) { /* in case the user changed while baking */ - SpaceImage *sima = bkr->sa->spacedata.first; - if (sima) - sima->image = RE_bake_shade_get_image(); - } -} - -static void bake_freejob(void *bkv) -{ - BakeRender *bkr = bkv; - finish_bake_internal(bkr); - - if (bkr->result == BAKE_RESULT_NO_OBJECTS) - BKE_report(bkr->reports, RPT_ERROR, "No objects or images found to bake to"); - else if (bkr->result == BAKE_RESULT_FEEDBACK_LOOP) - BKE_report(bkr->reports, RPT_WARNING, "Circular reference in texture stack"); - - MEM_freeN(bkr); - G.is_rendering = false; -} - /* catch esc */ static int objects_bake_render_modal(bContext *C, wmOperator *UNUSED(op), const wmEvent *event) { @@ -780,7 +592,7 @@ static int objects_bake_render_modal(bContext *C, wmOperator *UNUSED(op), const static bool is_multires_bake(Scene *scene) { - if (ELEM(scene->r.bake_mode, RE_BAKE_NORMALS, RE_BAKE_DISPLACEMENT, RE_BAKE_DERIVATIVE, RE_BAKE_AO)) + if (ELEM(scene->r.bake_mode, RE_BAKE_NORMALS, RE_BAKE_DISPLACEMENT, RE_BAKE_AO)) return scene->r.bake_flag & R_BAKE_MULTIRES; return 0; @@ -791,44 +603,7 @@ static int objects_bake_render_invoke(bContext *C, wmOperator *op, const wmEvent Scene *scene = CTX_data_scene(C); int result = OPERATOR_CANCELLED; - if (is_multires_bake(scene)) { - result = multiresbake_image_exec(C, op); - } - else { - /* only one render job at a time */ - if (WM_jobs_test(CTX_wm_manager(C), scene, WM_JOB_TYPE_OBJECT_BAKE_TEXTURE)) - return OPERATOR_CANCELLED; - - if (test_bake_internal(C, op->reports) == 0) { - return OPERATOR_CANCELLED; - } - else { - BakeRender *bkr = MEM_callocN(sizeof(BakeRender), "render bake"); - wmJob *wm_job; - - init_bake_internal(bkr, C); - bkr->reports = op->reports; - - /* setup job */ - wm_job = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, "Texture Bake", - WM_JOB_EXCL_RENDER | WM_JOB_PRIORITY | WM_JOB_PROGRESS, WM_JOB_TYPE_OBJECT_BAKE_TEXTURE); - WM_jobs_customdata_set(wm_job, bkr, bake_freejob); - WM_jobs_timer(wm_job, 0.5, NC_IMAGE, 0); /* TODO - only draw bake image, can we enforce this */ - WM_jobs_callbacks(wm_job, bake_startjob, NULL, bake_update, NULL); - - G.is_break = false; - G.is_rendering = true; - - WM_jobs_start(CTX_wm_manager(C), wm_job); - - WM_cursor_wait(0); - - /* add modal handler for ESC */ - WM_event_add_modal_handler(C, op); - } - - result = OPERATOR_RUNNING_MODAL; - } + result = multiresbake_image_exec(C, op); WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, scene); @@ -838,56 +613,11 @@ static int objects_bake_render_invoke(bContext *C, wmOperator *op, const wmEvent static int bake_image_exec(bContext *C, wmOperator *op) { - Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); int result = OPERATOR_CANCELLED; - if (is_multires_bake(scene)) { - result = multiresbake_image_exec_locked(C, op); - } - else { - if (test_bake_internal(C, op->reports) == 0) { - return OPERATOR_CANCELLED; - } - else { - ListBase threads; - BakeRender bkr = {NULL}; - - init_bake_internal(&bkr, C); - bkr.reports = op->reports; - - RE_test_break_cb(bkr.re, NULL, thread_break); - G.is_break = false; /* BKE_blender_test_break uses this global */ - - RE_Database_Baking(bkr.re, bmain, scene, bkr.view_layer, scene->lay, scene->r.bake_mode, - (scene->r.bake_flag & R_BAKE_TO_ACTIVE) ? OBACT(bkr.view_layer) : NULL); - - /* baking itself is threaded, cannot use test_break in threads */ - BLI_threadpool_init(&threads, do_bake_render, 1); - bkr.ready = 0; - BLI_threadpool_insert(&threads, &bkr); - - while (bkr.ready == 0) { - PIL_sleep_ms(50); - if (bkr.ready) - break; - - /* used to redraw in 2.4x but this is just for exec in 2.5 */ - if (!G.background) - BKE_blender_test_break(); - } - BLI_threadpool_end(&threads); - - if (bkr.result == BAKE_RESULT_NO_OBJECTS) - BKE_report(op->reports, RPT_ERROR, "No valid images found to bake to"); - else if (bkr.result == BAKE_RESULT_FEEDBACK_LOOP) - BKE_report(op->reports, RPT_ERROR, "Circular reference in texture stack"); - - finish_bake_internal(&bkr); - - result = OPERATOR_FINISHED; - } - } + BLI_assert(is_multires_bake(scene)); + result = multiresbake_image_exec_locked(C, op); WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, scene); diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index 2550c4006f2..d051e42cb32 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -1295,68 +1295,6 @@ void OBJECT_OT_shade_smooth(wmOperatorType *ot) /* ********************** */ -static void UNUSED_FUNCTION(image_aspect) (Scene *scene, ViewLayer *view_layer, Object *obedit) -{ - /* all selected objects with an image map: scale in image aspect */ - Base *base; - Object *ob; - Material *ma; - Tex *tex; - float x, y, space; - int a, b, done; - - if (obedit) return; - if (ID_IS_LINKED(scene)) return; - - for (base = FIRSTBASE(view_layer); base; base = base->next) { - if (TESTBASELIB(base)) { - ob = base->object; - done = false; - - for (a = 1; a <= ob->totcol; a++) { - ma = give_current_material(ob, a); - if (ma) { - for (b = 0; b < MAX_MTEX; b++) { - if (ma->mtex[b] && ma->mtex[b]->tex) { - tex = ma->mtex[b]->tex; - if (tex->type == TEX_IMAGE && tex->ima) { - ImBuf *ibuf = BKE_image_acquire_ibuf(tex->ima, NULL, NULL); - - /* texturespace */ - space = 1.0; - if (ob->type == OB_MESH) { - float size[3]; - BKE_mesh_texspace_get(ob->data, NULL, NULL, size); - space = size[0] / size[1]; - } - else if (ELEM(ob->type, OB_CURVE, OB_FONT, OB_SURF)) { - float size[3]; - BKE_curve_texspace_get(ob->data, NULL, NULL, size); - space = size[0] / size[1]; - } - - x = ibuf->x / space; - y = ibuf->y; - - if (x > y) ob->size[0] = ob->size[1] * x / y; - else ob->size[1] = ob->size[0] * y / x; - - done = true; - DEG_id_tag_update(&ob->id, OB_RECALC_OB); - - BKE_image_release_ibuf(tex->ima, ibuf, NULL); - } - } - if (done) break; - } - } - if (done) break; - } - } - } - -} - static const EnumPropertyItem *object_mode_set_itemsf( bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free) { diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index 3cef80db032..d2ac0f77c78 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -1773,7 +1773,6 @@ static void single_obdata_users(Main *bmain, Scene *scene, ViewLayer *view_layer Mesh *me; Lattice *lat; ID *id; - int a; FOREACH_OBJECT_FLAG_BEGIN(scene, view_layer, flag, ob) { @@ -1786,11 +1785,6 @@ static void single_obdata_users(Main *bmain, Scene *scene, ViewLayer *view_layer switch (ob->type) { case OB_LAMP: ob->data = la = ID_NEW_SET(ob->data, BKE_lamp_copy(bmain, ob->data)); - for (a = 0; a < MAX_MTEX; a++) { - if (la->mtex[a]) { - ID_NEW_REMAP(la->mtex[a]->object); - } - } break; case OB_CAMERA: ob->data = ID_NEW_SET(ob->data, BKE_camera_copy(bmain, ob->data)); @@ -1870,11 +1864,10 @@ static void single_object_action_users(Scene *scene, ViewLayer *view_layer, cons FOREACH_OBJECT_FLAG_END; } -static void single_mat_users(Main *bmain, Scene *scene, ViewLayer *view_layer, const int flag, const bool do_textures) +static void single_mat_users(Main *bmain, Scene *scene, ViewLayer *view_layer, const int flag) { Material *ma, *man; - Tex *tex; - int a, b; + int a; FOREACH_OBJECT_FLAG_BEGIN(scene, view_layer, flag, ob) { @@ -1890,19 +1883,6 @@ static void single_mat_users(Main *bmain, Scene *scene, ViewLayer *view_layer, c man->id.us = 0; assign_material(ob, man, a, BKE_MAT_ASSIGN_USERPREF); - - if (do_textures) { - for (b = 0; b < MAX_MTEX; b++) { - if (ma->mtex[b] && (tex = ma->mtex[b]->tex)) { - if (tex->id.us > 1) { - id_us_min(&tex->id); - tex = BKE_texture_copy(bmain, tex); - BKE_animdata_copy_id_action(&tex->id, false); - man->mtex[b]->tex = tex; - } - } - } - } } } } @@ -1911,66 +1891,6 @@ static void single_mat_users(Main *bmain, Scene *scene, ViewLayer *view_layer, c FOREACH_OBJECT_FLAG_END; } -static void do_single_tex_user(Main *bmain, Tex **from) -{ - Tex *tex, *texn; - - tex = *from; - if (tex == NULL) return; - - if (tex->id.newid) { - *from = (Tex *)tex->id.newid; - id_us_plus(tex->id.newid); - id_us_min(&tex->id); - } - else if (tex->id.us > 1) { - texn = ID_NEW_SET(tex, BKE_texture_copy(bmain, tex)); - BKE_animdata_copy_id_action(&texn->id, false); - tex->id.newid = (ID *)texn; - id_us_min(&tex->id); - *from = texn; - } -} - -static void single_tex_users_expand(Main *bmain) -{ - /* only when 'parent' blocks are LIB_TAG_NEW */ - Material *ma; - Lamp *la; - World *wo; - int b; - - for (ma = bmain->mat.first; ma; ma = ma->id.next) { - if (ma->id.tag & LIB_TAG_NEW) { - for (b = 0; b < MAX_MTEX; b++) { - if (ma->mtex[b] && ma->mtex[b]->tex) { - do_single_tex_user(bmain, &(ma->mtex[b]->tex)); - } - } - } - } - - for (la = bmain->lamp.first; la; la = la->id.next) { - if (la->id.tag & LIB_TAG_NEW) { - for (b = 0; b < MAX_MTEX; b++) { - if (la->mtex[b] && la->mtex[b]->tex) { - do_single_tex_user(bmain, &(la->mtex[b]->tex)); - } - } - } - } - - for (wo = bmain->world.first; wo; wo = wo->id.next) { - if (wo->id.tag & LIB_TAG_NEW) { - for (b = 0; b < MAX_MTEX; b++) { - if (wo->mtex[b] && wo->mtex[b]->tex) { - do_single_tex_user(bmain, &(wo->mtex[b]->tex)); - } - } - } - } -} - static void single_mat_users_expand(Main *bmain) { /* only when 'parent' blocks are LIB_TAG_NEW */ @@ -1978,8 +1898,6 @@ static void single_mat_users_expand(Main *bmain) Mesh *me; Curve *cu; MetaBall *mb; - Material *ma; - int a; for (ob = bmain->object.first; ob; ob = ob->id.next) if (ob->id.tag & LIB_TAG_NEW) @@ -1996,13 +1914,6 @@ static void single_mat_users_expand(Main *bmain) for (mb = bmain->mball.first; mb; mb = mb->id.next) if (mb->id.tag & LIB_TAG_NEW) new_id_matar(bmain, mb->mat, mb->totcol); - - /* material imats */ - for (ma = bmain->mat.first; ma; ma = ma->id.next) - if (ma->id.tag & LIB_TAG_NEW) - for (a = 0; a < MAX_MTEX; a++) - if (ma->mtex[a]) - ID_NEW_REMAP(ma->mtex[a]->object); } /* used for copying scenes */ @@ -2014,7 +1925,6 @@ void ED_object_single_users(Main *bmain, Scene *scene, const bool full, const bo single_obdata_users(bmain, scene, NULL, 0); single_object_action_users(scene, NULL, 0); single_mat_users_expand(bmain); - single_tex_users_expand(bmain); } /* Relink nodetrees' pointers that have been duplicated. */ @@ -2201,12 +2111,6 @@ static void make_local_material_tag(Material *ma) make_local_animdata_tag(BKE_animdata_from_id(&ma->id)); /* About nodetrees: root one is made local together with material, others we keep linked for now... */ - - for (int a = 0; a < MAX_MTEX; a++) { - if (ma->mtex[a] && ma->mtex[a]->tex) { - ma->mtex[a]->tex->id.tag &= ~LIB_TAG_PRE_EXISTING; - } - } } } @@ -2216,7 +2120,6 @@ static int make_local_exec(bContext *C, wmOperator *op) Scene *scene = CTX_data_scene(C); ParticleSystem *psys; Material *ma, ***matarar; - Lamp *la; const int mode = RNA_enum_get(op->ptr, "type"); int a; @@ -2267,16 +2170,6 @@ static int make_local_exec(bContext *C, wmOperator *op) } } } - - if (ob->type == OB_LAMP) { - BLI_assert(ob->data != NULL); - la = ob->data; - for (a = 0; a < MAX_MTEX; a++) { - if (la->mtex[a] && la->mtex[a]->tex) { - la->id.tag &= ~LIB_TAG_PRE_EXISTING; - } - } - } } if (ELEM(mode, MAKE_LOCAL_SELECT_OBDATA, MAKE_LOCAL_SELECT_OBDATA_MATERIAL) && ob->data != NULL) { @@ -2553,13 +2446,9 @@ static int make_single_user_exec(bContext *C, wmOperator *op) } if (RNA_boolean_get(op->ptr, "material")) { - single_mat_users(bmain, scene, view_layer, flag, RNA_boolean_get(op->ptr, "texture")); + single_mat_users(bmain, scene, view_layer, flag); } -#if 0 /* can't do this separate from materials */ - if (RNA_boolean_get(op->ptr, "texture")) - single_mat_users(scene, flag, true); -#endif if (RNA_boolean_get(op->ptr, "animation")) { single_object_action_users(scene, view_layer, flag); } @@ -2601,8 +2490,6 @@ void OBJECT_OT_make_single_user(wmOperatorType *ot) RNA_def_boolean(ot->srna, "object", 0, "Object", "Make single user objects"); RNA_def_boolean(ot->srna, "obdata", 0, "Object Data", "Make single user object data"); RNA_def_boolean(ot->srna, "material", 0, "Materials", "Make materials local to each data-block"); - RNA_def_boolean(ot->srna, "texture", 0, "Textures", - "Make textures local to each material (needs 'Materials' to be set too)"); RNA_def_boolean(ot->srna, "animation", 0, "Object Animation", "Make animation data local to each object"); } diff --git a/source/blender/editors/object/object_select.c b/source/blender/editors/object/object_select.c index d958381efe7..d0d0418c861 100644 --- a/source/blender/editors/object/object_select.c +++ b/source/blender/editors/object/object_select.c @@ -203,7 +203,6 @@ enum { OBJECT_SELECT_LINKED_IPO = 1, OBJECT_SELECT_LINKED_OBDATA, OBJECT_SELECT_LINKED_MATERIAL, - OBJECT_SELECT_LINKED_TEXTURE, OBJECT_SELECT_LINKED_DUPGROUP, OBJECT_SELECT_LINKED_PARTICLE, OBJECT_SELECT_LINKED_LIBRARY, @@ -214,7 +213,6 @@ static const EnumPropertyItem prop_select_linked_types[] = { //{OBJECT_SELECT_LINKED_IPO, "IPO", 0, "Object IPO", ""}, // XXX deprecated animation system stuff... {OBJECT_SELECT_LINKED_OBDATA, "OBDATA", 0, "Object Data", ""}, {OBJECT_SELECT_LINKED_MATERIAL, "MATERIAL", 0, "Material", ""}, - {OBJECT_SELECT_LINKED_TEXTURE, "TEXTURE", 0, "Texture", ""}, {OBJECT_SELECT_LINKED_DUPGROUP, "DUPGROUP", 0, "Dupligroup", ""}, {OBJECT_SELECT_LINKED_PARTICLE, "PARTICLE", 0, "Particle System", ""}, {OBJECT_SELECT_LINKED_LIBRARY, "LIBRARY", 0, "Library", ""}, @@ -240,7 +238,7 @@ static bool object_select_all_by_obdata(bContext *C, void *obdata) return changed; } -static bool object_select_all_by_material_texture(bContext *C, int use_texture, Material *mat, Tex *tex) +static bool object_select_all_by_material(bContext *C, Material *mat) { bool changed = false; @@ -249,27 +247,14 @@ static bool object_select_all_by_material_texture(bContext *C, int use_texture, if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLED) != 0)) { Object *ob = base->object; Material *mat1; - int a, b; + int a; for (a = 1; a <= ob->totcol; a++) { mat1 = give_current_material(ob, a); - if (!use_texture) { - if (mat1 == mat) { - ED_object_base_select(base, BA_SELECT); - changed = true; - } - } - else if (mat1 && use_texture) { - for (b = 0; b < MAX_MTEX; b++) { - if (mat1->mtex[b]) { - if (tex == mat1->mtex[b]->tex) { - ED_object_base_select(base, BA_SELECT); - changed = true; - break; - } - } - } + if (mat1 == mat) { + ED_object_base_select(base, BA_SELECT); + changed = true; } } } @@ -373,7 +358,7 @@ void ED_object_select_linked_by_id(bContext *C, ID *id) changed = object_select_all_by_obdata(C, id); } else if (idtype == ID_MA) { - changed = object_select_all_by_material_texture(C, false, (Material *)id, NULL); + changed = object_select_all_by_material(C, (Material *)id); } else if (idtype == ID_LI) { changed = object_select_all_by_library(C, (Library *) id); @@ -420,21 +405,13 @@ static int object_select_linked_exec(bContext *C, wmOperator *op) changed = object_select_all_by_obdata(C, ob->data); } - else if (nr == OBJECT_SELECT_LINKED_MATERIAL || nr == OBJECT_SELECT_LINKED_TEXTURE) { + else if (nr == OBJECT_SELECT_LINKED_MATERIAL) { Material *mat = NULL; - Tex *tex = NULL; - bool use_texture = false; mat = give_current_material(ob, ob->actcol); if (mat == NULL) return OPERATOR_CANCELLED; - if (nr == OBJECT_SELECT_LINKED_TEXTURE) { - use_texture = true; - - if (mat->mtex[(int)mat->texact]) tex = mat->mtex[(int)mat->texact]->tex; - if (tex == NULL) return OPERATOR_CANCELLED; - } - changed = object_select_all_by_material_texture(C, use_texture, mat, tex); + changed = object_select_all_by_material(C, mat); } else if (nr == OBJECT_SELECT_LINKED_DUPGROUP) { if (ob->dup_group == NULL) diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c index 7012046fc31..a509a909111 100644 --- a/source/blender/editors/physics/particle_edit.c +++ b/source/blender/editors/physics/particle_edit.c @@ -3587,7 +3587,7 @@ static int brush_add(const bContext *C, PEData *data, short number) tree=BLI_kdtree_new(psys->totpart); for (i=0, pa=psys->particles; i<totpart; i++, pa++) { - psys_particle_on_dm(psmd->dm_final, psys->part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, cur_co, 0, 0, 0, 0, 0); + psys_particle_on_dm(psmd->dm_final, psys->part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, cur_co, 0, 0, 0, 0); BLI_kdtree_insert(tree, i, cur_co); } @@ -3631,7 +3631,7 @@ static int brush_add(const bContext *C, PEData *data, short number) int w, maxw; float maxd, totw=0.0, weight[3]; - psys_particle_on_dm(psmd->dm_final, psys->part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, co1, 0, 0, 0, 0, 0); + psys_particle_on_dm(psmd->dm_final, psys->part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, co1, 0, 0, 0, 0); maxw = BLI_kdtree_find_nearest_n(tree, co1, ptn, 3); maxd= ptn[maxw-1].dist; diff --git a/source/blender/editors/render/render_intern.h b/source/blender/editors/render/render_intern.h index 2bc96a7f218..a1f646aefc1 100644 --- a/source/blender/editors/render/render_intern.h +++ b/source/blender/editors/render/render_intern.h @@ -83,15 +83,10 @@ void SCENE_OT_freestyle_stroke_material_create(struct wmOperatorType *ot); void TEXTURE_OT_slot_copy(struct wmOperatorType *ot); void TEXTURE_OT_slot_paste(struct wmOperatorType *ot); void TEXTURE_OT_slot_move(struct wmOperatorType *ot); -void TEXTURE_OT_envmap_save(struct wmOperatorType *ot); -void TEXTURE_OT_envmap_clear(struct wmOperatorType *ot); -void TEXTURE_OT_envmap_clear_all(struct wmOperatorType *ot); /* render_internal.c */ void RENDER_OT_render(struct wmOperatorType *ot); void RENDER_OT_shutter_curve_preset(struct wmOperatorType *ot); -void render_view3d_update(struct RenderEngine *engine, const struct bContext *C); -void render_view3d_draw(struct RenderEngine *engine, const struct bContext *C); /* render_view.c */ struct ScrArea *render_view_open(struct bContext *C, int mx, int my, struct ReportList *reports); diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c index 22e62c9ba0a..89dbd3da16d 100644 --- a/source/blender/editors/render/render_internal.c +++ b/source/blender/editors/render/render_internal.c @@ -1078,623 +1078,6 @@ void RENDER_OT_render(wmOperatorType *ot) } -/* ************** preview for 3d viewport ***************** */ - -#define PR_UPDATE_VIEW 1 -#define PR_UPDATE_RENDERSIZE 2 -#define PR_UPDATE_MATERIAL 4 -#define PR_UPDATE_DATABASE 8 - -typedef struct RenderPreview { - /* from wmJob */ - void *owner; - short *stop, *do_update; - wmJob *job; - - Scene *scene; - Depsgraph *depsgraph; - ScrArea *sa; - ARegion *ar; - View3D *v3d; - RegionView3D *rv3d; - Main *bmain; - RenderEngine *engine; - - float viewmat[4][4]; - - int start_resolution_divider; - int resolution_divider; - bool has_freestyle; -} RenderPreview; - -static int render_view3d_disprect(Scene *scene, Depsgraph *depsgraph, - ARegion *ar, View3D *v3d, RegionView3D *rv3d, rcti *disprect) -{ - /* copied code from view3d_draw.c */ - rctf viewborder; - int draw_border; - - if (rv3d->persp == RV3D_CAMOB) - draw_border = (scene->r.mode & R_BORDER) != 0; - else - draw_border = (v3d->flag2 & V3D_RENDER_BORDER) != 0; - - if (draw_border) { - if (rv3d->persp == RV3D_CAMOB) { - ED_view3d_calc_camera_border(scene, depsgraph, ar, v3d, rv3d, &viewborder, false); - - disprect->xmin = viewborder.xmin + scene->r.border.xmin * BLI_rctf_size_x(&viewborder); - disprect->ymin = viewborder.ymin + scene->r.border.ymin * BLI_rctf_size_y(&viewborder); - disprect->xmax = viewborder.xmin + scene->r.border.xmax * BLI_rctf_size_x(&viewborder); - disprect->ymax = viewborder.ymin + scene->r.border.ymax * BLI_rctf_size_y(&viewborder); - } - else { - disprect->xmin = v3d->render_border.xmin * ar->winx; - disprect->xmax = v3d->render_border.xmax * ar->winx; - disprect->ymin = v3d->render_border.ymin * ar->winy; - disprect->ymax = v3d->render_border.ymax * ar->winy; - } - - return 1; - } - - BLI_rcti_init(disprect, 0, 0, 0, 0); - return 0; -} - -/* returns true if OK */ -static bool render_view3d_get_rects( - Depsgraph *depsgraph, - ARegion *ar, View3D *v3d, RegionView3D *rv3d, rctf *viewplane, RenderEngine *engine, - float *r_clipsta, float *r_clipend, float *r_pixsize, bool *r_ortho) -{ - - if (ar->winx < 4 || ar->winy < 4) return false; - - *r_ortho = ED_view3d_viewplane_get(depsgraph, v3d, rv3d, ar->winx, ar->winy, viewplane, r_clipsta, r_clipend, r_pixsize); - - engine->resolution_x = ar->winx; - engine->resolution_y = ar->winy; - - return true; -} - -static bool render_view3d_is_valid(RenderPreview *rp) -{ - return (rp->rv3d->render_engine != NULL); -} - -/* called by renderer, checks job value */ -static int render_view3d_break(void *rpv) -{ - RenderPreview *rp = rpv; - - if (G.is_break) - return 1; - - /* during render, rv3d->engine can get freed */ - if (render_view3d_is_valid(rp) == false) { - *rp->stop = 1; - } - - return *(rp->stop); -} - -static void render_view3d_display_update(void *rpv, RenderResult *UNUSED(rr), volatile struct rcti *UNUSED(rect)) -{ - RenderPreview *rp = rpv; - - *(rp->do_update) = true; -} - -static void render_view3d_renderinfo_cb(void *rjp, RenderStats *rs) -{ - RenderPreview *rp = rjp; - - /* during render, rv3d->engine can get freed */ - if (rp->rv3d->render_engine == NULL) { - *rp->stop = 1; - } - else { - make_renderinfo_string(rs, rp->scene, false, NULL, rp->engine->text); - - /* make jobs timer to send notifier */ - *(rp->do_update) = true; - } -} - -BLI_INLINE void rcti_scale_coords(rcti *scaled_rect, const rcti *rect, - const float scale) -{ - scaled_rect->xmin = rect->xmin * scale; - scaled_rect->ymin = rect->ymin * scale; - scaled_rect->xmax = rect->xmax * scale; - scaled_rect->ymax = rect->ymax * scale; -} - -static void render_update_resolution(Render *re, const RenderPreview *rp, - bool use_border, const rcti *clip_rect) -{ - int winx = rp->ar->winx / rp->resolution_divider; - int winy = rp->ar->winy / rp->resolution_divider; - if (use_border) { - rcti scaled_cliprct; - rcti_scale_coords(&scaled_cliprct, clip_rect, - 1.0f / rp->resolution_divider); - RE_ChangeResolution(re, winx, winy, &scaled_cliprct); - } - else { - RE_ChangeResolution(re, winx, winy, NULL); - } - - if (rp->has_freestyle) { - if (rp->resolution_divider == BKE_render_preview_pixel_size(&rp->scene->r)) { - RE_ChangeModeFlag(re, R_EDGE_FRS, false); - } - else { - RE_ChangeModeFlag(re, R_EDGE_FRS, true); - } - } -} - -static void render_view3d_startjob(void *customdata, short *stop, short *do_update, float *UNUSED(progress)) -{ - RenderPreview *rp = customdata; - Render *re; - RenderStats *rstats; - rctf viewplane; - rcti cliprct; - float clipsta, clipend, pixsize; - bool orth, restore = 0; - char name[32]; - int update_flag; - bool use_border; - int ob_inst_update_flag = 0; - - update_flag = rp->engine->job_update_flag; - rp->engine->job_update_flag = 0; - - //printf("ma %d res %d view %d db %d\n", update_flag & PR_UPDATE_MATERIAL, update_flag & PR_UPDATE_RENDERSIZE, update_flag & PR_UPDATE_VIEW, update_flag & PR_UPDATE_DATABASE); - - G.is_break = false; - - if (false == render_view3d_get_rects(rp->depsgraph, rp->ar, rp->v3d, rp->rv3d, &viewplane, rp->engine, &clipsta, &clipend, &pixsize, &orth)) - return; - - rp->stop = stop; - rp->do_update = do_update; - - // printf("Enter previewrender\n"); - - /* ok, are we rendering all over? */ - sprintf(name, "View3dPreview %p", (void *)rp->ar); - re = rp->engine->re = RE_GetRender(name); - - /* set this always, rp is different for each job */ - RE_test_break_cb(re, rp, render_view3d_break); - RE_display_update_cb(re, rp, render_view3d_display_update); - RE_stats_draw_cb(re, rp, render_view3d_renderinfo_cb); - - rstats = RE_GetStats(re); - - if (update_flag & PR_UPDATE_VIEW) { - Object *object; - rp->resolution_divider = rp->start_resolution_divider; - - /* Same as database_init_objects(), loop over all objects. - * We might consider de-duplicating the code between this two cases. - */ - for (object = rp->bmain->object.first; object; object = object->id.next) { - float mat[4][4]; - mul_m4_m4m4(mat, rp->viewmat, object->obmat); - invert_m4_m4(object->imat_ren, mat); - } - } - - use_border = render_view3d_disprect(rp->scene, rp->depsgraph, - rp->ar, rp->v3d, rp->rv3d, - &cliprct); - - if ((update_flag & (PR_UPDATE_RENDERSIZE | PR_UPDATE_DATABASE | PR_UPDATE_VIEW)) || rstats->convertdone == 0) { - RenderData rdata; - - /* no osa, blur, seq, layers, savebuffer etc for preview render */ - rdata = rp->scene->r; - rdata.mode &= ~(R_OSA | R_MBLUR | R_BORDER | R_PANORAMA); - rdata.scemode &= ~(R_DOSEQ | R_DOCOMP | R_FREE_IMAGE | R_EXR_TILE_FILE | R_FULL_SAMPLE); - rdata.scemode |= R_VIEWPORT_PREVIEW; - - /* we do use layers, but only active */ - rdata.scemode |= R_SINGLE_LAYER; - - /* initalize always */ - if (use_border) { - rdata.mode |= R_BORDER; - RE_InitState(re, NULL, &rdata, &rp->scene->view_layers, rp->scene->active_view_layer, NULL, rp->ar->winx, rp->ar->winy, &cliprct); - } - else - RE_InitState(re, NULL, &rdata, &rp->scene->view_layers, rp->scene->active_view_layer, NULL, rp->ar->winx, rp->ar->winy, NULL); - } - - if (orth) - RE_SetOrtho(re, &viewplane, clipsta, clipend); - else - RE_SetWindow(re, &viewplane, clipsta, clipend); - - RE_SetPixelSize(re, pixsize); - - if ((update_flag & PR_UPDATE_DATABASE) || rstats->convertdone == 0) { - unsigned int lay = rp->scene->lay; - - /* allow localview render for objects with lights in normal layers */ - if (rp->v3d->lay & 0xFF000000) - lay |= rp->v3d->lay; - else lay = rp->v3d->lay; - - RE_SetView(re, rp->viewmat); - - /* copying blender data while main thread is locked, to avoid crashes */ - WM_job_main_thread_lock_acquire(rp->job); - RE_Database_Free(re); - RE_Database_FromScene(re, rp->bmain, rp->scene, lay, 0); // 0= dont use camera view - WM_job_main_thread_lock_release(rp->job); - - /* do preprocessing like building raytree, shadows, volumes, SSS */ - RE_Database_Preprocess(rp->depsgraph, re); - - /* conversion not completed, need to do it again */ - if (!rstats->convertdone) { - if (render_view3d_is_valid(rp)) { - rp->engine->job_update_flag |= PR_UPDATE_DATABASE; - } - } - - // printf("dbase update\n"); - } - else { - // printf("dbase rotate\n"); - RE_DataBase_IncrementalView(re, rp->viewmat, 0); - restore = 1; - } - - RE_DataBase_ApplyWindow(re); - - /* OK, can we enter render code? */ - if (rstats->convertdone) { - bool first_time = true; - - if (update_flag & PR_UPDATE_VIEW) { - ob_inst_update_flag |= RE_OBJECT_INSTANCES_UPDATE_VIEW; - } - - RE_updateRenderInstances(re, ob_inst_update_flag); - - for (;;) { - int pixel_size = BKE_render_preview_pixel_size(&rp->scene->r); - if (first_time == false) { - if (restore) - RE_DataBase_IncrementalView(re, rp->viewmat, 1); - - rp->resolution_divider = MAX2(rp->resolution_divider / 2, pixel_size); - *do_update = 1; - - render_update_resolution(re, rp, use_border, &cliprct); - - RE_DataBase_IncrementalView(re, rp->viewmat, 0); - RE_DataBase_ApplyWindow(re); - restore = 1; - } - else { - render_update_resolution(re, rp, use_border, &cliprct); - } - - RE_TileProcessor(re); - - first_time = false; - - if (*stop || rp->resolution_divider == pixel_size) { - break; - } - } - - /* always rotate back */ - if (restore) - RE_DataBase_IncrementalView(re, rp->viewmat, 1); - } -} - -static void render_view3d_free(void *customdata) -{ - RenderPreview *rp = customdata; - - MEM_freeN(rp); -} - -static bool render_view3d_flag_changed(RenderEngine *engine, const bContext *C) -{ - RegionView3D *rv3d = CTX_wm_region_view3d(C); - View3D *v3d = CTX_wm_view3d(C); - ARegion *ar = CTX_wm_region(C); - Scene *scene = CTX_data_scene(C); - Depsgraph *depsgraph = CTX_data_depsgraph(C); - Render *re; - rctf viewplane; - rcti disprect; - float clipsta, clipend; - bool orth; - int job_update_flag = 0; - char name[32]; - - /* ensure render engine exists */ - re = engine->re; - - if (!re) { - sprintf(name, "View3dPreview %p", (void *)ar); - re = engine->re = RE_GetRender(name); - if (!re) - re = engine->re = RE_NewRender(name); - - engine->update_flag |= RE_ENGINE_UPDATE_DATABASE; - } - - /* check update_flag */ - if (engine->update_flag & RE_ENGINE_UPDATE_MA) - job_update_flag |= PR_UPDATE_MATERIAL; - - if (engine->update_flag & RE_ENGINE_UPDATE_OTHER) - job_update_flag |= PR_UPDATE_MATERIAL; - - if (engine->update_flag & RE_ENGINE_UPDATE_DATABASE) { - job_update_flag |= PR_UPDATE_DATABASE; - - /* load editmesh */ - Object *obedit = CTX_data_edit_object(C); - if (obedit) { - ED_object_editmode_load(obedit); - } - } - - engine->update_flag = 0; - - /* check if viewport changed */ - if (engine->last_winx != ar->winx || engine->last_winy != ar->winy) { - engine->last_winx = ar->winx; - engine->last_winy = ar->winy; - job_update_flag |= PR_UPDATE_RENDERSIZE; - } - - if (compare_m4m4(engine->last_viewmat, rv3d->viewmat, 0.00001f) == 0) { - copy_m4_m4(engine->last_viewmat, rv3d->viewmat); - job_update_flag |= PR_UPDATE_VIEW; - } - - render_view3d_get_rects(depsgraph, ar, v3d, rv3d, &viewplane, engine, &clipsta, &clipend, NULL, &orth); - - if (BLI_rctf_compare(&viewplane, &engine->last_viewplane, 0.00001f) == 0) { - engine->last_viewplane = viewplane; - job_update_flag |= PR_UPDATE_VIEW; - } - - render_view3d_disprect(scene, depsgraph, ar, v3d, rv3d, &disprect); - if (BLI_rcti_compare(&disprect, &engine->last_disprect) == 0) { - engine->last_disprect = disprect; - job_update_flag |= PR_UPDATE_RENDERSIZE; - } - - /* any changes? go ahead and rerender */ - if (job_update_flag) { - engine->job_update_flag |= job_update_flag; - return true; - } - - return false; -} - -static void render_view3d_do(RenderEngine *engine, const bContext *C) -{ - wmJob *wm_job; - RenderPreview *rp; - Scene *scene = CTX_data_scene(C); - Depsgraph *depsgraph = CTX_data_depsgraph(C); - ARegion *ar = CTX_wm_region(C); - int width = ar->winx, height = ar->winy; - int divider = BKE_render_preview_pixel_size(&scene->r); - int resolution_threshold = scene->r.preview_start_resolution * - scene->r.preview_start_resolution; - - if (CTX_wm_window(C) == NULL) - return; - if (!render_view3d_flag_changed(engine, C)) - return; - - wm_job = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), CTX_wm_region(C), "Render Preview", - WM_JOB_EXCL_RENDER, WM_JOB_TYPE_RENDER_PREVIEW); - rp = MEM_callocN(sizeof(RenderPreview), "render preview"); - rp->job = wm_job; - - while (width * height > resolution_threshold) { - width = max_ii(1, width / 2); - height = max_ii(1, height / 2); - divider *= 2; - } - - /* customdata for preview thread */ - rp->scene = scene; - rp->depsgraph = depsgraph; - rp->engine = engine; - rp->sa = CTX_wm_area(C); - rp->ar = CTX_wm_region(C); - rp->v3d = rp->sa->spacedata.first; - rp->rv3d = CTX_wm_region_view3d(C); - rp->bmain = CTX_data_main(C); - rp->resolution_divider = divider; - rp->start_resolution_divider = divider; - rp->has_freestyle = (scene->r.mode & R_EDGE_FRS) != 0; - copy_m4_m4(rp->viewmat, rp->rv3d->viewmat); - - /* clear info text */ - engine->text[0] = '\0'; - - /* setup job */ - WM_jobs_customdata_set(wm_job, rp, render_view3d_free); - WM_jobs_timer(wm_job, 0.1, NC_SPACE | ND_SPACE_VIEW3D, NC_SPACE | ND_SPACE_VIEW3D); - WM_jobs_callbacks(wm_job, render_view3d_startjob, NULL, NULL, NULL); - - WM_jobs_start(CTX_wm_manager(C), wm_job); - - engine->flag &= ~RE_ENGINE_DO_UPDATE; -} - -/* callback for render engine, on changes */ -void render_view3d_update(RenderEngine *engine, const bContext *C) -{ - /* this shouldn't be needed and causes too many database rebuilds, but we - * aren't actually tracking updates for all relevant datablocks so this is - * a catch-all for updates */ - engine->update_flag |= RE_ENGINE_UPDATE_DATABASE; - - render_view3d_do(engine, C); -} - -void render_view3d_draw(RenderEngine *engine, const bContext *C) -{ - Render *re = engine->re; - RenderResult rres; - char name[32]; - - render_view3d_do(engine, C); - - if (re == NULL) { - sprintf(name, "View3dPreview %p", (void *)CTX_wm_region(C)); - re = RE_GetRender(name); - - if (re == NULL) return; - } - - /* Viewport render preview doesn't support multiview, view hardcoded to 0 */ - RE_AcquireResultImage(re, &rres, 0); - - if (rres.rectf) { - RegionView3D *rv3d = CTX_wm_region_view3d(C); - View3D *v3d = CTX_wm_view3d(C); - Scene *scene = CTX_data_scene(C); - Depsgraph *depsgraph = CTX_data_depsgraph(C); - ARegion *ar = CTX_wm_region(C); - bool force_fallback = false; - bool need_fallback = true; - float dither = scene->r.dither_intensity; - float scale_x, scale_y; - rcti clip_rect; - int xof, yof; - - if (render_view3d_disprect(scene, depsgraph, ar, v3d, rv3d, &clip_rect)) { - scale_x = (float) BLI_rcti_size_x(&clip_rect) / rres.rectx; - scale_y = (float) BLI_rcti_size_y(&clip_rect) / rres.recty; - xof = clip_rect.xmin; - yof = clip_rect.ymin; - } - else { - scale_x = (float) ar->winx / rres.rectx; - scale_y = (float) ar->winy / rres.recty; - xof = rres.xof; - yof = rres.yof; - } - - /* If user decided not to use GLSL, fallback to glaDrawPixelsAuto */ - force_fallback |= (U.image_draw_method != IMAGE_DRAW_METHOD_GLSL); - - /* Try using GLSL display transform. */ - if (force_fallback == false) { - if (IMB_colormanagement_setup_glsl_draw(&scene->view_settings, &scene->display_settings, dither, true)) { - glEnable(GL_BLEND); - IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR); - immDrawPixelsTex(&state, xof, yof, rres.rectx, rres.recty, - GL_RGBA, GL_FLOAT, GL_NEAREST, rres.rectf, - scale_x, scale_y, NULL);; - glDisable(GL_BLEND); - - IMB_colormanagement_finish_glsl_draw(); - need_fallback = false; - } - } - - /* If GLSL failed, use old-school CPU-based transform. */ - if (need_fallback) { - unsigned char *display_buffer = MEM_mallocN(4 * rres.rectx * rres.recty * sizeof(char), - "render_view3d_draw"); - - IMB_colormanagement_buffer_make_display_space(rres.rectf, display_buffer, rres.rectx, rres.recty, - 4, dither, &scene->view_settings, &scene->display_settings); - - glEnable(GL_BLEND); - IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR); - immDrawPixelsTex(&state, xof, yof, rres.rectx, rres.recty, - GL_RGBA, GL_UNSIGNED_BYTE, - GL_NEAREST, display_buffer, - scale_x, scale_y, NULL); - glDisable(GL_BLEND); - - MEM_freeN(display_buffer); - } - } - - RE_ReleaseResultImage(re); -} - -void ED_viewport_render_kill_jobs(wmWindowManager *wm, - Main *bmain, - bool free_database) -{ - bScreen *sc; - ScrArea *sa; - ARegion *ar; - - if (!wm) - return; - - /* kill all actively running jobs */ - WM_jobs_kill(wm, NULL, render_view3d_startjob); - - /* loop over 3D view render engines */ - for (sc = bmain->screen.first; sc; sc = sc->id.next) { - for (sa = sc->areabase.first; sa; sa = sa->next) { - if (sa->spacetype != SPACE_VIEW3D) - continue; - - for (ar = sa->regionbase.first; ar; ar = ar->next) { - RegionView3D *rv3d; - - if (ar->regiontype != RGN_TYPE_WINDOW) - continue; - - rv3d = ar->regiondata; - - if (rv3d->render_engine) { - /* free render database now before we change data, because - * RE_Database_Free will also loop over blender data */ - if (free_database) { - char name[32]; - Render *re; - - sprintf(name, "View3dPreview %p", (void *)ar); - re = RE_GetRender(name); - - if (re) - RE_Database_Free(re); - - /* tag render engine to update entire database */ - rv3d->render_engine->update_flag |= RE_ENGINE_UPDATE_DATABASE; - } - else { - /* quick shader update */ - rv3d->render_engine->update_flag |= RE_ENGINE_UPDATE_MA; - } - } - } - } - } -} - Scene *ED_render_job_get_scene(const bContext *C) { wmWindowManager *wm = CTX_wm_manager(C); @@ -1716,6 +1099,7 @@ Scene *ED_render_job_get_current_scene(const bContext *C) return NULL; } + /* Motion blur curve preset */ static int render_shutter_curve_preset_exec(bContext *C, wmOperator *op) diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c index 840c5c2b5aa..1c6938cbdb3 100644 --- a/source/blender/editors/render/render_opengl.c +++ b/source/blender/editors/render/render_opengl.c @@ -270,7 +270,6 @@ static void screen_opengl_render_doit(const bContext *C, OGLRender *oglrender, R { Depsgraph *depsgraph = CTX_data_depsgraph(C); Scene *scene = oglrender->scene; - ViewLayer *view_layer = oglrender->view_layer; ARegion *ar = oglrender->ar; View3D *v3d = oglrender->v3d; RegionView3D *rv3d = oglrender->rv3d; @@ -278,7 +277,6 @@ static void screen_opengl_render_doit(const bContext *C, OGLRender *oglrender, R int sizex = oglrender->sizex; int sizey = oglrender->sizey; const short view_context = (v3d != NULL); - bool draw_bgpic = true; bool draw_sky = (scene->r.alphamode == R_ADDSKY); float *rectf = NULL; const char *viewname = RE_GetActiveRenderView(oglrender->re); @@ -356,10 +354,8 @@ static void screen_opengl_render_doit(const bContext *C, OGLRender *oglrender, R draw_flags |= (oglrender->ofs_full_samples) ? V3D_OFSDRAW_USE_FULL_SAMPLE : 0; if (view_context) { - draw_flags |= (draw_bgpic) ? V3D_OFSDRAW_USE_BACKGROUND : 0; - ibuf_view = ED_view3d_draw_offscreen_imbuf( - depsgraph, scene, view_layer, v3d->drawtype, + depsgraph, scene, v3d->drawtype, v3d, ar, sizex, sizey, IB_rectfloat, draw_flags, alpha_mode, oglrender->ofs_samples, viewname, oglrender->ofs, err_out); @@ -370,9 +366,9 @@ static void screen_opengl_render_doit(const bContext *C, OGLRender *oglrender, R } } else { - draw_flags |= (V3D_OFSDRAW_USE_GPENCIL | V3D_OFSDRAW_USE_BACKGROUND); + draw_flags |= V3D_OFSDRAW_USE_GPENCIL; ibuf_view = ED_view3d_draw_offscreen_imbuf_simple( - depsgraph, scene, view_layer, OB_SOLID, + depsgraph, scene, OB_SOLID, scene->camera, oglrender->sizex, oglrender->sizey, IB_rectfloat, draw_flags, alpha_mode, oglrender->ofs_samples, viewname, diff --git a/source/blender/editors/render/render_ops.c b/source/blender/editors/render/render_ops.c index bd75c6879e1..13fe40e768a 100644 --- a/source/blender/editors/render/render_ops.c +++ b/source/blender/editors/render/render_ops.c @@ -85,9 +85,6 @@ void ED_operatortypes_render(void) WM_operatortype_append(TEXTURE_OT_slot_copy); WM_operatortype_append(TEXTURE_OT_slot_paste); WM_operatortype_append(TEXTURE_OT_slot_move); - WM_operatortype_append(TEXTURE_OT_envmap_save); - WM_operatortype_append(TEXTURE_OT_envmap_clear); - WM_operatortype_append(TEXTURE_OT_envmap_clear_all); /* render_internal.c */ WM_operatortype_append(RENDER_OT_view_show); diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c index f2f147ab874..9a179ce3b47 100644 --- a/source/blender/editors/render/render_preview.c +++ b/source/blender/editors/render/render_preview.c @@ -242,32 +242,6 @@ void ED_preview_free_dbase(void) BKE_main_free(G_pr_main_cycles); } -static int preview_mat_has_sss(Material *mat, bNodeTree *ntree) -{ - if (mat) { - if (mat->sss_flag & MA_DIFF_SSS) - return 1; - if (mat->nodetree) - if (preview_mat_has_sss(NULL, mat->nodetree)) - return 1; - } - else if (ntree) { - bNode *node; - for (node = ntree->nodes.first; node; node = node->next) { - if (node->type == NODE_GROUP && node->id) { - if (preview_mat_has_sss(NULL, (bNodeTree *)node->id)) - return 1; - } - else if (node->id && ELEM(node->type, SH_NODE_MATERIAL, SH_NODE_MATERIAL_EXT)) { - mat = (Material *)node->id; - if (mat->sss_flag & MA_DIFF_SSS) - return 1; - } - } - } - return 0; -} - static Scene *preview_get_scene(Main *pr_main) { if (pr_main == NULL) return NULL; @@ -382,7 +356,7 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty * seems commonly used render engines does not support * such kind of rendering. */ - BLI_strncpy(sce->r.engine, RE_engine_id_BLENDER_RENDER, sizeof(sce->r.engine)); + BLI_strncpy(sce->r.engine, RE_engine_id_BLENDER_EEVEE, sizeof(sce->r.engine)); } else { BLI_strncpy(sce->r.engine, scene->r.engine, sizeof(sce->r.engine)); @@ -397,83 +371,22 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty sp->matcopy = mat; BLI_addtail(&pr_main->mat, mat); - if (!BKE_scene_use_new_shading_nodes(scene)) { - init_render_material(mat, 0, NULL); /* call that retrieves mode_l */ - end_render_material(mat); - - /* un-useful option */ - if (sp->pr_method == PR_ICON_RENDER) - mat->shade_flag &= ~MA_OBCOLOR; - - /* turn on raytracing if needed */ - if (mat->mode_l & MA_RAYMIRROR) - sce->r.mode |= R_RAYTRACE; - if (mat->material_type == MA_TYPE_VOLUME) - sce->r.mode |= R_RAYTRACE; - if ((mat->mode_l & MA_RAYTRANSP) && (mat->mode_l & MA_TRANSP)) - sce->r.mode |= R_RAYTRACE; - if (preview_mat_has_sss(mat, NULL)) - sce->r.mode |= R_SSS; - - /* turn off fake shadows if needed */ - /* this only works in a specific case where the preview.blend contains - * an object starting with 'c' which has a material linked to it (not the obdata) - * and that material has a fake shadow texture in the active texture slot */ - for (Base *base = view_layer->object_bases.first; base; base = base->next) { - Object *ob = base->object; - if (ob->id.name[2] == 'c') { - Material *shadmat = give_current_material(ob, ob->actcol); - if (shadmat) { - if (mat->mode2 & MA_CASTSHADOW) { - shadmat->septex = 0; - } - else { - shadmat->septex |= 1; - } - } - } - } - - /* turn off bounce lights for volume, - * doesn't make much visual difference and slows it down too */ - for (Base *base = view_layer->object_bases.first; base; base = base->next) { - Object *ob = base->object; - if (ob->type == OB_LAMP) { - /* if doesn't match 'Lamp.002' --> main key light */ - if (!STREQ(ob->id.name + 2, "Lamp.002")) { - if (mat->material_type == MA_TYPE_VOLUME) { - base->flag &= ~BASE_VISIBLED; - } - else { - base->flag |= BASE_VISIBLED; - } - } - } - } + /* use current scene world to light sphere */ + if (mat->pr_type == MA_SPHERE_A && sp->pr_method == PR_BUTS_RENDER) { + /* Use current scene world to light sphere. */ + sce->world = preview_get_localized_world(sp, scene->world); } - else { - /* use current scene world to light sphere */ - if (mat->pr_type == MA_SPHERE_A && sp->pr_method == PR_BUTS_RENDER) { - /* Use current scene world to light sphere. */ - sce->world = preview_get_localized_world(sp, scene->world); - } - else if (sce->world) { - /* Use a default world color. Using the current - * scene world can be slow if it has big textures. */ - sce->world->use_nodes = false; - sce->world->horr = 0.5f; - sce->world->horg = 0.5f; - sce->world->horb = 0.5f; - } + else if (sce->world) { + /* Use a default world color. Using the current + * scene world can be slow if it has big textures. */ + sce->world->use_nodes = false; + sce->world->horr = 0.5f; + sce->world->horg = 0.5f; + sce->world->horb = 0.5f; } if (sp->pr_method == PR_ICON_RENDER) { - if (mat->material_type == MA_TYPE_HALO) { - set_preview_layer(view_layer, MA_FLAT); - } - else { - set_preview_layer(view_layer, MA_SPHERE_A); - } + set_preview_layer(view_layer, MA_SPHERE_A); } else { set_preview_layer(view_layer, mat->pr_type); @@ -486,7 +399,7 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty } } else { - sce->r.mode &= ~(R_OSA | R_RAYTRACE | R_SSS); + sce->r.mode &= ~(R_OSA); } @@ -519,29 +432,6 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty } set_preview_layer(view_layer, MA_TEXTURE); - for (Base *base = view_layer->object_bases.first; base; base = base->next) { - if (base->object->id.name[2] == 't') { - Material *mat = give_current_material(base->object, base->object->actcol); - if (mat && mat->mtex[0]) { - mat->mtex[0]->tex = tex; - - if (tex && sp->slot) - mat->mtex[0]->which_output = sp->slot->which_output; - - mat->mtex[0]->mapto &= ~MAP_ALPHA; - mat->alpha = 1.0f; - - /* show alpha in this case */ - if (tex == NULL || (tex->flag & TEX_PRV_ALPHA)) { - if (!(tex && tex->type == TEX_IMAGE && (tex->imaflag & (TEX_USEALPHA | TEX_CALCALPHA)) == 0)) { - mat->mtex[0]->mapto |= MAP_ALPHA; - mat->alpha = 0.0f; - } - } - } - } - } - if (tex && tex->nodetree && sp->pr_method == PR_NODE_RENDER) { /* two previews, they get copied by wmJob */ BKE_node_preview_init_tree(origtex->nodetree, sp->sizex, sp->sizey, true); @@ -558,28 +448,14 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty BLI_addtail(&pr_main->lamp, la); } - if (!BKE_scene_use_new_shading_nodes(scene)) { - if (la && la->type == LA_SUN && (la->sun_effect_type & LA_SUN_EFFECT_SKY)) { - set_preview_layer(view_layer, MA_ATMOS); - sce->world = preview_get_localized_world(sp, scene->world); - sce->camera = (Object *)BLI_findstring(&pr_main->object, "CameraAtmo", offsetof(ID, name) + 2); - } - else { - sce->world = NULL; - sce->camera = (Object *)BLI_findstring(&pr_main->object, "Camera", offsetof(ID, name) + 2); - set_preview_layer(view_layer, MA_LAMP); - } - } - else { - set_preview_layer(view_layer, MA_LAMP); + set_preview_layer(view_layer, MA_LAMP); - if (sce->world) { - /* Only use lighting from the lamp. */ - sce->world->use_nodes = false; - sce->world->horr = 0.0f; - sce->world->horg = 0.0f; - sce->world->horb = 0.0f; - } + if (sce->world) { + /* Only use lighting from the lamp. */ + sce->world->use_nodes = false; + sce->world->horr = 0.0f; + sce->world->horg = 0.0f; + sce->world->horb = 0.0f; } for (Base *base = view_layer->object_bases.first; base; base = base->next) { @@ -1132,12 +1008,6 @@ static void icon_preview_startjob(void *customdata, short *stop, short *do_updat if (idtype == ID_WO) { set_alpha((char *)sp->pr_rect, sp->sizex, sp->sizey, 255); } - else if (idtype == ID_MA) { - Material *ma = (Material *)id; - - if (ma->material_type == MA_TYPE_HALO) - set_alpha((char *)sp->pr_rect, sp->sizex, sp->sizey, 255); - } } } } @@ -1182,7 +1052,6 @@ static void icon_preview_startjob_all_sizes(void *customdata, short *stop, short { IconPreview *ip = (IconPreview *)customdata; IconPreviewSize *cur_size; - const bool use_new_shading = BKE_scene_use_new_shading_nodes(ip->scene); for (cur_size = ip->sizes.first; cur_size; cur_size = cur_size->next) { PreviewImage *prv = ip->owner; @@ -1207,19 +1076,14 @@ static void icon_preview_startjob_all_sizes(void *customdata, short *stop, short if (is_render) { BLI_assert(ip->id); - if (use_new_shading) { - /* texture icon rendering is hardcoded to use BI, - * so don't even think of using cycle's bmain for - * texture icons - */ - if (GS(ip->id->name) != ID_TE) - sp->pr_main = G_pr_main_cycles; - else - sp->pr_main = G_pr_main; - } - else { + /* texture icon rendering is hardcoded to use the BI scene, + * so don't even think of using cycle's bmain for + * texture icons + */ + if (GS(ip->id->name) != ID_TE) + sp->pr_main = G_pr_main_cycles; + else sp->pr_main = G_pr_main; - } } common_preview_startjob(sp, stop, do_update, progress); @@ -1344,10 +1208,9 @@ void ED_preview_shader_job(const bContext *C, void *owner, ID *id, ID *parent, M short id_type = GS(id->name); /* Use workspace render only for buttons Window, since the other previews are related to the datablock. */ - bool use_new_shading = BKE_scene_use_new_shading_nodes(scene); /* Only texture node preview is supported with Cycles. */ - if (use_new_shading && method == PR_NODE_RENDER && id_type != ID_TE) { + if (method == PR_NODE_RENDER && id_type != ID_TE) { return; } @@ -1368,9 +1231,9 @@ void ED_preview_shader_job(const bContext *C, void *owner, ID *id, ID *parent, M sp->slot = slot; sp->bmain = CTX_data_main(C); - /* hardcoded preview .blend for Eevee + cycles/internal, this should be solved + /* hardcoded preview .blend for Eevee + Cycles, this should be solved * once with custom preview .blend path for external engines */ - if ((method != PR_NODE_RENDER) && id_type != ID_TE && use_new_shading) { + if ((method != PR_NODE_RENDER) && id_type != ID_TE) { sp->pr_main = G_pr_main_cycles; } else { @@ -1388,11 +1251,9 @@ void ED_preview_shader_job(const bContext *C, void *owner, ID *id, ID *parent, M WM_jobs_start(CTX_wm_manager(C), wm_job); } -void ED_preview_kill_jobs(wmWindowManager *wm, Main *bmain) +void ED_preview_kill_jobs(wmWindowManager *wm, Main *UNUSED(bmain)) { if (wm) WM_jobs_kill(wm, NULL, common_preview_startjob); - - ED_viewport_render_kill_jobs(wm, bmain, false); } diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c index 270ba2a7947..c5787a1d46c 100644 --- a/source/blender/editors/render/render_shading.c +++ b/source/blender/editors/render/render_shading.c @@ -460,7 +460,6 @@ void OBJECT_OT_material_slot_move(wmOperatorType *ot) static int new_material_exec(bContext *C, wmOperator *UNUSED(op)) { - Scene *scene = CTX_data_scene(C); Material *ma = CTX_data_pointer_get_type(C, "material", &RNA_Material).data; Main *bmain = CTX_data_main(C); PointerRNA ptr, idptr; @@ -472,11 +471,8 @@ static int new_material_exec(bContext *C, wmOperator *UNUSED(op)) } else { ma = BKE_material_add(bmain, DATA_("Material")); - - if (BKE_scene_use_new_shading_nodes(scene)) { - ED_node_shader_default(C, &ma->id); - ma->use_nodes = true; - } + ED_node_shader_default(C, &ma->id); + ma->use_nodes = true; } /* hook into UI */ @@ -536,14 +532,6 @@ static int new_texture_exec(bContext *C, wmOperator *UNUSED(op)) * pointer use also increases user, so this compensates it */ id_us_min(&tex->id); - if (ptr.id.data && GS(((ID *)ptr.id.data)->name) == ID_MA && - RNA_property_pointer_get(&ptr, prop).id.data == NULL) - { - /* In case we are assigning new texture to a material, and active slot was empty, reset 'use' flag. */ - Material *ma = (Material *)ptr.id.data; - ma->septex &= ~(1 << ma->texact); - } - RNA_id_pointer_create(&tex->id, &idptr); RNA_property_pointer_set(&ptr, prop, idptr); RNA_property_update(C, &ptr, prop); @@ -572,7 +560,6 @@ void TEXTURE_OT_new(wmOperatorType *ot) static int new_world_exec(bContext *C, wmOperator *UNUSED(op)) { - Scene *scene = CTX_data_scene(C); World *wo = CTX_data_pointer_get_type(C, "world", &RNA_World).data; Main *bmain = CTX_data_main(C); PointerRNA ptr, idptr; @@ -584,11 +571,8 @@ static int new_world_exec(bContext *C, wmOperator *UNUSED(op)) } else { wo = BKE_world_add(bmain, DATA_("World")); - - if (BKE_scene_use_new_shading_nodes(scene)) { - ED_node_shader_default(C, &wo->id); - wo->use_nodes = true; - } + ED_node_shader_default(C, &wo->id); + wo->use_nodes = true; } /* hook into UI */ @@ -1457,15 +1441,6 @@ static int texture_slot_move_exec(bContext *C, wmOperator *op) BKE_animdata_fix_paths_rename(id, adt, NULL, "texture_slots", NULL, NULL, act - 1, -1, 0); BKE_animdata_fix_paths_rename(id, adt, NULL, "texture_slots", NULL, NULL, act, act - 1, 0); BKE_animdata_fix_paths_rename(id, adt, NULL, "texture_slots", NULL, NULL, -1, act, 0); - - if (GS(id->name) == ID_MA) { - Material *ma = (Material *)id; - int mtexuse = ma->septex & (1 << act); - ma->septex &= ~(1 << act); - ma->septex |= (ma->septex & (1 << (act - 1))) << 1; - ma->septex &= ~(1 << (act - 1)); - ma->septex |= mtexuse >> 1; - } set_active_mtex(id, act - 1); } @@ -1479,15 +1454,6 @@ static int texture_slot_move_exec(bContext *C, wmOperator *op) BKE_animdata_fix_paths_rename(id, adt, NULL, "texture_slots", NULL, NULL, act + 1, -1, 0); BKE_animdata_fix_paths_rename(id, adt, NULL, "texture_slots", NULL, NULL, act, act + 1, 0); BKE_animdata_fix_paths_rename(id, adt, NULL, "texture_slots", NULL, NULL, -1, act, 0); - - if (GS(id->name) == ID_MA) { - Material *ma = (Material *)id; - int mtexuse = ma->septex & (1 << act); - ma->septex &= ~(1 << act); - ma->septex |= (ma->septex & (1 << (act + 1))) >> 1; - ma->septex &= ~(1 << (act + 1)); - ma->septex |= mtexuse << 1; - } set_active_mtex(id, act + 1); } @@ -1524,180 +1490,6 @@ void TEXTURE_OT_slot_move(wmOperatorType *ot) -/********************** environment map operators *********************/ - -static int save_envmap(wmOperator *op, Scene *scene, EnvMap *env, char *path, const char imtype) -{ - PropertyRNA *prop; - float layout[12]; - - if ((prop = RNA_struct_find_property(op->ptr, "layout"))) { - RNA_property_float_get_array(op->ptr, prop, layout); - } - else { - memcpy(layout, default_envmap_layout, sizeof(layout)); - } - - if (RE_WriteEnvmapResult(op->reports, scene, env, path, imtype, layout)) { - return OPERATOR_FINISHED; - } - else { - return OPERATOR_CANCELLED; - } - -} - -static int envmap_save_exec(bContext *C, wmOperator *op) -{ - Tex *tex = CTX_data_pointer_get_type(C, "texture", &RNA_Texture).data; - Scene *scene = CTX_data_scene(C); - //int imtype = RNA_enum_get(op->ptr, "file_type"); - char imtype = scene->r.im_format.imtype; - char path[FILE_MAX]; - - RNA_string_get(op->ptr, "filepath", path); - - if (scene->r.scemode & R_EXTENSION) { - BKE_image_path_ensure_ext_from_imformat(path, &scene->r.im_format); - } - - WM_cursor_wait(1); - - save_envmap(op, scene, tex->env, path, imtype); - - WM_cursor_wait(0); - - WM_event_add_notifier(C, NC_TEXTURE, tex); - - return OPERATOR_FINISHED; -} - -static int envmap_save_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) -{ - //Scene *scene= CTX_data_scene(C); - - if (RNA_struct_property_is_set(op->ptr, "filepath")) - return envmap_save_exec(C, op); - - //RNA_enum_set(op->ptr, "file_type", scene->r.im_format.imtype); - RNA_string_set(op->ptr, "filepath", G.main->name); - WM_event_add_fileselect(C, op); - - return OPERATOR_RUNNING_MODAL; -} - -static int envmap_save_poll(bContext *C) -{ - Tex *tex = CTX_data_pointer_get_type(C, "texture", &RNA_Texture).data; - - if (!tex) - return 0; - if (!tex->env || !tex->env->ok) - return 0; - if (tex->env->cube[1] == NULL) - return 0; - - return 1; -} - -void TEXTURE_OT_envmap_save(wmOperatorType *ot) -{ - PropertyRNA *prop; - /* identifiers */ - ot->name = "Save Environment Map"; - ot->idname = "TEXTURE_OT_envmap_save"; - ot->description = "Save the current generated Environment map to an image file"; - - /* api callbacks */ - ot->exec = envmap_save_exec; - ot->invoke = envmap_save_invoke; - ot->poll = envmap_save_poll; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_INTERNAL; /* no undo since this doesnt modify the env-map */ - - /* properties */ - prop = RNA_def_float_array(ot->srna, "layout", 12, default_envmap_layout, 0.0f, 0.0f, - "File layout", - "Flat array describing the X,Y position of each cube face in the output image, " - "where 1 is the size of a face - order is [+Z -Z +Y -X -Y +X] " - "(use -1 to skip a face)", 0.0f, 0.0f); - RNA_def_property_flag(prop, PROP_HIDDEN); - - WM_operator_properties_filesel( - ot, FILE_TYPE_FOLDER | FILE_TYPE_IMAGE | FILE_TYPE_MOVIE, FILE_SPECIAL, FILE_SAVE, - WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY, FILE_SORT_ALPHA); -} - -static int envmap_clear_exec(bContext *C, wmOperator *UNUSED(op)) -{ - Tex *tex = CTX_data_pointer_get_type(C, "texture", &RNA_Texture).data; - - BKE_texture_envmap_free_data(tex->env); - - WM_event_add_notifier(C, NC_TEXTURE | NA_EDITED, tex); - - return OPERATOR_FINISHED; -} - -static int envmap_clear_poll(bContext *C) -{ - Tex *tex = CTX_data_pointer_get_type(C, "texture", &RNA_Texture).data; - - if (!tex) - return 0; - if (!tex->env || !tex->env->ok) - return 0; - if (tex->env->cube[1] == NULL) - return 0; - - return 1; -} - -void TEXTURE_OT_envmap_clear(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Clear Environment Map"; - ot->idname = "TEXTURE_OT_envmap_clear"; - ot->description = "Discard the environment map and free it from memory"; - - /* api callbacks */ - ot->exec = envmap_clear_exec; - ot->poll = envmap_clear_poll; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; -} - -static int envmap_clear_all_exec(bContext *C, wmOperator *UNUSED(op)) -{ - Main *bmain = CTX_data_main(C); - Tex *tex; - - for (tex = bmain->tex.first; tex; tex = tex->id.next) - if (tex->env) - BKE_texture_envmap_free_data(tex->env); - - WM_event_add_notifier(C, NC_TEXTURE | NA_EDITED, tex); - - return OPERATOR_FINISHED; -} - -void TEXTURE_OT_envmap_clear_all(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Clear All Environment Maps"; - ot->idname = "TEXTURE_OT_envmap_clear_all"; - ot->description = "Discard all environment maps in the .blend file and free them from memory"; - - /* api callbacks */ - ot->exec = envmap_clear_all_exec; - ot->poll = envmap_clear_poll; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; -} - /********************** material operators *********************/ /* material copy/paste */ @@ -1769,17 +1561,6 @@ static void copy_mtex_copybuf(ID *id) MTex **mtex = NULL; switch (GS(id->name)) { - case ID_MA: - mtex = &(((Material *)id)->mtex[(int)((Material *)id)->texact]); - break; - case ID_LA: - mtex = &(((Lamp *)id)->mtex[(int)((Lamp *)id)->texact]); - // la->mtex[(int)la->texact] // TODO - break; - case ID_WO: - mtex = &(((World *)id)->mtex[(int)((World *)id)->texact]); - // mtex= wrld->mtex[(int)wrld->texact]; // TODO - break; case ID_PA: mtex = &(((ParticleSettings *)id)->mtex[(int)((ParticleSettings *)id)->texact]); break; @@ -1807,17 +1588,6 @@ static void paste_mtex_copybuf(ID *id) return; switch (GS(id->name)) { - case ID_MA: - mtex = &(((Material *)id)->mtex[(int)((Material *)id)->texact]); - break; - case ID_LA: - mtex = &(((Lamp *)id)->mtex[(int)((Lamp *)id)->texact]); - // la->mtex[(int)la->texact] // TODO - break; - case ID_WO: - mtex = &(((World *)id)->mtex[(int)((World *)id)->texact]); - // mtex= wrld->mtex[(int)wrld->texact]; // TODO - break; case ID_PA: mtex = &(((ParticleSettings *)id)->mtex[(int)((ParticleSettings *)id)->texact]); break; diff --git a/source/blender/editors/render/render_update.c b/source/blender/editors/render/render_update.c index 9ae103ae017..1864cb0af6a 100644 --- a/source/blender/editors/render/render_update.c +++ b/source/blender/editors/render/render_update.c @@ -59,9 +59,7 @@ #include "BKE_scene.h" #include "BKE_workspace.h" -#include "GPU_lamp.h" #include "GPU_material.h" -#include "GPU_buffers.h" #include "RE_engine.h" #include "RE_pipeline.h" @@ -145,20 +143,18 @@ void ED_render_scene_update(const DEGEditorUpdateContext *update_ctx, int update } else { - RenderEngineType *engine_type = RE_engines_find(win->scene->r.engine); - if ((engine_type->flag & RE_USE_LEGACY_PIPELINE) == 0) { - if (updated) { - DRW_notify_view_update( - (&(DRWUpdateContext){ - .bmain = bmain, - .depsgraph = update_ctx->depsgraph, - .scene = scene, - .view_layer = view_layer, - .ar = ar, - .v3d = (View3D *)sa->spacedata.first, - .engine_type = engine_type - })); - } + RenderEngineType *engine_type = RE_engines_find(scene->r.engine); + if (updated) { + DRW_notify_view_update( + (&(DRWUpdateContext){ + .bmain = bmain, + .depsgraph = update_ctx->depsgraph, + .scene = scene, + .view_layer = view_layer, + .ar = ar, + .v3d = (View3D *)sa->spacedata.first, + .engine_type = engine_type + })); } } } @@ -243,69 +239,8 @@ static void render_engine_flag_changed(Main *bmain, int update_flag) } } -static int mtex_use_tex(MTex **mtex, int tot, Tex *tex) +static void material_changed(Main *UNUSED(bmain), Material *ma) { - int a; - - if (!mtex) - return 0; - - for (a = 0; a < tot; a++) - if (mtex[a] && mtex[a]->tex == tex) - return 1; - - return 0; -} - -static int nodes_use_tex(bNodeTree *ntree, Tex *tex) -{ - bNode *node; - - for (node = ntree->nodes.first; node; node = node->next) { - if (node->id) { - if (node->id == (ID *)tex) { - return 1; - } - else if (GS(node->id->name) == ID_MA) { - if (mtex_use_tex(((Material *)node->id)->mtex, MAX_MTEX, tex)) - return 1; - } - else if (node->type == NODE_GROUP) { - if (nodes_use_tex((bNodeTree *)node->id, tex)) - return 1; - } - } - } - - return 0; -} - -static int nodes_use_material(bNodeTree *ntree, Material *ma) -{ - bNode *node; - - for (node = ntree->nodes.first; node; node = node->next) { - if (node->id) { - if (node->id == (ID *)ma) { - return 1; - } - else if (node->type == NODE_GROUP) { - if (nodes_use_material((bNodeTree *)node->id, ma)) - return 1; - } - } - } - - return 0; -} - -static void material_changed(Main *bmain, Material *ma) -{ - Material *parent; - Object *ob; - Scene *scene; - int texture_draw = false; - /* icons */ BKE_icon_changed(BKE_icon_id_ensure(&ma->id)); @@ -315,86 +250,22 @@ static void material_changed(Main *bmain, Material *ma) GPU_material_free(&ma->gpumaterial); } } - - /* find node materials using this */ - for (parent = bmain->mat.first; parent; parent = parent->id.next) { - if (parent->use_nodes && parent->nodetree && nodes_use_material(parent->nodetree, ma)) { - /* pass */ - } - else { - continue; - } - - BKE_icon_changed(BKE_icon_id_ensure(&parent->id)); - - if (parent->gpumaterial.first) - GPU_material_free(&parent->gpumaterial); - } - - /* find if we have a scene with textured display */ - for (scene = bmain->scene.first; scene; scene = scene->id.next) { - if (scene->customdata_mask & CD_MASK_MTFACE) { - texture_draw = true; - break; - } - } - - /* find textured objects */ - if (texture_draw) { - for (ob = bmain->object.first; ob; ob = ob->id.next) { - DerivedMesh *dm = ob->derivedFinal; - Material ***material = give_matarar(ob); - short a, *totmaterial = give_totcolp(ob); - - if (dm && totmaterial && material) { - for (a = 0; a < *totmaterial; a++) { - if ((*material)[a] == ma) { - GPU_drawobject_free(dm); - break; - } - } - } - } - } - } -static void lamp_changed(Main *bmain, Lamp *la) +static void lamp_changed(Main *UNUSED(bmain), Lamp *la) { - Object *ob; - /* icons */ BKE_icon_changed(BKE_icon_id_ensure(&la->id)); - /* glsl */ - for (ob = bmain->object.first; ob; ob = ob->id.next) - if (ob->data == la && ob->gpulamp.first) - GPU_lamp_free(ob); - if (defmaterial.gpumaterial.first) GPU_material_free(&defmaterial.gpumaterial); } -static int material_uses_texture(Material *ma, Tex *tex) -{ - if (mtex_use_tex(ma->mtex, MAX_MTEX, tex)) - return true; - else if (ma->use_nodes && ma->nodetree && nodes_use_tex(ma->nodetree, tex)) - return true; - - return false; -} - static void texture_changed(Main *bmain, Tex *tex) { - Material *ma; - Lamp *la; - World *wo; Scene *scene; ViewLayer *view_layer; - Object *ob; bNode *node; - bool texture_draw = false; /* icons */ BKE_icon_changed(BKE_icon_id_ensure(&tex->id)); @@ -406,48 +277,6 @@ static void texture_changed(Main *bmain, Tex *tex) } } - /* find materials */ - for (ma = bmain->mat.first; ma; ma = ma->id.next) { - if (!material_uses_texture(ma, tex)) - continue; - - BKE_icon_changed(BKE_icon_id_ensure(&ma->id)); - - if (ma->gpumaterial.first) - GPU_material_free(&ma->gpumaterial); - } - - /* find lamps */ - for (la = bmain->lamp.first; la; la = la->id.next) { - if (mtex_use_tex(la->mtex, MAX_MTEX, tex)) { - lamp_changed(bmain, la); - } - else if (la->nodetree && nodes_use_tex(la->nodetree, tex)) { - lamp_changed(bmain, la); - } - else { - continue; - } - } - - /* find worlds */ - for (wo = bmain->world.first; wo; wo = wo->id.next) { - if (mtex_use_tex(wo->mtex, MAX_MTEX, tex)) { - /* pass */ - } - else if (wo->nodetree && nodes_use_tex(wo->nodetree, tex)) { - /* pass */ - } - else { - continue; - } - - BKE_icon_changed(BKE_icon_id_ensure(&wo->id)); - - if (wo->gpumaterial.first) - GPU_material_free(&wo->gpumaterial); - } - /* find compositing nodes */ for (scene = bmain->scene.first; scene; scene = scene->id.next) { if (scene->use_nodes && scene->nodetree) { @@ -456,32 +285,6 @@ static void texture_changed(Main *bmain, Tex *tex) ED_node_tag_update_id(&scene->id); } } - - if (scene->customdata_mask & CD_MASK_MTFACE) - texture_draw = true; - } - - /* find textured objects */ - if (texture_draw) { - for (ob = bmain->object.first; ob; ob = ob->id.next) { - DerivedMesh *dm = ob->derivedFinal; - Material ***material = give_matarar(ob); - short a, *totmaterial = give_totcolp(ob); - - if (dm && totmaterial && material) { - for (a = 0; a < *totmaterial; a++) { - if (ob->matbits && ob->matbits[a]) - ma = ob->mat[a]; - else - ma = (*material)[a]; - - if (ma && material_uses_texture(ma, tex)) { - GPU_drawobject_free(dm); - break; - } - } - } - } } } @@ -526,7 +329,6 @@ static void scene_changed(Main *bmain, Scene *scene) if (ob->mode & OB_MODE_TEXTURE_PAINT) { BKE_texpaint_slots_refresh_object(scene, ob); BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL); - GPU_drawobject_free(ob->derivedFinal); } } } @@ -568,12 +370,3 @@ void ED_render_id_flush_update(const DEGEditorUpdateContext *update_ctx, ID *id) } } - -void ED_render_internal_init(void) -{ - RenderEngineType *ret = RE_engines_find(RE_engine_id_BLENDER_RENDER); - - ret->view_update = render_view3d_update; - ret->render_to_view = render_view3d_draw; - -} diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c index ae26de8b269..dbb12282d0a 100644 --- a/source/blender/editors/sculpt_paint/paint_image.c +++ b/source/blender/editors/sculpt_paint/paint_image.c @@ -78,7 +78,6 @@ #include "RNA_define.h" #include "GPU_draw.h" -#include "GPU_buffers.h" #include "GPU_immediate.h" #include "BIF_gl.h" @@ -1121,7 +1120,6 @@ static int texture_paint_toggle_exec(bContext *C, wmOperator *op) // ED_workspace_object_mode_sync_from_object(wm, workspace, ob); - GPU_drawobject_free(ob->derivedFinal); WM_event_add_notifier(C, NC_SCENE | ND_MODE, scene); return OPERATOR_FINISHED; diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c index 469498f927a..cacb75b2668 100644 --- a/source/blender/editors/sculpt_paint/paint_image_proj.c +++ b/source/blender/editors/sculpt_paint/paint_image_proj.c @@ -283,7 +283,6 @@ typedef struct ProjPaintState { bool do_backfacecull; /* ignore faces with normals pointing away, skips a lot of raycasts if your normals are correctly flipped */ bool do_mask_normal; /* mask out pixels based on their normals */ bool do_mask_cavity; /* mask out pixels based on cavity */ - bool do_new_shading_nodes; /* cache BKE_scene_use_new_shading_nodes value */ float normal_angle; /* what angle to mask at */ float normal_angle__cos; /* cos(normal_angle), faster to compare */ float normal_angle_inner; @@ -5102,7 +5101,6 @@ static void project_state_init(bContext *C, Object *ob, ProjPaintState *ps, int else { ps->do_backfacecull = ps->do_occlude = ps->do_mask_normal = 0; } - ps->do_new_shading_nodes = BKE_scene_use_new_shading_nodes(scene); /* only cache the value */ if (ps->tool == PAINT_TOOL_CLONE) ps->do_layer_clone = (settings->imapaint.flag & IMAGEPAINT_PROJECT_LAYER_CLONE) ? 1 : 0; @@ -5438,7 +5436,6 @@ static int texture_paint_image_from_view_exec(bContext *C, wmOperator *op) Depsgraph *depsgraph = CTX_data_depsgraph(C); Scene *scene = CTX_data_scene(C); - ViewLayer *view_layer = CTX_data_view_layer(C); ToolSettings *settings = scene->toolsettings; View3D *v3d = CTX_wm_view3d(C); RegionView3D *rv3d = CTX_wm_region_view3d(C); @@ -5455,7 +5452,7 @@ static int texture_paint_image_from_view_exec(bContext *C, wmOperator *op) if (h > maxsize) h = maxsize; ibuf = ED_view3d_draw_offscreen_imbuf( - depsgraph, scene, view_layer, v3d->drawtype, + depsgraph, scene, v3d->drawtype, v3d, CTX_wm_region(C), w, h, IB_rect, V3D_OFSDRAW_NONE, R_ALPHAPREMUL, 0, NULL, NULL, err_out); @@ -5626,20 +5623,11 @@ bool BKE_paint_proj_mesh_data_check(Scene *scene, Object *ob, bool *uvs, bool *m /* Add layer operator */ static const EnumPropertyItem layer_type_items[] = { - {MAP_COL, "DIFFUSE_COLOR", 0, "Diffuse Color", ""}, - {MAP_REF, "DIFFUSE_INTENSITY", 0, "Diffuse Intensity", ""}, - {MAP_ALPHA, "ALPHA", 0, "Alpha", ""}, - {MAP_TRANSLU, "TRANSLUCENCY", 0, "Translucency", ""}, - {MAP_COLSPEC, "SPECULAR_COLOR", 0, "Specular Color", ""}, - {MAP_SPEC, "SPECULAR_INTENSITY", 0, "Specular Intensity", ""}, - {MAP_HAR, "SPECULAR_HARDNESS", 0, "Specular Hardness", ""}, - {MAP_AMB, "AMBIENT", 0, "Ambient", ""}, - {MAP_EMIT, "EMIT", 0, "Emit", ""}, - {MAP_COLMIR, "MIRROR_COLOR", 0, "Mirror Color", ""}, - {MAP_RAYMIRR, "RAYMIRROR", 0, "Ray Mirror", ""}, - {MAP_NORM, "NORMAL", 0, "Normal", ""}, - {MAP_WARP, "WARP", 0, "Warp", ""}, - {MAP_DISPLACE, "DISPLACE", 0, "Displace", ""}, + {0, "BASE_COLOR", 0, "Base Color", ""}, + {1, "EMISSION", 0, "Emission", ""}, + {2, "NORMAL", 0, "Normal", ""}, + {3, "BUMP", 0, "Bump", ""}, + {4, "DISPLACEMENT", 0, "Displacement", ""}, {0, NULL, 0, NULL, NULL} }; @@ -5674,7 +5662,6 @@ static bool proj_paint_add_slot(bContext *C, wmOperator *op) Object *ob = CTX_data_active_object(C); Scene *scene = CTX_data_scene(C); Material *ma; - bool is_bi = BKE_scene_uses_blender_internal(scene); Image *ima = NULL; if (!ob) @@ -5683,55 +5670,29 @@ static bool proj_paint_add_slot(bContext *C, wmOperator *op) ma = give_current_material(ob, ob->actcol); if (ma) { + /* TODO: use type to link to proper socket. */ Main *bmain = CTX_data_main(C); - if (!is_bi && BKE_scene_use_new_shading_nodes(scene)) { - bNode *imanode; - bNodeTree *ntree = ma->nodetree; - - if (!ntree) { - ED_node_shader_default(C, &ma->id); - ntree = ma->nodetree; - } - - ma->use_nodes = true; - - /* try to add an image node */ - imanode = nodeAddStaticNode(C, ntree, SH_NODE_TEX_IMAGE); - - ima = proj_paint_image_create(op, bmain); - imanode->id = &ima->id; - - nodeSetActive(ntree, imanode); - - ntreeUpdateTree(CTX_data_main(C), ntree); - } - else { - MTex *mtex = BKE_texture_mtex_add_id(&ma->id, -1); - - /* successful creation of mtex layer, now create set */ - if (mtex) { - int type = MAP_COL; - char imagename_buff[MAX_ID_NAME - 2]; - const char *imagename = DATA_("Diffuse Color"); - - if (op) { - type = RNA_enum_get(op->ptr, "type"); - RNA_string_get(op->ptr, "name", imagename_buff); - imagename = imagename_buff; - } - - mtex->tex = BKE_texture_add(bmain, imagename); - mtex->mapto = type; - - if (mtex->tex) { - ima = mtex->tex->ima = proj_paint_image_create(op, bmain); - } + bNode *imanode; + bNodeTree *ntree = ma->nodetree; - WM_event_add_notifier(C, NC_TEXTURE | NA_ADDED, mtex->tex); - } + if (!ntree) { + ED_node_shader_default(C, &ma->id); + ntree = ma->nodetree; } + ma->use_nodes = true; + + /* try to add an image node */ + imanode = nodeAddStaticNode(C, ntree, SH_NODE_TEX_IMAGE); + + ima = proj_paint_image_create(op, bmain); + imanode->id = &ima->id; + + nodeSetActive(ntree, imanode); + + ntreeUpdateTree(CTX_data_main(C), ntree); + if (ima) { BKE_texpaint_slot_refresh_cache(scene, ma); BKE_image_signal(ima, NULL, IMA_SIGNAL_USER_NEW_IMAGE); @@ -5822,59 +5783,6 @@ void PAINT_OT_add_texture_paint_slot(wmOperatorType *ot) RNA_def_boolean(ot->srna, "float", 0, "32 bit Float", "Create image with 32 bit floating point bit depth"); } -static int texture_paint_delete_texture_paint_slot_exec(bContext *C, wmOperator *UNUSED(op)) -{ - Object *ob = CTX_data_active_object(C); - Scene *scene = CTX_data_scene(C); - Material *ma; - bool is_bi = BKE_scene_uses_blender_internal(scene); - TexPaintSlot *slot; - - /* not supported for node-based engines */ - if (!ob || !is_bi) - return OPERATOR_CANCELLED; - - ma = give_current_material(ob, ob->actcol); - - if (!ma->texpaintslot || ma->use_nodes) - return OPERATOR_CANCELLED; - - slot = ma->texpaintslot + ma->paint_active_slot; - - if (ma->mtex[slot->index]->tex) { - id_us_min(&ma->mtex[slot->index]->tex->id); - - if (ma->mtex[slot->index]->tex->ima) { - id_us_min(&ma->mtex[slot->index]->tex->ima->id); - } - } - MEM_freeN(ma->mtex[slot->index]); - ma->mtex[slot->index] = NULL; - - BKE_texpaint_slot_refresh_cache(scene, ma); - DEG_id_tag_update(&ma->id, 0); - WM_event_add_notifier(C, NC_MATERIAL, ma); - /* we need a notifier for data change since we change the displayed modifier uvs */ - WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data); - return OPERATOR_FINISHED; -} - - -void PAINT_OT_delete_texture_paint_slot(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Delete Texture Paint Slot"; - ot->description = "Delete selected texture paint slot"; - ot->idname = "PAINT_OT_delete_texture_paint_slot"; - - /* api callbacks */ - ot->exec = texture_paint_delete_texture_paint_slot_exec; - ot->poll = ED_operator_region_view3d_active; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; -} - static int add_simple_uvs_exec(bContext *C, wmOperator *UNUSED(op)) { /* no checks here, poll function does them for us */ diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h index 4298fba3b2b..ca82ca52463 100644 --- a/source/blender/editors/sculpt_paint/paint_intern.h +++ b/source/blender/editors/sculpt_paint/paint_intern.h @@ -216,7 +216,6 @@ void PAINT_OT_texture_paint_toggle(struct wmOperatorType *ot); void PAINT_OT_project_image(struct wmOperatorType *ot); void PAINT_OT_image_from_view(struct wmOperatorType *ot); void PAINT_OT_add_texture_paint_slot(struct wmOperatorType *ot); -void PAINT_OT_delete_texture_paint_slot(struct wmOperatorType *ot); void PAINT_OT_image_paint(struct wmOperatorType *ot); void PAINT_OT_add_simple_uvs(struct wmOperatorType *ot); diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c index 004d2757a71..ad3047d6345 100644 --- a/source/blender/editors/sculpt_paint/paint_ops.c +++ b/source/blender/editors/sculpt_paint/paint_ops.c @@ -1035,7 +1035,6 @@ void ED_operatortypes_paint(void) WM_operatortype_append(PAINT_OT_image_from_view); WM_operatortype_append(PAINT_OT_brush_colors_flip); WM_operatortype_append(PAINT_OT_add_texture_paint_slot); - WM_operatortype_append(PAINT_OT_delete_texture_paint_slot); WM_operatortype_append(PAINT_OT_add_simple_uvs); /* weight */ diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index 0ae6db1f41d..1775d4b9c8b 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -3100,10 +3100,6 @@ static void vpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P * avoid this if we can! */ DEG_id_tag_update(ob->data, 0); } - else { - /* If using new VBO drawing, mark mcol as dirty to force colors gpu buffer refresh! */ - ob->derivedFinal->dirty |= DM_DIRTY_MCOL_UPDATE_DRAW; - } } static void vpaint_stroke_done(const bContext *C, struct PaintStroke *stroke) diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 3af789d4ebe..1d1c8460cfd 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -87,9 +87,6 @@ #include "RNA_access.h" #include "RNA_define.h" -#include "GPU_buffers.h" -#include "GPU_extensions.h" - #include "UI_interface.h" #include "UI_resources.h" @@ -4866,8 +4863,6 @@ static void sculpt_flush_update(bContext *C) if (mmd) multires_mark_as_modified(ob, MULTIRES_COORDS_MODIFIED); - if (ob->derivedFinal) /* VBO no longer valid */ - GPU_drawobject_free(ob->derivedFinal); if (ss->kb || ss->modifiers_active) { DEG_id_tag_update(&ob->id, OB_RECALC_DATA); @@ -5734,11 +5729,6 @@ void ED_object_sculptmode_enter_ex( } // ED_workspace_object_mode_sync_from_object(G.main->wm.first, workspace, ob); - - /* VBO no longer valid */ - if (ob->derivedFinal) { - GPU_drawobject_free(ob->derivedFinal); - } } void ED_object_sculptmode_enter(struct bContext *C, ReportList *reports) @@ -5791,11 +5781,6 @@ void ED_object_sculptmode_exit_ex( BKE_sculptsession_free(ob); paint_cursor_delete_textures(); - - /* VBO no longer valid */ - if (ob->derivedFinal) { - GPU_drawobject_free(ob->derivedFinal); - } } void ED_object_sculptmode_exit(bContext *C) diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c index 3feb8e105e6..b819fe8e97d 100644 --- a/source/blender/editors/sculpt_paint/sculpt_undo.c +++ b/source/blender/editors/sculpt_paint/sculpt_undo.c @@ -66,8 +66,6 @@ #include "WM_api.h" #include "WM_types.h" -#include "GPU_buffers.h" - #include "ED_paint.h" #include "ED_object.h" #include "ED_sculpt.h" @@ -585,9 +583,6 @@ static void sculpt_undo_restore_list(bContext *C, ListBase *lb) else { sculpt_update_object_bounding_box(ob); } - - /* for non-PBVH drawing, need to recreate VBOs */ - GPU_drawobject_free(ob->derivedFinal); } } diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c index 3f3cb8bce4b..fbdf543e5c4 100644 --- a/source/blender/editors/space_api/spacetypes.c +++ b/source/blender/editors/space_api/spacetypes.c @@ -147,9 +147,6 @@ void ED_spacetypes_init(void) type->operatortypes(); } } - - /* register internal render callbacks */ - ED_render_internal_init(); } void ED_spacemacros_init(void) diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c index 8866c6b6c40..b7ba8b5e065 100644 --- a/source/blender/editors/space_buttons/buttons_context.c +++ b/source/blender/editors/space_buttons/buttons_context.c @@ -279,7 +279,7 @@ static int buttons_context_path_modifier(ButsContextPath *path) return 0; } -static int buttons_context_path_material(ButsContextPath *path, bool for_texture, bool new_shading) +static int buttons_context_path_material(ButsContextPath *path) { Object *ob; PointerRNA *ptr = &path->ptr[path->len - 1]; @@ -297,18 +297,6 @@ static int buttons_context_path_material(ButsContextPath *path, bool for_texture ma = give_current_material(ob, ob->actcol); RNA_id_pointer_create(&ma->id, &path->ptr[path->len]); path->len++; - - if (for_texture && give_current_material_texture_node(ma)) - return 1; - - if (!new_shading) { - /* Only try to get mat from node in case of old shading system (see T40331). */ - ma = give_node_material(ma); - if (ma) { - RNA_id_pointer_create(&ma->id, &path->ptr[path->len]); - path->len++; - } - } return 1; } } @@ -441,132 +429,38 @@ static int buttons_context_path_brush(const bContext *C, ButsContextPath *path) static int buttons_context_path_texture(const bContext *C, ButsContextPath *path, ButsContextTexture *ct) { - if (ct) { - /* new shading system */ - PointerRNA *ptr = &path->ptr[path->len - 1]; - ID *id; - - /* if we already have a (pinned) texture, we're done */ - if (RNA_struct_is_a(ptr->type, &RNA_Texture)) - return 1; - - if (!ct->user) - return 0; - - id = ct->user->id; - - if (id) { - if (GS(id->name) == ID_BR) - buttons_context_path_brush(C, path); - else if (GS(id->name) == ID_MA) - buttons_context_path_material(path, false, true); - else if (GS(id->name) == ID_WO) - buttons_context_path_world(path); - else if (GS(id->name) == ID_LA) - buttons_context_path_data(path, OB_LAMP); - else if (GS(id->name) == ID_PA) - buttons_context_path_particle(path); - else if (GS(id->name) == ID_OB) - buttons_context_path_object(path); - else if (GS(id->name) == ID_LS) - buttons_context_path_linestyle(path); - } + PointerRNA *ptr = &path->ptr[path->len - 1]; + ID *id; - if (ct->texture) { - RNA_id_pointer_create(&ct->texture->id, &path->ptr[path->len]); - path->len++; - } + if (!ct) + return 0; + /* if we already have a (pinned) texture, we're done */ + if (RNA_struct_is_a(ptr->type, &RNA_Texture)) return 1; - } - else { - /* old shading system */ - Material *ma; - Lamp *la; - World *wo; - ParticleSystem *psys; - FreestyleLineStyle *ls; - Tex *tex; - PointerRNA *ptr = &path->ptr[path->len - 1]; - - /* if we already have a (pinned) texture, we're done */ - if (RNA_struct_is_a(ptr->type, &RNA_Texture)) { - return 1; - } - /* try world */ - else if ((path->tex_ctx == SB_TEXC_WORLD) && buttons_context_path_world(path)) { - wo = path->ptr[path->len - 1].data; - - if (wo && GS(wo->id.name) == ID_WO) { - tex = give_current_world_texture(wo); - - RNA_id_pointer_create(&tex->id, &path->ptr[path->len]); - path->len++; - return 1; - } - } - /* try particles */ - else if ((path->tex_ctx == SB_TEXC_PARTICLES) && buttons_context_path_particle(path)) { - if (path->ptr[path->len - 1].type == &RNA_ParticleSettings) { - ParticleSettings *part = path->ptr[path->len - 1].data; - - tex = give_current_particle_texture(part); - RNA_id_pointer_create(&tex->id, &path->ptr[path->len]); - path->len++; - return 1; - } - else { - psys = path->ptr[path->len - 1].data; - - if (psys && psys->part && GS(psys->part->id.name) == ID_PA) { - tex = give_current_particle_texture(psys->part); - - RNA_id_pointer_create(&tex->id, &path->ptr[path->len]); - path->len++; - return 1; - } - } - } - /* try material */ - else if ((path->tex_ctx == SB_TEXC_MATERIAL) && buttons_context_path_material(path, true, false)) { - ma = path->ptr[path->len - 1].data; - - if (ma) { - tex = give_current_material_texture(ma); - RNA_id_pointer_create(&tex->id, &path->ptr[path->len]); - path->len++; - return 1; - } - } - /* try lamp */ - else if ((path->tex_ctx == SB_TEXC_LAMP) && buttons_context_path_data(path, OB_LAMP)) { - la = path->ptr[path->len - 1].data; - - if (la) { - tex = give_current_lamp_texture(la); - - RNA_id_pointer_create(&tex->id, &path->ptr[path->len]); - path->len++; - return 1; - } - } - /* try linestyle */ - else if ((path->tex_ctx == SB_TEXC_LINESTYLE) && buttons_context_path_linestyle(path)) { - ls = path->ptr[path->len - 1].data; + if (!ct->user) + return 0; + + id = ct->user->id; - if (ls) { - tex = give_current_linestyle_texture(ls); + if (id) { + if (GS(id->name) == ID_BR) + buttons_context_path_brush(C, path); + else if (GS(id->name) == ID_PA) + buttons_context_path_particle(path); + else if (GS(id->name) == ID_OB) + buttons_context_path_object(path); + else if (GS(id->name) == ID_LS) + buttons_context_path_linestyle(path); + } - RNA_id_pointer_create(&tex->id, &path->ptr[path->len]); - path->len++; - return 1; - } - } + if (ct->texture) { + RNA_id_pointer_create(&ct->texture->id, &path->ptr[path->len]); + path->len++; } - /* no path to a texture possible */ - return 0; + return 1; } #ifdef WITH_FREESTYLE @@ -606,7 +500,6 @@ static int buttons_context_path(const bContext *C, ButsContextPath *path, int ma memset(path, 0, sizeof(*path)); path->flag = flag; - path->tex_ctx = sbuts->texture_context; const bool use_scene_settings = BKE_workspace_use_scene_settings_get(workspace); @@ -679,7 +572,7 @@ static int buttons_context_path(const bContext *C, ButsContextPath *path, int ma found = buttons_context_path_particle(path); break; case BCONTEXT_MATERIAL: - found = buttons_context_path_material(path, false, (sbuts->texuser != NULL)); + found = buttons_context_path_material(path); break; case BCONTEXT_TEXTURE: found = buttons_context_path_texture(C, path, sbuts->texuser); @@ -737,7 +630,7 @@ void buttons_context_compute(const bContext *C, SpaceButs *sbuts) path = sbuts->path; - /* We need to set Scene path now! Else, buttons_texture_context_compute() might not get a valid scene. */ + /* Set scene path. */ buttons_context_path(C, path, BCONTEXT_SCENE, pflag); buttons_texture_context_compute(C, sbuts); @@ -890,13 +783,8 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r ButsContextTexture *ct = sbuts->texuser; if (ct) { - /* new shading system */ CTX_data_pointer_set(result, &ct->texture->id, &RNA_Texture, ct->texture); } - else { - /* old shading system */ - set_pointer_type(path, result, &RNA_Texture); - } return 1; } @@ -920,7 +808,7 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r ButsContextTexture *ct = sbuts->texuser; if (!ct) - return -1; /* old shading system (found but not available) */ + return -1; if (ct->user && ct->user->ptr.data) { ButsTextureUser *user = ct->user; @@ -933,7 +821,7 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r ButsContextTexture *ct = sbuts->texuser; if (!ct) - return -1; /* old shading system (found but not available) */ + return -1; if (ct->user && ct->user->ptr.data) { ButsTextureUser *user = ct->user; @@ -953,21 +841,6 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r return 1; } - else { - /* old shading system */ - PointerRNA *ptr; - - if ((ptr = get_pointer_type(path, &RNA_Material))) { - Material *ma = ptr->data; - - if (ma) { - bNode *node = give_current_material_texture_node(ma); - CTX_data_pointer_set(result, &ma->nodetree->id, &RNA_Node, node); - } - } - - return 1; - } } else if (CTX_data_equals(member, "texture_slot")) { ButsContextTexture *ct = sbuts->texuser; @@ -983,38 +856,6 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r else if (ct) { return 0; /* new shading system */ } - else if ((ptr = get_pointer_type(path, &RNA_Material))) { - Material *ma = ptr->data; - - /* if we have a node material, get slot from material in material node */ - if (ma && ma->use_nodes && ma->nodetree) { - /* if there's an active texture node in the node tree, - * then that texture is in context directly, without a texture slot */ - if (give_current_material_texture_node(ma)) - return 0; - - ma = give_node_material(ma); - if (ma) - CTX_data_pointer_set(result, &ma->id, &RNA_MaterialTextureSlot, ma->mtex[(int)ma->texact]); - else - return 0; - } - else if (ma) { - CTX_data_pointer_set(result, &ma->id, &RNA_MaterialTextureSlot, ma->mtex[(int)ma->texact]); - } - } - else if ((ptr = get_pointer_type(path, &RNA_Lamp))) { - Lamp *la = ptr->data; - - if (la) - CTX_data_pointer_set(result, &la->id, &RNA_LampTextureSlot, la->mtex[(int)la->texact]); - } - else if ((ptr = get_pointer_type(path, &RNA_World))) { - World *wo = ptr->data; - - if (wo) - CTX_data_pointer_set(result, &wo->id, &RNA_WorldTextureSlot, wo->mtex[(int)wo->texact]); - } else if ((ptr = get_pointer_type(path, &RNA_FreestyleLineStyle))) { FreestyleLineStyle *ls = ptr->data; diff --git a/source/blender/editors/space_buttons/buttons_intern.h b/source/blender/editors/space_buttons/buttons_intern.h index e6d19caad47..84c935dd737 100644 --- a/source/blender/editors/space_buttons/buttons_intern.h +++ b/source/blender/editors/space_buttons/buttons_intern.h @@ -64,7 +64,6 @@ typedef struct ButsContextPath { PointerRNA ptr[8]; int len; int flag; - int tex_ctx; int collection_ctx; } ButsContextPath; diff --git a/source/blender/editors/space_buttons/buttons_texture.c b/source/blender/editors/space_buttons/buttons_texture.c index 809480baece..df06eee3fd5 100644 --- a/source/blender/editors/space_buttons/buttons_texture.c +++ b/source/blender/editors/space_buttons/buttons_texture.c @@ -41,8 +41,6 @@ #include "DNA_brush_types.h" #include "DNA_ID.h" -#include "DNA_lamp_types.h" -#include "DNA_material_types.h" #include "DNA_node_types.h" #include "DNA_object_types.h" #include "DNA_object_force_types.h" @@ -50,13 +48,11 @@ #include "DNA_scene_types.h" #include "DNA_screen_types.h" #include "DNA_space_types.h" -#include "DNA_world_types.h" #include "DNA_linestyle_types.h" #include "BKE_context.h" #include "BKE_layer.h" #include "BKE_linestyle.h" -#include "BKE_material.h" #include "BKE_modifier.h" #include "BKE_node.h" #include "BKE_paint.h" @@ -79,172 +75,6 @@ #include "buttons_intern.h" // own include -/****************** "Old Shading" Texture Context ****************/ - -bool ED_texture_context_check_world(const bContext *C) -{ - Scene *scene = CTX_data_scene(C); - return (scene && scene->world); -} - -bool ED_texture_context_check_material(const bContext *C) -{ - Object *ob = CTX_data_active_object(C); - return (ob && (ob->totcol != 0)); -} - -bool ED_texture_context_check_lamp(const bContext *C) -{ - Object *ob = CTX_data_active_object(C); - return (ob && (ob->type == OB_LAMP)); -} - -bool ED_texture_context_check_particles(const bContext *C) -{ - Object *ob = CTX_data_active_object(C); - return (ob && ob->particlesystem.first); -} - -bool ED_texture_context_check_linestyle(const bContext *C) -{ -#ifdef WITH_FREESTYLE - Scene *scene = CTX_data_scene(C); - ViewLayer *active_view_layer; - FreestyleConfig *config; - FreestyleLineSet *lineset; - FreestyleLineStyle *linestyle; - - if (scene && (scene->r.mode & R_EDGE_FRS)) { - active_view_layer = BLI_findlink(&scene->view_layers, scene->active_view_layer); - config = &active_view_layer->freestyle_config; - if (config->mode == FREESTYLE_CONTROL_EDITOR_MODE) { - lineset = BKE_freestyle_lineset_get_active(config); - if (lineset) { - linestyle = lineset->linestyle; - return linestyle && (linestyle->flag & LS_TEXTURE); - } - } - } -#else - (void)C; -#endif - return false; -} - -static void texture_context_check_modifier_foreach(void *userData, Object *UNUSED(ob), ModifierData *UNUSED(md), - const char *UNUSED(propname)) -{ - *((bool *)userData) = true; -} - -bool ED_texture_context_check_others(const bContext *C) -{ - /* We cannot rely on sbuts->texuser here, as it is NULL when in "old" tex handling, non-OTHERS tex context. */ - Object *ob = CTX_data_active_object(C); - - /* object */ - if (ob) { - /* Tex force field. */ - if (ob->pd && ob->pd->forcefield == PFIELD_TEXTURE) { - return true; - } - - /* modifiers */ - { - bool check = false; - modifiers_foreachTexLink(ob, texture_context_check_modifier_foreach, &check); - if (check) { - return true; - } - } - } - - /* brush */ - if (BKE_paint_brush(BKE_paint_get_active_from_context(C))) { - return true; - } - - return false; -} - -static void set_texture_context(const bContext *C, SpaceButs *sbuts) -{ - Scene *scene = CTX_data_scene(C); - - if (BKE_scene_use_new_shading_nodes(scene)) { - return; /* No texture context in new shading mode */ - } - - { - bool valid_world = ED_texture_context_check_world(C); - bool valid_material = ED_texture_context_check_material(C); - bool valid_lamp = ED_texture_context_check_lamp(C); - bool valid_particles = ED_texture_context_check_particles(C); - bool valid_linestyle = ED_texture_context_check_linestyle(C); - bool valid_others = ED_texture_context_check_others(C); - - /* this is similar to direct user action, no need to keep "better" ctxt in _prev */ - if ((sbuts->mainb == BCONTEXT_WORLD) && valid_world) { - sbuts->texture_context = sbuts->texture_context_prev = SB_TEXC_WORLD; - } - else if ((sbuts->mainb == BCONTEXT_MATERIAL) && valid_material) { - sbuts->texture_context = sbuts->texture_context_prev = SB_TEXC_MATERIAL; - } - else if ((sbuts->mainb == BCONTEXT_DATA) && valid_lamp) { - sbuts->texture_context = sbuts->texture_context_prev = SB_TEXC_LAMP; - } - else if ((sbuts->mainb == BCONTEXT_PARTICLE) && valid_particles) { - sbuts->texture_context = sbuts->texture_context_prev = SB_TEXC_PARTICLES; - } - else if ((sbuts->mainb == BCONTEXT_VIEW_LAYER) && valid_linestyle) { - sbuts->texture_context = sbuts->texture_context_prev = SB_TEXC_LINESTYLE; - } - else if ((ELEM(sbuts->mainb, BCONTEXT_MODIFIER, BCONTEXT_PHYSICS)) && valid_others) { - sbuts->texture_context = sbuts->texture_context_prev = SB_TEXC_OTHER; - } - /* Else, try to revive a previous "better" ctxt... */ - else if ((sbuts->texture_context_prev != sbuts->texture_context) && - (((sbuts->texture_context_prev == SB_TEXC_WORLD) && valid_world) || - ((sbuts->texture_context_prev == SB_TEXC_MATERIAL) && valid_material) || - ((sbuts->texture_context_prev == SB_TEXC_LAMP) && valid_lamp) || - ((sbuts->texture_context_prev == SB_TEXC_PARTICLES) && valid_particles) || - ((sbuts->texture_context_prev == SB_TEXC_LINESTYLE) && valid_linestyle) || - ((sbuts->texture_context_prev == SB_TEXC_OTHER) && valid_others))) - { - sbuts->texture_context = sbuts->texture_context_prev; - } - /* Else, just be sure that current context is valid! */ - else if (((sbuts->texture_context == SB_TEXC_WORLD) && !valid_world) || - ((sbuts->texture_context == SB_TEXC_MATERIAL) && !valid_material) || - ((sbuts->texture_context == SB_TEXC_LAMP) && !valid_lamp) || - ((sbuts->texture_context == SB_TEXC_PARTICLES) && !valid_particles) || - ((sbuts->texture_context == SB_TEXC_LINESTYLE) && !valid_linestyle) || - ((sbuts->texture_context == SB_TEXC_OTHER) && !valid_others)) - { - /* this is default fallback, do keep "better" ctxt in _prev */ - sbuts->texture_context_prev = sbuts->texture_context; - if (valid_material) { - sbuts->texture_context = SB_TEXC_MATERIAL; - } - else if (valid_lamp) { - sbuts->texture_context = SB_TEXC_LAMP; - } - else if (valid_particles) { - sbuts->texture_context = SB_TEXC_PARTICLES; - } - else if (valid_linestyle) { - sbuts->texture_context = SB_TEXC_LINESTYLE; - } - else if (valid_world) { - sbuts->texture_context = SB_TEXC_WORLD; - } - else if (valid_others) { - sbuts->texture_context = SB_TEXC_OTHER; - } - } - } -} - /************************* Texture User **************************/ static void buttons_texture_user_property_add(ListBase *users, ID *id, @@ -322,9 +152,6 @@ static void buttons_texture_users_from_context(ListBase *users, const bContext * { Scene *scene = NULL; Object *ob = NULL; - Material *ma = NULL; - Lamp *la = NULL; - World *wrld = NULL; WorkSpace *workspace = NULL; FreestyleLineStyle *linestyle = NULL; Brush *brush = NULL; @@ -337,12 +164,6 @@ static void buttons_texture_users_from_context(ListBase *users, const bContext * scene = (Scene *)pinid; else if (GS(pinid->name) == ID_OB) ob = (Object *)pinid; - else if (GS(pinid->name) == ID_LA) - la = (Lamp *)pinid; - else if (GS(pinid->name) == ID_WO) - wrld = (World *)pinid; - else if (GS(pinid->name) == ID_MA) - ma = (Material *)pinid; else if (GS(pinid->name) == ID_BR) brush = (Brush *)pinid; else if (GS(pinid->name) == ID_LS) @@ -360,7 +181,6 @@ static void buttons_texture_users_from_context(ListBase *users, const bContext * brush = BKE_paint_brush(BKE_paint_get_active_from_context(C)); if (workspace == NULL) { - wrld = scene->world; linestyle = BKE_linestyle_active_from_scene(scene); workspace = CTX_wm_workspace(C); } @@ -369,20 +189,9 @@ static void buttons_texture_users_from_context(ListBase *users, const bContext * ob = OBACT(view_layer); } - if (ob && ob->type == OB_LAMP && !la) - la = ob->data; - if (ob && !ma) - ma = give_current_material(ob, ob->actcol); - /* fill users */ BLI_listbase_clear(users); - if (ma && !limited_mode) - buttons_texture_users_find_nodetree(users, &ma->id, ma->nodetree, N_("Material")); - if (la && !limited_mode) - buttons_texture_users_find_nodetree(users, &la->id, la->nodetree, N_("Lamp")); - if (wrld && !limited_mode) - buttons_texture_users_find_nodetree(users, &wrld->id, wrld->nodetree, N_("World")); if (linestyle && !limited_mode) buttons_texture_users_find_nodetree(users, &linestyle->id, linestyle->nodetree, N_("Line Style")); @@ -451,21 +260,8 @@ void buttons_texture_context_compute(const bContext *C, SpaceButs *sbuts) /* gather available texture users in context. runs on every draw of * properties editor, before the buttons are created. */ ButsContextTexture *ct = sbuts->texuser; - Scene *scene = CTX_data_scene(C); ID *pinid = sbuts->pinid; - set_texture_context(C, sbuts); - - if (!((sbuts->texture_context == SB_TEXC_OTHER) || BKE_scene_use_new_shading_nodes(scene))) { - if (ct) { - BLI_freelistN(&ct->users); - MEM_freeN(ct); - sbuts->texuser = NULL; - } - - return; - } - if (!ct) { ct = MEM_callocN(sizeof(ButsContextTexture), "ButsContextTexture"); sbuts->texuser = ct; @@ -699,4 +495,3 @@ void uiTemplateTextureShow(uiLayout *layout, bContext *C, PointerRNA *ptr, Prope UI_but_func_set(but, template_texture_show, user->ptr.data, user->prop); } } - diff --git a/source/blender/editors/space_image/image_edit.c b/source/blender/editors/space_image/image_edit.c index c719af9e0e2..c598e486a7e 100644 --- a/source/blender/editors/space_image/image_edit.c +++ b/source/blender/editors/space_image/image_edit.c @@ -63,11 +63,8 @@ Image *ED_space_image(SpaceImage *sima) } /* called to assign images to UV faces */ -void ED_space_image_set(SpaceImage *sima, Scene *scene, Object *obedit, Image *ima) +void ED_space_image_set(SpaceImage *sima, Scene *UNUSED(scene), Object *obedit, Image *ima) { - /* context may be NULL, so use global */ - ED_uvedit_assign_image(G.main, scene, obedit, ima, sima->image); - /* change the space ima after because uvedit_face_visible_test uses the space ima * to check if the face is displayed in UV-localview */ sima->image = ima; diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index 9162b8b76a9..a905e61dd88 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -73,7 +73,6 @@ #include "DEG_depsgraph.h" #include "GPU_draw.h" -#include "GPU_buffers.h" #include "IMB_colormanagement.h" #include "IMB_imbuf.h" @@ -2445,7 +2444,6 @@ static int image_new_exec(bContext *C, wmOperator *op) bScreen *sc; Object *ob = CTX_data_active_object(C); - GPU_drawobject_free(ob->derivedFinal); if (scene->toolsettings->imapaint.canvas) id_us_min(&scene->toolsettings->imapaint.canvas->id); scene->toolsettings->imapaint.canvas = ima; diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index 54037059cc3..38a850568fd 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -410,7 +410,6 @@ static void image_refresh(const bContext *C, ScrArea *sa) { Scene *scene = CTX_data_scene(C); SpaceImage *sima = sa->spacedata.first; - Object *obedit = CTX_data_edit_object(C); Image *ima; ima = ED_space_image(sima); @@ -426,32 +425,6 @@ static void image_refresh(const bContext *C, ScrArea *sa) } } } - else if (ima && (ima->source == IMA_SRC_VIEWER || sima->pin)) { - /* pass */ - } - else if (obedit && obedit->type == OB_MESH) { - Mesh *me = (Mesh *)obedit->data; - struct BMEditMesh *em = me->edit_btmesh; - bool sloppy = true; /* partially selected face is ok */ - bool selected = !(scene->toolsettings->uv_flag & UV_SYNC_SELECTION); /* only selected active face? */ - - if (BKE_scene_use_new_shading_nodes(scene)) { - /* new shading system does not alter image */ - } - else { - /* old shading system, we set texface */ - if (em && EDBM_uv_check(em)) { - BMFace *efa = BM_mesh_active_face_get(em->bm, sloppy, selected); - - if (efa) { - /* don't need to check for pin here, see above */ - Image *image = BKE_object_material_edit_image_get(obedit, efa->mat_nr); - - sima->image = image; - } - } - } - } } static void image_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn, Scene *scene, diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 448286c7c3d..ca6ae5955a9 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -679,21 +679,6 @@ static void node_buts_image_user(uiLayout *layout, bContext *C, PointerRNA *ptr, } } -static void node_shader_buts_material(uiLayout *layout, bContext *C, PointerRNA *ptr) -{ - bNode *node = ptr->data; - uiLayout *col; - - uiTemplateID(layout, C, ptr, "material", "MATERIAL_OT_new", NULL, NULL, UI_TEMPLATE_ID_FILTER_ALL); - - if (!node->id) return; - - col = uiLayoutColumn(layout, false); - uiItemR(col, ptr, "use_diffuse", 0, NULL, ICON_NONE); - uiItemR(col, ptr, "use_specular", 0, NULL, ICON_NONE); - uiItemR(col, ptr, "invert_normal", 0, NULL, ICON_NONE); -} - static void node_shader_buts_mapping(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) { uiLayout *row, *col, *sub; @@ -741,30 +726,6 @@ static void node_shader_buts_vect_transform(uiLayout *layout, bContext *UNUSED(C uiItemR(layout, ptr, "convert_to", 0, "", ICON_NONE); } -static void node_shader_buts_geometry(uiLayout *layout, bContext *C, PointerRNA *ptr) -{ - PointerRNA obptr = CTX_data_pointer_get(C, "active_object"); - uiLayout *col; - - col = uiLayoutColumn(layout, false); - - if (obptr.data && RNA_enum_get(&obptr, "type") == OB_MESH) { - PointerRNA dataptr = RNA_pointer_get(&obptr, "data"); - - uiItemPointerR(col, ptr, "uv_layer", &dataptr, "uv_layers", "", ICON_NONE); - uiItemPointerR(col, ptr, "color_layer", &dataptr, "vertex_colors", "", ICON_NONE); - } - else { - uiItemR(col, ptr, "uv_layer", 0, IFACE_("UV"), ICON_NONE); - uiItemR(col, ptr, "color_layer", 0, IFACE_("VCol"), ICON_NONE); - } -} - -static void node_shader_buts_lamp(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) -{ - uiItemR(layout, ptr, "lamp_object", 0, IFACE_("Lamp Object"), ICON_NONE); -} - static void node_shader_buts_attribute(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) { uiItemR(layout, ptr, "attribute_name", 0, IFACE_("Name"), ICON_NONE); @@ -1108,13 +1069,6 @@ static void node_shader_buts_bevel(uiLayout *layout, bContext *UNUSED(C), Pointe static void node_shader_set_butfunc(bNodeType *ntype) { switch (ntype->type) { - case SH_NODE_MATERIAL: - case SH_NODE_MATERIAL_EXT: - ntype->draw_buttons = node_shader_buts_material; - break; - case SH_NODE_TEXTURE: - ntype->draw_buttons = node_buts_texture; - break; case SH_NODE_NORMAL: ntype->draw_buttons = node_buts_normal; break; @@ -1148,12 +1102,6 @@ static void node_shader_set_butfunc(bNodeType *ntype) case SH_NODE_VECT_TRANSFORM: ntype->draw_buttons = node_shader_buts_vect_transform; break; - case SH_NODE_GEOMETRY: - ntype->draw_buttons = node_shader_buts_geometry; - break; - case SH_NODE_LAMP: - ntype->draw_buttons = node_shader_buts_lamp; - break; case SH_NODE_ATTRIBUTE: ntype->draw_buttons = node_shader_buts_attribute; break; diff --git a/source/blender/editors/space_node/node_add.c b/source/blender/editors/space_node/node_add.c index ec35727d176..c200c5a7612 100644 --- a/source/blender/editors/space_node/node_add.c +++ b/source/blender/editors/space_node/node_add.c @@ -316,10 +316,7 @@ static int node_add_file_exec(bContext *C, wmOperator *op) switch (snode->nodetree->type) { case NTREE_SHADER: - if (BKE_scene_use_new_shading_nodes(CTX_data_scene(C))) - type = SH_NODE_TEX_IMAGE; - else - type = SH_NODE_TEXTURE; + type = SH_NODE_TEX_IMAGE; break; case NTREE_TEXTURE: type = TEX_NODE_IMAGE; @@ -340,14 +337,7 @@ static int node_add_file_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - if (type == SH_NODE_TEXTURE) { - Tex *tex = BKE_texture_add(CTX_data_main(C), DATA_(ima->id.name)); - tex->ima = ima; - node->id = (ID *)tex; - WM_event_add_notifier(C, NC_TEXTURE | NA_ADDED, node->id); - } - else - node->id = (ID *)ima; + node->id = (ID *)ima; /* When adding new image file via drag-drop we need to load imbuf in order * to get proper image source. diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c index c82c56ea648..ae810b0fde0 100644 --- a/source/blender/editors/space_node/node_draw.c +++ b/source/blender/editors/space_node/node_draw.c @@ -879,10 +879,6 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN char showname[128]; /* 128 used below */ View2D *v2d = &ar->v2d; - /* XXX hack: copy values from linked ID data where displayed as sockets */ - if (node->block) - nodeSynchronizeID(node, false); - /* skip if out of view */ if (BLI_rctf_isect(&node->totr, &v2d->cur, NULL) == false) { UI_block_end(C, node->block); diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index b6680d8560f..340184845b8 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -383,7 +383,6 @@ bool ED_node_is_texture(struct SpaceNode *snode) /* called from shading buttons or header */ void ED_node_shader_default(const bContext *C, ID *id) { - Scene *scene = CTX_data_scene(C); bNode *in, *out; bNodeSocket *fromsock, *tosock, *sock; bNodeTree *ntree; @@ -398,18 +397,8 @@ void ED_node_shader_default(const bContext *C, ID *id) Material *ma = (Material *)id; ma->nodetree = ntree; - if (BKE_scene_uses_blender_eevee(scene)) { - output_type = SH_NODE_OUTPUT_MATERIAL; - shader_type = SH_NODE_BSDF_PRINCIPLED; - } - else if (BKE_scene_use_new_shading_nodes(scene)) { - output_type = SH_NODE_OUTPUT_MATERIAL; - shader_type = SH_NODE_BSDF_DIFFUSE; - } - else { - output_type = SH_NODE_OUTPUT; - shader_type = SH_NODE_MATERIAL; - } + output_type = SH_NODE_OUTPUT_MATERIAL; + shader_type = SH_NODE_BSDF_PRINCIPLED; copy_v3_v3(color, &ma->r); strength = 0.0f; @@ -460,18 +449,16 @@ void ED_node_shader_default(const bContext *C, ID *id) nodeAddLink(ntree, in, fromsock, out, tosock); /* default values */ - if (BKE_scene_use_new_shading_nodes(scene)) { - PointerRNA sockptr; - sock = in->inputs.first; - RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &sockptr); - - RNA_float_set_array(&sockptr, "default_value", color); + PointerRNA sockptr; + sock = in->inputs.first; + RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &sockptr); + + RNA_float_set_array(&sockptr, "default_value", color); - if (strength != 0.0f) { - sock = in->inputs.last; - RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &sockptr); - RNA_float_set(&sockptr, "default_value", strength); - } + if (strength != 0.0f) { + sock = in->inputs.last; + RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &sockptr); + RNA_float_set(&sockptr, "default_value", strength); } ntreeUpdateTree(CTX_data_main(C), ntree); @@ -550,12 +537,6 @@ void snode_set_context(const bContext *C) bNodeTree *ntree = snode->nodetree; ID *id = snode->id, *from = snode->from; - /* we use this to signal warnings, when node shaders are drawn in wrong render engine */ - if (BKE_scene_use_new_shading_nodes(CTX_data_scene(C))) - snode->flag |= SNODE_NEW_SHADERS; - else - snode->flag &= ~SNODE_NEW_SHADERS; - /* check the tree type */ if (!treetype || (treetype->poll && !treetype->poll(C, treetype))) @@ -643,7 +624,7 @@ void ED_node_set_active(Main *bmain, bNodeTree *ntree, bNode *node) if (node->id && ELEM(GS(node->id->name), ID_MA, ID_LA, ID_WO)) nodeClearActiveID(ntree, ID_TE); - if (ELEM(node->type, SH_NODE_OUTPUT, SH_NODE_OUTPUT_MATERIAL, + if (ELEM(node->type, SH_NODE_OUTPUT_MATERIAL, SH_NODE_OUTPUT_WORLD, SH_NODE_OUTPUT_LAMP, SH_NODE_OUTPUT_LINESTYLE)) { bNode *tnode; @@ -1321,40 +1302,6 @@ void NODE_OT_read_viewlayers(wmOperatorType *ot) ot->flag = 0; } -static int node_read_fullsamplelayers_exec(bContext *C, wmOperator *UNUSED(op)) -{ - Main *bmain = CTX_data_main(C); - SpaceNode *snode = CTX_wm_space_node(C); - Scene *curscene = CTX_data_scene(C); - Render *re = RE_NewSceneRender(curscene); - - WM_cursor_wait(1); - RE_MergeFullSample(re, bmain, curscene, snode->nodetree); - WM_cursor_wait(0); - - /* note we are careful to send the right notifier, as otherwise the - * compositor would reexecute and overwrite the full sample result */ - WM_event_add_notifier(C, NC_SCENE | ND_COMPO_RESULT, NULL); - - return OPERATOR_FINISHED; -} - - -void NODE_OT_read_fullsamplelayers(wmOperatorType *ot) -{ - - ot->name = "Read Full Sample Layers"; - ot->idname = "NODE_OT_read_fullsamplelayers"; - ot->description = "Read all render layers of current scene, in full sample"; - - ot->exec = node_read_fullsamplelayers_exec; - - ot->poll = composite_node_active; - - /* flags */ - ot->flag = 0; -} - int node_render_changed_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *sce = CTX_data_scene(C); diff --git a/source/blender/editors/space_node/node_ops.c b/source/blender/editors/space_node/node_ops.c index 1859785173c..c9c29212f02 100644 --- a/source/blender/editors/space_node/node_ops.c +++ b/source/blender/editors/space_node/node_ops.c @@ -95,7 +95,6 @@ void node_operatortypes(void) WM_operatortype_append(NODE_OT_insert_offset); WM_operatortype_append(NODE_OT_read_viewlayers); - WM_operatortype_append(NODE_OT_read_fullsamplelayers); WM_operatortype_append(NODE_OT_render_changed); WM_operatortype_append(NODE_OT_backimage_move); @@ -336,7 +335,6 @@ void node_keymap(struct wmKeyConfig *keyconf) RNA_boolean_set(kmi->ptr, "exit", true); WM_keymap_add_item(keymap, "NODE_OT_read_viewlayers", RKEY, KM_PRESS, KM_CTRL, 0); - WM_keymap_add_item(keymap, "NODE_OT_read_fullsamplelayers", RKEY, KM_PRESS, KM_SHIFT, 0); WM_keymap_add_item(keymap, "NODE_OT_render_changed", ZKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "NODE_OT_clipboard_copy", CKEY, KM_PRESS, KM_CTRL, 0); diff --git a/source/blender/editors/space_node/node_templates.c b/source/blender/editors/space_node/node_templates.c index 173c919e38c..ed64cb6a6e1 100644 --- a/source/blender/editors/space_node/node_templates.c +++ b/source/blender/editors/space_node/node_templates.c @@ -455,10 +455,7 @@ static void ui_node_menu_column(NodeLinkArg *arg, int nclass, const char *cname) int compatibility = 0; if (ntree->type == NTREE_SHADER) { - if (BKE_scene_use_new_shading_nodes(arg->scene)) - compatibility = NODE_NEW_SHADING; - else - compatibility = NODE_OLD_SHADING; + compatibility = NODE_NEW_SHADING; } /* generate array of node types sorted by UI name */ diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c index 6fc5ac62949..a6a178b570d 100644 --- a/source/blender/editors/space_node/space_node.c +++ b/source/blender/editors/space_node/space_node.c @@ -382,13 +382,13 @@ static void node_init(struct wmWindowManager *UNUSED(wm), ScrArea *UNUSED(sa)) } -static void node_area_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn, Scene *scene, +static void node_area_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn, Scene *UNUSED(scene), WorkSpace *UNUSED(workspace)) { /* note, ED_area_tag_refresh will re-execute compositor */ SpaceNode *snode = sa->spacedata.first; /* shaderfrom is only used for new shading nodes, otherwise all shaders are from objects */ - short shader_type = BKE_scene_use_new_shading_nodes(scene) ? snode->shaderfrom : SNODE_SHADER_OBJECT; + short shader_type = snode->shaderfrom; /* preview renders */ switch (wmn->category) { diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c index 9ddaf6d7642..73f450e9392 100644 --- a/source/blender/editors/space_outliner/outliner_select.c +++ b/source/blender/editors/space_outliner/outliner_select.c @@ -253,93 +253,6 @@ static eOLDrawState tree_element_active_material( return OL_DRAWSEL_NONE; } -static eOLDrawState tree_element_active_texture( - bContext *C, Scene *scene, ViewLayer *view_layer, SpaceOops *UNUSED(soops), - TreeElement *te, const eOLSetState set) -{ - TreeElement *tep; - TreeStoreElem /* *tselem,*/ *tselemp; - Object *ob = OBACT(view_layer); - SpaceButs *sbuts = NULL; - - if (ob == NULL) { - /* no active object */ - return OL_DRAWSEL_NONE; - } - - /*tselem = TREESTORE(te);*/ /*UNUSED*/ - - /* find buttons region (note, this is undefined really still, needs recode in blender) */ - /* XXX removed finding sbuts */ - - /* where is texture linked to? */ - tep = te->parent; - tselemp = TREESTORE(tep); - - if (tep->idcode == ID_WO) { - World *wrld = (World *)tselemp->id; - - if (set != OL_SETSEL_NONE) { - if (sbuts) { - // XXX sbuts->tabo = TAB_SHADING_TEX; // hack from header_buttonswin.c - // XXX sbuts->texfrom = 1; - } -// XXX extern_set_butspace(F6KEY, 0); // force shading buttons texture - wrld->texact = te->index; - } - else if (tselemp->id == (ID *)(scene->world)) { - if (wrld->texact == te->index) { - return OL_DRAWSEL_NORMAL; - } - } - } - else if (tep->idcode == ID_LA) { - Lamp *la = (Lamp *)tselemp->id; - if (set != OL_SETSEL_NONE) { - if (sbuts) { - // XXX sbuts->tabo = TAB_SHADING_TEX; // hack from header_buttonswin.c - // XXX sbuts->texfrom = 2; - } -// XXX extern_set_butspace(F6KEY, 0); // force shading buttons texture - la->texact = te->index; - } - else { - if (tselemp->id == ob->data) { - if (la->texact == te->index) { - return OL_DRAWSEL_NORMAL; - } - } - } - } - else if (tep->idcode == ID_MA) { - Material *ma = (Material *)tselemp->id; - if (set != OL_SETSEL_NONE) { - if (sbuts) { - //sbuts->tabo = TAB_SHADING_TEX; // hack from header_buttonswin.c - // XXX sbuts->texfrom = 0; - } -// XXX extern_set_butspace(F6KEY, 0); // force shading buttons texture - ma->texact = (char)te->index; - - /* also set active material */ - ob->actcol = tep->index + 1; - } - else if (tep->flag & TE_ACTIVE) { // this is active material - if (ma->texact == te->index) { - return OL_DRAWSEL_NORMAL; - } - } - } - - if (set != OL_SETSEL_NONE) { - WM_event_add_notifier(C, NC_TEXTURE, NULL); - } - - /* no active object */ - return OL_DRAWSEL_NONE; -} - - static eOLDrawState tree_element_active_lamp( bContext *UNUSED(C), Scene *UNUSED(scene), ViewLayer *view_layer, SpaceOops *soops, TreeElement *te, const eOLSetState set) @@ -827,8 +740,6 @@ eOLDrawState tree_element_active(bContext *C, Scene *scene, ViewLayer *view_laye return tree_element_active_world(C, scene, view_layer, soops, te, set); case ID_LA: return tree_element_active_lamp(C, scene, view_layer, soops, te, set); - case ID_TE: - return tree_element_active_texture(C, scene, view_layer, soops, te, set); case ID_TXT: return tree_element_active_text(C, scene, view_layer, soops, te, set); case ID_CA: diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c index 735e2b5a37a..89c0712c217 100644 --- a/source/blender/editors/space_outliner/outliner_tools.c +++ b/source/blender/editors/space_outliner/outliner_tools.c @@ -196,19 +196,7 @@ static void unlink_texture_cb( MTex **mtex = NULL; int a; - if (GS(tsep->id->name) == ID_MA) { - Material *ma = (Material *)tsep->id; - mtex = ma->mtex; - } - else if (GS(tsep->id->name) == ID_LA) { - Lamp *la = (Lamp *)tsep->id; - mtex = la->mtex; - } - else if (GS(tsep->id->name) == ID_WO) { - World *wrld = (World *)tsep->id; - mtex = wrld->mtex; - } - else if (GS(tsep->id->name) == ID_LS) { + if (GS(tsep->id->name) == ID_LS) { FreestyleLineStyle *ls = (FreestyleLineStyle *)tsep->id; mtex = ls->mtex; } diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c index d418c571a8d..cd171bbc8ce 100644 --- a/source/blender/editors/space_outliner/outliner_tree.c +++ b/source/blender/editors/space_outliner/outliner_tree.c @@ -408,11 +408,6 @@ static void outliner_add_scene_contents(SpaceOops *soops, ListBase *lb, Scene *s outliner_add_element(soops, lb, sce, te, TSE_ANIM_DATA, 0); outliner_add_element(soops, lb, sce->gpd, te, 0, 0); - -#ifdef WITH_FREESTYLE - if (STREQ(sce->view_render->engine_id, RE_engine_id_BLENDER_RENDER) && (sce->r.mode & R_EDGE_FRS)) - outliner_add_line_styles(soops, lb, sce, te); -#endif } TreeTraversalAction outliner_find_selected_objects(TreeElement *te, void *customdata) @@ -750,14 +745,9 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor case ID_MA: { Material *ma = (Material *)id; - int a; if (outliner_animdata_test(ma->adt)) outliner_add_element(soops, &te->subtree, ma, te, TSE_ANIM_DATA, 0); - - for (a = 0; a < MAX_MTEX; a++) { - if (ma->mtex[a]) outliner_add_element(soops, &te->subtree, ma->mtex[a]->tex, te, 0, a); - } break; } case ID_TE: @@ -791,14 +781,9 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor case ID_LA: { Lamp *la = (Lamp *)id; - int a; if (outliner_animdata_test(la->adt)) outliner_add_element(soops, &te->subtree, la, te, TSE_ANIM_DATA, 0); - - for (a = 0; a < MAX_MTEX; a++) { - if (la->mtex[a]) outliner_add_element(soops, &te->subtree, la->mtex[a]->tex, te, 0, a); - } break; } case ID_SPK: @@ -820,14 +805,9 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor case ID_WO: { World *wrld = (World *)id; - int a; if (outliner_animdata_test(wrld->adt)) outliner_add_element(soops, &te->subtree, wrld, te, TSE_ANIM_DATA, 0); - - for (a = 0; a < MAX_MTEX; a++) { - if (wrld->mtex[a]) outliner_add_element(soops, &te->subtree, wrld->mtex[a]->tex, te, 0, a); - } break; } case ID_KE: diff --git a/source/blender/editors/space_view3d/CMakeLists.txt b/source/blender/editors/space_view3d/CMakeLists.txt index d027729c7a7..f8e38587117 100644 --- a/source/blender/editors/space_view3d/CMakeLists.txt +++ b/source/blender/editors/space_view3d/CMakeLists.txt @@ -43,11 +43,7 @@ set(INC_SYS ) set(SRC - drawanimviz.c - drawarmature.c - drawmesh.c drawobject.c - drawsimdebug.c drawvolume.c space_view3d.c view3d_buttons.c diff --git a/source/blender/editors/space_view3d/drawanimviz.c b/source/blender/editors/space_view3d/drawanimviz.c deleted file mode 100644 index 9fa85b55362..00000000000 --- a/source/blender/editors/space_view3d/drawanimviz.c +++ /dev/null @@ -1,438 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2009 by the Blender Foundation. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): Joshua Leung - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/editors/space_view3d/drawanimviz.c - * \ingroup spview3d - */ - - -#include <stdlib.h> -#include <string.h> -#include <math.h> - -#include "BLI_sys_types.h" - -#include "DNA_anim_types.h" -#include "DNA_armature_types.h" -#include "DNA_scene_types.h" -#include "DNA_screen_types.h" -#include "DNA_view3d_types.h" -#include "DNA_object_types.h" - -#include "BLI_math.h" -#include "BLI_dlrbTree.h" - -#include "BKE_animsys.h" -#include "BKE_action.h" - -#include "GPU_immediate.h" -#include "GPU_matrix.h" - -#include "ED_keyframes_draw.h" - - -#include "UI_resources.h" - -#include "view3d_intern.h" - -/* ************************************ Motion Paths ************************************* */ - -/* TODO: - * - options to draw paths with lines - * - include support for editing the path verts */ - -/* Set up drawing environment for drawing motion paths */ -void draw_motion_paths_init(View3D *v3d, ARegion *ar) -{ - RegionView3D *rv3d = ar->regiondata; - - if (v3d->zbuf) glDisable(GL_DEPTH_TEST); - - gpuPushMatrix(); - gpuLoadMatrix(rv3d->viewmat); -} - -/* set color - * - more intense for active/selected bones, less intense for unselected bones - * - black for before current frame, green for current frame, blue for after current frame - * - intensity decreases as distance from current frame increases - * - * If the user select custom color, the color is replaced for the color selected in UI panel - * - 75% Darker color is used for previous frames - * - 50% Darker color for current frame - * - User selected color for next frames - */ -static void set_motion_path_color(Scene *scene, bMotionPath *mpath, int i, short sel, int sfra, int efra, - float prev_color[3], float frame_color[3], float next_color[3], unsigned color) -{ - int frame = sfra + i; - int blend_base = (abs(frame - CFRA) == 1) ? TH_CFRAME : TH_BACK; /* "bleed" cframe color to ease color blending */ - unsigned char ubcolor[3]; - -#define SET_INTENSITY(A, B, C, min, max) (((1.0f - ((C - B) / (C - A))) * (max - min)) + min) - float intensity; /* how faint */ - - if (frame < CFRA) { - if (mpath->flag & MOTIONPATH_FLAG_CUSTOM) { - /* Custom color: previous frames color is darker than current frame */ - rgb_float_to_uchar(ubcolor, prev_color); - } - else { - /* black - before cfra */ - if (sel) { - /* intensity = 0.5f; */ - intensity = SET_INTENSITY(sfra, i, CFRA, 0.25f, 0.75f); - } - else { - /* intensity = 0.8f; */ - intensity = SET_INTENSITY(sfra, i, CFRA, 0.68f, 0.92f); - } - - UI_GetThemeColorBlend3ubv(TH_WIRE, blend_base, intensity, ubcolor); - } - } - else if (frame > CFRA) { - if (mpath->flag & MOTIONPATH_FLAG_CUSTOM) { - /* Custom color: next frames color is equal to user selected color */ - rgb_float_to_uchar(ubcolor, next_color); - } - else { - /* blue - after cfra */ - if (sel) { - /* intensity = 0.5f; */ - intensity = SET_INTENSITY(CFRA, i, efra, 0.25f, 0.75f); - } - else { - /* intensity = 0.8f; */ - intensity = SET_INTENSITY(CFRA, i, efra, 0.68f, 0.92f); - } - - UI_GetThemeColorBlend3ubv(TH_BONE_POSE, blend_base, intensity, ubcolor); - } - } - else { - if (mpath->flag & MOTIONPATH_FLAG_CUSTOM) { - /* Custom color: current frame color is slightly darker than user selected color */ - rgb_float_to_uchar(ubcolor, frame_color); - } - else { - /* green - on cfra */ - if (sel) { - intensity = 0.5f; - } - else { - intensity = 0.99f; - } - UI_GetThemeColorBlendShade3ubv(TH_CFRAME, TH_BACK, intensity, 10, ubcolor); - } - } - - immAttrib3ubv(color, ubcolor); - -#undef SET_INTENSITY -} - -/* Draw the given motion path for an Object or a Bone - * - assumes that the viewport has already been initialized properly - * i.e. draw_motion_paths_init() has been called - */ -void draw_motion_path_instance(Scene *scene, - Object *ob, bPoseChannel *pchan, bAnimVizSettings *avs, bMotionPath *mpath) -{ - //RegionView3D *rv3d = ar->regiondata; - bMotionPathVert *mpv, *mpv_start; - int i, stepsize = avs->path_step; - int sfra, efra, sind, len; - float prev_color[3]; - float frame_color[3]; - float next_color[3]; - - /* Custom color - Previous frames: color is darker than current frame */ - prev_color[0] = mpath->color[0] * 0.25f; - prev_color[1] = mpath->color[1] * 0.25f; - prev_color[2] = mpath->color[2] * 0.25f; - - /* Custom color - Current frame: color is slightly darker than user selected color */ - frame_color[0] = mpath->color[0] * 0.50f; - frame_color[1] = mpath->color[1] * 0.50f; - frame_color[2] = mpath->color[2] * 0.50f; - - /* Custom color - Next frames: color is equal to user selection */ - next_color[0] = mpath->color[0]; - next_color[1] = mpath->color[1]; - next_color[2] = mpath->color[2]; - - /* Save old line width */ - GLfloat old_width; - glGetFloatv(GL_LINE_WIDTH, &old_width); - - /* get frame ranges */ - if (avs->path_type == MOTIONPATH_TYPE_ACFRA) { - /* With "Around Current", we only choose frames from around - * the current frame to draw. - */ - sfra = CFRA - avs->path_bc; - efra = CFRA + avs->path_ac; - } - else { - /* Use the current display range */ - sfra = avs->path_sf; - efra = avs->path_ef; - } - - /* no matter what, we can only show what is in the cache and no more - * - abort if whole range is past ends of path - * - otherwise clamp endpoints to extents of path - */ - if (sfra < mpath->start_frame) { - /* start clamp */ - sfra = mpath->start_frame; - } - if (efra > mpath->end_frame) { - /* end clamp */ - efra = mpath->end_frame; - } - - if ((sfra > mpath->end_frame) || (efra < mpath->start_frame)) { - /* whole path is out of bounds */ - return; - } - - len = efra - sfra; - - if ((len <= 0) || (mpath->points == NULL)) { - return; - } - - /* get pointers to parts of path */ - sind = sfra - mpath->start_frame; - mpv_start = (mpath->points + sind); - - /* draw curve-line of path */ - /* Draw lines only if line drawing option is enabled */ - if (mpath->flag & MOTIONPATH_FLAG_LINES) { - /* set line thickness */ - glLineWidth(mpath->line_thickness); - - Gwn_VertFormat *format = immVertexFormat(); - unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - unsigned int color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 3, GWN_FETCH_INT_TO_FLOAT_UNIT); - - immBindBuiltinProgram(GPU_SHADER_3D_SMOOTH_COLOR); - - immBegin(GWN_PRIM_LINE_STRIP, len); - - for (i = 0, mpv = mpv_start; i < len; i++, mpv++) { - short sel = (pchan) ? (pchan->bone->flag & BONE_SELECTED) : (ob->flag & SELECT); - - /* Set color */ - set_motion_path_color(scene, mpath, i, sel, sfra, efra, prev_color, frame_color, next_color, color); - - /* draw a vertex with this color */ - immVertex3fv(pos, mpv->co); - } - - immEnd(); - - immUnbindProgram(); - - /* back to old line thickness */ - glLineWidth(old_width); - } - - unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - - /* Point must be bigger than line thickness */ - glPointSize(mpath->line_thickness + 1.0); - - /* draw little black point at each frame */ - immUniformColor3ub(0, 0, 0); - - immBegin(GWN_PRIM_POINTS, len); - - for (i = 0, mpv = mpv_start; i < len; i++, mpv++) { - immVertex3fv(pos, mpv->co); - } - - immEnd(); - - /* Draw little white dots at each framestep value or replace with custom color */ - if (mpath->flag & MOTIONPATH_FLAG_CUSTOM) { - immUniformColor3fv(mpath->color); - } - else { - immUniformThemeColor(TH_TEXT_HI); - } - - immBegin(GWN_PRIM_POINTS, (len + stepsize - 1) / stepsize); - - for (i = 0, mpv = mpv_start; i < len; i += stepsize, mpv += stepsize) { - immVertex3fv(pos, mpv->co); - } - - immEnd(); - - /* Draw big green dot where the current frame is - * NOTE: this is only done when keyframes are shown, since this adds similar types of clutter - */ - if ((avs->path_viewflag & MOTIONPATH_VIEW_KFRAS) && - (sfra < CFRA) && (CFRA <= efra)) - { - glPointSize(mpath->line_thickness + 5.0); - immUniformThemeColor(TH_CFRAME); - - immBegin(GWN_PRIM_POINTS, 1); - - mpv = mpv_start + (CFRA - sfra); - immVertex3fv(pos, mpv->co); - - immEnd(); - } - - immUnbindProgram(); - - /* XXX, this isn't up to date but probably should be kept so. */ - invert_m4_m4(ob->imat, ob->obmat); - - /* Draw frame numbers at each framestep value */ - if (avs->path_viewflag & MOTIONPATH_VIEW_FNUMS) { - unsigned char col[4]; - UI_GetThemeColor3ubv(TH_TEXT_HI, col); - col[3] = 255; - - for (i = 0, mpv = mpv_start; i < len; i += stepsize, mpv += stepsize) { - int frame = sfra + i; - char numstr[32]; - size_t numstr_len; - float co[3]; - - /* only draw framenum if several consecutive highlighted points don't occur on same point */ - if (i == 0) { - numstr_len = sprintf(numstr, " %d", frame); - mul_v3_m4v3(co, ob->imat, mpv->co); - view3d_cached_text_draw_add(co, numstr, numstr_len, - 0, V3D_CACHE_TEXT_WORLDSPACE | V3D_CACHE_TEXT_ASCII, col); - } - else if ((i >= stepsize) && (i < len - stepsize)) { - bMotionPathVert *mpvP = (mpv - stepsize); - bMotionPathVert *mpvN = (mpv + stepsize); - - if ((equals_v3v3(mpv->co, mpvP->co) == 0) || (equals_v3v3(mpv->co, mpvN->co) == 0)) { - numstr_len = sprintf(numstr, " %d", frame); - mul_v3_m4v3(co, ob->imat, mpv->co); - view3d_cached_text_draw_add(co, numstr, numstr_len, - 0, V3D_CACHE_TEXT_WORLDSPACE | V3D_CACHE_TEXT_ASCII, col); - } - } - } - } - - /* Keyframes - dots and numbers */ - if (avs->path_viewflag & MOTIONPATH_VIEW_KFRAS) { - unsigned char col[4]; - - AnimData *adt = BKE_animdata_from_id(&ob->id); - DLRBT_Tree keys; - - /* build list of all keyframes in active action for object or pchan */ - BLI_dlrbTree_init(&keys); - - if (adt) { - /* it is assumed that keyframes for bones are all grouped in a single group - * unless an option is set to always use the whole action - */ - if ((pchan) && (avs->path_viewflag & MOTIONPATH_VIEW_KFACT) == 0) { - bActionGroup *agrp = BKE_action_group_find_name(adt->action, pchan->name); - - if (agrp) { - agroup_to_keylist(adt, agrp, &keys, NULL); - BLI_dlrbTree_linkedlist_sync(&keys); - } - } - else { - action_to_keylist(adt, adt->action, &keys, NULL); - BLI_dlrbTree_linkedlist_sync(&keys); - } - } - - /* Draw slightly-larger yellow dots at each keyframe */ - UI_GetThemeColor3ubv(TH_VERTEX_SELECT, col); - col[3] = 255; - - /* point must be bigger than line */ - glPointSize(mpath->line_thickness + 3.0); - - pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - immUniformColor3ubv(col); - - immBeginAtMost(GWN_PRIM_POINTS, len); - - for (i = 0, mpv = mpv_start; i < len; i++, mpv++) { - int frame = sfra + i; - float mframe = (float)(frame); - - if (BLI_dlrbTree_search_exact(&keys, compare_ak_cfraPtr, &mframe)) { - immVertex3fv(pos, mpv->co); - } - } - - immEnd(); - - immUnbindProgram(); - - /* Draw frame numbers of keyframes */ - if (avs->path_viewflag & MOTIONPATH_VIEW_KFNOS) { - float co[3]; - for (i = 0, mpv = mpv_start; i < len; i++, mpv++) { - float mframe = (float)(sfra + i); - - if (BLI_dlrbTree_search_exact(&keys, compare_ak_cfraPtr, &mframe)) { - char numstr[32]; - size_t numstr_len; - - numstr_len = sprintf(numstr, " %d", (sfra + i)); - mul_v3_m4v3(co, ob->imat, mpv->co); - view3d_cached_text_draw_add(co, numstr, numstr_len, - 0, V3D_CACHE_TEXT_WORLDSPACE | V3D_CACHE_TEXT_ASCII, col); - } - } - } - - BLI_dlrbTree_free(&keys); - } -} - -/* Clean up drawing environment after drawing motion paths */ -void draw_motion_paths_cleanup(View3D *v3d) -{ - if (v3d->zbuf) glEnable(GL_DEPTH_TEST); - gpuPopMatrix(); -} diff --git a/source/blender/editors/space_view3d/drawarmature.c b/source/blender/editors/space_view3d/drawarmature.c deleted file mode 100644 index 9a82bce4b4b..00000000000 --- a/source/blender/editors/space_view3d/drawarmature.c +++ /dev/null @@ -1,3010 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2005 by the Blender Foundation. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/editors/space_view3d/drawarmature.c - * \ingroup spview3d - */ - - -#include <stdlib.h> -#include <string.h> -#include <math.h> - -#include "DNA_anim_types.h" -#include "DNA_armature_types.h" -#include "DNA_constraint_types.h" -#include "DNA_scene_types.h" -#include "DNA_screen_types.h" -#include "DNA_view3d_types.h" -#include "DNA_object_types.h" - -#include "BLI_blenlib.h" -#include "BLI_math.h" -#include "BLI_dlrbTree.h" -#include "BLI_utildefines.h" - -#include "BKE_animsys.h" -#include "BKE_action.h" -#include "BKE_armature.h" -#include "BKE_global.h" -#include "BKE_modifier.h" -#include "BKE_nla.h" -#include "BKE_curve.h" -#include "BKE_context.h" - -#include "DEG_depsgraph.h" - -#include "BIF_glutil.h" - -#include "ED_armature.h" -#include "ED_keyframes_draw.h" - -#include "GPU_basic_shader.h" -#include "GPU_batch.h" -#include "GPU_immediate.h" -#include "GPU_immediate_util.h" -#include "GPU_matrix.h" - -#include "UI_resources.h" - -#include "view3d_intern.h" - -#include "GPU_select.h" - -/* *************** Armature Drawing - Coloring API ***************************** */ - -/* global here is reset before drawing each bone */ -static ThemeWireColor *bcolor = NULL; -static float fcolor[4] = {0.0f}; -static bool flat_color; - -/* values of colCode for set_pchan_color */ -enum { - PCHAN_COLOR_NORMAL = 0, /* normal drawing */ - PCHAN_COLOR_SOLID, /* specific case where "solid" color is needed */ - PCHAN_COLOR_CONSTS, /* "constraint" colors (which may/may-not be suppressed) */ - - PCHAN_COLOR_SPHEREBONE_BASE, /* for the 'stick' of sphere (envelope) bones */ - PCHAN_COLOR_SPHEREBONE_END, /* for the ends of sphere (envelope) bones */ - PCHAN_COLOR_LINEBONE /* for the middle of line-bones */ -}; - -/* This function sets the color-set for coloring a certain bone */ -static void set_pchan_colorset(Object *ob, bPoseChannel *pchan) -{ - bPose *pose = (ob) ? ob->pose : NULL; - bArmature *arm = (ob) ? ob->data : NULL; - bActionGroup *grp = NULL; - short color_index = 0; - - /* sanity check */ - if (ELEM(NULL, ob, arm, pose, pchan)) { - bcolor = NULL; - return; - } - - /* only try to set custom color if enabled for armature */ - if (arm->flag & ARM_COL_CUSTOM) { - /* currently, a bone can only use a custom color set if it's group (if it has one), - * has been set to use one - */ - if (pchan->agrp_index) { - grp = (bActionGroup *)BLI_findlink(&pose->agroups, (pchan->agrp_index - 1)); - if (grp) - color_index = grp->customCol; - } - } - - /* bcolor is a pointer to the color set to use. If NULL, then the default - * color set (based on the theme colors for 3d-view) is used. - */ - if (color_index > 0) { - bTheme *btheme = UI_GetTheme(); - bcolor = &btheme->tarm[(color_index - 1)]; - } - else if (color_index == -1) { - /* use the group's own custom color set (grp is always != NULL here) */ - bcolor = &grp->cs; - } - else { - bcolor = NULL; - } -} - -/* This function is for brightening/darkening a given color (like UI_GetThemeColorShade3ubv()) */ -static void cp_shade_color3ub(unsigned char cp[3], const int offset) -{ - int r, g, b; - - r = offset + (int) cp[0]; - CLAMP(r, 0, 255); - g = offset + (int) cp[1]; - CLAMP(g, 0, 255); - b = offset + (int) cp[2]; - CLAMP(b, 0, 255); - - cp[0] = r; - cp[1] = g; - cp[2] = b; -} - -/* This function sets the gl-color for coloring a certain bone (based on bcolor) */ -static bool set_pchan_color(short colCode, int boneflag, short constflag) -{ - switch (colCode) { - case PCHAN_COLOR_NORMAL: - { - if (bcolor) { - unsigned char cp[4] = {255}; - - if (boneflag & BONE_DRAW_ACTIVE) { - copy_v3_v3_char((char *)cp, bcolor->active); - if (!(boneflag & BONE_SELECTED)) { - cp_shade_color3ub(cp, -80); - } - } - else if (boneflag & BONE_SELECTED) { - copy_v3_v3_char((char *)cp, bcolor->select); - } - else { - /* a bit darker than solid */ - copy_v3_v3_char((char *)cp, bcolor->solid); - cp_shade_color3ub(cp, -50); - } - - rgb_uchar_to_float(fcolor, cp); - } - else { - if ((boneflag & BONE_DRAW_ACTIVE) && (boneflag & BONE_SELECTED)) { - UI_GetThemeColor4fv(TH_BONE_POSE_ACTIVE, fcolor); - } - else if (boneflag & BONE_DRAW_ACTIVE) { - UI_GetThemeColorBlendShade4fv(TH_WIRE, TH_BONE_POSE, 0.15f, 0, fcolor); - } - else if (boneflag & BONE_SELECTED) { - UI_GetThemeColor4fv(TH_BONE_POSE, fcolor); - } - else { - UI_GetThemeColor4fv(TH_WIRE, fcolor); - } - } - - return true; - } - case PCHAN_COLOR_SOLID: - { - if (bcolor) { - rgb_uchar_to_float(fcolor, (unsigned char *)bcolor->solid); - } - else { - UI_GetThemeColor4fv(TH_BONE_SOLID, fcolor); - } - - return true; - } - case PCHAN_COLOR_CONSTS: - { - if ((bcolor == NULL) || (bcolor->flag & TH_WIRECOLOR_CONSTCOLS)) { - unsigned char cp[4]; - if (constflag & PCHAN_HAS_TARGET) rgba_char_args_set((char *)cp, 255, 150, 0, 80); - else if (constflag & PCHAN_HAS_IK) rgba_char_args_set((char *)cp, 255, 255, 0, 80); - else if (constflag & PCHAN_HAS_SPLINEIK) rgba_char_args_set((char *)cp, 200, 255, 0, 80); - else if (constflag & PCHAN_HAS_CONST) rgba_char_args_set((char *)cp, 0, 255, 120, 80); - - rgba_uchar_to_float(fcolor, cp); - - return true; - } - return false; - } - case PCHAN_COLOR_SPHEREBONE_BASE: - { - if (bcolor) { - unsigned char cp[4] = {255}; - - if (boneflag & BONE_DRAW_ACTIVE) { - copy_v3_v3_char((char *)cp, bcolor->active); - } - else if (boneflag & BONE_SELECTED) { - copy_v3_v3_char((char *)cp, bcolor->select); - } - else { - copy_v3_v3_char((char *)cp, bcolor->solid); - } - - rgb_uchar_to_float(fcolor, cp); - } - else { - if (boneflag & BONE_DRAW_ACTIVE) { - UI_GetThemeColorShade4fv(TH_BONE_POSE, 40, fcolor); - } - else if (boneflag & BONE_SELECTED) { - UI_GetThemeColor4fv(TH_BONE_POSE, fcolor); - } - else { - UI_GetThemeColor4fv(TH_BONE_SOLID, fcolor); - } - } - - return true; - } - case PCHAN_COLOR_SPHEREBONE_END: - { - if (bcolor) { - unsigned char cp[4] = {255}; - - if (boneflag & BONE_DRAW_ACTIVE) { - copy_v3_v3_char((char *)cp, bcolor->active); - cp_shade_color3ub(cp, 10); - } - else if (boneflag & BONE_SELECTED) { - copy_v3_v3_char((char *)cp, bcolor->select); - cp_shade_color3ub(cp, -30); - } - else { - copy_v3_v3_char((char *)cp, bcolor->solid); - cp_shade_color3ub(cp, -30); - } - - rgb_uchar_to_float(fcolor, cp); - } - else { - if (boneflag & BONE_DRAW_ACTIVE) { - UI_GetThemeColorShade4fv(TH_BONE_POSE, 10, fcolor); - } - else if (boneflag & BONE_SELECTED) { - UI_GetThemeColorShade4fv(TH_BONE_POSE, -30, fcolor); - } - else { - UI_GetThemeColorShade4fv(TH_BONE_SOLID, -30, fcolor); - } - } - break; - } - case PCHAN_COLOR_LINEBONE: - { - /* inner part in background color or constraint */ - if ((constflag) && ((bcolor == NULL) || (bcolor->flag & TH_WIRECOLOR_CONSTCOLS))) { - unsigned char cp[4]; - if (constflag & PCHAN_HAS_TARGET) rgba_char_args_set((char *)cp, 255, 150, 0, 255); - else if (constflag & PCHAN_HAS_IK) rgba_char_args_set((char *)cp, 255, 255, 0, 255); - else if (constflag & PCHAN_HAS_SPLINEIK) rgba_char_args_set((char *)cp, 200, 255, 0, 255); - else if (constflag & PCHAN_HAS_CONST) rgba_char_args_set((char *)cp, 0, 255, 120, 255); - else if (constflag) UI_GetThemeColor4ubv(TH_BONE_POSE, cp); /* PCHAN_HAS_ACTION */ - - rgb_uchar_to_float(fcolor, cp); - } - else { - if (bcolor) { - const char *cp = bcolor->solid; - rgb_uchar_to_float(fcolor, (unsigned char *)cp); - fcolor[3] = 204.f / 255.f; - } - else { - UI_GetThemeColorShade4fv(TH_BACK, -30, fcolor); - } - } - - return true; - } - } - - return false; -} - -static void set_ebone_color(const unsigned int boneflag) -{ - if ((boneflag & BONE_DRAW_ACTIVE) && (boneflag & BONE_SELECTED)) { - UI_GetThemeColor4fv(TH_EDGE_SELECT, fcolor); - } - else if (boneflag & BONE_DRAW_ACTIVE) { - UI_GetThemeColorBlendShade4fv(TH_WIRE_EDIT, TH_EDGE_SELECT, 0.15f, 0, fcolor); - } - else if (boneflag & BONE_SELECTED) { - UI_GetThemeColorShade4fv(TH_EDGE_SELECT, -20, fcolor); - } - else { - UI_GetThemeColor4fv(TH_WIRE_EDIT, fcolor); - } -} - -/* *************** Armature drawing, helper calls for parts ******************* */ - -static void add_solid_flat_triangle(Gwn_VertBuf *vbo, unsigned int *vertex, unsigned int pos, unsigned int nor, - const float p1[3], const float p2[3], const float p3[3], const float n[3]) -{ - GWN_vertbuf_attr_set(vbo, nor, *vertex, n); - GWN_vertbuf_attr_set(vbo, pos, (*vertex)++, p1); - GWN_vertbuf_attr_set(vbo, nor, *vertex, n); - GWN_vertbuf_attr_set(vbo, pos, (*vertex)++, p2); - GWN_vertbuf_attr_set(vbo, nor, *vertex, n); - GWN_vertbuf_attr_set(vbo, pos, (*vertex)++, p3); -} - -/* half the cube, in Y */ -static const float cube_vert[8][3] = { - {-1.0, 0.0, -1.0}, - {-1.0, 0.0, 1.0}, - {-1.0, 1.0, 1.0}, - {-1.0, 1.0, -1.0}, - { 1.0, 0.0, -1.0}, - { 1.0, 0.0, 1.0}, - { 1.0, 1.0, 1.0}, - { 1.0, 1.0, -1.0}, -}; - -static const float cube_wire[24] = { - 0, 1, 1, 2, 2, 3, 3, 0, - 4, 5, 5, 6, 6, 7, 7, 4, - 0, 4, 1, 5, 2, 6, 3, 7, -}; - -static void drawsolidcube_size(float xsize, float ysize, float zsize) -{ - static Gwn_VertFormat format = {0}; - static Gwn_VertBuf vbo = {{0}}; - static Gwn_Batch batch = {{0}}; - const float light_vec[3] = {0.0f, 0.0f, 1.0f}; - - if (format.attrib_ct == 0) { - unsigned int i = 0; - float n[3] = {0.0f}; - /* Vertex format */ - unsigned int pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - unsigned int nor = GWN_vertformat_attr_add(&format, "nor", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - - /* Vertices */ - GWN_vertbuf_init_with_format(&vbo, &format); - GWN_vertbuf_data_alloc(&vbo, 36); - - n[0] = -1.0; - add_solid_flat_triangle(&vbo, &i, pos, nor, cube_vert[0], cube_vert[1], cube_vert[2], n); - add_solid_flat_triangle(&vbo, &i, pos, nor, cube_vert[2], cube_vert[3], cube_vert[0], n); - n[0] = 0; - n[1] = -1.0; - add_solid_flat_triangle(&vbo, &i, pos, nor, cube_vert[0], cube_vert[4], cube_vert[5], n); - add_solid_flat_triangle(&vbo, &i, pos, nor, cube_vert[5], cube_vert[1], cube_vert[0], n); - n[1] = 0; - n[0] = 1.0; - add_solid_flat_triangle(&vbo, &i, pos, nor, cube_vert[4], cube_vert[7], cube_vert[6], n); - add_solid_flat_triangle(&vbo, &i, pos, nor, cube_vert[6], cube_vert[5], cube_vert[4], n); - n[0] = 0; - n[1] = 1.0; - add_solid_flat_triangle(&vbo, &i, pos, nor, cube_vert[7], cube_vert[3], cube_vert[2], n); - add_solid_flat_triangle(&vbo, &i, pos, nor, cube_vert[2], cube_vert[6], cube_vert[7], n); - n[1] = 0; - n[2] = 1.0; - add_solid_flat_triangle(&vbo, &i, pos, nor, cube_vert[1], cube_vert[5], cube_vert[6], n); - add_solid_flat_triangle(&vbo, &i, pos, nor, cube_vert[6], cube_vert[2], cube_vert[1], n); - n[2] = -1.0; - add_solid_flat_triangle(&vbo, &i, pos, nor, cube_vert[7], cube_vert[4], cube_vert[0], n); - add_solid_flat_triangle(&vbo, &i, pos, nor, cube_vert[0], cube_vert[3], cube_vert[7], n); - - GWN_batch_init(&batch, GWN_PRIM_TRIS, &vbo, NULL); - } - - gpuPushMatrix(); - gpuScale3f(xsize, ysize, zsize); - - if (flat_color) { - GWN_batch_program_set_builtin(&batch, GPU_SHADER_3D_UNIFORM_COLOR); - } - else { - /* TODO replace with good default lighting shader ? */ - GWN_batch_program_set_builtin(&batch, GPU_SHADER_SIMPLE_LIGHTING); - GWN_batch_uniform_3fv(&batch, "light", light_vec); - } - GWN_batch_uniform_4fv(&batch, "color", fcolor); - GWN_batch_draw(&batch); - - gpuPopMatrix(); -} - -static void drawcube_size(float xsize, float ysize, float zsize) -{ - static Gwn_VertFormat format = {0}; - static Gwn_VertBuf vbo = {{0}}; - static Gwn_IndexBufBuilder elb = {0}; - static Gwn_IndexBuf el = {0}; - static Gwn_Batch batch = {{0}}; - - if (format.attrib_ct == 0) { - /* Vertex format */ - unsigned int pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - - /* Elements */ - GWN_indexbuf_init(&elb, GWN_PRIM_LINES, 12, 8); - for (int i = 0; i < 12; ++i) { - GWN_indexbuf_add_line_verts(&elb, cube_wire[i * 2], cube_wire[i * 2 + 1]); - } - GWN_indexbuf_build_in_place(&elb, &el); - - /* Vertices */ - GWN_vertbuf_init_with_format(&vbo, &format); - GWN_vertbuf_data_alloc(&vbo, 8); - for (int i = 0; i < 8; ++i) { - GWN_vertbuf_attr_set(&vbo, pos, i, cube_vert[i]); - } - - GWN_batch_init(&batch, GWN_PRIM_LINES, &vbo, &el); - GWN_batch_program_set_builtin(&batch, GPU_SHADER_3D_UNIFORM_COLOR); - } - - gpuPushMatrix(); - gpuScale3f(xsize, ysize, zsize); - - GWN_batch_program_use_begin(&batch); - GWN_batch_uniform_4fv(&batch, "color", fcolor); - GWN_batch_draw(&batch); - - gpuPopMatrix(); -} - - -static void draw_bonevert(void) -{ - static Gwn_VertFormat format = {0}; - static Gwn_VertBuf vbo = {{0}}; - static Gwn_Batch batch = {{0}}; - - if (format.attrib_ct == 0) { - /* Vertex format */ - unsigned int pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - - /* Vertices */ - GWN_vertbuf_init_with_format(&vbo, &format); - GWN_vertbuf_data_alloc(&vbo, 96); - for (int i = 0; i < 16; ++i) { - float vert[3] = {0.f, 0.f, 0.f}; - const float r = 0.05f; - - vert[0] = r * cosf(2 * M_PI * i / 16.f); - vert[1] = r * sinf(2 * M_PI * i / 16.f); - GWN_vertbuf_attr_set(&vbo, pos, i * 6 + 0, vert); - vert[0] = r * cosf(2 * M_PI * (i + 1) / 16.f); - vert[1] = r * sinf(2 * M_PI * (i + 1) / 16.f); - GWN_vertbuf_attr_set(&vbo, pos, i * 6 + 1, vert); - - vert[0] = 0.f; - vert[1] = r * cosf(2 * M_PI * i / 16.f); - vert[2] = r * sinf(2 * M_PI * i / 16.f); - GWN_vertbuf_attr_set(&vbo, pos, i * 6 + 2, vert); - vert[1] = r * cosf(2 * M_PI * (i + 1) / 16.f); - vert[2] = r * sinf(2 * M_PI * (i + 1) / 16.f); - GWN_vertbuf_attr_set(&vbo, pos, i * 6 + 3, vert); - - vert[1] = 0.f; - vert[0] = r * cosf(2 * M_PI * i / 16.f); - vert[2] = r * sinf(2 * M_PI * i / 16.f); - GWN_vertbuf_attr_set(&vbo, pos, i * 6 + 4, vert); - vert[0] = r * cosf(2 * M_PI * (i + 1) / 16.f); - vert[2] = r * sinf(2 * M_PI * (i + 1) / 16.f); - GWN_vertbuf_attr_set(&vbo, pos, i * 6 + 5, vert); - } - - GWN_batch_init(&batch, GWN_PRIM_LINES, &vbo, NULL); - GWN_batch_program_set_builtin(&batch, GPU_SHADER_3D_UNIFORM_COLOR); - } - - GWN_batch_program_use_begin(&batch); - GWN_batch_uniform_4fv(&batch, "color", fcolor); - GWN_batch_draw(&batch); -} - -static void draw_bonevert_solid(void) -{ - Gwn_Batch *batch = GPU_batch_preset_sphere(0); - const float light_vec[3] = {0.0f, 0.0f, 1.0f}; - - gpuPushMatrix(); - gpuScaleUniform(0.05); - - if (flat_color) { - GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR); - } - else { - /* TODO replace with good default lighting shader ? */ - GWN_batch_program_set_builtin(batch, GPU_SHADER_SIMPLE_LIGHTING); - GWN_batch_uniform_3fv(batch, "light", light_vec); - } - GWN_batch_uniform_4fv(batch, "color", fcolor); - GWN_batch_draw(batch); - - gpuPopMatrix(); -} - -static const float bone_octahedral_verts[6][3] = { - { 0.0f, 0.0f, 0.0f}, - { 0.1f, 0.1f, 0.1f}, - { 0.1f, 0.1f, -0.1f}, - {-0.1f, 0.1f, -0.1f}, - {-0.1f, 0.1f, 0.1f}, - { 0.0f, 1.0f, 0.0f} -}; - -static const unsigned int bone_octahedral_wire[24] = { - 0, 1, 1, 5, 5, 3, 3, 0, - 0, 4, 4, 5, 5, 2, 2, 0, - 1, 2, 2, 3, 3, 4, 4, 1, -}; - -static const unsigned int bone_octahedral_solid_tris[8][3] = { - {2, 1, 0}, /* bottom */ - {3, 2, 0}, - {4, 3, 0}, - {1, 4, 0}, - - {5, 1, 2}, /* top */ - {5, 2, 3}, - {5, 3, 4}, - {5, 4, 1} -}; - -/* aligned with bone_octahedral_solid_tris */ -static const float bone_octahedral_solid_normals[8][3] = { - { M_SQRT1_2, -M_SQRT1_2, 0.00000000f}, - {-0.00000000f, -M_SQRT1_2, -M_SQRT1_2}, - {-M_SQRT1_2, -M_SQRT1_2, 0.00000000f}, - { 0.00000000f, -M_SQRT1_2, M_SQRT1_2}, - { 0.99388373f, 0.11043154f, -0.00000000f}, - { 0.00000000f, 0.11043154f, -0.99388373f}, - {-0.99388373f, 0.11043154f, 0.00000000f}, - { 0.00000000f, 0.11043154f, 0.99388373f} -}; - -static void draw_bone_octahedral(void) -{ - static Gwn_VertFormat format = {0}; - static Gwn_VertBuf vbo = {{0}}; - static Gwn_IndexBufBuilder elb = {0}; - static Gwn_IndexBuf el = {0}; - static Gwn_Batch batch = {{0}}; - - if (format.attrib_ct == 0) { - /* Vertex format */ - unsigned int pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - - /* Elements */ - GWN_indexbuf_init(&elb, GWN_PRIM_LINES, 12, 6); - for (int i = 0; i < 12; ++i) { - GWN_indexbuf_add_line_verts(&elb, bone_octahedral_wire[i * 2], bone_octahedral_wire[i * 2 + 1]); - } - GWN_indexbuf_build_in_place(&elb, &el); - - /* Vertices */ - GWN_vertbuf_init_with_format(&vbo, &format); - GWN_vertbuf_data_alloc(&vbo, 6); - for (int i = 0; i < 6; ++i) { - GWN_vertbuf_attr_set(&vbo, pos, i, bone_octahedral_verts[i]); - } - - GWN_batch_init(&batch, GWN_PRIM_LINES, &vbo, &el); - GWN_batch_program_set_builtin(&batch, GPU_SHADER_3D_UNIFORM_COLOR); - } - - GWN_batch_program_use_begin(&batch); - GWN_batch_uniform_4fv(&batch, "color", fcolor); - GWN_batch_draw(&batch); -} - -static void draw_bone_solid_octahedral(void) -{ - static Gwn_VertFormat format = {0}; - static Gwn_VertBuf vbo = {{0}}; - static Gwn_Batch batch = {{0}}; - const float light_vec[3] = {0.0f, 0.0f, 1.0f}; - - if (format.attrib_ct == 0) { - unsigned int v_idx = 0; - /* Vertex format */ - unsigned int pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - unsigned int nor = GWN_vertformat_attr_add(&format, "nor", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - - /* Vertices */ - GWN_vertbuf_init_with_format(&vbo, &format); - GWN_vertbuf_data_alloc(&vbo, 24); - - for (int i = 0; i < 8; i++) { - add_solid_flat_triangle(&vbo, &v_idx, pos, nor, - bone_octahedral_verts[bone_octahedral_solid_tris[i][0]], - bone_octahedral_verts[bone_octahedral_solid_tris[i][1]], - bone_octahedral_verts[bone_octahedral_solid_tris[i][2]], - bone_octahedral_solid_normals[i]); - } - - GWN_batch_init(&batch, GWN_PRIM_TRIS, &vbo, NULL); - } - - if (flat_color) { - GWN_batch_program_set_builtin(&batch, GPU_SHADER_3D_UNIFORM_COLOR); - } - else { - /* TODO replace with good default lighting shader ? */ - GWN_batch_program_set_builtin(&batch, GPU_SHADER_SIMPLE_LIGHTING); - GWN_batch_uniform_3fv(&batch, "light", light_vec); - } - GWN_batch_uniform_4fv(&batch, "color", fcolor); - GWN_batch_draw(&batch); -} - -/* *************** Armature drawing, bones ******************* */ - - -static void draw_bone_points(const short dt, int armflag, unsigned int boneflag, int id) -{ - /* Draw root point if we are not connected */ - if ((boneflag & BONE_CONNECTED) == 0) { - if (id != -1) - GPU_select_load_id(id | BONESEL_ROOT); - - if (dt <= OB_WIRE) { - if (armflag & ARM_EDITMODE) { - if (boneflag & BONE_ROOTSEL) { - UI_GetThemeColor4fv(TH_VERTEX_SELECT, fcolor); - } - else { - UI_GetThemeColor4fv(TH_VERTEX, fcolor); - } - } - } - else { - if (armflag & ARM_POSEMODE) - set_pchan_color(PCHAN_COLOR_SOLID, boneflag, 0); - else { - UI_GetThemeColor4fv(TH_BONE_SOLID, fcolor); - } - } - - if (dt > OB_WIRE) - draw_bonevert_solid(); - else - draw_bonevert(); - } - - /* Draw tip point */ - if (id != -1) - GPU_select_load_id(id | BONESEL_TIP); - - if (dt <= OB_WIRE) { - if (armflag & ARM_EDITMODE) { - if (boneflag & BONE_TIPSEL) { - UI_GetThemeColor4fv(TH_VERTEX_SELECT, fcolor); - } - else { - UI_GetThemeColor4fv(TH_VERTEX, fcolor); - } - } - } - else { - if (armflag & ARM_POSEMODE) - set_pchan_color(PCHAN_COLOR_SOLID, boneflag, 0); - else { - UI_GetThemeColor4fv(TH_BONE_SOLID, fcolor); - } - } - - gpuPushMatrix(); - gpuTranslate2f(0.0f, 1.0f); - if (dt > OB_WIRE) - draw_bonevert_solid(); - else - draw_bonevert(); - gpuPopMatrix(); -} - -/* 16 values of sin function (still same result!) */ -static const float si[16] = { - 0.00000000f, - 0.20129852f, 0.39435585f, - 0.57126821f, 0.72479278f, - 0.84864425f, 0.93775213f, - 0.98846832f, 0.99871650f, - 0.96807711f, 0.89780453f, - 0.79077573f, 0.65137248f, - 0.48530196f, 0.29936312f, - 0.10116832f -}; -/* 16 values of cos function (still same result!) */ -static const float co[16] = { - 1.00000000f, - 0.97952994f, 0.91895781f, - 0.82076344f, 0.68896691f, - 0.52896401f, 0.34730525f, - 0.15142777f, -0.05064916f, - -0.25065253f, -0.44039415f, - -0.61210598f, -0.75875812f, - -0.87434661f, -0.95413925f, - -0.99486932f -}; - - - -/* smat, imat = mat & imat to draw screenaligned */ -static void draw_sphere_bone_dist(float smat[4][4], float imat[4][4], bPoseChannel *pchan, EditBone *ebone) -{ - float head, tail, dist /*, length*/; - float *headvec, *tailvec, dirvec[3]; - - /* figure out the sizes of spheres */ - if (ebone) { - /* this routine doesn't call get_matrix_editbone() that calculates it */ - ebone->length = len_v3v3(ebone->head, ebone->tail); - - /*length = ebone->length;*/ /*UNUSED*/ - tail = ebone->rad_tail; - dist = ebone->dist; - if (ebone->parent && (ebone->flag & BONE_CONNECTED)) - head = ebone->parent->rad_tail; - else - head = ebone->rad_head; - headvec = ebone->head; - tailvec = ebone->tail; - } - else { - /*length = pchan->bone->length;*/ /*UNUSED*/ - tail = pchan->bone->rad_tail; - dist = pchan->bone->dist; - if (pchan->parent && (pchan->bone->flag & BONE_CONNECTED)) - head = pchan->parent->bone->rad_tail; - else - head = pchan->bone->rad_head; - headvec = pchan->pose_head; - tailvec = pchan->pose_tail; - } - - /* ***** draw it ***** */ - - /* move vector to viewspace */ - sub_v3_v3v3(dirvec, tailvec, headvec); - mul_mat3_m4_v3(smat, dirvec); - /* clear zcomp */ - dirvec[2] = 0.0f; - - if (head != tail) { - /* correction when viewing along the bones axis - * it pops in and out but better then artifacts, [#23841] */ - float view_dist = len_v2(dirvec); - - if (head - view_dist > tail) { - tailvec = headvec; - tail = head; - zero_v3(dirvec); - dirvec[0] = 0.00001; /* XXX. weak but ok */ - } - else if (tail - view_dist > head) { - headvec = tailvec; - head = tail; - zero_v3(dirvec); - dirvec[0] = 0.00001; /* XXX. weak but ok */ - } - } - - /* move vector back */ - mul_mat3_m4_v3(imat, dirvec); - - if (0.0f != normalize_v3(dirvec)) { - float norvec[3], vec1[3], vec2[3], vec[3]; - int a; - - //mul_v3_fl(dirvec, head); - cross_v3_v3v3(norvec, dirvec, imat[2]); - - Gwn_VertFormat *format = immVertexFormat(); - unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - immBegin(GWN_PRIM_TRI_STRIP, 66); - immUniformColor4ub(255, 255, 255, 50); - - for (a = 0; a < 16; a++) { - vec[0] = -si[a] * dirvec[0] + co[a] * norvec[0]; - vec[1] = -si[a] * dirvec[1] + co[a] * norvec[1]; - vec[2] = -si[a] * dirvec[2] + co[a] * norvec[2]; - - madd_v3_v3v3fl(vec1, headvec, vec, head); - madd_v3_v3v3fl(vec2, headvec, vec, head + dist); - - immVertex3fv(pos, vec1); - immVertex3fv(pos, vec2); - } - - for (a = 15; a >= 0; a--) { - vec[0] = si[a] * dirvec[0] + co[a] * norvec[0]; - vec[1] = si[a] * dirvec[1] + co[a] * norvec[1]; - vec[2] = si[a] * dirvec[2] + co[a] * norvec[2]; - - madd_v3_v3v3fl(vec1, tailvec, vec, tail); - madd_v3_v3v3fl(vec2, tailvec, vec, tail + dist); - - immVertex3fv(pos, vec1); - immVertex3fv(pos, vec2); - } - /* make it cyclic... */ - - vec[0] = -si[0] * dirvec[0] + co[0] * norvec[0]; - vec[1] = -si[0] * dirvec[1] + co[0] * norvec[1]; - vec[2] = -si[0] * dirvec[2] + co[0] * norvec[2]; - - madd_v3_v3v3fl(vec1, headvec, vec, head); - madd_v3_v3v3fl(vec2, headvec, vec, head + dist); - - immVertex3fv(pos, vec1); - immVertex3fv(pos, vec2); - - immEnd(); - immUnbindProgram(); - } -} - - -/* smat, imat = mat & imat to draw screenaligned */ -static void draw_sphere_bone_wire(float smat[4][4], float imat[4][4], - int armflag, int boneflag, short constflag, unsigned int id, - bPoseChannel *pchan, EditBone *ebone) -{ - float head, tail /*, length*/; - float *headvec, *tailvec, dirvec[3]; - - Gwn_VertFormat *format = immVertexFormat(); - unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - - /* figure out the sizes of spheres */ - if (ebone) { - /* this routine doesn't call get_matrix_editbone() that calculates it */ - ebone->length = len_v3v3(ebone->head, ebone->tail); - - /*length = ebone->length;*/ /*UNUSED*/ - tail = ebone->rad_tail; - if (ebone->parent && (boneflag & BONE_CONNECTED)) - head = ebone->parent->rad_tail; - else - head = ebone->rad_head; - headvec = ebone->head; - tailvec = ebone->tail; - } - else { - /*length = pchan->bone->length;*/ /*UNUSED*/ - tail = pchan->bone->rad_tail; - if ((pchan->parent) && (boneflag & BONE_CONNECTED)) - head = pchan->parent->bone->rad_tail; - else - head = pchan->bone->rad_head; - headvec = pchan->pose_head; - tailvec = pchan->pose_tail; - } - - /* sphere root color */ - if (armflag & ARM_EDITMODE) { - if (boneflag & BONE_ROOTSEL) { - UI_GetThemeColor4fv(TH_VERTEX_SELECT, fcolor); - } - else { - UI_GetThemeColor4fv(TH_VERTEX, fcolor); - } - } - else if (armflag & ARM_POSEMODE) - set_pchan_color(PCHAN_COLOR_NORMAL, boneflag, constflag); - - immUniformColor4fv(fcolor); - - /* Draw root point if we are not connected */ - if ((boneflag & BONE_CONNECTED) == 0) { - if (id != -1) - GPU_select_load_id(id | BONESEL_ROOT); - - imm_drawcircball(headvec, head, imat, pos); - } - - /* Draw tip point */ - if (armflag & ARM_EDITMODE) { - if (boneflag & BONE_TIPSEL) { - UI_GetThemeColor4fv(TH_VERTEX_SELECT, fcolor); - } - else { - UI_GetThemeColor4fv(TH_VERTEX, fcolor); - } - } - - if (id != -1) - GPU_select_load_id(id | BONESEL_TIP); - - imm_drawcircball(tailvec, tail, imat, pos); - - /* base */ - if (armflag & ARM_EDITMODE) { - if (boneflag & BONE_SELECTED) { - UI_GetThemeColor4fv(TH_SELECT, fcolor); - } - else { - UI_GetThemeColor4fv(TH_WIRE_EDIT, fcolor); - } - } - - sub_v3_v3v3(dirvec, tailvec, headvec); - - /* move vector to viewspace */ - mul_mat3_m4_v3(smat, dirvec); - /* clear zcomp */ - dirvec[2] = 0.0f; - /* move vector back */ - mul_mat3_m4_v3(imat, dirvec); - - if (0.0f != normalize_v3(dirvec)) { - float norvech[3], norvect[3], vec[3]; - - copy_v3_v3(vec, dirvec); - - mul_v3_fl(dirvec, head); - cross_v3_v3v3(norvech, dirvec, imat[2]); - - mul_v3_fl(vec, tail); - cross_v3_v3v3(norvect, vec, imat[2]); - - if (id != -1) - GPU_select_load_id(id | BONESEL_BONE); - - immBegin(GWN_PRIM_LINES, 4); - - add_v3_v3v3(vec, headvec, norvech); - immVertex3fv(pos, vec); - - add_v3_v3v3(vec, tailvec, norvect); - immVertex3fv(pos, vec); - - sub_v3_v3v3(vec, headvec, norvech); - immVertex3fv(pos, vec); - - sub_v3_v3v3(vec, tailvec, norvect); - immVertex3fv(pos, vec); - - immEnd(); - } - - immUnbindProgram(); -} - -/* does wire only for outline selecting */ -static void draw_sphere_bone(const short dt, int armflag, int boneflag, short constflag, unsigned int id, - bPoseChannel *pchan, EditBone *ebone) -{ - Gwn_Batch *sphere = GPU_batch_preset_sphere(1); - float head, tail, length; - float fac1, fac2, size1, size2; - const float light_vec[3] = {0.0f, 0.0f, 1.0f}; - - /* dt is always OB_SOlID */ - GWN_batch_program_set_builtin(sphere, GPU_SHADER_SIMPLE_LIGHTING); - GWN_batch_uniform_3fv(sphere, "light", light_vec); - - gpuPushMatrix(); - - /* figure out the sizes of spheres */ - if (ebone) { - length = ebone->length; - tail = ebone->rad_tail; - if (ebone->parent && (boneflag & BONE_CONNECTED)) - head = ebone->parent->rad_tail; - else - head = ebone->rad_head; - } - else { - length = pchan->bone->length; - tail = pchan->bone->rad_tail; - if (pchan->parent && (boneflag & BONE_CONNECTED)) - head = pchan->parent->bone->rad_tail; - else - head = pchan->bone->rad_head; - } - - /* move to z-axis space */ - gpuRotateAxis(-90.0f, 'X'); - - /* sphere root color */ - if (armflag & ARM_EDITMODE) { - if (boneflag & BONE_ROOTSEL) - UI_GetThemeColor4fv(TH_VERTEX_SELECT, fcolor); - else - UI_GetThemeColorShade4fv(TH_BONE_SOLID, -30, fcolor); - } - else if (armflag & ARM_POSEMODE) - set_pchan_color(PCHAN_COLOR_SPHEREBONE_END, boneflag, constflag); - else if (dt == OB_SOLID) - UI_GetThemeColorShade4fv(TH_BONE_SOLID, -30, fcolor); - - /* Draw root point if we are not connected */ - if ((boneflag & BONE_CONNECTED) == 0) { - if (id != -1) - GPU_select_load_id(id | BONESEL_ROOT); - gpuPushMatrix(); - gpuScaleUniform(head); - GWN_batch_uniform_4fv(sphere, "color", fcolor); - GWN_batch_draw(sphere); - gpuPopMatrix(); - } - - /* Draw tip point */ - if (armflag & ARM_EDITMODE) { - if (boneflag & BONE_TIPSEL) UI_GetThemeColor4fv(TH_VERTEX_SELECT, fcolor); - else UI_GetThemeColorShade4fv(TH_BONE_SOLID, -30, fcolor); - } - - if (id != -1) - GPU_select_load_id(id | BONESEL_TIP); - - gpuTranslate3f(0.0f, 0.0f, length); - - gpuPushMatrix(); - gpuScaleUniform(tail); - GWN_batch_program_use_begin(sphere); /* hack to make the following uniforms stick */ - GWN_batch_uniform_4fv(sphere, "color", fcolor); - GWN_batch_draw(sphere); - gpuPopMatrix(); - - gpuTranslate3f(0.0f, 0.0f, -length); - - /* base */ - if (armflag & ARM_EDITMODE) { - if (boneflag & BONE_SELECTED) UI_GetThemeColor4fv(TH_SELECT, fcolor); - else UI_GetThemeColor4fv(TH_BONE_SOLID, fcolor); - } - else if (armflag & ARM_POSEMODE) - set_pchan_color(PCHAN_COLOR_SPHEREBONE_BASE, boneflag, constflag); - else if (dt == OB_SOLID) - UI_GetThemeColor4fv(TH_BONE_SOLID, fcolor); - - GWN_batch_program_use_begin(sphere); /* hack to make the following uniforms stick */ - GWN_batch_uniform_4fv(sphere, "color", fcolor); - - fac1 = (length - head) / length; - fac2 = (length - tail) / length; - - if (length > (head + tail)) { - size1 = fac2 * tail + (1.0f - fac2) * head; - size2 = fac1 * head + (1.0f - fac1) * tail; - - if (id != -1) - GPU_select_load_id(id | BONESEL_BONE); - - /* draw sphere on extrema */ - gpuPushMatrix(); - gpuTranslate3f(0.0f, 0.0f, length - tail); - gpuScaleUniform(size1); - - GWN_batch_draw(sphere); - gpuPopMatrix(); - - gpuPushMatrix(); - gpuTranslate3f(0.0f, 0.0f, head); - gpuScaleUniform(size2); - - GWN_batch_draw(sphere); - gpuPopMatrix(); - - /* draw cynlinder between spheres */ - glEnable(GL_POLYGON_OFFSET_FILL); - glPolygonOffset(-1.0f, -1.0f); - - Gwn_VertFormat *format = immVertexFormat(); - unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - unsigned int nor = GWN_vertformat_attr_add(format, "nor", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - - immBindBuiltinProgram(GPU_SHADER_SIMPLE_LIGHTING); - immUniformColor4fv(fcolor); - immUniform3fv("light", light_vec); - - gpuTranslate3f(0.0f, 0.0f, head); - imm_draw_cylinder_fill_normal_3d(pos, nor, size2, size1, length - head - tail, 16, 1); - - immUnbindProgram(); - - glDisable(GL_POLYGON_OFFSET_FILL); - } - else { - size1 = fac1 * head + (1.0f - fac1) * tail; - - /* 1 sphere in center */ - gpuTranslate3f(0.0f, 0.0f, (head + length - tail) / 2.0f); - - gpuScaleUniform(size1); - GWN_batch_draw(sphere); - } - - gpuPopMatrix(); -} - -static void draw_line_bone(int armflag, int boneflag, short constflag, unsigned int id, - bPoseChannel *pchan, EditBone *ebone) -{ - float length; - - if (pchan) - length = pchan->bone->length; - else - length = ebone->length; - - Gwn_VertFormat *format = immVertexFormat(); - unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - - gpuPushMatrix(); - gpuScaleUniform(length); - - /* this chunk not in object mode */ - if (armflag & (ARM_EDITMODE | ARM_POSEMODE)) { - glLineWidth(4.0f); - glPointSize(8.0f); - - if (armflag & ARM_POSEMODE) - set_pchan_color(PCHAN_COLOR_NORMAL, boneflag, constflag); - else if (armflag & ARM_EDITMODE) { - UI_GetThemeColor4fv(TH_WIRE_EDIT, fcolor); - } - - /* line */ - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - immUniformColor4fv(fcolor); - - if (id != -1) - GPU_select_load_id(id | BONESEL_BONE); - - immBegin(GWN_PRIM_LINES, 2); - immVertex3f(pos, 0.0f, 1.0f, 0.0f); - immVertex3f(pos, 0.0f, 0.0f, 0.0f); - immEnd(); - - immUnbindProgram(); - - immBindBuiltinProgram(GPU_SHADER_3D_POINT_FIXED_SIZE_UNIFORM_COLOR); - immUniformColor4fv(fcolor); - - /* Draw root point if we are not connected */ - if ((boneflag & BONE_CONNECTED) == 0) { - if (G.f & G_PICKSEL) - GPU_select_load_id(id | BONESEL_ROOT); - - immBegin(GWN_PRIM_POINTS, 1); - immVertex3f(pos, 0.0f, 0.0f, 0.0f); - immEnd(); - } - - /* tip */ - if (G.f & G_PICKSEL) - GPU_select_load_id(id | BONESEL_TIP); - - immBegin(GWN_PRIM_POINTS, 1); - immVertex3f(pos, 0.0f, 1.0f, 0.0f); - immEnd(); - - immUnbindProgram(); - - - /* further we send no names */ - if (id != -1) - GPU_select_load_id(id & 0xFFFF); /* object tag, for bordersel optim */ - - if (armflag & ARM_POSEMODE) - set_pchan_color(PCHAN_COLOR_LINEBONE, boneflag, constflag); - } - - /* Now draw the inner color */ - glLineWidth(2.0f); - glPointSize(5.0f); - - /* line */ - if (armflag & ARM_EDITMODE) { - if (boneflag & BONE_SELECTED) UI_GetThemeColor4fv(TH_EDGE_SELECT, fcolor); - else UI_GetThemeColorShade4fv(TH_BACK, -30, fcolor); - } - - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - immUniformColor4fv(fcolor); - - immBegin(GWN_PRIM_LINES, 2); - immVertex3f(pos, 0.0f, 1.0f, 0.0f); - immVertex3f(pos, 0.0f, 0.0f, 0.0f); - immEnd(); - - immUnbindProgram(); - - immBindBuiltinProgram(GPU_SHADER_3D_POINT_FIXED_SIZE_UNIFORM_COLOR); - - /*Draw root point if we are not connected */ - if ((boneflag & BONE_CONNECTED) == 0) { - if (armflag & ARM_EDITMODE) { - if (boneflag & BONE_ROOTSEL) UI_GetThemeColor4fv(TH_VERTEX_SELECT, fcolor); - else UI_GetThemeColor4fv(TH_VERTEX, fcolor); - } - immUniformColor4fv(fcolor); - immBegin(GWN_PRIM_POINTS, 1); - immVertex3f(pos, 0.0f, 0.0f, 0.0f); - immEnd(); - } - - /* tip */ - if ((G.f & G_PICKSEL) == 0) { - /* no bitmap in selection mode, crashes 3d cards... */ - if (armflag & ARM_EDITMODE) { - if (boneflag & BONE_TIPSEL) UI_GetThemeColor4fv(TH_VERTEX_SELECT, fcolor); - else UI_GetThemeColor4fv(TH_VERTEX, fcolor); - } - immUniformColor4fv(fcolor); - immBegin(GWN_PRIM_POINTS, 1); - immVertex3f(pos, 0.0f, 1.0f, 0.0f); - immEnd(); - } - - immUnbindProgram(); - - gpuPopMatrix(); -} - -/* A partial copy of b_bone_spline_setup(), with just the parts for previewing editmode curve settings - * - * This assumes that prev/next bones don't have any impact (since they should all still be in the "straight" - * position here anyway), and that we can simply apply the bbone settings to get the desired effect... - */ -static void ebone_spline_preview(EditBone *ebone, Mat4 result_array[MAX_BBONE_SUBDIV]) -{ - float h1[3], h2[3], length, hlength1, hlength2, roll1 = 0.0f, roll2 = 0.0f; - float mat3[3][3]; - float data[MAX_BBONE_SUBDIV + 1][4], *fp; - int a; - - length = ebone->length; - - hlength1 = ebone->ease1 * length * 0.390464f; /* 0.5f * sqrt(2) * kappa, the handle length for near-perfect circles */ - hlength2 = ebone->ease2 * length * 0.390464f; - - /* find the handle points, since this is inside bone space, the - * first point = (0, 0, 0) - * last point = (0, length, 0) - * - * we also just apply all the "extra effects", since they're the whole reason we're doing this... - */ - h1[0] = ebone->curveInX; - h1[1] = hlength1; - h1[2] = ebone->curveInY; - roll1 = ebone->roll1; - - h2[0] = ebone->curveOutX; - h2[1] = -hlength2; - h2[2] = ebone->curveOutY; - roll2 = ebone->roll2; - - /* make curve */ - if (ebone->segments > MAX_BBONE_SUBDIV) - ebone->segments = MAX_BBONE_SUBDIV; - - BKE_curve_forward_diff_bezier(0.0f, h1[0], h2[0], 0.0f, data[0], MAX_BBONE_SUBDIV, 4 * sizeof(float)); - BKE_curve_forward_diff_bezier(0.0f, h1[1], length + h2[1], length, data[0] + 1, MAX_BBONE_SUBDIV, 4 * sizeof(float)); - BKE_curve_forward_diff_bezier(0.0f, h1[2], h2[2], 0.0f, data[0] + 2, MAX_BBONE_SUBDIV, 4 * sizeof(float)); - BKE_curve_forward_diff_bezier(roll1, roll1 + 0.390464f * (roll2 - roll1), roll2 - 0.390464f * (roll2 - roll1), roll2, data[0] + 3, MAX_BBONE_SUBDIV, 4 * sizeof(float)); - - equalize_bbone_bezier(data[0], ebone->segments); /* note: does stride 4! */ - - /* make transformation matrices for the segments for drawing */ - for (a = 0, fp = data[0]; a < ebone->segments; a++, fp += 4) { - sub_v3_v3v3(h1, fp + 4, fp); - vec_roll_to_mat3(h1, fp[3], mat3); /* fp[3] is roll */ - - copy_m4_m3(result_array[a].mat, mat3); - copy_v3_v3(result_array[a].mat[3], fp); - - /* "extra" scale facs... */ - { - const int num_segments = ebone->segments; - - const float scaleFactorIn = 1.0f + (ebone->scaleIn - 1.0f) * ((float)(num_segments - a) / (float)num_segments); - const float scaleFactorOut = 1.0f + (ebone->scaleOut - 1.0f) * ((float)(a + 1) / (float)num_segments); - - const float scalefac = scaleFactorIn * scaleFactorOut; - float bscalemat[4][4], bscale[3]; - - bscale[0] = scalefac; - bscale[1] = 1.0f; - bscale[2] = scalefac; - - size_to_mat4(bscalemat, bscale); - - /* Note: don't multiply by inverse scale mat here, as it causes problems with scaling shearing and breaking segment chains */ - mul_m4_series(result_array[a].mat, result_array[a].mat, bscalemat); - } - } -} - -static void draw_b_bone_boxes(const short dt, bPoseChannel *pchan, EditBone *ebone, float xwidth, float length, float zwidth) -{ - int segments = 0; - - if (pchan) - segments = pchan->bone->segments; - else if (ebone) - segments = ebone->segments; - - if (segments > 1) { - float dlen = length / (float)segments; - Mat4 bbone[MAX_BBONE_SUBDIV]; - int a; - - if (pchan) { - b_bone_spline_setup(pchan, 0, bbone); - } - else if (ebone) { - ebone_spline_preview(ebone, bbone); - } - - for (a = 0; a < segments; a++) { - gpuPushMatrix(); - gpuMultMatrix(bbone[a].mat); - if (dt == OB_SOLID) drawsolidcube_size(xwidth, dlen, zwidth); - else drawcube_size(xwidth, dlen, zwidth); - gpuPopMatrix(); - } - } - else { - if (dt == OB_SOLID) drawsolidcube_size(xwidth, length, zwidth); - else drawcube_size(xwidth, length, zwidth); - } -} - -static void draw_b_bone(const short dt, int armflag, int boneflag, short constflag, unsigned int id, - bPoseChannel *pchan, EditBone *ebone) -{ - float xwidth, length, zwidth; - - if (pchan) { - xwidth = pchan->bone->xwidth; - length = pchan->bone->length; - zwidth = pchan->bone->zwidth; - } - else { - xwidth = ebone->xwidth; - length = ebone->length; - zwidth = ebone->zwidth; - } - - /* draw points only if... */ - if (armflag & ARM_EDITMODE) { - /* move to unitspace */ - gpuPushMatrix(); - gpuScaleUniform(length); - draw_bone_points(dt, armflag, boneflag, id); - gpuPopMatrix(); - length *= 0.95f; /* make vertices visible */ - } - - /* colors for modes */ - if (armflag & ARM_POSEMODE) { - if (dt <= OB_WIRE) - set_pchan_color(PCHAN_COLOR_NORMAL, boneflag, constflag); - else - set_pchan_color(PCHAN_COLOR_SOLID, boneflag, constflag); - } - else if (armflag & ARM_EDITMODE) { - if (dt == OB_WIRE) { - set_ebone_color(boneflag); - } - else { - UI_GetThemeColor4fv(TH_BONE_SOLID, fcolor); - } - } - - if (id != -1) { - GPU_select_load_id((GLuint) id | BONESEL_BONE); - } - - /* set up solid drawing */ - if (dt > OB_WIRE) { - if (armflag & ARM_POSEMODE) - set_pchan_color(PCHAN_COLOR_SOLID, boneflag, constflag); - else { - UI_GetThemeColor4fv(TH_BONE_SOLID, fcolor); - } - - flat_color = false; - draw_b_bone_boxes(OB_SOLID, pchan, ebone, xwidth, length, zwidth); - } - else { - /* wire */ - if (armflag & ARM_POSEMODE) { - if (constflag && ((G.f & G_PICKSEL) == 0)) { - /* set constraint colors */ - if (set_pchan_color(PCHAN_COLOR_CONSTS, boneflag, constflag)) { - glEnable(GL_BLEND); - - flat_color = true; - draw_b_bone_boxes(OB_SOLID, pchan, ebone, xwidth, length, zwidth); - - glDisable(GL_BLEND); - } - - /* restore colors */ - set_pchan_color(PCHAN_COLOR_NORMAL, boneflag, constflag); - } - } - - draw_b_bone_boxes(OB_WIRE, pchan, ebone, xwidth, length, zwidth); - } -} - -static void draw_wire_bone_segments(bPoseChannel *pchan, Mat4 *bbones, float length, int segments) -{ - Gwn_VertFormat *format = immVertexFormat(); - unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - immUniformColor4fv(fcolor); - - if ((segments > 1) && (pchan)) { - float dlen = length / (float)segments; - Mat4 *bbone = bbones; - int a; - - for (a = 0; a < segments; a++, bbone++) { - gpuPushMatrix(); - gpuMultMatrix(bbone->mat); - - immBegin(GWN_PRIM_LINES, 2); - immVertex3f(pos, 0.0f, 0.0f, 0.0f); - immVertex3f(pos, 0.0f, dlen, 0.0f); - immEnd(); - - gpuPopMatrix(); - } - } - else { - gpuPushMatrix(); - - immBegin(GWN_PRIM_LINES, 2); - immVertex3f(pos, 0.0f, 0.0f, 0.0f); - immVertex3f(pos, 0.0f, length, 0.0f); - immEnd(); - - gpuPopMatrix(); - } - - immUnbindProgram(); -} - -static void draw_wire_bone(const short dt, int armflag, int boneflag, short constflag, unsigned int id, - bPoseChannel *pchan, EditBone *ebone) -{ - Mat4 bbones_array[MAX_BBONE_SUBDIV]; - Mat4 *bbones = NULL; - int segments = 0; - float length; - - if (pchan) { - segments = pchan->bone->segments; - length = pchan->bone->length; - - if (segments > 1) { - b_bone_spline_setup(pchan, 0, bbones_array); - bbones = bbones_array; - } - } - else - length = ebone->length; - - /* draw points only if... */ - if (armflag & ARM_EDITMODE) { - /* move to unitspace */ - gpuPushMatrix(); - gpuScaleUniform(length); - flat_color = true; - draw_bone_points(dt, armflag, boneflag, id); - gpuPopMatrix(); - length *= 0.95f; /* make vertices visible */ - } - - /* this chunk not in object mode */ - if (armflag & (ARM_EDITMODE | ARM_POSEMODE)) { - if (id != -1) - GPU_select_load_id((GLuint) id | BONESEL_BONE); - - draw_wire_bone_segments(pchan, bbones, length, segments); - - /* further we send no names */ - if (id != -1) - GPU_select_load_id(id & 0xFFFF); /* object tag, for bordersel optim */ - } - - /* colors for modes */ - if (armflag & ARM_POSEMODE) { - set_pchan_color(PCHAN_COLOR_NORMAL, boneflag, constflag); - } - else if (armflag & ARM_EDITMODE) { - set_ebone_color(boneflag); - } - - /* draw normal */ - draw_wire_bone_segments(pchan, bbones, length, segments); -} - -static void draw_bone(const short dt, int armflag, int boneflag, short constflag, unsigned int id, float length) -{ - - /* Draw a 3d octahedral bone, we use normalized space based on length */ - gpuScaleUniform(length); - - /* set up solid drawing */ - if (dt > OB_WIRE) { - UI_GetThemeColor4fv(TH_BONE_SOLID, fcolor); - flat_color = false; - } - else - flat_color = true; - - /* colors for posemode */ - if (armflag & ARM_POSEMODE) { - if (dt <= OB_WIRE) - set_pchan_color(PCHAN_COLOR_NORMAL, boneflag, constflag); - else - set_pchan_color(PCHAN_COLOR_SOLID, boneflag, constflag); - } - - - draw_bone_points(dt, armflag, boneflag, id); - - /* now draw the bone itself */ - if (id != -1) { - GPU_select_load_id((GLuint) id | BONESEL_BONE); - } - - /* wire? */ - if (dt <= OB_WIRE) { - /* colors */ - if (armflag & ARM_EDITMODE) { - set_ebone_color(boneflag); - } - else if (armflag & ARM_POSEMODE) { - if (constflag && ((G.f & G_PICKSEL) == 0)) { - /* draw constraint colors */ - if (set_pchan_color(PCHAN_COLOR_CONSTS, boneflag, constflag)) { - glEnable(GL_BLEND); - - draw_bone_solid_octahedral(); - - glDisable(GL_BLEND); - } - - /* restore colors */ - set_pchan_color(PCHAN_COLOR_NORMAL, boneflag, constflag); - } - } - draw_bone_octahedral(); - } - else { - /* solid */ - if (armflag & ARM_POSEMODE) - set_pchan_color(PCHAN_COLOR_SOLID, boneflag, constflag); - else - UI_GetThemeColor4fv(TH_BONE_SOLID, fcolor); - - draw_bone_solid_octahedral(); - } -} - -static void draw_custom_bone( - struct Depsgraph *depsgraph, - Scene *scene, ViewLayer *view_layer, View3D *v3d, RegionView3D *rv3d, Object *ob, - const short dt, int armflag, int boneflag, unsigned int id, float length) -{ - if (ob == NULL) return; - - gpuScaleUniform(length); - - /* colors for posemode */ - if (armflag & ARM_POSEMODE) { - set_pchan_color(PCHAN_COLOR_NORMAL, boneflag, 0); - } - - if (id != -1) { - GPU_select_load_id((GLuint) id | BONESEL_BONE); - } - - draw_object_instance(depsgraph, scene, view_layer, v3d, rv3d, ob, dt, armflag & ARM_POSEMODE, fcolor); -} - - -static void pchan_draw_IK_root_lines(bPoseChannel *pchan, short only_temp) -{ - bConstraint *con; - bPoseChannel *parchan; - - const uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - - immBindBuiltinProgram(GPU_SHADER_3D_LINE_DASHED_UNIFORM_COLOR); - - float viewport_size[4]; - glGetFloatv(GL_VIEWPORT, viewport_size); - immUniform2f("viewport_size", viewport_size[2], viewport_size[3]); - - immUniform1i("num_colors", 0); /* "simple" mode */ - immUniformColor4fv(fcolor); - immUniform1f("dash_width", 6.0f); - immUniform1f("dash_factor", 0.5f); - - for (con = pchan->constraints.first; con; con = con->next) { - if (con->enforce == 0.0f) - continue; - - switch (con->type) { - case CONSTRAINT_TYPE_KINEMATIC: - { - bKinematicConstraint *data = (bKinematicConstraint *)con->data; - int segcount = 0; - float ik_tip[3]; - - /* if only_temp, only draw if it is a temporary ik-chain */ - if ((only_temp) && !(data->flag & CONSTRAINT_IK_TEMP)) - continue; - - /* exclude tip from chain? */ - if ((data->flag & CONSTRAINT_IK_TIP) == 0) - parchan = pchan->parent; - else - parchan = pchan; - - copy_v3_v3(ik_tip, parchan->pose_tail); - - /* Find the chain's root */ - while (parchan->parent) { - segcount++; - /* FIXME: revise the breaking conditions */ - if (segcount == data->rootbone || segcount > 255) break; /* 255 is weak */ - parchan = parchan->parent; - } - - if (parchan) { - immBegin(GWN_PRIM_LINES, 2); - immVertex3fv(shdr_pos, ik_tip); - immVertex3fv(shdr_pos, parchan->pose_head); - immEnd(); - } - - break; - } - case CONSTRAINT_TYPE_SPLINEIK: - { - bSplineIKConstraint *data = (bSplineIKConstraint *)con->data; - int segcount = 0; - float ik_tip[3]; - - parchan = pchan; - copy_v3_v3(ik_tip, parchan->pose_tail); - - /* Find the chain's root */ - while (parchan->parent) { - segcount++; - /* FIXME: revise the breaking conditions */ - if (segcount == data->chainlen || segcount > 255) break; /* 255 is weak */ - parchan = parchan->parent; - } - /* Only draw line in case our chain is more than one bone long! */ - if (parchan != pchan) { /* XXX revise the breaking conditions to only stop at the tail? */ - immBegin(GWN_PRIM_LINES, 2); - immVertex3fv(shdr_pos, ik_tip); - immVertex3fv(shdr_pos, parchan->pose_head); - immEnd(); - } - break; - } - } - } - - immUnbindProgram(); -} - -static void imm_sphere_project(unsigned int pos, float ax, float az) -{ - float dir[3], sine, q3; - - sine = 1.0f - ax * ax - az * az; - q3 = (sine < 0.0f) ? 0.0f : (2.0f * sqrtf(sine)); - - dir[0] = -az * q3; - dir[1] = 1.0f - 2.0f * sine; - dir[2] = ax * q3; - - immVertex3fv(pos, dir); -} - -static void draw_dof_ellipse(unsigned int pos, float ax, float az) -{ - const int n = 16; - const int tri = n * n - 2 * n + 1; /* Yay fancy math ! */ - const float staticSine[16] = { - 0.0f, 0.104528463268f, 0.207911690818f, 0.309016994375f, - 0.406736643076f, 0.5f, 0.587785252292f, 0.669130606359f, - 0.743144825477f, 0.809016994375f, 0.866025403784f, - 0.913545457643f, 0.951056516295f, 0.978147600734f, - 0.994521895368f, 1.0f - }; - - int i, j; - float x, z, px, pz; - - glEnable(GL_BLEND); - glDepthMask(0); - - immUniformColor4ub(70, 70, 70, 50); - - immBegin(GWN_PRIM_TRIS, tri * 3); - pz = 0.0f; - for (i = 1; i < n; i++) { - z = staticSine[i]; - - px = 0.0f; - for (j = 1; j <= (n - i); j++) { - x = staticSine[j]; - - if (j == n - i) { - imm_sphere_project(pos, ax * px, az * z); - imm_sphere_project(pos, ax * px, az * pz); - imm_sphere_project(pos, ax * x, az * pz); - } - else { - imm_sphere_project(pos, ax * x, az * z); - imm_sphere_project(pos, ax * x, az * pz); - imm_sphere_project(pos, ax * px, az * pz); - - imm_sphere_project(pos, ax * px, az * pz); - imm_sphere_project(pos, ax * px, az * z); - imm_sphere_project(pos, ax * x, az * z); - } - - px = x; - } - pz = z; - } - immEnd(); - - glDisable(GL_BLEND); - glDepthMask(1); - - immUniformColor3ub(0, 0, 0); - - immBegin(GWN_PRIM_LINE_STRIP, n); - for (i = 0; i < n; i++) - imm_sphere_project(pos, staticSine[n - i - 1] * ax, staticSine[i] * az); - immEnd(); -} - -static void draw_pose_dofs(Object *ob) -{ - bArmature *arm = ob->data; - bPoseChannel *pchan; - Bone *bone; - - Gwn_VertFormat *format = immVertexFormat(); - unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - - for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { - bone = pchan->bone; - - if ((bone != NULL) && !(bone->flag & (BONE_HIDDEN_P | BONE_HIDDEN_PG))) { - if (bone->flag & BONE_SELECTED) { - if (bone->layer & arm->layer) { - if (pchan->ikflag & (BONE_IK_XLIMIT | BONE_IK_ZLIMIT)) { - if (BKE_pose_channel_in_IK_chain(ob, pchan)) { - float corner[4][3], posetrans[3], mat[4][4]; - float phi = 0.0f, theta = 0.0f, scale; - int a, i; - - /* in parent-bone pose, but own restspace */ - gpuPushMatrix(); - - copy_v3_v3(posetrans, pchan->pose_mat[3]); - gpuTranslate3fv(posetrans); - - if (pchan->parent) { - copy_m4_m4(mat, pchan->parent->pose_mat); - mat[3][0] = mat[3][1] = mat[3][2] = 0.0f; - gpuMultMatrix(mat); - } - - copy_m4_m3(mat, pchan->bone->bone_mat); - gpuMultMatrix(mat); - - scale = bone->length * pchan->size[1]; - gpuScaleUniform(scale); - - if (((pchan->ikflag & BONE_IK_XLIMIT) != 0) && - ((pchan->ikflag & BONE_IK_ZLIMIT) != 0)) - { - float amin[3], amax[3]; - - for (i = 0; i < 3; i++) { - /* *0.5f here comes from M_PI/360.0f when rotations were still in degrees */ - amin[i] = sinf(pchan->limitmin[i] * 0.5f); - amax[i] = sinf(pchan->limitmax[i] * 0.5f); - } - - gpuScale3f(1.0f, -1.0f, 1.0f); - if ((amin[0] != 0.0f) && (amin[2] != 0.0f)) - draw_dof_ellipse(pos, amin[0], amin[2]); - if ((amin[0] != 0.0f) && (amax[2] != 0.0f)) - draw_dof_ellipse(pos, amin[0], amax[2]); - if ((amax[0] != 0.0f) && (amin[2] != 0.0f)) - draw_dof_ellipse(pos, amax[0], amin[2]); - if ((amax[0] != 0.0f) && (amax[2] != 0.0f)) - draw_dof_ellipse(pos, amax[0], amax[2]); - gpuScale3f(1.0f, -1.0f, 1.0f); /* XXX same as above, is this intentional? */ - } - - /* arcs */ - if (pchan->ikflag & BONE_IK_ZLIMIT) { - /* OpenGL requires rotations in degrees; so we're taking the average angle here */ - theta = RAD2DEGF(0.5f * (pchan->limitmin[2] + pchan->limitmax[2])); - gpuPushMatrix(); - gpuRotateAxis(theta, 'Z'); - - immUniformColor3ub(50, 50, 255); /* blue, Z axis limit */ - immBegin(GWN_PRIM_LINE_STRIP, 33); - for (a = -16; a <= 16; a++) { - /* *0.5f here comes from M_PI/360.0f when rotations were still in degrees */ - float fac = ((float)a) / 16.0f * 0.5f; - - phi = fac * (pchan->limitmax[2] - pchan->limitmin[2]); - - i = (a == -16) ? 0 : 1; - corner[i][0] = sinf(phi); - corner[i][1] = cosf(phi); - corner[i][2] = 0.0f; - immVertex3fv(pos, corner[i]); - } - immEnd(); - - gpuPopMatrix(); - } - - if (pchan->ikflag & BONE_IK_XLIMIT) { - /* OpenGL requires rotations in degrees; so we're taking the average angle here */ - theta = RAD2DEGF(0.5f * (pchan->limitmin[0] + pchan->limitmax[0])); - gpuPushMatrix(); - gpuRotateAxis(theta, 'X'); - - immUniformColor3ub(255, 50, 50); /* Red, X axis limit */ - immBegin(GWN_PRIM_LINE_STRIP, 33); - for (a = -16; a <= 16; a++) { - /* *0.5f here comes from M_PI/360.0f when rotations were still in degrees */ - float fac = ((float)a) / 16.0f * 0.5f; - phi = (float)M_PI_2 + fac * (pchan->limitmax[0] - pchan->limitmin[0]); - - i = (a == -16) ? 2 : 3; - corner[i][0] = 0.0f; - corner[i][1] = sinf(phi); - corner[i][2] = cosf(phi); - immVertex3fv(pos, corner[i]); - } - immEnd(); - - gpuPopMatrix(); - } - - /* out of cone, out of bone */ - gpuPopMatrix(); - } - } - } - } - } - } - - immUnbindProgram(); -} - -static void bone_matrix_translate_y(float mat[4][4], float y) -{ - float trans[3]; - - copy_v3_v3(trans, mat[1]); - mul_v3_fl(trans, y); - add_v3_v3(mat[3], trans); -} - -/* assumes object is Armature with pose */ -static void draw_pose_bones( - struct Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer, View3D *v3d, ARegion *ar, Base *base, - const short dt, const unsigned char ob_wire_col[4], - const bool do_const_color, const bool is_outline) -{ - RegionView3D *rv3d = ar->regiondata; - Object *ob = base->object; - bArmature *arm = ob->data; - bPoseChannel *pchan; - Bone *bone; - float smat[4][4], imat[4][4], bmat[4][4]; - int index = -1; - const enum { - DASH_RELATIONSHIP_LINES = 1, - DASH_HELP_LINES = 2, - } do_dashed = ( - (is_outline ? 0 : DASH_RELATIONSHIP_LINES) | - ((v3d->flag & V3D_HIDE_HELPLINES) ? 0 : DASH_HELP_LINES)); - bool draw_wire = false; - int flag; - bool is_cull_enabled; - - /* being set below */ - arm->layer_used = 0; - - rgba_uchar_to_float(fcolor, ob_wire_col); - - /* precalc inverse matrix for drawing screen aligned */ - if (arm->drawtype == ARM_ENVELOPE) { - /* precalc inverse matrix for drawing screen aligned */ - copy_m4_m4(smat, rv3d->viewmatob); - mul_mat3_m4_fl(smat, 1.0f / len_v3(ob->obmat[0])); - invert_m4_m4(imat, smat); - - /* and draw blended distances */ - if (arm->flag & ARM_POSEMODE) { - glEnable(GL_BLEND); - - if (v3d->zbuf) glDisable(GL_DEPTH_TEST); - - for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { - bone = pchan->bone; - if (bone) { - /* 1) bone must be visible, 2) for OpenGL select-drawing cannot have unselectable [#27194] - * NOTE: this is the only case with (NO_DEFORM == 0) flag, as this is for envelope influence drawing - */ - if (((bone->flag & (BONE_HIDDEN_P | BONE_NO_DEFORM | BONE_HIDDEN_PG)) == 0) && - ((G.f & G_PICKSEL) == 0 || (bone->flag & BONE_UNSELECTABLE) == 0)) - { - if (bone->flag & (BONE_SELECTED)) { - if (bone->layer & arm->layer) - draw_sphere_bone_dist(smat, imat, pchan, NULL); - } - } - } - } - - if (v3d->zbuf) glEnable(GL_DEPTH_TEST); - glDisable(GL_BLEND); - } - } - - /* little speedup, also make sure transparent only draws once */ - glCullFace(GL_BACK); - if (v3d->flag2 & V3D_BACKFACE_CULLING) { - glEnable(GL_CULL_FACE); - is_cull_enabled = true; - } - else { - is_cull_enabled = false; - } - - /* if solid we draw that first, with selection codes, but without names, axes etc */ - if (dt > OB_WIRE) { - if (arm->flag & ARM_POSEMODE) - index = base->object->select_color; - - for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { - bone = pchan->bone; - arm->layer_used |= bone->layer; - - /* 1) bone must be visible, 2) for OpenGL select-drawing cannot have unselectable [#27194] */ - if (((bone->flag & (BONE_HIDDEN_P | BONE_HIDDEN_PG)) == 0) && - ((G.f & G_PICKSEL) == 0 || (bone->flag & BONE_UNSELECTABLE) == 0)) - { - if (bone->layer & arm->layer) { - const bool use_custom = (pchan->custom) && !(arm->flag & ARM_NO_CUSTOM); - gpuPushMatrix(); - - if (use_custom && pchan->custom_tx) { - gpuMultMatrix(pchan->custom_tx->pose_mat); - } - else { - gpuMultMatrix(pchan->pose_mat); - } - - /* catch exception for bone with hidden parent */ - flag = bone->flag; - if ((bone->parent) && (bone->parent->flag & (BONE_HIDDEN_P | BONE_HIDDEN_PG))) { - flag &= ~BONE_CONNECTED; - } - - /* set temporary flag for drawing bone as active, but only if selected */ - if (bone == arm->act_bone) - flag |= BONE_DRAW_ACTIVE; - - if (do_const_color) { - /* keep color */ - } - else { - /* set color-set to use */ - set_pchan_colorset(ob, pchan); - } - - /* may be 2x width from custom bone's outline option */ - glLineWidth(1.0f); - - if (use_custom) { - /* if drawwire, don't try to draw in solid */ - if (pchan->bone->flag & BONE_DRAWWIRE) { - draw_wire = true; - } - else { - if (is_cull_enabled && (v3d->flag2 & V3D_BACKFACE_CULLING) == 0) { - is_cull_enabled = false; - glDisable(GL_CULL_FACE); - } - - draw_custom_bone(depsgraph, scene, view_layer, v3d, rv3d, pchan->custom, - OB_SOLID, arm->flag, flag, index, PCHAN_CUSTOM_DRAW_SIZE(pchan)); - } - } - else { - if (is_cull_enabled == false) { - is_cull_enabled = true; - glEnable(GL_CULL_FACE); - } - - if (arm->drawtype == ARM_LINE) { - /* nothing in solid */ - } - else if (arm->drawtype == ARM_WIRE) { - /* nothing in solid */ - } - else if (arm->drawtype == ARM_ENVELOPE) { - draw_sphere_bone(OB_SOLID, arm->flag, flag, 0, index, pchan, NULL); - } - else if (arm->drawtype == ARM_B_BONE) { - draw_b_bone(OB_SOLID, arm->flag, flag, 0, index, pchan, NULL); - } - else { - draw_bone(OB_SOLID, arm->flag, flag, 0, index, bone->length); - } - } - - gpuPopMatrix(); - } - } - - if (index != -1) - index += 0x10000; /* pose bones count in higher 2 bytes only */ - } - - /* very very confusing... but in object mode, solid draw, we cannot do GPU_select_load_id yet, - * stick bones and/or wire custom-shapes are drawn in next loop - */ - if (ELEM(arm->drawtype, ARM_LINE, ARM_WIRE) == 0 && (draw_wire == false) && index != -1) { - /* object tag, for bordersel optim */ - GPU_select_load_id(index & 0xFFFF); - index = -1; - } - } - - /* custom bone may draw outline double-width */ - if (arm->flag & ARM_POSEMODE) { - glLineWidth(1.0f); - } - - /* draw custom bone shapes as wireframes */ - if (!(arm->flag & ARM_NO_CUSTOM) && - (draw_wire || (dt <= OB_WIRE)) ) - { - if (arm->flag & ARM_POSEMODE) - index = base->object->select_color; - - /* only draw custom bone shapes that need to be drawn as wires */ - for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { - bone = pchan->bone; - - /* 1) bone must be visible, 2) for OpenGL select-drawing cannot have unselectable [#27194] */ - if (((bone->flag & (BONE_HIDDEN_P | BONE_HIDDEN_PG)) == 0) && - ((G.f & G_PICKSEL) == 0 || (bone->flag & BONE_UNSELECTABLE) == 0) ) - { - if (bone->layer & arm->layer) { - if (pchan->custom) { - if ((dt < OB_SOLID) || (bone->flag & BONE_DRAWWIRE)) { - gpuPushMatrix(); - - if (pchan->custom_tx) { - gpuMultMatrix(pchan->custom_tx->pose_mat); - } - else { - gpuMultMatrix(pchan->pose_mat); - } - - /* prepare colors */ - if (do_const_color) { - /* 13 October 2009, Disabled this to make ghosting show the right colors (Aligorith) */ - } - else if (arm->flag & ARM_POSEMODE) - set_pchan_colorset(ob, pchan); - else { - rgba_uchar_to_float(fcolor, ob_wire_col); - } - - /* catch exception for bone with hidden parent */ - flag = bone->flag; - if ((bone->parent) && (bone->parent->flag & (BONE_HIDDEN_P | BONE_HIDDEN_PG))) - flag &= ~BONE_CONNECTED; - - /* set temporary flag for drawing bone as active, but only if selected */ - if (bone == arm->act_bone) - flag |= BONE_DRAW_ACTIVE; - - draw_custom_bone(depsgraph, scene, view_layer, v3d, rv3d, pchan->custom, - OB_WIRE, arm->flag, flag, index, PCHAN_CUSTOM_DRAW_SIZE(pchan)); - - gpuPopMatrix(); - } - } - } - } - - if (index != -1) - index += 0x10000; /* pose bones count in higher 2 bytes only */ - } - /* stick or wire bones have not been drawn yet so don't clear object selection in this case */ - if (ELEM(arm->drawtype, ARM_LINE, ARM_WIRE) == 0 && draw_wire && index != -1) { - /* object tag, for bordersel optim */ - GPU_select_load_id(index & 0xFFFF); - index = -1; - } - } - - /* wire draw over solid only in posemode */ - if ((dt <= OB_WIRE) || (arm->flag & ARM_POSEMODE) || ELEM(arm->drawtype, ARM_LINE, ARM_WIRE)) { - /* draw line check first. we do selection indices */ - if (ELEM(arm->drawtype, ARM_LINE, ARM_WIRE)) { - if (arm->flag & ARM_POSEMODE) - index = base->object->select_color; - } - /* if solid && posemode, we draw again with polygonoffset */ - else if ((dt > OB_WIRE) && (arm->flag & ARM_POSEMODE)) { - ED_view3d_polygon_offset(rv3d, 1.0); - } - else { - /* and we use selection indices if not done yet */ - if (arm->flag & ARM_POSEMODE) - index = base->object->select_color; - } - - if (is_cull_enabled == false) { - is_cull_enabled = true; - glEnable(GL_CULL_FACE); - } - - for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { - bone = pchan->bone; - arm->layer_used |= bone->layer; - - /* 1) bone must be visible, 2) for OpenGL select-drawing cannot have unselectable [#27194] */ - if (((bone->flag & (BONE_HIDDEN_P | BONE_HIDDEN_PG)) == 0) && - ((G.f & G_PICKSEL) == 0 || (bone->flag & BONE_UNSELECTABLE) == 0)) - { - if (bone->layer & arm->layer) { - const short constflag = pchan->constflag; - if ((do_dashed & DASH_RELATIONSHIP_LINES) && (pchan->parent)) { - /* Draw a line from our root to the parent's tip - * - only if V3D_HIDE_HELPLINES is enabled... - */ - if ((do_dashed & DASH_HELP_LINES) && ((bone->flag & BONE_CONNECTED) == 0)) { - const uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - - immBindBuiltinProgram(GPU_SHADER_3D_LINE_DASHED_UNIFORM_COLOR); - - float viewport_size[4]; - glGetFloatv(GL_VIEWPORT, viewport_size); - immUniform2f("viewport_size", viewport_size[2], viewport_size[3]); - - immUniform1i("num_colors", 0); /* "simple" mode */ - immUniformColor4fv(fcolor); - immUniform1f("dash_width", 6.0f); - immUniform1f("dash_factor", 0.5f); - - if (arm->flag & ARM_POSEMODE) { - GPU_select_load_id(index & 0xFFFF); /* object tag, for bordersel optim */ - immUniformThemeColor(TH_WIRE); - } - - immBegin(GWN_PRIM_LINES, 2); - immVertex3fv(shdr_pos, pchan->parent->pose_tail); - immVertex3fv(shdr_pos, pchan->pose_head); - immEnd(); - - immUnbindProgram(); - } - - /* Draw a line to IK root bone - * - only if temporary chain (i.e. "autoik") - */ - if (arm->flag & ARM_POSEMODE) { - if (constflag & PCHAN_HAS_IK) { - if (bone->flag & BONE_SELECTED) { - if (constflag & PCHAN_HAS_TARGET) { - rgba_float_args_set(fcolor, 200.f / 255.f, 120.f / 255.f, 0.f / 255.f, 1.0f); - } - /* add theme! */ - else rgba_float_args_set(fcolor, 200.f / 255.f, 200.f / 255.f, 50.f / 255.f, 1.0f); - - GPU_select_load_id(index & 0xFFFF); - pchan_draw_IK_root_lines(pchan, !(do_dashed & DASH_HELP_LINES)); - } - } - else if (constflag & PCHAN_HAS_SPLINEIK) { - if (bone->flag & BONE_SELECTED) { - /* add theme! */ - rgba_float_args_set(fcolor, 150.f / 255.f, 200.f / 255.f, 50.f / 255.f, 1.0f); - - GPU_select_load_id(index & 0xFFFF); - pchan_draw_IK_root_lines(pchan, !(do_dashed & DASH_HELP_LINES)); - } - } - } - } - - gpuPushMatrix(); - if (arm->drawtype != ARM_ENVELOPE) - gpuMultMatrix(pchan->pose_mat); - - /* catch exception for bone with hidden parent */ - flag = bone->flag; - if ((bone->parent) && (bone->parent->flag & (BONE_HIDDEN_P | BONE_HIDDEN_PG))) - flag &= ~BONE_CONNECTED; - - /* set temporary flag for drawing bone as active, but only if selected */ - if (bone == arm->act_bone) - flag |= BONE_DRAW_ACTIVE; - - /* extra draw service for pose mode */ - - /* set color-set to use */ - if (do_const_color) { - /* keep color */ - } - else { - set_pchan_colorset(ob, pchan); - } - - if ((pchan->custom) && !(arm->flag & ARM_NO_CUSTOM)) { - /* custom bone shapes should not be drawn here! */ - } - else if (arm->drawtype == ARM_ENVELOPE) { - if (dt < OB_SOLID) - draw_sphere_bone_wire(smat, imat, arm->flag, flag, constflag, index, pchan, NULL); - } - else if (arm->drawtype == ARM_LINE) - draw_line_bone(arm->flag, flag, constflag, index, pchan, NULL); - else if (arm->drawtype == ARM_WIRE) - draw_wire_bone(dt, arm->flag, flag, constflag, index, pchan, NULL); - else if (arm->drawtype == ARM_B_BONE) - draw_b_bone(OB_WIRE, arm->flag, flag, constflag, index, pchan, NULL); - else - draw_bone(OB_WIRE, arm->flag, flag, constflag, index, bone->length); - - gpuPopMatrix(); - } - } - - /* pose bones count in higher 2 bytes only */ - if (index != -1) - index += 0x10000; - } - /* restore things */ - if (!ELEM(arm->drawtype, ARM_WIRE, ARM_LINE) && (dt > OB_WIRE) && (arm->flag & ARM_POSEMODE)) - ED_view3d_polygon_offset(rv3d, 0.0); - } - - /* restore */ - if (is_cull_enabled) { - glDisable(GL_CULL_FACE); - } - - /* draw DoFs */ - if (arm->flag & ARM_POSEMODE) { - if (((base->flag_legacy & OB_FROMDUPLI) == 0) && ((v3d->flag & V3D_HIDE_HELPLINES) == 0)) { - draw_pose_dofs(ob); - } - } - - /* finally names and axes */ - if ((arm->flag & (ARM_DRAWNAMES | ARM_DRAWAXES)) && - (is_outline == 0) && - ((base->flag_legacy & OB_FROMDUPLI) == 0)) - { - /* patch for several 3d cards (IBM mostly) that crash on GL_SELECT with text drawing */ - if ((G.f & G_PICKSEL) == 0) { - float vec[3]; - - unsigned char col[4]; - col[0] = ob_wire_col[0]; - col[1] = ob_wire_col[1]; - col[2] = ob_wire_col[2]; - col[3] = 255; - - if (v3d->zbuf) glDisable(GL_DEPTH_TEST); - - for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { - if ((pchan->bone->flag & (BONE_HIDDEN_P | BONE_HIDDEN_PG)) == 0) { - if (pchan->bone->layer & arm->layer) { - if (arm->flag & (ARM_EDITMODE | ARM_POSEMODE)) { - bone = pchan->bone; - UI_GetThemeColor3ubv((bone->flag & BONE_SELECTED) ? TH_TEXT_HI : TH_TEXT, col); - } - else if (dt > OB_WIRE) { - UI_GetThemeColor3ubv(TH_TEXT, col); - } - - /* Draw names of bone */ - if (arm->flag & ARM_DRAWNAMES) { - mid_v3_v3v3(vec, pchan->pose_head, pchan->pose_tail); - view3d_cached_text_draw_add(vec, pchan->name, strlen(pchan->name), 10, 0, col); - } - - /* Draw additional axes on the bone tail */ - if ((arm->flag & ARM_DRAWAXES) && (arm->flag & ARM_POSEMODE)) { - gpuPushMatrix(); - copy_m4_m4(bmat, pchan->pose_mat); - bone_matrix_translate_y(bmat, pchan->bone->length); - gpuMultMatrix(bmat); - - float viewmat_pchan[4][4]; - mul_m4_m4m4(viewmat_pchan, rv3d->viewmatob, bmat); - drawaxes(viewmat_pchan, pchan->bone->length * 0.25f, OB_ARROWS, col); - - gpuPopMatrix(); - } - } - } - } - - if (v3d->zbuf) glEnable(GL_DEPTH_TEST); - } - } - - if (index != -1) { - GPU_select_load_id(-1); - } -} - -/* in editmode, we don't store the bone matrix... */ -static void get_matrix_editbone(EditBone *ebone, float bmat[4][4]) -{ - ebone->length = len_v3v3(ebone->tail, ebone->head); - ED_armature_ebone_to_mat4(ebone, bmat); -} - -static void draw_ebones(View3D *v3d, ARegion *ar, Object *ob, const short dt) -{ - RegionView3D *rv3d = ar->regiondata; - EditBone *eBone; - bArmature *arm = ob->data; - float smat[4][4], imat[4][4], bmat[4][4]; - unsigned int index; - int flag; - - /* being set in code below */ - arm->layer_used = 0; - - ED_view3d_check_mats_rv3d(rv3d); - - /* envelope (deform distance) */ - if (arm->drawtype == ARM_ENVELOPE) { - /* precalc inverse matrix for drawing screen aligned */ - copy_m4_m4(smat, rv3d->viewmatob); - mul_mat3_m4_fl(smat, 1.0f / len_v3(ob->obmat[0])); - invert_m4_m4(imat, smat); - - /* and draw blended distances */ - glEnable(GL_BLEND); - - if (v3d->zbuf) glDisable(GL_DEPTH_TEST); - - for (eBone = arm->edbo->first; eBone; eBone = eBone->next) { - if (eBone->layer & arm->layer) { - if ((eBone->flag & (BONE_HIDDEN_A | BONE_NO_DEFORM)) == 0) { - if (eBone->flag & (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL)) - draw_sphere_bone_dist(smat, imat, NULL, eBone); - } - } - } - - if (v3d->zbuf) glEnable(GL_DEPTH_TEST); - glDisable(GL_BLEND); - } - - /* if solid we draw it first */ - if ((dt > OB_WIRE) && (arm->drawtype != ARM_LINE)) { - for (eBone = arm->edbo->first, index = 0; eBone; eBone = eBone->next, index++) { - if (eBone->layer & arm->layer) { - if ((eBone->flag & BONE_HIDDEN_A) == 0) { - gpuPushMatrix(); - get_matrix_editbone(eBone, bmat); - gpuMultMatrix(bmat); - - /* catch exception for bone with hidden parent */ - flag = eBone->flag; - if ((eBone->parent) && !EBONE_VISIBLE(arm, eBone->parent)) { - flag &= ~BONE_CONNECTED; - } - - /* set temporary flag for drawing bone as active, but only if selected */ - if (eBone == arm->act_edbone) - flag |= BONE_DRAW_ACTIVE; - - if (arm->drawtype == ARM_ENVELOPE) - draw_sphere_bone(OB_SOLID, arm->flag, flag, 0, index, NULL, eBone); - else if (arm->drawtype == ARM_B_BONE) - draw_b_bone(OB_SOLID, arm->flag, flag, 0, index, NULL, eBone); - else if (arm->drawtype == ARM_WIRE) - draw_wire_bone(OB_SOLID, arm->flag, flag, 0, index, NULL, eBone); - else { - draw_bone(OB_SOLID, arm->flag, flag, 0, index, eBone->length); - } - - gpuPopMatrix(); - } - } - } - } - - /* if wire over solid, set offset */ - index = -1; - GPU_select_load_id(-1); - if (ELEM(arm->drawtype, ARM_LINE, ARM_WIRE)) { - if (G.f & G_PICKSEL) - index = 0; - } - else if (dt > OB_WIRE) - ED_view3d_polygon_offset(rv3d, 1.0); - else if (arm->flag & ARM_EDITMODE) - index = 0; /* do selection codes */ - - for (eBone = arm->edbo->first; eBone; eBone = eBone->next) { - arm->layer_used |= eBone->layer; - if (eBone->layer & arm->layer) { - if ((eBone->flag & BONE_HIDDEN_A) == 0) { - - /* catch exception for bone with hidden parent */ - flag = eBone->flag; - if ((eBone->parent) && !EBONE_VISIBLE(arm, eBone->parent)) { - flag &= ~BONE_CONNECTED; - } - - /* set temporary flag for drawing bone as active, but only if selected */ - if (eBone == arm->act_edbone) - flag |= BONE_DRAW_ACTIVE; - - if (arm->drawtype == ARM_ENVELOPE) { - if (dt < OB_SOLID) - draw_sphere_bone_wire(smat, imat, arm->flag, flag, 0, index, NULL, eBone); - } - else { - gpuPushMatrix(); - get_matrix_editbone(eBone, bmat); - gpuMultMatrix(bmat); - - if (arm->drawtype == ARM_LINE) - draw_line_bone(arm->flag, flag, 0, index, NULL, eBone); - else if (arm->drawtype == ARM_WIRE) - draw_wire_bone(OB_WIRE, arm->flag, flag, 0, index, NULL, eBone); - else if (arm->drawtype == ARM_B_BONE) - draw_b_bone(OB_WIRE, arm->flag, flag, 0, index, NULL, eBone); - else - draw_bone(OB_WIRE, arm->flag, flag, 0, index, eBone->length); - - gpuPopMatrix(); - } - - /* offset to parent */ - if (eBone->parent) { - const uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - - GPU_select_load_id(-1); /* -1 here is OK! */ - - immBindBuiltinProgram(GPU_SHADER_3D_LINE_DASHED_UNIFORM_COLOR); - - float viewport_size[4]; - glGetFloatv(GL_VIEWPORT, viewport_size); - immUniform2f("viewport_size", viewport_size[2], viewport_size[3]); - - immUniform1i("num_colors", 0); /* "simple" mode */ - immUniformThemeColor(TH_WIRE_EDIT); - immUniform1f("dash_width", 6.0f); - immUniform1f("dash_factor", 0.5f); - - immBegin(GWN_PRIM_LINES, 2); - immVertex3fv(shdr_pos, eBone->parent->tail); - immVertex3fv(shdr_pos, eBone->head); - immEnd(); - - immUnbindProgram(); - } - } - } - if (index != -1) index++; - } - - /* restore */ - if (index != -1) { - GPU_select_load_id(-1); - } - - if (ELEM(arm->drawtype, ARM_LINE, ARM_WIRE)) { - /* pass */ - } - else if (dt > OB_WIRE) { - ED_view3d_polygon_offset(rv3d, 0.0); - } - - /* finally names and axes */ - if (arm->flag & (ARM_DRAWNAMES | ARM_DRAWAXES)) { - /* patch for several 3d cards (IBM mostly) that crash on GL_SELECT with text drawing */ - if ((G.f & G_PICKSEL) == 0) { - float vec[3]; - unsigned char col[4]; - col[3] = 255; - - if (v3d->zbuf) glDisable(GL_DEPTH_TEST); - - for (eBone = arm->edbo->first; eBone; eBone = eBone->next) { - if (eBone->layer & arm->layer) { - if ((eBone->flag & BONE_HIDDEN_A) == 0) { - - UI_GetThemeColor3ubv((eBone->flag & BONE_SELECTED) ? TH_TEXT_HI : TH_TEXT, col); - - /* Draw name */ - if (arm->flag & ARM_DRAWNAMES) { - mid_v3_v3v3(vec, eBone->head, eBone->tail); - view3d_cached_text_draw_add(vec, eBone->name, strlen(eBone->name), 10, 0, col); - } - /* Draw additional axes */ - if (arm->flag & ARM_DRAWAXES) { - gpuPushMatrix(); - get_matrix_editbone(eBone, bmat); - bone_matrix_translate_y(bmat, eBone->length); - gpuMultMatrix(bmat); - - float viewmat_ebone[4][4]; - mul_m4_m4m4(viewmat_ebone, rv3d->viewmatob, bmat); - drawaxes(viewmat_ebone, eBone->length * 0.25f, OB_ARROWS, col); - - gpuPopMatrix(); - } - - } - } - } - - if (v3d->zbuf) glEnable(GL_DEPTH_TEST); - } - } -} - -/* ****************************** Armature Visualization ******************************** */ - -/* ---------- Paths --------- */ - -/* draw bone paths - * - in view space - */ -static void draw_pose_paths(Scene *scene, View3D *v3d, ARegion *ar, Object *ob) -{ - bAnimVizSettings *avs = &ob->pose->avs; - bArmature *arm = ob->data; - bPoseChannel *pchan; - - /* setup drawing environment for paths */ - draw_motion_paths_init(v3d, ar); - - /* draw paths where they exist and they releated bone is visible */ - for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { - if ((pchan->bone->layer & arm->layer) && (pchan->mpath)) - draw_motion_path_instance(scene, ob, pchan, avs, pchan->mpath); - } - - /* cleanup after drawing */ - draw_motion_paths_cleanup(v3d); -} - - -/* ---------- Ghosts --------- */ - -/* helper function for ghost drawing - sets/removes flags for temporarily - * hiding unselected bones while drawing ghosts - */ -static void ghost_poses_tag_unselected(Object *ob, short unset) -{ - bArmature *arm = ob->data; - bPose *pose = ob->pose; - bPoseChannel *pchan; - - /* don't do anything if no hiding any bones */ - if ((arm->flag & ARM_GHOST_ONLYSEL) == 0) - return; - - /* loop over all pchans, adding/removing tags as appropriate */ - for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) { - if ((pchan->bone) && (arm->layer & pchan->bone->layer)) { - if (unset) { - /* remove tags from all pchans if cleaning up */ - pchan->bone->flag &= ~BONE_HIDDEN_PG; - } - else { - /* set tags on unselected pchans only */ - if ((pchan->bone->flag & BONE_SELECTED) == 0) - pchan->bone->flag |= BONE_HIDDEN_PG; - } - } - } -} - -/* draw ghosts that occur within a frame range - * note: object should be in posemode - */ -static void draw_ghost_poses_range( - Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer, View3D *v3d, ARegion *ar, Base *base) -{ - Object *ob = base->object; - AnimData *adt = BKE_animdata_from_id(&ob->id); - bArmature *arm = ob->data; - bPose *posen, *poseo; - float start, end, stepsize, range, colfac; - int cfrao, flago; - unsigned char col[4]; - - start = (float)arm->ghostsf; - end = (float)arm->ghostef; - if (end <= start) - return; - - /* prevent infinite loops if this is set to 0 - T49527 */ - if (arm->ghostsize < 1) - arm->ghostsize = 1; - - stepsize = (float)(arm->ghostsize); - range = (float)(end - start); - - /* store values */ - ob->mode &= ~OB_MODE_POSE; - cfrao = CFRA; - flago = arm->flag; - arm->flag &= ~(ARM_DRAWNAMES | ARM_DRAWAXES); - - /* copy the pose */ - poseo = ob->pose; - BKE_pose_copy_data(&posen, ob->pose, 1); - ob->pose = posen; - BKE_pose_rebuild(ob, ob->data); /* child pointers for IK */ - ghost_poses_tag_unselected(ob, 0); /* hide unselected bones if need be */ - - glEnable(GL_BLEND); - if (v3d->zbuf) glDisable(GL_DEPTH_TEST); - - /* draw from first frame of range to last */ - for (CFRA = (int)start; CFRA <= end; CFRA += (int)stepsize) { - colfac = (end - (float)CFRA) / range; - UI_GetThemeColorShadeAlpha4ubv(TH_WIRE, 0, -128 - (int)(120.0f * sqrtf(colfac)), col); - - BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)CFRA, ADT_RECALC_ALL); - BKE_pose_where_is(depsgraph, scene, ob); - draw_pose_bones(depsgraph, scene, view_layer, v3d, ar, base, OB_WIRE, col, true, false); - } - glDisable(GL_BLEND); - if (v3d->zbuf) glEnable(GL_DEPTH_TEST); - - /* before disposing of temp pose, use it to restore object to a sane state */ - BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)cfrao, ADT_RECALC_ALL); - - /* clean up temporary pose */ - ghost_poses_tag_unselected(ob, 1); /* unhide unselected bones if need be */ - BKE_pose_free(posen); - - /* restore */ - CFRA = cfrao; - ob->pose = poseo; - arm->flag = flago; - ob->mode |= OB_MODE_POSE; -} - -/* draw ghosts on keyframes in action within range - * - object should be in posemode - */ -static void draw_ghost_poses_keys( - struct Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer, - View3D *v3d, ARegion *ar, Base *base) -{ - Object *ob = base->object; - AnimData *adt = BKE_animdata_from_id(&ob->id); - bAction *act = (adt) ? adt->action : NULL; - bArmature *arm = ob->data; - bPose *posen, *poseo; - DLRBT_Tree keys; - ActKeyColumn *ak, *akn; - float start, end, range, colfac, i; - int cfrao, flago; - unsigned char col[4]; - - start = (float)arm->ghostsf; - end = (float)arm->ghostef; - if (end <= start) - return; - - /* get keyframes - then clip to only within range */ - BLI_dlrbTree_init(&keys); - action_to_keylist(adt, act, &keys, NULL); - BLI_dlrbTree_linkedlist_sync(&keys); - - range = 0; - for (ak = keys.first; ak; ak = akn) { - akn = ak->next; - - if ((ak->cfra < start) || (ak->cfra > end)) - BLI_freelinkN((ListBase *)&keys, ak); - else - range++; - } - if (range == 0) return; - - /* store values */ - ob->mode &= ~OB_MODE_POSE; - cfrao = CFRA; - flago = arm->flag; - arm->flag &= ~(ARM_DRAWNAMES | ARM_DRAWAXES); - - /* copy the pose */ - poseo = ob->pose; - BKE_pose_copy_data(&posen, ob->pose, 1); - ob->pose = posen; - BKE_pose_rebuild(ob, ob->data); /* child pointers for IK */ - ghost_poses_tag_unselected(ob, 0); /* hide unselected bones if need be */ - - glEnable(GL_BLEND); - if (v3d->zbuf) glDisable(GL_DEPTH_TEST); - - /* draw from first frame of range to last */ - for (ak = keys.first, i = 0; ak; ak = ak->next, i++) { - colfac = i / range; - UI_GetThemeColorShadeAlpha4ubv(TH_WIRE, 0, -128 - (int)(120.0f * sqrtf(colfac)), col); - - CFRA = (int)ak->cfra; - - BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)CFRA, ADT_RECALC_ALL); - BKE_pose_where_is(depsgraph, scene, ob); - draw_pose_bones(depsgraph, scene, view_layer, v3d, ar, base, OB_WIRE, col, true, false); - } - glDisable(GL_BLEND); - if (v3d->zbuf) glEnable(GL_DEPTH_TEST); - - /* before disposing of temp pose, use it to restore object to a sane state */ - BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)cfrao, ADT_RECALC_ALL); - - /* clean up temporary pose */ - ghost_poses_tag_unselected(ob, 1); /* unhide unselected bones if need be */ - BLI_dlrbTree_free(&keys); - BKE_pose_free(posen); - - /* restore */ - CFRA = cfrao; - ob->pose = poseo; - arm->flag = flago; - ob->mode |= OB_MODE_POSE; -} - -/* draw ghosts around current frame - * - object is supposed to be armature in posemode - */ -static void draw_ghost_poses( - struct Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer, - View3D *v3d, ARegion *ar, Base *base) -{ - Object *ob = base->object; - AnimData *adt = BKE_animdata_from_id(&ob->id); - bArmature *arm = ob->data; - bPose *posen, *poseo; - float cur, start, end, stepsize, range, colfac, actframe, ctime; - int cfrao, flago; - unsigned char col[4]; - - /* pre conditions, get an action with sufficient frames */ - if (ELEM(NULL, adt, adt->action)) - return; - - calc_action_range(adt->action, &start, &end, 0); - if (start == end) - return; - - /* prevent infinite loops if this is set to 0 - T49527 */ - if (arm->ghostsize < 1) - arm->ghostsize = 1; - - stepsize = (float)(arm->ghostsize); - range = (float)(arm->ghostep) * stepsize + 0.5f; /* plus half to make the for loop end correct */ - - /* store values */ - ob->mode &= ~OB_MODE_POSE; - cfrao = CFRA; - actframe = BKE_nla_tweakedit_remap(adt, (float)CFRA, 0); - flago = arm->flag; - arm->flag &= ~(ARM_DRAWNAMES | ARM_DRAWAXES); - - /* copy the pose */ - poseo = ob->pose; - BKE_pose_copy_data(&posen, ob->pose, 1); - ob->pose = posen; - BKE_pose_rebuild(ob, ob->data); /* child pointers for IK */ - ghost_poses_tag_unselected(ob, 0); /* hide unselected bones if need be */ - - glEnable(GL_BLEND); - if (v3d->zbuf) glDisable(GL_DEPTH_TEST); - - /* draw from darkest blend to lowest */ - for (cur = stepsize; cur < range; cur += stepsize) { - ctime = cur - (float)fmod(cfrao, stepsize); /* ensures consistent stepping */ - colfac = ctime / range; - UI_GetThemeColorShadeAlpha4ubv(TH_WIRE, 0, -128 - (int)(120.0f * sqrtf(colfac)), col); - - /* only within action range */ - if (actframe + ctime >= start && actframe + ctime <= end) { - CFRA = (int)BKE_nla_tweakedit_remap(adt, actframe + ctime, NLATIME_CONVERT_MAP); - - if (CFRA != cfrao) { - BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)CFRA, ADT_RECALC_ALL); - BKE_pose_where_is(depsgraph, scene, ob); - draw_pose_bones(depsgraph, scene, view_layer, v3d, ar, base, OB_WIRE, col, true, false); - } - } - - ctime = cur + (float)fmod((float)cfrao, stepsize) - stepsize + 1.0f; /* ensures consistent stepping */ - colfac = ctime / range; - UI_GetThemeColorShadeAlpha4ubv(TH_WIRE, 0, -128 - (int)(120.0f * sqrtf(colfac)), col); - - /* only within action range */ - if ((actframe - ctime >= start) && (actframe - ctime <= end)) { - CFRA = (int)BKE_nla_tweakedit_remap(adt, actframe - ctime, NLATIME_CONVERT_MAP); - - if (CFRA != cfrao) { - BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)CFRA, ADT_RECALC_ALL); - BKE_pose_where_is(depsgraph, scene, ob); - draw_pose_bones(depsgraph, scene, view_layer, v3d, ar, base, OB_WIRE, col, true, false); - } - } - } - glDisable(GL_BLEND); - if (v3d->zbuf) glEnable(GL_DEPTH_TEST); - - /* before disposing of temp pose, use it to restore object to a sane state */ - BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)cfrao, ADT_RECALC_ALL); - - /* clean up temporary pose */ - ghost_poses_tag_unselected(ob, 1); /* unhide unselected bones if need be */ - BKE_pose_free(posen); - - /* restore */ - CFRA = cfrao; - ob->pose = poseo; - arm->flag = flago; - ob->mode |= OB_MODE_POSE; -} - -/* ********************************** Armature Drawing - Main ************************* */ - -/* called from drawobject.c, return true if nothing was drawn - * (ob_wire_col == NULL) when drawing ghost */ -bool draw_armature( - Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer, View3D *v3d, ARegion *ar, Base *base, - const short dt, const short dflag, const unsigned char ob_wire_col[4], - const bool is_outline) -{ - Object *ob = base->object; - bArmature *arm = ob->data; - bool retval = false; - - if (v3d->flag2 & V3D_RENDER_OVERRIDE) - return true; - -#if 0 /* Not used until lighting is properly reimplemented */ - if (dt > OB_WIRE) { - /* we use color for solid lighting */ - if (ELEM(arm->drawtype, ARM_LINE, ARM_WIRE)) { - const float diffuse[3] = {0.64f, 0.64f, 0.64f}; - const float specular[3] = {0.5f, 0.5f, 0.5f}; - GPU_basic_shader_colors(diffuse, specular, 35, 1.0f); - } - else { - const float diffuse[3] = {1.0f, 1.0f, 1.0f}; - const float specular[3] = {1.0f, 1.0f, 1.0f}; - GPU_basic_shader_colors(diffuse, specular, 35, 1.0f); - glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW); /* only for lighting... */ - } - } -#endif - - /* arm->flag is being used to detect mode... */ - /* editmode? */ - if (arm->edbo) { - arm->flag |= ARM_EDITMODE; - draw_ebones(v3d, ar, ob, dt); - arm->flag &= ~ARM_EDITMODE; - } - else { - /* Draw Pose */ - if (ob->pose && ob->pose->chanbase.first) { - /* We can't safely draw non-updated pose, might contain NULL bone pointers... */ - if (ob->pose->flag & POSE_RECALC) { - BKE_pose_rebuild(ob, arm); - } - - /* drawing posemode selection indices or colors only in these cases */ - if (!(base->flag_legacy & OB_FROMDUPLI)) { - if (G.f & G_PICKSEL) { -#if 0 - /* nifty but actually confusing to allow bone selection out of posemode */ - if (OBACT && (OBACT->mode & OB_MODE_WEIGHT_PAINT)) { - if (ob == modifiers_isDeformedByArmature(OBACT)) - arm->flag |= ARM_POSEMODE; - } - else -#endif - if (ob->mode & OB_MODE_POSE) { - arm->flag |= ARM_POSEMODE; - } - } - else if (ob->mode & OB_MODE_POSE) { - if (arm->ghosttype == ARM_GHOST_RANGE) { - draw_ghost_poses_range(depsgraph, scene, view_layer, v3d, ar, base); - } - else if (arm->ghosttype == ARM_GHOST_KEYS) { - draw_ghost_poses_keys(depsgraph, scene, view_layer, v3d, ar, base); - } - else if (arm->ghosttype == ARM_GHOST_CUR) { - if (arm->ghostep) - draw_ghost_poses(depsgraph, scene, view_layer, v3d, ar, base); - } - if ((dflag & DRAW_SCENESET) == 0) { - if (ob == OBACT(view_layer)) - arm->flag |= ARM_POSEMODE; - else if (OBACT(view_layer) && (OBACT(view_layer)->mode & OB_MODE_WEIGHT_PAINT)) { - if (ob == modifiers_isDeformedByArmature(OBACT(view_layer))) - arm->flag |= ARM_POSEMODE; - } - draw_pose_paths(scene, v3d, ar, ob); - } - } - } - draw_pose_bones(depsgraph, scene, view_layer, v3d, ar, base, dt, ob_wire_col, (dflag & DRAW_CONSTCOLOR), is_outline); - arm->flag &= ~ARM_POSEMODE; - } - else { - retval = true; - } - } - /* restore */ - glFrontFace(GL_CCW); - - return retval; -} diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c deleted file mode 100644 index 2b3678c4812..00000000000 --- a/source/blender/editors/space_view3d/drawmesh.c +++ /dev/null @@ -1,364 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * Contributor(s): Blender Foundation, full update, glsl support - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/editors/space_view3d/drawmesh.c - * \ingroup spview3d - */ - -#include <string.h> -#include <math.h> - -#include "MEM_guardedalloc.h" - -#include "BLI_utildefines.h" -#include "BLI_bitmap.h" -#include "BLI_math.h" - -#include "DNA_material_types.h" -#include "DNA_mesh_types.h" -#include "DNA_meshdata_types.h" -#include "DNA_node_types.h" -#include "DNA_object_types.h" -#include "DNA_scene_types.h" -#include "DNA_screen_types.h" -#include "DNA_view3d_types.h" - -#include "BKE_DerivedMesh.h" -#include "BKE_global.h" -#include "BKE_image.h" -#include "BKE_material.h" -#include "BKE_paint.h" -#include "BKE_editmesh.h" -#include "BKE_scene.h" - -#include "BIF_glutil.h" - -#include "UI_resources.h" - -#include "GPU_draw.h" -#include "GPU_material.h" -#include "GPU_basic_shader.h" -#include "GPU_shader.h" -#include "GPU_matrix.h" - -#include "RE_engine.h" - -#include "ED_uvedit.h" - -#include "view3d_intern.h" /* own include */ - -/* user data structures for derived mesh callbacks */ -typedef struct drawMeshFaceSelect_userData { - Mesh *me; - BLI_bitmap *edge_flags; /* pairs of edge options (visible, select) */ -} drawMeshFaceSelect_userData; - -/**************************** Face Select Mode *******************************/ - -/* mainly to be less confusing */ -BLI_INLINE int edge_vis_index(const int index) { return index * 2; } -BLI_INLINE int edge_sel_index(const int index) { return index * 2 + 1; } - -static BLI_bitmap *get_tface_mesh_marked_edge_info(Mesh *me, bool draw_select_edges) -{ - BLI_bitmap *bitmap_edge_flags = BLI_BITMAP_NEW(me->totedge * 2, __func__); - MPoly *mp; - MLoop *ml; - int i, j; - bool select_set; - - for (i = 0; i < me->totpoly; i++) { - mp = &me->mpoly[i]; - - if (!(mp->flag & ME_HIDE)) { - select_set = (mp->flag & ME_FACE_SEL) != 0; - - ml = me->mloop + mp->loopstart; - for (j = 0; j < mp->totloop; j++, ml++) { - if ((draw_select_edges == false) && - (select_set && BLI_BITMAP_TEST(bitmap_edge_flags, edge_sel_index(ml->e)))) - { - BLI_BITMAP_DISABLE(bitmap_edge_flags, edge_vis_index(ml->e)); - } - else { - BLI_BITMAP_ENABLE(bitmap_edge_flags, edge_vis_index(ml->e)); - if (select_set) { - BLI_BITMAP_ENABLE(bitmap_edge_flags, edge_sel_index(ml->e)); - } - } - } - } - } - - return bitmap_edge_flags; -} - - -static DMDrawOption draw_mesh_face_select__setHiddenOpts(void *userData, int index) -{ - drawMeshFaceSelect_userData *data = userData; - Mesh *me = data->me; - - if (me->drawflag & ME_DRAWEDGES) { - if ((BLI_BITMAP_TEST(data->edge_flags, edge_vis_index(index)))) - return DM_DRAW_OPTION_NORMAL; - else - return DM_DRAW_OPTION_SKIP; - } - else if (BLI_BITMAP_TEST(data->edge_flags, edge_sel_index(index)) && - BLI_BITMAP_TEST(data->edge_flags, edge_vis_index(index))) - { - return DM_DRAW_OPTION_NORMAL; - } - else { - return DM_DRAW_OPTION_SKIP; - } -} - -static DMDrawOption draw_mesh_face_select__setSelectOpts(void *userData, int index) -{ - drawMeshFaceSelect_userData *data = userData; - return (BLI_BITMAP_TEST(data->edge_flags, edge_sel_index(index)) && - BLI_BITMAP_TEST(data->edge_flags, edge_vis_index(index))) ? DM_DRAW_OPTION_NORMAL : DM_DRAW_OPTION_SKIP; -} - -/* draws unselected */ -static DMDrawOption draw_mesh_face_select__drawFaceOptsInv(void *userData, int index) -{ - Mesh *me = (Mesh *)userData; - - MPoly *mpoly = &me->mpoly[index]; - if (!(mpoly->flag & ME_HIDE) && !(mpoly->flag & ME_FACE_SEL)) - return DM_DRAW_OPTION_NORMAL; - else - return DM_DRAW_OPTION_SKIP; -} - -void draw_mesh_face_select(RegionView3D *rv3d, Mesh *me, DerivedMesh *dm, bool draw_select_edges) -{ - drawMeshFaceSelect_userData data; - - data.me = me; - data.edge_flags = get_tface_mesh_marked_edge_info(me, draw_select_edges); - - glEnable(GL_DEPTH_TEST); - ED_view3d_polygon_offset(rv3d, 1.0); - - /* Draw (Hidden) Edges */ - setlinestyle(1); - UI_ThemeColor(TH_EDGE_FACESEL); - dm->drawMappedEdges(dm, draw_mesh_face_select__setHiddenOpts, &data); - setlinestyle(0); - - /* Draw Selected Faces */ - if (me->drawflag & ME_DRAWFACES) { - glEnable(GL_BLEND); - glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - /* dull unselected faces so as not to get in the way of seeing color */ - glColor4ub(96, 96, 96, 64); - dm->drawMappedFaces(dm, draw_mesh_face_select__drawFaceOptsInv, NULL, NULL, (void *)me, DM_DRAW_SKIP_HIDDEN); - glDisable(GL_BLEND); - } - - ED_view3d_polygon_offset(rv3d, 1.0); - - /* Draw Stippled Outline for selected faces */ - glColor3ub(255, 255, 255); - setlinestyle(1); - dm->drawMappedEdges(dm, draw_mesh_face_select__setSelectOpts, &data); - setlinestyle(0); - - ED_view3d_polygon_offset(rv3d, 0.0); /* resets correctly now, even after calling accumulated offsets */ - - MEM_freeN(data.edge_flags); -} - -/***************************** Texture Drawing ******************************/ - -/* when face select is on, use face hidden flag */ -static DMDrawOption wpaint__setSolidDrawOptions_facemask(void *userData, int index) -{ - Mesh *me = (Mesh *)userData; - MPoly *mp = &me->mpoly[index]; - if (mp->flag & ME_HIDE) - return DM_DRAW_OPTION_SKIP; - return DM_DRAW_OPTION_NORMAL; -} - -/************************** NEW SHADING NODES ********************************/ - -typedef struct TexMatCallback { - Scene *scene; - Object *ob; - Mesh *me; - DerivedMesh *dm; - bool shadeless; - bool two_sided_lighting; -} TexMatCallback; - -void draw_mesh_textured(Scene *scene, ViewLayer *view_layer, View3D *v3d, RegionView3D *rv3d, - Object *ob, DerivedMesh *dm, const int draw_flags) -{ - UNUSED_VARS(scene, view_layer, v3d, rv3d, ob, dm, draw_flags); - return; -} - -/* Vertex Paint and Weight Paint */ -static void draw_mesh_paint_light_begin(void) -{ - /* get material diffuse color from vertex colors but set default spec */ - const float specular[3] = {0.47f, 0.47f, 0.47f}; - GPU_basic_shader_colors(NULL, specular, 35, 1.0f); - GPU_basic_shader_bind(GPU_SHADER_LIGHTING | GPU_SHADER_USE_COLOR); -} - -static void draw_mesh_paint_light_end(void) -{ - GPU_basic_shader_bind(GPU_SHADER_USE_COLOR); -} - -void draw_mesh_paint_weight_faces(DerivedMesh *dm, const bool use_light, - void *facemask_cb, void *user_data) -{ - DMSetMaterial setMaterial = GPU_object_materials_check() ? GPU_object_material_bind : NULL; - int flags = DM_DRAW_USE_COLORS; - - if (use_light) { - draw_mesh_paint_light_begin(); - flags |= DM_DRAW_NEED_NORMALS; - } - - dm->drawMappedFaces(dm, (DMSetDrawOptions)facemask_cb, setMaterial, NULL, user_data, flags); - - if (use_light) { - draw_mesh_paint_light_end(); - } -} - -void draw_mesh_paint_vcolor_faces(DerivedMesh *dm, const bool use_light, - void *facemask_cb, void *user_data, - const Mesh *me) -{ - DMSetMaterial setMaterial = GPU_object_materials_check() ? GPU_object_material_bind : NULL; - int flags = 0; - - if (use_light) { - draw_mesh_paint_light_begin(); - flags |= DM_DRAW_NEED_NORMALS; - } - - if (me->mloopcol) { - dm->drawMappedFaces(dm, facemask_cb, setMaterial, NULL, user_data, - DM_DRAW_USE_COLORS | flags); - } - else { - glColor3f(1.0f, 1.0f, 1.0f); - dm->drawMappedFaces(dm, facemask_cb, setMaterial, NULL, user_data, flags); - } - - if (use_light) { - draw_mesh_paint_light_end(); - } -} - -void draw_mesh_paint_weight_edges(RegionView3D *rv3d, DerivedMesh *dm, - const bool use_depth, const bool use_alpha, - void *edgemask_cb, void *user_data) -{ - /* weight paint in solid mode, special case. focus on making the weights clear - * rather than the shading, this is also forced in wire view */ - - if (use_depth) { - ED_view3d_polygon_offset(rv3d, 1.0); - glDepthMask(0); /* disable write in zbuffer, selected edge wires show better */ - } - else { - glDisable(GL_DEPTH_TEST); - } - - if (use_alpha) { - glEnable(GL_BLEND); - } - - glColor4ub(255, 255, 255, 96); - GPU_basic_shader_bind_enable(GPU_SHADER_LINE | GPU_SHADER_STIPPLE); - GPU_basic_shader_line_stipple(1, 0xAAAA); - - dm->drawMappedEdges(dm, (DMSetDrawOptions)edgemask_cb, user_data); - - if (use_depth) { - ED_view3d_polygon_offset(rv3d, 0.0); - glDepthMask(1); - } - else { - glEnable(GL_DEPTH_TEST); - } - - GPU_basic_shader_bind_disable(GPU_SHADER_LINE | GPU_SHADER_STIPPLE); - - if (use_alpha) { - glDisable(GL_BLEND); - } -} - -void draw_mesh_paint(View3D *v3d, RegionView3D *rv3d, - Object *ob, DerivedMesh *dm, const int draw_flags) -{ - DMSetDrawOptions facemask = NULL; - Mesh *me = ob->data; - const bool use_light = (v3d->drawtype >= OB_SOLID); - - /* hide faces in face select mode */ - if (me->editflag & (ME_EDIT_PAINT_VERT_SEL | ME_EDIT_PAINT_FACE_SEL)) - facemask = wpaint__setSolidDrawOptions_facemask; - - if (ob->mode & OB_MODE_WEIGHT_PAINT) { - draw_mesh_paint_weight_faces(dm, use_light, facemask, me); - } - else if (ob->mode & OB_MODE_VERTEX_PAINT) { - draw_mesh_paint_vcolor_faces(dm, use_light, facemask, me, me); - } - - /* draw face selection on top */ - if (draw_flags & DRAW_FACE_SELECT) { - bool draw_select_edges = (ob->mode & OB_MODE_TEXTURE_PAINT) == 0; - draw_mesh_face_select(rv3d, me, dm, draw_select_edges); - } - else if ((use_light == false) || (ob->dtx & OB_DRAWWIRE)) { - const bool use_depth = (v3d->flag & V3D_ZBUF_SELECT) || !(ob->mode & OB_MODE_WEIGHT_PAINT); - const bool use_alpha = (ob->mode & OB_MODE_VERTEX_PAINT) == 0; - - if (use_alpha == false) { - set_inverted_drawing(1); - } - - draw_mesh_paint_weight_edges(rv3d, dm, use_depth, use_alpha, NULL, NULL); - - if (use_alpha == false) { - set_inverted_drawing(0); - } - } -} - diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 37279c77ba0..8e04a2e17b8 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -116,136 +116,6 @@ #include "../../draw/intern/draw_cache_impl.h" /* bad level include (temporary) */ -/* prototypes */ -static void imm_draw_box(const float vec[8][3], bool solid, unsigned pos); - -// #define USE_MESH_DM_SELECT - -/* Workaround for sequencer scene render mode. - * - * Strips doesn't use DAG to update objects or so, which - * might lead to situations when object is drawing without - * curve cache ready. - * - * Ideally we don't want to evaluate objects from drawing, - * but it'll require some major sequencer re-design. So - * for now just fallback to legacy behavior with calling - * display ist creating from draw(). - */ -#define SEQUENCER_DAG_WORKAROUND - -typedef enum eWireDrawMode { - OBDRAW_WIRE_OFF = 0, - OBDRAW_WIRE_ON = 1, - OBDRAW_WIRE_ON_DEPTH = 2 -} eWireDrawMode; - -typedef struct drawDMVerts_userData { - BMesh *bm; - - BMVert *eve_act; - char sel; - unsigned int pos, color; - - /* cached theme values */ - unsigned char th_editmesh_active[4]; - unsigned char th_vertex_select[4]; - unsigned char th_vertex[4]; - unsigned char th_skin_root[4]; - - /* for skin node drawing */ - int cd_vskin_offset; - float imat[4][4]; -} drawDMVerts_userData; - -typedef struct drawDMEdgesSel_userData { - BMesh *bm; - - unsigned char *baseCol, *selCol, *actCol; - BMEdge *eed_act; -} drawDMEdgesSel_userData; - -typedef struct drawDMEdgesSelInterp_userData { - BMesh *bm; - - unsigned char *baseCol, *selCol; - unsigned char *lastCol; -} drawDMEdgesSelInterp_userData; - -typedef struct drawDMEdgesWeightInterp_userData { - BMesh *bm; - - int cd_dvert_offset; - int defgroup_tot; - int vgroup_index; - char weight_user; - float alert_color[3]; - -} drawDMEdgesWeightInterp_userData; - -typedef struct drawDMFacesSel_userData { -#ifdef WITH_FREESTYLE - unsigned char *cols[4]; -#else - unsigned char *cols[3]; -#endif - - DerivedMesh *dm; - BMesh *bm; - - BMFace *efa_act; - const int *orig_index_mp_to_orig; -} drawDMFacesSel_userData; - -typedef struct drawDMNormal_userData { - unsigned int pos; - BMesh *bm; - int uniform_scale; - float normalsize; - float tmat[3][3]; - float imat[3][3]; -} drawDMNormal_userData; - -typedef struct drawMVertOffset_userData { - unsigned int pos, col; - MVert *mvert; - int offset; -} drawMVertOffset_userData; - -typedef struct drawDMLayer_userData { - BMesh *bm; - int cd_layer_offset; - unsigned int pos, col; -} drawDMLayer_userData; - -typedef struct drawBMOffset_userData { - unsigned int pos, col; - BMesh *bm; - int offset; -} drawBMOffset_userData; - -typedef struct drawBMSelect_userData { - BMesh *bm; - bool select; - unsigned int pos; -} drawBMSelect_userData; - - -static void drawcube_size(float size, unsigned pos); -static void drawcircle_size(float size, unsigned pos); -static void draw_empty_sphere(float size, unsigned pos); -static void draw_empty_cone(float size, unsigned pos); - -static void ob_wire_color_blend_theme_id(const unsigned char ob_wire_col[4], const int theme_id, float fac, float r_col[3]) -{ - float col_wire[3], col_bg[3]; - - rgb_uchar_to_float(col_wire, ob_wire_col); - - UI_GetThemeColor3fv(theme_id, col_bg); - interp_v3_v3v3(r_col, col_bg, col_wire, fac); -} - int view3d_effective_drawtype(const struct View3D *v3d) { if (v3d->drawtype == OB_RENDER) { @@ -254,42 +124,6 @@ int view3d_effective_drawtype(const struct View3D *v3d) return v3d->drawtype; } -/* this condition has been made more complex since editmode can draw textures */ -bool check_object_draw_texture(Scene *scene, View3D *v3d, const char drawtype) -{ - const int v3d_drawtype = view3d_effective_drawtype(v3d); - /* texture and material draw modes */ - if (ELEM(v3d_drawtype, OB_TEXTURE, OB_MATERIAL) && drawtype > OB_SOLID) { - return true; - } - - /* textured solid */ - if ((v3d_drawtype == OB_SOLID) && - (v3d->flag2 & V3D_SOLID_TEX) && - (BKE_scene_use_new_shading_nodes(scene) == false)) - { - return true; - } - - if (v3d->flag2 & V3D_SHOW_SOLID_MATCAP) { - return true; - } - - return false; -} - -static bool check_object_draw_editweight(Mesh *me, DerivedMesh *finalDM) -{ - if (me->drawflag & ME_DRAWEIGHT) { - /* editmesh handles its own weight drawing */ - if (finalDM->type != DM_TYPE_EDITBMESH) { - return true; - } - } - - return false; -} - static bool check_ob_drawface_dot(Scene *sce, View3D *vd, char dt) { if ((sce->toolsettings->selectmode & SCE_SELECT_FACE) == 0) @@ -311,49 +145,6 @@ static bool check_ob_drawface_dot(Scene *sce, View3D *vd, char dt) return true; } -/* ************************ */ - -/* check for glsl drawing */ - -bool draw_glsl_material(Scene *scene, ViewLayer *view_layer, Object *ob, View3D *v3d, const char dt) -{ - if (G.f & G_PICKSEL) - return false; - if (!check_object_draw_texture(scene, v3d, dt)) - return false; - if (ob == OBACT(view_layer) && (ob && ob->mode & OB_MODE_WEIGHT_PAINT)) - return false; - - if (v3d->flag2 & V3D_SHOW_SOLID_MATCAP) - return true; - - if (v3d->drawtype == OB_TEXTURE) - return !BKE_scene_use_new_shading_nodes(scene); - else if (v3d->drawtype == OB_MATERIAL && dt > OB_SOLID) - return true; - else - return false; -} - -static bool check_alpha_pass(Base *base) -{ - if (base->flag_legacy & OB_FROMDUPLI) - return false; - - if (G.f & G_PICKSEL) - return false; - - if (base->object->mode & OB_MODE_ALL_PAINT) - return false; - - return (base->object->dtx & OB_DRAWTRANSP); -} - -/***/ -static const unsigned int colortab[] = { - 0x0, 0x403000, 0xFFFF88 -}; - /* ----------------- OpenGL Circle Drawing - Tables for Optimized Drawing Speed ------------------ */ /* 32 values of sin function (still same result!) */ #define CIRCLE_RESOL 32 @@ -429,365 +220,6 @@ static const float cosval[CIRCLE_RESOL] = { 1.00000000 }; -/** - * \param viewmat_local_unit is typically the 'rv3d->viewmatob' - * copied into a 3x3 matrix and normalized. - */ -static void draw_xyz_wire(const float viewmat_local_unit[3][3], const float c[3], float size, int axis, unsigned pos) -{ - Gwn_PrimType line_type = GWN_PRIM_LINES; - float buffer[4][3]; - int n = 0; - - float v1[3] = {0.0f, 0.0f, 0.0f}, v2[3] = {0.0f, 0.0f, 0.0f}; - float dim = size * 0.1f; - float dx[3], dy[3]; - - dx[0] = dim; dx[1] = 0.0f; dx[2] = 0.0f; - dy[0] = 0.0f; dy[1] = dim; dy[2] = 0.0f; - - switch (axis) { - case 0: /* x axis */ - /* bottom left to top right */ - negate_v3_v3(v1, dx); - sub_v3_v3(v1, dy); - copy_v3_v3(v2, dx); - add_v3_v3(v2, dy); - - copy_v3_v3(buffer[n++], v1); - copy_v3_v3(buffer[n++], v2); - - /* top left to bottom right */ - mul_v3_fl(dy, 2.0f); - add_v3_v3(v1, dy); - sub_v3_v3(v2, dy); - - copy_v3_v3(buffer[n++], v1); - copy_v3_v3(buffer[n++], v2); - - break; - case 1: /* y axis */ - /* bottom left to top right */ - mul_v3_fl(dx, 0.75f); - negate_v3_v3(v1, dx); - sub_v3_v3(v1, dy); - copy_v3_v3(v2, dx); - add_v3_v3(v2, dy); - - copy_v3_v3(buffer[n++], v1); - copy_v3_v3(buffer[n++], v2); - - /* top left to center */ - mul_v3_fl(dy, 2.0f); - add_v3_v3(v1, dy); - zero_v3(v2); - - copy_v3_v3(buffer[n++], v1); - copy_v3_v3(buffer[n++], v2); - - break; - case 2: /* z axis */ - line_type = GWN_PRIM_LINE_STRIP; - - /* start at top left */ - negate_v3_v3(v1, dx); - add_v3_v3(v1, dy); - - copy_v3_v3(buffer[n++], v1); - - mul_v3_fl(dx, 2.0f); - add_v3_v3(v1, dx); - - copy_v3_v3(buffer[n++], v1); - - mul_v3_fl(dy, 2.0f); - sub_v3_v3(v1, dx); - sub_v3_v3(v1, dy); - - copy_v3_v3(buffer[n++], v1); - - add_v3_v3(v1, dx); - - copy_v3_v3(buffer[n++], v1); - - break; - default: - BLI_assert(0); - return; - } - - immBegin(line_type, n); - for (int i = 0; i < n; i++) { - mul_transposed_m3_v3((float (*)[3])viewmat_local_unit, buffer[i]); - add_v3_v3(buffer[i], c); - immVertex3fv(pos, buffer[i]); - } - immEnd(); - - /* TODO: recode this function for clarity once we're not in a hurry to modernize GL usage */ -} - -void drawaxes(const float viewmat_local[4][4], float size, char drawtype, const unsigned char color[4]) -{ - int axis; - float v1[3] = {0.0, 0.0, 0.0}; - float v2[3] = {0.0, 0.0, 0.0}; - float v3[3] = {0.0, 0.0, 0.0}; - - glLineWidth(1.0f); - - unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - if (color) { - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - immUniformColor4ubv(color); - } - else { - immBindBuiltinProgram(GPU_SHADER_3D_DEPTH_ONLY); - } - - switch (drawtype) { - case OB_PLAINAXES: - immBegin(GWN_PRIM_LINES, 6); - for (axis = 0; axis < 3; axis++) { - v1[axis] = size; - v2[axis] = -size; - immVertex3fv(pos, v1); - immVertex3fv(pos, v2); - - /* reset v1 & v2 to zero */ - v1[axis] = v2[axis] = 0.0f; - } - immEnd(); - break; - - case OB_SINGLE_ARROW: - immBegin(GWN_PRIM_LINES, 2); - /* in positive z direction only */ - v1[2] = size; - immVertex3fv(pos, v1); - immVertex3fv(pos, v2); - immEnd(); - - /* square pyramid */ - immBegin(GWN_PRIM_TRIS, 12); - - v2[0] = size * 0.035f; v2[1] = size * 0.035f; - v3[0] = size * -0.035f; v3[1] = size * 0.035f; - v2[2] = v3[2] = size * 0.75f; - - for (axis = 0; axis < 4; axis++) { - if (axis % 2 == 1) { - v2[0] = -v2[0]; - v3[1] = -v3[1]; - } - else { - v2[1] = -v2[1]; - v3[0] = -v3[0]; - } - - immVertex3fv(pos, v1); - immVertex3fv(pos, v2); - immVertex3fv(pos, v3); - } - immEnd(); - break; - - case OB_CUBE: - drawcube_size(size, pos); - break; - - case OB_CIRCLE: - drawcircle_size(size, pos); - break; - - case OB_EMPTY_SPHERE: - draw_empty_sphere(size, pos); - break; - - case OB_EMPTY_CONE: - draw_empty_cone(size, pos); - break; - - case OB_ARROWS: - default: - { - float viewmat_local_unit[3][3]; - - copy_m3_m4(viewmat_local_unit, (float (*)[4])viewmat_local); - normalize_m3(viewmat_local_unit); - - for (axis = 0; axis < 3; axis++) { - const int arrow_axis = (axis == 0) ? 1 : 0; - - immBegin(GWN_PRIM_LINES, 6); - - v2[axis] = size; - immVertex3fv(pos, v1); - immVertex3fv(pos, v2); - - v1[axis] = size * 0.85f; - v1[arrow_axis] = -size * 0.08f; - immVertex3fv(pos, v1); - immVertex3fv(pos, v2); - - v1[arrow_axis] = size * 0.08f; - immVertex3fv(pos, v1); - immVertex3fv(pos, v2); - - immEnd(); - - v2[axis] += size * 0.125f; - - draw_xyz_wire(viewmat_local_unit, v2, size, axis, pos); - - /* reset v1 & v2 to zero */ - v1[arrow_axis] = v1[axis] = v2[axis] = 0.0f; - } - } - } - - immUnbindProgram(); -} - - -/* Function to draw an Image on an empty Object */ -static void draw_empty_image(Object *ob, const short dflag, const unsigned char ob_wire_col[4], eStereoViews sview) -{ - Image *ima = ob->data; - - const float ob_alpha = ob->col[3]; - float ima_x, ima_y; - - int bindcode = 0; - - if (ima) { - ImageUser iuser = *ob->iuser; - - /* Support multi-view */ - if (ima && (sview == STEREO_RIGHT_ID)) { - iuser.multiview_eye = sview; - iuser.flag |= IMA_SHOW_STEREO; - BKE_image_multiview_index(ima, &iuser); - } - - if (ob_alpha > 0.0f) { - bindcode = GPU_verify_image(ima, &iuser, GL_TEXTURE_2D, false, false, false); - /* don't bother drawing the image if alpha = 0 */ - } - - int w, h; - BKE_image_get_size(ima, &iuser, &w, &h); - ima_x = w; - ima_y = h; - } - else { - /* if no image, make it a 1x1 empty square, honor scale & offset */ - ima_x = ima_y = 1.0f; - } - - /* Get the image aspect even if the buffer is invalid */ - float sca_x = 1.0f, sca_y = 1.0f; - if (ima) { - if (ima->aspx > ima->aspy) { - sca_y = ima->aspy / ima->aspx; - } - else if (ima->aspx < ima->aspy) { - sca_x = ima->aspx / ima->aspy; - } - } - - float scale_x; - float scale_y; - { - const float scale_x_inv = ima_x * sca_x; - const float scale_y_inv = ima_y * sca_y; - if (scale_x_inv > scale_y_inv) { - scale_x = ob->empty_drawsize; - scale_y = ob->empty_drawsize * (scale_y_inv / scale_x_inv); - } - else { - scale_x = ob->empty_drawsize * (scale_x_inv / scale_y_inv); - scale_y = ob->empty_drawsize; - } - } - - const float ofs_x = ob->ima_ofs[0] * scale_x; - const float ofs_y = ob->ima_ofs[1] * scale_y; - - const rctf rect = { - .xmin = ofs_x, - .xmax = ofs_x + scale_x, - .ymin = ofs_y, - .ymax = ofs_y + scale_y, - }; - - bool use_blend = false; - - if (bindcode) { - use_blend = ob_alpha < 1.0f || BKE_image_has_alpha(ima); - - if (use_blend) { - glEnable(GL_BLEND); - glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - } - - Gwn_VertFormat *format = immVertexFormat(); - unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - unsigned int texCoord = GWN_vertformat_attr_add(format, "texCoord", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_3D_IMAGE_MODULATE_ALPHA); - immUniform1f("alpha", ob_alpha); - immUniform1i("image", 0); /* default GL_TEXTURE0 unit */ - - immBegin(GWN_PRIM_TRI_FAN, 4); - immAttrib2f(texCoord, 0.0f, 0.0f); - immVertex2f(pos, rect.xmin, rect.ymin); - - immAttrib2f(texCoord, 1.0f, 0.0f); - immVertex2f(pos, rect.xmax, rect.ymin); - - immAttrib2f(texCoord, 1.0f, 1.0f); - immVertex2f(pos, rect.xmax, rect.ymax); - - immAttrib2f(texCoord, 0.0f, 1.0f); - immVertex2f(pos, rect.xmin, rect.ymax); - immEnd(); - - immUnbindProgram(); - } - - /* Draw the image outline */ - glLineWidth(1.5f); - unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - - const bool picking = dflag & DRAW_CONSTCOLOR; - if (picking) { - /* TODO: deal with picking separately, use this function just to draw */ - immBindBuiltinProgram(GPU_SHADER_3D_DEPTH_ONLY); - if (use_blend) { - glDisable(GL_BLEND); - } - - imm_draw_box_wire_2d(pos, rect.xmin, rect.ymin, rect.xmax, rect.ymax); - } - else { - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - immUniformColor3ubv(ob_wire_col); - glEnable(GL_LINE_SMOOTH); - - if (!use_blend) { - glEnable(GL_BLEND); - glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - } - - imm_draw_box_wire_2d(pos, rect.xmin, rect.ymin, rect.xmax, rect.ymax); - - glDisable(GL_LINE_SMOOTH); - glDisable(GL_BLEND); - } - - immUnbindProgram(); -} - static void circball_array_fill(float verts[CIRCLE_RESOL][3], const float cent[3], float rad, const float tmat[4][4]) { float vx[3], vy[3]; @@ -816,8383 +248,11 @@ void imm_drawcircball(const float cent[3], float rad, const float tmat[4][4], un immEnd(); } -/* circle for object centers, special_color is for library or ob users */ -static void drawcentercircle(View3D *v3d, RegionView3D *UNUSED(rv3d), const float co[3], int selstate, bool special_color) -{ - const float outlineWidth = 1.0f * U.pixelsize; - const float size = U.obcenter_dia * U.pixelsize + outlineWidth; - - if (v3d->zbuf) { - glDisable(GL_DEPTH_TEST); - /* TODO(merwin): fit things like this into plates/buffers design */ - } - - glEnable(GL_BLEND); - GPU_enable_program_point_size(); - - unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA); - immUniform1f("size", size); - - if (special_color) { - if (selstate == ACTIVE || selstate == SELECT) immUniformColor4ub(0x88, 0xFF, 0xFF, 155); - else immUniformColor4ub(0x55, 0xCC, 0xCC, 155); - } - else { - if (selstate == ACTIVE) immUniformThemeColorShadeAlpha(TH_ACTIVE, 0, -80); - else if (selstate == SELECT) immUniformThemeColorShadeAlpha(TH_SELECT, 0, -80); - else if (selstate == DESELECT) immUniformThemeColorShadeAlpha(TH_TRANSFORM, 0, -80); - } - - /* set up outline */ - float outlineColor[4]; - UI_GetThemeColorShadeAlpha4fv(TH_WIRE, 0, -30, outlineColor); - immUniform4fv("outlineColor", outlineColor); - immUniform1f("outlineWidth", outlineWidth); - - immBegin(GWN_PRIM_POINTS, 1); - immVertex3fv(pos, co); - immEnd(); - - immUnbindProgram(); - - GPU_disable_program_point_size(); - glDisable(GL_BLEND); - - if (v3d->zbuf) { - glEnable(GL_DEPTH_TEST); - } -} - -/* *********** text drawing for object/particles/armature ************* */ - -typedef struct ViewCachedString { - struct ViewCachedString *next; - float vec[3]; - union { - unsigned char ub[4]; - int pack; - } col; - short sco[2]; - short xoffs; - short flag; - int str_len; - - /* str is allocated past the end */ - char str[0]; -} ViewCachedString; - -/* one arena for all 3 string lists */ -static MemArena *g_v3d_strings_arena = NULL; -static ViewCachedString *g_v3d_strings[3] = {NULL, NULL, NULL}; -static int g_v3d_string_level = -1; - -void view3d_cached_text_draw_begin(void) -{ - g_v3d_string_level++; - - BLI_assert(g_v3d_string_level >= 0); - - if (g_v3d_string_level == 0) { - BLI_assert(g_v3d_strings_arena == NULL); - } -} - -void view3d_cached_text_draw_add(const float co[3], - const char *str, const size_t str_len, - short xoffs, short flag, - const unsigned char col[4]) -{ - int alloc_len = str_len + 1; - ViewCachedString *vos; - - BLI_assert(str_len == strlen(str)); - - if (g_v3d_strings_arena == NULL) { - g_v3d_strings_arena = BLI_memarena_new(MEM_SIZE_OPTIMAL(1 << 14), __func__); - } - - vos = BLI_memarena_alloc(g_v3d_strings_arena, sizeof(ViewCachedString) + alloc_len); - - BLI_LINKS_PREPEND(g_v3d_strings[g_v3d_string_level], vos); - - copy_v3_v3(vos->vec, co); - copy_v4_v4_uchar(vos->col.ub, col); - vos->xoffs = xoffs; - vos->flag = flag; - vos->str_len = str_len; - - /* allocate past the end */ - memcpy(vos->str, str, alloc_len); -} - -void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, bool depth_write) -{ - RegionView3D *rv3d = ar->regiondata; - ViewCachedString *vos; - int tot = 0; - - BLI_assert(g_v3d_string_level >= 0 && g_v3d_string_level <= 2); - - /* project first and test */ - for (vos = g_v3d_strings[g_v3d_string_level]; vos; vos = vos->next) { - if (ED_view3d_project_short_ex(ar, - (vos->flag & V3D_CACHE_TEXT_GLOBALSPACE) ? rv3d->persmat : rv3d->persmatob, - (vos->flag & V3D_CACHE_TEXT_LOCALCLIP) != 0, - vos->vec, vos->sco, - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN | V3D_PROJ_TEST_CLIP_NEAR) == V3D_PROJ_RET_OK) - { - tot++; - } - else { - vos->sco[0] = IS_CLIPPED; - } - } - - if (tot) { - int col_pack_prev = 0; - - if (rv3d->rflag & RV3D_CLIPPING) { - ED_view3d_clipping_disable(); - } - - float original_proj[4][4]; - gpuGetProjectionMatrix(original_proj); - wmOrtho2_region_pixelspace(ar); - - gpuPushMatrix(); - gpuLoadIdentity(); - - if (depth_write) { - if (v3d->zbuf) glDisable(GL_DEPTH_TEST); - } - else { - glDepthMask(GL_FALSE); - } - - const int font_id = BLF_default(); - - for (vos = g_v3d_strings[g_v3d_string_level]; vos; vos = vos->next) { - if (vos->sco[0] != IS_CLIPPED) { - if (col_pack_prev != vos->col.pack) { - BLF_color3ubv(font_id, vos->col.ub); - col_pack_prev = vos->col.pack; - } - - ((vos->flag & V3D_CACHE_TEXT_ASCII) ? BLF_draw_default_ascii : BLF_draw_default)( - (float)(vos->sco[0] + vos->xoffs), - (float)(vos->sco[1]), - (depth_write) ? 0.0f : 2.0f, - vos->str, - vos->str_len); - } - } - - if (depth_write) { - if (v3d->zbuf) glEnable(GL_DEPTH_TEST); - } - else { - glDepthMask(GL_TRUE); - } - - gpuPopMatrix(); - gpuLoadProjectionMatrix(original_proj); - - if (rv3d->rflag & RV3D_CLIPPING) { - ED_view3d_clipping_enable(); - } - } - - g_v3d_strings[g_v3d_string_level] = NULL; - - if (g_v3d_string_level == 0) { - if (g_v3d_strings_arena) { - BLI_memarena_free(g_v3d_strings_arena); - g_v3d_strings_arena = NULL; - } - } - - g_v3d_string_level--; -} - -/* ******************** primitive drawing ******************* */ - -/* draws a cube given the scaling of the cube, assuming that - * all required matrices have been set (used for drawing empties) - */ -static void drawcube_size(float size, unsigned pos) -{ - const float verts[8][3] = { - {-size, -size, -size}, - {-size, -size, size}, - {-size, size, -size}, - {-size, size, size}, - { size, -size, -size}, - { size, -size, size}, - { size, size, -size}, - { size, size, size} - }; - - const GLubyte indices[24] = {0, 1, 1, 3, 3, 2, 2, 0, 0, 4, 4, 5, 5, 7, 7, 6, 6, 4, 1, 5, 3, 7, 2, 6}; - -#if 0 - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, 0, verts); - glDrawRangeElements(GL_LINES, 0, 7, 24, GL_UNSIGNED_BYTE, indices); - glDisableClientState(GL_VERTEX_ARRAY); -#else - immBegin(GWN_PRIM_LINES, 24); - for (int i = 0; i < 24; ++i) { - immVertex3fv(pos, verts[indices[i]]); - } - immEnd(); -#endif -} - -static void drawshadbuflimits(const Lamp *la, const float mat[4][4], unsigned pos) -{ - float sta[3], end[3], lavec[3]; - - negate_v3_v3(lavec, mat[2]); - normalize_v3(lavec); - - madd_v3_v3v3fl(sta, mat[3], lavec, la->clipsta); - madd_v3_v3v3fl(end, mat[3], lavec, la->clipend); - - immBegin(GWN_PRIM_LINES, 2); - immVertex3fv(pos, sta); - immVertex3fv(pos, end); - immEnd(); - - glPointSize(3.0f); - immBegin(GWN_PRIM_POINTS, 2); - immVertex3fv(pos, sta); - immVertex3fv(pos, end); - immEnd(); -} - -static void spotvolume(float lvec[3], float vvec[3], const float inp) -{ - /* camera is at 0,0,0 */ - float temp[3], plane[3], mat1[3][3], mat2[3][3], mat3[3][3], mat4[3][3], q[4], co, si, angle; - - normalize_v3(lvec); - normalize_v3(vvec); /* is this the correct vector ? */ - - cross_v3_v3v3(temp, vvec, lvec); /* equation for a plane through vvec and lvec */ - cross_v3_v3v3(plane, lvec, temp); /* a plane perpendicular to this, parallel with lvec */ - - /* vectors are exactly aligned, use the X axis, this is arbitrary */ - if (normalize_v3(plane) == 0.0f) - plane[1] = 1.0f; - - /* now we've got two equations: one of a cone and one of a plane, but we have - * three unknowns. We remove one unknown by rotating the plane to z=0 (the plane normal) */ - - /* rotate around cross product vector of (0,0,1) and plane normal, dot product degrees */ - /* according definition, we derive cross product is (plane[1],-plane[0],0), en cos = plane[2]);*/ - - /* translating this comment to english didnt really help me understanding the math! :-) (ton) */ - - q[1] = plane[1]; - q[2] = -plane[0]; - q[3] = 0; - normalize_v3(&q[1]); - - angle = saacos(plane[2]) / 2.0f; - co = cosf(angle); - si = sqrtf(1 - co * co); - - q[0] = co; - q[1] *= si; - q[2] *= si; - q[3] = 0; - - quat_to_mat3(mat1, q); - - /* rotate lamp vector now over acos(inp) degrees */ - copy_v3_v3(vvec, lvec); - - unit_m3(mat2); - co = inp; - si = sqrtf(1.0f - inp * inp); - - mat2[0][0] = co; - mat2[1][0] = -si; - mat2[0][1] = si; - mat2[1][1] = co; - mul_m3_m3m3(mat3, mat2, mat1); - - mat2[1][0] = si; - mat2[0][1] = -si; - mul_m3_m3m3(mat4, mat2, mat1); - transpose_m3(mat1); - - mul_m3_m3m3(mat2, mat1, mat3); - mul_m3_v3(mat2, lvec); - mul_m3_m3m3(mat2, mat1, mat4); - mul_m3_v3(mat2, vvec); -} - -static void draw_spot_cone(Lamp *la, float x, float z, unsigned pos) -{ - z = fabsf(z); - - const bool square = (la->mode & LA_SQUARE); - - immBegin(GWN_PRIM_TRI_FAN, square ? 6 : 34); - immVertex3f(pos, 0.0f, 0.0f, -x); - - if (square) { - immVertex3f(pos, z, z, 0); - immVertex3f(pos, -z, z, 0); - immVertex3f(pos, -z, -z, 0); - immVertex3f(pos, z, -z, 0); - immVertex3f(pos, z, z, 0); - } - else { - for (int a = 0; a < 33; a++) { - float angle = a * M_PI * 2 / (33 - 1); - immVertex3f(pos, z * cosf(angle), z * sinf(angle), 0.0f); - } - } - - immEnd(); -} - -static void draw_transp_spot_volume(Lamp *la, float x, float z, unsigned pos) -{ - glEnable(GL_CULL_FACE); - glEnable(GL_BLEND); - glDepthMask(GL_FALSE); - - /* draw backside darkening */ - glCullFace(GL_FRONT); - - glBlendFunc(GL_ZERO, GL_SRC_ALPHA); - immUniformColor4f(0.0f, 0.0f, 0.0f, 0.4f); - - draw_spot_cone(la, x, z, pos); - - /* draw front side lighting */ - glCullFace(GL_BACK); - - glBlendFunc(GL_ONE, GL_ONE); - immUniformColor3f(0.2f, 0.2f, 0.2f); - - draw_spot_cone(la, x, z, pos); - - /* restore state */ - glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - glDisable(GL_BLEND); - glDepthMask(GL_TRUE); - glDisable(GL_CULL_FACE); -} - -void drawlamp(View3D *v3d, RegionView3D *rv3d, Base *base, - const char dt, const short dflag, const unsigned char ob_wire_col[4], const bool is_obact) -{ - Object *ob = base->object; - const float pixsize = ED_view3d_pixel_size(rv3d, ob->obmat[3]); - Lamp *la = ob->data; - float vec[3], lvec[3], vvec[3], circrad; - float imat[4][4]; - - /* cone can't be drawn for duplicated lamps, because duplilist would be freed */ - /* the moment of view3d_draw_transp() call */ - const bool is_view = (rv3d->persp == RV3D_CAMOB && v3d->camera == base->object); - const bool drawcone = ((dt > OB_WIRE) && - !(G.f & G_PICKSEL) && - (la->type == LA_SPOT) && - (la->mode & LA_SHOW_CONE) && - !(base->flag_legacy & OB_FROMDUPLI) && - !is_view); - - if (drawcone && !v3d->transp) { - /* in this case we need to draw delayed */ - ED_view3d_after_add(&v3d->afterdraw_transp, base, dflag); - return; - } - - /* we first draw only the screen aligned & fixed scale stuff */ - gpuPushMatrix(); - gpuLoadMatrix(rv3d->viewmat); - - /* lets calculate the scale: */ - const float lampsize_px = U.obcenter_dia; - const float lampsize = pixsize * lampsize_px * 0.5f; - - /* and view aligned matrix: */ - copy_m4_m4(imat, rv3d->viewinv); - normalize_v3(imat[0]); - normalize_v3(imat[1]); - - const unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - - /* lamp center */ - copy_v3_v3(vec, ob->obmat[3]); - - float curcol[4]; - if ((dflag & DRAW_CONSTCOLOR) == 0) { - /* for AA effects */ - rgb_uchar_to_float(curcol, ob_wire_col); - curcol[3] = 0.6f; - /* TODO: pay attention to GL_BLEND */ - } - - glLineWidth(1.0f); - setlinestyle(3); - - if (lampsize > 0.0f) { - const float outlineWidth = 1.5f * U.pixelsize; - const float lampdot_size = lampsize_px * U.pixelsize + outlineWidth; - - /* Inner Circle */ - if ((dflag & DRAW_CONSTCOLOR) == 0) { - const float *color = curcol; - if (ob->id.us > 1) { - if (is_obact || ((base->flag & BASE_SELECTED) != 0)) { - static const float active_color[4] = {0.533f, 1.0f, 1.0f, 1.0f}; - color = active_color; - } - else { - static const float inactive_color[4] = {0.467f, 0.8f, 0.8f, 1.0f}; - color = inactive_color; - } - } - - GPU_enable_program_point_size(); - glEnable(GL_BLEND); - glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - - immBindBuiltinProgram(GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA); - immUniform1f("size", lampdot_size); - immUniform1f("outlineWidth", outlineWidth); - immUniformColor3fvAlpha(color, 0.3f); - immUniform4fv("outlineColor", color); - - immBegin(GWN_PRIM_POINTS, 1); - immVertex3fv(pos, vec); - immEnd(); - - immUnbindProgram(); - - glDisable(GL_BLEND); - GPU_disable_program_point_size(); - } - else { - /* CONSTCOLOR in effect */ - /* TODO: separate picking from drawing */ - immBindBuiltinProgram(GPU_SHADER_3D_POINT_FIXED_SIZE_UNIFORM_COLOR); - /* color doesn't matter, so don't set */ - glPointSize(lampdot_size); - - immBegin(GWN_PRIM_POINTS, 1); - immVertex3fv(pos, vec); - immEnd(); - - immUnbindProgram(); - } - - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - /* TODO(merwin): short term, use DEPTH_ONLY for picking - * long term, separate picking from drawing - */ - - /* restore */ - if ((dflag & DRAW_CONSTCOLOR) == 0) { - immUniformColor4fv(curcol); - } - - /* Outer circle */ - circrad = 3.0f * lampsize; - - imm_drawcircball(vec, circrad, imat, pos); - - /* draw dashed outer circle if shadow is on. remember some lamps can't have certain shadows! */ - if (la->type != LA_HEMI) { - if ((la->mode & LA_SHAD_RAY) || ((la->mode & LA_SHAD_BUF) && (la->type == LA_SPOT))) { - imm_drawcircball(vec, circrad + 3.0f * pixsize, imat, pos); - } - } - } - else { - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - if ((dflag & DRAW_CONSTCOLOR) == 0) { - immUniformColor4fv(curcol); - } - circrad = 0.0f; - } - - /* draw the pretty sun rays */ - if (la->type == LA_SUN) { - float v1[3], v2[3], mat[3][3]; - short axis; - - /* setup a 45 degree rotation matrix */ - axis_angle_normalized_to_mat3_ex(mat, imat[2], M_SQRT1_2, M_SQRT1_2); - - /* vectors */ - mul_v3_v3fl(v1, imat[0], circrad * 1.2f); - mul_v3_v3fl(v2, imat[0], circrad * 2.5f); - - /* center */ - gpuPushMatrix(); - gpuTranslate3fv(vec); - - setlinestyle(3); - - immBegin(GWN_PRIM_LINES, 16); - for (axis = 0; axis < 8; axis++) { - immVertex3fv(pos, v1); - immVertex3fv(pos, v2); - mul_m3_v3(mat, v1); - mul_m3_v3(mat, v2); - } - immEnd(); - - gpuPopMatrix(); - } - - if (la->type == LA_LOCAL) { - if (la->mode & LA_SPHERE) { - imm_drawcircball(vec, la->dist, imat, pos); - } - } - - gpuPopMatrix(); /* back in object space */ - zero_v3(vec); - - if (is_view) { - /* skip drawing extra info */ - } - else if (la->type == LA_SPOT) { - float x, y, z, z_abs; - copy_v3_fl3(lvec, 0.0f, 0.0f, 1.0f); - copy_v3_fl3(vvec, rv3d->persmat[0][2], rv3d->persmat[1][2], rv3d->persmat[2][2]); - mul_transposed_mat3_m4_v3(ob->obmat, vvec); - - x = -la->dist; - y = cosf(la->spotsize * 0.5f); - z = x * sqrtf(1.0f - y * y); - - spotvolume(lvec, vvec, y); - mul_v3_fl(lvec, x); - mul_v3_fl(vvec, x); - - x *= y; - - z_abs = fabsf(z); - - if (la->mode & LA_SQUARE) { - /* draw pyramid */ - const float vertices[5][3] = { - /* 5 of vertex coords of pyramid */ - {0.0f, 0.0f, 0.0f}, - {z_abs, z_abs, x}, - {-z_abs, -z_abs, x}, - {z_abs, -z_abs, x}, - {-z_abs, z_abs, x}, - }; - - immBegin(GWN_PRIM_LINES, 16); - for (int i = 1; i <= 4; ++i) { - immVertex3fv(pos, vertices[0]); /* apex to corner */ - immVertex3fv(pos, vertices[i]); - int next_i = (i == 4) ? 1 : (i + 1); - immVertex3fv(pos, vertices[i]); /* corner to next corner */ - immVertex3fv(pos, vertices[next_i]); - } - immEnd(); - - gpuTranslate3f(0.0f, 0.0f, x); - - /* draw the square representing spotbl */ - if (la->type == LA_SPOT) { - float blend = z_abs * (1.0f - pow2f(la->spotblend)); - - /* hide line if it is zero size or overlaps with outer border, - * previously it adjusted to always to show it but that seems - * confusing because it doesn't show the actual blend size */ - if (blend != 0.0f && blend != z_abs) { - imm_draw_box_wire_3d(pos, blend, -blend, -blend, blend); - } - } - } - else { - /* draw the angled sides of the cone */ - immBegin(GWN_PRIM_LINE_STRIP, 3); - immVertex3fv(pos, vvec); - immVertex3fv(pos, vec); - immVertex3fv(pos, lvec); - immEnd(); - - /* draw the circle at the end of the cone */ - gpuTranslate3f(0.0f, 0.0f, x); - imm_draw_circle_wire_3d(pos, 0.0f, 0.0f, z_abs, 32); - - /* draw the circle representing spotbl */ - if (la->type == LA_SPOT) { - float blend = z_abs * (1.0f - pow2f(la->spotblend)); - - /* hide line if it is zero size or overlaps with outer border, - * previously it adjusted to always to show it but that seems - * confusing because it doesn't show the actual blend size */ - if (blend != 0.0f && blend != z_abs) { - imm_draw_circle_wire_3d(pos, 0.0f, 0.0f, blend, 32); - } - } - } - - if (drawcone) - draw_transp_spot_volume(la, x, z, pos); - - /* draw clip start, useful for wide cones where its not obvious where the start is */ - gpuTranslate3f(0.0f, 0.0f, -x); /* reverse translation above */ - immBegin(GWN_PRIM_LINES, 2); - if (la->type == LA_SPOT && (la->mode & LA_SHAD_BUF)) { - float lvec_clip[3]; - float vvec_clip[3]; - float clipsta_fac = la->clipsta / -x; - - interp_v3_v3v3(lvec_clip, vec, lvec, clipsta_fac); - interp_v3_v3v3(vvec_clip, vec, vvec, clipsta_fac); - - immVertex3fv(pos, lvec_clip); - immVertex3fv(pos, vvec_clip); - } - /* Else, draw spot direction (using distance as end limit, same as for Area lamp). */ - else { - immVertex3f(pos, 0.0f, 0.0f, -circrad); - immVertex3f(pos, 0.0f, 0.0f, -la->dist); - } - immEnd(); - } - else if (ELEM(la->type, LA_HEMI, LA_SUN)) { - /* draw the line from the circle along the dist */ - immBegin(GWN_PRIM_LINES, 2); - vec[2] = -circrad; - immVertex3fv(pos, vec); - vec[2] = -la->dist; - immVertex3fv(pos, vec); - immEnd(); - - if (la->type == LA_HEMI) { - /* draw the hemisphere curves */ - short axis, steps, dir; - float outdist, zdist, mul; - zero_v3(vec); - outdist = 0.14f; mul = 1.4f; dir = 1; - - setlinestyle(4); - /* loop over the 4 compass points, and draw each arc as a LINE_STRIP */ - for (axis = 0; axis < 4; axis++) { - float v[3] = {0.0f, 0.0f, 0.0f}; - zdist = 0.02f; - - immBegin(GWN_PRIM_LINE_STRIP, 6); - - for (steps = 0; steps < 6; steps++) { - if (axis == 0 || axis == 1) { /* x axis up, x axis down */ - /* make the arcs start at the edge of the energy circle */ - if (steps == 0) v[0] = dir * circrad; - else v[0] = v[0] + dir * (steps * outdist); - } - else if (axis == 2 || axis == 3) { /* y axis up, y axis down */ - /* make the arcs start at the edge of the energy circle */ - v[1] = (steps == 0) ? (dir * circrad) : (v[1] + dir * (steps * outdist)); - } - - v[2] = v[2] - steps * zdist; - - immVertex3fv(pos, v); - - zdist = zdist * mul; - } - - immEnd(); - /* flip the direction */ - dir = -dir; - } - } - - } - else if (la->type == LA_AREA) { - setlinestyle(3); - if (la->area_shape == LA_AREA_SQUARE) - imm_draw_box_wire_3d(pos, -la->area_size * 0.5f, -la->area_size * 0.5f, la->area_size * 0.5f, la->area_size * 0.5f); - else if (la->area_shape == LA_AREA_RECT) - imm_draw_box_wire_3d(pos, -la->area_size * 0.5f, -la->area_sizey * 0.5f, la->area_size * 0.5f, la->area_sizey * 0.5f); - - immBegin(GWN_PRIM_LINES, 2); - immVertex3f(pos, 0.0f, 0.0f, -circrad); - immVertex3f(pos, 0.0f, 0.0f, -la->dist); - immEnd(); - } - - /* and back to viewspace */ - gpuPushMatrix(); - gpuLoadMatrix(rv3d->viewmat); - copy_v3_v3(vec, ob->obmat[3]); - - setlinestyle(0); - - if ((la->type == LA_SPOT) && (la->mode & LA_SHAD_BUF) && (is_view == false)) { - drawshadbuflimits(la, ob->obmat, pos); - } - - if ((dflag & DRAW_CONSTCOLOR) == 0) { - immUniformThemeColor(TH_LAMP); - } - - glEnable(GL_BLEND); - - if (vec[2] > 0) vec[2] -= circrad; - else vec[2] += circrad; - - immBegin(GWN_PRIM_LINES, 2); - immVertex3fv(pos, vec); - vec[2] = 0; - immVertex3fv(pos, vec); - immEnd(); - - glPointSize(2.0f); - immBegin(GWN_PRIM_POINTS, 1); - immVertex3fv(pos, vec); - immEnd(); - - glDisable(GL_BLEND); - - immUnbindProgram(); - gpuPopMatrix(); -} - -static void draw_limit_line(float sta, float end, const short dflag, const unsigned char col[3], unsigned pos) -{ - immBegin(GWN_PRIM_LINES, 2); - immVertex3f(pos, 0.0f, 0.0f, -sta); - immVertex3f(pos, 0.0f, 0.0f, -end); - immEnd(); - - if (!(dflag & DRAW_PICKING)) { - glPointSize(3.0f); - /* would like smooth round points here, but that means binding another shader... - * if it's really desired, pull these points into their own function to be called after */ - immBegin(GWN_PRIM_POINTS, 2); - if ((dflag & DRAW_CONSTCOLOR) == 0) { - immUniformColor3ubv(col); - } - immVertex3f(pos, 0.0f, 0.0f, -sta); - immVertex3f(pos, 0.0f, 0.0f, -end); - immEnd(); - } -} - - -/* yafray: draw camera focus point (cross, similar to aqsis code in tuhopuu) */ -/* qdn: now also enabled for Blender to set focus point for defocus composite node */ -static void draw_focus_cross(float dist, float size, unsigned pos) -{ - immBegin(GWN_PRIM_LINES, 4); - immVertex3f(pos, -size, 0.0f, -dist); - immVertex3f(pos, size, 0.0f, -dist); - immVertex3f(pos, 0.0f, -size, -dist); - immVertex3f(pos, 0.0f, size, -dist); - immEnd(); -} - #ifdef VIEW3D_CAMERA_BORDER_HACK unsigned char view3d_camera_border_hack_col[3]; bool view3d_camera_border_hack_test = false; #endif -/* ****************** draw clip data *************** */ - -static void draw_viewport_object_reconstruction( - Scene *scene, Base *base, const View3D *v3d, const RegionView3D *rv3d, - MovieClip *clip, MovieTrackingObject *tracking_object, - const short dflag, const unsigned char ob_wire_col[4], - int *global_track_index, bool draw_selected) -{ - MovieTracking *tracking = &clip->tracking; - MovieTrackingTrack *track; - float mat[4][4], imat[4][4]; - unsigned char col_unsel[4], col_sel[4]; - int tracknr = *global_track_index; - ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, tracking_object); - float camera_size[3]; - - UI_GetThemeColor4ubv(TH_TEXT, col_unsel); - UI_GetThemeColor4ubv(TH_SELECT, col_sel); - - BKE_tracking_get_camera_object_matrix(scene, base->object, mat); - - /* we're compensating camera size for bundles size, - * to make it so bundles are always displayed with the same size */ - copy_v3_v3(camera_size, base->object->size); - if ((tracking_object->flag & TRACKING_OBJECT_CAMERA) == 0) - mul_v3_fl(camera_size, tracking_object->scale); - - gpuPushMatrix(); - - if (tracking_object->flag & TRACKING_OBJECT_CAMERA) { - /* current ogl matrix is translated in camera space, bundles should - * be rendered in world space, so camera matrix should be "removed" - * from current ogl matrix */ - invert_m4_m4(imat, base->object->obmat); - - gpuMultMatrix(imat); - gpuMultMatrix(mat); - } - else { - float obmat[4][4]; - int framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, scene->r.cfra); - - BKE_tracking_camera_get_reconstructed_interpolate(tracking, tracking_object, framenr, obmat); - - invert_m4_m4(imat, obmat); - gpuMultMatrix(imat); - } - - for (track = tracksbase->first; track; track = track->next) { - bool selected = TRACK_SELECTED(track); - - if (draw_selected && !selected) - continue; - - if ((track->flag & TRACK_HAS_BUNDLE) == 0) - continue; - - if (dflag & DRAW_PICKING) - GPU_select_load_id(base->object->select_color + (tracknr << 16)); - - gpuPushMatrix(); - gpuTranslate3fv(track->bundle_pos); - gpuScale3f(v3d->bundle_size / 0.05f / camera_size[0], - v3d->bundle_size / 0.05f / camera_size[1], - v3d->bundle_size / 0.05f / camera_size[2]); - - const int v3d_drawtype = view3d_effective_drawtype(v3d); - if (v3d_drawtype == OB_WIRE) { - unsigned char color[4]; - const unsigned char *color_ptr = NULL; - if ((dflag & DRAW_CONSTCOLOR) == 0) { - if (selected && (track->flag & TRACK_CUSTOMCOLOR) == 0) { - color_ptr = ob_wire_col; - } - else { - rgba_float_to_uchar(color, track->color); - color_ptr = color; - } - } - - drawaxes(rv3d->viewmatob, 0.05f, v3d->bundle_drawtype, color_ptr); - } - else if (v3d_drawtype > OB_WIRE) { - if (v3d->bundle_drawtype == OB_EMPTY_SPHERE) { - Gwn_Batch *batch; - - gpuScaleUniform(0.05f); - - /* selection outline */ - if (selected) { - batch = GPU_batch_preset_sphere_wire(1); - - if ((dflag & DRAW_CONSTCOLOR) == 0) { - GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR); - GWN_batch_uniform_4f(batch, "color", - ob_wire_col[0] / 255.f, - ob_wire_col[1] / 255.f, - ob_wire_col[2] / 255.f, 1.0f); - } - else { - GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_DEPTH_ONLY); - } - glLineWidth(2.0f); - - GWN_batch_draw(batch); - } - - batch = GPU_batch_preset_sphere(0); - - if ((dflag & DRAW_CONSTCOLOR) == 0) { - const float light[3] = {0.0f, 0.0f, 1.0f}; - float col[3]; - GWN_batch_program_set_builtin(batch, GPU_SHADER_SIMPLE_LIGHTING); - GWN_batch_uniform_3fv(batch, "light", light); - - if (track->flag & TRACK_CUSTOMCOLOR) copy_v3_v3(col, track->color); - else UI_GetThemeColor3fv(TH_BUNDLE_SOLID, col); - GWN_batch_uniform_4f(batch, "color", col[0], col[1], col[2], 1.0f); - } - else { - GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_DEPTH_ONLY); - } - - GWN_batch_draw(batch); - } - else { - unsigned char color[4]; - const unsigned char *color_ptr = NULL; - if ((dflag & DRAW_CONSTCOLOR) == 0) { - if (selected) { - color_ptr = ob_wire_col; - } - else { - if (track->flag & TRACK_CUSTOMCOLOR) rgba_float_to_uchar(color, track->color); - else UI_GetThemeColor4ubv(TH_WIRE, color); - - color_ptr = color; - } - } - - drawaxes(rv3d->viewmatob, 0.05f, v3d->bundle_drawtype, color_ptr); - } - } - - gpuPopMatrix(); - - if ((dflag & DRAW_PICKING) == 0 && (v3d->flag2 & V3D_SHOW_BUNDLENAME)) { - float pos[3]; - - mul_v3_m4v3(pos, mat, track->bundle_pos); - view3d_cached_text_draw_add(pos, - track->name, strlen(track->name), - 10, V3D_CACHE_TEXT_GLOBALSPACE, - selected ? col_sel : col_unsel); - } - - tracknr++; - } - - if ((dflag & DRAW_PICKING) == 0) { - if ((v3d->flag2 & V3D_SHOW_CAMERAPATH) && (tracking_object->flag & TRACKING_OBJECT_CAMERA)) { - MovieTrackingReconstruction *reconstruction; - reconstruction = BKE_tracking_object_get_reconstruction(tracking, tracking_object); - - if (reconstruction->camnr >= 2) { - MovieReconstructedCamera *camera = reconstruction->cameras; - unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - immUniformThemeColor(TH_CAMERA_PATH); - - glLineWidth(2.0f); - - immBegin(GWN_PRIM_LINE_STRIP, reconstruction->camnr); - for (int a = 0; a < reconstruction->camnr; a++, camera++) { - immVertex3fv(pos, camera->mat[3]); - } - immEnd(); - - immUnbindProgram(); - } - } - } - - gpuPopMatrix(); - - *global_track_index = tracknr; -} - -static void draw_viewport_reconstruction( - Scene *scene, Base *base, const View3D *v3d, const RegionView3D *rv3d, MovieClip *clip, - const short dflag, const unsigned char ob_wire_col[4], - const bool draw_selected) -{ - MovieTracking *tracking = &clip->tracking; - MovieTrackingObject *tracking_object; - int global_track_index = 1; - - if ((v3d->flag2 & V3D_SHOW_RECONSTRUCTION) == 0) - return; - - if (v3d->flag2 & V3D_RENDER_OVERRIDE) - return; - - GPU_basic_shader_colors(NULL, NULL, 0, 1.0f); - GPU_basic_shader_bind(GPU_SHADER_LIGHTING | GPU_SHADER_USE_COLOR); - - tracking_object = tracking->objects.first; - while (tracking_object) { - draw_viewport_object_reconstruction( - scene, base, v3d, rv3d, clip, tracking_object, - dflag, ob_wire_col, &global_track_index, draw_selected); - - tracking_object = tracking_object->next; - } - - /* restore */ - GPU_basic_shader_bind(GPU_SHADER_USE_COLOR); - - if (dflag & DRAW_PICKING) - GPU_select_load_id(base->object->select_color); -} - -/* camera frame */ -static void drawcamera_frame(float vec[4][3], bool filled, unsigned pos) -{ - immBegin(filled ? GWN_PRIM_TRI_FAN : GWN_PRIM_LINE_LOOP, 4); - immVertex3fv(pos, vec[0]); - immVertex3fv(pos, vec[1]); - immVertex3fv(pos, vec[2]); - immVertex3fv(pos, vec[3]); - immEnd(); -} - -/* center point to camera frame */ -static void drawcamera_framelines(float vec[4][3], float origin[3], unsigned pos) -{ - immBegin(GWN_PRIM_LINES, 8); - immVertex3fv(pos, origin); - immVertex3fv(pos, vec[0]); - immVertex3fv(pos, origin); - immVertex3fv(pos, vec[1]); - immVertex3fv(pos, origin); - immVertex3fv(pos, vec[2]); - immVertex3fv(pos, origin); - immVertex3fv(pos, vec[3]); - immEnd(); -} - -static void drawcamera_volume(float near_plane[4][3], float far_plane[4][3], bool filled, unsigned pos) -{ - drawcamera_frame(near_plane, filled, pos); - drawcamera_frame(far_plane, filled, pos); - - if (filled) { - immBegin(GWN_PRIM_TRI_STRIP, 10); - - immVertex3fv(pos, near_plane[0]); - immVertex3fv(pos, far_plane[0]); - immVertex3fv(pos, near_plane[1]); - immVertex3fv(pos, far_plane[1]); - immVertex3fv(pos, near_plane[2]); - immVertex3fv(pos, far_plane[2]); - immVertex3fv(pos, near_plane[3]); - immVertex3fv(pos, far_plane[3]); - immVertex3fv(pos, near_plane[0]); - immVertex3fv(pos, far_plane[0]); - - immEnd(); - } - else { - immBegin(GWN_PRIM_LINES, 8); - for (int i = 0; i < 4; ++i) { - immVertex3fv(pos, near_plane[i]); - immVertex3fv(pos, far_plane[i]); - } - immEnd(); - } -} - -static bool drawcamera_is_stereo3d(Scene *scene, View3D *v3d, Object *ob) -{ - return (ob == v3d->camera) && - (scene->r.scemode & R_MULTIVIEW) != 0 && - (v3d->stereo3d_flag); -} - -static void drawcamera_stereo3d( - Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, const Camera *cam, - float vec[4][3], float drawsize, const float scale[3], unsigned pos) -{ - float obmat[4][4]; - float vec_lr[2][4][3]; - const float fac = (cam->stereo.pivot == CAM_S3D_PIVOT_CENTER) ? 2.0f : 1.0f; - float origin[2][3] = {{0}}; - float tvec[3]; - const Camera *cam_lr[2]; - const char *names[2] = {STEREO_LEFT_NAME, STEREO_RIGHT_NAME}; - - const bool is_stereo3d_cameras = (v3d->stereo3d_flag & V3D_S3D_DISPCAMERAS) && (scene->r.views_format == SCE_VIEWS_FORMAT_STEREO_3D); - const bool is_stereo3d_plane = (v3d->stereo3d_flag & V3D_S3D_DISPPLANE) && (scene->r.views_format == SCE_VIEWS_FORMAT_STEREO_3D); - const bool is_stereo3d_volume = (v3d->stereo3d_flag & V3D_S3D_DISPVOLUME); - - zero_v3(tvec); - - /* caller bound GPU_SHADER_3D_UNIFORM_COLOR, passed in pos attribute ID */ - - for (int i = 0; i < 2; i++) { - ob = BKE_camera_multiview_render(scene, ob, names[i]); - cam_lr[i] = ob->data; - - gpuLoadMatrix(rv3d->viewmat); - BKE_camera_multiview_model_matrix(&scene->r, ob, names[i], obmat); - gpuMultMatrix(obmat); - - copy_m3_m3(vec_lr[i], vec); - copy_v3_v3(vec_lr[i][3], vec[3]); - - if (cam->stereo.convergence_mode == CAM_S3D_OFFAXIS) { - const float shift_x = - ((BKE_camera_multiview_shift_x(&scene->r, ob, names[i]) - cam->shiftx) * - (drawsize * scale[0] * fac)); - - for (int j = 0; j < 4; j++) { - vec_lr[i][j][0] += shift_x; - } - } - - if (is_stereo3d_cameras) { - /* camera frame */ - drawcamera_frame(vec_lr[i], false, pos); - - /* center point to camera frame */ - drawcamera_framelines(vec_lr[i], tvec, pos); - } - - /* connecting line */ - mul_m4_v3(obmat, origin[i]); - - /* convergence plane */ - if (is_stereo3d_plane || is_stereo3d_volume) { - for (int j = 0; j < 4; j++) { - mul_m4_v3(obmat, vec_lr[i][j]); - } - } - } - - /* the remaining drawing takes place in the view space */ - gpuLoadMatrix(rv3d->viewmat); - - if (is_stereo3d_cameras) { - /* draw connecting lines */ - glLineStipple(2, 0xAAAA); - glEnable(GL_LINE_STIPPLE); - - immBegin(GWN_PRIM_LINES, 2); - immVertex3fv(pos, origin[0]); - immVertex3fv(pos, origin[1]); - immEnd(); - - glDisable(GL_LINE_STIPPLE); - } - - /* draw convergence plane */ - if (is_stereo3d_plane) { - float axis_center[3], screen_center[3]; - float world_plane[4][3]; - float local_plane[4][3]; - float offset; - - mid_v3_v3v3(axis_center, origin[0], origin[1]); - - for (int i = 0; i < 4; i++) { - mid_v3_v3v3(world_plane[i], vec_lr[0][i], vec_lr[1][i]); - sub_v3_v3v3(local_plane[i], world_plane[i], axis_center); - } - - mid_v3_v3v3(screen_center, world_plane[0], world_plane[2]); - offset = cam->stereo.convergence_distance / len_v3v3(screen_center, axis_center); - - for (int i = 0; i < 4; i++) { - mul_v3_fl(local_plane[i], offset); - add_v3_v3(local_plane[i], axis_center); - } - - immUniformColor3f(0.0f, 0.0f, 0.0f); - - /* camera frame */ - drawcamera_frame(local_plane, false, pos); - - if (v3d->stereo3d_convergence_alpha > 0.0f) { - glEnable(GL_BLEND); - glDepthMask(GL_FALSE); /* disable write in zbuffer, needed for nice transp */ - - immUniformColor4f(0.0f, 0.0f, 0.0f, v3d->stereo3d_convergence_alpha); - - drawcamera_frame(local_plane, true, pos); - - glDisable(GL_BLEND); - glDepthMask(GL_TRUE); /* restore write in zbuffer */ - } - } - - /* draw convergence plane */ - if (is_stereo3d_volume) { - float screen_center[3]; - float near_plane[4][3], far_plane[4][3]; - - for (int i = 0; i < 2; i++) { - mid_v3_v3v3(screen_center, vec_lr[i][0], vec_lr[i][2]); - - float offset = len_v3v3(screen_center, origin[i]); - - for (int j = 0; j < 4; j++) { - sub_v3_v3v3(near_plane[j], vec_lr[i][j], origin[i]); - mul_v3_fl(near_plane[j], cam_lr[i]->clipsta / offset); - add_v3_v3(near_plane[j], origin[i]); - - sub_v3_v3v3(far_plane[j], vec_lr[i][j], origin[i]); - mul_v3_fl(far_plane[j], cam_lr[i]->clipend / offset); - add_v3_v3(far_plane[j], origin[i]); - } - - /* camera frame */ - immUniformColor3f(0.0f, 0.0f, 0.0f); - - drawcamera_volume(near_plane, far_plane, false, pos); - - if (v3d->stereo3d_volume_alpha > 0.0f) { - glEnable(GL_BLEND); - glDepthMask(GL_FALSE); /* disable write in zbuffer, needed for nice transp */ - - if (i == 0) - immUniformColor4f(0.0f, 1.0f, 1.0f, v3d->stereo3d_volume_alpha); - else - immUniformColor4f(1.0f, 0.0f, 0.0f, v3d->stereo3d_volume_alpha); - - drawcamera_volume(near_plane, far_plane, true, pos); - - glDisable(GL_BLEND); - glDepthMask(GL_TRUE); /* restore write in zbuffer */ - } - } - } -} - -/* flag similar to draw_object() */ -void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, - const short dflag, const unsigned char ob_wire_col[4]) -{ - /* a standing up pyramid with (0,0,0) as top */ - Camera *cam; - Object *ob = base->object; - float tvec[3]; - float vec[4][3], asp[2], shift[2], scale[3]; - MovieClip *clip = BKE_object_movieclip_get(scene, base->object, false); - - const bool is_active = (ob == v3d->camera); - const bool is_view = (rv3d->persp == RV3D_CAMOB && is_active); - const bool is_multiview = (scene->r.scemode & R_MULTIVIEW) != 0; - const bool is_stereo3d = drawcamera_is_stereo3d(scene, v3d, ob); - const bool is_stereo3d_view = (scene->r.views_format == SCE_VIEWS_FORMAT_STEREO_3D); - const bool is_stereo3d_cameras = (ob == scene->camera) && - is_multiview && - is_stereo3d_view && - (v3d->stereo3d_flag & V3D_S3D_DISPCAMERAS); - const bool is_selection_camera_stereo = (G.f & G_PICKSEL) && - is_view && is_multiview && - is_stereo3d_view; - - /* draw data for movie clip set as active for scene */ - if (clip) { - draw_viewport_reconstruction(scene, base, v3d, rv3d, clip, dflag, ob_wire_col, false); - draw_viewport_reconstruction(scene, base, v3d, rv3d, clip, dflag, ob_wire_col, true); - } - -#ifdef VIEW3D_CAMERA_BORDER_HACK - if (is_view && !(G.f & G_PICKSEL)) { - if ((dflag & DRAW_CONSTCOLOR) == 0) { - view3d_camera_border_hack_col[0] = ob_wire_col[0]; - view3d_camera_border_hack_col[1] = ob_wire_col[1]; - view3d_camera_border_hack_col[2] = ob_wire_col[2]; - } - else { - float col[4]; - glGetFloatv(GL_CURRENT_COLOR, col); - rgb_float_to_uchar(view3d_camera_border_hack_col, col); - } - view3d_camera_border_hack_test = true; - return; - } -#endif - - cam = ob->data; - - /* BKE_camera_multiview_model_matrix already accounts for scale, don't do it here */ - if (is_selection_camera_stereo) { - scale[0] = 1.0f; - scale[1] = 1.0f; - scale[2] = 1.0f; - } - else { - scale[0] = 1.0f / len_v3(ob->obmat[0]); - scale[1] = 1.0f / len_v3(ob->obmat[1]); - scale[2] = 1.0f / len_v3(ob->obmat[2]); - } - - float drawsize; - BKE_camera_view_frame_ex(scene, cam, cam->drawsize, is_view, scale, - asp, shift, &drawsize, vec); - - unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - if (ob_wire_col) { - immUniformColor3ubv(ob_wire_col); - } - glLineWidth(1.0f); - - /* camera frame */ - if (!is_stereo3d_cameras) { - /* make sure selection uses the same matrix for camera as the one used while viewing */ - if (is_selection_camera_stereo) { - float obmat[4][4]; - bool is_left = v3d->multiview_eye == STEREO_LEFT_ID; - - gpuPushMatrix(); - gpuLoadMatrix(rv3d->viewmat); - BKE_camera_multiview_model_matrix(&scene->r, ob, is_left ? STEREO_LEFT_NAME : STEREO_RIGHT_NAME, obmat); - gpuMultMatrix(obmat); - - drawcamera_frame(vec, false, pos); - gpuPopMatrix(); - } - else { - drawcamera_frame(vec, false, pos); - } - } - - if (is_view) { - immUnbindProgram(); - return; - } - - zero_v3(tvec); - - /* center point to camera frame */ - if (!is_stereo3d_cameras) - drawcamera_framelines(vec, tvec, pos); - - /* arrow on top */ - tvec[2] = vec[1][2]; /* copy the depth */ - - /* draw an outline arrow for inactive cameras and filled - * for active cameras. We actually draw both outline+filled - * for active cameras so the wire can be seen side-on */ - for (int i = 0; i < 2; i++) { - if (i == 0) immBegin(GWN_PRIM_LINE_LOOP, 3); - else if (i == 1 && is_active) { - glDisable(GL_CULL_FACE); /* TODO: declarative state tracking */ - immBegin(GWN_PRIM_TRIS, 3); - } - else break; - - tvec[0] = shift[0] + ((-0.7f * drawsize) * scale[0]); - tvec[1] = shift[1] + ((drawsize * (asp[1] + 0.1f)) * scale[1]); - immVertex3fv(pos, tvec); /* left */ - - tvec[0] = shift[0] + ((0.7f * drawsize) * scale[0]); - immVertex3fv(pos, tvec); /* right */ - - tvec[0] = shift[0]; - tvec[1] = shift[1] + ((1.1f * drawsize * (asp[1] + 0.7f)) * scale[1]); - immVertex3fv(pos, tvec); /* top */ - - immEnd(); - } - - if ((dflag & DRAW_SCENESET) == 0) { - if (cam->flag & (CAM_SHOWLIMITS | CAM_SHOWMIST)) { - float nobmat[4][4]; - - /* draw in normalized object matrix space */ - copy_m4_m4(nobmat, ob->obmat); - normalize_m4(nobmat); - - gpuLoadMatrix(rv3d->viewmat); - gpuMultMatrix(nobmat); - - if (cam->flag & CAM_SHOWLIMITS) { - const unsigned char col[3] = {128, 128, 60}, col_hi[3] = {255, 255, 120}; - - draw_limit_line(cam->clipsta, cam->clipend, dflag, (is_active ? col_hi : col), pos); - /* qdn: was yafray only, now also enabled for Blender to be used with defocus composite node */ - draw_focus_cross(BKE_camera_object_dof_distance(ob), cam->drawsize, pos); - } - - if (cam->flag & CAM_SHOWMIST) { - World *world = scene->world; - const unsigned char col[3] = {128, 128, 128}, col_hi[3] = {255, 255, 255}; - - if (world) { - draw_limit_line(world->miststa, world->miststa + world->mistdist, - dflag, (is_active ? col_hi : col), pos); - } - } - } - } - - /* stereo cameras drawing */ - if (is_stereo3d) { - drawcamera_stereo3d(scene, v3d, rv3d, ob, cam, vec, drawsize, scale, pos); - } - - immUnbindProgram(); -} - -/* flag similar to draw_object() */ -void drawspeaker(const unsigned char ob_wire_col[3]) -{ - Gwn_VertFormat *format = immVertexFormat(); - unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - - if (ob_wire_col) { - immUniformColor3ubv(ob_wire_col); - } - - glLineWidth(1.0f); - - const int segments = 16; - - for (int j = 0; j < 3; j++) { - float z = 0.25f * j - 0.125f; - - immBegin(GWN_PRIM_LINE_LOOP, segments); - for (int i = 0; i < segments; i++) { - float x = cosf((float)M_PI * i / 8.0f) * (j == 0 ? 0.5f : 0.25f); - float y = sinf((float)M_PI * i / 8.0f) * (j == 0 ? 0.5f : 0.25f); - immVertex3f(pos, x, y, z); - } - immEnd(); - } - - for (int j = 0; j < 4; j++) { - float x = (((j + 1) % 2) * (j - 1)) * 0.5f; - float y = ((j % 2) * (j - 2)) * 0.5f; - immBegin(GWN_PRIM_LINE_STRIP, 3); - for (int i = 0; i < 3; i++) { - if (i == 1) { - x *= 0.5f; - y *= 0.5f; - } - - float z = 0.25f * i - 0.125f; - immVertex3f(pos, x, y, z); - } - immEnd(); - } - - immUnbindProgram(); -} - -static void lattice_draw_verts(Lattice *lt, DispList *dl, BPoint *actbp, short sel, - unsigned int pos, unsigned int color) -{ - BPoint *bp = lt->def; - const float *co = dl ? dl->verts : NULL; - float active_color[4], draw_color[4]; - - UI_GetThemeColor4fv(sel ? TH_VERTEX_SELECT : TH_VERTEX, draw_color); - UI_GetThemeColor4fv(TH_ACTIVE_VERT, active_color); - - glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE)); - immBeginAtMost(GWN_PRIM_POINTS, lt->pntsw * lt->pntsv * lt->pntsu); - - for (int w = 0; w < lt->pntsw; w++) { - int wxt = (w == 0 || w == lt->pntsw - 1); - for (int v = 0; v < lt->pntsv; v++) { - int vxt = (v == 0 || v == lt->pntsv - 1); - for (int u = 0; u < lt->pntsu; u++, bp++, co += 3) { - int uxt = (u == 0 || u == lt->pntsu - 1); - if (!(lt->flag & LT_OUTSIDE) || uxt || vxt || wxt) { - if (bp->hide == 0) { - /* check for active BPoint and ensure selected */ - if ((bp == actbp) && (bp->f1 & SELECT)) { - immAttrib4fv(color, active_color); - immVertex3fv(pos, dl ? co : bp->vec); - } - else if ((bp->f1 & SELECT) == sel) { - immAttrib4fv(color, draw_color); - immVertex3fv(pos, dl ? co : bp->vec); - } - } - } - } - } - } - - immEnd(); -} - -static void drawlattice__point(Lattice *lt, DispList *dl, int u, int v, int w, int actdef_wcol, - unsigned int pos, unsigned int color) -{ - int index = ((w * lt->pntsv + v) * lt->pntsu) + u; - - if (actdef_wcol) { - float col[3]; - MDeformWeight *mdw = defvert_find_index(lt->dvert + index, actdef_wcol - 1); - weight_to_rgb(col, mdw ? mdw->weight : 0.0f); - immAttrib3fv(color, col); - } - - if (dl) { - immVertex3fv(pos, &dl->verts[index * 3]); - } - else { - immVertex3fv(pos, lt->def[index].vec); - } -} - -#ifdef SEQUENCER_DAG_WORKAROUND -static void ensure_curve_cache( - Depsgraph *depsgraph, Scene *scene, Object *object) -{ - bool need_recalc = object->curve_cache == NULL; - /* Render thread might have freed the curve cache if the - * object is not visible. If the object is also used for - * particles duplication, then render thread might have - * also created curve_cache with only bevel and path - * filled in. - * - * So check for curve_cache != NULL is not fully correct - * here, we also need to check whether display list is - * empty or not. - * - * The trick below tries to optimize calls to displist - * creation for cases curve is empty. Meaning, if the curve - * is empty (without splines) bevel list would also be empty. - * And the thing is, render thread always leaves bevel list - * in a proper state. So if bevel list is here and display - * list is not we need to make display list. - */ - if (need_recalc == false) { - need_recalc = object->curve_cache->disp.first == NULL && - object->curve_cache->bev.first != NULL; - } - if (need_recalc) { - switch (object->type) { - case OB_CURVE: - case OB_SURF: - case OB_FONT: - BKE_displist_make_curveTypes(depsgraph, scene, object, false); - break; - case OB_MBALL: - BKE_displist_make_mball(depsgraph, scene, object); - break; - case OB_LATTICE: - BKE_lattice_modifiers_calc(depsgraph, scene, object); - break; - } - } -} -#endif - -/* lattice color is hardcoded, now also shows weightgroup values in edit mode */ -static void drawlattice(View3D *v3d, Object *ob, const short dflag, const unsigned char ob_wire_col[4]) -{ - Lattice *lt = ob->data; - DispList *dl; - int u, v, w; - int actdef_wcol = 0; - const bool is_edit = (lt->editlatt != NULL); - - dl = BKE_displist_find(&ob->curve_cache->disp, DL_VERTS); - - if (is_edit) { - lt = lt->editlatt->latt; - - if (ob->defbase.first && lt->dvert) { - actdef_wcol = ob->actdef; - } - } - - Gwn_VertFormat *format = immVertexFormat(); - unsigned int color, pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - - if (actdef_wcol) { - color = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_3D_SMOOTH_COLOR); - } - else { - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - - if (is_edit) { - immUniformThemeColor(TH_WIRE_EDIT); - } - else { - if ((dflag & DRAW_CONSTCOLOR) == 0) { - immUniformColor3ubv(ob_wire_col); - } - else { - immUniformColor3f(0.0f, 0.0f, 0.0f); - } - } - } - - glLineWidth(1.0f); - immBeginAtMost(GWN_PRIM_LINES, lt->pntsw * lt->pntsv * lt->pntsu * 6); - - for (w = 0; w < lt->pntsw; w++) { - int wxt = (w == 0 || w == lt->pntsw - 1); - for (v = 0; v < lt->pntsv; v++) { - int vxt = (v == 0 || v == lt->pntsv - 1); - for (u = 0; u < lt->pntsu; u++) { - int uxt = (u == 0 || u == lt->pntsu - 1); - - if (w && ((uxt || vxt) || !(lt->flag & LT_OUTSIDE))) { - drawlattice__point(lt, dl, u, v, w - 1, actdef_wcol, pos, color); - drawlattice__point(lt, dl, u, v, w, actdef_wcol, pos, color); - } - if (v && ((uxt || wxt) || !(lt->flag & LT_OUTSIDE))) { - drawlattice__point(lt, dl, u, v - 1, w, actdef_wcol, pos, color); - drawlattice__point(lt, dl, u, v, w, actdef_wcol, pos, color); - } - if (u && ((vxt || wxt) || !(lt->flag & LT_OUTSIDE))) { - drawlattice__point(lt, dl, u - 1, v, w, actdef_wcol, pos, color); - drawlattice__point(lt, dl, u, v, w, actdef_wcol, pos, color); - } - } - } - } - - immEnd(); - immUnbindProgram(); - - if (is_edit) { - BPoint *actbp = BKE_lattice_active_point_get(lt); - - if (v3d->zbuf) glDisable(GL_DEPTH_TEST); - - Gwn_VertFormat *v_format = immVertexFormat(); - unsigned int v_pos = GWN_vertformat_attr_add(v_format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - unsigned int v_color = GWN_vertformat_attr_add(v_format, "color", GWN_COMP_F32, 4, GWN_FETCH_FLOAT); - - immBindBuiltinProgram(GPU_SHADER_3D_POINT_FIXED_SIZE_VARYING_COLOR); - - lattice_draw_verts(lt, dl, actbp, 0, v_pos, v_color); - lattice_draw_verts(lt, dl, actbp, 1, v_pos, v_color); - - immUnbindProgram(); - - if (v3d->zbuf) glEnable(GL_DEPTH_TEST); - } -} - -/* ***************** ******************** */ - -/* draw callback */ - -typedef struct drawDMVertSel_userData { - MVert *mvert; - int active; - unsigned char *col[3]; /* (base, sel, act) */ - char sel_prev; - unsigned int pos, color; -} drawDMVertSel_userData; - -static void drawSelectedVertices__mapFunc(void *userData, int index, const float co[3], - const float UNUSED(no_f[3]), const short UNUSED(no_s[3])) -{ - drawDMVertSel_userData *data = userData; - MVert *mv = &data->mvert[index]; - - if (!(mv->flag & ME_HIDE)) { - const char sel = (index == data->active) ? 2 : (mv->flag & SELECT); - if (sel != data->sel_prev) { - immAttrib3ubv(data->color, data->col[sel]); - data->sel_prev = sel; - } - - immVertex3fv(data->pos, co); - } -} - -static void drawSelectedVertices(DerivedMesh *dm, Mesh *me) -{ - drawDMVertSel_userData data; - Gwn_VertFormat *format = immVertexFormat(); - - /* TODO define selected color */ - unsigned char base_col[3] = {0x0, 0x0, 0x0}; - unsigned char sel_col[3] = {0xd8, 0xb8, 0x0}; - unsigned char act_col[3] = {0xff, 0xff, 0xff}; - - data.mvert = me->mvert; - data.active = BKE_mesh_mselect_active_get(me, ME_VSEL); - data.sel_prev = 0xff; - - data.col[0] = base_col; - data.col[1] = sel_col; - data.col[2] = act_col; - - data.color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 3, GWN_FETCH_INT_TO_FLOAT_UNIT); - data.pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - - if (dm->getNumVerts(dm) == 0) return; - - immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR); - - immBeginAtMost(GWN_PRIM_POINTS, dm->getNumVerts(dm)); - dm->foreachMappedVert(dm, drawSelectedVertices__mapFunc, &data, DM_FOREACH_NOP); - immEnd(); - - immUnbindProgram(); -} - -/* ************** DRAW MESH ****************** */ - -/* First section is all the "simple" draw routines, - * ones that just pass some sort of primitive to GL, - * with perhaps various options to control lighting, - * color, etc. - * - * These routines should not have user interface related - * logic!!! - */ - -static void calcDrawDMNormalScale(Object *ob, drawDMNormal_userData *data) -{ - float obmat[3][3]; - - copy_m3_m4(obmat, ob->obmat); - - data->uniform_scale = is_uniform_scaled_m3(obmat); - - if (!data->uniform_scale) { - /* inverted matrix */ - invert_m3_m3(data->imat, obmat); - - /* transposed inverted matrix */ - transpose_m3_m3(data->tmat, data->imat); - } -} - -static void draw_dm_face_normals__mapFunc(void *userData, int index, const float cent[3], const float no[3]) -{ - drawDMNormal_userData *data = userData; - BMFace *efa = BM_face_at_index(data->bm, index); - float n[3]; - - if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { - if (!data->uniform_scale) { - mul_v3_m3v3(n, data->tmat, no); - normalize_v3(n); - mul_m3_v3(data->imat, n); - } - else { - copy_v3_v3(n, no); - } - - immVertex3fv(data->pos, cent); - immVertex3f(data->pos, cent[0] + n[0] * data->normalsize, - cent[1] + n[1] * data->normalsize, - cent[2] + n[2] * data->normalsize); - } -} - -static void draw_dm_face_normals(BMEditMesh *em, Scene *scene, Object *ob, DerivedMesh *dm, int theme_id) -{ - Gwn_VertFormat *format = immVertexFormat(); - drawDMNormal_userData data; - - data.bm = em->bm; - data.normalsize = scene->toolsettings->normalsize; - data.pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - - calcDrawDMNormalScale(ob, &data); - - if (dm->getNumPolys(dm) == 0) return; - - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - immUniformThemeColor(theme_id); - - immBeginAtMost(GWN_PRIM_LINES, dm->getNumPolys(dm) * 2); - dm->foreachMappedFaceCenter(dm, draw_dm_face_normals__mapFunc, &data, DM_FOREACH_USE_NORMAL); - immEnd(); - - immUnbindProgram(); -} - -static void draw_dm_face_centers__mapFunc(void *userData, int index, const float cent[3], const float UNUSED(no[3])) -{ - drawBMSelect_userData *data = userData; - BMFace *efa = BM_face_at_index(data->bm, index); - - if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN) && - (BM_elem_flag_test(efa, BM_ELEM_SELECT) == data->select)) - { - immVertex3fv(data->pos, cent); - } -} -static void draw_dm_face_centers(BMEditMesh *em, DerivedMesh *dm, bool select, const unsigned char fcol[3]) -{ - Gwn_VertFormat *format = immVertexFormat(); - - drawBMSelect_userData data; - data.bm = em->bm; - data.select = select; - data.pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - - if (dm->getNumPolys(dm) == 0) return; - - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - immUniformColor3ubv(fcol); - - immBeginAtMost(GWN_PRIM_POINTS, dm->getNumPolys(dm)); - dm->foreachMappedFaceCenter(dm, draw_dm_face_centers__mapFunc, &data, DM_FOREACH_NOP); - immEnd(); - - immUnbindProgram(); -} - -static void draw_dm_vert_normals__mapFunc(void *userData, int index, const float co[3], const float no_f[3], const short no_s[3]) -{ - drawDMNormal_userData *data = userData; - BMVert *eve = BM_vert_at_index(data->bm, index); - - if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) { - float no[3], n[3]; - - if (no_f) { - copy_v3_v3(no, no_f); - } - else { - normal_short_to_float_v3(no, no_s); - } - - if (!data->uniform_scale) { - mul_v3_m3v3(n, data->tmat, no); - normalize_v3(n); - mul_m3_v3(data->imat, n); - } - else { - copy_v3_v3(n, no); - } - - immVertex3fv(data->pos, co); - immVertex3f(data->pos, co[0] + n[0] * data->normalsize, - co[1] + n[1] * data->normalsize, - co[2] + n[2] * data->normalsize); - } -} - -static void draw_dm_vert_normals(BMEditMesh *em, Scene *scene, Object *ob, DerivedMesh *dm, int theme_id) -{ - drawDMNormal_userData data; - Gwn_VertFormat *format = immVertexFormat(); - - data.bm = em->bm; - data.normalsize = scene->toolsettings->normalsize; - data.pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - - calcDrawDMNormalScale(ob, &data); - - if (dm->getNumVerts(dm) == 0) return; - - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - immUniformThemeColor(theme_id); - - immBeginAtMost(GWN_PRIM_LINES, dm->getNumVerts(dm) * 2); - dm->foreachMappedVert(dm, draw_dm_vert_normals__mapFunc, &data, DM_FOREACH_USE_NORMAL); - immEnd(); - - immUnbindProgram(); -} - -static void draw_dm_verts_skin_root__mapFunc(void *userData, int index, const float co[3], - const float UNUSED(no_f[3]), const short UNUSED(no_s[3])) -{ - drawDMVerts_userData *data = userData; - BMVert *eve = BM_vert_at_index(data->bm, index); - - if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN) && BM_elem_flag_test(eve, BM_ELEM_SELECT) == data->sel) { - /* skin nodes: draw a red circle around the root node(s) */ - const MVertSkin *vs = BM_ELEM_CD_GET_VOID_P(eve, data->cd_vskin_offset); - if (vs->flag & MVERT_SKIN_ROOT) { - float radius = (vs->radius[0] + vs->radius[1]) * 0.5f; - imm_drawcircball(co, radius, data->imat, data->pos); - } - } -} - -/* Draw verts with color set based on selection */ -static void draw_dm_verts__mapFunc(void *userData, int index, const float co[3], - const float UNUSED(no_f[3]), const short UNUSED(no_s[3])) -{ - drawDMVerts_userData *data = userData; - BMVert *eve = BM_vert_at_index(data->bm, index); - - if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN) && BM_elem_flag_test(eve, BM_ELEM_SELECT) == data->sel) { - /* draw active in a different color - no need to stop/start point drawing for this :D */ - if (eve == data->eve_act) { - immAttrib4ubv(data->color, data->th_editmesh_active); - immVertex3fv(data->pos, co); - } - else { - immAttrib4ubv(data->color, data->sel ? data->th_vertex_select : data->th_vertex); - immVertex3fv(data->pos, co); - } - } -} - -static void draw_dm_verts(BMEditMesh *em, DerivedMesh *dm, const char sel, BMVert *eve_act, - RegionView3D *rv3d, const unsigned char col[4]) -{ - Gwn_VertFormat *format = immVertexFormat(); - - drawDMVerts_userData data; - data.sel = sel; - data.eve_act = eve_act; - data.bm = em->bm; - data.pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - data.color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT); - - /* Cache theme values */ - UI_GetThemeColor4ubv(TH_EDITMESH_ACTIVE, data.th_editmesh_active); - UI_GetThemeColor4ubv(TH_VERTEX_SELECT, data.th_vertex_select); - UI_GetThemeColor4ubv(TH_VERTEX, data.th_vertex); - UI_GetThemeColor4ubv(TH_SKIN_ROOT, data.th_skin_root); - - /* Set correct alpha */ - data.th_editmesh_active[3] = data.th_vertex_select[3] = data.th_vertex[3] = data.th_skin_root[3] = col[3]; - - /* view-aligned matrix */ - mul_m4_m4m4(data.imat, rv3d->viewmat, em->ob->obmat); - invert_m4(data.imat); - - if (dm->getNumVerts(dm) == 0) return; - - immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR); - - glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE)); - - immBeginAtMost(GWN_PRIM_POINTS, dm->getNumVerts(dm)); - dm->foreachMappedVert(dm, draw_dm_verts__mapFunc, &data, DM_FOREACH_NOP); - immEnd(); - - immUnbindProgram(); - - /* For skin root drawing */ - data.cd_vskin_offset = CustomData_get_offset(&em->bm->vdata, CD_MVERT_SKIN); - - if (data.cd_vskin_offset != -1) { - data.pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - immUniformColor4ubv(data.th_skin_root); - - dm->foreachMappedVert(dm, draw_dm_verts_skin_root__mapFunc, &data, DM_FOREACH_NOP); - - immUnbindProgram(); - } -} - -/* Draw edges with color set based on selection */ -static DMDrawOption draw_dm_edges_sel__setDrawOptions(void *userData, int index) -{ - BMEdge *eed; - drawDMEdgesSel_userData *data = userData; - unsigned char *col; - - eed = BM_edge_at_index(data->bm, index); - - if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { - if (eed == data->eed_act) { - glColor4ubv(data->actCol); - } - else { - if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) { - col = data->selCol; - } - else { - col = data->baseCol; - } - /* no alpha, this is used so a transparent color can disable drawing unselected edges in editmode */ - if (col[3] == 0) - return DM_DRAW_OPTION_SKIP; - - glColor4ubv(col); - } - return DM_DRAW_OPTION_NORMAL; - } - else { - return DM_DRAW_OPTION_SKIP; - } -} - -static void draw_dm_edges_sel(BMEditMesh *em, DerivedMesh *dm, unsigned char *baseCol, - unsigned char *selCol, unsigned char *actCol, BMEdge *eed_act) -{ - drawDMEdgesSel_userData data; - - data.baseCol = baseCol; - data.selCol = selCol; - data.actCol = actCol; - data.bm = em->bm; - data.eed_act = eed_act; - dm->drawMappedEdges(dm, draw_dm_edges_sel__setDrawOptions, &data); -} - -/* Draw edges */ -static DMDrawOption draw_dm_edges__setDrawOptions(void *userData, int index) -{ - if (BM_elem_flag_test(BM_edge_at_index(userData, index), BM_ELEM_HIDDEN)) - return DM_DRAW_OPTION_SKIP; - else - return DM_DRAW_OPTION_NORMAL; -} - -static void draw_dm_edges(BMEditMesh *em, DerivedMesh *dm) -{ - dm->drawMappedEdges(dm, draw_dm_edges__setDrawOptions, em->bm); -} - -/* Draw edges with color interpolated based on selection */ -static DMDrawOption draw_dm_edges_sel_interp__setDrawOptions(void *userData, int index) -{ - drawDMEdgesSelInterp_userData *data = userData; - if (BM_elem_flag_test(BM_edge_at_index(data->bm, index), BM_ELEM_HIDDEN)) - return DM_DRAW_OPTION_SKIP; - else - return DM_DRAW_OPTION_NORMAL; -} -static void draw_dm_edges_sel_interp__setDrawInterpOptions(void *userData, int index, float t) -{ - drawDMEdgesSelInterp_userData *data = userData; - BMEdge *eed = BM_edge_at_index(data->bm, index); - unsigned char **cols = userData; - unsigned int col0_id = (BM_elem_flag_test(eed->v1, BM_ELEM_SELECT)) ? 2 : 1; - unsigned int col1_id = (BM_elem_flag_test(eed->v2, BM_ELEM_SELECT)) ? 2 : 1; - unsigned char *col0 = cols[col0_id]; - unsigned char *col1 = cols[col1_id]; - unsigned char *col_pt; - - if (col0_id == col1_id) { - col_pt = col0; - } - else if (t == 0.0f) { - col_pt = col0; - } - else if (t == 1.0f) { - col_pt = col1; - } - else { - unsigned char col_blend[4]; - interp_v4_v4v4_uchar(col_blend, col0, col1, t); - glColor4ubv(col_blend); - data->lastCol = NULL; - return; - } - - if (data->lastCol != col_pt) { - data->lastCol = col_pt; - glColor4ubv(col_pt); - } -} - -static void draw_dm_edges_sel_interp(BMEditMesh *em, DerivedMesh *dm, unsigned char *baseCol, unsigned char *selCol) -{ - drawDMEdgesSelInterp_userData data; - data.bm = em->bm; - data.baseCol = baseCol; - data.selCol = selCol; - data.lastCol = NULL; - - dm->drawMappedEdgesInterp(dm, draw_dm_edges_sel_interp__setDrawOptions, draw_dm_edges_sel_interp__setDrawInterpOptions, &data); -} - -static void bm_color_from_weight(float col[3], BMVert *vert, drawDMEdgesWeightInterp_userData *data) -{ - MDeformVert *dvert = BM_ELEM_CD_GET_VOID_P(vert, data->cd_dvert_offset); - float weight = defvert_find_weight(dvert, data->vgroup_index); - - if ((weight == 0.0f) && - ((data->weight_user == OB_DRAW_GROUPUSER_ACTIVE) || - ((data->weight_user == OB_DRAW_GROUPUSER_ALL) && defvert_is_weight_zero(dvert, data->defgroup_tot)))) - { - copy_v3_v3(col, data->alert_color); - } - else { - weight_to_rgb(col, weight); - } -} - -static void draw_dm_edges_nop_interp__setDrawInterpOptions(void *UNUSED(userData), int UNUSED(index), float UNUSED(t)) -{ - /* pass */ -} - -static void draw_dm_edges_weight_interp__setDrawInterpOptions(void *userData, int index, float t) -{ - drawDMEdgesWeightInterp_userData *data = userData; - BMEdge *eed = BM_edge_at_index(data->bm, index); - float col[3]; - - if (t == 0.0f) { - bm_color_from_weight(col, eed->v1, data); - } - else if (t == 1.0f) { - bm_color_from_weight(col, eed->v2, data); - } - else { - float col_v1[3]; - float col_v2[3]; - - bm_color_from_weight(col_v1, eed->v1, data); - bm_color_from_weight(col_v2, eed->v2, data); - interp_v3_v3v3(col, col_v1, col_v2, t); - } - - glColor3fv(col); -} - -static void draw_dm_edges_weight_interp(BMEditMesh *em, DerivedMesh *dm, const char weight_user) -{ - drawDMEdgesWeightInterp_userData data; - Object *ob = em->ob; - - data.bm = em->bm; - data.cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT); - data.defgroup_tot = BLI_listbase_count(&ob->defbase); - data.vgroup_index = ob->actdef - 1; - data.weight_user = weight_user; - UI_GetThemeColor3fv(TH_VERTEX_UNREFERENCED, data.alert_color); - - if ((data.vgroup_index != -1) && (data.cd_dvert_offset != -1)) { - glEnable(GL_BLEND); - dm->drawMappedEdgesInterp( - dm, - draw_dm_edges_sel_interp__setDrawOptions, - draw_dm_edges_weight_interp__setDrawInterpOptions, - &data); - glDisable(GL_BLEND); - } - else { - float col[3]; - - if (data.weight_user == OB_DRAW_GROUPUSER_NONE) { - weight_to_rgb(col, 0.0f); - } - else { - copy_v3_v3(col, data.alert_color); - } - glColor3fv(col); - - dm->drawMappedEdgesInterp( - dm, - draw_dm_edges_sel_interp__setDrawOptions, - draw_dm_edges_nop_interp__setDrawInterpOptions, - &data); - } - -} - -static bool draw_dm_edges_weight_check(Mesh *me, View3D *v3d) -{ - if (me->drawflag & ME_DRAWEIGHT) { - if ((v3d->drawtype == OB_WIRE) || - (v3d->flag2 & V3D_SOLID_MATCAP) || - ((v3d->flag2 & V3D_OCCLUDE_WIRE) && (v3d->drawtype > OB_WIRE))) - { - return true; - } - } - - return false; -} - -/* Draw only seam edges */ -static DMDrawOption draw_dm_edges_seams__setDrawOptions(void *userData, int index) -{ - BMEdge *eed = BM_edge_at_index(userData, index); - - if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN) && BM_elem_flag_test(eed, BM_ELEM_SEAM)) - return DM_DRAW_OPTION_NORMAL; - else - return DM_DRAW_OPTION_SKIP; -} - -static void draw_dm_edges_seams(BMEditMesh *em, DerivedMesh *dm) -{ - dm->drawMappedEdges(dm, draw_dm_edges_seams__setDrawOptions, em->bm); -} - -/* Draw only sharp edges */ -static DMDrawOption draw_dm_edges_sharp__setDrawOptions(void *userData, int index) -{ - BMEdge *eed = BM_edge_at_index(userData, index); - - if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN) && !BM_elem_flag_test(eed, BM_ELEM_SMOOTH)) - return DM_DRAW_OPTION_NORMAL; - else - return DM_DRAW_OPTION_SKIP; -} - -static void draw_dm_edges_sharp(BMEditMesh *em, DerivedMesh *dm) -{ - dm->drawMappedEdges(dm, draw_dm_edges_sharp__setDrawOptions, em->bm); -} - -#ifdef WITH_FREESTYLE - -static bool draw_dm_test_freestyle_edge_mark(BMesh *bm, BMEdge *eed) -{ - FreestyleEdge *fed = CustomData_bmesh_get(&bm->edata, eed->head.data, CD_FREESTYLE_EDGE); - if (!fed) - return false; - return (fed->flag & FREESTYLE_EDGE_MARK) != 0; -} - -/* Draw only Freestyle feature edges */ -static DMDrawOption draw_dm_edges_freestyle__setDrawOptions(void *userData, int index) -{ - BMEdge *eed = BM_edge_at_index(userData, index); - - if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN) && draw_dm_test_freestyle_edge_mark(userData, eed)) - return DM_DRAW_OPTION_NORMAL; - else - return DM_DRAW_OPTION_SKIP; -} - -static void draw_dm_edges_freestyle(BMEditMesh *em, DerivedMesh *dm) -{ - dm->drawMappedEdges(dm, draw_dm_edges_freestyle__setDrawOptions, em->bm); -} - -static bool draw_dm_test_freestyle_face_mark(BMesh *bm, BMFace *efa) -{ - FreestyleFace *ffa = CustomData_bmesh_get(&bm->pdata, efa->head.data, CD_FREESTYLE_FACE); - if (!ffa) - return false; - return (ffa->flag & FREESTYLE_FACE_MARK) != 0; -} - -#endif - -/* Draw loop normals. */ -static void draw_dm_loop_normals__mapFunc(void *userData, int vertex_index, int face_index, - const float co[3], const float no[3]) -{ - if (no) { - const drawDMNormal_userData *data = userData; - const BMVert *eve = BM_vert_at_index(data->bm, vertex_index); - const BMFace *efa = BM_face_at_index(data->bm, face_index); - float vec[3]; - - if (!(BM_elem_flag_test(eve, BM_ELEM_HIDDEN) || BM_elem_flag_test(efa, BM_ELEM_HIDDEN))) { - if (!data->uniform_scale) { - mul_v3_m3v3(vec, (float(*)[3])data->tmat, no); - normalize_v3(vec); - mul_m3_v3((float(*)[3])data->imat, vec); - } - else { - copy_v3_v3(vec, no); - } - mul_v3_fl(vec, data->normalsize); - add_v3_v3(vec, co); - immVertex3fv(data->pos, co); - immVertex3fv(data->pos, vec); - } - } -} - -static void draw_dm_loop_normals(BMEditMesh *em, Scene *scene, Object *ob, DerivedMesh *dm, int theme_id) -{ - drawDMNormal_userData data; - - data.bm = em->bm; - data.normalsize = scene->toolsettings->normalsize; - data.pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - - if (dm->getNumLoops(dm) == 0) return; - - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - immUniformThemeColor(theme_id); - - calcDrawDMNormalScale(ob, &data); - - immBeginAtMost(GWN_PRIM_LINES, dm->getNumLoops(dm) * 2); - dm->foreachMappedLoop(dm, draw_dm_loop_normals__mapFunc, &data, DM_FOREACH_USE_NORMAL); - immEnd(); - - immUnbindProgram(); -} - -/* Draw faces with color set based on selection - * return 2 for the active face so it renders with stipple enabled */ -static DMDrawOption draw_dm_faces_sel__setDrawOptions(void *userData, int index) -{ - drawDMFacesSel_userData *data = userData; - BMFace *efa = BM_face_at_index(data->bm, index); - unsigned char *col; - - if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { - if (efa == data->efa_act) { - glColor4ubv(data->cols[2]); - return DM_DRAW_OPTION_STIPPLE; - } - else { -#ifdef WITH_FREESTYLE - col = data->cols[BM_elem_flag_test(efa, BM_ELEM_SELECT) ? 1 : draw_dm_test_freestyle_face_mark(data->bm, efa) ? 3 : 0]; -#else - col = data->cols[BM_elem_flag_test(efa, BM_ELEM_SELECT) ? 1 : 0]; -#endif - if (col[3] == 0) - return DM_DRAW_OPTION_SKIP; - glColor4ubv(col); - return DM_DRAW_OPTION_NORMAL; - } - } - return DM_DRAW_OPTION_SKIP; -} - -static int draw_dm_faces_sel__compareDrawOptions(void *userData, int index, int next_index) -{ - - drawDMFacesSel_userData *data = userData; - int i; - BMFace *efa; - BMFace *next_efa; - - unsigned char *col, *next_col; - - i = data->orig_index_mp_to_orig ? data->orig_index_mp_to_orig[index] : index; - efa = (i != ORIGINDEX_NONE) ? BM_face_at_index(data->bm, i) : NULL; - i = data->orig_index_mp_to_orig ? data->orig_index_mp_to_orig[next_index] : next_index; - next_efa = (i != ORIGINDEX_NONE) ? BM_face_at_index(data->bm, i) : NULL; - - if (ELEM(NULL, efa, next_efa)) - return 0; - - if (efa == next_efa) - return 1; - - if (efa == data->efa_act || next_efa == data->efa_act) - return 0; - -#ifdef WITH_FREESTYLE - col = data->cols[BM_elem_flag_test(efa, BM_ELEM_SELECT) ? 1 : draw_dm_test_freestyle_face_mark(data->bm, efa) ? 3 : 0]; - next_col = data->cols[BM_elem_flag_test(next_efa, BM_ELEM_SELECT) ? 1 : draw_dm_test_freestyle_face_mark(data->bm, efa) ? 3 : 0]; -#else - col = data->cols[BM_elem_flag_test(efa, BM_ELEM_SELECT) ? 1 : 0]; - next_col = data->cols[BM_elem_flag_test(next_efa, BM_ELEM_SELECT) ? 1 : 0]; -#endif - - if (col[3] == 0 || next_col[3] == 0) - return 0; - - return col == next_col; -} - -/* also draws the active face */ -#ifdef WITH_FREESTYLE -static void draw_dm_faces_sel(BMEditMesh *em, DerivedMesh *dm, unsigned char *baseCol, - unsigned char *selCol, unsigned char *actCol, unsigned char *markCol, BMFace *efa_act) -#else -static void draw_dm_faces_sel(BMEditMesh *em, DerivedMesh *dm, unsigned char *baseCol, - unsigned char *selCol, unsigned char *actCol, BMFace *efa_act) -#endif -{ - drawDMFacesSel_userData data; - data.dm = dm; - data.cols[0] = baseCol; - data.bm = em->bm; - data.cols[1] = selCol; - data.cols[2] = actCol; -#ifdef WITH_FREESTYLE - data.cols[3] = markCol; -#endif - data.efa_act = efa_act; - /* double lookup */ - data.orig_index_mp_to_orig = DM_get_poly_data_layer(dm, CD_ORIGINDEX); - - dm->drawMappedFaces(dm, draw_dm_faces_sel__setDrawOptions, NULL, draw_dm_faces_sel__compareDrawOptions, &data, DM_DRAW_SKIP_HIDDEN); -} - -static DMDrawOption draw_dm_creases__setDrawOptions(void *userData, int index) -{ - drawDMLayer_userData *data = userData; - BMesh *bm = data->bm; - BMEdge *eed = BM_edge_at_index(bm, index); - - if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { - const float crease = BM_ELEM_CD_GET_FLOAT(eed, data->cd_layer_offset); - if (crease != 0.0f) { - UI_ThemeColorBlend(TH_WIRE_EDIT, TH_EDGE_CREASE, crease); - return DM_DRAW_OPTION_NORMAL; - } - } - return DM_DRAW_OPTION_SKIP; -} -static void draw_dm_creases(BMEditMesh *em, DerivedMesh *dm) -{ - drawDMLayer_userData data; - - data.bm = em->bm; - data.cd_layer_offset = CustomData_get_offset(&em->bm->edata, CD_CREASE); - - if (data.cd_layer_offset != -1) { - glLineWidth(3.0f); - dm->drawMappedEdges(dm, draw_dm_creases__setDrawOptions, &data); - } -} - -static DMDrawOption draw_dm_bweights__setDrawOptions(void *userData, int index) -{ - drawDMLayer_userData *data = userData; - BMesh *bm = data->bm; - BMEdge *eed = BM_edge_at_index(bm, index); - - if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { - const float bweight = BM_ELEM_CD_GET_FLOAT(eed, data->cd_layer_offset); - if (bweight != 0.0f) { - UI_ThemeColorBlend(TH_WIRE_EDIT, TH_EDGE_BEVEL, bweight); - return DM_DRAW_OPTION_NORMAL; - } - } - return DM_DRAW_OPTION_SKIP; -} -static void draw_dm_bweights__mapFunc(void *userData, int index, const float co[3], - const float UNUSED(no_f[3]), const short UNUSED(no_s[3])) -{ - drawDMLayer_userData *data = userData; - BMesh *bm = data->bm; - BMVert *eve = BM_vert_at_index(bm, index); - - if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) { - const float bweight = BM_ELEM_CD_GET_FLOAT(eve, data->cd_layer_offset); - if (bweight != 0.0f) { - unsigned char col[3]; - UI_GetThemeColorBlend3ubv(TH_VERTEX, TH_VERTEX_BEVEL, bweight, col); - immAttrib3ubv(data->col, col); - immVertex3fv(data->pos, co); - } - } -} -static void draw_dm_bweights(BMEditMesh *em, Scene *scene, DerivedMesh *dm) -{ - ToolSettings *ts = scene->toolsettings; - - if (ts->selectmode & SCE_SELECT_VERTEX) { - drawDMLayer_userData data; - - data.bm = em->bm; - data.cd_layer_offset = CustomData_get_offset(&em->bm->vdata, CD_BWEIGHT); - - /* is that ever true? */ - if (data.cd_layer_offset != -1) { - Gwn_VertFormat *format = immVertexFormat(); - data.pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - data.col = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT); - - immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR); - - glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE) + 2.0f); - - immBeginAtMost(GWN_PRIM_POINTS, dm->getNumVerts(dm)); - dm->foreachMappedVert(dm, draw_dm_bweights__mapFunc, &data, DM_FOREACH_NOP); - immEnd(); - - immUnbindProgram(); - } - } - else { - drawDMLayer_userData data; - - data.bm = em->bm; - data.cd_layer_offset = CustomData_get_offset(&em->bm->edata, CD_BWEIGHT); - - if (data.cd_layer_offset != -1) { - glLineWidth(3.0f); - dm->drawMappedEdges(dm, draw_dm_bweights__setDrawOptions, &data); - } - } -} - -/* Second section of routines: Combine first sets to form fancy - * drawing routines (for example rendering twice to get overlays). - * - * Also includes routines that are basic drawing but are too - * specialized to be split out (like drawing creases or measurements). - */ - -/* EditMesh drawing routines */ - -static void draw_em_fancy_verts(Scene *scene, View3D *v3d, Object *obedit, - BMEditMesh *em, DerivedMesh *cageDM, BMVert *eve_act, - RegionView3D *rv3d) -{ - ToolSettings *ts = scene->toolsettings; - - if (v3d->zbuf) glDepthMask(GL_FALSE); /* disable write in zbuffer, zbuf select */ - - for (int sel = 0; sel < 2; sel++) { - unsigned char col[4], fcol[4]; - - UI_GetThemeColor3ubv(sel ? TH_VERTEX_SELECT : TH_VERTEX, col); - UI_GetThemeColor3ubv(sel ? TH_FACE_DOT : TH_WIRE_EDIT, fcol); - - for (int pass = 0; pass < 2; pass++) { - float size = UI_GetThemeValuef(TH_VERTEX_SIZE); - float fsize = UI_GetThemeValuef(TH_FACEDOT_SIZE); - - if (pass == 0) { - if (v3d->zbuf && !(v3d->flag & V3D_ZBUF_SELECT)) { - glDisable(GL_DEPTH_TEST); - glEnable(GL_BLEND); - } - else { - continue; - } - - size = (size > 2.1f ? size / 2.0f : size); - fsize = (fsize > 2.1f ? fsize / 2.0f : fsize); - col[3] = fcol[3] = 100; - } - else { - col[3] = fcol[3] = 255; - } - - if (ts->selectmode & SCE_SELECT_VERTEX) { - draw_dm_verts(em, cageDM, sel, eve_act, rv3d, col); - } - - if (check_ob_drawface_dot(scene, v3d, obedit->dt)) { - glPointSize(fsize); - draw_dm_face_centers(em, cageDM, sel, fcol); - } - - if (pass == 0) { - glDisable(GL_BLEND); - glEnable(GL_DEPTH_TEST); - } - } - } - - if (v3d->zbuf) glDepthMask(GL_TRUE); -} - -static void draw_em_fancy_edges(BMEditMesh *em, Scene *scene, View3D *v3d, - Mesh *me, DerivedMesh *cageDM, short sel_only, - BMEdge *eed_act) -{ - ToolSettings *ts = scene->toolsettings; - unsigned char wireCol[4], selCol[4], actCol[4]; - - /* since this function does transparent... */ - UI_GetThemeColor4ubv(TH_EDGE_SELECT, selCol); - UI_GetThemeColor4ubv(TH_WIRE_EDIT, wireCol); - UI_GetThemeColor4ubv(TH_EDITMESH_ACTIVE, actCol); - - /* when sel only is used, don't render wire, only selected, this is used for - * textured draw mode when the 'edges' option is disabled */ - if (sel_only) - wireCol[3] = 0; - - for (int pass = 0; pass < 2; pass++) { - /* show wires in transparent when no zbuf clipping for select */ - if (pass == 0) { - if (v3d->zbuf && (v3d->flag & V3D_ZBUF_SELECT) == 0) { - glEnable(GL_BLEND); - glDisable(GL_DEPTH_TEST); - selCol[3] = 85; - if (!sel_only) wireCol[3] = 85; - } - else { - continue; - } - } - else { - selCol[3] = 255; - if (!sel_only) wireCol[3] = 255; - } - - if ((me->drawflag & ME_DRAWEDGES) || (ts->selectmode & SCE_SELECT_EDGE)) { - if (cageDM->drawMappedEdgesInterp && - ((ts->selectmode & SCE_SELECT_VERTEX) || (me->drawflag & ME_DRAWEIGHT))) - { - if (draw_dm_edges_weight_check(me, v3d)) { - // Interpolate vertex weights - draw_dm_edges_weight_interp(em, cageDM, ts->weightuser); - } - else if (ts->selectmode == SCE_SELECT_FACE) { - draw_dm_edges_sel(em, cageDM, wireCol, selCol, actCol, eed_act); - } - else { - // Interpolate vertex selection - draw_dm_edges_sel_interp(em, cageDM, wireCol, selCol); - } - } - else { - draw_dm_edges_sel(em, cageDM, wireCol, selCol, actCol, eed_act); - } - } - else { - if (!sel_only) { - glColor4ubv(wireCol); - draw_dm_edges(em, cageDM); - } - } - - if (pass == 0) { - glDisable(GL_BLEND); - glEnable(GL_DEPTH_TEST); - } - } -} - -static void draw_em_measure_stats(ARegion *ar, View3D *v3d, Object *ob, BMEditMesh *em, UnitSettings *unit) -{ - /* Do not use ascii when using non-default unit system, some unit chars are utf8 (micro, square, etc.). - * See bug #36090. - */ - const short txt_flag = V3D_CACHE_TEXT_LOCALCLIP | (unit->system ? 0 : V3D_CACHE_TEXT_ASCII); - Mesh *me = ob->data; - float v1[3], v2[3], v3[3], vmid[3], fvec[3]; - char numstr[32]; /* Stores the measurement display text here */ - size_t numstr_len; - const char *conv_float; /* Use a float conversion matching the grid size */ - unsigned char col[4] = {0, 0, 0, 255}; /* color of the text to draw */ - float area; /* area of the face */ - float grid = unit->system ? unit->scale_length : v3d->grid; - const bool do_split = (unit->flag & USER_UNIT_OPT_SPLIT) != 0; - const bool do_global = (v3d->flag & V3D_GLOBAL_STATS) != 0; - const bool do_moving = (G.moving & G_TRANSFORM_EDIT) != 0; - /* when 2 edge-info options are enabled, space apart */ - const bool do_edge_textpair = (me->drawflag & ME_DRAWEXTRA_EDGELEN) && (me->drawflag & ME_DRAWEXTRA_EDGEANG); - const float edge_texpair_sep = 0.4f; - float clip_planes[4][4]; - /* allow for displaying shape keys and deform mods */ - DerivedMesh *dm = EDBM_mesh_deform_dm_get(em); - BMIter iter; - - /* make the precision of the display value proportionate to the gridsize */ - - if (grid <= 0.01f) conv_float = "%.6g"; - else if (grid <= 0.1f) conv_float = "%.5g"; - else if (grid <= 1.0f) conv_float = "%.4g"; - else if (grid <= 10.0f) conv_float = "%.3g"; - else conv_float = "%.2g"; - - if (me->drawflag & (ME_DRAWEXTRA_EDGELEN | ME_DRAWEXTRA_EDGEANG)) { - BoundBox bb; - const rcti rect = {0, ar->winx, 0, ar->winy}; - - ED_view3d_clipping_calc(&bb, clip_planes, ar, em->ob, &rect); - } - - if (me->drawflag & ME_DRAWEXTRA_EDGELEN) { - BMEdge *eed; - - UI_GetThemeColor3ubv(TH_DRAWEXTRA_EDGELEN, col); - - if (dm) { - BM_mesh_elem_index_ensure(em->bm, BM_VERT); - } - - BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) { - /* draw selected edges, or edges next to selected verts while dragging */ - if (BM_elem_flag_test(eed, BM_ELEM_SELECT) || - (do_moving && (BM_elem_flag_test(eed->v1, BM_ELEM_SELECT) || - BM_elem_flag_test(eed->v2, BM_ELEM_SELECT)))) - { - float v1_clip[3], v2_clip[3]; - - if (dm) { - dm->getVertCo(dm, BM_elem_index_get(eed->v1), v1); - dm->getVertCo(dm, BM_elem_index_get(eed->v2), v2); - } - else { - copy_v3_v3(v1, eed->v1->co); - copy_v3_v3(v2, eed->v2->co); - } - - if (clip_segment_v3_plane_n(v1, v2, clip_planes, 4, v1_clip, v2_clip)) { - - if (do_edge_textpair) { - interp_v3_v3v3(vmid, v1, v2, edge_texpair_sep); - } - else { - mid_v3_v3v3(vmid, v1_clip, v2_clip); - } - - if (do_global) { - mul_mat3_m4_v3(ob->obmat, v1); - mul_mat3_m4_v3(ob->obmat, v2); - } - - if (unit->system) { - numstr_len = bUnit_AsString(numstr, sizeof(numstr), len_v3v3(v1, v2) * unit->scale_length, 3, - unit->system, B_UNIT_LENGTH, do_split, false); - } - else { - numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), conv_float, len_v3v3(v1, v2)); - } - - view3d_cached_text_draw_add(vmid, numstr, numstr_len, 0, txt_flag, col); - } - } - } - } - - if (me->drawflag & ME_DRAWEXTRA_EDGEANG) { - const bool is_rad = (unit->system_rotation == USER_UNIT_ROT_RADIANS); - BMEdge *eed; - - UI_GetThemeColor3ubv(TH_DRAWEXTRA_EDGEANG, col); - - if (dm) { - BM_mesh_elem_index_ensure(em->bm, BM_VERT | BM_FACE); - } - - BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) { - BMLoop *l_a, *l_b; - if (BM_edge_loop_pair(eed, &l_a, &l_b)) { - /* draw selected edges, or edges next to selected verts while dragging */ - if (BM_elem_flag_test(eed, BM_ELEM_SELECT) || - (do_moving && (BM_elem_flag_test(eed->v1, BM_ELEM_SELECT) || - BM_elem_flag_test(eed->v2, BM_ELEM_SELECT) || - /* special case, this is useful to show when verts connected to - * this edge via a face are being transformed */ - BM_elem_flag_test(l_a->next->next->v, BM_ELEM_SELECT) || - BM_elem_flag_test(l_a->prev->v, BM_ELEM_SELECT) || - BM_elem_flag_test(l_b->next->next->v, BM_ELEM_SELECT) || - BM_elem_flag_test(l_b->prev->v, BM_ELEM_SELECT) - ))) - { - float v1_clip[3], v2_clip[3]; - - if (dm) { - dm->getVertCo(dm, BM_elem_index_get(eed->v1), v1); - dm->getVertCo(dm, BM_elem_index_get(eed->v2), v2); - } - else { - copy_v3_v3(v1, eed->v1->co); - copy_v3_v3(v2, eed->v2->co); - } - - if (clip_segment_v3_plane_n(v1, v2, clip_planes, 4, v1_clip, v2_clip)) { - float no_a[3], no_b[3]; - float angle; - - if (do_edge_textpair) { - interp_v3_v3v3(vmid, v2_clip, v1_clip, edge_texpair_sep); - } - else { - mid_v3_v3v3(vmid, v1_clip, v2_clip); - } - - if (dm) { - dm->getPolyNo(dm, BM_elem_index_get(l_a->f), no_a); - dm->getPolyNo(dm, BM_elem_index_get(l_b->f), no_b); - } - else { - copy_v3_v3(no_a, l_a->f->no); - copy_v3_v3(no_b, l_b->f->no); - } - - if (do_global) { - mul_mat3_m4_v3(ob->imat, no_a); - mul_mat3_m4_v3(ob->imat, no_b); - normalize_v3(no_a); - normalize_v3(no_b); - } - - angle = angle_normalized_v3v3(no_a, no_b); - - numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%.3f", is_rad ? angle : RAD2DEGF(angle)); - - view3d_cached_text_draw_add(vmid, numstr, numstr_len, 0, txt_flag, col); - } - } - } - } - } - - if (me->drawflag & ME_DRAWEXTRA_FACEAREA) { - /* would be nice to use BM_face_calc_area, but that is for 2d faces - * so instead add up tessellation triangle areas */ - BMFace *f = NULL; - -#define DRAW_EM_MEASURE_STATS_FACEAREA() \ - if (BM_elem_flag_test(f, BM_ELEM_SELECT)) { \ - mul_v3_fl(vmid, 1.0f / (float)n); \ - if (unit->system) { \ - numstr_len = bUnit_AsString( \ - numstr, sizeof(numstr), \ - (double)(area * unit->scale_length * unit->scale_length), \ - 3, unit->system, B_UNIT_AREA, do_split, false); \ - } \ - else { \ - numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), conv_float, area); \ - } \ - view3d_cached_text_draw_add(vmid, numstr, numstr_len, 0, txt_flag, col); \ - } (void)0 - - UI_GetThemeColor3ubv(TH_DRAWEXTRA_FACEAREA, col); - - if (dm) { - BM_mesh_elem_index_ensure(em->bm, BM_VERT); - } - - area = 0.0; - zero_v3(vmid); - int n = 0; - for (int i = 0; i < em->tottri; i++) { - BMLoop **l = em->looptris[i]; - if (f && l[0]->f != f) { - DRAW_EM_MEASURE_STATS_FACEAREA(); - zero_v3(vmid); - area = 0.0; - n = 0; - } - - f = l[0]->f; - - if (dm) { - dm->getVertCo(dm, BM_elem_index_get(l[0]->v), v1); - dm->getVertCo(dm, BM_elem_index_get(l[1]->v), v2); - dm->getVertCo(dm, BM_elem_index_get(l[2]->v), v3); - } - else { - copy_v3_v3(v1, l[0]->v->co); - copy_v3_v3(v2, l[1]->v->co); - copy_v3_v3(v3, l[2]->v->co); - } - - add_v3_v3(vmid, v1); - add_v3_v3(vmid, v2); - add_v3_v3(vmid, v3); - n += 3; - if (do_global) { - mul_mat3_m4_v3(ob->obmat, v1); - mul_mat3_m4_v3(ob->obmat, v2); - mul_mat3_m4_v3(ob->obmat, v3); - } - area += area_tri_v3(v1, v2, v3); - } - - if (f) { - DRAW_EM_MEASURE_STATS_FACEAREA(); - } -#undef DRAW_EM_MEASURE_STATS_FACEAREA - } - - if (me->drawflag & ME_DRAWEXTRA_FACEANG) { - BMFace *efa; - const bool is_rad = (unit->system_rotation == USER_UNIT_ROT_RADIANS); - - UI_GetThemeColor3ubv(TH_DRAWEXTRA_FACEANG, col); - - if (dm) { - BM_mesh_elem_index_ensure(em->bm, BM_VERT); - } - - BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { - const bool is_face_sel = BM_elem_flag_test_bool(efa, BM_ELEM_SELECT); - - if (is_face_sel || do_moving) { - BMIter liter; - BMLoop *loop; - bool is_first = true; - - BM_ITER_ELEM (loop, &liter, efa, BM_LOOPS_OF_FACE) { - if (is_face_sel || - (do_moving && - (BM_elem_flag_test(loop->v, BM_ELEM_SELECT) || - BM_elem_flag_test(loop->prev->v, BM_ELEM_SELECT) || - BM_elem_flag_test(loop->next->v, BM_ELEM_SELECT)))) - { - float v2_local[3]; - - /* lazy init center calc */ - if (is_first) { - if (dm) { - BMLoop *l_iter, *l_first; - float tvec[3]; - zero_v3(vmid); - l_iter = l_first = BM_FACE_FIRST_LOOP(efa); - do { - dm->getVertCo(dm, BM_elem_index_get(l_iter->v), tvec); - add_v3_v3(vmid, tvec); - } while ((l_iter = l_iter->next) != l_first); - mul_v3_fl(vmid, 1.0f / (float)efa->len); - } - else { - BM_face_calc_center_bounds(efa, vmid); - } - is_first = false; - } - - if (dm) { - dm->getVertCo(dm, BM_elem_index_get(loop->prev->v), v1); - dm->getVertCo(dm, BM_elem_index_get(loop->v), v2); - dm->getVertCo(dm, BM_elem_index_get(loop->next->v), v3); - } - else { - copy_v3_v3(v1, loop->prev->v->co); - copy_v3_v3(v2, loop->v->co); - copy_v3_v3(v3, loop->next->v->co); - } - - copy_v3_v3(v2_local, v2); - - if (do_global) { - mul_mat3_m4_v3(ob->obmat, v1); - mul_mat3_m4_v3(ob->obmat, v2); - mul_mat3_m4_v3(ob->obmat, v3); - } - - float angle = angle_v3v3v3(v1, v2, v3); - - numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%.3f", is_rad ? angle : RAD2DEGF(angle)); - interp_v3_v3v3(fvec, vmid, v2_local, 0.8f); - view3d_cached_text_draw_add(fvec, numstr, numstr_len, 0, txt_flag, col); - } - } - } - } - } -} - -static void draw_em_indices(BMEditMesh *em) -{ - const short txt_flag = V3D_CACHE_TEXT_ASCII | V3D_CACHE_TEXT_LOCALCLIP; - BMEdge *e; - BMFace *f; - BMVert *v; - char numstr[32]; - size_t numstr_len; - float pos[3]; - unsigned char col[4]; - - BMIter iter; - BMesh *bm = em->bm; - - /* For now, reuse appropriate theme colors from stats text colors */ - int i = 0; - if (em->selectmode & SCE_SELECT_VERTEX) { - UI_GetThemeColor3ubv(TH_DRAWEXTRA_FACEANG, col); - BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { - if (BM_elem_flag_test(v, BM_ELEM_SELECT)) { - numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%d", i); - view3d_cached_text_draw_add(v->co, numstr, numstr_len, 0, txt_flag, col); - } - i++; - } - } - - if (em->selectmode & SCE_SELECT_EDGE) { - i = 0; - UI_GetThemeColor3ubv(TH_DRAWEXTRA_EDGELEN, col); - BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { - if (BM_elem_flag_test(e, BM_ELEM_SELECT)) { - numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%d", i); - mid_v3_v3v3(pos, e->v1->co, e->v2->co); - view3d_cached_text_draw_add(pos, numstr, numstr_len, 0, txt_flag, col); - } - i++; - } - } - - if (em->selectmode & SCE_SELECT_FACE) { - i = 0; - UI_GetThemeColor3ubv(TH_DRAWEXTRA_FACEAREA, col); - BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) { - if (BM_elem_flag_test(f, BM_ELEM_SELECT)) { - BM_face_calc_center_mean(f, pos); - numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%d", i); - view3d_cached_text_draw_add(pos, numstr, numstr_len, 0, txt_flag, col); - } - i++; - } - } -} - -static DMDrawOption draw_em_fancy__setFaceOpts(void *userData, int index) -{ - BMEditMesh *em = userData; - - if (UNLIKELY(index >= em->bm->totface)) - return DM_DRAW_OPTION_NORMAL; - - BMFace *efa = BM_face_at_index(em->bm, index); - if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { - return DM_DRAW_OPTION_NORMAL; - } - else { - return DM_DRAW_OPTION_SKIP; - } -} - -static DMDrawOption draw_em_fancy__setGLSLFaceOpts(void *userData, int index) -{ - BMEditMesh *em = userData; - - if (UNLIKELY(index >= em->bm->totface)) - return DM_DRAW_OPTION_NORMAL; - - BMFace *efa = BM_face_at_index(em->bm, index); - - if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { - return DM_DRAW_OPTION_NORMAL; - } - else { - return DM_DRAW_OPTION_SKIP; - } -} - -static void draw_em_fancy(Scene *scene, ViewLayer *view_layer, ARegion *ar, View3D *v3d, - Object *ob, BMEditMesh *em, DerivedMesh *cageDM, DerivedMesh *finalDM, const char dt) - -{ - RegionView3D *rv3d = ar->regiondata; - Mesh *me = ob->data; - const bool use_occlude_wire = (dt > OB_WIRE) && (v3d->flag2 & V3D_OCCLUDE_WIRE); - bool use_depth_offset = false; - - glLineWidth(1.0f); - - BM_mesh_elem_table_ensure(em->bm, BM_VERT | BM_EDGE | BM_FACE); - - if (check_object_draw_editweight(me, finalDM)) { - if (dt > OB_WIRE) { - draw_mesh_paint_weight_faces(finalDM, true, draw_em_fancy__setFaceOpts, me->edit_btmesh); - - ED_view3d_polygon_offset(rv3d, 1.0); - glDepthMask(GL_FALSE); - use_depth_offset = true; - } - else { - glEnable(GL_DEPTH_TEST); - draw_mesh_paint_weight_faces(finalDM, false, draw_em_fancy__setFaceOpts, me->edit_btmesh); - draw_mesh_paint_weight_edges(rv3d, finalDM, true, true, draw_dm_edges__setDrawOptions, me->edit_btmesh->bm); - glDisable(GL_DEPTH_TEST); - } - } - else if (dt > OB_WIRE) { - if (use_occlude_wire) { - /* use the cageDM since it always overlaps the editmesh faces */ - glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - cageDM->drawMappedFaces(cageDM, draw_em_fancy__setFaceOpts, - GPU_object_material_bind, NULL, me->edit_btmesh, DM_DRAW_SKIP_HIDDEN | DM_DRAW_NEED_NORMALS); - GPU_object_material_unbind(); - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - } - else if (check_object_draw_texture(scene, v3d, dt)) { - if (draw_glsl_material(scene, view_layer, ob, v3d, dt)) { - glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW); - - finalDM->drawMappedFacesGLSL(finalDM, GPU_object_material_bind, - draw_em_fancy__setGLSLFaceOpts, em); - GPU_object_material_unbind(); - - glFrontFace(GL_CCW); - } - else { - draw_mesh_textured(scene, view_layer, v3d, rv3d, ob, finalDM, 0); - } - } - else { - glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW); - finalDM->drawMappedFaces(finalDM, draw_em_fancy__setFaceOpts, GPU_object_material_bind, NULL, me->edit_btmesh, DM_DRAW_SKIP_HIDDEN | DM_DRAW_NEED_NORMALS); - - glFrontFace(GL_CCW); - - GPU_object_material_unbind(); - } - - /* Setup for drawing wire over, disable zbuffer - * write to show selected edge wires better */ - UI_ThemeColor(TH_WIRE_EDIT); - - ED_view3d_polygon_offset(rv3d, 1.0); - glDepthMask(GL_FALSE); - use_depth_offset = true; - } - else { - if (cageDM != finalDM) { - UI_ThemeColorBlend(TH_WIRE_EDIT, TH_BACK, 0.7); - finalDM->drawEdges(finalDM, 1, 0); - } - } - - if ((dt > OB_WIRE) && (v3d->flag2 & V3D_RENDER_SHADOW)) { - /* pass */ - } - else { - /* annoying but active faces is stored differently */ - BMFace *efa_act = BM_mesh_active_face_get(em->bm, false, true); - BMEdge *eed_act = NULL; - BMVert *eve_act = NULL; - - if (em->bm->selected.last) { - BMEditSelection *ese = em->bm->selected.last; - /* face is handled above */ -#if 0 - if (ese->type == BM_FACE) { - efa_act = (BMFace *)ese->data; - } - else -#endif - if (ese->htype == BM_EDGE) { - eed_act = (BMEdge *)ese->ele; - } - else if (ese->htype == BM_VERT) { - eve_act = (BMVert *)ese->ele; - } - } - - if ((me->drawflag & ME_DRAWFACES) && (use_occlude_wire == false)) { /* transp faces */ - unsigned char col1[4], col2[4], col3[4]; -#ifdef WITH_FREESTYLE - unsigned char col4[4]; -#endif - - UI_GetThemeColor4ubv(TH_FACE, col1); - UI_GetThemeColor4ubv(TH_FACE_SELECT, col2); - UI_GetThemeColor4ubv(TH_EDITMESH_ACTIVE, col3); -#ifdef WITH_FREESTYLE - UI_GetThemeColor4ubv(TH_FREESTYLE_FACE_MARK, col4); -#endif - - glEnable(GL_BLEND); - glDepthMask(GL_FALSE); /* disable write in zbuffer, needed for nice transp */ - - /* don't draw unselected faces, only selected, this is MUCH nicer when texturing */ - if (check_object_draw_texture(scene, v3d, dt)) - col1[3] = 0; - -#ifdef WITH_FREESTYLE - if (!(me->drawflag & ME_DRAW_FREESTYLE_FACE) || !CustomData_has_layer(&em->bm->pdata, CD_FREESTYLE_FACE)) - col4[3] = 0; - - draw_dm_faces_sel(em, cageDM, col1, col2, col3, col4, efa_act); -#else - draw_dm_faces_sel(em, cageDM, col1, col2, col3, efa_act); -#endif - - glDisable(GL_BLEND); - glDepthMask(GL_TRUE); /* restore write in zbuffer */ - } - else if (efa_act) { - /* even if draw faces is off it would be nice to draw the stipple face - * Make all other faces zero alpha except for the active */ - unsigned char col1[4], col2[4], col3[4]; -#ifdef WITH_FREESTYLE - unsigned char col4[4]; - col4[3] = 0; /* don't draw */ -#endif - col1[3] = col2[3] = 0; /* don't draw */ - - UI_GetThemeColor4ubv(TH_EDITMESH_ACTIVE, col3); - - glEnable(GL_BLEND); - glDepthMask(GL_FALSE); /* disable write in zbuffer, needed for nice transp */ - -#ifdef WITH_FREESTYLE - draw_dm_faces_sel(em, cageDM, col1, col2, col3, col4, efa_act); -#else - draw_dm_faces_sel(em, cageDM, col1, col2, col3, efa_act); -#endif - - glDisable(GL_BLEND); - glDepthMask(GL_TRUE); /* restore write in zbuffer */ - } - - /* here starts all fancy draw-extra over */ - if ((me->drawflag & ME_DRAWEDGES) == 0 && check_object_draw_texture(scene, v3d, dt)) { - /* we are drawing textures and 'ME_DRAWEDGES' is disabled, don't draw any edges */ - - /* only draw selected edges otherwise there is no way of telling if a face is selected */ - draw_em_fancy_edges(em, scene, v3d, me, cageDM, 1, eed_act); - - } - else { - if (me->drawflag & ME_DRAWSEAMS) { - UI_ThemeColor(TH_EDGE_SEAM); - glLineWidth(2.0f); - - draw_dm_edges_seams(em, cageDM); - - glColor3ub(0, 0, 0); - } - - if (me->drawflag & ME_DRAWSHARP) { - UI_ThemeColor(TH_EDGE_SHARP); - glLineWidth(2.0f); - - draw_dm_edges_sharp(em, cageDM); - - glColor3ub(0, 0, 0); - } - -#ifdef WITH_FREESTYLE - if (me->drawflag & ME_DRAW_FREESTYLE_EDGE && CustomData_has_layer(&em->bm->edata, CD_FREESTYLE_EDGE)) { - UI_ThemeColor(TH_FREESTYLE_EDGE_MARK); - glLineWidth(2.0f); - - draw_dm_edges_freestyle(em, cageDM); - - glColor3ub(0, 0, 0); - } -#endif - - if (me->drawflag & ME_DRAWCREASES) { - draw_dm_creases(em, cageDM); - } - if (me->drawflag & ME_DRAWBWEIGHTS) { - draw_dm_bweights(em, scene, cageDM); - } - - glLineWidth(1.0f); - draw_em_fancy_edges(em, scene, v3d, me, cageDM, 0, eed_act); - } - - { - draw_em_fancy_verts(scene, v3d, ob, em, cageDM, eve_act, rv3d); - - if (me->drawflag & ME_DRAWNORMALS) { - draw_dm_face_normals(em, scene, ob, cageDM, TH_NORMAL); - } - if (me->drawflag & ME_DRAW_VNORMALS) { - draw_dm_vert_normals(em, scene, ob, cageDM, TH_VNORMAL); - } - if (me->drawflag & ME_DRAW_LNORMALS) { - draw_dm_loop_normals(em, scene, ob, cageDM, TH_LNORMAL); - } - - if ((me->drawflag & (ME_DRAWEXTRA_EDGELEN | - ME_DRAWEXTRA_FACEAREA | - ME_DRAWEXTRA_FACEANG | - ME_DRAWEXTRA_EDGEANG)) && - !(v3d->flag2 & V3D_RENDER_OVERRIDE)) - { - draw_em_measure_stats(ar, v3d, ob, em, &scene->unit); - } - - if ((G.debug & G_DEBUG) && (me->drawflag & ME_DRAWEXTRA_INDICES) && - !(v3d->flag2 & V3D_RENDER_OVERRIDE)) - { - draw_em_indices(em); - } - } - } - - if (use_depth_offset) { - glDepthMask(GL_TRUE); - ED_view3d_polygon_offset(rv3d, 0.0); - GPU_object_material_unbind(); - } -#if 0 /* currently not needed */ - else if (use_occlude_wire) { - ED_view3d_polygon_offset(rv3d, 0.0); - } -#endif -} - -static void draw_em_fancy_new(Scene *UNUSED(scene), ARegion *UNUSED(ar), View3D *UNUSED(v3d), - Object *UNUSED(ob), Mesh *me, BMEditMesh *UNUSED(em), DerivedMesh *UNUSED(cageDM), DerivedMesh *UNUSED(finalDM), const char UNUSED(dt)) -{ - /* for now... something simple! */ - Gwn_Batch *surface = DRW_mesh_batch_cache_get_all_triangles(me); - - glEnable(GL_DEPTH_TEST); - glDepthFunc(GL_LEQUAL); - - glEnable(GL_BLEND); - - /* disable depth writes for transparent surface, so it doesn't interfere with itself */ - glDepthMask(GL_FALSE); - - GWN_batch_program_set_builtin(surface, GPU_SHADER_3D_UNIFORM_COLOR); - GWN_batch_uniform_4f(surface, "color", 1.0f, 0.5f, 0.0f, 0.5f); - GWN_batch_draw(surface); - -#if 0 /* until I understand finalDM better */ - if (finalDM != cageDM) { - puts("finalDM != cageDM"); - Gwn_Batch *finalSurface = MBC_get_all_triangles(finalDM); - GWN_batch_program_set_builtin(finalSurface, GPU_SHADER_3D_UNIFORM_COLOR); - GWN_batch_uniform_4f(finalSurface, "color", 0.0f, 0.0f, 0.0f, 0.05f); - GWN_batch_draw(finalSurface); - } -#endif - - glDepthMask(GL_TRUE); - - /* now write surface depth so other objects won't poke through - * NOTE: does not help as much as desired - * TODO: draw edit object last to avoid this mess - */ - GWN_batch_program_set_builtin(surface, GPU_SHADER_3D_DEPTH_ONLY); - GWN_batch_draw(surface); - - if (GLEW_VERSION_3_2) { -#if 0 - Gwn_Batch *overlay = DRW_mesh_batch_cache_get_overlay_edges(me); - GWN_batch_program_set_builtin(overlay, GPU_SHADER_EDGES_OVERLAY); - GWN_batch_uniform_2f(overlay, "viewportSize", ar->winx, ar->winy); - GWN_batch_draw(overlay); -#endif - -#if 0 /* TODO: use this SIMPLE variant for pure triangle meshes */ - GWN_batch_program_set_builtin(surface, GPU_SHADER_EDGES_OVERLAY_SIMPLE); - /* use these defaults: - * const float edgeColor[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; - * GWN_batch_uniform_4f(surface, "fillColor", edgeColor[0], edgeColor[1], edgeColor[2], 0.0f); - * GWN_batch_uniform_4fv(surface, "outlineColor", edgeColor); - * GWN_batch_uniform_1f(surface, "outlineWidth", 1.0f); - */ - GWN_batch_uniform_2f(surface, "viewportSize", ar->winx, ar->winy); - GWN_batch_draw(surface); -#endif - } - else { - Gwn_Batch *edges = DRW_mesh_batch_cache_get_all_edges(me); - GWN_batch_program_set_builtin(edges, GPU_SHADER_3D_UNIFORM_COLOR); - GWN_batch_uniform_4f(edges, "color", 0.0f, 0.0f, 0.0f, 1.0f); - glEnable(GL_LINE_SMOOTH); - glLineWidth(1.5f); - GWN_batch_draw(edges); - glDisable(GL_LINE_SMOOTH); - } - -#if 0 /* looks good even without points */ - Gwn_Batch *verts = MBC_get_all_verts(me); - glEnable(GL_BLEND); - - GWN_batch_program_set_builtin(verts, GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA); - GWN_batch_uniform_4f(verts, "color", 0.0f, 0.0f, 0.0f, 1.0f); - GWN_batch_uniform_1f(verts, "size", UI_GetThemeValuef(TH_VERTEX_SIZE) * 1.5f); - GWN_batch_draw(verts); - - glDisable(GL_BLEND); -#endif -} - -/* Mesh drawing routines */ - -void draw_mesh_object_outline(View3D *v3d, Object *ob, DerivedMesh *dm, const unsigned char ob_wire_col[4]) /* LEGACY */ -{ - if ((v3d->transp == false) && /* not when we draw the transparent pass */ - (ob->mode & OB_MODE_ALL_PAINT) == false) /* not when painting (its distracting) - campbell */ - { - glLineWidth(UI_GetThemeValuef(TH_OUTLINE_WIDTH) * 2.0f); - glDepthMask(GL_FALSE); - - if (ob_wire_col) glColor4ubv(ob_wire_col); - - /* if transparent, we cannot draw the edges for solid select... edges - * have no material info. GPU_object_material_visible will skip the - * transparent faces */ - if (ob->dtx & OB_DRAWTRANSP) { - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - dm->drawFacesSolid(dm, NULL, 0, GPU_object_material_visible); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - } - else { - dm->drawEdges(dm, 0, 1); - } - - glDepthMask(GL_TRUE); - } -} - -static void draw_mesh_object_outline_new(View3D *v3d, RegionView3D *rv3d, Object *ob, Mesh *me, const bool is_active) -{ - if ((v3d->transp == false) && /* not when we draw the transparent pass */ - (ob->mode & OB_MODE_ALL_PAINT) == false) /* not when painting (its distracting) - campbell */ - { - glLineWidth(UI_GetThemeValuef(TH_OUTLINE_WIDTH) * 2.0f); - glDepthMask(GL_FALSE); - - float outline_color[4]; - UI_GetThemeColor4fv((is_active ? TH_ACTIVE : TH_SELECT), outline_color); - -#if 1 /* new version that draws only silhouette edges */ - Gwn_Batch *fancy_edges = DRW_mesh_batch_cache_get_fancy_edges(me); - - if (rv3d->persp == RV3D_ORTHO) { - GWN_batch_program_set_builtin(fancy_edges, GPU_SHADER_EDGES_FRONT_BACK_ORTHO); - /* set eye vector, transformed to object coords */ - float eye[3] = { 0.0f, 0.0f, 1.0f }; /* looking into the screen */ - mul_m3_v3(gpuGetNormalMatrixInverse(NULL), eye); - GWN_batch_uniform_3fv(fancy_edges, "eye", eye); - } - else { - GWN_batch_program_set_builtin(fancy_edges, GPU_SHADER_EDGES_FRONT_BACK_PERSP); - } - - GWN_batch_uniform_1b(fancy_edges, "drawFront", false); - GWN_batch_uniform_1b(fancy_edges, "drawBack", false); - GWN_batch_uniform_1b(fancy_edges, "drawSilhouette", true); - GWN_batch_uniform_4fv(fancy_edges, "silhouetteColor", outline_color); - - GWN_batch_draw(fancy_edges); -#else /* alternate version that matches look of old viewport (but more efficient) */ - Gwn_Batch *batch = MBC_get_all_edges(dm); - GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR); - GWN_batch_uniform_4fv(batch, "color", outline_color); - GWN_batch_draw(batch); -#endif - - glDepthMask(GL_TRUE); - } -} - -static bool object_is_halo(Scene *scene, Object *ob) -{ - const Material *ma = give_current_material(ob, 1); - return (ma && (ma->material_type == MA_TYPE_HALO) && !BKE_scene_use_new_shading_nodes(scene)); -} - -static void draw_mesh_fancy( - Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer, ARegion *ar, View3D *v3d, RegionView3D *rv3d, Base *base, - const char dt, const unsigned char ob_wire_col[4], const short dflag) -{ - Object *ob = base->object; - Mesh *me = ob->data; - eWireDrawMode draw_wire = OBDRAW_WIRE_OFF; - bool /* no_verts,*/ no_edges, no_faces; - DerivedMesh *dm = mesh_get_derived_final(depsgraph, scene, ob, scene->customdata_mask); - const bool is_obact = (ob == OBACT(view_layer)); - int draw_flags = (is_obact && BKE_paint_select_face_test(ob)) ? DRAW_FACE_SELECT : 0; - - if (!dm) - return; - - DM_update_materials(dm, ob); - - /* Check to draw dynamic paint colors (or weights from WeightVG modifiers). - * Note: Last "preview-active" modifier in stack will win! */ - if (DM_get_loop_data_layer(dm, CD_PREVIEW_MLOOPCOL) && modifiers_isPreview(ob)) - draw_flags |= DRAW_MODIFIERS_PREVIEW; - - /* Unwanted combination */ - if (draw_flags & DRAW_FACE_SELECT) { - draw_wire = OBDRAW_WIRE_OFF; - } - else if (ob->dtx & OB_DRAWWIRE) { - draw_wire = OBDRAW_WIRE_ON_DEPTH; /* draw wire after solid using zoffset and depth buffer adjusment */ - } - - /* check polys instead of tessfaces because of dyntopo where tessfaces don't exist */ - if (dm->type == DM_TYPE_CCGDM) { - no_edges = !subsurf_has_edges(dm); - no_faces = !subsurf_has_faces(dm); - } - else { - no_edges = (dm->getNumEdges(dm) == 0); - no_faces = (dm->getNumPolys(dm) == 0); - } - - /* vertexpaint, faceselect wants this, but it doesnt work for shaded? */ - glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW); - - if (dt == OB_BOUNDBOX) { - if (((v3d->flag2 & V3D_RENDER_OVERRIDE) && v3d->drawtype >= OB_WIRE) == 0) - draw_bounding_volume(ob, ob->boundtype, ob_wire_col); - } - else if ((no_faces && no_edges) || - ((!is_obact || (ob->mode == OB_MODE_OBJECT)) && object_is_halo(scene, ob))) - { - glPointSize(1.5f); - dm->drawVerts(dm); - } - else if ((dt == OB_WIRE) || no_faces) { - draw_wire = OBDRAW_WIRE_ON; /* draw wire only, no depth buffer stuff */ - } - else if (((is_obact && ob->mode & OB_MODE_TEXTURE_PAINT)) || - check_object_draw_texture(scene, v3d, dt)) - { - bool draw_loose = true; - - if ((v3d->flag & V3D_SELECT_OUTLINE) && - ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) && - (base->flag & BASE_SELECTED) && - !(G.f & G_PICKSEL || (draw_flags & DRAW_FACE_SELECT)) && - (draw_wire == OBDRAW_WIRE_OFF)) - { - draw_mesh_object_outline(v3d, ob, dm, ob_wire_col); - } - - if (draw_glsl_material(scene, view_layer, ob, v3d, dt) && !(draw_flags & DRAW_MODIFIERS_PREVIEW)) { - Paint *p; - - glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW); - - if ((v3d->flag2 & V3D_SHOW_SOLID_MATCAP) && ob->sculpt && (p = BKE_paint_get_active(scene, view_layer))) { - GPUVertexAttribs gattribs; - float planes[4][4]; - float (*fpl)[4] = NULL; - const bool fast = (p->flags & PAINT_FAST_NAVIGATE) && (rv3d->rflag & RV3D_NAVIGATING); - - if (ob->sculpt->partial_redraw) { - if (ar->do_draw & RGN_DRAW_PARTIAL) { - ED_sculpt_redraw_planes_get(planes, ar, ob); - fpl = planes; - ob->sculpt->partial_redraw = 0; - } - } - - GPU_object_material_bind(1, &gattribs); - dm->drawFacesSolid(dm, fpl, fast, NULL); - draw_loose = false; - } - else - dm->drawFacesGLSL(dm, GPU_object_material_bind); - -#if 0 /* XXX */ - if (BKE_bproperty_object_get(ob, "Text")) - draw_mesh_text(ob, 1); -#endif - GPU_object_material_unbind(); - - glFrontFace(GL_CCW); - - if (draw_flags & DRAW_FACE_SELECT) - draw_mesh_face_select(rv3d, me, dm, false); - } - else { - draw_mesh_textured(scene, view_layer, v3d, rv3d, ob, dm, draw_flags); - } - - if (draw_loose && !(draw_flags & DRAW_FACE_SELECT)) { - if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { - if ((dflag & DRAW_CONSTCOLOR) == 0) { - glColor3ubv(ob_wire_col); - } - glLineWidth(1.0f); - dm->drawLooseEdges(dm); - } - } - } - else if (dt == OB_SOLID) { - if (draw_flags & DRAW_MODIFIERS_PREVIEW) { - /* for object selection draws no shade */ - if (dflag & (DRAW_PICKING | DRAW_CONSTCOLOR)) { - dm->drawFacesSolid(dm, NULL, 0, GPU_object_material_bind); - GPU_object_material_unbind(); - } - else { - const float specular[3] = {0.47f, 0.47f, 0.47f}; - - /* draw outline */ - if ((v3d->flag & V3D_SELECT_OUTLINE) && - ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) && - (base->flag & BASE_SELECTED) && - (draw_wire == OBDRAW_WIRE_OFF) && - (ob->sculpt == NULL)) - { - draw_mesh_object_outline(v3d, ob, dm, ob_wire_col); - } - - /* materials arent compatible with vertex colors */ - GPU_end_object_materials(); - - /* set default specular */ - GPU_basic_shader_colors(NULL, specular, 35, 1.0f); - GPU_basic_shader_bind(GPU_SHADER_LIGHTING | GPU_SHADER_USE_COLOR); - - dm->drawMappedFaces(dm, NULL, NULL, NULL, NULL, DM_DRAW_USE_COLORS | DM_DRAW_NEED_NORMALS); - - GPU_basic_shader_bind(GPU_SHADER_USE_COLOR); - } - } - else { - Paint *p; - - if ((v3d->flag & V3D_SELECT_OUTLINE) && - ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) && - (base->flag & BASE_SELECTED) && - (draw_wire == OBDRAW_WIRE_OFF) && - (ob->sculpt == NULL)) - { - draw_mesh_object_outline(v3d, ob, dm, ob_wire_col); - } - - glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW); - - if (ob->sculpt && (p = BKE_paint_get_active(scene, view_layer))) { - float planes[4][4]; - float (*fpl)[4] = NULL; - const bool fast = (p->flags & PAINT_FAST_NAVIGATE) && (rv3d->rflag & RV3D_NAVIGATING); - - if (ob->sculpt->partial_redraw) { - if (ar->do_draw & RGN_DRAW_PARTIAL) { - ED_sculpt_redraw_planes_get(planes, ar, ob); - fpl = planes; - ob->sculpt->partial_redraw = 0; - } - } - - dm->drawFacesSolid(dm, fpl, fast, GPU_object_material_bind); - } - else - dm->drawFacesSolid(dm, NULL, 0, GPU_object_material_bind); - - glFrontFace(GL_CCW); - - GPU_object_material_unbind(); - - if (!ob->sculpt && (v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { - if ((dflag & DRAW_CONSTCOLOR) == 0) { - glColor3ubv(ob_wire_col); - } - glLineWidth(1.0f); - dm->drawLooseEdges(dm); - } - } - } - else if (dt == OB_PAINT) { - draw_mesh_paint(v3d, rv3d, ob, dm, draw_flags); - - /* since we already draw wire as wp guide, don't draw over the top */ - draw_wire = OBDRAW_WIRE_OFF; - } - - if ((draw_wire != OBDRAW_WIRE_OFF) && /* draw extra wire */ - /* when overriding with render only, don't bother */ - (((v3d->flag2 & V3D_RENDER_OVERRIDE) && v3d->drawtype >= OB_SOLID) == 0)) - { - /* When using wireframe object draw in particle edit mode - * the mesh gets in the way of seeing the particles, fade the wire color - * with the background. */ - - if ((dflag & DRAW_CONSTCOLOR) == 0) { - if (is_obact && (ob->mode & OB_MODE_PARTICLE_EDIT)) { - float color[3]; - ob_wire_color_blend_theme_id(ob_wire_col, TH_BACK, 0.15f, color); - glColor3fv(color); - } - else { - glColor3ubv(ob_wire_col); - } - } - - /* If drawing wire and drawtype is not OB_WIRE then we are - * overlaying the wires. - * - * UPDATE bug #10290 - With this wire-only objects can draw - * behind other objects depending on their order in the scene. 2x if 0's below. undo'ing zr's commit: r4059 - * - * if draw wire is 1 then just drawing wire, no need for depth buffer stuff, - * otherwise this wire is to overlay solid mode faces so do some depth buffer tricks. - */ - if (dt != OB_WIRE && (draw_wire == OBDRAW_WIRE_ON_DEPTH)) { - ED_view3d_polygon_offset(rv3d, 1.0); - glDepthMask(GL_FALSE); /* disable write in zbuffer, selected edge wires show better */ - } - - glLineWidth(1.0f); - dm->drawEdges(dm, ((dt == OB_WIRE) || no_faces), (ob->dtx & OB_DRAW_ALL_EDGES) != 0); - - if (dt != OB_WIRE && (draw_wire == OBDRAW_WIRE_ON_DEPTH)) { - glDepthMask(GL_TRUE); - ED_view3d_polygon_offset(rv3d, 0.0); - } - } - - if (is_obact && BKE_paint_select_vert_test(ob)) { - const bool use_depth = (v3d->flag & V3D_ZBUF_SELECT) != 0; - glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE)); - - if (!use_depth) glDisable(GL_DEPTH_TEST); - else ED_view3d_polygon_offset(rv3d, 1.0); - drawSelectedVertices(dm, ob->data); - if (!use_depth) glEnable(GL_DEPTH_TEST); - else ED_view3d_polygon_offset(rv3d, 0.0); - } - dm->release(dm); -} - -/* returns true if nothing was drawn, for detecting to draw an object center */ -static bool draw_mesh_object( - Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer, ARegion *ar, View3D *v3d, RegionView3D *rv3d, Base *base, - const char dt, const unsigned char ob_wire_col[4], const short dflag) -{ - Object *ob = base->object; - Object *obedit = OBEDIT_FROM_VIEW_LAYER(view_layer); - Mesh *me = ob->data; - BMEditMesh *em = me->edit_btmesh; - bool do_alpha_after = false, drawlinked = false, retval = false; - - /* If we are drawing shadows and any of the materials don't cast a shadow, - * then don't draw the object */ - if (v3d->flag2 & V3D_RENDER_SHADOW) { - for (int i = 0; i < ob->totcol; ++i) { - Material *ma = give_current_material(ob, i); - if (ma && !(ma->mode2 & MA_CASTSHADOW)) { - return true; - } - } - } - - if (obedit && ob != obedit && ob->data == obedit->data) { - if (BKE_key_from_object(ob) || BKE_key_from_object(obedit)) {} - else if (ob->modifiers.first || obedit->modifiers.first) {} - else drawlinked = true; - } - - /* backface culling */ - if (v3d->flag2 & V3D_BACKFACE_CULLING) { - glEnable(GL_CULL_FACE); - glCullFace(GL_BACK); - } - - if (ob == obedit || drawlinked) { - DerivedMesh *finalDM, *cageDM; - - if (obedit != ob) { - finalDM = cageDM = editbmesh_get_derived_base( - ob, em, scene->customdata_mask); - } - else { - cageDM = editbmesh_get_derived_cage_and_final( - depsgraph, scene, ob, em, scene->customdata_mask, - &finalDM); - } - - const bool use_material = ((me->drawflag & ME_DRAWEIGHT) == 0); - - DM_update_materials(finalDM, ob); - if (cageDM != finalDM) { - DM_update_materials(cageDM, ob); - } - - if (use_material) { - if (dt > OB_WIRE) { - const bool glsl = draw_glsl_material(scene, view_layer, ob, v3d, dt); - - GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, glsl, NULL); - } - } - - draw_em_fancy(scene, view_layer, ar, v3d, ob, em, cageDM, finalDM, dt); - - if (use_material) { - GPU_end_object_materials(); - } - - if (obedit != ob) - finalDM->release(finalDM); - } - else { - /* ob->bb was set by derived mesh system, do NULL check just to be sure */ - if (me->totpoly <= 4 || (!ob->bb || ED_view3d_boundbox_clip(rv3d, ob->bb))) { - if (dt > OB_WIRE) { - const bool glsl = draw_glsl_material(scene, view_layer, ob, v3d, dt); - - if (dt == OB_SOLID || glsl) { - const bool check_alpha = check_alpha_pass(base); - GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, glsl, - (check_alpha) ? &do_alpha_after : NULL); - } - } - - draw_mesh_fancy(depsgraph, scene, view_layer, ar, v3d, rv3d, base, dt, ob_wire_col, dflag); - - GPU_end_object_materials(); - - if (me->totvert == 0) retval = true; - } - } - - if ((dflag & DRAW_PICKING) == 0 && (base->flag_legacy & OB_FROMDUPLI) == 0 && (v3d->flag2 & V3D_RENDER_SHADOW) == 0) { - /* GPU_begin_object_materials checked if this is needed */ - if (do_alpha_after) { - if (ob->dtx & OB_DRAWXRAY) { - ED_view3d_after_add(&v3d->afterdraw_xraytransp, base, dflag); - } - else { - ED_view3d_after_add(&v3d->afterdraw_transp, base, dflag); - } - } - else if (ob->dtx & OB_DRAWXRAY && ob->dtx & OB_DRAWTRANSP) { - /* special case xray+transp when alpha is 1.0, without this the object vanishes */ - if (v3d->xray == 0 && v3d->transp == 0) { - ED_view3d_after_add(&v3d->afterdraw_xray, base, dflag); - } - } - } - - if (v3d->flag2 & V3D_BACKFACE_CULLING) - glDisable(GL_CULL_FACE); - - return retval; -} - -static void make_color_variations(const unsigned char base_ubyte[4], float low[4], float med[4], float high[4], const bool other_obedit) -{ - /* original idea: nice variations (lighter & darker shades) of base color - * current implementation uses input color as high; med & low get closer to background color - */ - - float bg[3]; - UI_GetThemeColor3fv(TH_BACK, bg); - - float base[4]; - rgba_uchar_to_float(base, base_ubyte); - - if (other_obedit) { - /* this object should fade away so user can focus on the object being edited */ - interp_v3_v3v3(low, bg, base, 0.1f); - interp_v3_v3v3(med, bg, base, 0.2f); - interp_v3_v3v3(high, bg, base, 0.25f); - } - else { - interp_v3_v3v3(low, bg, base, 0.333f); - interp_v3_v3v3(med, bg, base, 0.667f); - copy_v3_v3(high, base); - } - - /* use original alpha */ - low[3] = base[3]; - med[3] = base[3]; - high[3] = base[3]; -} - -static void draw_mesh_fancy_new( - Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer, - ARegion *ar, View3D *v3d, RegionView3D *rv3d, Base *base, - const char dt, const unsigned char ob_wire_col[4], const short dflag, const bool other_obedit) -{ - if (dflag & (DRAW_PICKING | DRAW_CONSTCOLOR)) { - /* too complicated! use existing methods */ - /* TODO: move this into a separate depth pre-pass */ - draw_mesh_fancy(depsgraph, scene, view_layer, ar, v3d, rv3d, base, dt, ob_wire_col, dflag); - return; - } - - Object *ob = base->object; - Mesh *me = ob->data; - eWireDrawMode draw_wire = OBDRAW_WIRE_OFF; /* could be bool draw_wire_overlay */ - bool no_edges, no_faces; - DerivedMesh *dm = mesh_get_derived_final(depsgraph, scene, ob, scene->customdata_mask); - const bool is_obact = (ob == OBACT(view_layer)); - int draw_flags = (is_obact && BKE_paint_select_face_test(ob)) ? DRAW_FACE_SELECT : 0; - - if (!dm) - return; - - const bool solid = dt >= OB_SOLID; - if (solid) { - DM_update_materials(dm, ob); - } - - /* Check to draw dynamic paint colors (or weights from WeightVG modifiers). - * Note: Last "preview-active" modifier in stack will win! */ - if (DM_get_loop_data_layer(dm, CD_PREVIEW_MLOOPCOL) && modifiers_isPreview(ob)) - draw_flags |= DRAW_MODIFIERS_PREVIEW; - - /* Unwanted combination */ - if (draw_flags & DRAW_FACE_SELECT) { - draw_wire = OBDRAW_WIRE_OFF; - } - else if (ob->dtx & OB_DRAWWIRE) { - draw_wire = OBDRAW_WIRE_ON; - } - - /* check polys instead of tessfaces because of dyntopo where tessfaces don't exist */ - if (dm->type == DM_TYPE_CCGDM) { - no_edges = !subsurf_has_edges(dm); - no_faces = !subsurf_has_faces(dm); - } - else { - no_edges = (dm->getNumEdges(dm) == 0); - no_faces = (dm->getNumPolys(dm) == 0); - } - - if (solid) { - /* vertexpaint, faceselect wants this, but it doesnt work for shaded? */ - glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW); - } - - if (dt == OB_BOUNDBOX) { - if (((v3d->flag2 & V3D_RENDER_OVERRIDE) && v3d->drawtype >= OB_WIRE) == 0) - draw_bounding_volume(ob, ob->boundtype, ob_wire_col); - } - else if ((no_faces && no_edges) || - ((!is_obact || (ob->mode == OB_MODE_OBJECT)) && object_is_halo(scene, ob))) - { - glPointSize(1.5f); - // dm->drawVerts(dm); - // TODO: draw smooth round points as a batch - } - else if ((dt == OB_WIRE) || no_faces) { - draw_wire = OBDRAW_WIRE_ON; - - /* enable depth for wireframes */ - glEnable(GL_DEPTH_TEST); - glDepthFunc(GL_LESS); - - glLineWidth(1.0f); - -#if 1 /* fancy wireframes */ - - Gwn_Batch *fancy_edges = DRW_mesh_batch_cache_get_fancy_edges(me); - - if (rv3d->persp == RV3D_ORTHO) { - GWN_batch_program_set_builtin(fancy_edges, GPU_SHADER_EDGES_FRONT_BACK_ORTHO); - /* set eye vector, transformed to object coords */ - float eye[3] = { 0.0f, 0.0f, 1.0f }; /* looking into the screen */ - mul_m3_v3(gpuGetNormalMatrixInverse(NULL), eye); - GWN_batch_uniform_3fv(fancy_edges, "eye", eye); - } - else { - GWN_batch_program_set_builtin(fancy_edges, GPU_SHADER_EDGES_FRONT_BACK_PERSP); - } - - float frontColor[4]; - float backColor[4]; - float outlineColor[4]; - make_color_variations(ob_wire_col, backColor, frontColor, outlineColor, other_obedit); - - GWN_batch_uniform_4fv(fancy_edges, "frontColor", frontColor); - GWN_batch_uniform_4fv(fancy_edges, "backColor", backColor); - GWN_batch_uniform_1b(fancy_edges, "drawFront", true); - GWN_batch_uniform_1b(fancy_edges, "drawBack", true); /* false here = backface cull */ - GWN_batch_uniform_1b(fancy_edges, "drawSilhouette", false); - - GWN_batch_draw(fancy_edges); - - /* extra oomph for the silhouette contours */ - glLineWidth(2.0f); - GWN_batch_program_use_begin(fancy_edges); /* hack to make the following uniforms stick */ - GWN_batch_uniform_1b(fancy_edges, "drawFront", false); - GWN_batch_uniform_1b(fancy_edges, "drawBack", false); - GWN_batch_uniform_1b(fancy_edges, "drawSilhouette", true); - GWN_batch_uniform_4fv(fancy_edges, "silhouetteColor", outlineColor); - - GWN_batch_draw(fancy_edges); - -#else /* simple wireframes */ - - Gwn_Batch *batch = MBC_get_all_edges(dm); - GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR); - - float color[4]; - rgba_uchar_to_float(color, ob_wire_col); - - GWN_batch_uniform_4fv(batch, "color", color); - - GWN_batch_draw(batch); -#endif - } - else if (((is_obact && ob->mode & OB_MODE_TEXTURE_PAINT)) || - check_object_draw_texture(scene, v3d, dt)) - { - bool draw_loose = true; - - if ((v3d->flag & V3D_SELECT_OUTLINE) && - ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) && - (base->flag & BASE_SELECTED) && - !(G.f & G_PICKSEL || (draw_flags & DRAW_FACE_SELECT)) && - (draw_wire == OBDRAW_WIRE_OFF)) - { - draw_mesh_object_outline_new(v3d, rv3d, ob, me, (ob == OBACT(view_layer))); - } - - if (draw_glsl_material(scene, view_layer, ob, v3d, dt) && !(draw_flags & DRAW_MODIFIERS_PREVIEW)) { - Paint *p; - - glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW); - - if ((v3d->flag2 & V3D_SHOW_SOLID_MATCAP) && ob->sculpt && (p = BKE_paint_get_active(scene, view_layer))) { - GPUVertexAttribs gattribs; - float planes[4][4]; - float (*fpl)[4] = NULL; - const bool fast = (p->flags & PAINT_FAST_NAVIGATE) && (rv3d->rflag & RV3D_NAVIGATING); - - if (ob->sculpt->partial_redraw) { - if (ar->do_draw & RGN_DRAW_PARTIAL) { - ED_sculpt_redraw_planes_get(planes, ar, ob); - fpl = planes; - ob->sculpt->partial_redraw = 0; - } - } - - GPU_object_material_bind(1, &gattribs); - dm->drawFacesSolid(dm, fpl, fast, NULL); - draw_loose = false; - } - else - dm->drawFacesGLSL(dm, GPU_object_material_bind); - - GPU_object_material_unbind(); - - glFrontFace(GL_CCW); - - if (draw_flags & DRAW_FACE_SELECT) - draw_mesh_face_select(rv3d, me, dm, false); - } - else { - draw_mesh_textured(scene, view_layer, v3d, rv3d, ob, dm, draw_flags); - } - - if (draw_loose && !(draw_flags & DRAW_FACE_SELECT)) { - if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { - if ((dflag & DRAW_CONSTCOLOR) == 0) { - glColor3ubv(ob_wire_col); - } - glLineWidth(1.0f); - dm->drawLooseEdges(dm); - } - } - } - else if (dt == OB_SOLID) { - if (draw_flags & DRAW_MODIFIERS_PREVIEW) { - /* for object selection draws no shade */ - if (dflag & (DRAW_PICKING | DRAW_CONSTCOLOR)) { - /* TODO: draw basic faces with GPU_SHADER_3D_DEPTH_ONLY */ - } - else { - const float specular[3] = {0.47f, 0.47f, 0.47f}; - - /* draw outline */ - /* TODO: move this into a separate pass */ - if ((v3d->flag & V3D_SELECT_OUTLINE) && - ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) && - (base->flag & BASE_SELECTED) && - (draw_wire == OBDRAW_WIRE_OFF) && - (ob->sculpt == NULL)) - { - draw_mesh_object_outline_new(v3d, rv3d, ob, me, (ob == OBACT(view_layer))); - } - - /* materials arent compatible with vertex colors */ - GPU_end_object_materials(); - - /* set default specular */ - GPU_basic_shader_colors(NULL, specular, 35, 1.0f); - GPU_basic_shader_bind(GPU_SHADER_LIGHTING | GPU_SHADER_USE_COLOR); - - dm->drawMappedFaces(dm, NULL, NULL, NULL, NULL, DM_DRAW_USE_COLORS | DM_DRAW_NEED_NORMALS); - - GPU_basic_shader_bind(GPU_SHADER_USE_COLOR); - } - } - else { - Paint *p; - - if ((v3d->flag & V3D_SELECT_OUTLINE) && - ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) && - (base->flag & BASE_SELECTED) && - (draw_wire == OBDRAW_WIRE_OFF) && - (ob->sculpt == NULL)) - { - /* TODO: move this into a separate pass */ - draw_mesh_object_outline_new(v3d, rv3d, ob, me, (ob == OBACT(view_layer))); - } - - glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW); - - if (ob->sculpt && (p = BKE_paint_get_active(scene, view_layer))) { - float planes[4][4]; - float (*fpl)[4] = NULL; - const bool fast = (p->flags & PAINT_FAST_NAVIGATE) && (rv3d->rflag & RV3D_NAVIGATING); - - if (ob->sculpt->partial_redraw) { - if (ar->do_draw & RGN_DRAW_PARTIAL) { - ED_sculpt_redraw_planes_get(planes, ar, ob); - fpl = planes; - ob->sculpt->partial_redraw = 0; - } - } - - dm->drawFacesSolid(dm, fpl, fast, GPU_object_material_bind); - } - else - dm->drawFacesSolid(dm, NULL, 0, GPU_object_material_bind); - - glFrontFace(GL_CCW); - - GPU_object_material_unbind(); - - if (!ob->sculpt && (v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { - if ((dflag & DRAW_CONSTCOLOR) == 0) { - glColor3ubv(ob_wire_col); - } - glLineWidth(1.0f); - dm->drawLooseEdges(dm); - } - } - } - else if (dt == OB_PAINT) { - draw_mesh_paint(v3d, rv3d, ob, dm, draw_flags); - - /* since we already draw wire as wp guide, don't draw over the top */ - draw_wire = OBDRAW_WIRE_OFF; - } - - if ((draw_wire != OBDRAW_WIRE_OFF) && /* draw extra wire */ - /* when overriding with render only, don't bother */ - (((v3d->flag2 & V3D_RENDER_OVERRIDE) && v3d->drawtype >= OB_SOLID) == 0)) // <-- is this "== 0" in the right spot??? - { - /* When using wireframe object draw in particle edit mode - * the mesh gets in the way of seeing the particles, fade the wire color - * with the background. */ - - if ((dflag & DRAW_CONSTCOLOR) == 0) { - /* TODO: - * Batch_UniformColor4ubv(ob_wire_col); - */ - } - - /* If drawing wire and drawtype is not OB_WIRE then we are - * overlaying the wires. - * - * No need for polygon offset because new technique is AWESOME. - */ -#if 0 - glLineWidth(1.0f); - dm->drawEdges(dm, ((dt == OB_WIRE) || no_faces), (ob->dtx & OB_DRAW_ALL_EDGES) != 0); -#else - /* something */ -#endif - } - -#if 0 // (merwin) what is this for? - if (is_obact && BKE_paint_select_vert_test(ob)) { - const bool use_depth = (v3d->flag & V3D_ZBUF_SELECT) != 0; - glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE)); - - if (!use_depth) glDisable(GL_DEPTH_TEST); - else ED_view3d_polygon_offset(rv3d, 1.0); - drawSelectedVertices(dm, ob->data); - if (!use_depth) glEnable(GL_DEPTH_TEST); - else ED_view3d_polygon_offset(rv3d, 0.0); - } -#endif - - dm->release(dm); -} - -static bool UNUSED_FUNCTION(draw_mesh_object_new)( - Depsgraph *depsgraph, Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d, Base *base, - const char dt, const unsigned char ob_wire_col[4], const short dflag) -{ - ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph); - Object *ob = base->object; - Mesh *me = ob->data; - BMEditMesh *em = me->edit_btmesh; - bool do_alpha_after = false, drawlinked = false, retval = false; - - if (v3d->flag2 & V3D_RENDER_SHADOW) { - /* TODO: handle shadow pass separately */ - return true; - } - Object *obedit = OBEDIT_FROM_VIEW_LAYER(view_layer); - - if (obedit && ob != obedit && ob->data == obedit->data) { - if (BKE_key_from_object(ob) || BKE_key_from_object(obedit)) {} - else if (ob->modifiers.first || obedit->modifiers.first) {} - else drawlinked = true; - } - - /* backface culling */ - const bool solid = dt > OB_WIRE; - const bool cullBackface = solid && (v3d->flag2 & V3D_BACKFACE_CULLING); - if (cullBackface) { - glEnable(GL_CULL_FACE); - glCullFace(GL_BACK); - } - - if (ob == obedit || drawlinked) { - DerivedMesh *finalDM, *cageDM; - - if (obedit != ob) { - /* linked to the edit object */ - finalDM = cageDM = editbmesh_get_derived_base( - ob, em, scene->customdata_mask); - } - else { - cageDM = editbmesh_get_derived_cage_and_final( - depsgraph, scene, ob, em, scene->customdata_mask, - &finalDM); - } - - const bool use_material = solid && ((me->drawflag & ME_DRAWEIGHT) == 0); - -#if 0 // why update if not being used? - DM_update_materials(finalDM, ob); - if (cageDM != finalDM) { - DM_update_materials(cageDM, ob); - } -#endif // moved to below - - if (use_material) { - DM_update_materials(finalDM, ob); - if (cageDM != finalDM) { - DM_update_materials(cageDM, ob); - } - - const bool glsl = draw_glsl_material(scene, view_layer, ob, v3d, dt); - - GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, glsl, NULL); - } - - draw_em_fancy_new(scene, ar, v3d, ob, me, em, cageDM, finalDM, dt); - - if (use_material) { - GPU_end_object_materials(); - } - - if (obedit != ob) - finalDM->release(finalDM); - } - else { - /* ob->bb was set by derived mesh system, do NULL check just to be sure */ - if (me->totpoly <= 4 || (!ob->bb || ED_view3d_boundbox_clip(rv3d, ob->bb))) { - if (solid) { - const bool glsl = draw_glsl_material(scene, view_layer, ob, v3d, dt); - - if (dt == OB_SOLID || glsl) { - const bool check_alpha = check_alpha_pass(base); - GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, glsl, - (check_alpha) ? &do_alpha_after : NULL); - } - } - - const bool other_obedit = obedit && (obedit != ob); - - draw_mesh_fancy_new(depsgraph, scene, view_layer, ar, v3d, rv3d, base, dt, ob_wire_col, dflag, other_obedit); - - GPU_end_object_materials(); - - if (me->totvert == 0) retval = true; - } - } - - if (cullBackface) - glDisable(GL_CULL_FACE); - - return retval; -} - -/* ************** DRAW DISPLIST ****************** */ - -static void drawDispListVerts(Gwn_PrimType prim_type, const void *data, unsigned int vert_ct, const unsigned char wire_col[3]) -{ - Gwn_VertFormat format = {0}; - unsigned int pos_id = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, vert_ct); - - GWN_vertbuf_attr_fill(vbo, pos_id, data); - - Gwn_Batch *batch = GWN_batch_create_ex(prim_type, vbo, NULL, GWN_BATCH_OWNS_VBO); - GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR); - if (wire_col) { - GWN_batch_uniform_4f(batch, "color", wire_col[0] / 255.0f, wire_col[1] / 255.0f, wire_col[2] / 255.0f, 1.0f); - } - GWN_batch_draw(batch); - GWN_batch_discard(batch); -} - -/* convert dispList with elem indices to batch, only support triangles and quads - * XXX : This is a huge perf issue. We should cache the resulting batches inside the object instead. - * But new viewport will do it anyway - * TODO implement flat drawing */ -static void drawDispListElem( - bool quads, bool UNUSED(smooth), bool ndata_is_single, - const float *data, const float *ndata, unsigned int data_len, - const int *elem, unsigned int elem_len, const unsigned char wire_col[3]) -{ - Gwn_VertFormat format = {0}; - int i; - const int *idx = elem; - unsigned int pos_id, nor_id; - - pos_id = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - if (ndata) { - if (ndata_is_single) { - /* pass */ - } - else { - nor_id = GWN_vertformat_attr_add(&format, "nor", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - } - } - - Gwn_IndexBufBuilder elb; - GWN_indexbuf_init(&elb, GWN_PRIM_TRIS, (quads) ? elem_len * 2 : elem_len, 0xffffffff); - - if (quads) { - for (i = elem_len; i; --i, idx += 4) { - GWN_indexbuf_add_tri_verts(&elb, idx[0], idx[1], idx[2]); - GWN_indexbuf_add_tri_verts(&elb, idx[0], idx[2], idx[3]); - } - } - else { - for (i = elem_len; i; --i, idx += 3) { - GWN_indexbuf_add_tri_verts(&elb, idx[0], idx[1], idx[2]); - } - } - - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, data_len); - - GWN_vertbuf_attr_fill(vbo, pos_id, data); - - if (ndata) { - if (ndata_is_single) { - /* TODO: something like glNormal for a single value */ - } - else { - GWN_vertbuf_attr_fill(vbo, nor_id, ndata); - } - } - - Gwn_Batch *batch = GWN_batch_create_ex( - GWN_PRIM_TRIS, vbo, GWN_indexbuf_build(&elb), GWN_BATCH_OWNS_VBO | GWN_BATCH_OWNS_INDEX); - GWN_batch_program_set_builtin(batch, GPU_SHADER_SIMPLE_LIGHTING); - if (wire_col) { - GWN_batch_uniform_4f(batch, "color", wire_col[0] / 255.0f, wire_col[1] / 255.0f, wire_col[2] / 255.0f, 1.0f); - } - GWN_batch_uniform_4f(batch, "color", 0.8f, 0.8f, 0.8f, 1.0f); - GWN_batch_uniform_3f(batch, "light", 0.0f, 0.0f, 1.0f); - GWN_batch_draw(batch); - GWN_batch_discard(batch); -} - -/** - * \param dl_type_mask Only draw types matching this mask. - * \return true when nothing was drawn - */ -static bool drawDispListwire_ex(ListBase *dlbase, unsigned int dl_type_mask, const unsigned char wire_col[3]) -{ - if (dlbase == NULL) return true; - - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - - for (DispList *dl = dlbase->first; dl; dl = dl->next) { - if (dl->parts == 0 || dl->nr == 0) { - continue; - } - - if ((dl_type_mask & (1 << dl->type)) == 0) { - continue; - } - - const float *data = dl->verts; - int parts; - - switch (dl->type) { - case DL_SEGM: - for (parts = 0; parts < dl->parts; parts++) - drawDispListVerts(GWN_PRIM_LINE_STRIP, data + (parts * dl->nr * 3), dl->nr, wire_col); - break; - - case DL_POLY: - for (parts = 0; parts < dl->parts; parts++) - drawDispListVerts(GWN_PRIM_LINE_LOOP, data + (parts * dl->nr * 3), dl->nr, wire_col); - break; - - case DL_SURF: - for (parts = 0; parts < dl->parts; parts++) { - if (dl->flag & DL_CYCL_U) - drawDispListVerts(GWN_PRIM_LINE_LOOP, data + (parts * dl->nr * 3), dl->nr, wire_col); - else - drawDispListVerts(GWN_PRIM_LINE_STRIP, data + (parts * dl->nr * 3), dl->nr, wire_col); - } - - float *data_aligned = MEM_mallocN(sizeof(float) * 3 * dl->parts, "aligned data"); - for (int nr = 0; nr < dl->nr; nr++) { - int ofs = 3 * dl->nr; - int idx = 0; - - data = (dl->verts) + 3 * nr; - parts = dl->parts; - - while (parts--) { - copy_v3_v3(data_aligned + idx, data); - data += ofs; - idx += 3; - } - - if (dl->flag & DL_CYCL_V) - drawDispListVerts(GWN_PRIM_LINE_LOOP, data_aligned, dl->parts, wire_col); - else - drawDispListVerts(GWN_PRIM_LINE_STRIP, data_aligned, dl->parts, wire_col); - } - - if (data_aligned) - MEM_freeN(data_aligned); - - break; - - case DL_INDEX3: - drawDispListElem( - false, true, false, - dl->verts, NULL, dl->nr, - dl->index, dl->parts, wire_col); - break; - - case DL_INDEX4: - drawDispListElem( - true, true, false, - dl->verts, NULL, dl->nr, - dl->index, dl->parts, wire_col); - break; - } - } - - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - - return false; -} - -static bool drawDispListwire(ListBase *dlbase, const short ob_type, const unsigned char wire_col[3]) -{ - unsigned int dl_mask = 0xffffffff; - - /* skip fill-faces for curves & fonts */ - if (ELEM(ob_type, OB_FONT, OB_CURVE)) { - dl_mask &= ~((1 << DL_INDEX3) | (1 << DL_INDEX4)); - } - - return drawDispListwire_ex(dlbase, dl_mask, wire_col); -} - -static bool index3_nors_incr = true; - -static void drawDispListsolid(ListBase *lb, Object *ob, const short UNUSED(dflag), - const unsigned char ob_wire_col[4], const bool use_glsl) -{ - GPUVertexAttribs gattribs; - - if (lb == NULL) return; - - /* track current material, -1 for none (needed for lines) */ - short col = -1; - - DispList *dl = lb->first; - while (dl) { - const float *data = dl->verts; - //const float *ndata = dl->nors; - - switch (dl->type) { - case DL_SEGM: - if (ob->type == OB_SURF) { - if (col != -1) { - GPU_object_material_unbind(); - col = -1; - } - - drawDispListVerts(GWN_PRIM_LINE_STRIP, data, dl->nr, ob_wire_col); - } - break; - case DL_POLY: - if (ob->type == OB_SURF) { - if (col != -1) { - GPU_object_material_unbind(); - col = -1; - } - - drawDispListVerts(GWN_PRIM_LINE_LOOP, data, dl->nr, ob_wire_col); - } - break; - case DL_SURF: - - if (dl->index) { - if (col != dl->col) { - GPU_object_material_bind(dl->col + 1, use_glsl ? &gattribs : NULL); - col = dl->col; - } - const unsigned int verts_len = dl->nr * dl->parts; - - drawDispListElem( - true, (dl->rt & CU_SMOOTH) != 0, false, - dl->verts, dl->nors, verts_len, - dl->index, dl->totindex, ob_wire_col); - } - break; - - case DL_INDEX3: - if (col != dl->col) { - GPU_object_material_bind(dl->col + 1, use_glsl ? &gattribs : NULL); - col = dl->col; - } - -#if 0 - /* for polys only one normal needed */ - if (index3_nors_incr) { - glEnableClientState(GL_NORMAL_ARRAY); - glNormalPointer(GL_FLOAT, 0, dl->nors); - } - else - glNormal3fv(ndata); -#endif - /* special case, 'nors' is a single value */ - drawDispListElem( - false, (dl->rt & CU_SMOOTH) != 0, true, - dl->verts, dl->nors, dl->nr, - dl->index, dl->parts, ob_wire_col); - -#if 0 - if (index3_nors_incr) - glDisableClientState(GL_NORMAL_ARRAY); -#endif - - break; - - case DL_INDEX4: - if (col != dl->col) { - GPU_object_material_bind(dl->col + 1, use_glsl ? &gattribs : NULL); - col = dl->col; - } - - drawDispListElem( - true, true, false, - dl->verts, dl->nors, dl->nr, - dl->index, dl->parts, ob_wire_col); - - break; - } - dl = dl->next; - } - - glFrontFace(GL_CCW); - - if (col != -1) { - GPU_object_material_unbind(); - } -} - -static void drawCurveDMWired(Object *ob) -{ - DerivedMesh *dm = ob->derivedFinal; - dm->drawEdges(dm, 1, 0); -} - -/* return true when nothing was drawn */ -static bool drawCurveDerivedMesh(Scene *scene, ViewLayer *view_layer, View3D *v3d, RegionView3D *rv3d, Base *base, const char dt) -{ - Object *ob = base->object; - DerivedMesh *dm = ob->derivedFinal; - - if (!dm) { - return true; - } - - DM_update_materials(dm, ob); - - glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW); - - if (dt > OB_WIRE && dm->getNumPolys(dm)) { - bool glsl = draw_glsl_material(scene, view_layer, ob, v3d, dt); - GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, glsl, NULL); - - if (!glsl) - dm->drawFacesSolid(dm, NULL, 0, GPU_object_material_bind); - else - dm->drawFacesGLSL(dm, GPU_object_material_bind); - - GPU_end_object_materials(); - } - else { - if (((v3d->flag2 & V3D_RENDER_OVERRIDE) && v3d->drawtype >= OB_SOLID) == 0) - drawCurveDMWired(ob); - } - - return false; -} - -/** - * Only called by #drawDispList - * \return true when nothing was drawn - */ -static bool drawDispList_nobackface(Scene *scene, ViewLayer *view_layer, View3D *v3d, RegionView3D *rv3d, Base *base, - const char dt, const short dflag, const unsigned char ob_wire_col[4]) -{ - Object *ob = base->object; - ListBase *lb = NULL; - DispList *dl; - Curve *cu; - const bool render_only = (v3d->flag2 & V3D_RENDER_OVERRIDE) != 0; - const bool solid = (dt > OB_WIRE); - - switch (ob->type) { - case OB_FONT: - case OB_CURVE: - cu = ob->data; - - lb = &ob->curve_cache->disp; - - if (solid) { - const bool has_faces = BKE_displist_has_faces(lb); - dl = lb->first; - if (dl == NULL) { - return true; - } - - if (dl->nors == NULL) BKE_displist_normals_add(lb); - index3_nors_incr = false; - - if (!render_only) { - /* when we have faces, only draw loose-wire */ - if (has_faces) { - drawDispListwire_ex(lb, (1 << DL_SEGM), ob_wire_col); - } - else { - drawDispListwire(lb, ob->type, ob_wire_col); - } - } - - if (has_faces == false) { - /* pass */ - } - else { - if (draw_glsl_material(scene, view_layer, ob, v3d, dt)) { - GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, 1, NULL); - drawDispListsolid(lb, ob, dflag, ob_wire_col, true); - GPU_end_object_materials(); - } - else { - GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, 0, NULL); - drawDispListsolid(lb, ob, dflag, ob_wire_col, false); - GPU_end_object_materials(); - } - if (cu->editnurb && cu->bevobj == NULL && cu->taperobj == NULL && cu->ext1 == 0.0f && cu->ext2 == 0.0f) { - unsigned char col[4] = {0, 0, 0, 0}; - drawDispListwire(lb, ob->type, col); - } - } - index3_nors_incr = true; - } - else { - if (!render_only || BKE_displist_has_faces(lb)) { - return drawDispListwire(lb, ob->type, ob_wire_col); - } - } - break; - case OB_SURF: - - lb = &ob->curve_cache->disp; - - if (solid) { - dl = lb->first; - if (dl == NULL) { - return true; - } - - if (dl->nors == NULL) BKE_displist_normals_add(lb); - - if (draw_glsl_material(scene, view_layer, ob, v3d, dt)) { - GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, 1, NULL); - drawDispListsolid(lb, ob, dflag, ob_wire_col, true); - GPU_end_object_materials(); - } - else { - GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, 0, NULL); - drawDispListsolid(lb, ob, dflag, ob_wire_col, false); - GPU_end_object_materials(); - } - } - else { - return drawDispListwire(lb, ob->type, ob_wire_col); - } - break; - case OB_MBALL: - - if (BKE_mball_is_basis(ob)) { - lb = &ob->curve_cache->disp; - if (BLI_listbase_is_empty(lb)) { - return true; - } - - if (solid) { - - if (draw_glsl_material(scene, view_layer, ob, v3d, dt)) { - GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, 1, NULL); - drawDispListsolid(lb, ob, dflag, ob_wire_col, true); - GPU_end_object_materials(); - } - else { - GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, 0, NULL); - drawDispListsolid(lb, ob, dflag, ob_wire_col, false); - GPU_end_object_materials(); - } - } - else { - return drawDispListwire(lb, ob->type, ob_wire_col); - } - } - break; - } - - return false; -} -static bool drawDispList( - Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer, View3D *v3d, RegionView3D *rv3d, Base *base, - const char dt, const short dflag, const unsigned char ob_wire_col[4]) -{ - bool retval; - - /* backface culling */ - if (v3d->flag2 & V3D_BACKFACE_CULLING) { - /* not all displists use same in/out normal direction convention */ - glEnable(GL_CULL_FACE); - glCullFace(GL_BACK); - } - -#ifdef SEQUENCER_DAG_WORKAROUND - ensure_curve_cache(depsgraph, scene, base->object); -#endif - - if (drawCurveDerivedMesh(scene, view_layer, v3d, rv3d, base, dt) == false) { - retval = false; - } - else { - Object *ob = base->object; - GLenum mode; - - if (ob->type == OB_MBALL) { - mode = (ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW; - } - else { - mode = (ob->transflag & OB_NEG_SCALE) ? GL_CCW : GL_CW; - } - - glFrontFace(mode); - - retval = drawDispList_nobackface(scene, view_layer, v3d, rv3d, base, dt, dflag, ob_wire_col); - - if (mode != GL_CCW) { - glFrontFace(GL_CCW); - } - } - - if (v3d->flag2 & V3D_BACKFACE_CULLING) { - glDisable(GL_CULL_FACE); - } - - return retval; -} - -/* *********** drawing for particles ************* */ -/* stride : offset size in bytes - * col[4] : the color to use when *color is NULL, can be also NULL */ -static void draw_vertex_array(Gwn_PrimType prim_type, const float *vert, const float *nor, const float *color, int stride, int vert_ct, float col[4]) -{ - Gwn_VertFormat format = {0}; - unsigned int pos_id, nor_id, col_id; - pos_id = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - if (nor) nor_id = GWN_vertformat_attr_add(&format, "nor", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - if (color) col_id = GWN_vertformat_attr_add(&format, "color", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, vert_ct); - - if (stride == 0) { - GWN_vertbuf_attr_fill(vbo, pos_id, vert); - if (nor) GWN_vertbuf_attr_fill(vbo, nor_id, nor); - if (color) GWN_vertbuf_attr_fill(vbo, col_id, color); - } - else { - GWN_vertbuf_attr_fill_stride(vbo, pos_id, stride, vert); - if (nor) GWN_vertbuf_attr_fill_stride(vbo, nor_id, stride, nor); - if (color) GWN_vertbuf_attr_fill_stride(vbo, col_id, stride, color); - } - - Gwn_Batch *batch = GWN_batch_create_ex(prim_type, vbo, NULL, GWN_BATCH_OWNS_VBO); - if (nor && color) { - GWN_batch_program_set_builtin(batch, GPU_SHADER_SIMPLE_LIGHTING_SMOOTH_COLOR); - GWN_batch_uniform_3f(batch, "light", 0.0f, 0.0f, 1.0f); - } - else if (nor) { - GWN_batch_program_set_builtin(batch, GPU_SHADER_SIMPLE_LIGHTING); - GWN_batch_uniform_3f(batch, "light", 0.0f, 0.0f, 1.0f); - if (col) GWN_batch_uniform_4fv(batch, "color", col); - } - else if (color) { - GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_SMOOTH_COLOR); - } - else { - GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR); - if (col) GWN_batch_uniform_4fv(batch, "color", col); - } - GWN_batch_draw(batch); - GWN_batch_discard(batch); -} - -static void draw_particle_arrays_new(int draw_as, int ob_dt, int select, - const float *vert, const float *nor, const float *color, - int totpoint, float col[4]) -{ - /* draw created data arrays */ - switch (draw_as) { - case PART_DRAW_AXIS: - case PART_DRAW_CROSS: - draw_vertex_array(GWN_PRIM_LINES, vert, nor, color, 0, 6 * totpoint, col); - break; - case PART_DRAW_LINE: - draw_vertex_array(GWN_PRIM_LINES, vert, nor, color, 0, 2 * totpoint, col); - break; - case PART_DRAW_BB: - if (ob_dt <= OB_WIRE || select) - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - else - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - - draw_vertex_array(GWN_PRIM_TRIS, vert, nor, color, 0, 6 * totpoint, col); - break; - default: - draw_vertex_array(GWN_PRIM_POINTS, vert, nor, color, 0, totpoint, col); - break; - } -} -static void draw_particle(ParticleKey *state, int draw_as, short draw, float pixsize, - float imat[4][4], const float draw_line[2], ParticleBillboardData *bb, ParticleDrawData *pdd, - unsigned int pos) -{ - float vec[3], vec2[3]; - float *vd = NULL; - float *cd = NULL; - float ma_col[3] = {0.0f, 0.0f, 0.0f}; - - /* null only for PART_DRAW_CIRC */ - if (pdd) { - vd = pdd->vd; - cd = pdd->cd; - - if (pdd->ma_col) { - copy_v3_v3(ma_col, pdd->ma_col); - } - } - - switch (draw_as) { - case PART_DRAW_DOT: - { - if (vd) { - copy_v3_v3(vd, state->co); pdd->vd += 3; - } - if (cd) { - copy_v3_v3(cd, pdd->ma_col); - pdd->cd += 3; - } - break; - } - case PART_DRAW_CROSS: - case PART_DRAW_AXIS: - { - vec[0] = 2.0f * pixsize; - vec[1] = vec[2] = 0.0; - mul_qt_v3(state->rot, vec); - if (draw_as == PART_DRAW_AXIS) { - if (cd) { - cd[1] = cd[2] = cd[4] = cd[5] = 0.0; - cd[0] = cd[3] = 1.0; - cd[6] = cd[8] = cd[9] = cd[11] = 0.0; - cd[7] = cd[10] = 1.0; - cd[13] = cd[12] = cd[15] = cd[16] = 0.0; - cd[14] = cd[17] = 1.0; - pdd->cd += 18; - } - - copy_v3_v3(vec2, state->co); - } - else { - if (cd) { - cd[0] = cd[3] = cd[6] = cd[9] = cd[12] = cd[15] = ma_col[0]; - cd[1] = cd[4] = cd[7] = cd[10] = cd[13] = cd[16] = ma_col[1]; - cd[2] = cd[5] = cd[8] = cd[11] = cd[14] = cd[17] = ma_col[2]; - pdd->cd += 18; - } - sub_v3_v3v3(vec2, state->co, vec); - } - - add_v3_v3(vec, state->co); - copy_v3_v3(pdd->vd, vec); pdd->vd += 3; - copy_v3_v3(pdd->vd, vec2); pdd->vd += 3; - - vec[1] = 2.0f * pixsize; - vec[0] = vec[2] = 0.0; - mul_qt_v3(state->rot, vec); - if (draw_as == PART_DRAW_AXIS) { - copy_v3_v3(vec2, state->co); - } - else { - sub_v3_v3v3(vec2, state->co, vec); - } - - add_v3_v3(vec, state->co); - copy_v3_v3(pdd->vd, vec); pdd->vd += 3; - copy_v3_v3(pdd->vd, vec2); pdd->vd += 3; - - vec[2] = 2.0f * pixsize; - vec[0] = vec[1] = 0.0f; - mul_qt_v3(state->rot, vec); - if (draw_as == PART_DRAW_AXIS) { - copy_v3_v3(vec2, state->co); - } - else { - sub_v3_v3v3(vec2, state->co, vec); - } - - add_v3_v3(vec, state->co); - - copy_v3_v3(pdd->vd, vec); pdd->vd += 3; - copy_v3_v3(pdd->vd, vec2); pdd->vd += 3; - break; - } - case PART_DRAW_LINE: - { - copy_v3_v3(vec, state->vel); - normalize_v3(vec); - if (draw & PART_DRAW_VEL_LENGTH) - mul_v3_fl(vec, len_v3(state->vel)); - madd_v3_v3v3fl(pdd->vd, state->co, vec, -draw_line[0]); pdd->vd += 3; - madd_v3_v3v3fl(pdd->vd, state->co, vec, draw_line[1]); pdd->vd += 3; - if (cd) { - cd[0] = cd[3] = ma_col[0]; - cd[1] = cd[4] = ma_col[1]; - cd[2] = cd[5] = ma_col[2]; - pdd->cd += 6; - } - break; - } - case PART_DRAW_CIRC: - { - imm_drawcircball(state->co, pixsize, imat, pos); - break; - } - case PART_DRAW_BB: - { - float xvec[3], yvec[3], zvec[3], bb_center[3]; - - copy_v3_v3(bb->vec, state->co); - copy_v3_v3(bb->vel, state->vel); - - psys_make_billboard(bb, xvec, yvec, zvec, bb_center); - - /* First tri */ - add_v3_v3v3(pdd->vd, bb_center, xvec); - add_v3_v3(pdd->vd, yvec); pdd->vd += 3; - - sub_v3_v3v3(pdd->vd, bb_center, xvec); - add_v3_v3(pdd->vd, yvec); pdd->vd += 3; - - sub_v3_v3v3(pdd->vd, bb_center, xvec); - sub_v3_v3v3(pdd->vd, pdd->vd, yvec); pdd->vd += 3; - - /* Second tri */ - add_v3_v3v3(pdd->vd, bb_center, xvec); - add_v3_v3(pdd->vd, yvec); pdd->vd += 3; - - sub_v3_v3v3(pdd->vd, bb_center, xvec); - sub_v3_v3v3(pdd->vd, pdd->vd, yvec); pdd->vd += 3; - - add_v3_v3v3(pdd->vd, bb_center, xvec); - sub_v3_v3v3(pdd->vd, pdd->vd, yvec); pdd->vd += 3; - - if (cd) { - for (int i = 0; i < 6; i++, cd += 3, pdd->cd += 3) { - copy_v3_v3(cd, ma_col); - } - } - for (int i = 0; i < 6; i++, pdd->nd += 3) { - copy_v3_v3(pdd->nd, zvec); - } - break; - } - } -} -static void draw_particle_data(ParticleSystem *psys, RegionView3D *rv3d, - ParticleKey *state, int draw_as, - float imat[4][4], ParticleBillboardData *bb, ParticleDrawData *pdd, - const float ct, const float pa_size, const float r_tilt, const float pixsize_scale, - unsigned int pos) -{ - ParticleSettings *part = psys->part; - float pixsize; - - if (psys->parent) - mul_m4_v3(psys->parent->obmat, state->co); - - /* create actual particle data */ - if (draw_as == PART_DRAW_BB) { - bb->offset[0] = part->bb_offset[0]; - bb->offset[1] = part->bb_offset[1]; - bb->size[0] = part->bb_size[0] * pa_size; - if (part->bb_align == PART_BB_VEL) { - float pa_vel = len_v3(state->vel); - float head = part->bb_vel_head * pa_vel; - float tail = part->bb_vel_tail * pa_vel; - bb->size[1] = part->bb_size[1] * pa_size + head + tail; - /* use offset to adjust the particle center. this is relative to size, so need to divide! */ - if (bb->size[1] > 0.0f) - bb->offset[1] += (head - tail) / bb->size[1]; - } - else { - bb->size[1] = part->bb_size[1] * pa_size; - } - bb->tilt = part->bb_tilt * (1.0f - part->bb_rand_tilt * r_tilt); - bb->time = ct; - } - - pixsize = ED_view3d_pixel_size(rv3d, state->co) * pixsize_scale; - - draw_particle(state, draw_as, part->draw, pixsize, imat, part->draw_line, bb, pdd, pos); -} -/* unified drawing of all new particle systems draw types except dupli ob & group - * mostly tries to use vertex arrays for speed - * - * 1. check that everything is ok & updated - * 2. start initializing things - * 3. initialize according to draw type - * 4. allocate drawing data arrays - * 5. start filling the arrays - * 6. draw the arrays - * 7. clean up - */ -static void draw_new_particle_system( - Depsgraph *depsgraph, Scene *scene, View3D *v3d, RegionView3D *rv3d, - Base *base, ParticleSystem *psys, - const char ob_dt, const short dflag) -{ - Object *ob = base->object; - ParticleEditSettings *pset = PE_settings(scene); - ParticleSettings *part = psys->part; - ParticleData *pars = psys->particles; - ParticleData *pa; - ParticleKey state, *states = NULL; - ParticleBillboardData bb; - ParticleSimulationData sim = {NULL}; - ParticleDrawData *pdd = psys->pdd; - Material *ma; - float vel[3], imat[4][4]; - float timestep, pixsize_scale = 1.0f, pa_size, r_tilt, r_length; - float pa_time, pa_birthtime, pa_dietime, pa_health, intensity; - float cfra; - float ma_col[3] = {0.0f, 0.0f, 0.0f}; - int a, totpart, totpoint = 0, totve = 0, drawn, draw_as, totchild = 0; - bool select = (base->flag & BASE_SELECTED) != 0, create_cdata = false, need_v = false; - GLint polygonmode[2]; - char numstr[32]; - unsigned char tcol[4] = {0, 0, 0, 255}; - unsigned int pos; - -/* 1. */ - if (part == NULL || !psys_check_enabled(ob, psys, G.is_rendering)) - return; - - if (pars == NULL) return; - - /* don't draw normal paths in edit mode */ - if (psys_in_edit_mode(depsgraph, psys) && (pset->flag & PE_DRAW_PART) == 0) - return; - - if (part->draw_as == PART_DRAW_REND) - draw_as = part->ren_as; - else - draw_as = part->draw_as; - - if (draw_as == PART_DRAW_NOT) - return; - - /* prepare curvemapping tables */ - if ((psys->part->child_flag & PART_CHILD_USE_CLUMP_CURVE) && psys->part->clumpcurve) - curvemapping_changed_all(psys->part->clumpcurve); - if ((psys->part->child_flag & PART_CHILD_USE_ROUGH_CURVE) && psys->part->roughcurve) - curvemapping_changed_all(psys->part->roughcurve); - if ((psys->part->child_flag & PART_CHILD_USE_TWIST_CURVE) && psys->part->twistcurve) - curvemapping_changed_all(psys->part->twistcurve); - -/* 2. */ - sim.depsgraph = depsgraph; - sim.scene = scene; - sim.ob = ob; - sim.psys = psys; - sim.psmd = psys_get_modifier(ob, psys); - - if (part->phystype == PART_PHYS_KEYED) { - if (psys->flag & PSYS_KEYED) { - psys_count_keyed_targets(&sim); - if (psys->totkeyed == 0) - return; - } - } - - if (select) { - select = false; - if (psys_get_current(ob) == psys) - select = true; - } - - psys->flag |= PSYS_DRAWING; - - if (part->type == PART_HAIR && !psys->childcache) - totchild = 0; - else - totchild = psys->totchild * part->disp / 100; - - ma = give_current_material(ob, part->omat); - - if (v3d->zbuf) glDepthMask(1); - - if ((ma) && (part->draw_col == PART_DRAW_COL_MAT)) { - rgb_float_to_uchar(tcol, &(ma->r)); - copy_v3_v3(ma_col, &ma->r); - } - - timestep = psys_get_timestep(&sim); - - if ((ob->flag & OB_FROMGROUP) != 0) { - float mat[4][4]; - mul_m4_m4m4(mat, ob->obmat, psys->imat); - gpuMultMatrix(mat); - } - - /* needed for text display */ - invert_m4_m4(ob->imat, ob->obmat); - - totpart = psys->totpart; - - cfra = BKE_scene_frame_get(scene); - - if (draw_as == PART_DRAW_PATH && psys->pathcache == NULL && psys->childcache == NULL) - draw_as = PART_DRAW_DOT; - -/* 3. */ - glLineWidth(1.0f); - - switch (draw_as) { - case PART_DRAW_DOT: - if (part->draw_size) - glPointSize(part->draw_size); - else - glPointSize(2.0); /* default dot size */ - break; - case PART_DRAW_CIRC: - /* calculate view aligned matrix: */ - copy_m4_m4(imat, rv3d->viewinv); - normalize_v3(imat[0]); - normalize_v3(imat[1]); - ATTR_FALLTHROUGH; - case PART_DRAW_CROSS: - case PART_DRAW_AXIS: - /* lets calculate the scale: */ - - if (part->draw_size == 0.0) - pixsize_scale = 2.0f; - else - pixsize_scale = part->draw_size; - - if (draw_as == PART_DRAW_AXIS) - create_cdata = 1; - break; - case PART_DRAW_OB: - if (part->dup_ob == NULL) - draw_as = PART_DRAW_DOT; - else - draw_as = 0; - break; - case PART_DRAW_GR: - if (part->dup_group == NULL) - draw_as = PART_DRAW_DOT; - else - draw_as = 0; - break; - case PART_DRAW_BB: - if (v3d->camera == NULL && part->bb_ob == NULL) { - printf("Billboards need an active camera or a target object!\n"); - - draw_as = part->draw_as = PART_DRAW_DOT; - - if (part->draw_size) - glPointSize(part->draw_size); - else - glPointSize(2.0); /* default dot size */ - } - else if (part->bb_ob) - bb.ob = part->bb_ob; - else - bb.ob = v3d->camera; - - bb.align = part->bb_align; - bb.anim = part->bb_anim; - bb.lock = part->draw & PART_DRAW_BB_LOCK; - break; - case PART_DRAW_PATH: - break; - case PART_DRAW_LINE: - need_v = 1; - break; - } - if (part->draw & PART_DRAW_SIZE && part->draw_as != PART_DRAW_CIRC) { - copy_m4_m4(imat, rv3d->viewinv); - normalize_v3(imat[0]); - normalize_v3(imat[1]); - } - - if (ELEM(draw_as, PART_DRAW_DOT, PART_DRAW_CROSS, PART_DRAW_LINE) && - (part->draw_col > PART_DRAW_COL_MAT)) - { - create_cdata = 1; - } - - if (!create_cdata && pdd && pdd->cdata) { - MEM_freeN(pdd->cdata); - pdd->cdata = pdd->cd = NULL; - } - -/* 4. */ - if (draw_as && ELEM(draw_as, PART_DRAW_PATH, PART_DRAW_CIRC) == 0) { - int partsize = 3 * sizeof(float); - int create_ndata = 0; - - if (!pdd) - pdd = psys->pdd = MEM_callocN(sizeof(ParticleDrawData), "ParticleDrawData"); - - if (part->draw_as == PART_DRAW_REND && part->trail_count > 1) { - partsize *= part->trail_count; - psys_make_temp_pointcache(ob, psys); - } - - switch (draw_as) { - case PART_DRAW_AXIS: - case PART_DRAW_CROSS: - partsize *= 6; - if (draw_as != PART_DRAW_CROSS) - create_cdata = 1; - break; - case PART_DRAW_LINE: - partsize *= 2; - break; - case PART_DRAW_BB: - partsize *= 6; /* New OGL only understands tris, no choice here. */ - create_ndata = 1; - break; - } - - if (pdd->totpart != totpart + totchild || pdd->partsize != partsize) - psys_free_pdd(psys); - - if (!pdd->vdata) - pdd->vdata = MEM_calloc_arrayN(totpart + totchild, partsize, "particle_vdata"); - if (create_cdata && !pdd->cdata) - pdd->cdata = MEM_calloc_arrayN(totpart + totchild, partsize, "particle_cdata"); - if (create_ndata && !pdd->ndata) - pdd->ndata = MEM_calloc_arrayN(totpart + totchild, partsize, "particle_ndata"); - - if (part->draw & PART_DRAW_VEL && draw_as != PART_DRAW_LINE) { - if (!pdd->vedata) - pdd->vedata = MEM_calloc_arrayN(totpart + totchild, 2 * 3 * sizeof(float), "particle_vedata"); - - need_v = 1; - } - else if (pdd->vedata) { - /* velocity data not needed, so free it */ - MEM_freeN(pdd->vedata); - pdd->vedata = NULL; - } - - pdd->vd = pdd->vdata; - pdd->ved = pdd->vedata; - pdd->cd = pdd->cdata; - pdd->nd = pdd->ndata; - pdd->totpart = totpart + totchild; - pdd->partsize = partsize; - } - else if (psys->pdd) { - psys_free_pdd(psys); - MEM_freeN(psys->pdd); - pdd = psys->pdd = NULL; - } - - if (pdd) { - pdd->ma_col = ma_col; - } - - psys->lattice_deform_data = psys_create_lattice_deform_data(&sim); - - /* circles don't use drawdata, so have to add a special case here */ - if ((pdd || draw_as == PART_DRAW_CIRC) && draw_as != PART_DRAW_PATH) { - /* 5. */ - if (pdd && (pdd->flag & PARTICLE_DRAW_DATA_UPDATED) && - (pdd->vedata || part->draw & (PART_DRAW_SIZE | PART_DRAW_NUM | PART_DRAW_HEALTH)) == 0) - { - totpoint = pdd->totpoint; /* draw data is up to date */ - } - else { - if ((draw_as == PART_DRAW_CIRC) || (part->draw & PART_DRAW_SIZE)) { - pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - imm_cpack(0xFFFFFF); - } - for (a = 0, pa = pars; a < totpart + totchild; a++, pa++) { - /* setup per particle individual stuff */ - if (a < totpart) { - if (totchild && (part->draw & PART_DRAW_PARENT) == 0) continue; - if (pa->flag & PARS_NO_DISP || pa->flag & PARS_UNEXIST) continue; - - pa_time = (cfra - pa->time) / pa->lifetime; - pa_birthtime = pa->time; - pa_dietime = pa->dietime; - pa_size = pa->size; - if (part->phystype == PART_PHYS_BOIDS) - pa_health = pa->boid->data.health; - else - pa_health = -1.0; - - r_tilt = 2.0f * (psys_frand(psys, a + 21) - 0.5f); - r_length = psys_frand(psys, a + 22); - - if (part->draw_col > PART_DRAW_COL_MAT) { - switch (part->draw_col) { - case PART_DRAW_COL_VEL: - intensity = len_v3(pa->state.vel) / part->color_vec_max; - break; - case PART_DRAW_COL_ACC: - intensity = len_v3v3(pa->state.vel, pa->prev_state.vel) / ((pa->state.time - pa->prev_state.time) * part->color_vec_max); - break; - default: - intensity = 1.0f; /* should never happen */ - BLI_assert(0); - break; - } - CLAMP(intensity, 0.0f, 1.0f); - weight_to_rgb(ma_col, intensity); - } - } - else { - ChildParticle *cpa = &psys->child[a - totpart]; - - pa_time = psys_get_child_time(psys, cpa, cfra, &pa_birthtime, &pa_dietime); - pa_size = psys_get_child_size(psys, cpa, cfra, NULL); - - pa_health = -1.0; - - r_tilt = 2.0f * (psys_frand(psys, a + 21) - 0.5f); - r_length = psys_frand(psys, a + 22); - } - - drawn = 0; - if (part->draw_as == PART_DRAW_REND && part->trail_count > 1) { - float length = part->path_end * (1.0f - part->randlength * r_length); - int trail_count = part->trail_count * (1.0f - part->randlength * r_length); - float ct = ((part->draw & PART_ABS_PATH_TIME) ? cfra : pa_time) - length; - float dt = length / (trail_count ? (float)trail_count : 1.0f); - int i = 0; - - ct += dt; - for (i = 0; i < trail_count; i++, ct += dt) { - - if (part->draw & PART_ABS_PATH_TIME) { - if (ct < pa_birthtime || ct > pa_dietime) - continue; - } - else if (ct < 0.0f || ct > 1.0f) - continue; - - state.time = (part->draw & PART_ABS_PATH_TIME) ? -ct : -(pa_birthtime + ct * (pa_dietime - pa_birthtime)); - psys_get_particle_on_path(&sim, a, &state, need_v); - - draw_particle_data(psys, rv3d, - &state, draw_as, imat, &bb, psys->pdd, - ct, pa_size, r_tilt, pixsize_scale, pos); - - totpoint++; - drawn = 1; - } - } - else { - state.time = cfra; - if (psys_get_particle_state(&sim, a, &state, 0)) { - - draw_particle_data(psys, rv3d, - &state, draw_as, imat, &bb, psys->pdd, - pa_time, pa_size, r_tilt, pixsize_scale, pos); - - totpoint++; - drawn = 1; - } - } - - if (drawn) { - /* additional things to draw for each particle - * (velocity, size and number) */ - if ((part->draw & PART_DRAW_VEL) && pdd && pdd->vedata) { - copy_v3_v3(pdd->ved, state.co); - pdd->ved += 3; - mul_v3_v3fl(vel, state.vel, timestep); - add_v3_v3v3(pdd->ved, state.co, vel); - pdd->ved += 3; - - totve++; - } - - if (part->draw & PART_DRAW_SIZE) { - setlinestyle(3); - imm_drawcircball(state.co, pa_size, imat, pos); - setlinestyle(0); - } - - - if ((part->draw & PART_DRAW_NUM || part->draw & PART_DRAW_HEALTH) && - (v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) - { - size_t numstr_len; - float vec_txt[3]; - char *val_pos = numstr; - numstr[0] = '\0'; - - if (part->draw & PART_DRAW_NUM) { - if (a < totpart && (part->draw & PART_DRAW_HEALTH) && (part->phystype == PART_PHYS_BOIDS)) { - numstr_len = BLI_snprintf_rlen(val_pos, sizeof(numstr), "%d:%.2f", a, pa_health); - } - else { - numstr_len = BLI_snprintf_rlen(val_pos, sizeof(numstr), "%d", a); - } - } - else { - if (a < totpart && (part->draw & PART_DRAW_HEALTH) && (part->phystype == PART_PHYS_BOIDS)) { - numstr_len = BLI_snprintf_rlen(val_pos, sizeof(numstr), "%.2f", pa_health); - } - } - - if (numstr[0]) { - /* in path drawing state.co is the end point - * use worldspace because object matrix is already applied */ - mul_v3_m4v3(vec_txt, ob->imat, state.co); - view3d_cached_text_draw_add(vec_txt, numstr, numstr_len, - 10, V3D_CACHE_TEXT_WORLDSPACE | V3D_CACHE_TEXT_ASCII, tcol); - } - } - } - } - if ((draw_as == PART_DRAW_CIRC) || (part->draw & PART_DRAW_SIZE)) { - immUnbindProgram(); - } - } - } -/* 6. */ - - glGetIntegerv(GL_POLYGON_MODE, polygonmode); - - if (draw_as == PART_DRAW_PATH) { - ParticleCacheKey **cache, *path; - float *cdata2 = NULL; - - if (totchild && (part->draw & PART_DRAW_PARENT) == 0) - totpart = 0; - else if (psys->pathcache == NULL) - totpart = 0; - - /* draw actual/parent particles */ - cache = psys->pathcache; - for (a = 0, pa = psys->particles; a < totpart; a++, pa++) { - path = cache[a]; - if (path->segments > 0) { - if (((dflag & DRAW_CONSTCOLOR) == 0) && (part->draw_col == PART_DRAW_COL_MAT)) { - draw_vertex_array(GWN_PRIM_LINE_STRIP, path->co, path->vel, path->col, sizeof(ParticleCacheKey), path->segments + 1, NULL); - } - else { - float color[4]; - rgba_uchar_to_float(color, tcol); - draw_vertex_array(GWN_PRIM_LINE_STRIP, path->co, path->vel, NULL, sizeof(ParticleCacheKey), path->segments + 1, color); - } - } - } - - if (part->type == PART_HAIR) { - if (part->draw & PART_DRAW_GUIDE_HAIRS) { - DerivedMesh *hair_dm = psys->hair_out_dm; - - for (a = 0, pa = psys->particles; a < totpart; a++, pa++) { - if (pa->totkey > 1) { - HairKey *hkey = pa->hair; - - /* XXX use proper theme color here */ - float color[4] = {0.58f, 0.67f, 1.0f, 1.0f}; - draw_vertex_array(GWN_PRIM_LINE_STRIP, hkey->world_co, NULL, NULL, sizeof(HairKey), pa->totkey, color); - } - } - - if (hair_dm) { - MVert *mvert = hair_dm->getVertArray(hair_dm); - int i; - - unsigned int pos_id = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - immUniformColor3f(0.9f, 0.4f, 0.4f); - - unsigned int count = 0; - for (a = 0, pa = psys->particles; a < totpart; a++, pa++) { - count += MAX2(pa->totkey - 1, 0); - } - - if (count > 0) { - immBegin(GWN_PRIM_LINES, count * 2); - for (a = 0, pa = psys->particles; a < totpart; a++, pa++) { - for (i = 1; i < pa->totkey; ++i) { - float v1[3], v2[3]; - - copy_v3_v3(v1, mvert[pa->hair_index + i - 1].co); - copy_v3_v3(v2, mvert[pa->hair_index + i].co); - - mul_m4_v3(ob->obmat, v1); - mul_m4_v3(ob->obmat, v2); - - immVertex3fv(pos_id, v1); - immVertex3fv(pos_id, v2); - } - } - immEnd(); - } - - immUnbindProgram(); - } - } - - if (part->draw & PART_DRAW_HAIR_GRID) { - ClothModifierData *clmd = psys->clmd; - if (clmd) { - float *gmin = clmd->hair_grid_min; - float *gmax = clmd->hair_grid_max; - int *res = clmd->hair_grid_res; - int i; - - unsigned int pos_id = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - if (select) - immUniformThemeColor(TH_ACTIVE); - else - immUniformThemeColor(TH_WIRE); - - immBegin(GWN_PRIM_LINES, 24); - immVertex3f(pos_id, gmin[0], gmin[1], gmin[2]); immVertex3f(pos_id, gmax[0], gmin[1], gmin[2]); - immVertex3f(pos_id, gmax[0], gmin[1], gmin[2]); immVertex3f(pos_id, gmax[0], gmax[1], gmin[2]); - immVertex3f(pos_id, gmax[0], gmax[1], gmin[2]); immVertex3f(pos_id, gmin[0], gmax[1], gmin[2]); - immVertex3f(pos_id, gmin[0], gmax[1], gmin[2]); immVertex3f(pos_id, gmin[0], gmin[1], gmin[2]); - - immVertex3f(pos_id, gmin[0], gmin[1], gmax[2]); immVertex3f(pos_id, gmax[0], gmin[1], gmax[2]); - immVertex3f(pos_id, gmax[0], gmin[1], gmax[2]); immVertex3f(pos_id, gmax[0], gmax[1], gmax[2]); - immVertex3f(pos_id, gmax[0], gmax[1], gmax[2]); immVertex3f(pos_id, gmin[0], gmax[1], gmax[2]); - immVertex3f(pos_id, gmin[0], gmax[1], gmax[2]); immVertex3f(pos_id, gmin[0], gmin[1], gmax[2]); - - immVertex3f(pos_id, gmin[0], gmin[1], gmin[2]); immVertex3f(pos_id, gmin[0], gmin[1], gmax[2]); - immVertex3f(pos_id, gmax[0], gmin[1], gmin[2]); immVertex3f(pos_id, gmax[0], gmin[1], gmax[2]); - immVertex3f(pos_id, gmin[0], gmax[1], gmin[2]); immVertex3f(pos_id, gmin[0], gmax[1], gmax[2]); - immVertex3f(pos_id, gmax[0], gmax[1], gmin[2]); immVertex3f(pos_id, gmax[0], gmax[1], gmax[2]); - immEnd(); - - if (select) - immUniformThemeColorShadeAlpha(TH_ACTIVE, 0, -100); - else - immUniformThemeColorShadeAlpha(TH_WIRE, 0, -100); - - int count = 0; - count += MAX2(0, res[0] - 2) * 8; - count += MAX2(0, res[1] - 2) * 8; - count += MAX2(0, res[2] - 2) * 8; - - if (count >= 2) { - glEnable(GL_BLEND); - immBegin(GWN_PRIM_LINES, count); - for (i = 1; i < res[0] - 1; ++i) { - float f = interpf(gmax[0], gmin[0], (float)i / (float)(res[0] - 1)); - immVertex3f(pos_id, f, gmin[1], gmin[2]); immVertex3f(pos_id, f, gmax[1], gmin[2]); - immVertex3f(pos_id, f, gmax[1], gmin[2]); immVertex3f(pos_id, f, gmax[1], gmax[2]); - immVertex3f(pos_id, f, gmax[1], gmax[2]); immVertex3f(pos_id, f, gmin[1], gmax[2]); - immVertex3f(pos_id, f, gmin[1], gmax[2]); immVertex3f(pos_id, f, gmin[1], gmin[2]); - } - for (i = 1; i < res[1] - 1; ++i) { - float f = interpf(gmax[1], gmin[1], (float)i / (float)(res[1] - 1)); - immVertex3f(pos_id, gmin[0], f, gmin[2]); immVertex3f(pos_id, gmax[0], f, gmin[2]); - immVertex3f(pos_id, gmax[0], f, gmin[2]); immVertex3f(pos_id, gmax[0], f, gmax[2]); - immVertex3f(pos_id, gmax[0], f, gmax[2]); immVertex3f(pos_id, gmin[0], f, gmax[2]); - immVertex3f(pos_id, gmin[0], f, gmax[2]); immVertex3f(pos_id, gmin[0], f, gmin[2]); - } - for (i = 1; i < res[2] - 1; ++i) { - float f = interpf(gmax[2], gmin[2], (float)i / (float)(res[2] - 1)); - immVertex3f(pos_id, gmin[0], gmin[1], f); immVertex3f(pos_id, gmax[0], gmin[1], f); - immVertex3f(pos_id, gmax[0], gmin[1], f); immVertex3f(pos_id, gmax[0], gmax[1], f); - immVertex3f(pos_id, gmax[0], gmax[1], f); immVertex3f(pos_id, gmin[0], gmax[1], f); - immVertex3f(pos_id, gmin[0], gmax[1], f); immVertex3f(pos_id, gmin[0], gmin[1], f); - } - immEnd(); - glDisable(GL_BLEND); - } - - immUnbindProgram(); - } - } - } - - /* draw child particles */ - cache = psys->childcache; - for (a = 0; a < totchild; a++) { - path = cache[a]; - - if (((dflag & DRAW_CONSTCOLOR) == 0) && (part->draw_col == PART_DRAW_COL_MAT)) { - draw_vertex_array(GWN_PRIM_LINE_STRIP, path->co, path->vel, path->col, sizeof(ParticleCacheKey), path->segments + 1, NULL); - } - else { - float color[4] = {0.0f, 0.0f, 0.0f, 1.0f}; - draw_vertex_array(GWN_PRIM_LINE_STRIP, path->co, path->vel, NULL, sizeof(ParticleCacheKey), path->segments + 1, color); - } - } - - /* restore & clean up */ - if (cdata2) { - MEM_freeN(cdata2); - cdata2 = NULL; - } - - if ((part->draw & PART_DRAW_NUM) && (v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { - cache = psys->pathcache; - - for (a = 0, pa = psys->particles; a < totpart; a++, pa++) { - float vec_txt[3]; - size_t numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%i", a); - /* use worldspace because object matrix is already applied */ - mul_v3_m4v3(vec_txt, ob->imat, cache[a]->co); - view3d_cached_text_draw_add(vec_txt, numstr, numstr_len, - 10, V3D_CACHE_TEXT_WORLDSPACE | V3D_CACHE_TEXT_ASCII, tcol); - } - } - } - else if (pdd && ELEM(draw_as, 0, PART_DRAW_CIRC) == 0) { - - if (pdd->vdata) { - if (select) { - float color[4]; - UI_GetThemeColor4fv(TH_ACTIVE, color); - - if (part->draw_size) - glPointSize(part->draw_size + 2); - else - glPointSize(4.0); - - glLineWidth(3.0); - - draw_particle_arrays_new(draw_as, ob_dt, 1, pdd->vdata, NULL, NULL, totpoint, color); - } - - glPointSize(part->draw_size ? part->draw_size : 2.0); - glLineWidth(1.0); - - -#if 0 - /* enable other data arrays */ - /* billboards are drawn this way */ - if (pdd->ndata && ob_dt > OB_WIRE) { - GPU_basic_shader_colors(NULL, NULL, 0.0f, 1.0f); - GPU_basic_shader_bind(GPU_SHADER_LIGHTING | GPU_SHADER_USE_COLOR); - } - if ((dflag & DRAW_CONSTCOLOR) == 0) { - if (pdd->cdata) { - glEnableClientState(GL_COLOR_ARRAY); - glColorPointer(3, GL_FLOAT, 0, pdd->cdata); - } - } -#endif - - draw_particle_arrays_new(draw_as, ob_dt, 0, pdd->vdata, pdd->ndata, pdd->cdata, totpoint, NULL); - } - - - pdd->flag |= PARTICLE_DRAW_DATA_UPDATED; - pdd->totpoint = totpoint; - } - - if (pdd && pdd->vedata) { - float color[4] = {0.75f, 0.75f, 0.75f, 1.0f}; - draw_vertex_array(GWN_PRIM_LINES, pdd->vedata, NULL, NULL, 0, 2 * totve, color); - } - - glPolygonMode(GL_FRONT, polygonmode[0]); - glPolygonMode(GL_BACK, polygonmode[1]); - -/* 7. */ - - GPU_basic_shader_bind(GPU_SHADER_USE_COLOR); - - if (states) - MEM_freeN(states); - - psys->flag &= ~PSYS_DRAWING; - - /* draw data can't be saved for billboards as they must update to target changes */ - if (draw_as == PART_DRAW_BB) { - psys_free_pdd(psys); - pdd->flag &= ~PARTICLE_DRAW_DATA_UPDATED; - } - - if (psys->lattice_deform_data) { - end_latt_deform(psys->lattice_deform_data); - psys->lattice_deform_data = NULL; - } - - if (pdd) { - /* drop references to stack memory */ - pdd->ma_col = NULL; - } - - if ((ob->flag & OB_FROMGROUP) != 0) { - gpuLoadMatrix(rv3d->viewmat); - } -} - -static void draw_update_ptcache_edit( - Depsgraph *depsgraph, Scene *scene, Object *ob, PTCacheEdit *edit) -{ - if (edit->psys && edit->psys->flag & PSYS_HAIR_UPDATED) - PE_update_object(depsgraph, scene, ob, 0); - - /* create path and child path cache if it doesn't exist already */ - if (edit->pathcache == NULL) { - psys_cache_edit_paths(depsgraph, scene, ob, edit, CFRA, G.is_rendering); - } -} - -static void draw_ptcache_edit(Scene *scene, View3D *v3d, PTCacheEdit *edit) -{ - ParticleEditSettings *pset = PE_settings(scene); - const int totpoint = edit->totpoint; - const bool timed = (pset->flag & PE_FADE_TIME) ? pset->fade_frames : false; - - if (edit->pathcache == NULL) - return; - - PE_hide_keys_time(scene, edit, CFRA); - - /* opengl setup */ - if ((v3d->flag & V3D_ZBUF_SELECT) == 0) - glDisable(GL_DEPTH_TEST); - - /* get selection theme colors */ - float sel_col[3], nosel_col[3]; - UI_GetThemeColor3fv(TH_VERTEX_SELECT, sel_col); - UI_GetThemeColor3fv(TH_VERTEX, nosel_col); - - /* draw paths */ - const int totkeys = (*edit->pathcache)->segments + 1; - - glEnable(GL_BLEND); - float *pathcol = MEM_calloc_arrayN(totkeys, 4 * sizeof(float), "particle path color data"); - - if (pset->brushtype == PE_BRUSH_WEIGHT) - glLineWidth(2.0f); - - ParticleCacheKey **cache = edit->pathcache; - PTCacheEditPoint *point; - int i; - - for (i = 0, point = edit->points; i < totpoint; i++, point++) { - ParticleCacheKey *path = cache[i]; - - Gwn_VertFormat format = {0}; - unsigned int pos_id, col_id, col_comp; - - col_comp = ((point->flag & PEP_HIDE) || timed) ? 4 : 3; - - pos_id = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - col_id = GWN_vertformat_attr_add(&format, "color", GWN_COMP_F32, col_comp, GWN_FETCH_FLOAT); - - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, path->segments + 1); - - GWN_vertbuf_attr_fill_stride(vbo, pos_id, sizeof(ParticleCacheKey), path->co); - - float *pcol = pathcol; - - if (point->flag & PEP_HIDE) { - for (int k = 0; k < totkeys; k++, pcol += 4) { - copy_v3_v3(pcol, path->col); - pcol[3] = 0.25f; - } - - GWN_vertbuf_attr_fill(vbo, col_id, pathcol); - } - else if (timed) { - ParticleCacheKey *pkey = path; - for (int k = 0; k < totkeys; k++, pkey++, pcol += 4) { - copy_v3_v3(pcol, pkey->col); - pcol[3] = 1.0f - fabsf((float)(CFRA) -pkey->time) / (float)pset->fade_frames; - } - - GWN_vertbuf_attr_fill(vbo, col_id, pathcol); - } - else { - /* FIXME: shader wants 4 color components but the cache only contains ParticleCacheKey - * So alpha is random */ - GWN_vertbuf_attr_fill_stride(vbo, col_id, sizeof(ParticleCacheKey), path->col); - } - - Gwn_Batch *batch = GWN_batch_create_ex(GWN_PRIM_LINE_STRIP, vbo, NULL, GWN_BATCH_OWNS_VBO); - GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_SMOOTH_COLOR); - GWN_batch_draw(batch); - GWN_batch_discard(batch); - } - - if (pathcol) { MEM_freeN(pathcol); pathcol = NULL; } - - /* draw edit vertices */ - if (pset->selectmode != SCE_SELECT_PATH) { - glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE)); - - if (pset->selectmode == SCE_SELECT_POINT) { - float *pd = NULL, *pdata = NULL; - float *cd = NULL, *cdata = NULL; - int totkeys_visible = 0; - - Gwn_VertFormat format = {0}; - unsigned int pos_id = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - unsigned int col_id = GWN_vertformat_attr_add(&format, "color", GWN_COMP_F32, (timed ? 4 : 3), GWN_FETCH_FLOAT); - - for (i = 0, point = edit->points; i < totpoint; i++, point++) - if (!(point->flag & PEP_HIDE)) - totkeys_visible += point->totkey; - - if (totkeys_visible) { - if (edit->points && !(edit->points->keys->flag & PEK_USE_WCO)) - pd = pdata = MEM_calloc_arrayN(totkeys_visible, 3 * sizeof(float), "particle edit point data"); - cd = cdata = MEM_calloc_arrayN(totkeys_visible, (timed ? 4 : 3) * sizeof(float), "particle edit color data"); - } - - for (i = 0, point = edit->points; i < totpoint; i++, point++) { - if (point->flag & PEP_HIDE) - continue; - - PTCacheEditKey *key = point->keys; - for (int k = 0; k < point->totkey; k++, key++) { - if (pd) { - copy_v3_v3(pd, key->co); - pd += 3; - } - - if (key->flag & PEK_SELECT) { - copy_v3_v3(cd, sel_col); - } - else { - copy_v3_v3(cd, nosel_col); - } - - if (timed) - *(cd + 3) = 1.0f - fabsf((float)CFRA - *key->time) / (float)pset->fade_frames; - - cd += (timed ? 4 : 3); - } - } - cd = cdata; - pd = pdata; - for (i = 0, point = edit->points; i < totpoint; i++, point++) { - if (point->flag & PEP_HIDE || point->totkey == 0) - continue; - - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, point->totkey); - - if (point->keys->flag & PEK_USE_WCO) - GWN_vertbuf_attr_fill_stride(vbo, pos_id, sizeof(PTCacheEditKey), point->keys->world_co); - else - GWN_vertbuf_attr_fill(vbo, pos_id, pd); - - GWN_vertbuf_attr_fill(vbo, col_id, cd); - - Gwn_Batch *batch = GWN_batch_create_ex(GWN_PRIM_POINTS, vbo, NULL, GWN_BATCH_OWNS_VBO); - GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_SMOOTH_COLOR); - GWN_batch_draw(batch); - GWN_batch_discard(batch); - - pd += pd ? 3 * point->totkey : 0; - cd += (timed ? 4 : 3) * point->totkey; - } - if (pdata) { MEM_freeN(pdata); pd = pdata = NULL; } - if (cdata) { MEM_freeN(cdata); cd = cdata = NULL; } - } - else if (pset->selectmode == SCE_SELECT_END) { - Gwn_VertFormat *format = immVertexFormat(); - unsigned int pos_id = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - unsigned int col_id = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR); - immBeginAtMost(GWN_PRIM_POINTS, totpoint); - for (i = 0, point = edit->points; i < totpoint; i++, point++) { - if ((point->flag & PEP_HIDE) == 0 && point->totkey) { - PTCacheEditKey *key = point->keys + point->totkey - 1; - if ((key->flag & PEK_SELECT) != 0) { - immAttrib3fv(col_id, sel_col); - } - else { - immAttrib3fv(col_id, nosel_col); - } - /* has to be like this.. otherwise selection won't work, have try glArrayElement later..*/ - immVertex3fv(pos_id, (key->flag & PEK_USE_WCO) ? key->world_co : key->co); - } - } - immEnd(); - immUnbindProgram(); - } - } - - glDisable(GL_BLEND); - if (v3d->zbuf) glEnable(GL_DEPTH_TEST); -} - -static void ob_draw_RE_motion(float com[3], float rotscale[3][3], float itw, float ith, float drw_size) -{ - float tr[3][3]; - float root[3], tip[3]; - /* take a copy for not spoiling original */ - copy_m3_m3(tr, rotscale); - float tw = itw * drw_size; - float th = ith * drw_size; - - Gwn_VertFormat *format = immVertexFormat(); - unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - unsigned int col = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT); - immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR); - - immBegin(GWN_PRIM_LINES, 30); - - immAttrib4ub(col, 0x7F, 0x00, 0x00, 155); - root[1] = root[2] = 0.0f; - root[0] = -drw_size; - mul_m3_v3(tr, root); - add_v3_v3(root, com); - immVertex3fv(pos, root); - tip[1] = tip[2] = 0.0f; - tip[0] = drw_size; - mul_m3_v3(tr, tip); - add_v3_v3(tip, com); - immVertex3fv(pos, tip); - - root[1] = 0.0f; root[2] = tw; - root[0] = th; - mul_m3_v3(tr, root); - add_v3_v3(root, com); - immVertex3fv(pos, root); - immVertex3fv(pos, tip); - - root[1] = 0.0f; root[2] = -tw; - root[0] = th; - mul_m3_v3(tr, root); - add_v3_v3(root, com); - immVertex3fv(pos, root); - immVertex3fv(pos, tip); - - root[1] = tw; root[2] = 0.0f; - root[0] = th; - mul_m3_v3(tr, root); - add_v3_v3(root, com); - immVertex3fv(pos, root); - immVertex3fv(pos, tip); - - root[1] = -tw; root[2] = 0.0f; - root[0] = th; - mul_m3_v3(tr, root); - add_v3_v3(root, com); - immVertex3fv(pos, root); - immVertex3fv(pos, tip); - - immAttrib4ub(col, 0x00, 0x7F, 0x00, 155); - - root[0] = root[2] = 0.0f; - root[1] = -drw_size; - mul_m3_v3(tr, root); - add_v3_v3(root, com); - immVertex3fv(pos, root); - tip[0] = tip[2] = 0.0f; - tip[1] = drw_size; - mul_m3_v3(tr, tip); - add_v3_v3(tip, com); - immVertex3fv(pos, tip); - - root[0] = 0.0f; root[2] = tw; - root[1] = th; - mul_m3_v3(tr, root); - add_v3_v3(root, com); - immVertex3fv(pos, root); - immVertex3fv(pos, tip); - - root[0] = 0.0f; root[2] = -tw; - root[1] = th; - mul_m3_v3(tr, root); - add_v3_v3(root, com); - immVertex3fv(pos, root); - immVertex3fv(pos, tip); - - root[0] = tw; root[2] = 0.0f; - root[1] = th; - mul_m3_v3(tr, root); - add_v3_v3(root, com); - immVertex3fv(pos, root); - immVertex3fv(pos, tip); - - root[0] = -tw; root[2] = 0.0f; - root[1] = th; - mul_m3_v3(tr, root); - add_v3_v3(root, com); - immVertex3fv(pos, root); - immVertex3fv(pos, tip); - - immAttrib4ub(col, 0x00, 0x00, 0x7F, 155); - root[0] = root[1] = 0.0f; - root[2] = -drw_size; - mul_m3_v3(tr, root); - add_v3_v3(root, com); - immVertex3fv(pos, root); - tip[0] = tip[1] = 0.0f; - tip[2] = drw_size; - mul_m3_v3(tr, tip); - add_v3_v3(tip, com); - immVertex3fv(pos, tip); - - root[0] = 0.0f; root[1] = tw; - root[2] = th; - mul_m3_v3(tr, root); - add_v3_v3(root, com); - immVertex3fv(pos, root); - immVertex3fv(pos, tip); - - root[0] = 0.0f; root[1] = -tw; - root[2] = th; - mul_m3_v3(tr, root); - add_v3_v3(root, com); - immVertex3fv(pos, root); - immVertex3fv(pos, tip); - - root[0] = tw; root[1] = 0.0f; - root[2] = th; - mul_m3_v3(tr, root); - add_v3_v3(root, com); - immVertex3fv(pos, root); - immVertex3fv(pos, tip); - - root[0] = -tw; root[1] = 0.0f; - root[2] = th; - mul_m3_v3(tr, root); - add_v3_v3(root, com); - immVertex3fv(pos, root); - immVertex3fv(pos, tip); - - immEnd(); - - immUnbindProgram(); -} - -/* place to add drawers */ - -static void drawhandlesN(Nurb *nu, const char sel, const bool hide_handles) -{ - if (nu->hide || hide_handles) return; - - if (nu->type == CU_BEZIER && nu->pntsu > 0) { - - const float *fp; - -#define TH_HANDLE_COL_TOT ((TH_HANDLE_SEL_FREE - TH_HANDLE_FREE) + 1) - /* use MIN2 when indexing to ensure newer files don't read outside the array */ - unsigned char handle_cols[TH_HANDLE_COL_TOT][3]; - const int basecol = sel ? TH_HANDLE_SEL_FREE : TH_HANDLE_FREE; - - for (int a = 0; a < TH_HANDLE_COL_TOT; a++) { - UI_GetThemeColor3ubv(basecol + a, handle_cols[a]); - } - - Gwn_VertFormat *format = immVertexFormat(); - unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - unsigned int col = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 3, GWN_FETCH_INT_TO_FLOAT_UNIT); - immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR); - - glLineWidth(1.0f); - - immBeginAtMost(GWN_PRIM_LINES, nu->pntsu * 4); - - BezTriple *bezt = nu->bezt; - int a = nu->pntsu; - while (a--) { - if (bezt->hide == 0) { - if ((bezt->f2 & SELECT) == sel) { - fp = bezt->vec[0]; - - immAttrib3ubv(col, handle_cols[MIN2(bezt->h1, TH_HANDLE_COL_TOT - 1)]); - immVertex3fv(pos, fp); - immVertex3fv(pos, fp + 3); - - immAttrib3ubv(col, handle_cols[MIN2(bezt->h2, TH_HANDLE_COL_TOT - 1)]); - immVertex3fv(pos, fp + 3); - immVertex3fv(pos, fp + 6); - } - else if ((bezt->f1 & SELECT) == sel) { - fp = bezt->vec[0]; - - immAttrib3ubv(col, handle_cols[MIN2(bezt->h1, TH_HANDLE_COL_TOT - 1)]); - immVertex3fv(pos, fp); - immVertex3fv(pos, fp + 3); - } - else if ((bezt->f3 & SELECT) == sel) { - fp = bezt->vec[1]; - - immAttrib3ubv(col, handle_cols[MIN2(bezt->h2, TH_HANDLE_COL_TOT - 1)]); - immVertex3fv(pos, fp); - immVertex3fv(pos, fp + 3); - } - } - bezt++; - } - - immEnd(); - - immUnbindProgram(); - -#undef TH_HANDLE_COL_TOT - - } -} - -static void drawhandlesN_active(Nurb *nu) -{ - if (nu->hide) return; - - if (nu->type == CU_BEZIER && nu->pntsu > 0) { - unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - immUniformThemeColor(TH_ACTIVE_SPLINE); - glLineWidth(2.0f); - - immBeginAtMost(GWN_PRIM_LINES, nu->pntsu * 4); - BezTriple *bezt = nu->bezt; - int a = nu->pntsu; - while (a--) { - if (bezt->hide == 0) { - const float *fp = bezt->vec[0]; - - immVertex3fv(pos, fp); - immVertex3fv(pos, fp + 3); - - immVertex3fv(pos, fp + 3); - immVertex3fv(pos, fp + 6); - } - bezt++; - } - immEnd(); - immUnbindProgram(); - } -} - -static void drawvertsN(const Nurb *nurb, const bool hide_handles, const void *vert) -{ - const Nurb *nu; - - // just quick guesstimate of how many verts to draw - int count = 0; - for (nu = nurb; nu; nu = nu->next) { - if (!nu->hide) { - if (nu->type == CU_BEZIER) { - count += nu->pntsu * 3; - } - else { - count += nu->pntsu * nu->pntsv; - } - } - } - if (count == 0) return; - - Gwn_VertFormat *format = immVertexFormat(); - unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - unsigned int color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 3, GWN_FETCH_INT_TO_FLOAT_UNIT); - immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR); - - unsigned char vert_color[3]; - unsigned char vert_color_select[3]; - unsigned char vert_color_active[3]; - UI_GetThemeColor3ubv(TH_VERTEX, vert_color); - UI_GetThemeColor3ubv(TH_VERTEX_SELECT, vert_color_select); - UI_GetThemeColor3ubv(TH_ACTIVE_VERT, vert_color_active); - - glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE)); - - immBeginAtMost(GWN_PRIM_POINTS, count); - - for (nu = nurb; nu; nu = nu->next) { - - if (nu->hide) continue; - - if (nu->type == CU_BEZIER) { - - const BezTriple *bezt = nu->bezt; - int a = nu->pntsu; - while (a--) { - if (bezt->hide == 0) { - if (bezt == vert) { - immAttrib3ubv(color, bezt->f2 & SELECT ? vert_color_active : vert_color); - immVertex3fv(pos, bezt->vec[1]); - if (!hide_handles) { - immAttrib3ubv(color, bezt->f1 & SELECT ? vert_color_active : vert_color); - immVertex3fv(pos, bezt->vec[0]); - immAttrib3ubv(color, bezt->f3 & SELECT ? vert_color_active : vert_color); - immVertex3fv(pos, bezt->vec[2]); - } - } - else { - immAttrib3ubv(color, bezt->f2 & SELECT ? vert_color_select : vert_color); - immVertex3fv(pos, bezt->vec[1]); - if (!hide_handles) { - immAttrib3ubv(color, bezt->f1 & SELECT ? vert_color_select : vert_color); - immVertex3fv(pos, bezt->vec[0]); - immAttrib3ubv(color, bezt->f3 & SELECT ? vert_color_select : vert_color); - immVertex3fv(pos, bezt->vec[2]); - } - } - } - bezt++; - } - } - else { - const BPoint *bp = nu->bp; - int a = nu->pntsu * nu->pntsv; - while (a--) { - if (bp->hide == 0) { - if (bp == vert) { - immAttrib3ubv(color, vert_color_active); - } - else { - immAttrib3ubv(color, bp->f1 & SELECT ? vert_color_select : vert_color); - } - immVertex3fv(pos, bp->vec); - } - bp++; - } - } - } - - immEnd(); - immUnbindProgram(); -} - -static void editnurb_draw_active_poly(Nurb *nu) -{ - Gwn_VertFormat *format = immVertexFormat(); - unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - immUniformThemeColor(TH_ACTIVE_SPLINE); - - glLineWidth(2.0f); - - BPoint *bp = nu->bp; - for (int b = 0; b < nu->pntsv; b++) { - if (nu->pntsu >= 2) { - if (nu->flagu & 1) immBegin(GWN_PRIM_LINE_LOOP, nu->pntsu); - else immBegin(GWN_PRIM_LINE_STRIP, nu->pntsu); - - for (int a = 0; a < nu->pntsu; a++, bp++) { - immVertex3fv(pos, bp->vec); - } - - immEnd(); - } - } - - immUnbindProgram(); -} - -static void editnurb_draw_active_nurbs(Nurb *nu) -{ - if (nu->pntsv > 0) { - Gwn_VertFormat *format = immVertexFormat(); - unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - immUniformThemeColor(TH_ACTIVE_SPLINE); - - glLineWidth(2.0f); - // just quick guesstimate of how many verts to draw - int count = (nu->pntsu - 1) * nu->pntsv * 2; - if (nu->pntsv > 1) count += (nu->pntsv - 1) * nu->pntsu * 2; - if (count < 2) return; - - immBeginAtMost(GWN_PRIM_LINES, count); - BPoint *bp = nu->bp; - for (int b = 0; b < nu->pntsv; b++) { - BPoint *bp1 = bp; - bp++; - - for (int a = nu->pntsu - 1; a > 0; a--, bp++) { - if (bp->hide == 0 && bp1->hide == 0) { - immVertex3fv(pos, bp->vec); - immVertex3fv(pos, bp1->vec); - } - bp1 = bp; - } - } - - if (nu->pntsv > 1) { /* surface */ - int ofs = nu->pntsu; - for (int b = 0; b < nu->pntsu; b++) { - BPoint *bp1 = nu->bp + b; - bp = bp1 + ofs; - for (int a = nu->pntsv - 1; a > 0; a--, bp += ofs) { - if (bp->hide == 0 && bp1->hide == 0) { - immVertex3fv(pos, bp->vec); - immVertex3fv(pos, bp1->vec); - } - bp1 = bp; - } - } - } - - immEnd(); - - immUnbindProgram(); - } -} - -static void draw_editnurb_splines(Object *ob, Nurb *nurb, const bool sel) -{ - BPoint *bp, *bp1; - int a, b; - Curve *cu = ob->data; - Gwn_VertFormat *format; - unsigned int pos, col; - unsigned char color[3]; - - int index = 0; - Nurb *nu = nurb; - while (nu) { - if (nu->hide == 0) { - switch (nu->type) { - case CU_POLY: - { - if (!sel && index == cu->actnu) { - /* we should draw active spline highlight below everything */ - editnurb_draw_active_poly(nu); - } - - format = immVertexFormat(); - pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - - glLineWidth(1.0f); - - immUniformThemeColor(TH_NURB_ULINE); - bp = nu->bp; - for (b = 0; b < nu->pntsv; b++) { - if (nu->pntsu >= 2) { - if (nu->flagu & 1) immBegin(GWN_PRIM_LINE_LOOP, nu->pntsu); - else immBegin(GWN_PRIM_LINE_STRIP, nu->pntsu); - - for (a = 0; a < nu->pntsu; a++, bp++) { - immVertex3fv(pos, bp->vec); - } - - immEnd(); - } - } - immUnbindProgram(); - break; - } - case CU_NURBS: - { - if (!sel && index == cu->actnu) { - /* we should draw active spline highlight below everything */ - editnurb_draw_active_nurbs(nu); - } - - format = immVertexFormat(); - pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - col = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 3, GWN_FETCH_INT_TO_FLOAT_UNIT); - immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR); - - // just quick guesstimate of how many verts to draw - int count = (nu->pntsu - 1) * nu->pntsv * 2; - if (nu->pntsv > 1) count += (nu->pntsv - 1) * nu->pntsu * 2; - if (count < 2) return; - - glLineWidth(1.0f); - - immBeginAtMost(GWN_PRIM_LINES, count); - - bp = nu->bp; - for (b = 0; b < nu->pntsv; b++) { - bp1 = bp; - bp++; - for (a = nu->pntsu - 1; a > 0; a--, bp++) { - if (bp->hide == 0 && bp1->hide == 0) { - if (sel) { - if ((bp->f1 & SELECT) && (bp1->f1 & SELECT)) { - UI_GetThemeColor3ubv(TH_NURB_SEL_ULINE, color); - immAttrib3ubv(col, color); - immVertex3fv(pos, bp->vec); - immVertex3fv(pos, bp1->vec); - } - } - else { - if ((bp->f1 & SELECT) && (bp1->f1 & SELECT)) { - /* pass */ - } - else { - UI_GetThemeColor3ubv(TH_NURB_ULINE, color); - immAttrib3ubv(col, color); - immVertex3fv(pos, bp->vec); - immVertex3fv(pos, bp1->vec); - } - } - } - bp1 = bp; - } - } - - if (nu->pntsv > 1) { /* surface */ - int ofs = nu->pntsu; - for (b = 0; b < nu->pntsu; b++) { - bp1 = nu->bp + b; - bp = bp1 + ofs; - for (a = nu->pntsv - 1; a > 0; a--, bp += ofs) { - if (bp->hide == 0 && bp1->hide == 0) { - if (sel) { - if ((bp->f1 & SELECT) && (bp1->f1 & SELECT)) { - UI_GetThemeColor3ubv(TH_NURB_SEL_VLINE, color); - immAttrib3ubv(col, color); - immVertex3fv(pos, bp->vec); - immVertex3fv(pos, bp1->vec); - } - } - else { - if ((bp->f1 & SELECT) && (bp1->f1 & SELECT)) { - /* pass */ - } - else { - UI_GetThemeColor3ubv(TH_NURB_VLINE, color); - immAttrib3ubv(col, color); - immVertex3fv(pos, bp->vec); - immVertex3fv(pos, bp1->vec); - } - } - } - bp1 = bp; - } - } - } - immEnd(); - immUnbindProgram(); - break; - } - } - } - - index++; - nu = nu->next; - } -} - -static void draw_editnurb( - Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer, - View3D *v3d, RegionView3D *rv3d, Base *base, Nurb *nurb, - const char dt, const short dflag, const unsigned char UNUSED(ob_wire_col[4])) -{ - ToolSettings *ts = scene->toolsettings; - Object *ob = base->object; - Curve *cu = ob->data; - Nurb *nu; - const void *vert = BKE_curve_vert_active_get(cu); - const bool hide_handles = (cu->drawflag & CU_HIDE_HANDLES) != 0; - unsigned char wire_col[3]; - - /* DispList */ - UI_GetThemeColor3ubv(TH_WIRE_EDIT, wire_col); - - drawDispList(depsgraph, scene, view_layer, v3d, rv3d, base, dt, dflag, wire_col); - - /* for shadows only show solid faces */ - if (v3d->flag2 & V3D_RENDER_SHADOW) - return; - - if (v3d->zbuf) glDepthFunc(GL_ALWAYS); - - /* first non-selected and active handles */ - int index = 0; - for (nu = nurb; nu; nu = nu->next) { - if (nu->type == CU_BEZIER) { - if (index == cu->actnu && !hide_handles) - drawhandlesN_active(nu); - drawhandlesN(nu, 0, hide_handles); - } - index++; - } - draw_editnurb_splines(ob, nurb, false); - draw_editnurb_splines(ob, nurb, true); - /* selected handles */ - for (nu = nurb; nu; nu = nu->next) { - if (nu->type == CU_BEZIER && (cu->drawflag & CU_HIDE_HANDLES) == 0) - drawhandlesN(nu, 1, hide_handles); - } - - if (v3d->zbuf) glDepthFunc(GL_LEQUAL); - - /* direction vectors for 3d curve paths - * when at its lowest, don't render normals */ - if ((cu->flag & CU_3D) && (ts->normalsize > 0.0015f) && (cu->drawflag & CU_HIDE_NORMALS) == 0) { - BevList *bl; - - Gwn_VertFormat *format = immVertexFormat(); - unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - immUniformThemeColor(TH_WIRE_EDIT); - - glLineWidth(1.0f); - - int count = 0; - int count_used = 0; - for (bl = ob->curve_cache->bev.first, nu = nurb; nu && bl; bl = bl->next, nu = nu->next) { - int nr = bl->nr; - int skip = nu->resolu / 16; - -#if 0 - while (nr-- > 0) { /* accounts for empty bevel lists */ - count += 4; - nr -= skip; - } -#else - /* Same as loop above */ - count += 4 * ((nr / (skip + 1)) + ((nr % (skip + 1)) != 0)); -#endif - } - - if (count > 2) { - immBegin(GWN_PRIM_LINES, count); - for (bl = ob->curve_cache->bev.first, nu = nurb; nu && bl; bl = bl->next, nu = nu->next) { - BevPoint *bevp = bl->bevpoints; - int nr = bl->nr; - int skip = nu->resolu / 16; - - while (nr-- > 0) { /* accounts for empty bevel lists */ - const float fac = bevp->radius * ts->normalsize; - float vec_a[3]; /* Offset perpendicular to the curve */ - float vec_b[3]; /* Delta along the curve */ - - vec_a[0] = fac; - vec_a[1] = 0.0f; - vec_a[2] = 0.0f; - - mul_qt_v3(bevp->quat, vec_a); - madd_v3_v3fl(vec_a, bevp->dir, -fac); - - reflect_v3_v3v3(vec_b, vec_a, bevp->dir); - negate_v3(vec_b); - - add_v3_v3(vec_a, bevp->vec); - add_v3_v3(vec_b, bevp->vec); - - immVertex3fv(pos, vec_a); - immVertex3fv(pos, bevp->vec); - immVertex3fv(pos, bevp->vec); - immVertex3fv(pos, vec_b); - - bevp += skip + 1; - nr -= skip; - count_used += 4; - } - } - BLI_assert(count == count_used); - UNUSED_VARS_NDEBUG(count_used); - - immEnd(); - } - immUnbindProgram(); - } - - if (v3d->zbuf) glDisable(GL_DEPTH_TEST); - - drawvertsN(nurb, hide_handles, vert); - - if (v3d->zbuf) glEnable(GL_DEPTH_TEST); -} - -static void draw_editfont_textcurs(RegionView3D *rv3d, float textcurs[4][2]) -{ - unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - ED_view3d_polygon_offset(rv3d, -1.0); - set_inverted_drawing(1); - immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); - imm_cpack(0); - immBegin(GWN_PRIM_TRI_FAN, 4); - immVertex2fv(pos, textcurs[0]); - immVertex2fv(pos, textcurs[1]); - immVertex2fv(pos, textcurs[2]); - immVertex2fv(pos, textcurs[3]); - immEnd(); - set_inverted_drawing(0); - ED_view3d_polygon_offset(rv3d, 0.0); - immUnbindProgram(); -} - -static void draw_editfont( - Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer, View3D *v3d, RegionView3D *rv3d, Base *base, - const char dt, const short dflag, const unsigned char ob_wire_col[4]) -{ - Object *ob = base->object; - Curve *cu = ob->data; - EditFont *ef = cu->editfont; - float vec1[3], vec2[3]; - - draw_editfont_textcurs(rv3d, ef->textcurs); - - if (cu->flag & CU_FAST) { - imm_cpack(0xFFFFFF); - set_inverted_drawing(1); - drawDispList(depsgraph, scene, view_layer, v3d, rv3d, base, OB_WIRE, dflag, ob_wire_col); - set_inverted_drawing(0); - } - else { - drawDispList(depsgraph, scene, view_layer, v3d, rv3d, base, dt, dflag, ob_wire_col); - } - - if (cu->linewidth != 0.0f) { - unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); - immUniformThemeColor(TH_WIRE_EDIT); - copy_v3_v3(vec1, ob->orig); - copy_v3_v3(vec2, ob->orig); - vec1[0] += cu->linewidth; - vec2[0] += cu->linewidth; - vec1[1] += cu->linedist * cu->fsize; - vec2[1] -= cu->lines * cu->linedist * cu->fsize; - setlinestyle(3); - immBegin(GWN_PRIM_LINES, 2); - immVertex2fv(pos, vec1); - immVertex2fv(pos, vec2); - immEnd(); - setlinestyle(0); - immUnbindProgram(); - } - - setlinestyle(3); - for (int i = 0; i < cu->totbox; i++) { - if (cu->tb[i].w != 0.0f) { - unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - immUniformThemeColor(i == (cu->actbox - 1) ? TH_ACTIVE : TH_WIRE); - vec1[0] = cu->xof + cu->tb[i].x; - vec1[1] = cu->yof + cu->tb[i].y + cu->fsize; - vec1[2] = 0.001; - immBegin(GWN_PRIM_LINE_STRIP, 5); - immVertex3fv(pos, vec1); - vec1[0] += cu->tb[i].w; - immVertex3fv(pos, vec1); - vec1[1] -= cu->tb[i].h; - immVertex3fv(pos, vec1); - vec1[0] -= cu->tb[i].w; - immVertex3fv(pos, vec1); - vec1[1] += cu->tb[i].h; - immVertex3fv(pos, vec1); - immEnd(); - immUnbindProgram(); - } - } - setlinestyle(0); - - - if (ef->selboxes && ef->selboxes_len) { - float selboxw; - - unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - imm_cpack(0xffffff); - set_inverted_drawing(1); - for (int i = 0; i < ef->selboxes_len; i++) { - EditFontSelBox *sb = &ef->selboxes[i]; - float tvec[3]; - - if (i + 1 != ef->selboxes_len) { - if (ef->selboxes[i + 1].y == sb->y) - selboxw = ef->selboxes[i + 1].x - sb->x; - else - selboxw = sb->w; - } - else { - selboxw = sb->w; - } - - /* fill in xy below */ - tvec[2] = 0.001; - - immBegin(GWN_PRIM_TRI_FAN, 4); - - if (sb->rot == 0.0f) { - copy_v2_fl2(tvec, sb->x, sb->y); - immVertex3fv(pos, tvec); - - copy_v2_fl2(tvec, sb->x + selboxw, sb->y); - immVertex3fv(pos, tvec); - - copy_v2_fl2(tvec, sb->x + selboxw, sb->y + sb->h); - immVertex3fv(pos, tvec); - - copy_v2_fl2(tvec, sb->x, sb->y + sb->h); - immVertex3fv(pos, tvec); - } - else { - float mat[2][2]; - - angle_to_mat2(mat, sb->rot); - - copy_v2_fl2(tvec, sb->x, sb->y); - immVertex3fv(pos, tvec); - - copy_v2_fl2(tvec, selboxw, 0.0f); - mul_m2v2(mat, tvec); - add_v2_v2(tvec, &sb->x); - immVertex3fv(pos, tvec); - - copy_v2_fl2(tvec, selboxw, sb->h); - mul_m2v2(mat, tvec); - add_v2_v2(tvec, &sb->x); - immVertex3fv(pos, tvec); - - copy_v2_fl2(tvec, 0.0f, sb->h); - mul_m2v2(mat, tvec); - add_v2_v2(tvec, &sb->x); - immVertex3fv(pos, tvec); - } - - immEnd(); - } - set_inverted_drawing(0); - immUnbindProgram(); - } -} - -/* draw a sphere for use as an empty drawtype */ -static void draw_empty_sphere(float size, unsigned pos) -{ -#define NSEGMENTS 16 - /* a single ring of vertices */ - float p[NSEGMENTS][2]; - for (int i = 0; i < NSEGMENTS; ++i) { - float angle = 2 * M_PI * ((float)i / (float)NSEGMENTS); - p[i][0] = size * cosf(angle); - p[i][1] = size * sinf(angle); - } - - immBegin(GWN_PRIM_LINE_LOOP, NSEGMENTS); - for (int i = 0; i < NSEGMENTS; ++i) - immVertex3f(pos, p[i][0], p[i][1], 0.0f); - immEnd(); - immBegin(GWN_PRIM_LINE_LOOP, NSEGMENTS); - for (int i = 0; i < NSEGMENTS; ++i) - immVertex3f(pos, p[i][0], 0.0f, p[i][1]); - immEnd(); - immBegin(GWN_PRIM_LINE_LOOP, NSEGMENTS); - for (int i = 0; i < NSEGMENTS; ++i) - immVertex3f(pos, 0.0f, p[i][0], p[i][1]); - immEnd(); -#undef NSEGMENTS -} - -/* draw a cone for use as an empty drawtype */ -static void draw_empty_cone(float size, unsigned pos) -{ -#define NSEGMENTS 8 - /* a single ring of vertices */ - float p[NSEGMENTS][2]; - for (int i = 0; i < NSEGMENTS; ++i) { - float angle = 2 * M_PI * ((float)i / (float)NSEGMENTS); - p[i][0] = size * cosf(angle); - p[i][1] = size * sinf(angle); - } - - /* cone sides */ - immBegin(GWN_PRIM_LINES, NSEGMENTS * 2); - for (int i = 0; i < NSEGMENTS; ++i) { - immVertex3f(pos, 0.0f, 2.0f * size, 0.0f); - immVertex3f(pos, p[i][0], 0.0f, p[i][1]); - } - immEnd(); - - /* end ring */ - immBegin(GWN_PRIM_LINE_LOOP, NSEGMENTS); - for (int i = 0; i < NSEGMENTS; ++i) - immVertex3f(pos, p[i][0], 0.0f, p[i][1]); - immEnd(); -#undef NSEGMENTS -} - -static void drawspiral(unsigned int pos, const float cent[3], float rad, float tmat[4][4], int start) -{ - float vec[3], vx[3], vy[3]; - const float tot_inv = 1.0f / (float)CIRCLE_RESOL; - int a; - bool inverse = false; - float x, y, fac; - - if (start < 0) { - inverse = true; - start = -start; - } - - mul_v3_v3fl(vx, tmat[0], rad); - mul_v3_v3fl(vy, tmat[1], rad); - - immBegin(GWN_PRIM_LINE_STRIP, CIRCLE_RESOL + 1); - - if (inverse == 0) { - copy_v3_v3(vec, cent); - immVertex3fv(pos, vec); - - for (a = 0; a < CIRCLE_RESOL; a++) { - if (a + start >= CIRCLE_RESOL) - start = -a + 1; - - fac = (float)a * tot_inv; - x = sinval[a + start] * fac; - y = cosval[a + start] * fac; - - vec[0] = cent[0] + (x * vx[0] + y * vy[0]); - vec[1] = cent[1] + (x * vx[1] + y * vy[1]); - vec[2] = cent[2] + (x * vx[2] + y * vy[2]); - - immVertex3fv(pos, vec); - } - } - else { - fac = (float)(CIRCLE_RESOL - 1) * tot_inv; - x = sinval[start] * fac; - y = cosval[start] * fac; - - vec[0] = cent[0] + (x * vx[0] + y * vy[0]); - vec[1] = cent[1] + (x * vx[1] + y * vy[1]); - vec[2] = cent[2] + (x * vx[2] + y * vy[2]); - - immVertex3fv(pos, vec); - - for (a = 0; a < CIRCLE_RESOL; a++) { - if (a + start >= CIRCLE_RESOL) - start = -a + 1; - - fac = (float)(-a + (CIRCLE_RESOL - 1)) * tot_inv; - x = sinval[a + start] * fac; - y = cosval[a + start] * fac; - - vec[0] = cent[0] + (x * vx[0] + y * vy[0]); - vec[1] = cent[1] + (x * vx[1] + y * vy[1]); - vec[2] = cent[2] + (x * vx[2] + y * vy[2]); - immVertex3fv(pos, vec); - } - } - - immEnd(); -} - -/* draws a circle on x-z plane given the scaling of the circle, assuming that - * all required matrices have been set (used for drawing empties) */ -static void drawcircle_size(float size, unsigned pos) -{ - immBegin(GWN_PRIM_LINE_LOOP, CIRCLE_RESOL); - - /* coordinates are: cos(degrees * 11.25) = x, sin(degrees * 11.25) = y, 0.0f = z */ - for (short degrees = 0; degrees < CIRCLE_RESOL; degrees++) { - float x = cosval[degrees]; - float y = sinval[degrees]; - - immVertex3f(pos, x * size, 0.0f, y * size); - } - - immEnd(); -} - -/* needs fixing if non-identity matrix used */ -static void imm_drawtube(const float vec[3], float radius, float height, float tmat[4][4], unsigned pos) -{ - float cur[3]; - imm_drawcircball(vec, radius, tmat, pos); - - copy_v3_v3(cur, vec); - cur[2] += height; - - imm_drawcircball(cur, radius, tmat, pos); - - immBegin(GWN_PRIM_LINES, 8); - immVertex3f(pos, vec[0] + radius, vec[1], vec[2]); - immVertex3f(pos, cur[0] + radius, cur[1], cur[2]); - immVertex3f(pos, vec[0] - radius, vec[1], vec[2]); - immVertex3f(pos, cur[0] - radius, cur[1], cur[2]); - immVertex3f(pos, vec[0], vec[1] + radius, vec[2]); - immVertex3f(pos, cur[0], cur[1] + radius, cur[2]); - immVertex3f(pos, vec[0], vec[1] - radius, vec[2]); - immVertex3f(pos, cur[0], cur[1] - radius, cur[2]); - immEnd(); -} - -/* needs fixing if non-identity matrix used */ -static void imm_drawcone(const float vec[3], float radius, float height, float tmat[4][4], unsigned pos) -{ - float cur[3]; - - copy_v3_v3(cur, vec); - cur[2] += height; - - imm_drawcircball(cur, radius, tmat, pos); - - immBegin(GWN_PRIM_LINES, 8); - immVertex3f(pos, vec[0], vec[1], vec[2]); - immVertex3f(pos, cur[0] + radius, cur[1], cur[2]); - immVertex3f(pos, vec[0], vec[1], vec[2]); - immVertex3f(pos, cur[0] - radius, cur[1], cur[2]); - immVertex3f(pos, vec[0], vec[1], vec[2]); - immVertex3f(pos, cur[0], cur[1] + radius, cur[2]); - immVertex3f(pos, vec[0], vec[1], vec[2]); - immVertex3f(pos, cur[0], cur[1] - radius, cur[2]); - immEnd(); -} - -/* return true if nothing was drawn */ -static bool drawmball( - Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer, View3D *v3d, RegionView3D *rv3d, Base *base, - const char dt, const short dflag, const unsigned char ob_wire_col[4]) -{ - Object *ob = base->object; - MetaElem *ml; - float imat[4][4]; - int code = 1; - - MetaBall *mb = ob->data; - - if (mb->editelems) { - if ((G.f & G_PICKSEL) == 0) { - unsigned char wire_col[4]; - UI_GetThemeColor4ubv(TH_WIRE_EDIT, wire_col); - drawDispList(depsgraph, scene, view_layer, v3d, rv3d, base, dt, dflag, wire_col); - } - ml = mb->editelems->first; - } - else { - if ((base->flag_legacy & OB_FROMDUPLI) == 0) { - drawDispList(depsgraph, scene, view_layer, v3d, rv3d, base, dt, dflag, ob_wire_col); - } - ml = mb->elems.first; - } - - if (ml == NULL) { - return true; - } - - if (v3d->flag2 & V3D_RENDER_OVERRIDE) { - return false; - } - - invert_m4_m4(imat, rv3d->viewmatob); - normalize_v3(imat[0]); - normalize_v3(imat[1]); - -#if 0 /* no purpose? */ - if (mb->editelems == NULL) { - if ((dflag & DRAW_CONSTCOLOR) == 0) { - glColor3ubv(ob_wire_col); - } - } -#endif - - glLineWidth(1.0f); - - const unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - - while (ml) { - /* draw radius */ - if (mb->editelems) { - if ((dflag & DRAW_CONSTCOLOR) == 0) { - if ((ml->flag & SELECT) && (ml->flag & MB_SCALE_RAD)) imm_cpack(0xA0A0F0); - else imm_cpack(0x3030A0); - } - - if (G.f & G_PICKSEL) { - ml->selcol1 = code; - GPU_select_load_id(code++); - } - } - imm_drawcircball(&(ml->x), ml->rad, imat, pos); - - /* draw stiffness */ - if (mb->editelems) { - if ((dflag & DRAW_CONSTCOLOR) == 0) { - if ((ml->flag & SELECT) && !(ml->flag & MB_SCALE_RAD)) imm_cpack(0xA0F0A0); - else imm_cpack(0x30A030); - } - - if (G.f & G_PICKSEL) { - ml->selcol2 = code; - GPU_select_load_id(code++); - } - imm_drawcircball(&(ml->x), ml->rad * atanf(ml->s) / (float)M_PI_2, imat, pos); - } - - ml = ml->next; - } - - immUnbindProgram(); - return false; -} - -static void draw_forcefield(Object *ob, RegionView3D *rv3d, - const short dflag, const unsigned char ob_wire_col[4]) -{ - PartDeflect *pd = ob->pd; - float imat[4][4], tmat[4][4]; - float vec[3] = {0.0, 0.0, 0.0}; - float draw_color[3] = {0.0f, 0.0f, 0.0f}; - /* scale size of circle etc with the empty drawsize */ - const float size = (ob->type == OB_EMPTY) ? ob->empty_drawsize : 1.0f; - - /* calculus here, is reused in PFIELD_FORCE */ - invert_m4_m4(imat, rv3d->viewmatob); -#if 0 - normalize_v3(imat[0]); /* we don't do this because field doesnt scale either... apart from wind! */ - normalize_v3(imat[1]); -#endif - - const unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - immUniformColor3fv(draw_color); - - if (pd->forcefield == PFIELD_WIND) { - float force_val = pd->f_strength; - - if ((dflag & DRAW_CONSTCOLOR) == 0) { - ob_wire_color_blend_theme_id(ob_wire_col, TH_BACK, 0.5f, draw_color); - immUniformColor3fv(draw_color); - } - - unit_m4(tmat); - force_val *= 0.1f; - imm_drawcircball(vec, size, tmat, pos); - vec[2] = 0.5f * force_val; - imm_drawcircball(vec, size, tmat, pos); - vec[2] = 1.0f * force_val; - imm_drawcircball(vec, size, tmat, pos); - vec[2] = 1.5f * force_val; - imm_drawcircball(vec, size, tmat, pos); - vec[2] = 0.0f; /* reset vec for max dist circle */ - } - else if (pd->forcefield == PFIELD_FORCE) { - float ffall_val = pd->f_power; - - if ((dflag & DRAW_CONSTCOLOR) == 0) { - ob_wire_color_blend_theme_id(ob_wire_col, TH_BACK, 0.5f, draw_color); - immUniformColor3fv(draw_color); - } - - imm_drawcircball(vec, size, imat, pos); - - if ((dflag & DRAW_CONSTCOLOR) == 0) { - ob_wire_color_blend_theme_id(ob_wire_col, TH_BACK, 0.9f - 0.4f / powf(1.5f, ffall_val), draw_color); - immUniformColor3fv(draw_color); - } - - imm_drawcircball(vec, size * 1.5f, imat, pos); - - if ((dflag & DRAW_CONSTCOLOR) == 0) { - ob_wire_color_blend_theme_id(ob_wire_col, TH_BACK, 0.9f - 0.4f / powf(2.0f, ffall_val), draw_color); - immUniformColor3fv(draw_color); - } - - imm_drawcircball(vec, size * 2.0f, imat, pos); - } - else if (pd->forcefield == PFIELD_VORTEX) { - float force_val = pd->f_strength; - - unit_m4(tmat); - - if ((dflag & DRAW_CONSTCOLOR) == 0) { - ob_wire_color_blend_theme_id(ob_wire_col, TH_BACK, 0.7f, draw_color); - immUniformColor3fv(draw_color); - } - - if (force_val < 0) { - drawspiral(pos, vec, size, tmat, 1); - drawspiral(pos, vec, size, tmat, 16); - } - else { - drawspiral(pos, vec, size, tmat, -1); - drawspiral(pos, vec, size, tmat, -16); - } - } - else if (pd->forcefield == PFIELD_GUIDE && ob->type == OB_CURVE) { - Curve *cu = ob->data; - if ((cu->flag & CU_PATH) && ob->curve_cache->path && ob->curve_cache->path->data) { - float guidevec1[4], guidevec2[3]; - float mindist = pd->f_strength; - - if ((dflag & DRAW_CONSTCOLOR) == 0) { - ob_wire_color_blend_theme_id(ob_wire_col, TH_BACK, 0.5f, draw_color); - immUniformColor3fv(draw_color); - } - - /* path end */ - setlinestyle(3); - where_on_path(ob, 1.0f, guidevec1, guidevec2, NULL, NULL, NULL); - imm_drawcircball(guidevec1, mindist, imat, pos); - - /* path beginning */ - setlinestyle(0); - where_on_path(ob, 0.0f, guidevec1, guidevec2, NULL, NULL, NULL); - imm_drawcircball(guidevec1, mindist, imat, pos); - - copy_v3_v3(vec, guidevec1); /* max center */ - } - } - - setlinestyle(3); - - if ((dflag & DRAW_CONSTCOLOR) == 0) { - ob_wire_color_blend_theme_id(ob_wire_col, TH_BACK, 0.5f, draw_color); - immUniformColor3fv(draw_color); - } - - if (pd->falloff == PFIELD_FALL_SPHERE) { - /* as last, guide curve alters it */ - if ((pd->flag & PFIELD_USEMAX) != 0) { - imm_drawcircball(vec, pd->maxdist, imat, pos); - } - - if ((pd->flag & PFIELD_USEMIN) != 0) { - imm_drawcircball(vec, pd->mindist, imat, pos); - } - } - else if (pd->falloff == PFIELD_FALL_TUBE) { - float radius, distance; - - unit_m4(tmat); - - vec[0] = vec[1] = 0.0f; - radius = (pd->flag & PFIELD_USEMAXR) ? pd->maxrad : 1.0f; - distance = (pd->flag & PFIELD_USEMAX) ? pd->maxdist : 0.0f; - vec[2] = distance; - distance = (pd->flag & PFIELD_POSZ) ? -distance : -2.0f * distance; - - if (pd->flag & (PFIELD_USEMAX | PFIELD_USEMAXR)) { - imm_drawtube(vec, radius, distance, tmat, pos); - } - - radius = (pd->flag & PFIELD_USEMINR) ? pd->minrad : 1.0f; - distance = (pd->flag & PFIELD_USEMIN) ? pd->mindist : 0.0f; - vec[2] = distance; - distance = (pd->flag & PFIELD_POSZ) ? -distance : -2.0f * distance; - - if (pd->flag & (PFIELD_USEMIN | PFIELD_USEMINR)) { - imm_drawtube(vec, radius, distance, tmat, pos); - } - } - else if (pd->falloff == PFIELD_FALL_CONE) { - float radius, distance; - - unit_m4(tmat); - - radius = DEG2RADF((pd->flag & PFIELD_USEMAXR) ? pd->maxrad : 1.0f); - distance = (pd->flag & PFIELD_USEMAX) ? pd->maxdist : 0.0f; - - if (pd->flag & (PFIELD_USEMAX | PFIELD_USEMAXR)) { - imm_drawcone(vec, distance * sinf(radius), distance * cosf(radius), tmat, pos); - if ((pd->flag & PFIELD_POSZ) == 0) - imm_drawcone(vec, distance * sinf(radius), -distance * cosf(radius), tmat, pos); - } - - radius = DEG2RADF((pd->flag & PFIELD_USEMINR) ? pd->minrad : 1.0f); - distance = (pd->flag & PFIELD_USEMIN) ? pd->mindist : 0.0f; - - if (pd->flag & (PFIELD_USEMIN | PFIELD_USEMINR)) { - imm_drawcone(vec, distance * sinf(radius), distance * cosf(radius), tmat, pos); - if ((pd->flag & PFIELD_POSZ) == 0) - imm_drawcone(vec, distance * sinf(radius), -distance * cosf(radius), tmat, pos); - } - } - setlinestyle(0); - - immUnbindProgram(); -} - -static void imm_draw_box(const float vec[8][3], bool solid, unsigned pos) -{ - if (solid) { - /* Adpated from "Optimizing Triangle Strips for Fast Rendering" by F. Evans, S. Skiena and A. Varshney - * (http://www.cs.umd.edu/gvil/papers/av_ts.pdf). */ - static const GLubyte tris_strip_indices[14] = {0, 1, 3, 2, 6, 1, 5, 0, 4, 3, 7, 6, 4, 5}; - immBegin(GWN_PRIM_TRI_STRIP, 14); - for (int i = 0; i < 14; ++i) { - immVertex3fv(pos, vec[tris_strip_indices[i]]); - } - immEnd(); - } - else { - static const GLubyte line_indices[24] = - {0, 1, 1, 2, 2, 3, 3, 0, 0, 4, 4, 5, 5, 6, 6, 7, 7, 4, 1, 5, 2, 6, 3, 7}; - immBegin(GWN_PRIM_LINES, 24); - for (int i = 0; i < 24; ++i) { - immVertex3fv(pos, vec[line_indices[i]]); - } - immEnd(); - } - -} - -static void imm_draw_bb(BoundBox *bb, char type, bool around_origin, const unsigned char ob_wire_col[4]) -{ - float size[3], cent[3]; - Gwn_Batch *sphere = GPU_batch_preset_sphere_wire(0); - GWN_batch_program_set_builtin(sphere, GPU_SHADER_3D_UNIFORM_COLOR); - if (ob_wire_col) GWN_batch_uniform_4f(sphere, "color", ob_wire_col[0] / 255.0f, ob_wire_col[1] / 255.0f, ob_wire_col[2] / 255.0f, 1.0f); - - BKE_boundbox_calc_size_aabb(bb, size); - - if (around_origin) { - zero_v3(cent); - } - else { - BKE_boundbox_calc_center_aabb(bb, cent); - } - - gpuPushMatrix(); - - unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - if (ob_wire_col) immUniformColor3ubv(ob_wire_col); - - if (type == OB_BOUND_SPHERE) { - float scale = MAX3(size[0], size[1], size[2]); - gpuTranslate3fv(cent); - gpuRotateAxis(90, 'X'); - gpuScaleUniform(scale); - GWN_batch_draw(sphere); - } - else if (type == OB_BOUND_CYLINDER) { - float radius = size[0] > size[1] ? size[0] : size[1]; - gpuTranslate3f(cent[0], cent[1], cent[2] - size[2]); - gpuScale3f(radius, radius, 2.0f * size[2]); - imm_draw_cylinder_wire_3d(pos, 1.0f, 1.0f, 1.0f, 8, 1); - } - else if (type == OB_BOUND_CONE) { - float radius = size[0] > size[1] ? size[0] : size[1]; - gpuTranslate3f(cent[0], cent[1], cent[2] - size[2]); - gpuScale3f(radius, radius, 2.0f * size[2]); - imm_draw_cylinder_wire_3d(pos, 1.0f, 0.0f, 1.0f, 8, 1); - - } - else if (type == OB_BOUND_CAPSULE) { - float radius = size[0] > size[1] ? size[0] : size[1]; - float length = size[2] > radius ? 2.0f * (size[2] - radius) : 0.0f; - gpuTranslate3f(cent[0], cent[1], cent[2] - length * 0.5f); - imm_draw_cylinder_wire_3d(pos, radius, radius, length, 8, 1); - - gpuRotateAxis(90, 'X'); - gpuScaleUniform(radius); - GWN_batch_draw(sphere); - - gpuTranslate3f(0.0f, length / radius, 0.0f); - GWN_batch_draw(sphere); - } - - gpuPopMatrix(); - immUnbindProgram(); -} - -void draw_bounding_volume(Object *ob, char type, const unsigned char ob_wire_col[4]) -{ - BoundBox bb_local; - BoundBox *bb = NULL; - - if (ob->type == OB_MESH) { - bb = BKE_mesh_boundbox_get(ob); - } - else if (ELEM(ob->type, OB_CURVE, OB_SURF, OB_FONT)) { - bb = BKE_curve_boundbox_get(ob); - } - else if (ob->type == OB_MBALL) { - if (BKE_mball_is_basis(ob)) { - bb = ob->bb; - } - } - else if (ob->type == OB_ARMATURE) { - bb = BKE_armature_boundbox_get(ob); - } - else if (ob->type == OB_LATTICE) { - bb = BKE_lattice_boundbox_get(ob); - } - else { - const float min[3] = {-1.0f, -1.0f, -1.0f}, max[3] = {1.0f, 1.0f, 1.0f}; - bb = &bb_local; - BKE_boundbox_init_from_minmax(bb, min, max); - } - - if (bb == NULL) - return; - - { - if (type == OB_BOUND_BOX) { - unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - if (ob_wire_col) immUniformColor3ubv(ob_wire_col); - - imm_draw_box(bb->vec, false, pos); - - immUnbindProgram(); - } - else - imm_draw_bb(bb, type, false, ob_wire_col); - } - -} - -static void drawtexspace(Object *ob, const unsigned char ob_wire_col[3]) -{ - float vec[8][3], loc[3], size[3]; - - if (ob->type == OB_MESH) { - BKE_mesh_texspace_get(ob->data, loc, NULL, size); - } - else if (ELEM(ob->type, OB_CURVE, OB_SURF, OB_FONT)) { - BKE_curve_texspace_get(ob->data, loc, NULL, size); - } - else if (ob->type == OB_MBALL) { - MetaBall *mb = ob->data; - copy_v3_v3(size, mb->size); - copy_v3_v3(loc, mb->loc); - } - else { - return; - } - - vec[0][0] = vec[1][0] = vec[2][0] = vec[3][0] = loc[0] - size[0]; - vec[4][0] = vec[5][0] = vec[6][0] = vec[7][0] = loc[0] + size[0]; - - vec[0][1] = vec[1][1] = vec[4][1] = vec[5][1] = loc[1] - size[1]; - vec[2][1] = vec[3][1] = vec[6][1] = vec[7][1] = loc[1] + size[1]; - - vec[0][2] = vec[3][2] = vec[4][2] = vec[7][2] = loc[2] - size[2]; - vec[1][2] = vec[2][2] = vec[5][2] = vec[6][2] = loc[2] + size[2]; - - setlinestyle(2); - - unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - - if (ob_wire_col) { - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - immUniformColor3ubv(ob_wire_col); - } - else { - immBindBuiltinProgram(GPU_SHADER_3D_DEPTH_ONLY); - } - - imm_draw_box(vec, false, pos); - - immUnbindProgram(); - - setlinestyle(0); -} - -/* draws wire outline */ -static void draw_object_selected_outline( - Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer, View3D *v3d, ARegion *ar, Base *base, - const unsigned char ob_wire_col[4]) -{ - RegionView3D *rv3d = ar->regiondata; - Object *ob = base->object; - - glDepthMask(GL_FALSE); - - if (ELEM(ob->type, OB_FONT, OB_CURVE, OB_SURF)) { - bool has_faces = false; - -#ifdef SEQUENCER_DAG_WORKAROUND - ensure_curve_cache(depsgraph, scene, ob); -#endif - - DerivedMesh *dm = ob->derivedFinal; - if (dm) { - DM_update_materials(dm, ob); - } - - if (dm) { - has_faces = (dm->getNumPolys(dm) != 0); - } - else { - has_faces = BKE_displist_has_faces(&ob->curve_cache->disp); - } - - if (has_faces && ED_view3d_boundbox_clip(rv3d, ob->bb)) { - glLineWidth(UI_GetThemeValuef(TH_OUTLINE_WIDTH) * 2.0f); - if (dm) { - draw_mesh_object_outline(v3d, ob, dm, ob_wire_col); - } - else { - /* only draw 'solid' parts of the display list as wire. */ - drawDispListwire_ex(&ob->curve_cache->disp, (DL_INDEX3 | DL_INDEX4 | DL_SURF), ob_wire_col); - } - } - } - else if (ob->type == OB_MBALL) { - if (BKE_mball_is_basis(ob)) { - if ((base->flag_legacy & OB_FROMDUPLI) == 0) { - glLineWidth(UI_GetThemeValuef(TH_OUTLINE_WIDTH) * 2.0f); - drawDispListwire(&ob->curve_cache->disp, ob->type, ob_wire_col); - } - } - } - else if (ob->type == OB_ARMATURE) { - if (!(ob->mode & OB_MODE_POSE && base == view_layer->basact)) { - glLineWidth(UI_GetThemeValuef(TH_OUTLINE_WIDTH) * 2.0f); - draw_armature(depsgraph, scene, view_layer, v3d, ar, base, OB_WIRE, 0, ob_wire_col, true); - } - } - - glDepthMask(GL_TRUE); -} - -static void draw_wire_extra( - RegionView3D *rv3d, Object *ob, const bool is_obedit, const unsigned char ob_wire_col[4]) -{ - if (ELEM(ob->type, OB_FONT, OB_CURVE, OB_SURF, OB_MBALL)) { - unsigned char wire_edit_col[4]; - UI_GetThemeColor4ubv(TH_WIRE_EDIT, wire_edit_col); - - ED_view3d_polygon_offset(rv3d, 1.0); - glDepthMask(GL_FALSE); /* disable write in zbuffer, selected edge wires show better */ - glLineWidth(1.0f); - - if (ELEM(ob->type, OB_FONT, OB_CURVE, OB_SURF)) { - if (ED_view3d_boundbox_clip(rv3d, ob->bb)) { - - if (ob->derivedFinal) { - drawCurveDMWired(ob); - } - else { - drawDispListwire(&ob->curve_cache->disp, ob->type, is_obedit ? wire_edit_col : ob_wire_col); - } - } - } - else if (ob->type == OB_MBALL) { - if (BKE_mball_is_basis(ob)) { - drawDispListwire(&ob->curve_cache->disp, ob->type, is_obedit ? wire_edit_col : ob_wire_col); - } - } - - glDepthMask(GL_TRUE); - ED_view3d_polygon_offset(rv3d, 0.0); - } -} - -/* should be called in view space */ -static void draw_hooks(Object *ob, unsigned int pos) -{ - for (ModifierData *md = ob->modifiers.first; md; md = md->next) { - if (md->type == eModifierType_Hook) { - HookModifierData *hmd = (HookModifierData *) md; - float vec[3]; - - mul_v3_m4v3(vec, ob->obmat, hmd->cent); - - if (hmd->object) { - setlinestyle(3); - immBegin(GWN_PRIM_LINES, 2); - immVertex3fv(pos, hmd->object->obmat[3]); - immVertex3fv(pos, vec); - immEnd(); - setlinestyle(0); - } - - glPointSize(3.0f); - immBegin(GWN_PRIM_POINTS, 1); - immVertex3fv(pos, vec); - immEnd(); - } - } -} - -void draw_object_wire_color(ViewLayer *view_layer, Base *base, unsigned char r_ob_wire_col[4]) -{ - Object *ob = base->object; - int colindex = 0; - const bool is_edit = (ob->mode & OB_MODE_EDIT) != 0; - /* confusing logic here, there are 2 methods of setting the color - * 'colortab[colindex]' and 'theme_id', colindex overrides theme_id. - * - * note: no theme yet for 'colindex' */ - int theme_id = is_edit ? TH_WIRE_EDIT : TH_WIRE; - int theme_shade = 0; - - if (((ob->mode & OB_MODE_EDIT) == 0) && - (G.moving & G_TRANSFORM_OBJ) && - ((base->flag & BASE_SELECTED) || (base->flag_legacy & BA_WAS_SEL))) - { - theme_id = TH_TRANSFORM; - } - else { - /* Sets the 'colindex' */ - if (ID_IS_LINKED(ob)) { - colindex = ((base->flag & BASE_SELECTED) || (base->flag_legacy & BA_WAS_SEL)) ? 2 : 1; - } - /* Sets the 'theme_id' or fallback to wire */ - else { - if ((ob->flag & OB_FROMGROUP) != 0) { - if ((base->flag & BASE_SELECTED) || (base->flag_legacy & BA_WAS_SEL)) { - /* uses darker active color for non-active + selected */ - theme_id = TH_GROUP_ACTIVE; - - if (view_layer->basact != base) { - theme_shade = -32; - } - } - else { - theme_id = TH_GROUP; - } - } - else { - if ((base->flag & BASE_SELECTED) || (base->flag_legacy & BA_WAS_SEL)) { - theme_id = view_layer->basact == base ? TH_ACTIVE : TH_SELECT; - } - else { - if (ob->type == OB_LAMP) theme_id = TH_LAMP; - else if (ob->type == OB_SPEAKER) theme_id = TH_SPEAKER; - else if (ob->type == OB_CAMERA) theme_id = TH_CAMERA; - else if (ob->type == OB_EMPTY) theme_id = TH_EMPTY; - /* fallback to TH_WIRE */ - } - } - } - } - - /* finally set the color */ - if (colindex == 0) { - if (theme_shade == 0) UI_GetThemeColor3ubv(theme_id, r_ob_wire_col); - else UI_GetThemeColorShade3ubv(theme_id, theme_shade, r_ob_wire_col); - } - else { - cpack_cpy_3ub(r_ob_wire_col, colortab[colindex]); - } - - /* no reason to use this but some functions take col[4] */ - r_ob_wire_col[3] = 255; -} - -static void draw_object_matcap_check(View3D *v3d, Object *ob) -{ - /* fixed rule, active object draws as matcap */ - BLI_assert((ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT)) == 0); - (void)ob; - - if (v3d->defmaterial == NULL) { - extern Material defmaterial; - - v3d->defmaterial = MEM_mallocN(sizeof(Material), "matcap material"); - *(v3d->defmaterial) = defmaterial; - BLI_listbase_clear(&v3d->defmaterial->gpumaterial); - v3d->defmaterial->preview = NULL; - } - /* first time users */ - if (v3d->matcap_icon < ICON_MATCAP_01 || - v3d->matcap_icon > ICON_MATCAP_24) - { - v3d->matcap_icon = ICON_MATCAP_01; - } - - if (v3d->defmaterial->preview == NULL) - v3d->defmaterial->preview = UI_icon_to_preview(v3d->matcap_icon); - - /* signal to all material checks, gets cleared below */ - v3d->flag2 |= V3D_SHOW_SOLID_MATCAP; -} - -void draw_rigidbody_shape(Object *ob, const unsigned char ob_wire_col[4]) -{ - BoundBox *bb = NULL; - float size[3], vec[8][3]; - unsigned int pos; - - if (ob->type == OB_MESH) { - bb = BKE_mesh_boundbox_get(ob); - } - - if (bb == NULL) - return; - - switch (ob->rigidbody_object->shape) { - case RB_SHAPE_BOX: - BKE_boundbox_calc_size_aabb(bb, size); - - pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - if (ob_wire_col) immUniformColor3ubv(ob_wire_col); - - vec[0][0] = vec[1][0] = vec[2][0] = vec[3][0] = -size[0]; - vec[4][0] = vec[5][0] = vec[6][0] = vec[7][0] = +size[0]; - vec[0][1] = vec[1][1] = vec[4][1] = vec[5][1] = -size[1]; - vec[2][1] = vec[3][1] = vec[6][1] = vec[7][1] = +size[1]; - vec[0][2] = vec[3][2] = vec[4][2] = vec[7][2] = -size[2]; - vec[1][2] = vec[2][2] = vec[5][2] = vec[6][2] = +size[2]; - - imm_draw_box(vec, false, pos); - immUnbindProgram(); - break; - case RB_SHAPE_SPHERE: - imm_draw_bb(bb, OB_BOUND_SPHERE, true, ob_wire_col); - break; - case RB_SHAPE_CONE: - imm_draw_bb(bb, OB_BOUND_CONE, true, ob_wire_col); - break; - case RB_SHAPE_CYLINDER: - imm_draw_bb(bb, OB_BOUND_CYLINDER, true, ob_wire_col); - break; - case RB_SHAPE_CAPSULE: - imm_draw_bb(bb, OB_BOUND_CAPSULE, true, ob_wire_col); - break; - } -} - -/** - * main object drawing function, draws in selection - * \param dflag (draw flag) can be DRAW_PICKING and/or DRAW_CONSTCOLOR, DRAW_SCENESET - */ -void draw_object( - Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer, ARegion *ar, View3D *v3d, - Base *base, const short dflag) -{ - ModifierData *md = NULL; - Object *ob = base->object; - Curve *cu; - RegionView3D *rv3d = ar->regiondata; - unsigned char _ob_wire_col[4]; /* dont initialize this */ - const unsigned char *ob_wire_col = NULL; /* dont initialize this, use NULL crashes as a way to find invalid use */ - bool zbufoff = false, is_paint = false, empty_object = false; - Object *ob_active = OBACT(view_layer); - const bool is_obact = (ob == ob_active); - /* this could be moved to a 'dflag'. */ - const bool is_obedit = (is_obact && (ob == OBEDIT_FROM_OBACT(ob_active))); - const bool render_override = (v3d->flag2 & V3D_RENDER_OVERRIDE) != 0; - const bool is_picking = (G.f & G_PICKSEL) != 0; - const bool has_particles = (ob->particlesystem.first != NULL); - bool skip_object = false; /* Draw particles but not their emitter object. */ - SmokeModifierData *smd = NULL; - - if (is_obedit == false) { - if (ob->restrictflag & OB_RESTRICT_VIEW) - return; - - if (render_override) { - if (ob->restrictflag & OB_RESTRICT_RENDER) - return; - - if (!has_particles && (ob->transflag & (OB_DUPLI & ~OB_DUPLIFRAMES))) - return; - } - } - - if (has_particles) { - /* XXX particles are not safe for simultaneous threaded render */ - if (G.is_rendering) { - return; - } - - if (ob->mode == OB_MODE_OBJECT) { - ParticleSystem *psys; - - skip_object = render_override; - for (psys = ob->particlesystem.first; psys; psys = psys->next) { - /* Once we have found a psys which renders its emitter object, we are done. */ - if (psys->part->draw & PART_DRAW_EMITTER) { - skip_object = false; - break; - } - } - } - } - - if (((base->flag_legacy & OB_FROMDUPLI) == 0) && - (md = modifiers_findByType(ob, eModifierType_Smoke)) && - (modifier_isEnabled(scene, md, eModifierMode_Realtime))) - { - smd = (SmokeModifierData *)md; - - if (smd->domain) { - if (!v3d->transp && (dflag & DRAW_PICKING) == 0) { - if (!v3d->xray && !(ob->dtx & OB_DRAWXRAY)) { - /* object has already been drawn so skip drawing it */ - ED_view3d_after_add(&v3d->afterdraw_transp, base, dflag); - return; - } - else if (v3d->xray) { - /* object has already been drawn so skip drawing it */ - ED_view3d_after_add(&v3d->afterdraw_xraytransp, base, dflag); - return; - } - } - } - } - - - /* xray delay? */ - if ((dflag & DRAW_PICKING) == 0 && (base->flag_legacy & OB_FROMDUPLI) == 0 && (v3d->flag2 & V3D_RENDER_SHADOW) == 0) { - /* don't do xray in particle mode, need the z-buffer */ - if (!(ob->mode & OB_MODE_PARTICLE_EDIT)) { - /* xray and transp are set when it is drawing the 2nd/3rd pass */ - if (!v3d->xray && !v3d->transp && (ob->dtx & OB_DRAWXRAY) && !(ob->dtx & OB_DRAWTRANSP)) { - ED_view3d_after_add(&v3d->afterdraw_xray, base, dflag); - return; - } - - /* allow transp option for empty images */ - if (ob->type == OB_EMPTY && ob->empty_drawtype == OB_EMPTY_IMAGE) { - if (!v3d->xray && !v3d->transp && !(ob->dtx & OB_DRAWXRAY) && (ob->dtx & OB_DRAWTRANSP)) { - ED_view3d_after_add(&v3d->afterdraw_transp, base, dflag); - return; - } - } - } - } - - - /* -------------------------------------------------------------------- */ - /* no return after this point, otherwise leaks */ - - /* only once set now, will be removed too, should become a global standard */ - glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - /* reset here to avoid having to call all over */ - glLineWidth(1.0f); - - view3d_cached_text_draw_begin(); - - /* draw motion paths (in view space) */ - if (ob->mpath && !render_override) { - bAnimVizSettings *avs = &ob->avs; - - /* setup drawing environment for paths */ - draw_motion_paths_init(v3d, ar); - - /* draw motion path for object */ - draw_motion_path_instance(scene, ob, NULL, avs, ob->mpath); - - /* cleanup after drawing */ - draw_motion_paths_cleanup(v3d); - } - - /* multiply view with object matrix. - * local viewmat and persmat, to calculate projections */ - ED_view3d_init_mats_rv3d_gl(ob, rv3d); - - /* which wire color */ - if ((dflag & DRAW_CONSTCOLOR) == 0) { - - ED_view3d_project_base(ar, base); - - draw_object_wire_color(view_layer, base, _ob_wire_col); - ob_wire_col = _ob_wire_col; - - //glColor3ubv(ob_wire_col); - } - - /* maximum drawtype */ - char dt = v3d->drawtype; - if (dt == OB_RENDER) dt = v3d->prev_drawtype; - dt = MIN2(dt, ob->dt); - if (v3d->zbuf == 0 && dt > OB_WIRE) dt = OB_WIRE; - short dtx = 0; - - - /* faceselect exception: also draw solid when (dt == wire), except in editmode */ - if (is_obact) { - if (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT)) { - if (ob->type == OB_MESH) { - if (dt < OB_SOLID) { - zbufoff = true; - dt = OB_SOLID; - } - - if (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT)) { - dt = OB_PAINT; - } - - is_paint = true; - glEnable(GL_DEPTH_TEST); - } - } - } - - /* matcap check - only when not painting color */ - if ((v3d->flag2 & V3D_SOLID_MATCAP) && - (dt == OB_SOLID) && - (is_paint == false && is_picking == false) && - ((v3d->flag2 & V3D_RENDER_SHADOW) == 0)) - { - draw_object_matcap_check(v3d, ob); - } - - /* draw-extra supported for boundbox drawmode too */ - if (dt >= OB_BOUNDBOX) { - dtx = ob->dtx; - if (ob->mode & OB_MODE_EDIT) { - /* the only 2 extra drawtypes alowed in editmode */ - dtx = dtx & (OB_DRAWWIRE | OB_TEXSPACE); - } - } - - if (!skip_object) { - /* draw outline for selected objects, mesh does itself */ - if ((v3d->flag & V3D_SELECT_OUTLINE) && !render_override && ob->type != OB_MESH) { - if (dt > OB_WIRE && (ob->mode & OB_MODE_EDIT) == 0 && (dflag & DRAW_SCENESET) == 0) { - if (!(ob->dtx & OB_DRAWWIRE) && (base->flag & BASE_SELECTED) && !(dflag & (DRAW_PICKING | DRAW_CONSTCOLOR))) { - draw_object_selected_outline(depsgraph, scene, view_layer, v3d, ar, base, ob_wire_col); - } - } - } - - /* TODO Viewport: draw only for selection */ - if ((dflag & DRAW_PICKING) == 0) { - if ((dt == OB_BOUNDBOX) || ELEM(ob->type, OB_EMPTY, OB_LAMP, OB_CAMERA, OB_SPEAKER)) { - goto afterdraw; - } - } - - switch (ob->type) { - case OB_MESH: - empty_object = draw_mesh_object(depsgraph, scene, view_layer, ar, v3d, rv3d, base, dt, ob_wire_col, dflag); - if ((dflag & DRAW_CONSTCOLOR) == 0) { - /* mesh draws wire itself */ - dtx &= ~OB_DRAWWIRE; - } - - break; - case OB_FONT: - cu = ob->data; - if (cu->editfont) { - draw_editfont(depsgraph, scene, view_layer, v3d, rv3d, base, dt, dflag, ob_wire_col); - } - else if (dt == OB_BOUNDBOX) { - if ((render_override && v3d->drawtype >= OB_WIRE) == 0) { -#ifdef SEQUENCER_DAG_WORKAROUND - ensure_curve_cache(depsgraph, scene, base->object); -#endif - draw_bounding_volume(ob, ob->boundtype, ob_wire_col); - } - } - else if (ED_view3d_boundbox_clip(rv3d, ob->bb)) { - empty_object = drawDispList(depsgraph, scene, view_layer, v3d, rv3d, base, dt, dflag, ob_wire_col); - } - - break; - case OB_CURVE: - case OB_SURF: - cu = ob->data; - - if (cu->editnurb) { - ListBase *nurbs = BKE_curve_editNurbs_get(cu); - draw_editnurb(depsgraph, scene, view_layer, v3d, rv3d, base, nurbs->first, dt, dflag, ob_wire_col); - } - else if (dt == OB_BOUNDBOX) { - if ((render_override && (v3d->drawtype >= OB_WIRE)) == 0) { -#ifdef SEQUENCER_DAG_WORKAROUND - ensure_curve_cache(depsgraph, scene, base->object); -#endif - draw_bounding_volume(ob, ob->boundtype, ob_wire_col); - } - } - else if (ED_view3d_boundbox_clip(rv3d, ob->bb)) { - empty_object = drawDispList(depsgraph, scene, view_layer, v3d, rv3d, base, dt, dflag, ob_wire_col); - } - break; - case OB_MBALL: - { - MetaBall *mb = ob->data; - - if (mb->editelems) - drawmball(depsgraph, scene, view_layer, v3d, rv3d, base, dt, dflag, ob_wire_col); - else if (dt == OB_BOUNDBOX) { - if ((render_override && (v3d->drawtype >= OB_WIRE)) == 0) { -#ifdef SEQUENCER_DAG_WORKAROUND - ensure_curve_cache(depsgraph, scene, base->object); -#endif - draw_bounding_volume(ob, ob->boundtype, ob_wire_col); - } - } - else - empty_object = drawmball(depsgraph, scene, view_layer, v3d, rv3d, base, dt, dflag, ob_wire_col); - break; - } - case OB_EMPTY: - if (!render_override) { - if (ob->empty_drawtype == OB_EMPTY_IMAGE) { - draw_empty_image(ob, dflag, ob_wire_col, v3d->multiview_eye); - } - else { - drawaxes(rv3d->viewmatob, ob->empty_drawsize, ob->empty_drawtype, ob_wire_col); - } - } - break; - case OB_LAMP: - if (!render_override) { - drawlamp(v3d, rv3d, base, dt, dflag, ob_wire_col, is_obact); - } - break; - case OB_CAMERA: - if (!render_override || - (rv3d->persp == RV3D_CAMOB && v3d->camera == ob)) /* special exception for active camera */ - { - drawcamera(scene, v3d, rv3d, base, dflag, ob_wire_col); - } - break; - case OB_SPEAKER: - if (!render_override) - drawspeaker(ob_wire_col); - break; - case OB_LATTICE: - if (!render_override) { - /* Do not allow boundbox in edit nor pose mode! */ - if ((dt == OB_BOUNDBOX) && (ob->mode & OB_MODE_EDIT)) - dt = OB_WIRE; - if (dt == OB_BOUNDBOX) { - draw_bounding_volume(ob, ob->boundtype, ob_wire_col); - } - else { -#ifdef SEQUENCER_DAG_WORKAROUND - ensure_curve_cache(depsgraph, scene, ob); -#endif - drawlattice(v3d, ob, dflag, ob_wire_col); - } - } - break; - case OB_ARMATURE: - if (!render_override) { - /* Do not allow boundbox in edit nor pose mode! */ - if ((dt == OB_BOUNDBOX) && (ob->mode & (OB_MODE_EDIT | OB_MODE_POSE))) - dt = OB_WIRE; - if (dt == OB_BOUNDBOX) { - draw_bounding_volume(ob, ob->boundtype, ob_wire_col); - } - else { - unsigned char arm_col[4]; - glLineWidth(1.0f); - - if (ob_wire_col == NULL) { - float fcol[4] = {0.0f, 0.0f, 0.0f, 1.0f}; - rgba_float_to_uchar(arm_col, fcol); - } - else - copy_v4_v4_uchar(arm_col, ob_wire_col); - - empty_object = draw_armature(depsgraph, scene, view_layer, v3d, ar, base, dt, dflag, arm_col, false); - } - } - break; - default: - if (!render_override) { - drawaxes(rv3d->viewmatob, 1.0, OB_ARROWS, ob_wire_col); - } - break; - } - - /* TODO Viewport: some elements are being drawn for object selection only */ -afterdraw: - - if (!render_override) { - if (ob->soft /*&& dflag & OB_SBMOTION*/) { - float mrt[3][3], msc[3][3], mtr[3][3]; - SoftBody *sb = NULL; - float tipw = 0.5f, tiph = 0.5f, drawsize = 4.0f; - if ((sb = ob->soft)) { - if (sb->solverflags & SBSO_ESTIMATEIPO) { - - gpuLoadMatrix(rv3d->viewmat); - copy_m3_m3(msc, sb->lscale); - copy_m3_m3(mrt, sb->lrot); - mul_m3_m3m3(mtr, mrt, msc); - ob_draw_RE_motion(sb->lcom, mtr, tipw, tiph, drawsize); - gpuMultMatrix(ob->obmat); - } - } - } - - if (ob->pd && ob->pd->forcefield) { - draw_forcefield(ob, rv3d, dflag, ob_wire_col); - } - } - } - - /* code for new particle system */ - if ((ob->particlesystem.first) && - (is_obedit == false)) - { - ParticleSystem *psys; - - //glDepthMask(GL_FALSE); - - gpuLoadMatrix(rv3d->viewmat); - - view3d_cached_text_draw_begin(); - - for (psys = ob->particlesystem.first; psys; psys = psys->next) { - /* run this so that possible child particles get cached */ - if (ob->mode & OB_MODE_PARTICLE_EDIT && is_obact) { - PTCacheEdit *edit = PE_create_current(depsgraph, scene, ob); - if (edit && edit->psys == psys) - draw_update_ptcache_edit(depsgraph, scene, ob, edit); - } - - draw_new_particle_system(depsgraph, scene, v3d, rv3d, base, psys, dt, dflag); - } - invert_m4_m4(ob->imat, ob->obmat); - view3d_cached_text_draw_end(v3d, ar, 0); - - gpuMultMatrix(ob->obmat); - - //glDepthMask(GL_TRUE); - } - - /* draw edit particles last so that they can draw over child particles */ - if ((dflag & DRAW_PICKING) == 0 && - (is_obedit == false)) - { - - if (ob->mode & OB_MODE_PARTICLE_EDIT && is_obact) { - PTCacheEdit *edit = PE_create_current(depsgraph, scene, ob); - if (edit) { - gpuLoadMatrix(rv3d->viewmat); - draw_update_ptcache_edit(depsgraph, scene, ob, edit); - draw_ptcache_edit(scene, v3d, edit); - gpuMultMatrix(ob->obmat); - } - } - } - - /* draw code for smoke, only draw domains */ - if (smd && smd->domain) { - SmokeDomainSettings *sds = smd->domain; - const bool show_smoke = (CFRA >= sds->point_cache[0]->startframe); - float viewnormal[3]; - - gpuLoadMatrix(rv3d->viewmat); - gpuMultMatrix(ob->obmat); - - if (!render_override) { - BoundBox bb; - float p0[3], p1[3]; - unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - if (ob_wire_col) immUniformColor3ubv(ob_wire_col); - - /* draw max domain bounds */ - if ((sds->flags & MOD_SMOKE_ADAPTIVE_DOMAIN)) { - VECSUBFAC(p0, sds->p0, sds->cell_size, sds->adapt_res); - VECADDFAC(p1, sds->p1, sds->cell_size, sds->adapt_res); - BKE_boundbox_init_from_minmax(&bb, p0, p1); - imm_draw_box(bb.vec, false, pos); - } - - /* draw a single voxel to hint the user about the resolution of the fluid */ - copy_v3_v3(p0, sds->p0); - - if (sds->flags & MOD_SMOKE_HIGHRES) { - madd_v3_v3v3fl(p1, p0, sds->cell_size, 1.0f / (sds->amplify + 1)); - } - else { - add_v3_v3v3(p1, p0, sds->cell_size); - } - - BKE_boundbox_init_from_minmax(&bb, p0, p1); - imm_draw_box(bb.vec, false, pos); - - immUnbindProgram(); - } - - /* don't show smoke before simulation starts, this could be made an option in the future */ - if (sds->fluid && show_smoke) { - float p0[3], p1[3]; - - /* get view vector */ - invert_m4_m4(ob->imat, ob->obmat); - mul_v3_mat3_m4v3(viewnormal, ob->imat, rv3d->viewinv[2]); - normalize_v3(viewnormal); - - /* set dynamic boundaries to draw the volume - * also scale cube to global space to equalize volume slicing on all axes - * (it's scaled back before drawing) */ - p0[0] = (sds->p0[0] + sds->cell_size[0] * sds->res_min[0] + sds->obj_shift_f[0]) * fabsf(ob->size[0]); - p0[1] = (sds->p0[1] + sds->cell_size[1] * sds->res_min[1] + sds->obj_shift_f[1]) * fabsf(ob->size[1]); - p0[2] = (sds->p0[2] + sds->cell_size[2] * sds->res_min[2] + sds->obj_shift_f[2]) * fabsf(ob->size[2]); - p1[0] = (sds->p0[0] + sds->cell_size[0] * sds->res_max[0] + sds->obj_shift_f[0]) * fabsf(ob->size[0]); - p1[1] = (sds->p0[1] + sds->cell_size[1] * sds->res_max[1] + sds->obj_shift_f[1]) * fabsf(ob->size[1]); - p1[2] = (sds->p0[2] + sds->cell_size[2] * sds->res_max[2] + sds->obj_shift_f[2]) * fabsf(ob->size[2]); - - if (!sds->wt || !(sds->viewsettings & MOD_SMOKE_VIEW_SHOWBIG)) { - sds->tex = NULL; - GPU_create_smoke(smd, 0); - draw_smoke_volume(sds, ob, p0, p1, viewnormal); - GPU_free_smoke(smd); - } - else if (sds->wt && (sds->viewsettings & MOD_SMOKE_VIEW_SHOWBIG)) { - sds->tex = NULL; - GPU_create_smoke(smd, 1); - draw_smoke_volume(sds, ob, p0, p1, viewnormal); - GPU_free_smoke(smd); - } - - /* smoke debug render */ - if (!render_override && sds->draw_velocity) { - draw_smoke_velocity(sds, viewnormal); - } - } - } - - if (!render_override) { - if (ob->rigidbody_object) { - draw_rigidbody_shape(ob, ob_wire_col); - } - - /* draw extra: after normal draw because of makeDispList */ - if (dtx && (G.f & G_RENDER_OGL) == 0) { - - if (dtx & OB_AXIS) { - if ((dflag & DRAW_CONSTCOLOR) == 0) { - /* prevent random colors being used */ - drawaxes(rv3d->viewmatob, 1.0f, OB_ARROWS, ob_wire_col); - } - else { - drawaxes(rv3d->viewmatob, 1.0f, OB_ARROWS, NULL); - } - } - if (dtx & OB_DRAWBOUNDOX) { - draw_bounding_volume(ob, ob->boundtype, ob_wire_col); - } - if (dtx & OB_TEXSPACE) { - if ((dflag & DRAW_CONSTCOLOR) == 0) { - /* prevent random colors being used */ - drawtexspace(ob, ob_wire_col); - } - else { - drawtexspace(ob, NULL); - } - } - if (dtx & OB_DRAWNAME) { - /* patch for several 3d cards (IBM mostly) that crash on GL_SELECT with text drawing */ - /* but, we also don't draw names for sets or duplicators */ - if (dflag == 0) { - const float zero[3] = {0, 0, 0}; - view3d_cached_text_draw_add(zero, ob->id.name + 2, strlen(ob->id.name + 2), 10, 0, ob_wire_col); - } - } - if ((dtx & OB_DRAWWIRE) && dt >= OB_SOLID) { - if ((dflag & DRAW_CONSTCOLOR) == 0) { - draw_wire_extra(rv3d, ob, is_obedit, ob_wire_col); - } - } - } - } - - /* return warning, this is cached text draw */ - invert_m4_m4(ob->imat, ob->obmat); - view3d_cached_text_draw_end(v3d, ar, 1); - /* return warning, clear temp flag */ - v3d->flag2 &= ~V3D_SHOW_SOLID_MATCAP; - - gpuLoadMatrix(rv3d->viewmat); - - if (zbufoff) { - glDisable(GL_DEPTH_TEST); - } - - if ((base->flag_legacy & OB_FROMDUPLI) || render_override) { - ED_view3d_clear_mats_rv3d(rv3d); - return; - } - - /* object centers, need to be drawn in viewmat space for speed, but OK for picking select */ - if (!is_obact || !(ob->mode & OB_MODE_ALL_PAINT)) { - int do_draw_center = -1; /* defines below are zero or positive... */ - - if (render_override) { - /* don't draw */ - } - else if (is_obact) - do_draw_center = ACTIVE; - else if (base->flag & BASE_SELECTED) - do_draw_center = SELECT; - else if (empty_object || (v3d->flag & V3D_DRAW_CENTERS)) - do_draw_center = DESELECT; - - if (do_draw_center != -1) { - if (dflag & DRAW_PICKING) { - /* draw a single point for opengl selection */ - if ((base->sx != IS_CLIPPED) && - (U.obcenter_dia != 0.0)) - { - unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_3D_POINT_FIXED_SIZE_UNIFORM_COLOR); - /* TODO: short term, use DEPTH_ONLY shader or set appropriate color */ - /* TODO: long term, solve picking & selection problem better */ - glPointSize(U.obcenter_dia); - immBegin(GWN_PRIM_POINTS, 1); - immVertex3fv(pos, ob->obmat[3]); - immEnd(); - immUnbindProgram(); - } - } - else if ((dflag & DRAW_CONSTCOLOR) == 0) { - /* we don't draw centers for duplicators and sets */ - if ((base->sx != IS_CLIPPED) && - (U.obcenter_dia != 0.0) && - !(G.f & G_RENDER_OGL)) - { - /* check > 0 otherwise grease pencil can draw into the circle select which is annoying. */ - drawcentercircle(v3d, rv3d, ob->obmat[3], do_draw_center, ID_IS_LINKED(ob) || ob->id.us > 1); - } - } - } - } - - /* not for sets, duplicators or picking */ - if (dflag == 0 && (v3d->flag & V3D_HIDE_HELPLINES) == 0 && !render_override) { - ListBase *list; - RigidBodyCon *rbc = ob->rigidbody_constraint; - - unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - immUniformColor3ubv(ob_wire_col); - - /* draw hook center and offset line */ - if (is_obedit == false) - draw_hooks(ob, pos); - - /* help lines and so */ - if ((is_obedit == false) && ob->parent) { - const eObjectVisibilityCheck mode = DEG_get_mode(depsgraph) != DAG_EVAL_VIEWPORT ? - OB_VISIBILITY_CHECK_FOR_RENDER : - OB_VISIBILITY_CHECK_FOR_VIEWPORT; - if (BKE_object_is_visible(ob->parent, mode)) { - setlinestyle(3); - immBegin(GWN_PRIM_LINES, 2); - immVertex3fv(pos, ob->obmat[3]); - immVertex3fv(pos, ob->orig); - immEnd(); - setlinestyle(0); - } - } - - /* Drawing the constraint lines */ - if (ob->constraints.first) { - bConstraint *curcon; - bConstraintOb *cob; - unsigned char col1[4], col2[4]; - - list = &ob->constraints; - - UI_GetThemeColor3ubv(TH_GRID, col1); - UI_make_axis_color(col1, col2, 'Z'); - immUniformColor3ubv(col2); - - cob = BKE_constraints_make_evalob(scene, ob, NULL, CONSTRAINT_OBTYPE_OBJECT); - - for (curcon = list->first; curcon; curcon = curcon->next) { - if (ELEM(curcon->type, CONSTRAINT_TYPE_FOLLOWTRACK, CONSTRAINT_TYPE_OBJECTSOLVER)) { - /* special case for object solver and follow track constraints because they don't fill - * constraint targets properly (design limitation -- scene is needed for their target - * but it can't be accessed from get_targets callback) */ - - Object *camob = NULL; - - if (curcon->type == CONSTRAINT_TYPE_FOLLOWTRACK) { - bFollowTrackConstraint *data = (bFollowTrackConstraint *)curcon->data; - - camob = data->camera ? data->camera : scene->camera; - } - else if (curcon->type == CONSTRAINT_TYPE_OBJECTSOLVER) { - bObjectSolverConstraint *data = (bObjectSolverConstraint *)curcon->data; - - camob = data->camera ? data->camera : scene->camera; - } - - if (camob) { - setlinestyle(3); - immBegin(GWN_PRIM_LINES, 2); - immVertex3fv(pos, camob->obmat[3]); - immVertex3fv(pos, ob->obmat[3]); - immEnd(); - setlinestyle(0); - } - } - else { - const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(curcon); - - if ((cti && cti->get_constraint_targets) && (curcon->flag & CONSTRAINT_EXPAND)) { - ListBase targets = {NULL, NULL}; - bConstraintTarget *ct; - - cti->get_constraint_targets(curcon, &targets); - - for (ct = targets.first; ct; ct = ct->next) { - /* calculate target's matrix */ - if (cti->get_target_matrix) - cti->get_target_matrix(depsgraph, curcon, cob, ct, BKE_scene_frame_get(scene)); - else - unit_m4(ct->matrix); - - setlinestyle(3); - immBegin(GWN_PRIM_LINES, 2); - immVertex3fv(pos, ct->matrix[3]); - immVertex3fv(pos, ob->obmat[3]); - immEnd(); - setlinestyle(0); - } - - if (cti->flush_constraint_targets) - cti->flush_constraint_targets(curcon, &targets, 1); - } - } - } - - BKE_constraints_clear_evalob(cob); - } - /* draw rigid body constraint lines */ - if (rbc && (rbc->ob1 || rbc->ob2)) { - immUniformThemeColor(TH_WIRE); - - setlinestyle(3); - immBegin(GWN_PRIM_LINES, ((int)((bool)rbc->ob1) + (int)((bool)rbc->ob2)) * 2); - if (rbc->ob1) { - immVertex3fv(pos, ob->obmat[3]); - immVertex3fv(pos, rbc->ob1->obmat[3]); - } - if (rbc->ob2) { - immVertex3fv(pos, ob->obmat[3]); - immVertex3fv(pos, rbc->ob2->obmat[3]); - } - immEnd(); - setlinestyle(0); - } - - immUnbindProgram(); - } - - ED_view3d_clear_mats_rv3d(rv3d); -} - - -/** - * Drawing for selection picking, - * caller must have called 'GPU_select_load_id(base->selcode)' first. - */ -void draw_object_select( - Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer, ARegion *ar, View3D *v3d, - Base *base, const short dflag) -{ - BLI_assert(dflag & DRAW_PICKING && dflag & DRAW_CONSTCOLOR); - draw_object(depsgraph, scene, view_layer, ar, v3d, base, dflag); - - /* we draw duplicators for selection too */ - if ((base->object->transflag & OB_DUPLI)) { - ListBase *lb; - DupliObject *dob; - Base tbase; - - tbase.flag_legacy = OB_FROMDUPLI; - lb = object_duplilist(depsgraph, scene, base->object); - - for (dob = lb->first; dob; dob = dob->next) { - float omat[4][4]; - - tbase.object = dob->ob; - copy_m4_m4(omat, dob->ob->obmat); - copy_m4_m4(dob->ob->obmat, dob->mat); - - /* extra service: draw the duplicator in drawtype of parent */ - /* MIN2 for the drawtype to allow bounding box objects in groups for lods */ - char dt = tbase.object->dt; tbase.object->dt = MIN2(tbase.object->dt, base->object->dt); - short dtx = tbase.object->dtx; tbase.object->dtx = base->object->dtx; - - draw_object(depsgraph, scene, view_layer, ar, v3d, &tbase, dflag); - - tbase.object->dt = dt; - tbase.object->dtx = dtx; - - copy_m4_m4(dob->ob->obmat, omat); - } - free_object_duplilist(lb); - } -} - /* ***************** BACKBUF SEL (BBS) ********* */ #ifdef USE_MESH_DM_SELECT @@ -9476,24 +536,6 @@ static void bbs_mesh_solid_EM(BMEditMesh *em, Scene *scene, View3D *v3d, } } -static DMDrawOption bbs_mesh_solid__setDrawOpts(void *UNUSED(userData), int index) -{ - GPU_select_index_set(index + 1); - return DM_DRAW_OPTION_NORMAL; -} - -static DMDrawOption bbs_mesh_solid_hide__setDrawOpts(void *userData, int index) -{ - Mesh *me = userData; - - if (!(me->mpoly[index].flag & ME_HIDE)) { - return DM_DRAW_OPTION_NORMAL; - } - else { - return DM_DRAW_OPTION_SKIP; - } -} - #ifdef USE_MESH_DM_SELECT /* must have called GPU_framebuffer_index_set beforehand */ static DMDrawOption bbs_mesh_solid_hide2__setDrawOpts(void *userData, int index) @@ -9553,10 +595,9 @@ static void bbs_mesh_solid_verts(Depsgraph *UNUSED(depsgraph), Scene *UNUSED(sce } #endif -static void bbs_mesh_solid_faces(Scene *scene, Object *ob) +static void bbs_mesh_solid_faces(Scene *UNUSED(scene), Object *ob) { Mesh *me = ob->data; - UNUSED_VARS(scene, bbs_mesh_solid_hide__setDrawOpts, bbs_mesh_solid__setDrawOpts); Gwn_Batch *batch; if ((me->editflag & ME_EDIT_PAINT_FACE_SEL)) { batch = DRW_mesh_batch_cache_get_triangles_with_select_id(me, true, 1); @@ -9644,81 +685,6 @@ void draw_object_backbufsel( } -/* ************* draw object instances for bones, for example ****************** */ -/* assumes all matrices/etc set OK */ - -/* helper function for drawing object instances - meshes */ -static void draw_object_mesh_instance( - Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer, View3D *v3d, RegionView3D *rv3d, - Object *ob, const short dt, int outline, const unsigned char ob_wire_col[4]) -{ - Mesh *me = ob->data; - DerivedMesh *dm = NULL, *edm = NULL; - - if (ob->mode & OB_MODE_EDIT) { - edm = editbmesh_get_derived_base(ob, me->edit_btmesh, CD_MASK_BAREMESH); - DM_update_materials(edm, ob); - } - else { - dm = mesh_get_derived_final(depsgraph, scene, ob, CD_MASK_BAREMESH); - DM_update_materials(dm, ob); - } - - if (dt <= OB_WIRE) { - glColor4ubv(ob_wire_col); - if (dm) - dm->drawEdges(dm, 1, 0); - else if (edm) - edm->drawEdges(edm, 1, 0); - } - else { - if (outline) - draw_mesh_object_outline(v3d, ob, dm ? dm : edm, ob_wire_col); - - if (dm) { - bool glsl = draw_glsl_material(scene, view_layer, ob, v3d, dt); - GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, glsl, NULL); - } - - glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW); - - if (dm) { - dm->drawFacesSolid(dm, NULL, 0, GPU_object_material_bind); - GPU_end_object_materials(); - } - else if (edm) - edm->drawMappedFaces(edm, NULL, GPU_object_material_bind, NULL, NULL, DM_DRAW_NEED_NORMALS); - - GPU_object_material_unbind(); - } - - if (edm) edm->release(edm); - if (dm) dm->release(dm); -} - -void draw_object_instance(Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer, View3D *v3d, RegionView3D *rv3d, Object *ob, const char dt, int outline, const float wire_col[4]) -{ - if (ob == NULL) - return; - - unsigned char bcol[4]; - rgba_float_to_uchar(bcol, wire_col); - - switch (ob->type) { - case OB_MESH: - draw_object_mesh_instance(depsgraph, scene, view_layer, v3d, rv3d, ob, dt, outline, bcol); - break; - case OB_EMPTY: - if (ob->empty_drawtype == OB_EMPTY_IMAGE) { - draw_empty_image(ob, 0, bcol, v3d->multiview_eye); - } - else { - drawaxes(rv3d->viewmatob, ob->empty_drawsize, ob->empty_drawtype, bcol); - } - break; - } -} - void ED_draw_object_facemap( Depsgraph *depsgraph, Scene *scene, Object *ob, const float col[4], const int facemap) { diff --git a/source/blender/editors/space_view3d/drawsimdebug.c b/source/blender/editors/space_view3d/drawsimdebug.c deleted file mode 100644 index 14708ca67bc..00000000000 --- a/source/blender/editors/space_view3d/drawsimdebug.c +++ /dev/null @@ -1,209 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2014 by the Blender Foundation. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): Lukas Toenne - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/editors/space_view3d/drawsimdebug.c - * \ingroup spview3d - */ - -#include "DNA_scene_types.h" -#include "DNA_screen_types.h" -#include "DNA_view3d_types.h" -#include "DNA_object_types.h" - -#include "BLI_math.h" -#include "BLI_utildefines.h" -#include "BLI_ghash.h" - -#include "BKE_effect.h" - -#include "GPU_immediate.h" -#include "GPU_matrix.h" - -#include "view3d_intern.h" - - -static void draw_sim_debug_elements(SimDebugData *debug_data, float imat[4][4]) -{ - Gwn_VertFormat *format = immVertexFormat(); - unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - unsigned int color = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - - immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR); - - /* count element types */ - GHashIterator iter; - int num_dots = 0; - int num_circles = 0; - int num_lines = 0; - int num_vectors = 0; - for (BLI_ghashIterator_init(&iter, debug_data->gh); !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter)) { - SimDebugElement *elem = BLI_ghashIterator_getValue(&iter); - switch (elem->type) { - case SIM_DEBUG_ELEM_DOT: ++num_dots; break; - case SIM_DEBUG_ELEM_CIRCLE: ++num_circles; break; - case SIM_DEBUG_ELEM_LINE: ++num_lines; break; - case SIM_DEBUG_ELEM_VECTOR: ++num_vectors; break; - } - } - - /**** dots ****/ - - glPointSize(3.0f); - immBegin(GWN_PRIM_POINTS, num_dots); - for (BLI_ghashIterator_init(&iter, debug_data->gh); !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter)) { - SimDebugElement *elem = BLI_ghashIterator_getValue(&iter); - if (elem->type != SIM_DEBUG_ELEM_DOT) - continue; - - immAttrib3fv(color, elem->color); - immVertex3fv(pos, elem->v1); - } - immEnd(); - - /**** circles ****/ - - { -#define CIRCLERES 16 - float circle[CIRCLERES][2] = { - {0.000000, 1.000000}, {0.382683, 0.923880}, {0.707107, 0.707107}, {0.923880, 0.382683}, - {1.000000, -0.000000}, {0.923880, -0.382683}, {0.707107, -0.707107}, {0.382683, -0.923880}, - {-0.000000, -1.000000}, {-0.382683, -0.923880}, {-0.707107, -0.707107}, {-0.923879, -0.382684}, - {-1.000000, 0.000000}, {-0.923879, 0.382684}, {-0.707107, 0.707107}, {-0.382683, 0.923880} }; - - immBegin(GWN_PRIM_LINES, num_circles * CIRCLERES * 2); - - for (BLI_ghashIterator_init(&iter, debug_data->gh); !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter)) { - SimDebugElement *elem = BLI_ghashIterator_getValue(&iter); - float radius = elem->v2[0]; - float co[3], nco[3]; - int i; - - if (elem->type != SIM_DEBUG_ELEM_CIRCLE) - continue; - - immAttrib3fv(color, elem->color); - zero_v3(co); - for (i = 0; i <= CIRCLERES; ++i) { - int ni = i % CIRCLERES; - nco[0] = radius * circle[ni][0]; - nco[1] = radius * circle[ni][1]; - nco[2] = 0.0f; - mul_mat3_m4_v3(imat, nco); - add_v3_v3(nco, elem->v1); - - if (i > 0) { - immVertex3fv(pos, co); - immVertex3fv(pos, nco); - } - - copy_v3_v3(co, nco); - } - } - - immEnd(); -#undef CIRCLERES - } - - /**** lines ****/ - - immBegin(GWN_PRIM_LINES, num_lines * 2); - for (BLI_ghashIterator_init(&iter, debug_data->gh); !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter)) { - SimDebugElement *elem = BLI_ghashIterator_getValue(&iter); - if (elem->type != SIM_DEBUG_ELEM_LINE) - continue; - - immAttrib3fv(color, elem->color); - immVertex3fv(pos, elem->v1); - immVertex3fv(pos, elem->v2); - } - immEnd(); - - /**** vectors ****/ - - glPointSize(2.0f); - immBegin(GWN_PRIM_POINTS, num_vectors); - for (BLI_ghashIterator_init(&iter, debug_data->gh); !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter)) { - SimDebugElement *elem = BLI_ghashIterator_getValue(&iter); - if (elem->type != SIM_DEBUG_ELEM_VECTOR) - continue; - - immAttrib3fv(color, elem->color); - immVertex3fv(pos, elem->v1); - } - immEnd(); - - immBegin(GWN_PRIM_LINES, num_vectors * 2); - for (BLI_ghashIterator_init(&iter, debug_data->gh); !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter)) { - SimDebugElement *elem = BLI_ghashIterator_getValue(&iter); - float t[3]; - if (elem->type != SIM_DEBUG_ELEM_VECTOR) - continue; - - immAttrib3fv(color, elem->color); - immVertex3fv(pos, elem->v1); - add_v3_v3v3(t, elem->v1, elem->v2); - immVertex3fv(pos, t); - } - immEnd(); - - immUnbindProgram(); - - /**** strings ****/ - - for (BLI_ghashIterator_init(&iter, debug_data->gh); !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter)) { - SimDebugElement *elem = BLI_ghashIterator_getValue(&iter); - if (elem->type != SIM_DEBUG_ELEM_STRING) - continue; - - unsigned char col[4]; - rgb_float_to_uchar(col, elem->color); - col[3] = 255; - view3d_cached_text_draw_add(elem->v1, elem->str, strlen(elem->str), - 0, V3D_CACHE_TEXT_GLOBALSPACE, col); - } -} - -void draw_sim_debug_data(Scene *UNUSED(scene), View3D *v3d, ARegion *ar) -{ - RegionView3D *rv3d = ar->regiondata; - /*Object *ob = base->object;*/ - float imat[4][4]; - - if (!_sim_debug_data) - return; - - invert_m4_m4(imat, rv3d->viewmatob); - - gpuPushMatrix(); - gpuLoadMatrix(rv3d->viewmat); - - view3d_cached_text_draw_begin(); - draw_sim_debug_elements(_sim_debug_data, imat); - view3d_cached_text_draw_end(v3d, ar, false); - - gpuPopMatrix(); -} diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 5e9d6f4ea1c..337d9c004ad 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -290,8 +290,6 @@ void ED_view3d_stop_render_preview(wmWindowManager *wm, ARegion *ar) BPy_END_ALLOW_THREADS; #endif - if (rv3d->render_engine->re) - RE_Database_Free(rv3d->render_engine->re); RE_engine_free(rv3d->render_engine); rv3d->render_engine = NULL; } diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 1910f7e27c0..5316520ccab 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -98,23 +98,6 @@ /* ******************** general functions ***************** */ -static bool use_depth_doit(View3D *v3d, Object *obedit) -{ - if (v3d->drawtype > OB_WIRE) - return true; - - /* special case (depth for wire color) */ - if (v3d->drawtype <= OB_WIRE) { - if (obedit && obedit->type == OB_MESH) { - Mesh *me = obedit->data; - if (me->drawflag & ME_DRAWEIGHT) { - return true; - } - } - } - return false; -} - /** * \note keep this synced with #ED_view3d_mats_rv3d_backup/#ED_view3d_mats_rv3d_restore */ @@ -742,16 +725,7 @@ void ED_view3d_draw_depth( v3d->zbuf = true; glEnable(GL_DEPTH_TEST); -#ifdef WITH_OPENGL_LEGACY - if (IS_VIEWPORT_LEGACY(vc->v3d)) { - /* temp, calls into view3d_draw_legacy.c */ - ED_view3d_draw_depth_loop(scene, ar, v3d); - } - else -#endif /* WITH_OPENGL_LEGACY */ - { - DRW_draw_depth_loop(depsgraph, ar, v3d); - } + DRW_draw_depth_loop(depsgraph, ar, v3d); if (rv3d->rflag & RV3D_CLIPPING) { ED_view3d_clipping_disable(); @@ -768,536 +742,8 @@ void ED_view3d_draw_depth( UI_Theme_Restore(&theme_state); } -/* ******************** background plates ***************** */ - -static void view3d_draw_background_gradient(void) -{ - /* TODO: finish 2D API & draw background with that */ - - Gwn_VertFormat *format = immVertexFormat(); - unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - unsigned int color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 3, GWN_FETCH_INT_TO_FLOAT_UNIT); - unsigned char col_hi[3], col_lo[3]; - - immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR); - - UI_GetThemeColor3ubv(TH_LOW_GRAD, col_lo); - UI_GetThemeColor3ubv(TH_HIGH_GRAD, col_hi); - - immBegin(GWN_PRIM_TRI_FAN, 4); - immAttrib3ubv(color, col_lo); - immVertex2f(pos, -1.0f, -1.0f); - immVertex2f(pos, 1.0f, -1.0f); - - immAttrib3ubv(color, col_hi); - immVertex2f(pos, 1.0f, 1.0f); - immVertex2f(pos, -1.0f, 1.0f); - immEnd(); - - immUnbindProgram(); -} - -static void view3d_draw_background_none(void) -{ - UI_ThemeClearColorAlpha(TH_HIGH_GRAD, 1.0f); - glClear(GL_COLOR_BUFFER_BIT); -} - -static void view3d_draw_background_world(Scene *scene, RegionView3D *rv3d) -{ - if (scene->world) { - GPUMaterial *gpumat = GPU_material_world(scene, scene->world); - - /* calculate full shader for background */ - GPU_material_bind(gpumat, 1, 1, 1.0f, false, rv3d->viewmat, rv3d->viewinv, rv3d->viewcamtexcofac); - - if (GPU_material_bound(gpumat)) { - /* TODO viewport (dfelinto): GPU_material_bind relies on immediate mode, - * we can't get rid of the following code without a bigger refactor - * or we dropping this functionality. */ - - glBegin(GL_TRIANGLE_STRIP); - glVertex2f(-1.0f, -1.0f); - glVertex2f(1.0f, -1.0f); - glVertex2f(-1.0f, 1.0f); - glVertex2f(1.0f, 1.0f); - glEnd(); - - GPU_material_unbind(gpumat); - return; - } - } - - /* if any of the above fails */ - view3d_draw_background_none(); -} - /* ******************** other elements ***************** */ - -#define DEBUG_GRID 0 - -static void gridline_range(double x0, double dx, double max, int *r_first, int *r_count) -{ - /* determine range of gridlines that appear in this Area -- similar calc but separate ranges for x & y - * x0 is gridline 0, the axis in screen space - * Area covers [0 .. max) pixels */ - - int first = (int)ceil(-x0 / dx); - int last = (int)floor((max - x0) / dx); - - if (first <= last) { - *r_first = first; - *r_count = last - first + 1; - } - else { - *r_first = 0; - *r_count = 0; - } - -#if DEBUG_GRID - printf(" first %d * dx = %f\n", first, x0 + first * dx); - printf(" last %d * dx = %f\n", last, x0 + last * dx); - printf(" count = %d\n", *count_out); -#endif -} - -static int gridline_count(ARegion *ar, double x0, double y0, double dx) -{ - /* x0 & y0 establish the "phase" of the grid within this 2D region - * dx is the frequency, shared by x & y directions - * pass in dx of smallest (highest precision) grid we want to draw */ - -#if DEBUG_GRID - printf(" %s(%f, %f, dx:%f)\n", __FUNCTION__, x0, y0, dx); -#endif - - int first, x_ct, y_ct; - - gridline_range(x0, dx, ar->winx, &first, &x_ct); - gridline_range(y0, dx, ar->winy, &first, &y_ct); - - int total_ct = x_ct + y_ct; - -#if DEBUG_GRID - printf(" %d + %d = %d gridlines\n", x_ct, y_ct, total_ct); -#endif - - return total_ct; -} - -static bool drawgrid_draw(ARegion *ar, double x0, double y0, double dx, int skip_mod, unsigned pos, unsigned col, GLubyte col_value[3]) -{ - /* skip every skip_mod lines relative to each axis; they will be overlaid by another drawgrid_draw - * always skip exact x0 & y0 axes; they will be drawn later in color - * - * set grid color once, just before the first line is drawn - * it's harmless to set same color for every line, or every vertex - * but if no lines are drawn, color must not be set! */ - -#if DEBUG_GRID - printf(" %s(%f, %f, dx:%f, skip_mod:%d)\n", __FUNCTION__, x0, y0, dx, skip_mod); -#endif - - const float x_max = (float)ar->winx; - const float y_max = (float)ar->winy; - - int first, ct; - int x_ct = 0, y_ct = 0; /* count of lines actually drawn */ - int lines_skipped_for_next_unit = 0; - - /* draw vertical lines */ - gridline_range(x0, dx, x_max, &first, &ct); - - for (int i = first; i < first + ct; ++i) { - if (i == 0) - continue; - else if (skip_mod && (i % skip_mod) == 0) { - ++lines_skipped_for_next_unit; - continue; - } - - if (x_ct == 0) - immAttrib3ub(col, col_value[0], col_value[1], col_value[2]); - - float x = (float)(x0 + i * dx); - immVertex2f(pos, x, 0.0f); - immVertex2f(pos, x, y_max); - ++x_ct; - } - - /* draw horizontal lines */ - gridline_range(y0, dx, y_max, &first, &ct); - - for (int i = first; i < first + ct; ++i) { - if (i == 0) - continue; - else if (skip_mod && (i % skip_mod) == 0) { - ++lines_skipped_for_next_unit; - continue; - } - - if (x_ct + y_ct == 0) - immAttrib3ub(col, col_value[0], col_value[1], col_value[2]); - - float y = (float)(y0 + i * dx); - immVertex2f(pos, 0.0f, y); - immVertex2f(pos, x_max, y); - ++y_ct; - } - -#if DEBUG_GRID - int total_ct = x_ct + y_ct; - printf(" %d + %d = %d gridlines drawn, %d skipped for next unit\n", x_ct, y_ct, total_ct, lines_skipped_for_next_unit); -#endif - - return lines_skipped_for_next_unit > 0; -} - -#define GRID_MIN_PX_D 6.0 -#define GRID_MIN_PX_F 6.0f - -static void drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, const char **grid_unit) -{ - RegionView3D *rv3d = ar->regiondata; - -#if DEBUG_GRID - printf("%s width %d, height %d\n", __FUNCTION__, ar->winx, ar->winy); -#endif - - double fx = rv3d->persmat[3][0]; - double fy = rv3d->persmat[3][1]; - double fw = rv3d->persmat[3][3]; - - const double wx = 0.5 * ar->winx; /* use double precision to avoid rounding errors */ - const double wy = 0.5 * ar->winy; - - double x = wx * fx / fw; - double y = wy * fy / fw; - - double vec4[4] = { v3d->grid, v3d->grid, 0.0, 1.0 }; - mul_m4_v4d(rv3d->persmat, vec4); - fx = vec4[0]; - fy = vec4[1]; - fw = vec4[3]; - - double dx = fabs(x - wx * fx / fw); - if (dx == 0) dx = fabs(y - wy * fy / fw); - - x += wx; - y += wy; - - /* now x, y, and dx have their final values - * (x,y) is the world origin (0,0,0) mapped to Area-relative screen space - * dx is the distance in pixels between grid lines -- same for horiz or vert grid lines */ - - glLineWidth(1.0f); - -#if 0 /* TODO: write to UI/widget depth buffer, not scene depth */ - glDepthMask(GL_FALSE); /* disable write in zbuffer */ -#endif - - Gwn_VertFormat *format = immVertexFormat(); - unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - unsigned int color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 3, GWN_FETCH_INT_TO_FLOAT_UNIT); - - immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR); - - unsigned char col[3], col2[3]; - UI_GetThemeColor3ubv(TH_GRID, col); - - if (unit->system) { - const void *usys; - int len; - - bUnit_GetSystem(unit->system, B_UNIT_LENGTH, &usys, &len); - - bool first = true; - - if (usys) { - int i = len; - while (i--) { - double scalar = bUnit_GetScaler(usys, i); - - double dx_scalar = dx * scalar / (double)unit->scale_length; - if (dx_scalar < (GRID_MIN_PX_D * 2.0)) { - /* very very small grid items are less useful when dealing with units */ - continue; - } - - if (first) { - first = false; - - /* Store the smallest drawn grid size units name so users know how big each grid cell is */ - *grid_unit = bUnit_GetNameDisplay(usys, i); - rv3d->gridview = (float)((scalar * (double)v3d->grid) / (double)unit->scale_length); - - int gridline_ct = gridline_count(ar, x, y, dx_scalar); - if (gridline_ct == 0) - goto drawgrid_cleanup; /* nothing to draw */ - - immBegin(GWN_PRIM_LINES, gridline_ct * 2); - } - - float blend_fac = 1.0f - ((GRID_MIN_PX_F * 2.0f) / (float)dx_scalar); - /* tweak to have the fade a bit nicer */ - blend_fac = (blend_fac * blend_fac) * 2.0f; - CLAMP(blend_fac, 0.3f, 1.0f); - - UI_GetThemeColorBlend3ubv(TH_HIGH_GRAD, TH_GRID, blend_fac, col2); - - const int skip_mod = (i == 0) ? 0 : (int)round(bUnit_GetScaler(usys, i - 1) / scalar); -#if DEBUG_GRID - printf("%s %f, ", bUnit_GetNameDisplay(usys, i), scalar); - if (i > 0) - printf("next unit is %d times larger\n", skip_mod); - else - printf("largest unit\n"); -#endif - if (!drawgrid_draw(ar, x, y, dx_scalar, skip_mod, pos, color, col2)) - break; - } - } - } - else { - const double sublines = v3d->gridsubdiv; - const float sublines_fl = v3d->gridsubdiv; - - int grids_to_draw = 2; /* first the faint fine grid, then the bold coarse grid */ - - if (dx < GRID_MIN_PX_D) { - rv3d->gridview *= sublines_fl; - dx *= sublines; - if (dx < GRID_MIN_PX_D) { - rv3d->gridview *= sublines_fl; - dx *= sublines; - if (dx < GRID_MIN_PX_D) { - rv3d->gridview *= sublines_fl; - dx *= sublines; - grids_to_draw = (dx < GRID_MIN_PX_D) ? 0 : 1; - } - } - } - else { - if (dx > (GRID_MIN_PX_D * 10.0)) { /* start blending in */ - rv3d->gridview /= sublines_fl; - dx /= sublines; - if (dx > (GRID_MIN_PX_D * 10.0)) { /* start blending in */ - rv3d->gridview /= sublines_fl; - dx /= sublines; - if (dx > (GRID_MIN_PX_D * 10.0)) { - grids_to_draw = 1; - } - } - } - } - - int gridline_ct = gridline_count(ar, x, y, dx); - if (gridline_ct == 0) - goto drawgrid_cleanup; /* nothing to draw */ - - immBegin(GWN_PRIM_LINES, gridline_ct * 2); - - if (grids_to_draw == 2) { - UI_GetThemeColorBlend3ubv(TH_HIGH_GRAD, TH_GRID, dx / (GRID_MIN_PX_D * 6.0), col2); - if (drawgrid_draw(ar, x, y, dx, v3d->gridsubdiv, pos, color, col2)) - drawgrid_draw(ar, x, y, dx * sublines, 0, pos, color, col); - } - else if (grids_to_draw == 1) { - drawgrid_draw(ar, x, y, dx, 0, pos, color, col); - } - } - - /* draw visible axes */ - /* horizontal line */ - if (0 <= y && y < ar->winy) { - UI_make_axis_color(col, col2, ELEM(rv3d->view, RV3D_VIEW_RIGHT, RV3D_VIEW_LEFT) ? 'Y' : 'X'); - immAttrib3ub(color, col2[0], col2[1], col2[2]); - immVertex2f(pos, 0.0f, y); - immVertex2f(pos, (float)ar->winx, y); - } - - /* vertical line */ - if (0 <= x && x < ar->winx) { - UI_make_axis_color(col, col2, ELEM(rv3d->view, RV3D_VIEW_TOP, RV3D_VIEW_BOTTOM) ? 'Y' : 'Z'); - immAttrib3ub(color, col2[0], col2[1], col2[2]); - immVertex2f(pos, x, 0.0f); - immVertex2f(pos, x, (float)ar->winy); - } - - immEnd(); - -drawgrid_cleanup: - immUnbindProgram(); - -#if 0 /* depth write is left enabled above */ - glDepthMask(GL_TRUE); /* enable write in zbuffer */ -#endif -} - -#undef DEBUG_GRID -#undef GRID_MIN_PX_D -#undef GRID_MIN_PX_F - -static void drawfloor(Scene *scene, View3D *v3d, const char **grid_unit, bool write_depth) -{ - /* draw only if there is something to draw */ - if (v3d->gridflag & (V3D_SHOW_FLOOR | V3D_SHOW_X | V3D_SHOW_Y | V3D_SHOW_Z)) { - /* draw how many lines? - * trunc(v3d->gridlines / 2) * 4 - * + 2 for xy axes (possibly with special colors) - * + 1 for z axis (the only line not in xy plane) - * even v3d->gridlines are honored, odd rounded down */ - const int gridlines = v3d->gridlines / 2; - const float grid_scale = ED_view3d_grid_scale(scene, v3d, grid_unit); - const float grid = gridlines * grid_scale; - - const bool show_floor = (v3d->gridflag & V3D_SHOW_FLOOR) && gridlines >= 1; - - bool show_axis_x = v3d->gridflag & V3D_SHOW_X; - bool show_axis_y = v3d->gridflag & V3D_SHOW_Y; - bool show_axis_z = v3d->gridflag & V3D_SHOW_Z; - - unsigned char col_grid[3], col_axis[3]; - - glLineWidth(1.0f); - - UI_GetThemeColor3ubv(TH_GRID, col_grid); - - if (!write_depth) - glDepthMask(GL_FALSE); - - if (show_floor) { - const unsigned vertex_ct = 2 * (gridlines * 4 + 2); - const int sublines = v3d->gridsubdiv; - - unsigned char col_bg[3], col_grid_emphasise[3], col_grid_light[3]; - - Gwn_VertFormat *format = immVertexFormat(); - unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - unsigned int color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 3, GWN_FETCH_INT_TO_FLOAT_UNIT); - - immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR); - - immBegin(GWN_PRIM_LINES, vertex_ct); - - /* draw normal grid lines */ - UI_GetColorPtrShade3ubv(col_grid, col_grid_light, 10); - - for (int a = 1; a <= gridlines; a++) { - /* skip emphasised divider lines */ - if (a % sublines != 0) { - const float line = a * grid_scale; - - immAttrib3ubv(color, col_grid_light); - - immVertex2f(pos, -grid, -line); - immVertex2f(pos, +grid, -line); - immVertex2f(pos, -grid, +line); - immVertex2f(pos, +grid, +line); - - immVertex2f(pos, -line, -grid); - immVertex2f(pos, -line, +grid); - immVertex2f(pos, +line, -grid); - immVertex2f(pos, +line, +grid); - } - } - - /* draw emphasised grid lines */ - UI_GetThemeColor3ubv(TH_BACK, col_bg); - /* emphasise division lines lighter instead of darker, if background is darker than grid */ - UI_GetColorPtrShade3ubv(col_grid, col_grid_emphasise, - (col_grid[0] + col_grid[1] + col_grid[2] + 30 > - col_bg[0] + col_bg[1] + col_bg[2]) ? 20 : -10); - - if (sublines <= gridlines) { - immAttrib3ubv(color, col_grid_emphasise); - - for (int a = sublines; a <= gridlines; a += sublines) { - const float line = a * grid_scale; - - immVertex2f(pos, -grid, -line); - immVertex2f(pos, +grid, -line); - immVertex2f(pos, -grid, +line); - immVertex2f(pos, +grid, +line); - - immVertex2f(pos, -line, -grid); - immVertex2f(pos, -line, +grid); - immVertex2f(pos, +line, -grid); - immVertex2f(pos, +line, +grid); - } - } - - /* draw X axis */ - if (show_axis_x) { - show_axis_x = false; /* drawing now, won't need to draw later */ - UI_make_axis_color(col_grid, col_axis, 'X'); - immAttrib3ubv(color, col_axis); - } - else - immAttrib3ubv(color, col_grid_emphasise); - - immVertex2f(pos, -grid, 0.0f); - immVertex2f(pos, +grid, 0.0f); - - /* draw Y axis */ - if (show_axis_y) { - show_axis_y = false; /* drawing now, won't need to draw later */ - UI_make_axis_color(col_grid, col_axis, 'Y'); - immAttrib3ubv(color, col_axis); - } - else - immAttrib3ubv(color, col_grid_emphasise); - - immVertex2f(pos, 0.0f, -grid); - immVertex2f(pos, 0.0f, +grid); - - immEnd(); - immUnbindProgram(); - - /* done with XY plane */ - } - - if (show_axis_x || show_axis_y || show_axis_z) { - /* draw axis lines -- sometimes grid floor is off, other times we still need to draw the Z axis */ - - Gwn_VertFormat *format = immVertexFormat(); - unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - unsigned int color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 3, GWN_FETCH_INT_TO_FLOAT_UNIT); - - immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR); - immBegin(GWN_PRIM_LINES, (show_axis_x + show_axis_y + show_axis_z) * 2); - - if (show_axis_x) { - UI_make_axis_color(col_grid, col_axis, 'X'); - immAttrib3ubv(color, col_axis); - immVertex3f(pos, -grid, 0.0f, 0.0f); - immVertex3f(pos, +grid, 0.0f, 0.0f); - } - - if (show_axis_y) { - UI_make_axis_color(col_grid, col_axis, 'Y'); - immAttrib3ubv(color, col_axis); - immVertex3f(pos, 0.0f, -grid, 0.0f); - immVertex3f(pos, 0.0f, +grid, 0.0f); - } - - if (show_axis_z) { - UI_make_axis_color(col_grid, col_axis, 'Z'); - immAttrib3ubv(color, col_axis); - immVertex3f(pos, 0.0f, 0.0f, -grid); - immVertex3f(pos, 0.0f, 0.0f, +grid); - } - - immEnd(); - immUnbindProgram(); - } - - if (!write_depth) - glDepthMask(GL_TRUE); - } -} - /** could move this elsewhere, but tied into #ED_view3d_grid_scale */ float ED_scene_grid_scale(Scene *scene, const char **grid_unit) { @@ -1324,102 +770,6 @@ float ED_view3d_grid_scale(Scene *scene, View3D *v3d, const char **grid_unit) return v3d->grid * ED_scene_grid_scale(scene, grid_unit); } -static bool is_cursor_visible(Scene *scene, ViewLayer *view_layer) -{ - if (U.app_flag & USER_APP_VIEW3D_HIDE_CURSOR) { - return false; - } - - Object *ob = OBACT(view_layer); - - /* don't draw cursor in paint modes, but with a few exceptions */ - if (ob && ob->mode & OB_MODE_ALL_PAINT) { - /* exception: object is in weight paint and has deforming armature in pose mode */ - if (ob->mode & OB_MODE_WEIGHT_PAINT) { - if (BKE_object_pose_armature_get(ob) != NULL) { - return true; - } - } - /* exception: object in texture paint mode, clone brush, use_clone_layer disabled */ - else if (ob->mode & OB_MODE_TEXTURE_PAINT) { - const Paint *p = BKE_paint_get_active(scene, view_layer); - - if (p && p->brush && p->brush->imagepaint_tool == PAINT_TOOL_CLONE) { - if ((scene->toolsettings->imapaint.flag & IMAGEPAINT_PROJECT_LAYER_CLONE) == 0) { - return true; - } - } - } - - /* no exception met? then don't draw cursor! */ - return false; - } - - return true; -} - -static void drawcursor(Scene *scene, ARegion *ar, View3D *v3d) -{ - int co[2]; - - /* we don't want the clipping for cursor */ - if (ED_view3d_project_int_global(ar, ED_view3d_cursor3d_get(scene, v3d), co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { - const float f5 = 0.25f * U.widget_unit; - const float f10 = 0.5f * U.widget_unit; - const float f20 = U.widget_unit; - - glLineWidth(1.0f); - - Gwn_VertFormat *format = immVertexFormat(); - unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - unsigned int color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 3, GWN_FETCH_INT_TO_FLOAT_UNIT); - - immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR); - - const int segments = 16; - - immBegin(GWN_PRIM_LINE_LOOP, segments); - - for (int i = 0; i < segments; ++i) { - float angle = 2 * M_PI * ((float)i / (float)segments); - float x = co[0] + f10 * cosf(angle); - float y = co[1] + f10 * sinf(angle); - - if (i % 2 == 0) - immAttrib3ub(color, 255, 0, 0); - else - immAttrib3ub(color, 255, 255, 255); - - immVertex2f(pos, x, y); - } - immEnd(); - - immUnbindProgram(); - - GWN_vertformat_clear(format); - pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - - immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); - - unsigned char crosshair_color[3]; - UI_GetThemeColor3ubv(TH_VIEW_OVERLAY, crosshair_color); - immUniformColor3ubv(crosshair_color); - - immBegin(GWN_PRIM_LINES, 8); - immVertex2f(pos, co[0] - f20, co[1]); - immVertex2f(pos, co[0] - f5, co[1]); - immVertex2f(pos, co[0] + f5, co[1]); - immVertex2f(pos, co[0] + f20, co[1]); - immVertex2f(pos, co[0], co[1] - f20); - immVertex2f(pos, co[0], co[1] - f5); - immVertex2f(pos, co[0], co[1] + f5); - immVertex2f(pos, co[0], co[1] + f20); - immEnd(); - - immUnbindProgram(); - } -} - static void draw_view_axis(RegionView3D *rv3d, const rcti *rect) { const float k = U.rvisize * U.pixelsize; /* axis size */ @@ -1909,16 +1259,8 @@ RenderEngineType *ED_view3d_engine_type(Scene *scene, int drawtype) void view3d_main_region_draw(const bContext *C, ARegion *ar) { - Scene *scene = CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); RegionView3D *rv3d = ar->regiondata; - RenderEngineType *type = ED_view3d_engine_type(scene, v3d->drawtype); - - /* Provisory Blender Internal drawing */ - if (type->flag & RE_USE_LEGACY_PIPELINE) { - view3d_main_region_draw_legacy(C, ar); - return; - } if (!rv3d->viewport) { rv3d->viewport = GPU_viewport_create(); @@ -1965,50 +1307,17 @@ static void view3d_stereo3d_setup_offscreen( } } -void ED_view3d_draw_offscreen_init(Depsgraph *depsgraph, - Scene *scene, - ViewLayer *view_layer, - View3D *v3d, - int drawtype) -{ - RenderEngineType *engine_type = ED_view3d_engine_type(scene, drawtype); - - if (engine_type->flag & RE_USE_LEGACY_PIPELINE) { - /* shadow buffers, before we setup matrices */ - if (draw_glsl_material(scene, view_layer, NULL, v3d, drawtype)) { - VP_deprecated_gpu_update_lamps_shadows_world(depsgraph, scene, v3d); - } - } -} - -/* - * Function to clear the view - */ -static void view3d_main_region_clear(Scene *scene, View3D *v3d, ARegion *ar) -{ - glClear(GL_DEPTH_BUFFER_BIT); - - if (scene->world && (v3d->flag3 & V3D_SHOW_WORLD)) { - VP_view3d_draw_background_world(scene, ar->regiondata); - } - else { - VP_view3d_draw_background_none(); - } -} - -/* ED_view3d_draw_offscreen_init should be called before this to initialize - * stuff like shadow buffers - */ void ED_view3d_draw_offscreen( Depsgraph *depsgraph, Scene *scene, - ViewLayer *view_layer, int drawtype, + int drawtype, View3D *v3d, ARegion *ar, int winx, int winy, float viewmat[4][4], float winmat[4][4], - bool do_bgpic, bool do_sky, bool UNUSED(is_persp), const char *viewname, + bool do_sky, bool UNUSED(is_persp), const char *viewname, GPUFXSettings *UNUSED(fx_settings), GPUOffScreen *ofs, GPUViewport *viewport) { RegionView3D *rv3d = ar->regiondata; + RenderEngineType *engine_type = ED_view3d_engine_type(scene, drawtype); /* set temporary new size */ int bwinx = ar->winx; @@ -2046,29 +1355,9 @@ void ED_view3d_draw_offscreen( view3d_main_region_setup_view(depsgraph, scene, v3d, ar, viewmat, winmat, NULL); /* main drawing call */ - RenderEngineType *engine_type = ED_view3d_engine_type(scene, drawtype); - - if (engine_type->flag & RE_USE_LEGACY_PIPELINE) { - VP_deprecated_view3d_draw_objects(NULL, depsgraph, scene, v3d, ar, NULL, do_bgpic, true); - - if ((v3d->flag2 & V3D_RENDER_SHADOW) == 0) { - /* draw grease-pencil stuff */ - ED_region_pixelspace(ar); - - if (v3d->flag2 & V3D_SHOW_GPENCIL) { - /* draw grease-pencil stuff - needed to get paint-buffer shown too (since it's 2D) */ - ED_gpencil_draw_view3d(NULL, scene, view_layer, depsgraph, v3d, ar, false); - } - - /* freeing the images again here could be done after the operator runs, leaving for now */ - GPU_free_images_anim(); - } - } - else { - DRW_draw_render_loop_offscreen( - depsgraph, engine_type, ar, v3d, - do_sky, ofs, viewport); - } + DRW_draw_render_loop_offscreen( + depsgraph, engine_type, ar, v3d, + do_sky, ofs, viewport); /* restore size */ ar->winx = bwinx; @@ -2091,7 +1380,7 @@ void ED_view3d_draw_offscreen( */ ImBuf *ED_view3d_draw_offscreen_imbuf( Depsgraph *depsgraph, Scene *scene, - ViewLayer *view_layer, int drawtype, + int drawtype, View3D *v3d, ARegion *ar, int sizex, int sizey, unsigned int flag, unsigned int draw_flags, int alpha_mode, int samples, const char *viewname, @@ -2100,7 +1389,6 @@ ImBuf *ED_view3d_draw_offscreen_imbuf( { RegionView3D *rv3d = ar->regiondata; const bool draw_sky = (alpha_mode == R_ADDSKY); - const bool draw_background = (draw_flags & V3D_OFSDRAW_USE_BACKGROUND); const bool use_full_sample = (draw_flags & V3D_OFSDRAW_USE_FULL_SAMPLE); /* view state */ @@ -2125,8 +1413,6 @@ ImBuf *ED_view3d_draw_offscreen_imbuf( } } - ED_view3d_draw_offscreen_init(depsgraph, scene, view_layer, v3d, drawtype); - GPU_offscreen_bind(ofs, true); /* read in pixels & stamp */ @@ -2167,9 +1453,9 @@ ImBuf *ED_view3d_draw_offscreen_imbuf( if ((samples && use_full_sample) == 0) { /* Single-pass render, common case */ ED_view3d_draw_offscreen( - depsgraph, scene, view_layer, drawtype, + depsgraph, scene, drawtype, v3d, ar, sizex, sizey, NULL, winmat, - draw_background, draw_sky, !is_ortho, viewname, + draw_sky, !is_ortho, viewname, &fx_settings, ofs, NULL); if (ibuf->rect_float) { @@ -2192,9 +1478,9 @@ ImBuf *ED_view3d_draw_offscreen_imbuf( /* first sample buffer, also initializes 'rv3d->persmat' */ ED_view3d_draw_offscreen( - depsgraph, scene, view_layer, drawtype, + depsgraph, scene, drawtype, v3d, ar, sizex, sizey, NULL, winmat, - draw_background, draw_sky, !is_ortho, viewname, + draw_sky, !is_ortho, viewname, &fx_settings, ofs, viewport); GPU_offscreen_read_pixels(ofs, GL_FLOAT, accum_buffer); @@ -2207,9 +1493,9 @@ ImBuf *ED_view3d_draw_offscreen_imbuf( (jit_ofs[j][1] * 2.0f) / sizey); ED_view3d_draw_offscreen( - depsgraph, scene, view_layer, drawtype, + depsgraph, scene, drawtype, v3d, ar, sizex, sizey, NULL, winmat_jitter, - draw_background, draw_sky, !is_ortho, viewname, + draw_sky, !is_ortho, viewname, &fx_settings, ofs, viewport); GPU_offscreen_read_pixels(ofs, GL_FLOAT, rect_temp); @@ -2272,7 +1558,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf( */ ImBuf *ED_view3d_draw_offscreen_imbuf_simple( Depsgraph *depsgraph, Scene *scene, - ViewLayer *view_layer, int drawtype, + int drawtype, Object *camera, int width, int height, unsigned int flag, unsigned int draw_flags, int alpha_mode, int samples, const char *viewname, @@ -2298,9 +1584,9 @@ ImBuf *ED_view3d_draw_offscreen_imbuf_simple( if (draw_flags & V3D_OFSDRAW_USE_SOLID_TEX) { v3d.flag2 |= V3D_SOLID_TEX; } - if (draw_flags & V3D_OFSDRAW_USE_BACKGROUND) { - v3d.flag3 |= V3D_SHOW_WORLD; - } + + v3d.flag3 |= V3D_SHOW_WORLD; + if (draw_flags & V3D_OFSDRAW_USE_CAMERA_DOF) { if (camera->type == OB_CAMERA) { v3d.fx_settings.dof = &((Camera *)camera->data)->gpu_dof; @@ -2334,105 +1620,9 @@ ImBuf *ED_view3d_draw_offscreen_imbuf_simple( invert_m4_m4(rv3d.persinv, rv3d.viewinv); return ED_view3d_draw_offscreen_imbuf( - depsgraph, scene, view_layer, drawtype, + depsgraph, scene, drawtype, &v3d, &ar, width, height, flag, draw_flags, alpha_mode, samples, viewname, ofs, err_out); } /** \} */ - - -/* -------------------------------------------------------------------- */ - -/** \name Legacy Interface - * - * This will be removed once the viewport gets replaced - * meanwhile it should keep the old viewport working. - * - * \{ */ - -void VP_legacy_drawcursor(Scene *scene, ViewLayer *view_layer, ARegion *ar, View3D *v3d) -{ - if (is_cursor_visible(scene, view_layer)) { - drawcursor(scene, ar, v3d); - } -} - -void VP_legacy_draw_view_axis(RegionView3D *rv3d, const rcti *rect) -{ - draw_view_axis(rv3d, rect); -} - -void VP_legacy_draw_viewport_name(ARegion *ar, View3D *v3d, const rcti *rect) -{ - draw_viewport_name(ar, v3d, rect); -} - -void VP_legacy_draw_selected_name(Scene *scene, Object *ob, rcti *rect) -{ - draw_selected_name(scene, ob, rect); -} - -void VP_legacy_drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, const char **grid_unit) -{ - drawgrid(unit, ar, v3d, grid_unit); -} - -void VP_legacy_drawfloor(Scene *scene, View3D *v3d, const char **grid_unit, bool write_depth) -{ - drawfloor(scene, v3d, grid_unit, write_depth); -} - -void VP_legacy_view3d_main_region_setup_view( - Depsgraph *depsgraph, Scene *scene, View3D *v3d, - ARegion *ar, float viewmat[4][4], float winmat[4][4]) -{ - view3d_main_region_setup_view(depsgraph, scene, v3d, ar, viewmat, winmat, NULL); -} - -bool VP_legacy_view3d_stereo3d_active(wmWindow *win, Scene *scene, View3D *v3d, RegionView3D *rv3d) -{ - return view3d_stereo3d_active(win, scene, v3d, rv3d); -} - -void VP_legacy_view3d_stereo3d_setup(Depsgraph *depsgraph, Scene *scene, View3D *v3d, ARegion *ar) -{ - view3d_stereo3d_setup(depsgraph, scene, v3d, ar, NULL); -} - -bool VP_legacy_use_depth(View3D *v3d, Object *obedit) -{ - return use_depth_doit(v3d, obedit); -} - -void VP_drawviewborder(Scene *scene, struct Depsgraph *depsgraph, ARegion *ar, View3D *v3d) -{ - drawviewborder(scene, depsgraph, ar, v3d); -} - -void VP_drawrenderborder(ARegion *ar, View3D *v3d) -{ - drawrenderborder(ar, v3d); -} - -void VP_view3d_draw_background_none(void) -{ - if (UI_GetThemeValue(TH_SHOW_BACK_GRAD)) { - view3d_draw_background_gradient(); - } - else { - view3d_draw_background_none(); - } -} - -void VP_view3d_draw_background_world(Scene *scene, RegionView3D *rv3d) -{ - view3d_draw_background_world(scene, rv3d); -} - -void VP_view3d_main_region_clear(Scene *scene, View3D *v3d, ARegion *ar) -{ - view3d_main_region_clear(scene, v3d, ar); -} - -/** \} */ diff --git a/source/blender/editors/space_view3d/view3d_draw_legacy.c b/source/blender/editors/space_view3d/view3d_draw_legacy.c index 51adcc47b6c..1ba46453915 100644 --- a/source/blender/editors/space_view3d/view3d_draw_legacy.c +++ b/source/blender/editors/space_view3d/view3d_draw_legacy.c @@ -99,7 +99,6 @@ #include "GPU_draw.h" #include "GPU_framebuffer.h" -#include "GPU_lamp.h" #include "GPU_material.h" #include "GPU_extensions.h" #include "GPU_immediate.h" @@ -115,34 +114,6 @@ /* ********* custom clipping *********** */ -static void view3d_draw_clipping(RegionView3D *rv3d) -{ - BoundBox *bb = rv3d->clipbb; - - if (bb) { - const unsigned int clipping_index[6][4] = { - {0, 1, 2, 3}, - {0, 4, 5, 1}, - {4, 7, 6, 5}, - {7, 3, 2, 6}, - {1, 5, 6, 2}, - {7, 4, 0, 3} - }; - - /* fill in zero alpha for rendering & re-projection [#31530] */ - unsigned char col[4]; - UI_GetThemeColor4ubv(TH_V3D_CLIPPING_BORDER, col); - glColor4ubv(col); - - glEnable(GL_BLEND); - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, 0, bb->vec); - glDrawElements(GL_QUADS, sizeof(clipping_index) / sizeof(unsigned int), GL_UNSIGNED_INT, clipping_index); - glDisableClientState(GL_VERTEX_ARRAY); - glDisable(GL_BLEND); - } -} - void ED_view3d_clipping_set(RegionView3D *rv3d) { double plane[4]; @@ -187,28 +158,6 @@ bool ED_view3d_clipping_test(const RegionView3D *rv3d, const float co[3], const return view3d_clipping_test(co, is_local ? rv3d->clip_local : rv3d->clip); } -/* ********* end custom clipping *********** */ - -static void draw_view_icon(RegionView3D *rv3d, rcti *rect) -{ - BIFIconID icon; - - if (ELEM(rv3d->view, RV3D_VIEW_TOP, RV3D_VIEW_BOTTOM)) - icon = ICON_AXIS_TOP; - else if (ELEM(rv3d->view, RV3D_VIEW_FRONT, RV3D_VIEW_BACK)) - icon = ICON_AXIS_FRONT; - else if (ELEM(rv3d->view, RV3D_VIEW_RIGHT, RV3D_VIEW_LEFT)) - icon = ICON_AXIS_SIDE; - else return; - - glEnable(GL_BLEND); - glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - - UI_icon_draw(5.0 + rect->xmin, 5.0 + rect->ymin, icon); - - glDisable(GL_BLEND); -} - /* *********************** backdraw for selection *************** */ static void backdrawview3d( @@ -807,253 +756,8 @@ void ED_view3d_draw_bgpic_test( } } -/* ****************** View3d afterdraw *************** */ - -typedef struct View3DAfter { - struct View3DAfter *next, *prev; - struct Base *base; - short dflag; -} View3DAfter; - -/* temp storage of Objects that need to be drawn as last */ -void ED_view3d_after_add(ListBase *lb, Base *base, const short dflag) -{ - View3DAfter *v3da = MEM_callocN(sizeof(View3DAfter), "View 3d after"); - BLI_assert((base->flag_legacy & OB_FROMDUPLI) == 0); - BLI_addtail(lb, v3da); - v3da->base = base; - v3da->dflag = dflag; -} - -/* disables write in zbuffer and draws it over */ -static void view3d_draw_transp( - Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer, ARegion *ar, View3D *v3d) -{ - View3DAfter *v3da; - - glDepthMask(GL_FALSE); - v3d->transp = true; - - while ((v3da = BLI_pophead(&v3d->afterdraw_transp))) { - draw_object(depsgraph, scene, view_layer, ar, v3d, v3da->base, v3da->dflag); - MEM_freeN(v3da); - } - v3d->transp = false; - - glDepthMask(GL_TRUE); - -} - -/* clears zbuffer and draws it over */ -static void view3d_draw_xray( - Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer, ARegion *ar, View3D *v3d, bool *clear) -{ - if (*clear && v3d->zbuf) { - glClear(GL_DEPTH_BUFFER_BIT); - *clear = false; - } - - v3d->xray = true; - View3DAfter *v3da; - while ((v3da = BLI_pophead(&v3d->afterdraw_xray))) { - draw_object(depsgraph, scene, view_layer, ar, v3d, v3da->base, v3da->dflag); - MEM_freeN(v3da); - } - v3d->xray = false; -} - - -/* clears zbuffer and draws it over */ -static void view3d_draw_xraytransp( - Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer, ARegion *ar, View3D *v3d, const bool clear) -{ - if (clear && v3d->zbuf) - glClear(GL_DEPTH_BUFFER_BIT); - - v3d->xray = true; - v3d->transp = true; - - glDepthMask(GL_FALSE); - - View3DAfter *v3da; - while ((v3da = BLI_pophead(&v3d->afterdraw_xraytransp))) { - draw_object(depsgraph, scene, view_layer, ar, v3d, v3da->base, v3da->dflag); - MEM_freeN(v3da); - } - - v3d->transp = false; - v3d->xray = false; - - glDepthMask(GL_TRUE); -} - -/* clears zbuffer and draws it over, - * note that in the select version we don't care about transparent flag as with regular drawing */ -static void view3d_draw_xray_select( - struct Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer, ARegion *ar, View3D *v3d, bool *clear) -{ - /* Not ideal, but we need to read from the previous depths before clearing - * otherwise we could have a function to load the depths after drawing. - * - * Clearing the depth buffer isn't all that common between drawing objects so accept this for now. - */ - if (U.gpu_select_pick_deph) { - GPU_select_load_id(-1); - } - - View3DAfter *v3da; - if (*clear && v3d->zbuf) { - glClear(GL_DEPTH_BUFFER_BIT); - *clear = false; - } - - v3d->xray = true; - while ((v3da = BLI_pophead(&v3d->afterdraw_xray))) { - if (GPU_select_load_id(v3da->base->object->select_color)) { - draw_object_select(depsgraph, scene, view_layer, ar, v3d, v3da->base, v3da->dflag); - } - MEM_freeN(v3da); - } - v3d->xray = false; -} - /* *********************** */ -/* - * In most cases call draw_dupli_objects, - * draw_dupli_objects_color was added because when drawing set dupli's - * we need to force the color - */ - -#if 0 -int dupli_ob_sort(void *arg1, void *arg2) -{ - void *p1 = ((DupliObject *)arg1)->ob; - void *p2 = ((DupliObject *)arg2)->ob; - int val = 0; - if (p1 < p2) val = -1; - else if (p1 > p2) val = 1; - return val; -} -#endif - - -static DupliObject *dupli_step(DupliObject *dob) -{ - while (dob && dob->no_draw) - dob = dob->next; - return dob; -} - -static void draw_dupli_objects_color( - Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer, ARegion *ar, View3D *v3d, Base *base, - const short dflag, const int color) -{ - RegionView3D *rv3d = ar->regiondata; - ListBase *lb; - LodLevel *savedlod; - Base tbase = {NULL}; - BoundBox bb, *bb_tmp; /* use a copy because draw_object, calls clear_mesh_caches */ - unsigned char color_rgb[3]; - const short dflag_dupli = dflag | DRAW_CONSTCOLOR; - short transflag; - char dt; - short dtx; - DupliApplyData *apply_data; - - if ((base->flag & BASE_VISIBLED) == 0) return; - if ((base->object->restrictflag & OB_RESTRICT_RENDER) && (v3d->flag2 & V3D_RENDER_OVERRIDE)) return; - - if (dflag & DRAW_CONSTCOLOR) { - BLI_assert(color == TH_UNDEFINED); - } - else { - UI_GetThemeColorBlend3ubv(color, TH_BACK, 0.5f, color_rgb); - } - - tbase.flag_legacy = OB_FROMDUPLI | base->flag_legacy; - tbase.flag = base->flag; - lb = object_duplilist(depsgraph, scene, base->object); - // BLI_listbase_sort(lb, dupli_ob_sort); /* might be nice to have if we have a dupli list with mixed objects. */ - - apply_data = duplilist_apply(depsgraph, base->object, scene, lb); - - DupliObject *dob_next = NULL; - DupliObject *dob = dupli_step(lb->first); - if (dob) dob_next = dupli_step(dob->next); - - for (; dob; dob = dob_next, dob_next = dob_next ? dupli_step(dob_next->next) : NULL) { - bool testbb = false; - - tbase.object = dob->ob; - - /* Make sure lod is updated from dupli's position */ - savedlod = dob->ob->currentlod; - - /* extra service: draw the duplicator in drawtype of parent, minimum taken - * to allow e.g. boundbox box objects in groups for LOD */ - dt = tbase.object->dt; - tbase.object->dt = MIN2(tbase.object->dt, base->object->dt); - - /* inherit draw extra, but not if a boundbox under the assumption that this - * is intended to speed up drawing, and drawing extra (especially wire) can - * slow it down too much */ - dtx = tbase.object->dtx; - if (tbase.object->dt != OB_BOUNDBOX) - tbase.object->dtx = base->object->dtx; - - /* negative scale flag has to propagate */ - transflag = tbase.object->transflag; - - if (is_negative_m4(dob->mat)) - tbase.object->transflag |= OB_NEG_SCALE; - else - tbase.object->transflag &= ~OB_NEG_SCALE; - - /* should move outside the loop but possible color is set in draw_object still */ - if ((dflag & DRAW_CONSTCOLOR) == 0) { - glColor3ubv(color_rgb); - } - - if ((bb_tmp = BKE_object_boundbox_get(dob->ob))) { - bb = *bb_tmp; /* must make a copy */ - testbb = true; - } - - if (!testbb || ED_view3d_boundbox_clip_ex(rv3d, &bb, dob->mat)) { - copy_m4_m4(dob->ob->obmat, dob->mat); - GPU_begin_dupli_object(dob); - draw_object(depsgraph, scene, view_layer, ar, v3d, &tbase, dflag_dupli); - GPU_end_dupli_object(); - } - - tbase.object->dt = dt; - tbase.object->dtx = dtx; - tbase.object->transflag = transflag; - tbase.object->currentlod = savedlod; - } - - if (apply_data) { - duplilist_restore(lb, apply_data); - duplilist_free_apply_data(apply_data); - } - - free_object_duplilist(lb); -} - -void draw_dupli_objects(Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer, ARegion *ar, View3D *v3d, Base *base) -{ - /* define the color here so draw_dupli_objects_color can be called - * from the set loop */ - - int color = (base->flag & BASE_SELECTED) ? TH_SELECT : TH_WIRE; - /* debug */ - if (base->object->dup_group && base->object->dup_group->id.us < 1) - color = TH_REDALERT; - - draw_dupli_objects_color(depsgraph, scene, view_layer, ar, v3d, base, 0, color); -} - /* XXX warning, not using gpu offscreen here */ void view3d_update_depths_rect(ARegion *ar, ViewDepths *d, rcti *rect) { @@ -1186,265 +890,9 @@ void ED_view3d_draw_depth_gpencil( if (!zbuf) glDisable(GL_DEPTH_TEST); } -void ED_view3d_draw_depth_loop(Depsgraph *depsgraph, Scene *scene, ARegion *ar, View3D *v3d) -{ - Base *base; - ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph); - /* no need for color when drawing depth buffer */ - const short dflag_depth = DRAW_CONSTCOLOR; - - /* draw set first */ - if (scene->set) { - Scene *sce_iter; - for (SETLOOPER(scene->set, sce_iter, base)) { - if ((base->flag & BASE_VISIBLED) != 0) { - draw_object(depsgraph, scene, view_layer, ar, v3d, base, 0); - if (base->object->transflag & OB_DUPLI) { - draw_dupli_objects_color(depsgraph, scene, view_layer, ar, v3d, base, dflag_depth, TH_UNDEFINED); - } - } - } - } - - for (base = view_layer->object_bases.first; base; base = base->next) { - if ((base->flag & BASE_VISIBLED) != 0) { - /* dupli drawing */ - if (base->object->transflag & OB_DUPLI) { - draw_dupli_objects_color(depsgraph, scene, view_layer, ar, v3d, base, dflag_depth, TH_UNDEFINED); - } - draw_object(depsgraph, scene, view_layer, ar, v3d, base, dflag_depth); - } - } - - /* this isn't that nice, draw xray objects as if they are normal */ - if (v3d->afterdraw_transp.first || - v3d->afterdraw_xray.first || - v3d->afterdraw_xraytransp.first) - { - View3DAfter *v3da; - int mask_orig; - - v3d->xray = true; - - /* transp materials can change the depth mask, see #21388 */ - glGetIntegerv(GL_DEPTH_WRITEMASK, &mask_orig); - - - if (v3d->afterdraw_xray.first || v3d->afterdraw_xraytransp.first) { - glDepthFunc(GL_ALWAYS); /* always write into the depth bufer, overwriting front z values */ - for (v3da = v3d->afterdraw_xray.first; v3da; v3da = v3da->next) { - draw_object(depsgraph, scene, view_layer, ar, v3d, v3da->base, dflag_depth); - } - glDepthFunc(GL_LEQUAL); /* Now write the depth buffer normally */ - } - - /* draw 3 passes, transp/xray/xraytransp */ - v3d->xray = false; - v3d->transp = true; - while ((v3da = BLI_pophead(&v3d->afterdraw_transp))) { - draw_object(depsgraph, scene, view_layer, ar, v3d, v3da->base, dflag_depth); - MEM_freeN(v3da); - } - - v3d->xray = true; - v3d->transp = false; - while ((v3da = BLI_pophead(&v3d->afterdraw_xray))) { - draw_object(depsgraph, scene, view_layer, ar, v3d, v3da->base, dflag_depth); - MEM_freeN(v3da); - } - - v3d->xray = true; - v3d->transp = true; - while ((v3da = BLI_pophead(&v3d->afterdraw_xraytransp))) { - draw_object(depsgraph, scene, view_layer, ar, v3d, v3da->base, dflag_depth); - MEM_freeN(v3da); - } - - - v3d->xray = false; - v3d->transp = false; - - glDepthMask(mask_orig); - } -} - -void ED_view3d_draw_select_loop( - struct Depsgraph *depsgraph, ViewContext *vc, Scene *scene, ViewLayer *view_layer, - View3D *v3d, ARegion *ar, bool use_obedit_skip, bool use_nearest) -{ - struct bThemeState theme_state; - - short code = 1; - const short dflag = DRAW_PICKING | DRAW_CONSTCOLOR; - - /* Tools may request depth outside of regular drawing code. */ - UI_Theme_Store(&theme_state); - UI_SetTheme(SPACE_VIEW3D, RGN_TYPE_WINDOW); - - if (vc->obedit && vc->obedit->type == OB_MBALL) { - draw_object(depsgraph, scene, view_layer, ar, v3d, BASACT(view_layer), dflag); - } - else if ((vc->obedit && vc->obedit->type == OB_ARMATURE)) { - /* if not drawing sketch, draw bones */ - if (!BDR_drawSketchNames(vc)) { - draw_object(depsgraph, scene, view_layer, ar, v3d, BASACT(view_layer), dflag); - } - } - else { - Base *base; - - for (base = view_layer->object_bases.first; base; base = base->next) { - if ((base->flag & BASE_VISIBLED) != 0) { - if (((base->flag & BASE_SELECTABLED) == 0) || - (use_obedit_skip && (vc->obedit->data == base->object->data))) - { - base->object->select_color = 0; - } - else { - base->object->select_color = code; - - if (use_nearest && (base->object->dtx & OB_DRAWXRAY)) { - ED_view3d_after_add(&v3d->afterdraw_xray, base, dflag); - } - else { - if (GPU_select_load_id(code)) { - draw_object(depsgraph, scene, view_layer, ar, v3d, base, dflag); - } - } - code++; - } - } - } - - if (use_nearest) { - bool xrayclear = true; - if (v3d->afterdraw_xray.first) { - view3d_draw_xray_select(depsgraph, scene, view_layer, ar, v3d, &xrayclear); - } - } - } - - UI_Theme_Restore(&theme_state); -} - -typedef struct View3DShadow { - struct View3DShadow *next, *prev; - GPULamp *lamp; -} View3DShadow; - -static void gpu_render_lamp_update(Scene *scene, View3D *v3d, - Object *ob, Object *par, - float obmat[4][4], unsigned int lay, - ListBase *shadows) -{ - GPULamp *lamp = GPU_lamp_from_blender(scene, ob, par); - - if (lamp) { - Lamp *la = (Lamp *)ob->data; - - GPU_lamp_update(lamp, lay, (ob->restrictflag & OB_RESTRICT_RENDER), obmat); - GPU_lamp_update_colors(lamp, la->r, la->g, la->b, la->energy); - - unsigned int layers = lay & v3d->lay; - - if (layers && - GPU_lamp_has_shadow_buffer(lamp) && - /* keep last, may do string lookup */ - GPU_lamp_visible(lamp, NULL)) - { - View3DShadow *shadow = MEM_callocN(sizeof(View3DShadow), "View3DShadow"); - shadow->lamp = lamp; - BLI_addtail(shadows, shadow); - } - } -} - -static void gpu_update_lamps_shadows_world(Depsgraph *depsgraph, Scene *scene, View3D *v3d) -{ - ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph); - ListBase shadows; - Scene *sce_iter; - Base *base; - World *world = scene->world; - - BLI_listbase_clear(&shadows); - - /* update lamp transform and gather shadow lamps */ - for (SETLOOPER(scene, sce_iter, base)) { - Object *ob = base->object; - - if (ob->type == OB_LAMP) - gpu_render_lamp_update(scene, v3d, ob, NULL, ob->obmat, ob->lay, &shadows); - - if (ob->transflag & OB_DUPLI) { - DupliObject *dob; - ListBase *lb = object_duplilist(depsgraph, scene, ob); - - for (dob = lb->first; dob; dob = dob->next) - if (dob->ob->type == OB_LAMP) - gpu_render_lamp_update(scene, v3d, dob->ob, ob, dob->mat, ob->lay, &shadows); - - free_object_duplilist(lb); - } - } - - /* render shadows after updating all lamps, nested object_duplilist - * don't work correct since it's replacing object matrices */ - for (View3DShadow *shadow = shadows.first; shadow; shadow = shadow->next) { - /* this needs to be done better .. */ - float viewmat[4][4], winmat[4][4]; - ARegion ar = {NULL}; - RegionView3D rv3d = {{{0}}}; - - int drawtype = v3d->drawtype; - int lay = v3d->lay; - int flag2 = v3d->flag2; - - v3d->drawtype = OB_SOLID; - v3d->lay &= GPU_lamp_shadow_layer(shadow->lamp); - v3d->flag2 &= ~(V3D_SOLID_TEX | V3D_SHOW_SOLID_MATCAP); - v3d->flag2 |= V3D_RENDER_OVERRIDE | V3D_RENDER_SHADOW; - - int winsize; - GPU_lamp_shadow_buffer_bind(shadow->lamp, viewmat, &winsize, winmat); - - ar.regiondata = &rv3d; - ar.regiontype = RGN_TYPE_WINDOW; - rv3d.persp = RV3D_CAMOB; - copy_m4_m4(rv3d.winmat, winmat); - copy_m4_m4(rv3d.viewmat, viewmat); - invert_m4_m4(rv3d.viewinv, rv3d.viewmat); - mul_m4_m4m4(rv3d.persmat, rv3d.winmat, rv3d.viewmat); - invert_m4_m4(rv3d.persinv, rv3d.viewinv); - - /* no need to call ED_view3d_draw_offscreen_init since shadow buffers were already updated */ - ED_view3d_draw_offscreen( - depsgraph, scene, view_layer, v3d->drawtype, - v3d, &ar, winsize, winsize, viewmat, winmat, - false, false, true, - NULL, NULL, NULL, NULL); - GPU_lamp_shadow_buffer_unbind(shadow->lamp); - - v3d->drawtype = drawtype; - v3d->lay = lay; - v3d->flag2 = flag2; - } - - BLI_freelistN(&shadows); - - /* update world values */ - if (world) { - GPU_mist_update_enable(world->mode & WO_MIST); - GPU_mist_update_values(world->mistype, world->miststa, world->mistdist, world->misi, &world->horr); - GPU_horizon_update_color(&world->horr); - GPU_ambient_update_color(&world->ambr); - GPU_zenith_update_color(&world->zenr); - } -} - /* *********************** customdata **************** */ -CustomDataMask ED_view3d_datamask(const Scene *scene, const View3D *v3d) +CustomDataMask ED_view3d_datamask(const Scene *UNUSED(scene), const View3D *v3d) { CustomDataMask mask = 0; const int drawtype = view3d_effective_drawtype(v3d); @@ -1454,15 +902,8 @@ CustomDataMask ED_view3d_datamask(const Scene *scene, const View3D *v3d) { mask |= CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL; - if (BKE_scene_use_new_shading_nodes(scene)) { - if (drawtype == OB_MATERIAL) - mask |= CD_MASK_ORCO; - } - else { - if (drawtype == OB_MATERIAL) { - mask |= CD_MASK_ORCO; - } - } + if (drawtype == OB_MATERIAL) + mask |= CD_MASK_ORCO; } return mask; @@ -1484,178 +925,6 @@ CustomDataMask ED_view3d_screen_datamask(const Scene *scene, const bScreen *scre } /** - * Shared by #ED_view3d_draw_offscreen and #view3d_main_region_draw_objects - * - * \note \a C and \a grid_unit will be NULL when \a draw_offscreen is set. - * \note Drawing lamps and opengl render uses this, so dont do grease pencil or view widgets here. - */ -static void view3d_draw_objects( - const bContext *C, - Depsgraph *depsgraph, - Scene *scene, View3D *v3d, ARegion *ar, - const char **grid_unit, - const bool do_bgpic, const bool draw_offscreen) -{ - ViewLayer *view_layer = C ? CTX_data_view_layer(C) : BKE_view_layer_from_scene_get(scene); - RegionView3D *rv3d = ar->regiondata; - Base *base; - Object *obedit = OBEDIT_FROM_VIEW_LAYER(view_layer); - const bool do_camera_frame = !draw_offscreen; - const bool draw_grids = !draw_offscreen && (v3d->flag2 & V3D_RENDER_OVERRIDE) == 0; - const bool draw_floor = (rv3d->view == RV3D_VIEW_USER) || (rv3d->persp != RV3D_ORTHO); - /* only draw grids after in solid modes, else it hovers over mesh wires */ - const bool draw_grids_after = draw_grids && draw_floor && (v3d->drawtype > OB_WIRE); - bool xrayclear = true; - - if (!draw_offscreen) { - ED_region_draw_cb_draw(C, ar, REGION_DRAW_PRE_VIEW); - } - - if (rv3d->rflag & RV3D_CLIPPING) - view3d_draw_clipping(rv3d); - - /* set zbuffer after we draw clipping region */ - v3d->zbuf = VP_legacy_use_depth(v3d, obedit); - - if (v3d->zbuf) { - glEnable(GL_DEPTH_TEST); - } - - /* ortho grid goes first, does not write to depth buffer and doesn't need depth test so it will override - * objects if done last */ - if (draw_grids) { - /* needs to be done always, gridview is adjusted in drawgrid() now, but only for ortho views. */ - rv3d->gridview = ED_view3d_grid_scale(scene, v3d, grid_unit); - - if (!draw_floor) { - ED_region_pixelspace(ar); - *grid_unit = NULL; /* drawgrid need this to detect/affect smallest valid unit... */ - VP_legacy_drawgrid(&scene->unit, ar, v3d, grid_unit); - gpuLoadProjectionMatrix(rv3d->winmat); - gpuLoadMatrix(rv3d->viewmat); - } - else if (!draw_grids_after) { - VP_legacy_drawfloor(scene, v3d, grid_unit, true); - } - } - - /* important to do before clipping */ - if (do_bgpic) { - ED_view3d_draw_bgpic_test(scene, depsgraph, ar, v3d, false, do_camera_frame); - } - - if (rv3d->rflag & RV3D_CLIPPING) { - ED_view3d_clipping_set(rv3d); - } - - /* draw set first */ - if (scene->set) { - const short dflag = DRAW_CONSTCOLOR | DRAW_SCENESET; - Scene *sce_iter; - for (SETLOOPER(scene->set, sce_iter, base)) { - if ((base->flag & BASE_VISIBLED) != 0) { - UI_ThemeColorBlend(TH_WIRE, TH_BACK, 0.6f); - draw_object(depsgraph, scene, view_layer, ar, v3d, base, dflag); - - if (base->object->transflag & OB_DUPLI) { - draw_dupli_objects_color(depsgraph, scene, view_layer, ar, v3d, base, dflag, TH_UNDEFINED); - } - } - } - - /* Transp and X-ray afterdraw stuff for sets is done later */ - } - - if (draw_offscreen) { - for (base = view_layer->object_bases.first; base; base = base->next) { - if ((base->flag & BASE_VISIBLED) != 0) { - /* dupli drawing */ - if (base->object->transflag & OB_DUPLI) { - draw_dupli_objects(depsgraph, scene, view_layer, ar, v3d, base); - } - - draw_object(depsgraph, scene, view_layer, ar, v3d, base, 0); - } - } - } - else { - unsigned int lay_used = 0; - - /* then draw not selected and the duplis, but skip editmode object */ - for (base = view_layer->object_bases.first; base; base = base->next) { - lay_used |= base->lay; - - if ((base->flag & BASE_VISIBLED) != 0) { - - /* dupli drawing */ - if (base->object->transflag & OB_DUPLI) { - draw_dupli_objects(depsgraph, scene, view_layer, ar, v3d, base); - } - if ((base->flag & BASE_SELECTED) == 0) { - if (base->object != obedit) - draw_object(depsgraph, scene, view_layer, ar, v3d, base, 0); - } - } - } - - /* mask out localview */ - v3d->lay_used = lay_used & ((1 << 20) - 1); - - /* draw selected and editmode */ - for (base = view_layer->object_bases.first; base; base = base->next) { - if ((base->flag & BASE_VISIBLED) != 0) { - if (base->object == obedit || (base->flag & BASE_SELECTED)) { - draw_object(depsgraph, scene, view_layer, ar, v3d, base, 0); - } - } - } - } - - /* perspective floor goes last to use scene depth and avoid writing to depth buffer */ - if (draw_grids_after) { - VP_legacy_drawfloor(scene, v3d, grid_unit, false); - } - - /* must be before xray draw which clears the depth buffer */ - if (v3d->flag2 & V3D_SHOW_GPENCIL) { - wmWindowManager *wm = (C != NULL) ? CTX_wm_manager(C) : NULL; - - /* must be before xray draw which clears the depth buffer */ - if (v3d->zbuf) glDisable(GL_DEPTH_TEST); - ED_gpencil_draw_view3d(wm, scene, view_layer, depsgraph, v3d, ar, true); - if (v3d->zbuf) glEnable(GL_DEPTH_TEST); - } - - /* transp and X-ray afterdraw stuff */ - if (v3d->afterdraw_transp.first) view3d_draw_transp(depsgraph, scene, view_layer, ar, v3d); - - if (v3d->afterdraw_xray.first) view3d_draw_xray(depsgraph, scene, view_layer, ar, v3d, &xrayclear); - if (v3d->afterdraw_xraytransp.first) view3d_draw_xraytransp(depsgraph, scene, view_layer, ar, v3d, xrayclear); - - if (!draw_offscreen) { - ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW); - } - - if (rv3d->rflag & RV3D_CLIPPING) - ED_view3d_clipping_disable(); - - /* important to do after clipping */ - if (do_bgpic) { - ED_view3d_draw_bgpic_test(scene, depsgraph, ar, v3d, true, do_camera_frame); - } - - /* cleanup */ - if (v3d->zbuf) { - v3d->zbuf = false; - glDisable(GL_DEPTH_TEST); - } - - if ((v3d->flag2 & V3D_RENDER_SHADOW) == 0) { - GPU_free_images_old(); - } -} - -/** * Store values from #RegionView3D, set when drawing. * This is needed when we draw with to a viewport using a different matrix (offscreen drawing for example). * @@ -1800,310 +1069,3 @@ bool ED_view3d_calc_render_border(const Scene *scene, Depsgraph *depsgraph, View return true; } - -/** - * IMPORTANT: this is deprecated, any changes made in this function should - * be mirrored in view3d_draw_render_draw() in view3d_draw.c - */ -static bool view3d_main_region_draw_engine( - const bContext *C, Depsgraph *depsgraph, Scene *scene, - ARegion *ar, View3D *v3d, - bool clip_border, const rcti *border_rect) -{ - RegionView3D *rv3d = ar->regiondata; - RenderEngineType *type; - GLint scissor[4]; - - /* create render engine */ - if (!rv3d->render_engine) { - RenderEngine *engine; - type = RE_engines_find(scene->r.engine); - - if (!(type->view_update && type->render_to_view)) - return false; - - engine = RE_engine_create_ex(type, true); - - engine->tile_x = scene->r.tilex; - engine->tile_y = scene->r.tiley; - - type->view_update(engine, C); - - rv3d->render_engine = engine; - } - - /* setup view matrices */ - VP_legacy_view3d_main_region_setup_view(depsgraph, scene, v3d, ar, NULL, NULL); - - /* background draw */ - ED_region_pixelspace(ar); - - if (clip_border) { - /* for border draw, we only need to clear a subset of the 3d view */ - if (border_rect->xmax > border_rect->xmin && border_rect->ymax > border_rect->ymin) { - glGetIntegerv(GL_SCISSOR_BOX, scissor); - glScissor(border_rect->xmin, border_rect->ymin, - BLI_rcti_size_x(border_rect), BLI_rcti_size_y(border_rect)); - } - else { - return false; - } - } - - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - bool show_image = false; - { - Camera *cam = ED_view3d_camera_data_get(v3d, rv3d); - if (cam->flag & CAM_SHOW_BG_IMAGE) { - show_image = true; - ED_view3d_draw_bgpic_test(scene, depsgraph, ar, v3d, false, true); - } - else { - imm_draw_box_checker_2d(0, 0, ar->winx, ar->winy); - } - } - - if (show_image) { - ED_view3d_draw_bgpic_test(scene, depsgraph, ar, v3d, false, true); - } - else { - imm_draw_box_checker_2d(0, 0, ar->winx, ar->winy); - } - - /* render result draw */ - type = rv3d->render_engine->type; - type->render_to_view(rv3d->render_engine, C); - - if (show_image) { - ED_view3d_draw_bgpic_test(scene, depsgraph, ar, v3d, true, true); - } - - if (clip_border) { - /* restore scissor as it was before */ - glScissor(scissor[0], scissor[1], scissor[2], scissor[3]); - } - - return true; -} - -static void view3d_main_region_draw_engine_info(View3D *v3d, RegionView3D *rv3d, ARegion *ar, bool render_border) -{ - float fill_color[4] = {0.0f, 0.0f, 0.0f, 0.25f}; - - if (!rv3d->render_engine || !rv3d->render_engine->text[0]) - return; - - if (render_border) { - /* draw darkened background color. no alpha because border render does - * partial redraw and will not redraw the region behind this info bar */ - float alpha = 1.0f - fill_color[3]; - Camera *camera = ED_view3d_camera_data_get(v3d, rv3d); - - if (camera) { - if (camera->flag & CAM_SHOWPASSEPARTOUT) { - alpha *= (1.0f - camera->passepartalpha); - } - } - - UI_GetThemeColor3fv(TH_HIGH_GRAD, fill_color); - mul_v3_fl(fill_color, alpha); - fill_color[3] = 1.0f; - } - - ED_region_info_draw(ar, rv3d->render_engine->text, fill_color, true); -} - -static void view3d_main_region_draw_objects(const bContext *C, Scene *scene, ViewLayer *view_layer, View3D *v3d, - ARegion *ar, const char **grid_unit) -{ - wmWindow *win = CTX_wm_window(C); - Depsgraph *depsgraph = CTX_data_depsgraph(C); - RegionView3D *rv3d = ar->regiondata; - unsigned int lay_used = v3d->lay_used; - - /* shadow buffers, before we setup matrices */ - if (draw_glsl_material(scene, view_layer, NULL, v3d, v3d->drawtype)) - gpu_update_lamps_shadows_world(depsgraph, scene, v3d); - - /* reset default OpenGL lights if needed (i.e. after preferences have been altered) */ - if (rv3d->rflag & RV3D_GPULIGHT_UPDATE) { - rv3d->rflag &= ~RV3D_GPULIGHT_UPDATE; - GPU_default_lights(); - } - - /* setup the view matrix */ - if (VP_legacy_view3d_stereo3d_active(win, scene, v3d, rv3d)) { - VP_legacy_view3d_stereo3d_setup(depsgraph, scene, v3d, ar); - } - else { - VP_legacy_view3d_main_region_setup_view(depsgraph, scene, v3d, ar, NULL, NULL); - } - - /* main drawing call */ - view3d_draw_objects(C, depsgraph, scene, v3d, ar, grid_unit, true, false); - - if (v3d->lay_used != lay_used) { /* happens when loading old files or loading with UI load */ - /* find header and force tag redraw */ - ScrArea *sa = CTX_wm_area(C); - ARegion *ar_header = BKE_area_find_region_type(sa, RGN_TYPE_HEADER); - ED_region_tag_redraw(ar_header); /* can be NULL */ - } - - if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { - BDR_drawSketch(C); - } -} - -static void view3d_main_region_draw_info(const bContext *C, Scene *scene, - ARegion *ar, View3D *v3d, - const char *grid_unit, bool render_border) -{ - Depsgraph *depsgraph = CTX_data_depsgraph(C); - ViewLayer *view_layer = CTX_data_view_layer(C); - wmWindowManager *wm = CTX_wm_manager(C); - RegionView3D *rv3d = ar->regiondata; - rcti rect; - - /* local coordinate visible rect inside region, to accomodate overlapping ui */ - ED_region_visible_rect(ar, &rect); - - if (rv3d->persp == RV3D_CAMOB) { - VP_drawviewborder(scene, depsgraph, ar, v3d); - } - else if (v3d->flag2 & V3D_RENDER_BORDER) { - VP_drawrenderborder(ar, v3d); - } - - if (v3d->flag2 & V3D_SHOW_GPENCIL) { - /* draw grease-pencil stuff - needed to get paint-buffer shown too (since it's 2D) */ - ED_gpencil_draw_view3d(wm, scene, view_layer, depsgraph, v3d, ar, false); - } - - if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { - VP_legacy_drawcursor(scene, view_layer, ar, v3d); /* 3D cursor */ - - if (U.uiflag & USER_SHOW_ROTVIEWICON) - VP_legacy_draw_view_axis(rv3d, &rect); - else - draw_view_icon(rv3d, &rect); - - if (U.uiflag & USER_DRAWVIEWINFO) { - Object *ob = OBACT(view_layer); - VP_legacy_draw_selected_name(scene, ob, &rect); - } - } - - if (rv3d->render_engine) { - view3d_main_region_draw_engine_info(v3d, rv3d, ar, render_border); - return; - } - - if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { - if ((U.uiflag & USER_SHOW_FPS) && ED_screen_animation_no_scrub(wm)) { - ED_scene_draw_fps(scene, &rect); - } - else if (U.uiflag & USER_SHOW_VIEWPORTNAME) { - VP_legacy_draw_viewport_name(ar, v3d, &rect); - } - - if (grid_unit) { /* draw below the viewport name */ - char numstr[32] = ""; - - UI_FontThemeColor(BLF_default(), TH_TEXT_HI); - if (v3d->grid != 1.0f) { - BLI_snprintf(numstr, sizeof(numstr), "%s x %.4g", grid_unit, v3d->grid); - } - - BLF_draw_default_ascii(rect.xmin + U.widget_unit, - rect.ymax - (USER_SHOW_VIEWPORTNAME ? 2 * U.widget_unit : U.widget_unit), 0.0f, - numstr[0] ? numstr : grid_unit, sizeof(numstr)); - } - } -} - -void view3d_main_region_draw_legacy(const bContext *C, ARegion *ar) -{ - Depsgraph *depsgraph = CTX_data_depsgraph(C); - Scene *scene = CTX_data_scene(C); - ViewLayer *view_layer = CTX_data_view_layer(C); - View3D *v3d = CTX_wm_view3d(C); - const char *grid_unit = NULL; - rcti border_rect; - - /* if we only redraw render border area, skip opengl draw and also - * don't do scissor because it's already set */ - bool render_border = ED_view3d_calc_render_border(scene, depsgraph, v3d, ar, &border_rect); - bool clip_border = (render_border && !BLI_rcti_compare(&ar->drawrct, &border_rect)); - - gpuPushProjectionMatrix(); - gpuLoadIdentityProjectionMatrix(); - gpuPushMatrix(); - gpuLoadIdentity(); - - /* draw viewport using opengl */ - if (v3d->drawtype != OB_RENDER || !view3d_main_region_do_render_draw(scene) || clip_border) { - VP_view3d_main_region_clear(scene, v3d, ar); /* background */ - view3d_main_region_draw_objects(C, scene, view_layer, v3d, ar, &grid_unit); - - if (G.debug & G_DEBUG_SIMDATA) - draw_sim_debug_data(scene, v3d, ar); - - glDisable(GL_DEPTH_TEST); - ED_region_pixelspace(ar); - } - - /* draw viewport using external renderer */ - if (v3d->drawtype == OB_RENDER) { - view3d_main_region_draw_engine(C, depsgraph, scene, ar, v3d, clip_border, &border_rect); - } - - VP_legacy_view3d_main_region_setup_view(depsgraph, scene, v3d, ar, NULL, NULL); - glClear(GL_DEPTH_BUFFER_BIT); - - WM_manipulatormap_draw(ar->manipulator_map, C, WM_MANIPULATORMAP_DRAWSTEP_3D); - - ED_region_pixelspace(ar); - - view3d_main_region_draw_info(C, scene, ar, v3d, grid_unit, render_border); - - WM_manipulatormap_draw(ar->manipulator_map, C, WM_MANIPULATORMAP_DRAWSTEP_2D); - - gpuPopProjectionMatrix(); - gpuPopMatrix(); - - v3d->flag |= V3D_INVALID_BACKBUF; - - BLI_assert(BLI_listbase_is_empty(&v3d->afterdraw_transp)); - BLI_assert(BLI_listbase_is_empty(&v3d->afterdraw_xray)); - BLI_assert(BLI_listbase_is_empty(&v3d->afterdraw_xraytransp)); -} - - -/* -------------------------------------------------------------------- */ - -/** \name Deprecated Interface - * - * New viewport sometimes has a check for new/old viewport code. - * Use these functions so new viewport can *optionally* call. - * - * \{ */ - - -void VP_deprecated_view3d_draw_objects( - const bContext *C, - Depsgraph *depsgraph, - Scene *scene, View3D *v3d, ARegion *ar, - const char **grid_unit, - const bool do_bgpic, const bool draw_offscreen) -{ - view3d_draw_objects(C, depsgraph, scene, v3d, ar, grid_unit, do_bgpic, draw_offscreen); -} - -void VP_deprecated_gpu_update_lamps_shadows_world(Depsgraph *depsgraph, Scene *scene, View3D *v3d) -{ - gpu_update_lamps_shadows_world(depsgraph, scene, v3d); -} - -/** \} */ diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h index 64927ff55c7..58bf05299ea 100644 --- a/source/blender/editors/space_view3d/view3d_intern.h +++ b/source/blender/editors/space_view3d/view3d_intern.h @@ -63,12 +63,6 @@ enum { DRAW_SCENESET = (1 << 2) }; -/* draw_mesh_fancy/draw_mesh_textured draw_flags */ -enum { - DRAW_MODIFIERS_PREVIEW = (1 << 0), - DRAW_FACE_SELECT = (1 << 1) -}; - /* view3d_header.c */ void VIEW3D_OT_layers(struct wmOperatorType *ot); @@ -138,84 +132,11 @@ void VIEW3D_OT_walk(struct wmOperatorType *ot); /* view3d_ruler.c */ void VIEW3D_OT_ruler(struct wmOperatorType *ot); -/* drawanim.c */ -void draw_motion_paths_init(View3D *v3d, struct ARegion *ar); -void draw_motion_path_instance(Scene *scene, - struct Object *ob, struct bPoseChannel *pchan, - struct bAnimVizSettings *avs, struct bMotionPath *mpath); -void draw_motion_paths_cleanup(View3D *v3d); - - - /* drawobject.c */ -void draw_object( - struct Depsgraph *depsgraph, Scene *scene, struct ViewLayer *view_layer, struct ARegion *ar, View3D *v3d, - struct Base *base, const short dflag); -void draw_object_select( - struct Depsgraph *depsgraph, Scene *scene, struct ViewLayer *view_layer, struct ARegion *ar, View3D *v3d, - Base *base, const short dflag); - -void draw_mesh_object_outline(View3D *v3d, struct Object *ob, struct DerivedMesh *dm, const unsigned char ob_wire_col[4]); - -bool draw_glsl_material(Scene *scene, struct ViewLayer *view_layer, struct Object *ob, View3D *v3d, const char dt); -void draw_object_instance(struct Depsgraph *depsgraph, Scene *scene, struct ViewLayer *view_layer, View3D *v3d, RegionView3D *rv3d, struct Object *ob, const char dt, int outline, const float wire_col[4]); void draw_object_backbufsel(struct Depsgraph *depsgraph, Scene *scene, View3D *v3d, RegionView3D *rv3d, struct Object *ob); -void draw_object_wire_color(struct ViewLayer *, Base *base, unsigned char r_ob_wire_col[4]); -void drawaxes(const float viewmat_local[4][4], float size, char drawtype, const unsigned char color[4]); -void drawlamp(View3D *v3d, RegionView3D *rv3d, Base *base, - const char dt, const short dflag, const unsigned char ob_wire_col[4], - const bool is_obact); -void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, - const short dflag, const unsigned char ob_wire_col[4]); -void drawspeaker(const unsigned char ob_wire_col[3]); -void draw_bounding_volume(struct Object *ob, char type, const unsigned char ob_wire_col[4]); -void draw_rigidbody_shape(struct Object *ob, const unsigned char ob_wire_col[4]); - -void view3d_cached_text_draw_begin(void); -void view3d_cached_text_draw_add(const float co[3], - const char *str, const size_t str_len, - short xoffs, short flag, const unsigned char col[4]); -void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, bool depth_write); - -bool check_object_draw_texture(struct Scene *scene, struct View3D *v3d, const char drawtype); - -enum { - V3D_CACHE_TEXT_ZBUF = (1 << 0), - V3D_CACHE_TEXT_WORLDSPACE = (1 << 1), - V3D_CACHE_TEXT_ASCII = (1 << 2), - V3D_CACHE_TEXT_GLOBALSPACE = (1 << 3), - V3D_CACHE_TEXT_LOCALCLIP = (1 << 4) -}; - int view3d_effective_drawtype(const struct View3D *v3d); -/* drawarmature.c */ -bool draw_armature( - struct Depsgraph *depsgraph, Scene *scene, struct ViewLayer *view_layer, View3D *v3d, ARegion *ar, Base *base, - const short dt, const short dflag, const unsigned char ob_wire_col[4], - const bool is_outline); - -/* drawmesh.c */ -void draw_mesh_textured(Scene *scene, struct ViewLayer *view_layer, View3D *v3d, RegionView3D *rv3d, - struct Object *ob, struct DerivedMesh *dm, const int draw_flags); -void draw_mesh_face_select( - struct RegionView3D *rv3d, struct Mesh *me, struct DerivedMesh *dm, - bool draw_select_edges); -void draw_mesh_paint_weight_faces(struct DerivedMesh *dm, const bool do_light, - void *facemask_cb, void *user_data); -void draw_mesh_paint_vcolor_faces(struct DerivedMesh *dm, const bool use_light, - void *facemask_cb, void *user_data, - const struct Mesh *me); -void draw_mesh_paint_weight_edges(RegionView3D *rv3d, struct DerivedMesh *dm, - const bool use_depth, const bool use_alpha, - void *edgemask_cb, void *user_data); -void draw_mesh_paint(View3D *v3d, RegionView3D *rv3d, - struct Object *ob, struct DerivedMesh *dm, const int draw_flags); - -/* drawsimdebug.c */ -void draw_sim_debug_data(Scene *scene, View3D *v3d, ARegion *ar); - /* view3d_draw.c */ void view3d_main_region_draw(const struct bContext *C, struct ARegion *ar); void view3d_draw_region_info(const struct bContext *C, struct ARegion *ar, const int offset); @@ -225,7 +146,6 @@ void ED_view3d_draw_depth( struct ARegion *ar, View3D *v3d, bool alphaoverride); /* view3d_draw_legacy.c */ -void view3d_main_region_draw_legacy(const struct bContext *C, struct ARegion *ar); void ED_view3d_draw_depth_gpencil(struct Depsgraph *depsgraph, Scene *scene, ARegion *ar, View3D *v3d); void ED_view3d_draw_select_loop( @@ -365,31 +285,4 @@ extern unsigned char view3d_camera_border_hack_col[3]; extern bool view3d_camera_border_hack_test; #endif -/* temporary for legacy viewport to work */ -void VP_legacy_drawcursor(Scene *scene, struct ViewLayer *view_layer, ARegion *ar, View3D *v3d); -void VP_legacy_draw_view_axis(RegionView3D *rv3d, const rcti *rect); -void VP_legacy_draw_viewport_name(ARegion *ar, View3D *v3d, const rcti *rect); -void VP_legacy_draw_selected_name(Scene *scene, struct Object *ob, rcti *rect); -void VP_legacy_drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, const char **grid_unit); -void VP_legacy_drawfloor(Scene *scene, View3D *v3d, const char **grid_unit, bool write_depth); -void VP_legacy_view3d_main_region_setup_view(struct Depsgraph *depsgraph, Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4]); -bool VP_legacy_view3d_stereo3d_active(struct wmWindow *win, Scene *scene, View3D *v3d, RegionView3D *rv3d); -void VP_legacy_view3d_stereo3d_setup(struct Depsgraph *depsgraph, Scene *scene, View3D *v3d, ARegion *ar); -void draw_dupli_objects(struct Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer, ARegion *ar, View3D *v3d, Base *base); -bool VP_legacy_use_depth(View3D *v3d, struct Object *obedit); -void VP_drawviewborder(Scene *scene, struct Depsgraph *depsgraph, ARegion *ar, View3D *v3d); -void VP_drawrenderborder(ARegion *ar, View3D *v3d); -void VP_view3d_draw_background_none(void); -void VP_view3d_draw_background_world(Scene *scene, RegionView3D *rv3d); -void VP_view3d_main_region_clear(Scene *scene, View3D *v3d, ARegion *ar); - -/* temporary legacy calls, only when there is a switch between new/old draw calls */ -void VP_deprecated_gpu_update_lamps_shadows_world(struct Depsgraph *depsgraph, Scene *scene, View3D *v3d); -void VP_deprecated_view3d_draw_objects( - const struct bContext *C, - struct Depsgraph *depsgraph, - Scene *scene, View3D *v3d, ARegion *ar, - const char **grid_unit, - const bool do_bgpic, const bool draw_offscreen); - #endif /* __VIEW3D_INTERN_H__ */ diff --git a/source/blender/editors/undo/ed_undo.c b/source/blender/editors/undo/ed_undo.c index 0b77006afb7..18366f87b59 100644 --- a/source/blender/editors/undo/ed_undo.c +++ b/source/blender/editors/undo/ed_undo.c @@ -336,8 +336,6 @@ int ED_undo_operator_repeat(bContext *C, struct wmOperator *op) { int retval; - ED_viewport_render_kill_jobs(wm, CTX_data_main(C), true); - if (G.debug & G_DEBUG) printf("redo_cb: operator redo %s\n", op->type->name); diff --git a/source/blender/editors/undo/memfile_undo.c b/source/blender/editors/undo/memfile_undo.c index 511f4bc72f1..d45470ab0a1 100644 --- a/source/blender/editors/undo/memfile_undo.c +++ b/source/blender/editors/undo/memfile_undo.c @@ -85,8 +85,6 @@ static void memfile_undosys_step_decode(struct bContext *C, UndoStep *us_p, int /* Loading the content will correctly switch into compatible non-object modes. */ ED_object_mode_set(C, OB_MODE_OBJECT); - /* This is needed so undoing/redoing doesn't crash with threaded previews going */ - ED_viewport_render_kill_jobs(CTX_wm_manager(C), CTX_data_main(C), true); MemFileUndoStep *us = (MemFileUndoStep *)us_p; BKE_memfile_undo_decode(us->data, C); diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c index bcdc8193137..945d30eabb5 100644 --- a/source/blender/editors/uvedit/uvedit_draw.c +++ b/source/blender/editors/uvedit/uvedit_draw.c @@ -436,43 +436,8 @@ static void draw_uvs_lineloop_mpoly(Mesh *me, MPoly *mpoly, unsigned int pos) immEnd(); } -static void draw_uvs_other_mesh_texface(Object *ob, const Image *curimage, const int other_uv_filter, unsigned int pos) -{ - Mesh *me = ob->data; - MPoly *mpoly = me->mpoly; - int a; - - if (me->mloopuv == NULL) { - return; - } - - Image **image_array = NULL; - - if (other_uv_filter == SI_FILTER_SAME_IMAGE) { - image_array = BKE_object_material_edit_image_get_array(ob); - } - - for (a = me->totpoly; a != 0; a--, mpoly++) { - if (other_uv_filter == SI_FILTER_ALL) { - /* Nothing to compare, all UV faces are visible. */ - } - else if (other_uv_filter == SI_FILTER_SAME_IMAGE) { - if (mpoly[a].mat_nr >= ob->totcol) { - continue; - } - if (image_array[mpoly[a].mat_nr] != curimage) { - continue; - } - } - - draw_uvs_lineloop_mpoly(me, mpoly, pos); - } - - if (image_array) { - MEM_freeN(image_array); - } -} -static void draw_uvs_other_mesh_new_shading(Object *ob, const Image *curimage, const int other_uv_filter, unsigned int pos) +static void draw_uvs_other_mesh(Object *ob, const Image *curimage, + const int other_uv_filter, unsigned int pos) { Mesh *me = ob->data; MPoly *mpoly = me->mpoly; @@ -527,18 +492,8 @@ static void draw_uvs_other_mesh_new_shading(Object *ob, const Image *curimage, c draw_uvs_lineloop_mpoly(me, mpoly, pos); } } -static void draw_uvs_other_mesh(Object *ob, const Image *curimage, const bool new_shading_nodes, - const int other_uv_filter, unsigned int pos) -{ - if (new_shading_nodes) { - draw_uvs_other_mesh_new_shading(ob, curimage, other_uv_filter, pos); - } - else { - draw_uvs_other_mesh_texface(ob, curimage, other_uv_filter, pos); - } -} -static void draw_uvs_other(ViewLayer *view_layer, Object *obedit, const Image *curimage, const bool new_shading_nodes, +static void draw_uvs_other(ViewLayer *view_layer, Object *obedit, const Image *curimage, const int other_uv_filter) { unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); @@ -553,7 +508,7 @@ static void draw_uvs_other(ViewLayer *view_layer, Object *obedit, const Image *c { Object *ob = base->object; if ((ob->type == OB_MESH) && (ob != obedit) && ((Mesh *)ob->data)->mloopuv) { - draw_uvs_other_mesh(ob, curimage, new_shading_nodes, other_uv_filter, pos); + draw_uvs_other_mesh(ob, curimage, other_uv_filter, pos); } } } @@ -562,13 +517,12 @@ static void draw_uvs_other(ViewLayer *view_layer, Object *obedit, const Image *c static void draw_uvs_texpaint(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Object *ob) { - const bool new_shading_nodes = BKE_scene_use_new_shading_nodes(scene); Image *curimage = ED_space_image(sima); Mesh *me = ob->data; Material *ma; if (sima->flag & SI_DRAW_OTHER) { - draw_uvs_other(view_layer, ob, curimage, new_shading_nodes, sima->other_uv_filter); + draw_uvs_other(view_layer, ob, curimage, sima->other_uv_filter); } ma = give_current_material(ob, ob->actcol); @@ -627,7 +581,6 @@ static void draw_uvs_looptri(BMEditMesh *em, unsigned int *r_loop_index, const i /* draws uv's in the image space */ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Object *obedit, Depsgraph *depsgraph) { - const bool new_shading_nodes = BKE_scene_use_new_shading_nodes(scene); ToolSettings *ts; Mesh *me = obedit->data; BMEditMesh *em = me->edit_btmesh; @@ -658,19 +611,14 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje if (sima->flag & SI_DRAW_OTHER) { Image *curimage; - if (new_shading_nodes) { - if (efa_act) { - ED_object_get_active_image(obedit, efa_act->mat_nr + 1, &curimage, NULL, NULL, NULL); - } - else { - curimage = ima; - } + if (efa_act) { + ED_object_get_active_image(obedit, efa_act->mat_nr + 1, &curimage, NULL, NULL, NULL); } else { - curimage = (efa_act) ? BKE_object_material_edit_image_get(obedit, efa_act->mat_nr) : ima; + curimage = ima; } - draw_uvs_other(view_layer, obedit, curimage, new_shading_nodes, sima->other_uv_filter); + draw_uvs_other(view_layer, obedit, curimage, sima->other_uv_filter); } /* 1. draw shadow mesh */ diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index 06b408a04ae..6fa75b0a2b3 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -195,93 +195,6 @@ void ED_object_assign_active_image(Main *bmain, Object *ob, int mat_nr, Image *i //#define USE_SWITCH_ASPECT -void ED_uvedit_assign_image(Main *UNUSED(bmain), Scene *scene, Object *obedit, Image *ima, Image *previma) -{ - BMEditMesh *em; - BMIter iter; - bool update = false; - const bool selected = !(scene->toolsettings->uv_flag & UV_SYNC_SELECTION); - - /* skip assigning these procedural images... */ - if (ima && (ima->type == IMA_TYPE_R_RESULT || ima->type == IMA_TYPE_COMPOSITE)) - return; - - /* verify we have a mesh we can work with */ - if (!obedit || (obedit->type != OB_MESH)) - return; - - em = BKE_editmesh_from_object(obedit); - if (!em || !em->bm->totface) { - return; - } - - if (BKE_scene_use_new_shading_nodes(scene)) { - /* new shading system, do not assign anything */ - } - else { - BMFace *efa; - - int cd_loop_uv_offset; - /* old shading system, assign image to selected faces */ -#ifdef USE_SWITCH_ASPECT - float prev_aspect[2], fprev_aspect; - float aspect[2], faspect; - - ED_image_get_uv_aspect(previma, prev_aspect, prev_aspect + 1); - ED_image_get_uv_aspect(ima, aspect, aspect + 1); - - fprev_aspect = prev_aspect[0] / prev_aspect[1]; - faspect = aspect[0] / aspect[1]; -#endif - - /* ensure we have a uv map */ - if (!CustomData_has_layer(&em->bm->ldata, CD_MLOOPUV)) { - BM_data_layer_add(em->bm, &em->bm->ldata, CD_MLOOPUV); - /* make UVs all nice 0-1 */ - ED_mesh_uv_loop_reset_ex(obedit->data, CustomData_get_active_layer(&em->bm->ldata, CD_MLOOPUV)); - update = true; - } - - cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); - - /* now assign to all visible faces */ - BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { - if (uvedit_face_visible_test(scene, obedit, previma, efa) && - (selected == true || uvedit_face_select_test(scene, efa, cd_loop_uv_offset))) - { -#ifdef USE_SWITCH_ASPECT - if (ima) { - /* we also need to correct the aspect of uvs */ - if (scene->toolsettings->uvcalc_flag & UVCALC_NO_ASPECT_CORRECT) { - /* do nothing */ - } - else { - BMIter liter; - BMLoop *l; - - BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - - luv->uv[0] *= fprev_aspect; - luv->uv[0] /= faspect; - } - } - } -#endif - BKE_object_material_edit_image_set(obedit, efa->mat_nr, ima); - - update = true; - } - } - - /* and update depdency graph */ - if (update) { - DEG_id_tag_update(obedit->data, 0); - } - } - -} - /** \} */ /* -------------------------------------------------------------------- */ @@ -340,7 +253,8 @@ bool uvedit_face_visible_test(Scene *scene, Object *obedit, Image *ima, BMFace * ToolSettings *ts = scene->toolsettings; if (ts->uv_flag & UV_SHOW_SAME_IMAGE) { - const Image *face_image = BKE_object_material_edit_image_get(obedit, efa->mat_nr); + Image *face_image; + ED_object_get_active_image(obedit, efa->mat_nr + 1, &face_image, NULL, NULL, NULL); return (face_image == ima) ? uvedit_face_visible_nolocal(scene, efa) : false; } else { diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c index 7c87905775b..1442266a3aa 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c @@ -103,9 +103,8 @@ static void modifier_unwrap_state(Object *obedit, Scene *scene, bool *r_use_subs *r_use_subsurf = subsurf; } -static bool ED_uvedit_ensure_uvs(bContext *C, Scene *scene, Object *obedit) +static bool ED_uvedit_ensure_uvs(bContext *C, Scene *UNUSED(scene), Object *obedit) { - Main *bmain = CTX_data_main(C); BMEditMesh *em = BKE_editmesh_from_object(obedit); BMFace *efa; BMIter iter; @@ -149,9 +148,6 @@ static bool ED_uvedit_ensure_uvs(bContext *C, Scene *scene, Object *obedit) } } - if (ima) - ED_uvedit_assign_image(bmain, scene, obedit, ima, NULL); - /* select new UV's (ignore UV_SYNC_SELECTION in this case) */ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { BMIter liter; @@ -218,7 +214,7 @@ static bool uvedit_have_selection_multi( return have_select; } -void ED_uvedit_get_aspect(Scene *scene, Object *ob, BMesh *bm, float *aspx, float *aspy) +void ED_uvedit_get_aspect(Scene *UNUSED(scene), Object *ob, BMesh *bm, float *aspx, float *aspy) { bool sloppy = true; bool selected = false; @@ -228,12 +224,7 @@ void ED_uvedit_get_aspect(Scene *scene, Object *ob, BMesh *bm, float *aspx, floa efa = BM_mesh_active_face_get(bm, sloppy, selected); if (efa) { - if (BKE_scene_use_new_shading_nodes(scene)) { - ED_object_get_active_image(ob, efa->mat_nr + 1, &ima, NULL, NULL, NULL); - } - else { - ima = BKE_object_material_edit_image_get(ob, efa->mat_nr); - } + ED_object_get_active_image(ob, efa->mat_nr + 1, &ima, NULL, NULL, NULL); ED_image_get_uv_aspect(ima, NULL, aspx, aspy); } diff --git a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp index 29d14442a47..d571ca135a1 100644 --- a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp +++ b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp @@ -425,19 +425,8 @@ void BlenderFileLoader::insertShapeNode(Object *ob, Mesh *me, int id) float v1[3], v2[3], v3[3]; float n1[3], n2[3], n3[3], facenormal[3]; int clip[3]; - int wire_material = 0; for (int a = 0; a < tottri; a++) { const MLoopTri *lt = &mlooptri[a]; - const MPoly *mp = &mpoly[lt->poly]; - Material *mat = give_current_material(ob, mp->mat_nr + 1); - - if (mat && mat->mode & MA_ONLYCAST) { - continue; - } - if (mat && mat->material_type == MA_TYPE_WIRE) { - wire_material = 1; - continue; - } copy_v3_v3(v1, mvert[mloop[lt->tri[0]].v].co); copy_v3_v3(v2, mvert[mloop[lt->tri[1]].v].co); @@ -453,11 +442,6 @@ void BlenderFileLoader::insertShapeNode(Object *ob, Mesh *me, int id) numFaces += countClippedFaces(v1, v2, v3, clip); } - if (wire_material) { - if (G.debug & G_DEBUG_FREESTYLE) { - cout << "Warning: Object " << name << " has wire materials (ignored)" << endl; - } - } #if 0 if (G.debug & G_DEBUG_FREESTYLE) { cout << "numFaces " << numFaces << endl; @@ -514,9 +498,6 @@ void BlenderFileLoader::insertShapeNode(Object *ob, Mesh *me, int id) const MPoly *mp = &mpoly[lt->poly]; Material *mat = give_current_material(ob, mp->mat_nr + 1); - if (mat && ((mat->mode & MA_ONLYCAST) || mat->material_type == MA_TYPE_WIRE)) - continue; - copy_v3_v3(v1, mvert[mloop[lt->tri[0]].v].co); copy_v3_v3(v2, mvert[mloop[lt->tri[1]].v].co); copy_v3_v3(v3, mvert[mloop[lt->tri[2]].v].co); @@ -566,11 +547,8 @@ void BlenderFileLoader::insertShapeNode(Object *ob, Mesh *me, int id) if (mat) { tmpMat.setLine(mat->line_col[0], mat->line_col[1], mat->line_col[2], mat->line_col[3]); tmpMat.setDiffuse(mat->r, mat->g, mat->b, mat->alpha); - tmpMat.setSpecular(mat->specr, mat->specg, mat->specb, mat->spectra); - float s = 1.0 * (mat->har + 1) / 4 ; // in Blender: [1;511] => in OpenGL: [0;128] - if (s > 128.f) - s = 128.f; - tmpMat.setShininess(s); + tmpMat.setSpecular(mat->specr, mat->specg, mat->specb, 1.0f); + tmpMat.setShininess(128.f); tmpMat.setPriority(mat->line_priority); } diff --git a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.h b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.h index f9a8c787c08..0542b7f45fd 100644 --- a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.h +++ b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.h @@ -49,7 +49,6 @@ extern "C" { #include "DNA_object_types.h" #include "DNA_scene_types.h" -#include "renderdatabase.h" #include "render_types.h" #include "BKE_customdata.h" diff --git a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp index 2de1050e167..06f62f5a5dc 100644 --- a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp +++ b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp @@ -89,7 +89,7 @@ BlenderStrokeRenderer::BlenderStrokeRenderer(Render *re, int render_count) : Str freestyle_scene = BKE_scene_add(freestyle_bmain, name); freestyle_scene->r.cfra = old_scene->r.cfra; freestyle_scene->r.mode = old_scene->r.mode & - ~(R_EDGE_FRS | R_SHADOW | R_SSS | R_PANORAMA | R_ENVMAP | R_MBLUR | R_BORDER); + ~(R_EDGE_FRS | R_PANORAMA | R_MBLUR | R_BORDER); freestyle_scene->r.xsch = re->rectx; // old_scene->r.xsch freestyle_scene->r.ysch = re->recty; // old_scene->r.ysch freestyle_scene->r.xasp = 1.0f; // old_scene->r.xasp; @@ -97,8 +97,6 @@ BlenderStrokeRenderer::BlenderStrokeRenderer(Render *re, int render_count) : Str freestyle_scene->r.tilex = old_scene->r.tilex; freestyle_scene->r.tiley = old_scene->r.tiley; freestyle_scene->r.size = 100; // old_scene->r.size - //freestyle_scene->r.maximsize = old_scene->r.maximsize; /* DEPRECATED */ - freestyle_scene->r.ocres = old_scene->r.ocres; freestyle_scene->r.color_mgt_flag = 0; // old_scene->r.color_mgt_flag; freestyle_scene->r.scemode = old_scene->r.scemode & ~(R_SINGLE_LAYER | R_NO_FRAME_UPDATE | R_MULTIVIEW); freestyle_scene->r.flag = old_scene->r.flag; @@ -112,9 +110,6 @@ BlenderStrokeRenderer::BlenderStrokeRenderer(Render *re, int render_count) : Str freestyle_scene->r.safety.ymin = old_scene->r.safety.ymin; freestyle_scene->r.safety.xmax = old_scene->r.safety.xmax; freestyle_scene->r.safety.ymax = old_scene->r.safety.ymax; - freestyle_scene->r.osa = old_scene->r.osa; - freestyle_scene->r.filtertype = old_scene->r.filtertype; - freestyle_scene->r.gauss = old_scene->r.gauss; freestyle_scene->r.dither_intensity = old_scene->r.dither_intensity; STRNCPY(freestyle_scene->r.engine, old_scene->r.engine); if (G.debug & G_DEBUG_FREESTYLE) { @@ -167,14 +162,8 @@ BlenderStrokeRenderer::BlenderStrokeRenderer(Render *re, int render_count) : Str // Reset serial mesh ID (used for BlenderStrokeRenderer::NewMesh()) _mesh_id = 0xffffffff; - // Check if the rendering engine uses new shading nodes - _use_shading_nodes = BKE_scene_use_new_shading_nodes(freestyle_scene); - // Create a bNodeTree-to-Material hash table - if (_use_shading_nodes) - _nodetree_hash = BLI_ghash_ptr_new("BlenderStrokeRenderer::_nodetree_hash"); - else - _nodetree_hash = NULL; + _nodetree_hash = BLI_ghash_ptr_new("BlenderStrokeRenderer::_nodetree_hash"); // Depsgraph freestyle_depsgraph = DEG_graph_new(freestyle_scene, view_layer, DAG_EVAL_RENDER); @@ -230,21 +219,11 @@ BlenderStrokeRenderer::~BlenderStrokeRenderer() while (lnk) { Material *ma = (Material*)lnk; - // We want to retain the linestyle mtexs, so let's detach them first - for (int a = 0; a < MAX_MTEX; a++) { - if (ma->mtex[a]) { - ma->mtex[a] = NULL; - } - else { - break; // Textures are ordered, no empty slots between two textures - } - } lnk = lnk->next; BKE_libblock_free(freestyle_bmain, ma); } - if (_use_shading_nodes) - BLI_ghash_free(_nodetree_hash, NULL, NULL); + BLI_ghash_free(_nodetree_hash, NULL, NULL); DEG_graph_free(freestyle_depsgraph); @@ -488,67 +467,13 @@ void BlenderStrokeRenderer::RenderStrokeRep(StrokeRep *iStrokeRep) const void BlenderStrokeRenderer::RenderStrokeRepBasic(StrokeRep *iStrokeRep) const { - if (_use_shading_nodes) { - bNodeTree *nt = iStrokeRep->getNodeTree(); - Material *ma = (Material *)BLI_ghash_lookup(_nodetree_hash, nt); - if (!ma) { - ma = BlenderStrokeRenderer::GetStrokeShader(freestyle_bmain, nt, false); - BLI_ghash_insert(_nodetree_hash, nt, ma); - } - iStrokeRep->setMaterial(ma); - } - else { - bool has_mat = false; - int a = 0; - - // Look for a good existing material - for (Link *lnk = (Link *)freestyle_bmain->mat.first; lnk; lnk = lnk->next) { - Material *ma = (Material*)lnk; - bool texs_are_good = true; - // as soon as textures differ it's not the right one - for (int a = 0; a < MAX_MTEX; a++) { - if (ma->mtex[a] != iStrokeRep->getMTex(a)) { - texs_are_good = false; - break; - } - } - - if (texs_are_good) { - iStrokeRep->setMaterial(ma); - has_mat = true; - break; // if textures are good, no need to search anymore - } - } - - // If still no material, create one - if (!has_mat) { - Material *ma = BKE_material_add(freestyle_bmain, "stroke_material"); - DEG_relations_tag_update(freestyle_bmain); - ma->mode |= MA_VERTEXCOLP; - ma->mode |= MA_TRANSP; - ma->mode |= MA_SHLESS; - ma->vcol_alpha = 1; - - id_us_min(&ma->id); - - // Textures - while (iStrokeRep->getMTex(a)) { - ma->mtex[a] = (MTex *)iStrokeRep->getMTex(a); - - // We'll generate both with tips and without tips - // coordinates, on two different UV layers. - if (ma->mtex[a]->texflag & MTEX_TIPS) { - BLI_strncpy(ma->mtex[a]->uvname, uvNames[1], sizeof(ma->mtex[a]->uvname)); - } - else { - BLI_strncpy(ma->mtex[a]->uvname, uvNames[0], sizeof(ma->mtex[a]->uvname)); - } - a++; - } - - iStrokeRep->setMaterial(ma); - } + bNodeTree *nt = iStrokeRep->getNodeTree(); + Material *ma = (Material *)BLI_ghash_lookup(_nodetree_hash, nt); + if (!ma) { + ma = BlenderStrokeRenderer::GetStrokeShader(freestyle_bmain, nt, false); + BLI_ghash_insert(_nodetree_hash, nt, ma); } + iStrokeRep->setMaterial(ma); const vector<Strip*>& strips = iStrokeRep->getStrips(); const bool hasTex = iStrokeRep->hasTex(); diff --git a/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp b/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp index e2560a33443..75687edd9f6 100644 --- a/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp +++ b/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp @@ -58,12 +58,12 @@ extern "C" { #include "BLI_blenlib.h" #include "BLI_math.h" +#include "BLI_math_color_blend.h" #include "BLI_callbacks.h" #include "BPY_extern.h" #include "renderpipeline.h" -#include "pixelblending.h" #include "FRS_freestyle.h" @@ -530,7 +530,7 @@ void FRS_composite_result(Render *re, ViewLayer *view_layer, Render *freestyle_r pixSrc = src + 4 * (rectx * y + x); if (pixSrc[3] > 0.0) { pixDest = dest + 4 * (rectx * y + x); - addAlphaOverFloat(pixDest, pixSrc); + blend_color_mix_float(pixDest, pixDest, pixSrc); } } } diff --git a/source/blender/freestyle/intern/stroke/Stroke.h b/source/blender/freestyle/intern/stroke/Stroke.h index db96a27e073..c004d73e6fe 100644 --- a/source/blender/freestyle/intern/stroke/Stroke.h +++ b/source/blender/freestyle/intern/stroke/Stroke.h @@ -44,8 +44,7 @@ #endif extern "C" { -#include "DNA_material_types.h" - +struct MTex; struct bNodeTree; } diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index 94b27c8f916..c3ef9d18f13 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -62,7 +62,6 @@ set(SRC intern/gpu_immediate.c intern/gpu_immediate_util.c intern/gpu_init_exit.c - intern/gpu_lamp.c intern/gpu_material.c intern/gpu_matrix.c intern/gpu_select.c @@ -105,7 +104,6 @@ set(SRC GPU_immediate.h GPU_immediate_util.h GPU_init_exit.h - GPU_lamp.h GPU_legacy_stubs.h GPU_material.h GPU_matrix.h @@ -117,7 +115,6 @@ set(SRC intern/gpu_codegen.h intern/gpu_private.h - intern/gpu_lamp_private.h intern/gpu_select_private.h intern/gpu_shader_private.h ) diff --git a/source/blender/gpu/GPU_buffers.h b/source/blender/gpu/GPU_buffers.h index 0d8a7a45ee9..f496c92f283 100644 --- a/source/blender/gpu/GPU_buffers.h +++ b/source/blender/gpu/GPU_buffers.h @@ -32,192 +32,19 @@ #ifndef __GPU_BUFFERS_H__ #define __GPU_BUFFERS_H__ -#ifdef DEBUG -/* #define DEBUG_VBO(X) printf(X)*/ -# define DEBUG_VBO(X) -#else -# define DEBUG_VBO(X) -#endif - #include <stddef.h> struct BMesh; struct CCGElem; struct CCGKey; struct DMFlagMat; -struct DerivedMesh; -struct GSet; -struct GPUVertPointLink; -struct GPUDrawObject; struct GridCommonGPUBuffer; -struct PBVH; -struct Gwn_Batch; +struct GSet; +struct MLoop; +struct MLoopTri; +struct MPoly; struct MVert; - -typedef struct GPUBuffer { - size_t size; /* in bytes */ - unsigned int id; /* used with vertex buffer objects */ -} GPUBuffer; - -typedef struct GPUBufferMaterial { - /* range of points used for this material */ - unsigned int start; - unsigned int totelements; - unsigned int totloops; - unsigned int *polys; /* array of polygons for this material */ - unsigned int totpolys; /* total polygons in polys */ - unsigned int totvisiblepolys; /* total visible polygons */ - - /* original material index */ - short mat_nr; -} GPUBufferMaterial; - -void GPU_buffer_material_finalize(struct GPUDrawObject *gdo, GPUBufferMaterial *matinfo, int totmat); - -/* meshes are split up by material since changing materials requires - * GL state changes that can't occur in the middle of drawing an - * array. - * - * some simplifying assumptions are made: - * - all quads are treated as two triangles. - * - no vertex sharing is used; each triangle gets its own copy of the - * vertices it uses (this makes it easy to deal with a vertex used - * by faces with different properties, such as smooth/solid shading, - * different MCols, etc.) - * - * to avoid confusion between the original MVert vertices and the - * arrays of OpenGL vertices, the latter are referred to here and in - * the source as `points'. similarly, the OpenGL triangles generated - * for MFaces are referred to as triangles rather than faces. - */ -typedef struct GPUDrawObject { - GPUBuffer *points; - GPUBuffer *normals; - GPUBuffer *uv; - GPUBuffer *uv_tex; - GPUBuffer *colors; - GPUBuffer *edges; - GPUBuffer *uvedges; - GPUBuffer *triangles; /* triangle index buffer */ - - /* for each original vertex, the list of related points */ - struct GPUVertPointLink *vert_points; - - /* see: USE_GPU_POINT_LINK define */ -#if 0 - /* storage for the vert_points lists */ - struct GPUVertPointLink *vert_points_mem; - int vert_points_usage; -#endif - - int colType; - - GPUBufferMaterial *materials; - int totmaterial; - - unsigned int tot_triangle_point; - unsigned int tot_loose_point; - /* different than total loops since ngons get tesselated still */ - unsigned int tot_loop_verts; - - /* caches of the original DerivedMesh values */ - unsigned int totvert; - unsigned int totedge; - - unsigned int loose_edge_offset; - unsigned int tot_loose_edge_drawn; - unsigned int tot_edge_drawn; - - /* for subsurf, offset where drawing of interior edges starts */ - unsigned int interior_offset; - unsigned int totinterior; -} GPUDrawObject; - -/* currently unused */ -// #define USE_GPU_POINT_LINK - -typedef struct GPUVertPointLink { -#ifdef USE_GPU_POINT_LINK - struct GPUVertPointLink *next; -#endif - /* -1 means uninitialized */ - int point_index; -} GPUVertPointLink; - - - -/* used for GLSL materials */ -typedef struct GPUAttrib { - int index; - int info_index; - int size; - int type; -} GPUAttrib; - -void GPU_global_buffer_pool_free(void); -void GPU_global_buffer_pool_free_unused(void); - -GPUBuffer *GPU_buffer_alloc(size_t size); -void GPU_buffer_free(GPUBuffer *buffer); - -void GPU_drawobject_free(struct DerivedMesh *dm); - -/* flag that controls data type to fill buffer with, a modifier will prepare. */ -typedef enum { - GPU_BUFFER_VERTEX = 0, - GPU_BUFFER_NORMAL, - GPU_BUFFER_COLOR, - GPU_BUFFER_UV, - GPU_BUFFER_UV_TEXPAINT, - GPU_BUFFER_EDGE, - GPU_BUFFER_UVEDGE, - GPU_BUFFER_TRIANGLES -} GPUBufferType; - -typedef enum { - GPU_BINDING_ARRAY = 0, - GPU_BINDING_INDEX = 1, -} GPUBindingType; - -typedef enum { - GPU_ATTR_INFO_SRGB = (1 << 0), -} GPUAttrInfo; - -/* called before drawing */ -void GPU_vertex_setup(struct DerivedMesh *dm); -void GPU_normal_setup(struct DerivedMesh *dm); -void GPU_uv_setup(struct DerivedMesh *dm); -void GPU_texpaint_uv_setup(struct DerivedMesh *dm); -/* colType is the cddata MCol type to use! */ -void GPU_color_setup(struct DerivedMesh *dm, int colType); -void GPU_buffer_bind_as_color(GPUBuffer *buffer); -void GPU_edge_setup(struct DerivedMesh *dm); /* does not mix with other data */ -void GPU_uvedge_setup(struct DerivedMesh *dm); - -void GPU_triangle_setup(struct DerivedMesh *dm); - -int GPU_attrib_element_size(GPUAttrib data[], int numdata); -void GPU_interleaved_attrib_setup(GPUBuffer *buffer, GPUAttrib data[], int numdata, int element_size); - -void GPU_buffer_bind(GPUBuffer *buffer, GPUBindingType binding); -void GPU_buffer_unbind(GPUBuffer *buffer, GPUBindingType binding); - -/* can't lock more than one buffer at once */ -void *GPU_buffer_lock(GPUBuffer *buffer, GPUBindingType binding); -void *GPU_buffer_lock_stream(GPUBuffer *buffer, GPUBindingType binding); -void GPU_buffer_unlock(GPUBuffer *buffer, GPUBindingType binding); - -/* switch color rendering on=1/off=0 */ -void GPU_color_switch(int mode); - -/* used for drawing edges */ -void GPU_buffer_draw_elements(GPUBuffer *elements, unsigned int mode, int start, int count); - -/* called after drawing */ -void GPU_buffers_unbind(void); - -/* only unbind interleaved data */ -void GPU_interleaved_attrib_unbind(void); +struct PBVH; /* Buffers for non-DerivedMesh drawing */ typedef struct GPU_PBVH_Buffers GPU_PBVH_Buffers; @@ -264,9 +91,6 @@ void GPU_pbvh_grid_buffers_update( const int update_flags); /* draw */ -void GPU_pbvh_buffers_draw( - GPU_PBVH_Buffers *buffers, DMSetMaterial setMaterial, - bool wireframe, bool fast); struct Gwn_Batch *GPU_pbvh_buffers_batch_get(GPU_PBVH_Buffers *buffers, bool fast); /* debug PBVH draw */ @@ -278,4 +102,6 @@ bool GPU_pbvh_buffers_mask_changed(GPU_PBVH_Buffers *buffers, bool show_mask); void GPU_pbvh_buffers_free(GPU_PBVH_Buffers *buffers); void GPU_pbvh_multires_buffers_free(struct GridCommonGPUBuffer **grid_common_gpu_buffer); +void GPU_pbvh_fix_linking(void); + #endif diff --git a/source/blender/gpu/GPU_draw.h b/source/blender/gpu/GPU_draw.h index 2dbb1b1e90c..e26d973142b 100644 --- a/source/blender/gpu/GPU_draw.h +++ b/source/blender/gpu/GPU_draw.h @@ -65,41 +65,6 @@ void GPU_state_init(void); void GPU_enable_program_point_size(void); void GPU_disable_program_point_size(void); -/* Material drawing - * - first the state is initialized by a particular object and - * it's materials - * - after this, materials can be quickly enabled by their number, - * GPU_object_material_bind returns 0 if drawing should be skipped - * - after drawing, the material must be disabled again */ - -void GPU_begin_object_materials( - struct View3D *v3d, struct RegionView3D *rv3d, - struct Scene *scene, struct ViewLayer *view_layer, - struct Object *ob, bool glsl, bool *do_alpha_after); -void GPU_end_object_materials(void); -bool GPU_object_materials_check(void); - -int GPU_object_material_bind(int nr, void *attribs); -void GPU_object_material_unbind(void); -int GPU_object_material_visible(int nr, void *attribs); - -void GPU_begin_dupli_object(struct DupliObject *dob); -void GPU_end_dupli_object(void); - -void GPU_material_diffuse_get(int nr, float diff[4]); -bool GPU_material_use_matcaps_get(void); - -void GPU_set_material_alpha_blend(int alphablend); -int GPU_get_material_alpha_blend(void); - -/* Lights - * - returns how many lights were enabled - * - this affects fixed functions materials and texface, not glsl */ - -int GPU_default_lights(void); -int GPU_scene_object_lights( - struct ViewLayer *view_layer, float viewmat[4][4], int ortho); - /* Mipmap settings * - these will free textures on changes */ @@ -143,11 +108,6 @@ void GPU_create_smoke(struct SmokeModifierData *smd, int highres); /* Delayed free of OpenGL buffers by main thread */ void GPU_free_unused_buffers(void); -#ifdef WITH_OPENSUBDIV -struct DerivedMesh; -void GPU_draw_update_fvar_offset(struct DerivedMesh *dm); -#endif - /* utilities */ void GPU_select_index_set(int index); void GPU_select_index_get(int index, int *r_col); diff --git a/source/blender/gpu/GPU_lamp.h b/source/blender/gpu/GPU_lamp.h deleted file mode 100644 index 87350f1ceb4..00000000000 --- a/source/blender/gpu/GPU_lamp.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2005 Blender Foundation. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): Brecht Van Lommel, Clément Foucault. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file GPU_lamp.h - * \ingroup gpu - */ - -#ifndef __GPU_LAMP_H__ -#define __GPU_LAMP_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -struct Scene; -struct Object; -struct RenderEngineType; - -typedef struct GPULamp GPULamp; - -#define MAX_LAMP_DATA 2 - -typedef struct LampEngineData { - void *storage[MAX_LAMP_DATA]; -} LampEngineData; - -LampEngineData *GPU_lamp_engine_data_get(struct Scene *scene, struct Object *ob, struct Object *par, struct RenderEngineType *re); - -GPULamp *GPU_lamp_from_blender(struct Scene *scene, struct Object *ob, struct Object *par); -void GPU_lamp_free(struct Object *ob); -void GPU_lamp_engine_data_free(LampEngineData *led); - -bool GPU_lamp_visible(GPULamp *lamp, struct Material *ma); -bool GPU_lamp_has_shadow_buffer(GPULamp *lamp); -void GPU_lamp_update_buffer_mats(GPULamp *lamp); -void GPU_lamp_shadow_buffer_bind(GPULamp *lamp, float viewmat[4][4], int *winsize, float winmat[4][4]); -void GPU_lamp_shadow_buffer_unbind(GPULamp *lamp); -int GPU_lamp_shadow_buffer_type(GPULamp *lamp); -int GPU_lamp_shadow_bind_code(GPULamp *lamp); -float *GPU_lamp_dynpersmat(GPULamp *lamp); - -void GPU_lamp_update(GPULamp *lamp, int lay, int hide, float obmat[4][4]); -void GPU_lamp_update_colors(GPULamp *lamp, float r, float g, float b, float energy); -void GPU_lamp_update_distance(GPULamp *lamp, float distance, float att1, float att2, - float coeff_const, float coeff_lin, float coeff_quad); -void GPU_lamp_update_spot(GPULamp *lamp, float spotsize, float spotblend); -int GPU_lamp_shadow_layer(GPULamp *lamp); - -#ifdef __cplusplus -} -#endif - -#endif /* __GPU_LAMP_H__ */ diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h index 1d2b234e7f3..c9ef5ca3ae6 100644 --- a/source/blender/gpu/GPU_material.h +++ b/source/blender/gpu/GPU_material.h @@ -236,37 +236,23 @@ GPUNodeLink *GPU_uniformbuffer_link_out( struct GPUNodeStack *stack, const int index); void GPU_material_output_link(GPUMaterial *material, GPUNodeLink *link); -void GPU_material_enable_alpha(GPUMaterial *material); GPUBuiltin GPU_get_material_builtins(GPUMaterial *material); -GPUBlendMode GPU_material_alpha_blend(GPUMaterial *material, float obcol[4]); void GPU_material_sss_profile_create(GPUMaterial *material, float *radii, short *falloff_type, float *sharpness); struct GPUUniformBuffer *GPU_material_sss_profile_get( GPUMaterial *material, int sample_ct, struct GPUTexture **tex_profile); /* High level functions to create and use GPU materials */ -GPUMaterial *GPU_material_world(struct Scene *scene, struct World *wo); GPUMaterial *GPU_material_from_nodetree_find( struct ListBase *gpumaterials, const void *engine_type, int options); GPUMaterial *GPU_material_from_nodetree( - struct Scene *scene, struct bNodeTree *ntree, struct ListBase *gpumaterials, const void *engine_type, int options, - const char *vert_code, const char *geom_code, const char *frag_lib, const char *defines, bool deferred); -GPUMaterial *GPU_material_from_blender(struct Scene *scene, struct Material *ma, bool use_opensubdiv); -GPUMaterial *GPU_material_matcap(struct Scene *scene, struct Material *ma, bool use_opensubdiv); + struct Scene *scene, struct bNodeTree *ntree, struct ListBase *gpumaterials, const void *engine_type, int options); void GPU_material_generate_pass( GPUMaterial *mat, const char *vert_code, const char *geom_code, const char *frag_lib, const char *defines); void GPU_material_free(struct ListBase *gpumaterial); void GPU_materials_free(void); -void GPU_material_bind( - GPUMaterial *material, int oblay, int viewlay, double time, int mipmap, - float viewmat[4][4], float viewinv[4][4], float cameraborder[4]); -void GPU_material_bind_uniforms( - GPUMaterial *material, float obmat[4][4], float viewmat[4][4], float obcol[4], - float autobumpscale, GPUParticleInfo *pi, float object_info[3]); -void GPU_material_unbind(GPUMaterial *material); -bool GPU_material_bound(GPUMaterial *material); struct Scene *GPU_material_scene(GPUMaterial *material); GPUMatType GPU_Material_get_type(GPUMaterial *material); struct GPUPass *GPU_material_get_pass(GPUMaterial *material); @@ -281,103 +267,9 @@ void GPU_material_vertex_attributes(GPUMaterial *material, struct GPUVertexAttribs *attrib); bool GPU_material_do_color_management(GPUMaterial *mat); -bool GPU_material_use_new_shading_nodes(GPUMaterial *mat); -bool GPU_material_use_world_space_shading(GPUMaterial *mat); bool GPU_material_use_domain_surface(GPUMaterial *mat); bool GPU_material_use_domain_volume(GPUMaterial *mat); -/* Exported shading */ - -typedef struct GPUShadeInput { - GPUMaterial *gpumat; - struct Material *mat; - - GPUNodeLink *rgb, *specrgb, *vn, *view, *vcol, *ref; - GPUNodeLink *alpha, *refl, *spec, *emit, *har, *amb; - GPUNodeLink *spectra, *mir, *refcol; -} GPUShadeInput; - -typedef struct GPUShadeResult { - GPUNodeLink *diff, *spec, *combined, *alpha; -} GPUShadeResult; - -void GPU_shadeinput_set(GPUMaterial *mat, struct Material *ma, GPUShadeInput *shi); -void GPU_shaderesult_set(GPUShadeInput *shi, GPUShadeResult *shr); - -/* Export GLSL shader */ - -typedef enum GPUDataType { - GPU_DATA_NONE = 0, - GPU_DATA_1I = 1, /* 1 integer */ - GPU_DATA_1F = 2, - GPU_DATA_2F = 3, - GPU_DATA_3F = 4, - GPU_DATA_4F = 5, - GPU_DATA_9F = 6, - GPU_DATA_16F = 7, - GPU_DATA_4UB = 8, -} GPUDataType; - -/* this structure gives information of each uniform found in the shader */ -typedef struct GPUInputUniform { - struct GPUInputUniform *next, *prev; - char varname[32]; /* name of uniform in shader */ - GPUDynamicType type; /* type of uniform, data format and calculation derive from it */ - GPUDataType datatype; /* type of uniform data */ - struct Object *lamp; /* when type=GPU_DYNAMIC_LAMP_... or GPU_DYNAMIC_SAMPLER_2DSHADOW */ - struct Image *image; /* when type=GPU_DYNAMIC_SAMPLER_2DIMAGE */ - struct Material *material;/* when type=GPU_DYNAMIC_MAT_... */ - int texnumber; /* when type=GPU_DYNAMIC_SAMPLER, texture number: 0.. */ - unsigned char *texpixels; /* for internally generated texture, pixel data in RGBA format */ - int texsize; /* size in pixel of the texture in texpixels buffer: - * for 2D textures, this is S and T size (square texture) */ -} GPUInputUniform; - -typedef struct GPUInputAttribute { - struct GPUInputAttribute *next, *prev; - char varname[32]; /* name of attribute in shader */ - int type; /* from CustomData.type, data type derives from it */ - GPUDataType datatype; /* type of attribute data */ - const char *name; /* layer name */ - int number; /* generic attribute number */ -} GPUInputAttribute; - -typedef struct GPUShaderExport { - ListBase uniforms; - ListBase attributes; - char *vertex; - char *fragment; -} GPUShaderExport; - -GPUShaderExport *GPU_shader_export(struct Scene *scene, struct Material *ma); -void GPU_free_shader_export(GPUShaderExport *shader); - -/* Lamps */ -GPUNodeLink *GPU_lamp_get_data( - GPUMaterial *mat, struct GPULamp *lamp, - GPUNodeLink **r_col, GPUNodeLink **r_lv, GPUNodeLink **r_dist, GPUNodeLink **r_shadow, GPUNodeLink **r_energy); - -/* World */ -void GPU_mist_update_enable(short enable); -void GPU_mist_update_values(int type, float start, float dist, float inten, float color[3]); -void GPU_horizon_update_color(float color[3]); -void GPU_ambient_update_color(float color[3]); -void GPU_zenith_update_color(float color[3]); - -struct GPUParticleInfo -{ - float scalprops[4]; - float location[4]; - float velocity[3]; - float angular_velocity[3]; -}; - -#ifdef WITH_OPENSUBDIV -struct DerivedMesh; -void GPU_material_update_fvar_offset(GPUMaterial *gpu_material, - struct DerivedMesh *dm); -#endif - void GPU_pass_cache_garbage_collect(void); void GPU_pass_cache_free(void); diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c index d2a18684e27..bbee252cd20 100644 --- a/source/blender/gpu/intern/gpu_buffers.c +++ b/source/blender/gpu/intern/gpu_buffers.c @@ -58,52 +58,6 @@ #include "bmesh.h" -/* TODO: gawain support for baseelemarray */ -// #define USE_BASE_ELEM - -typedef enum { - GPU_BUFFER_VERTEX_STATE = (1 << 0), - GPU_BUFFER_NORMAL_STATE = (1 << 1), - GPU_BUFFER_TEXCOORD_UNIT_0_STATE = (1 << 2), - GPU_BUFFER_TEXCOORD_UNIT_2_STATE = (1 << 3), - GPU_BUFFER_COLOR_STATE = (1 << 4), - GPU_BUFFER_ELEMENT_STATE = (1 << 5), -} GPUBufferState; - -typedef struct { - GLenum gl_buffer_type; - int num_components; /* number of data components for one vertex */ -} GPUBufferTypeSettings; - - -static size_t gpu_buffer_size_from_type(DerivedMesh *dm, GPUBufferType type); - -static const GPUBufferTypeSettings gpu_buffer_type_settings[] = { - /* vertex */ - {GL_ARRAY_BUFFER, 3}, - /* normal */ - {GL_ARRAY_BUFFER, 4}, /* we copy 3 shorts per normal but we add a fourth for alignment */ - /* mcol */ - {GL_ARRAY_BUFFER, 4}, - /* uv */ - {GL_ARRAY_BUFFER, 2}, - /* uv for texpaint */ - {GL_ARRAY_BUFFER, 4}, - /* edge */ - {GL_ELEMENT_ARRAY_BUFFER, 2}, - /* uv edge */ - {GL_ELEMENT_ARRAY_BUFFER, 4}, - /* triangles, 1 point since we are allocating from tottriangle points, which account for all points */ - {GL_ELEMENT_ARRAY_BUFFER, 1}, -}; - -#define MAX_GPU_ATTRIB_DATA 32 - -#define BUFFER_OFFSET(n) ((GLubyte *)NULL + (n)) - -static GPUBufferState GLStates = 0; -static GPUAttrib attribData[MAX_GPU_ATTRIB_DATA] = { { -1, 0, 0 } }; - static ThreadMutex buffer_mutex = BLI_MUTEX_INITIALIZER; /* multires global buffer, can be used for many grids having the same grid size */ @@ -113,834 +67,6 @@ typedef struct GridCommonGPUBuffer { unsigned mres_prev_totquad; } GridCommonGPUBuffer; -void GPU_buffer_material_finalize(GPUDrawObject *gdo, GPUBufferMaterial *matinfo, int totmat) -{ - int i, curmat, curelement; - - /* count the number of materials used by this DerivedMesh */ - for (i = 0; i < totmat; i++) { - if (matinfo[i].totelements > 0) - gdo->totmaterial++; - } - - /* allocate an array of materials used by this DerivedMesh */ - gdo->materials = MEM_mallocN(sizeof(GPUBufferMaterial) * gdo->totmaterial, - "GPUDrawObject.materials"); - - /* initialize the materials array */ - for (i = 0, curmat = 0, curelement = 0; i < totmat; i++) { - if (matinfo[i].totelements > 0) { - gdo->materials[curmat] = matinfo[i]; - gdo->materials[curmat].start = curelement; - gdo->materials[curmat].mat_nr = i; - gdo->materials[curmat].polys = MEM_mallocN(sizeof(int) * matinfo[i].totpolys, "GPUBufferMaterial.polys"); - - curelement += matinfo[i].totelements; - curmat++; - } - } - - MEM_freeN(matinfo); -} - - -/* stores recently-deleted buffers so that new buffers won't have to - * be recreated as often - * - * only one instance of this pool is created, stored in - * gpu_buffer_pool - * - * note that the number of buffers in the pool is usually limited to - * MAX_FREE_GPU_BUFFERS, but this limit may be exceeded temporarily - * when a GPUBuffer is released outside the main thread; due to OpenGL - * restrictions it cannot be immediately released - */ -typedef struct GPUBufferPool { - /* number of allocated buffers stored */ - int totbuf; - /* actual allocated length of the arrays */ - int maxsize; - GPUBuffer **buffers; -} GPUBufferPool; -#define MAX_FREE_GPU_BUFFERS 8 - -/* create a new GPUBufferPool */ -static GPUBufferPool *gpu_buffer_pool_new(void) -{ - GPUBufferPool *pool; - - pool = MEM_callocN(sizeof(GPUBufferPool), "GPUBuffer_Pool"); - - pool->maxsize = MAX_FREE_GPU_BUFFERS; - pool->buffers = MEM_mallocN(sizeof(*pool->buffers) * pool->maxsize, - "GPUBufferPool.buffers"); - return pool; -} - -/* remove a GPUBuffer from the pool (does not free the GPUBuffer) */ -static void gpu_buffer_pool_remove_index(GPUBufferPool *pool, int index) -{ - int i; - - if (!pool || index < 0 || index >= pool->totbuf) - return; - - /* shift entries down, overwriting the buffer at `index' */ - for (i = index; i < pool->totbuf - 1; i++) - pool->buffers[i] = pool->buffers[i + 1]; - - /* clear the last entry */ - if (pool->totbuf > 0) - pool->buffers[pool->totbuf - 1] = NULL; - - pool->totbuf--; -} - -/* delete the last entry in the pool */ -static void gpu_buffer_pool_delete_last(GPUBufferPool *pool) -{ - GPUBuffer *last; - - if (pool->totbuf <= 0) - return; - - /* get the last entry */ - if (!(last = pool->buffers[pool->totbuf - 1])) - return; - - /* delete the buffer's data */ - glDeleteBuffers(1, &last->id); - - /* delete the buffer and remove from pool */ - MEM_freeN(last); - pool->totbuf--; - pool->buffers[pool->totbuf] = NULL; -} - -/* free a GPUBufferPool; also frees the data in the pool's - * GPUBuffers */ -static void gpu_buffer_pool_free(GPUBufferPool *pool) -{ - if (!pool) - return; - - while (pool->totbuf) - gpu_buffer_pool_delete_last(pool); - - MEM_freeN(pool->buffers); - MEM_freeN(pool); -} - -static void gpu_buffer_pool_free_unused(GPUBufferPool *pool) -{ - if (!pool) - return; - - BLI_mutex_lock(&buffer_mutex); - - while (pool->totbuf) - gpu_buffer_pool_delete_last(pool); - - BLI_mutex_unlock(&buffer_mutex); -} - -static GPUBufferPool *gpu_buffer_pool = NULL; -static GPUBufferPool *gpu_get_global_buffer_pool(void) -{ - /* initialize the pool */ - if (!gpu_buffer_pool) - gpu_buffer_pool = gpu_buffer_pool_new(); - - return gpu_buffer_pool; -} - -void GPU_global_buffer_pool_free(void) -{ - gpu_buffer_pool_free(gpu_buffer_pool); - gpu_buffer_pool = NULL; -} - -void GPU_global_buffer_pool_free_unused(void) -{ - gpu_buffer_pool_free_unused(gpu_buffer_pool); -} - -/* get a GPUBuffer of at least `size' bytes; uses one from the buffer - * pool if possible, otherwise creates a new one - * - * Thread-unsafe version for internal usage only. - */ -static GPUBuffer *gpu_buffer_alloc_intern(size_t size) -{ - GPUBufferPool *pool; - GPUBuffer *buf; - int i, bestfit = -1; - size_t bufsize; - - /* bad case, leads to leak of buf since buf->pointer will allocate - * NULL, leading to return without cleanup. In any case better detect early - * psy-fi */ - if (size == 0) - return NULL; - - pool = gpu_get_global_buffer_pool(); - - /* not sure if this buffer pool code has been profiled much, - * seems to me that the graphics driver and system memory - * management might do this stuff anyway. --nicholas - */ - - /* check the global buffer pool for a recently-deleted buffer - * that is at least as big as the request, but not more than - * twice as big */ - for (i = 0; i < pool->totbuf; i++) { - bufsize = pool->buffers[i]->size; - - /* check for an exact size match */ - if (bufsize == size) { - bestfit = i; - break; - } - /* smaller buffers won't fit data and buffers at least - * twice as big are a waste of memory */ - else if (bufsize > size && size > (bufsize / 2)) { - /* is it closer to the required size than the - * last appropriate buffer found. try to save - * memory */ - if (bestfit == -1 || pool->buffers[bestfit]->size > bufsize) { - bestfit = i; - } - } - } - - /* if an acceptable buffer was found in the pool, remove it - * from the pool and return it */ - if (bestfit != -1) { - buf = pool->buffers[bestfit]; - gpu_buffer_pool_remove_index(pool, bestfit); - return buf; - } - - /* no acceptable buffer found in the pool, create a new one */ - buf = MEM_callocN(sizeof(GPUBuffer), "GPUBuffer"); - buf->size = size; - - glGenBuffers(1, &buf->id); - glBindBuffer(GL_ARRAY_BUFFER, buf->id); - glBufferData(GL_ARRAY_BUFFER, size, NULL, GL_STATIC_DRAW); - glBindBuffer(GL_ARRAY_BUFFER, 0); - - return buf; -} - -/* Same as above, but safe for threading. */ -GPUBuffer *GPU_buffer_alloc(size_t size) -{ - GPUBuffer *buffer; - - if (size == 0) { - /* Early out, no lock needed in this case. */ - return NULL; - } - - BLI_mutex_lock(&buffer_mutex); - buffer = gpu_buffer_alloc_intern(size); - BLI_mutex_unlock(&buffer_mutex); - - return buffer; -} - -/* release a GPUBuffer; does not free the actual buffer or its data, - * but rather moves it to the pool of recently-freed buffers for - * possible re-use - * - * Thread-unsafe version for internal usage only. - */ -static void gpu_buffer_free_intern(GPUBuffer *buffer) -{ - GPUBufferPool *pool; - int i; - - if (!buffer) - return; - - pool = gpu_get_global_buffer_pool(); - - /* free the last used buffer in the queue if no more space, but only - * if we are in the main thread. for e.g. rendering or baking it can - * happen that we are in other thread and can't call OpenGL, in that - * case cleanup will be done GPU_buffer_pool_free_unused */ - if (BLI_thread_is_main()) { - /* in main thread, safe to decrease size of pool back - * down to MAX_FREE_GPU_BUFFERS */ - while (pool->totbuf >= MAX_FREE_GPU_BUFFERS) - gpu_buffer_pool_delete_last(pool); - } - else { - /* outside of main thread, can't safely delete the - * buffer, so increase pool size */ - if (pool->maxsize == pool->totbuf) { - pool->maxsize += MAX_FREE_GPU_BUFFERS; - pool->buffers = MEM_reallocN(pool->buffers, - sizeof(GPUBuffer *) * pool->maxsize); - } - } - - /* shift pool entries up by one */ - for (i = pool->totbuf; i > 0; i--) - pool->buffers[i] = pool->buffers[i - 1]; - - /* insert the buffer into the beginning of the pool */ - pool->buffers[0] = buffer; - pool->totbuf++; -} - -/* Same as above, but safe for threading. */ -void GPU_buffer_free(GPUBuffer *buffer) -{ - if (!buffer) { - /* Early output, no need to lock in this case, */ - return; - } - - BLI_mutex_lock(&buffer_mutex); - gpu_buffer_free_intern(buffer); - BLI_mutex_unlock(&buffer_mutex); -} - -void GPU_drawobject_free(DerivedMesh *dm) -{ - GPUDrawObject *gdo; - int i; - - if (!dm || !(gdo = dm->drawObject)) - return; - - for (i = 0; i < gdo->totmaterial; i++) { - if (gdo->materials[i].polys) - MEM_freeN(gdo->materials[i].polys); - } - - MEM_freeN(gdo->materials); - if (gdo->vert_points) - MEM_freeN(gdo->vert_points); -#ifdef USE_GPU_POINT_LINK - MEM_freeN(gdo->vert_points_mem); -#endif - GPU_buffer_free(gdo->points); - GPU_buffer_free(gdo->normals); - GPU_buffer_free(gdo->uv); - GPU_buffer_free(gdo->uv_tex); - GPU_buffer_free(gdo->colors); - GPU_buffer_free(gdo->edges); - GPU_buffer_free(gdo->uvedges); - GPU_buffer_free(gdo->triangles); - - MEM_freeN(gdo); - dm->drawObject = NULL; -} - -static GPUBuffer *gpu_try_realloc(GPUBufferPool *pool, GPUBuffer *buffer, size_t size) -{ - /* try freeing an entry from the pool - * and reallocating the buffer */ - gpu_buffer_free_intern(buffer); - - buffer = NULL; - - while (pool->totbuf && !buffer) { - gpu_buffer_pool_delete_last(pool); - buffer = gpu_buffer_alloc_intern(size); - } - - return buffer; -} - -static GPUBuffer *gpu_buffer_setup(DerivedMesh *dm, GPUDrawObject *object, - int type, void *user, GPUBuffer *buffer) -{ - GPUBufferPool *pool; - float *varray; - int *mat_orig_to_new; - int i; - const GPUBufferTypeSettings *ts = &gpu_buffer_type_settings[type]; - GLenum target = ts->gl_buffer_type; - size_t size = gpu_buffer_size_from_type(dm, type); - GLboolean uploaded; - - pool = gpu_get_global_buffer_pool(); - - BLI_mutex_lock(&buffer_mutex); - - /* alloc a GPUBuffer; fall back to legacy mode on failure */ - if (!buffer) { - if (!(buffer = gpu_buffer_alloc_intern(size))) { - BLI_mutex_unlock(&buffer_mutex); - return NULL; - } - } - - mat_orig_to_new = MEM_mallocN(sizeof(*mat_orig_to_new) * dm->totmat, - "GPU_buffer_setup.mat_orig_to_new"); - for (i = 0; i < object->totmaterial; i++) { - /* map from original material index to new - * GPUBufferMaterial index */ - mat_orig_to_new[object->materials[i].mat_nr] = i; - } - - /* bind the buffer and discard previous data, - * avoids stalling gpu */ - glBindBuffer(target, buffer->id); - glBufferData(target, buffer->size, NULL, GL_STATIC_DRAW); - - /* attempt to map the buffer */ - if (!(varray = glMapBuffer(target, GL_WRITE_ONLY))) { - buffer = gpu_try_realloc(pool, buffer, size); - - /* allocation still failed; unfortunately we need to exit */ - if (!(buffer && (varray = glMapBuffer(target, GL_WRITE_ONLY)))) { - if (buffer) - gpu_buffer_free_intern(buffer); - BLI_mutex_unlock(&buffer_mutex); - return NULL; - } - } - - uploaded = GL_FALSE; - - /* attempt to upload the data to the VBO */ - while (uploaded == GL_FALSE) { - dm->copy_gpu_data(dm, type, varray, mat_orig_to_new, user); - /* glUnmapBuffer returns GL_FALSE if - * the data store is corrupted; retry - * in that case */ - uploaded = glUnmapBuffer(target); - } - glBindBuffer(target, 0); - - MEM_freeN(mat_orig_to_new); - - BLI_mutex_unlock(&buffer_mutex); - - return buffer; -} - -/* get the GPUDrawObject buffer associated with a type */ -static GPUBuffer **gpu_drawobject_buffer_from_type(GPUDrawObject *gdo, GPUBufferType type) -{ - switch (type) { - case GPU_BUFFER_VERTEX: - return &gdo->points; - case GPU_BUFFER_NORMAL: - return &gdo->normals; - case GPU_BUFFER_COLOR: - return &gdo->colors; - case GPU_BUFFER_UV: - return &gdo->uv; - case GPU_BUFFER_UV_TEXPAINT: - return &gdo->uv_tex; - case GPU_BUFFER_EDGE: - return &gdo->edges; - case GPU_BUFFER_UVEDGE: - return &gdo->uvedges; - case GPU_BUFFER_TRIANGLES: - return &gdo->triangles; - default: - return NULL; - } -} - -/* get the amount of space to allocate for a buffer of a particular type */ -static size_t gpu_buffer_size_from_type(DerivedMesh *dm, GPUBufferType type) -{ - const int components = gpu_buffer_type_settings[type].num_components; - switch (type) { - case GPU_BUFFER_VERTEX: - return sizeof(float) * components * (dm->drawObject->tot_loop_verts + dm->drawObject->tot_loose_point); - case GPU_BUFFER_NORMAL: - return sizeof(short) * components * dm->drawObject->tot_loop_verts; - case GPU_BUFFER_COLOR: - return sizeof(char) * components * dm->drawObject->tot_loop_verts; - case GPU_BUFFER_UV: - return sizeof(float) * components * dm->drawObject->tot_loop_verts; - case GPU_BUFFER_UV_TEXPAINT: - return sizeof(float) * components * dm->drawObject->tot_loop_verts; - case GPU_BUFFER_EDGE: - return sizeof(int) * components * dm->drawObject->totedge; - case GPU_BUFFER_UVEDGE: - return sizeof(int) * components * dm->drawObject->tot_loop_verts; - case GPU_BUFFER_TRIANGLES: - return sizeof(int) * components * dm->drawObject->tot_triangle_point; - default: - return -1; - } -} - -/* call gpu_buffer_setup with settings for a particular type of buffer */ -static GPUBuffer *gpu_buffer_setup_type(DerivedMesh *dm, GPUBufferType type, GPUBuffer *buf) -{ - void *user_data = NULL; - - /* special handling for MCol and UV buffers */ - if (type == GPU_BUFFER_COLOR) { - if (!(user_data = DM_get_loop_data_layer(dm, dm->drawObject->colType))) - return NULL; - } - else if (ELEM(type, GPU_BUFFER_UV, GPU_BUFFER_UV_TEXPAINT)) { - if (!DM_get_loop_data_layer(dm, CD_MLOOPUV)) - return NULL; - } - - buf = gpu_buffer_setup(dm, dm->drawObject, type, user_data, buf); - - return buf; -} - -/* get the buffer of `type', initializing the GPUDrawObject and - * buffer if needed */ -static GPUBuffer *gpu_buffer_setup_common(DerivedMesh *dm, GPUBufferType type, bool update) -{ - GPUBuffer **buf; - - if (!dm->drawObject) - dm->drawObject = dm->gpuObjectNew(dm); - - buf = gpu_drawobject_buffer_from_type(dm->drawObject, type); - if (!(*buf)) - *buf = gpu_buffer_setup_type(dm, type, NULL); - else if (update) - *buf = gpu_buffer_setup_type(dm, type, *buf); - - return *buf; -} - -void GPU_vertex_setup(DerivedMesh *dm) -{ - if (!gpu_buffer_setup_common(dm, GPU_BUFFER_VERTEX, false)) - return; - - glEnableClientState(GL_VERTEX_ARRAY); - glBindBuffer(GL_ARRAY_BUFFER, dm->drawObject->points->id); - glVertexPointer(3, GL_FLOAT, 0, 0); - - GLStates |= GPU_BUFFER_VERTEX_STATE; -} - -void GPU_normal_setup(DerivedMesh *dm) -{ - if (!gpu_buffer_setup_common(dm, GPU_BUFFER_NORMAL, false)) - return; - - glEnableClientState(GL_NORMAL_ARRAY); - glBindBuffer(GL_ARRAY_BUFFER, dm->drawObject->normals->id); - glNormalPointer(GL_SHORT, 4 * sizeof(short), 0); - - GLStates |= GPU_BUFFER_NORMAL_STATE; -} - -void GPU_uv_setup(DerivedMesh *dm) -{ - if (!gpu_buffer_setup_common(dm, GPU_BUFFER_UV, false)) - return; - - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glBindBuffer(GL_ARRAY_BUFFER, dm->drawObject->uv->id); - glTexCoordPointer(2, GL_FLOAT, 0, 0); - - GLStates |= GPU_BUFFER_TEXCOORD_UNIT_0_STATE; -} - -void GPU_texpaint_uv_setup(DerivedMesh *dm) -{ - if (!gpu_buffer_setup_common(dm, GPU_BUFFER_UV_TEXPAINT, false)) - return; - - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glBindBuffer(GL_ARRAY_BUFFER, dm->drawObject->uv_tex->id); - glTexCoordPointer(2, GL_FLOAT, 4 * sizeof(float), 0); - glClientActiveTexture(GL_TEXTURE2); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, 4 * sizeof(float), BUFFER_OFFSET(2 * sizeof(float))); - glClientActiveTexture(GL_TEXTURE0); - - GLStates |= GPU_BUFFER_TEXCOORD_UNIT_0_STATE | GPU_BUFFER_TEXCOORD_UNIT_2_STATE; -} - - -void GPU_color_setup(DerivedMesh *dm, int colType) -{ - bool update = false; - - if (!dm->drawObject) { - /* XXX Not really nice, but we need a valid gpu draw object to set the colType... - * Else we would have to add a new param to gpu_buffer_setup_common. */ - dm->drawObject = dm->gpuObjectNew(dm); - dm->dirty &= ~DM_DIRTY_MCOL_UPDATE_DRAW; - dm->drawObject->colType = colType; - } - /* In paint mode, dm may stay the same during stroke, however we still want to update colors! - * Also check in case we changed color type (i.e. which MCol cdlayer we use). */ - else if ((dm->dirty & DM_DIRTY_MCOL_UPDATE_DRAW) || (colType != dm->drawObject->colType)) { - update = true; - dm->dirty &= ~DM_DIRTY_MCOL_UPDATE_DRAW; - dm->drawObject->colType = colType; - } - - if (!gpu_buffer_setup_common(dm, GPU_BUFFER_COLOR, update)) - return; - - glEnableClientState(GL_COLOR_ARRAY); - glBindBuffer(GL_ARRAY_BUFFER, dm->drawObject->colors->id); - glColorPointer(4, GL_UNSIGNED_BYTE, 0, 0); - - GLStates |= GPU_BUFFER_COLOR_STATE; -} - -void GPU_buffer_bind_as_color(GPUBuffer *buffer) -{ - glEnableClientState(GL_COLOR_ARRAY); - glBindBuffer(GL_ARRAY_BUFFER, buffer->id); - glColorPointer(4, GL_UNSIGNED_BYTE, 0, 0); - - GLStates |= GPU_BUFFER_COLOR_STATE; -} - - -void GPU_edge_setup(DerivedMesh *dm) -{ - if (!gpu_buffer_setup_common(dm, GPU_BUFFER_EDGE, false)) - return; - - if (!gpu_buffer_setup_common(dm, GPU_BUFFER_VERTEX, false)) - return; - - glEnableClientState(GL_VERTEX_ARRAY); - glBindBuffer(GL_ARRAY_BUFFER, dm->drawObject->points->id); - glVertexPointer(3, GL_FLOAT, 0, 0); - - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, dm->drawObject->edges->id); - - GLStates |= (GPU_BUFFER_VERTEX_STATE | GPU_BUFFER_ELEMENT_STATE); -} - -void GPU_uvedge_setup(DerivedMesh *dm) -{ - if (!gpu_buffer_setup_common(dm, GPU_BUFFER_UVEDGE, false)) - return; - - glEnableClientState(GL_VERTEX_ARRAY); - glBindBuffer(GL_ARRAY_BUFFER, dm->drawObject->uvedges->id); - glVertexPointer(2, GL_FLOAT, 0, 0); - - GLStates |= GPU_BUFFER_VERTEX_STATE; -} - -void GPU_triangle_setup(struct DerivedMesh *dm) -{ - if (!gpu_buffer_setup_common(dm, GPU_BUFFER_TRIANGLES, false)) - return; - - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, dm->drawObject->triangles->id); - GLStates |= GPU_BUFFER_ELEMENT_STATE; -} - -static int gpu_typesize(int type) -{ - switch (type) { - case GL_FLOAT: - return sizeof(float); - case GL_INT: - return sizeof(int); - case GL_UNSIGNED_INT: - return sizeof(unsigned int); - case GL_BYTE: - return sizeof(char); - case GL_UNSIGNED_BYTE: - return sizeof(unsigned char); - default: - return 0; - } -} - -int GPU_attrib_element_size(GPUAttrib data[], int numdata) -{ - int i, elementsize = 0; - - for (i = 0; i < numdata; i++) { - int typesize = gpu_typesize(data[i].type); - if (typesize != 0) - elementsize += typesize * data[i].size; - } - return elementsize; -} - -void GPU_interleaved_attrib_setup(GPUBuffer *buffer, GPUAttrib data[], int numdata, int element_size) -{ - int i; - int elementsize; - size_t offset = 0; - - for (i = 0; i < MAX_GPU_ATTRIB_DATA; i++) { - if (attribData[i].index != -1) { - glDisableVertexAttribArray(attribData[i].index); - } - else - break; - } - if (element_size == 0) - elementsize = GPU_attrib_element_size(data, numdata); - else - elementsize = element_size; - - glBindBuffer(GL_ARRAY_BUFFER, buffer->id); - - for (i = 0; i < numdata; i++) { - glEnableVertexAttribArray(data[i].index); - int info = 0; - if (data[i].type == GL_UNSIGNED_BYTE) { - info |= GPU_ATTR_INFO_SRGB; - } - glUniform1i(data[i].info_index, info); - - glVertexAttribPointer(data[i].index, data[i].size, data[i].type, - GL_TRUE, elementsize, BUFFER_OFFSET(offset)); - offset += data[i].size * gpu_typesize(data[i].type); - - attribData[i].index = data[i].index; - attribData[i].size = data[i].size; - attribData[i].type = data[i].type; - } - - attribData[numdata].index = -1; -} - -void GPU_interleaved_attrib_unbind(void) -{ - int i; - for (i = 0; i < MAX_GPU_ATTRIB_DATA; i++) { - if (attribData[i].index != -1) { - glDisableVertexAttribArray(attribData[i].index); - } - else - break; - } - attribData[0].index = -1; -} - -void GPU_buffers_unbind(void) -{ - int i; - - if (GLStates & GPU_BUFFER_VERTEX_STATE) - glDisableClientState(GL_VERTEX_ARRAY); - if (GLStates & GPU_BUFFER_NORMAL_STATE) - glDisableClientState(GL_NORMAL_ARRAY); - if (GLStates & GPU_BUFFER_TEXCOORD_UNIT_0_STATE) - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - if (GLStates & GPU_BUFFER_TEXCOORD_UNIT_2_STATE) { - glClientActiveTexture(GL_TEXTURE2); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glClientActiveTexture(GL_TEXTURE0); - } - if (GLStates & GPU_BUFFER_COLOR_STATE) - glDisableClientState(GL_COLOR_ARRAY); - if (GLStates & GPU_BUFFER_ELEMENT_STATE) - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - - GLStates &= ~(GPU_BUFFER_VERTEX_STATE | GPU_BUFFER_NORMAL_STATE | - GPU_BUFFER_TEXCOORD_UNIT_0_STATE | GPU_BUFFER_TEXCOORD_UNIT_2_STATE | - GPU_BUFFER_COLOR_STATE | GPU_BUFFER_ELEMENT_STATE); - - for (i = 0; i < MAX_GPU_ATTRIB_DATA; i++) { - if (attribData[i].index != -1) { - glDisableVertexAttribArray(attribData[i].index); - } - else - break; - } - attribData[0].index = -1; - - glBindBuffer(GL_ARRAY_BUFFER, 0); -} - -void GPU_color_switch(int mode) -{ - if (mode) { - if (!(GLStates & GPU_BUFFER_COLOR_STATE)) - glEnableClientState(GL_COLOR_ARRAY); - GLStates |= GPU_BUFFER_COLOR_STATE; - } - else { - if (GLStates & GPU_BUFFER_COLOR_STATE) - glDisableClientState(GL_COLOR_ARRAY); - GLStates &= ~GPU_BUFFER_COLOR_STATE; - } -} - -static int gpu_binding_type_gl[] = -{ - GL_ARRAY_BUFFER, - GL_ELEMENT_ARRAY_BUFFER -}; - -void *GPU_buffer_lock(GPUBuffer *buffer, GPUBindingType binding) -{ - float *varray; - int bindtypegl; - - if (!buffer) - return 0; - - bindtypegl = gpu_binding_type_gl[binding]; - glBindBuffer(bindtypegl, buffer->id); - varray = glMapBuffer(bindtypegl, GL_WRITE_ONLY); - return varray; -} - -void *GPU_buffer_lock_stream(GPUBuffer *buffer, GPUBindingType binding) -{ - float *varray; - int bindtypegl; - - if (!buffer) - return 0; - - bindtypegl = gpu_binding_type_gl[binding]; - glBindBuffer(bindtypegl, buffer->id); - /* discard previous data, avoid stalling gpu */ - glBufferData(bindtypegl, buffer->size, 0, GL_STREAM_DRAW); - varray = glMapBuffer(bindtypegl, GL_WRITE_ONLY); - return varray; -} - -void GPU_buffer_unlock(GPUBuffer *UNUSED(buffer), GPUBindingType binding) -{ - int bindtypegl = gpu_binding_type_gl[binding]; - /* note: this operation can fail, could return - * an error code from this function? */ - glUnmapBuffer(bindtypegl); - glBindBuffer(bindtypegl, 0); -} - -void GPU_buffer_bind(GPUBuffer *buffer, GPUBindingType binding) -{ - int bindtypegl = gpu_binding_type_gl[binding]; - glBindBuffer(bindtypegl, buffer->id); -} - -void GPU_buffer_unbind(GPUBuffer *UNUSED(buffer), GPUBindingType binding) -{ - int bindtypegl = gpu_binding_type_gl[binding]; - glBindBuffer(bindtypegl, 0); -} - -/* used for drawing edges */ -void GPU_buffer_draw_elements(GPUBuffer *UNUSED(elements), unsigned int mode, int start, int count) -{ - glDrawElements(mode, count, GL_UNSIGNED_INT, BUFFER_OFFSET(start * sizeof(unsigned int))); -} - - /* XXX: the rest of the code in this file is used for optimized PBVH * drawing and doesn't interact at all with the buffer code above */ @@ -982,7 +108,6 @@ struct GPU_PBVH_Buffers { bool show_diffuse_color; bool show_mask; - bool use_matcaps; float diffuse_color[4]; }; @@ -990,6 +115,15 @@ static struct { uint pos, nor, col; } g_vbo_id = {0}; +static void gpu_material_diffuse_get(int UNUSED(nr), float diff[4]) +{ + /* TODO: sculpt diffuse color option not supported in 2.8 yet. */ + diff[0] = 0.8f; + diff[1] = 0.8f; + diff[2] = 0.8f; + diff[3] = 1.0f; +} + /* Allocates a non-initialized buffer to be sent to GPU. * Return is false it indicates that the memory map failed. */ static bool gpu_pbvh_vert_buf_data_set(GPU_PBVH_Buffers *buffers, unsigned int vert_ct) @@ -1086,19 +220,16 @@ void GPU_pbvh_mesh_buffers_update( buffers->vmask = vmask; buffers->show_diffuse_color = show_diffuse_color; buffers->show_mask = show_mask; - buffers->use_matcaps = GPU_material_use_matcaps_get(); { int totelem = (buffers->smooth ? totvert : (buffers->tot_tri * 3)); float diffuse_color[4] = {0.8f, 0.8f, 0.8f, 0.8f}; - if (buffers->use_matcaps) - diffuse_color[0] = diffuse_color[1] = diffuse_color[2] = 1.0; - else if (show_diffuse_color) { + if (show_diffuse_color) { const MLoopTri *lt = &buffers->looptri[buffers->face_indices[0]]; const MPoly *mp = &buffers->mpoly[lt->poly]; - GPU_material_diffuse_get(mp->mat_nr + 1, diffuse_color); + gpu_material_diffuse_get(mp->mat_nr + 1, diffuse_color); } copy_v4_v4(buffers->diffuse_color, diffuse_color); @@ -1210,7 +341,6 @@ GPU_PBVH_Buffers *GPU_pbvh_mesh_buffers_build( buffers->show_diffuse_color = false; buffers->show_mask = true; - buffers->use_matcaps = false; /* Count the number of visible triangles */ for (i = 0, tottri = 0; i < face_indices_len; ++i) { @@ -1283,7 +413,6 @@ void GPU_pbvh_grid_buffers_update( buffers->show_diffuse_color = show_diffuse_color; buffers->show_mask = show_mask; - buffers->use_matcaps = GPU_material_use_matcaps_get(); buffers->smooth = grid_flag_mats[grid_indices[0]].flag & ME_SMOOTH; /* Build VBO */ @@ -1291,13 +420,10 @@ void GPU_pbvh_grid_buffers_update( const int has_mask = key->has_mask; float diffuse_color[4] = {0.8f, 0.8f, 0.8f, 1.0f}; - if (buffers->use_matcaps) { - diffuse_color[0] = diffuse_color[1] = diffuse_color[2] = 1.0; - } - else if (show_diffuse_color) { + if (show_diffuse_color) { const DMFlagMat *flags = &grid_flag_mats[grid_indices[0]]; - GPU_material_diffuse_get(flags->mat_nr + 1, diffuse_color); + gpu_material_diffuse_get(flags->mat_nr + 1, diffuse_color); } copy_v4_v4(buffers->diffuse_color, diffuse_color); @@ -1504,7 +630,6 @@ GPU_PBVH_Buffers *GPU_pbvh_grid_buffers_build( buffers->show_diffuse_color = false; buffers->show_mask = true; - buffers->use_matcaps = false; /* Count the number of quads */ totquad = BKE_pbvh_count_grid_quads(grid_hidden, grid_indices, totgrid, gridsize); @@ -1661,7 +786,6 @@ void GPU_pbvh_bmesh_buffers_update( buffers->show_diffuse_color = show_diffuse_color; buffers->show_mask = show_mask; - buffers->use_matcaps = GPU_material_use_matcaps_get(); /* Count visible triangles */ tottri = gpu_bmesh_face_visible_count(bm_faces); @@ -1678,15 +802,13 @@ void GPU_pbvh_bmesh_buffers_update( return; } - if (buffers->use_matcaps) - diffuse_color[0] = diffuse_color[1] = diffuse_color[2] = 1.0; - else if (show_diffuse_color) { + if (show_diffuse_color) { /* due to dynamic nature of dyntopo, only get first material */ GSetIterator gs_iter; BMFace *f; BLI_gsetIterator_init(&gs_iter, bm_faces); f = BLI_gsetIterator_getKey(&gs_iter); - GPU_material_diffuse_get(f->mat_nr + 1, diffuse_color); + gpu_material_diffuse_get(f->mat_nr + 1, diffuse_color); } copy_v4_v4(buffers->diffuse_color, diffuse_color); @@ -1823,44 +945,10 @@ GPU_PBVH_Buffers *GPU_pbvh_bmesh_buffers_build(bool smooth_shading) buffers->smooth = smooth_shading; buffers->show_diffuse_color = false; buffers->show_mask = true; - buffers->use_matcaps = false; return buffers; } -void GPU_pbvh_buffers_draw( - GPU_PBVH_Buffers *buffers, DMSetMaterial setMaterial, - bool wireframe, bool fast) -{ - UNUSED_VARS(wireframe, fast, setMaterial); - bool do_fast = fast && buffers->triangles_fast; - Gwn_Batch *triangles = do_fast ? buffers->triangles_fast : buffers->triangles; - - if (triangles) { - - /* Simple Shader: use when drawing without the draw-manager (old 2.7x viewport) */ - if (triangles->interface == NULL) { - GPUBuiltinShader shader_id = - buffers->smooth ? GPU_SHADER_SIMPLE_LIGHTING_SMOOTH_COLOR : GPU_SHADER_SIMPLE_LIGHTING_FLAT_COLOR; - GPUShader *shader = GPU_shader_get_builtin_shader(shader_id); - - GWN_batch_program_set( - triangles, - GPU_shader_get_program(shader), GPU_shader_get_interface(shader)); - - static float light[3] = {-0.3f, 0.5f, 1.0f}; - static float alpha = 1.0f; - static float world_light = 1.0f; - - GPU_shader_uniform_vector(shader, GPU_shader_get_uniform(shader, "light"), 3, 1, light); - GPU_shader_uniform_vector(shader, GPU_shader_get_uniform(shader, "alpha"), 1, 1, &alpha); - GPU_shader_uniform_vector(shader, GPU_shader_get_uniform(shader, "global"), 1, 1, &world_light); - - } - GWN_batch_draw(triangles); - } -} - Gwn_Batch *GPU_pbvh_buffers_batch_get(GPU_PBVH_Buffers *buffers, bool fast) { return (fast && buffers->triangles_fast) ? @@ -1870,22 +958,18 @@ Gwn_Batch *GPU_pbvh_buffers_batch_get(GPU_PBVH_Buffers *buffers, bool fast) bool GPU_pbvh_buffers_diffuse_changed(GPU_PBVH_Buffers *buffers, GSet *bm_faces, bool show_diffuse_color) { float diffuse_color[4]; - bool use_matcaps = GPU_material_use_matcaps_get(); if (buffers->show_diffuse_color != show_diffuse_color) return true; - if (buffers->use_matcaps != use_matcaps) - return true; - - if ((buffers->show_diffuse_color == false) || use_matcaps) + if (buffers->show_diffuse_color == false) return false; if (buffers->looptri) { const MLoopTri *lt = &buffers->looptri[buffers->face_indices[0]]; const MPoly *mp = &buffers->mpoly[lt->poly]; - GPU_material_diffuse_get(mp->mat_nr + 1, diffuse_color); + gpu_material_diffuse_get(mp->mat_nr + 1, diffuse_color); } else if (buffers->use_bmesh) { /* due to dynamic nature of dyntopo, only get first material */ @@ -1895,7 +979,7 @@ bool GPU_pbvh_buffers_diffuse_changed(GPU_PBVH_Buffers *buffers, GSet *bm_faces, BLI_gsetIterator_init(&gs_iter, bm_faces); f = BLI_gsetIterator_getKey(&gs_iter); - GPU_material_diffuse_get(f->mat_nr + 1, diffuse_color); + gpu_material_diffuse_get(f->mat_nr + 1, diffuse_color); } else { return false; @@ -1904,7 +988,7 @@ bool GPU_pbvh_buffers_diffuse_changed(GPU_PBVH_Buffers *buffers, GSet *bm_faces, else { const DMFlagMat *flags = &buffers->grid_flag_mats[buffers->grid_indices[0]]; - GPU_material_diffuse_get(flags->mat_nr + 1, diffuse_color); + gpu_material_diffuse_get(flags->mat_nr + 1, diffuse_color); } return !equals_v3v3(diffuse_color, buffers->diffuse_color); @@ -2007,3 +1091,7 @@ void GPU_pbvh_BB_draw(float min[3], float max[3], bool leaf, unsigned int pos) immEnd(); } + +void GPU_pbvh_fix_linking() +{ +} diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c index b245c9a161f..da69d9cdb16 100644 --- a/source/blender/gpu/intern/gpu_codegen.c +++ b/source/blender/gpu/intern/gpu_codegen.c @@ -780,7 +780,7 @@ static void codegen_call_functions(DynStr *ds, ListBase *nodes, GPUOutput *final BLI_dynstr_append(ds, ";\n"); } -static char *code_generate_fragment(GPUMaterial *material, ListBase *nodes, GPUOutput *output, bool use_new_shading) +static char *code_generate_fragment(GPUMaterial *material, ListBase *nodes, GPUOutput *output) { DynStr *ds = BLI_dynstr_new(); char *code; @@ -806,38 +806,20 @@ static char *code_generate_fragment(GPUMaterial *material, ListBase *nodes, GPUO BLI_dynstr_append(ds, "Closure nodetree_exec(void)\n{\n"); - if (use_new_shading) { - if (builtins & GPU_VIEW_MATRIX) - BLI_dynstr_append(ds, "\tmat4 viewmat = ViewMatrix;\n"); - if (builtins & GPU_CAMERA_TEXCO_FACTORS) - BLI_dynstr_append(ds, "\tvec4 camtexfac = CameraTexCoFactors;\n"); - if (builtins & GPU_OBJECT_MATRIX) - BLI_dynstr_append(ds, "\tmat4 objmat = ModelMatrix;\n"); - if (builtins & GPU_INVERSE_OBJECT_MATRIX) - BLI_dynstr_append(ds, "\tmat4 objinv = ModelMatrixInverse;\n"); - if (builtins & GPU_INVERSE_VIEW_MATRIX) - BLI_dynstr_append(ds, "\tmat4 viewinv = ViewMatrixInverse;\n"); - if (builtins & GPU_VIEW_NORMAL) - BLI_dynstr_append(ds, "\tvec3 facingnormal = gl_FrontFacing? viewNormal: -viewNormal;\n"); - if (builtins & GPU_VIEW_POSITION) - BLI_dynstr_append(ds, "\tvec3 viewposition = viewPosition;\n"); - } - else { - if (builtins & GPU_VIEW_MATRIX) - BLI_dynstr_append(ds, "\tmat4 viewmat = unfviewmat;\n"); - if (builtins & GPU_CAMERA_TEXCO_FACTORS) - BLI_dynstr_append(ds, "\tvec4 camtexfac = unfcameratexfactors;\n"); - if (builtins & GPU_OBJECT_MATRIX) - BLI_dynstr_append(ds, "\tmat4 objmat = unfobmat;\n"); - if (builtins & GPU_INVERSE_OBJECT_MATRIX) - BLI_dynstr_append(ds, "\tmat4 objinv = unfinvobmat;\n"); - if (builtins & GPU_INVERSE_VIEW_MATRIX) - BLI_dynstr_append(ds, "\tmat4 viewinv = unfinvviewmat;\n"); - if (builtins & GPU_VIEW_NORMAL) - BLI_dynstr_append(ds, "\tvec3 facingnormal = gl_FrontFacing? varnormal: -varnormal;\n"); - if (builtins & GPU_VIEW_POSITION) - BLI_dynstr_append(ds, "\tvec3 viewposition = varposition;\n"); - } + if (builtins & GPU_VIEW_MATRIX) + BLI_dynstr_append(ds, "\tmat4 viewmat = ViewMatrix;\n"); + if (builtins & GPU_CAMERA_TEXCO_FACTORS) + BLI_dynstr_append(ds, "\tvec4 camtexfac = CameraTexCoFactors;\n"); + if (builtins & GPU_OBJECT_MATRIX) + BLI_dynstr_append(ds, "\tmat4 objmat = ModelMatrix;\n"); + if (builtins & GPU_INVERSE_OBJECT_MATRIX) + BLI_dynstr_append(ds, "\tmat4 objinv = ModelMatrixInverse;\n"); + if (builtins & GPU_INVERSE_VIEW_MATRIX) + BLI_dynstr_append(ds, "\tmat4 viewinv = ViewMatrixInverse;\n"); + if (builtins & GPU_VIEW_NORMAL) + BLI_dynstr_append(ds, "\tvec3 facingnormal = gl_FrontFacing? viewNormal: -viewNormal;\n"); + if (builtins & GPU_VIEW_POSITION) + BLI_dynstr_append(ds, "\tvec3 viewposition = viewPosition;\n"); /* Calculate tangent space. */ #ifdef WITH_OPENSUBDIV @@ -906,7 +888,7 @@ static const char *attrib_prefix_get(CustomDataType type) } } -static char *code_generate_vertex_new(ListBase *nodes, const char *vert_code, bool use_geom) +static char *code_generate_vertex(ListBase *nodes, const char *vert_code, bool use_geom) { DynStr *ds = BLI_dynstr_new(); GPUNode *node; @@ -983,115 +965,7 @@ static char *code_generate_vertex_new(ListBase *nodes, const char *vert_code, bo return code; } -static char *code_generate_vertex(ListBase *nodes, const GPUMatType type) -{ - DynStr *ds = BLI_dynstr_new(); - GPUNode *node; - GPUInput *input; - char *code; - char *vertcode = NULL; - - for (node = nodes->first; node; node = node->next) { - for (input = node->inputs.first; input; input = input->next) { - if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) { -#ifdef WITH_OPENSUBDIV - bool skip_opensubdiv = ELEM(input->attribtype, CD_MTFACE, CD_TANGENT); - if (skip_opensubdiv) { - BLI_dynstr_appendf(ds, "#ifndef USE_OPENSUBDIV\n"); - } -#endif - BLI_dynstr_appendf(ds, "%s %s att%d;\n", - GLEW_VERSION_3_0 ? "in" : "attribute", - GPU_DATATYPE_STR[input->type], input->attribid); - BLI_dynstr_appendf(ds, "uniform int att%d_info;\n", input->attribid); - BLI_dynstr_appendf(ds, "%s %s var%d;\n", - GLEW_VERSION_3_0 ? "out" : "varying", - GPU_DATATYPE_STR[input->type], input->attribid); -#ifdef WITH_OPENSUBDIV - if (skip_opensubdiv) { - BLI_dynstr_appendf(ds, "#endif\n"); - } -#endif - } - } - } - - BLI_dynstr_append(ds, "\n"); - - switch (type) { - case GPU_MATERIAL_TYPE_MESH: - vertcode = datatoc_gpu_shader_vertex_glsl; - break; - case GPU_MATERIAL_TYPE_WORLD: - vertcode = datatoc_gpu_shader_vertex_world_glsl; - break; - default: - fprintf(stderr, "invalid material type, set one after GPU_material_construct_begin\n"); - break; - } - - BLI_dynstr_append(ds, vertcode); - - for (node = nodes->first; node; node = node->next) - for (input = node->inputs.first; input; input = input->next) - if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) { - if (input->attribtype == CD_TANGENT) { /* silly exception */ -#ifdef WITH_OPENSUBDIV - BLI_dynstr_appendf(ds, "#ifndef USE_OPENSUBDIV\n"); -#endif - BLI_dynstr_appendf( - ds, "\tvar%d.xyz = normalize(NormalMatrix * att%d.xyz);\n", - input->attribid, input->attribid); - BLI_dynstr_appendf( - ds, "\tvar%d.w = att%d.w;\n", - input->attribid, input->attribid); -#ifdef WITH_OPENSUBDIV - BLI_dynstr_appendf(ds, "#endif\n"); -#endif - } - else { -#ifdef WITH_OPENSUBDIV - bool is_mtface = input->attribtype == CD_MTFACE; - if (is_mtface) { - BLI_dynstr_appendf(ds, "#ifndef USE_OPENSUBDIV\n"); - } -#endif - BLI_dynstr_appendf(ds, "\tset_var_from_attr(att%d, att%d_info, var%d);\n", - input->attribid, input->attribid, input->attribid); -#ifdef WITH_OPENSUBDIV - if (is_mtface) { - BLI_dynstr_appendf(ds, "#endif\n"); - } -#endif - } - } - /* unfortunately special handling is needed here because we abuse gl_Color/gl_SecondaryColor flat shading */ - else if (input->source == GPU_SOURCE_OPENGL_BUILTIN) { - if (input->oglbuiltin == GPU_MATCAP_NORMAL) { - /* remap to 0.0 - 1.0 range. This is done because OpenGL 2.0 clamps colors - * between shader stages and we want the full range of the normal */ - BLI_dynstr_appendf(ds, "\tvec3 matcapcol = vec3(0.5) * varnormal + vec3(0.5);\n"); - BLI_dynstr_appendf(ds, "\tgl_FrontSecondaryColor = vec4(matcapcol, 1.0);\n"); - } - else if (input->oglbuiltin == GPU_COLOR) { - BLI_dynstr_appendf(ds, "\tgl_FrontColor = gl_Color;\n"); - } - } - - BLI_dynstr_append(ds, "}\n"); - - code = BLI_dynstr_get_cstring(ds); - - BLI_dynstr_free(ds); - -#if 0 - if (G.debug & G_DEBUG) printf("%s\n", code); -#endif - - return code; -} - -static char *code_generate_geometry_new(ListBase *nodes, const char *geom_code) +static char *code_generate_geometry(ListBase *nodes, const char *geom_code) { DynStr *ds = BLI_dynstr_new(); GPUNode *node; @@ -1136,67 +1010,6 @@ static char *code_generate_geometry_new(ListBase *nodes, const char *geom_code) return code; } -static char *code_generate_geometry(ListBase *nodes, bool use_opensubdiv) -{ -#ifdef WITH_OPENSUBDIV - if (use_opensubdiv) { - DynStr *ds = BLI_dynstr_new(); - GPUNode *node; - GPUInput *input; - char *code; - - /* Generate varying declarations. */ - for (node = nodes->first; node; node = node->next) { - for (input = node->inputs.first; input; input = input->next) { - if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) { - if (input->attribtype == CD_MTFACE) { - /* NOTE: For now we are using varying on purpose, - * otherwise we are not able to write to the varying. - */ - BLI_dynstr_appendf(ds, "%s %s var%d%s;\n", - "varying", - GPU_DATATYPE_STR[input->type], - input->attribid, - ""); - BLI_dynstr_appendf(ds, "uniform int fvar%d_offset;\n", - input->attribid); - } - } - } - } - - BLI_dynstr_append(ds, datatoc_gpu_shader_geometry_glsl); - - /* Generate varying assignments. */ - for (node = nodes->first; node; node = node->next) { - for (input = node->inputs.first; input; input = input->next) { - if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) { - if (input->attribtype == CD_MTFACE) { - BLI_dynstr_appendf( - ds, - "\tINTERP_FACE_VARYING_ATT_2(var%d, " - "int(texelFetch(FVarDataOffsetBuffer, fvar%d_offset).r), st);\n", - input->attribid, - input->attribid); - } - } - } - } - - BLI_dynstr_append(ds, "}\n"); - code = BLI_dynstr_get_cstring(ds); - BLI_dynstr_free(ds); - - //if (G.debug & G_DEBUG) printf("%s\n", code); - - return code; - } -#else - UNUSED_VARS(nodes, use_opensubdiv); -#endif - return NULL; -} - void GPU_code_generate_glsl_lib(void) { DynStr *ds; @@ -1223,65 +1036,6 @@ GPUShader *GPU_pass_shader(GPUPass *pass) return pass->shader; } -static void gpu_nodes_extract_dynamic_inputs_new(GPUShader *shader, ListBase *inputs, ListBase *nodes) -{ - GPUNode *node; - GPUInput *next, *input; - int extract, z; - - BLI_listbase_clear(inputs); - - if (!shader) - return; - - GPU_shader_bind(shader); - - for (node = nodes->first; node; node = node->next) { - z = 0; - for (input = node->inputs.first; input; input = next, z++) { - next = input->next; - - /* attributes don't need to be bound, they already have - * an id that the drawing functions will use */ - if (input->source == GPU_SOURCE_ATTRIB) { - continue; - } - - if (input->source == GPU_SOURCE_BUILTIN || - input->source == GPU_SOURCE_OPENGL_BUILTIN) - { - continue; - } - - if (input->ima || input->tex || input->prv) - BLI_snprintf(input->shadername, sizeof(input->shadername), "samp%d", input->texid); - else - BLI_snprintf(input->shadername, sizeof(input->shadername), "unf%d", input->id); - - /* pass non-dynamic uniforms to opengl */ - extract = 0; - - if (input->ima || input->tex || input->prv) { - if (input->bindtex) - extract = 1; - } - else if (input->dynamicvec) - extract = 1; - - if (extract) - input->shaderloc = GPU_shader_get_uniform(shader, input->shadername); - - /* extract nodes */ - if (extract) { - BLI_remlink(&node->inputs, input); - BLI_addtail(inputs, input); - } - } - } - - GPU_shader_unbind(); -} - static void gpu_nodes_extract_dynamic_inputs(GPUShader *shader, ListBase *inputs, ListBase *nodes) { GPUNode *node; @@ -1303,26 +1057,9 @@ static void gpu_nodes_extract_dynamic_inputs(GPUShader *shader, ListBase *inputs /* attributes don't need to be bound, they already have * an id that the drawing functions will use */ if (input->source == GPU_SOURCE_ATTRIB) { -#ifdef WITH_OPENSUBDIV - /* We do need mtface attributes for later, so we can - * update face-varuing variables offset in the texture - * buffer for proper sampling from the shader. - * - * We don't do anything about attribute itself, we - * only use it to learn which uniform name is to be - * updated. - * - * TODO(sergey): We can add ad extra uniform input - * for the offset, which will be purely internal and - * which would avoid having such an exceptions. - */ - if (input->attribtype != CD_MTFACE) { - continue; - } -#else continue; -#endif } + if (input->source == GPU_SOURCE_BUILTIN || input->source == GPU_SOURCE_OPENGL_BUILTIN) { @@ -1347,14 +1084,6 @@ static void gpu_nodes_extract_dynamic_inputs(GPUShader *shader, ListBase *inputs if (extract) input->shaderloc = GPU_shader_get_uniform(shader, input->shadername); -#ifdef WITH_OPENSUBDIV - if (input->source == GPU_SOURCE_ATTRIB && - input->attribtype == CD_MTFACE) - { - extract = 1; - } -#endif - /* extract nodes */ if (extract) { BLI_remlink(&node->inputs, input); @@ -1802,19 +1531,6 @@ void GPU_nodes_get_vertex_attributes(ListBase *nodes, GPUVertexAttribs *attribs) } } -static void gpu_nodes_get_builtin_flag(ListBase *nodes, int *builtin) -{ - GPUNode *node; - GPUInput *input; - - *builtin = 0; - - for (node = nodes->first; node; node = node->next) - for (input = node->inputs.first; input; input = input->next) - if (input->source == GPU_SOURCE_BUILTIN) - *builtin |= input->builtin; -} - /* varargs linking */ GPUNodeLink *GPU_attribute(const CustomDataType type, const char *name) @@ -2129,11 +1845,11 @@ GPUPass *GPU_generate_pass_new( GPU_nodes_get_vertex_attributes(nodes, attribs); /* generate code */ - char *fragmentgen = code_generate_fragment(material, nodes, frag_outlink->output, true); + char *fragmentgen = code_generate_fragment(material, nodes, frag_outlink->output); char *tmp = BLI_strdupcat(frag_lib, glsl_material_library); - vertexcode = code_generate_vertex_new(nodes, vert_code, (geom_code != NULL)); - geometrycode = (geom_code) ? code_generate_geometry_new(nodes, geom_code) : NULL; + vertexcode = code_generate_vertex(nodes, vert_code, (geom_code != NULL)); + geometrycode = (geom_code) ? code_generate_geometry(nodes, geom_code) : NULL; fragmentcode = BLI_strdupcat(tmp, fragmentgen); MEM_freeN(fragmentgen); @@ -2182,85 +1898,11 @@ GPUPass *GPU_generate_pass_new( return NULL; } else { - gpu_nodes_extract_dynamic_inputs_new(shader, inputs, nodes); + gpu_nodes_extract_dynamic_inputs(shader, inputs, nodes); return pass; } } -/* TODO(fclem) Remove for 2.8 */ -GPUPass *GPU_generate_pass( - ListBase *nodes, ListBase *inputs, GPUNodeLink *outlink, - GPUVertexAttribs *attribs, int *builtins, - const GPUMatType type, const char *UNUSED(name), - const bool use_opensubdiv, - const bool use_new_shading) -{ - GPUShader *shader; - GPUPass *pass; - char *vertexcode, *geometrycode, *fragmentcode; - -#if 0 - if (!FUNCTION_LIB) { - GPU_nodes_free(nodes); - return NULL; - } -#endif - - /* prune unused nodes */ - GPU_nodes_prune(nodes, outlink); - - GPU_nodes_get_vertex_attributes(nodes, attribs); - gpu_nodes_get_builtin_flag(nodes, builtins); - - /* generate code and compile with opengl */ - fragmentcode = code_generate_fragment(NULL, nodes, outlink->output, false); - vertexcode = code_generate_vertex(nodes, type); - geometrycode = code_generate_geometry(nodes, use_opensubdiv); - - int flags = GPU_SHADER_FLAGS_NONE; - if (use_opensubdiv) { - flags |= GPU_SHADER_FLAGS_SPECIAL_OPENSUBDIV; - } - if (use_new_shading) { - flags |= GPU_SHADER_FLAGS_NEW_SHADING; - } - shader = GPU_shader_create_ex(vertexcode, - fragmentcode, - geometrycode, - glsl_material_library, - NULL, - flags); - - /* failed? */ - if (!shader) { - if (fragmentcode) - MEM_freeN(fragmentcode); - if (vertexcode) - MEM_freeN(vertexcode); - memset(attribs, 0, sizeof(*attribs)); - memset(builtins, 0, sizeof(*builtins)); - gpu_nodes_free(nodes); - return NULL; - } - - /* create pass */ - pass = MEM_callocN(sizeof(GPUPass), "GPUPass"); - pass->refcount = 1; - pass->shader = shader; - pass->fragmentcode = fragmentcode; - pass->geometrycode = geometrycode; - pass->vertexcode = vertexcode; - pass->libcode = glsl_material_library; - - BLI_linklist_prepend(&pass_cache, pass); - - /* extract dynamic inputs and throw away nodes */ - gpu_nodes_extract_dynamic_inputs(shader, inputs, nodes); - gpu_nodes_free(nodes); - - return pass; -} - void GPU_pass_release(GPUPass *pass) { BLI_assert(pass->refcount > 0); diff --git a/source/blender/gpu/intern/gpu_codegen.h b/source/blender/gpu/intern/gpu_codegen.h index dab0bc3f8b1..328da36c3de 100644 --- a/source/blender/gpu/intern/gpu_codegen.h +++ b/source/blender/gpu/intern/gpu_codegen.h @@ -180,8 +180,7 @@ GPUPass *GPU_generate_pass( ListBase *nodes, ListBase *inputs, struct GPUNodeLink *outlink, struct GPUVertexAttribs *attribs, int *builtin, const GPUMatType type, const char *name, - const bool use_opensubdiv, - const bool use_new_shading); + const bool use_opensubdiv); struct GPUShader *GPU_pass_shader(GPUPass *pass); diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c index 5d9270223ab..6b768d4bdd6 100644 --- a/source/blender/gpu/intern/gpu_draw.c +++ b/source/blender/gpu/intern/gpu_draw.c @@ -72,7 +72,6 @@ #include "BKE_DerivedMesh.h" #include "GPU_basic_shader.h" -#include "GPU_buffers.h" #include "GPU_draw.h" #include "GPU_extensions.h" #include "GPU_material.h" @@ -240,38 +239,6 @@ static unsigned int *gpu_get_image_bindcode(Image *ima, GLenum textarget) return bind; } -static void gpu_set_alpha_blend(GPUBlendMode alphablend) -{ - if (alphablend == GPU_BLEND_SOLID) { - glDisable(GL_BLEND); - glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE); - glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - } - else if (alphablend == GPU_BLEND_ADD) { - glEnable(GL_BLEND); - glBlendFunc(GL_ONE, GL_ONE); - glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE); - } - else if (ELEM(alphablend, GPU_BLEND_ALPHA, GPU_BLEND_ALPHA_SORT)) { - glEnable(GL_BLEND); - glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE); - - /* for OpenGL render we use the alpha channel, this makes alpha blend correct */ - glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - - /* if U.glalphaclip == 1.0, some cards go bonkers... - * turn off alpha test in this case */ - - } - else if (alphablend == GPU_BLEND_CLIP) { - glDisable(GL_BLEND); - glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE); - } - else if (alphablend == GPU_BLEND_ALPHA_TO_COVERAGE) { - glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE); - } -} - typedef struct VerifyThreadData { ImBuf *ibuf; float *srgb_frect; @@ -1038,9 +1005,6 @@ void GPU_free_unused_buffers(void) BLI_linklist_free(image_free_queue, NULL); image_free_queue = NULL; - /* vbo buffers */ - GPU_global_buffer_pool_free_unused(); - BLI_thread_unlock(LOCK_OPENGL); } @@ -1120,652 +1084,6 @@ void GPU_free_images_old(void) } } - -/* OpenGL Materials */ - -#define FIXEDMAT 8 - -/* OpenGL state caching for materials */ - -typedef struct GPUMaterialFixed { - float diff[3]; - float spec[3]; - int hard; - float alpha; -} GPUMaterialFixed; - -static struct GPUMaterialState { - GPUMaterialFixed (*matbuf); - GPUMaterialFixed matbuf_fixed[FIXEDMAT]; - int totmat; - - /* set when called inside GPU_begin_object_materials / GPU_end_object_materials - * otherwise calling GPU_object_material_bind returns zero */ - bool is_enabled; - - Material **gmatbuf; - Material *gmatbuf_fixed[FIXEDMAT]; - Material *gboundmat; - Object *gob; - DupliObject *dob; - Scene *gscene; - int glay; - float (*gviewmat)[4]; - float (*gviewinv)[4]; - float (*gviewcamtexcofac); - - bool backface_culling; - bool two_sided_lighting; - - GPUBlendMode *alphablend; - GPUBlendMode alphablend_fixed[FIXEDMAT]; - bool use_alpha_pass, is_alpha_pass; - bool use_matcaps; - - int lastmatnr, lastretval; - GPUBlendMode lastalphablend; - bool is_opensubdiv; -} GMS = {NULL}; - -/* fixed function material, alpha handed by caller */ -static void gpu_material_to_fixed( - GPUMaterialFixed *smat, const Material *bmat, const int gamma, const Object *ob, - const int new_shading_nodes, const bool dimdown) -{ - if (bmat->mode & MA_SHLESS) { - copy_v3_v3(smat->diff, &bmat->r); - - if (gamma) - linearrgb_to_srgb_v3_v3(smat->diff, smat->diff); - - zero_v3(smat->spec); - smat->alpha = 1.0f; - smat->hard = 0; - } - else if (new_shading_nodes) { - copy_v3_v3(smat->diff, &bmat->r); - copy_v3_v3(smat->spec, &bmat->specr); - smat->alpha = 1.0f; - smat->hard = CLAMPIS(bmat->har, 0, 128); - - if (dimdown) { - mul_v3_fl(smat->diff, 0.8f); - mul_v3_fl(smat->spec, 0.5f); - } - - if (gamma) { - linearrgb_to_srgb_v3_v3(smat->diff, smat->diff); - linearrgb_to_srgb_v3_v3(smat->spec, smat->spec); - } - } - else { - mul_v3_v3fl(smat->diff, &bmat->r, bmat->ref + bmat->emit); - - if (bmat->shade_flag & MA_OBCOLOR) - mul_v3_v3(smat->diff, ob->col); - - mul_v3_v3fl(smat->spec, &bmat->specr, bmat->spec); - smat->hard = CLAMPIS(bmat->har, 1, 128); - smat->alpha = 1.0f; - - if (gamma) { - linearrgb_to_srgb_v3_v3(smat->diff, smat->diff); - linearrgb_to_srgb_v3_v3(smat->spec, smat->spec); - } - } -} - -static Material *gpu_active_node_material(Material *ma) -{ - if (ma && ma->use_nodes && ma->nodetree) { - bNode *node = nodeGetActiveID(ma->nodetree, ID_MA); - - if (node) - return (Material *)node->id; - else - return NULL; - } - - return ma; -} - -void GPU_begin_dupli_object(DupliObject *dob) -{ - GMS.dob = dob; -} - -void GPU_end_dupli_object(void) -{ - GMS.dob = NULL; -} - -void GPU_begin_object_materials( - View3D *v3d, RegionView3D *rv3d, Scene *scene, ViewLayer *UNUSED(view_layer), Object *ob, - bool glsl, bool *do_alpha_after) -{ - Material *ma; - GPUMaterial *gpumat; - GPUBlendMode alphablend; - DupliObject *dob; - int a; - const bool gamma = BKE_scene_check_color_management_enabled(scene); - const bool new_shading_nodes = BKE_scene_use_new_shading_nodes(scene); - const bool use_matcap = (v3d->flag2 & V3D_SHOW_SOLID_MATCAP) != 0; /* assumes v3d->defmaterial->preview is set */ - bool use_opensubdiv = false; - -#ifdef WITH_OPENSUBDIV - { - DerivedMesh *derivedFinal = NULL; - if (ob->type == OB_MESH) { - Mesh *me = ob->data; - BMEditMesh *em = me->edit_btmesh; - if (em != NULL) { - derivedFinal = em->derivedFinal; - } - else { - derivedFinal = ob->derivedFinal; - } - } - else { - derivedFinal = ob->derivedFinal; - } - - if (derivedFinal != NULL && derivedFinal->type == DM_TYPE_CCGDM) { - CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) derivedFinal; - use_opensubdiv = ccgdm->useGpuBackend; - } - } -#endif - - /* initialize state */ - /* DupliObject must be restored */ - dob = GMS.dob; - memset(&GMS, 0, sizeof(GMS)); - GMS.is_enabled = true; - GMS.dob = dob; - GMS.lastmatnr = -1; - GMS.lastretval = -1; - GMS.lastalphablend = GPU_BLEND_SOLID; - GMS.use_matcaps = use_matcap; - - GMS.backface_culling = (v3d->flag2 & V3D_BACKFACE_CULLING) != 0; - - GMS.two_sided_lighting = false; - if (ob && ob->type == OB_MESH) - GMS.two_sided_lighting = (((Mesh *)ob->data)->flag & ME_TWOSIDED) != 0; - - GMS.gob = ob; - GMS.gscene = scene; - GMS.is_opensubdiv = use_opensubdiv; - GMS.totmat = use_matcap ? 1 : ob->totcol + 1; /* materials start from 1, default material is 0 */ - GMS.glay = (v3d->localvd) ? v3d->localvd->lay : v3d->lay; /* keep lamps visible in local view */ - GMS.gviewmat = rv3d->viewmat; - GMS.gviewinv = rv3d->viewinv; - GMS.gviewcamtexcofac = rv3d->viewcamtexcofac; - - /* alpha pass setup. there's various cases to handle here: - * - object transparency on: only solid materials draw in the first pass, - * and only transparent in the second 'alpha' pass. - * - object transparency off: for glsl we draw both in a single pass, and - * for solid we don't use transparency at all. */ - GMS.use_alpha_pass = (do_alpha_after != NULL); - GMS.is_alpha_pass = (v3d->transp != false); - if (GMS.use_alpha_pass) - *do_alpha_after = false; - - if (GMS.totmat > FIXEDMAT) { - GMS.matbuf = MEM_callocN(sizeof(GPUMaterialFixed) * GMS.totmat, "GMS.matbuf"); - GMS.gmatbuf = MEM_callocN(sizeof(*GMS.gmatbuf) * GMS.totmat, "GMS.matbuf"); - GMS.alphablend = MEM_callocN(sizeof(*GMS.alphablend) * GMS.totmat, "GMS.matbuf"); - } - else { - GMS.matbuf = GMS.matbuf_fixed; - GMS.gmatbuf = GMS.gmatbuf_fixed; - GMS.alphablend = GMS.alphablend_fixed; - } - - /* viewport material, setup in space_view3d, defaults to matcap using ma->preview now */ - if (use_matcap) { - GMS.gmatbuf[0] = v3d->defmaterial; - GPU_material_matcap(scene, v3d->defmaterial, use_opensubdiv); - - /* do material 1 too, for displists! */ - memcpy(&GMS.matbuf[1], &GMS.matbuf[0], sizeof(GPUMaterialFixed)); - - GMS.alphablend[0] = GPU_BLEND_SOLID; - } - else { - - /* no materials assigned? */ - if (ob->totcol == 0) { - gpu_material_to_fixed(&GMS.matbuf[0], &defmaterial, 0, ob, new_shading_nodes, true); - - /* do material 1 too, for displists! */ - memcpy(&GMS.matbuf[1], &GMS.matbuf[0], sizeof(GPUMaterialFixed)); - - if (glsl) { - GMS.gmatbuf[0] = &defmaterial; - GPU_material_from_blender(GMS.gscene, &defmaterial, GMS.is_opensubdiv); - } - - GMS.alphablend[0] = GPU_BLEND_SOLID; - } - - /* setup materials */ - for (a = 1; a <= ob->totcol; a++) { - /* find a suitable material */ - ma = give_current_material(ob, a); - if (!glsl && !new_shading_nodes) ma = gpu_active_node_material(ma); - if (ma == NULL) ma = &defmaterial; - - /* create glsl material if requested */ - gpumat = glsl ? GPU_material_from_blender(GMS.gscene, ma, GMS.is_opensubdiv) : NULL; - - if (gpumat) { - /* do glsl only if creating it succeed, else fallback */ - GMS.gmatbuf[a] = ma; - alphablend = GPU_material_alpha_blend(gpumat, ob->col); - } - else { - /* fixed function opengl materials */ - gpu_material_to_fixed(&GMS.matbuf[a], ma, gamma, ob, new_shading_nodes, false); - - if (GMS.use_alpha_pass && ((ma->mode & MA_TRANSP) || (new_shading_nodes && ma->alpha != 1.0f))) { - GMS.matbuf[a].alpha = ma->alpha; - alphablend = (ma->alpha == 1.0f) ? GPU_BLEND_SOLID: GPU_BLEND_ALPHA; - } - else { - GMS.matbuf[a].alpha = 1.0f; - alphablend = GPU_BLEND_SOLID; - } - } - - /* setting 'do_alpha_after = true' indicates this object needs to be - * drawn in a second alpha pass for improved blending */ - if (do_alpha_after && !GMS.is_alpha_pass) - if (ELEM(alphablend, GPU_BLEND_ALPHA, GPU_BLEND_ADD, GPU_BLEND_ALPHA_SORT)) - *do_alpha_after = true; - - GMS.alphablend[a] = alphablend; - } - } - - /* let's start with a clean state */ - GPU_object_material_unbind(); -} - -static int gpu_get_particle_info(GPUParticleInfo *pi) -{ - DupliObject *dob = GMS.dob; - if (dob->particle_system) { - int ind; - if (dob->persistent_id[0] < dob->particle_system->totpart) - ind = dob->persistent_id[0]; - else { - ind = dob->particle_system->child[dob->persistent_id[0] - dob->particle_system->totpart].parent; - } - if (ind >= 0) { - ParticleData *p = &dob->particle_system->particles[ind]; - - pi->scalprops[0] = ind; - pi->scalprops[1] = GMS.gscene->r.cfra - p->time; - pi->scalprops[2] = p->lifetime; - pi->scalprops[3] = p->size; - - copy_v3_v3(pi->location, p->state.co); - pi->location[3] = BLI_hash_int_01(ind); - - copy_v3_v3(pi->velocity, p->state.vel); - copy_v3_v3(pi->angular_velocity, p->state.ave); - return 1; - } - else return 0; - } - else - return 0; -} - -static void GPU_get_object_info(float oi[3], Material *mat) -{ - Object *ob = GMS.gob; - oi[0] = ob->index; - oi[1] = mat->index; - unsigned int random; - if (GMS.dob) { - random = GMS.dob->random_id; - } - else { - random = BLI_hash_int_2d(BLI_hash_string(GMS.gob->id.name + 2), 0); - } - oi[2] = random * (1.0f / (float)0xFFFFFFFF); -} - -int GPU_object_material_bind(int nr, void *attribs) -{ - GPUVertexAttribs *gattribs = attribs; - - /* no GPU_begin_object_materials, use default material */ - if (!GMS.matbuf) { - memset(&GMS, 0, sizeof(GMS)); - - float diffuse[3], specular[3]; - mul_v3_v3fl(diffuse, &defmaterial.r, defmaterial.ref + defmaterial.emit); - mul_v3_v3fl(specular, &defmaterial.specr, defmaterial.spec); - GPU_basic_shader_colors(diffuse, specular, 35, 1.0f); - - if (GMS.two_sided_lighting) - GPU_basic_shader_bind(GPU_SHADER_LIGHTING | GPU_SHADER_TWO_SIDED); - else - GPU_basic_shader_bind(GPU_SHADER_LIGHTING); - - return 0; - } - - /* prevent index to use un-initialized array items */ - if (nr >= GMS.totmat) - nr = 0; - - if (gattribs) - memset(gattribs, 0, sizeof(*gattribs)); - - /* keep current material */ - if (nr == GMS.lastmatnr) - return GMS.lastretval; - - /* unbind glsl material */ - if (GMS.gboundmat) { - if (GMS.is_alpha_pass) glDepthMask(0); - GPU_material_unbind(GPU_material_from_blender(GMS.gscene, GMS.gboundmat, GMS.is_opensubdiv)); - GMS.gboundmat = NULL; - } - - /* draw materials with alpha in alpha pass */ - GMS.lastmatnr = nr; - GMS.lastretval = 1; - - if (GMS.use_alpha_pass) { - GMS.lastretval = ELEM(GMS.alphablend[nr], GPU_BLEND_SOLID, GPU_BLEND_CLIP); - if (GMS.is_alpha_pass) - GMS.lastretval = !GMS.lastretval; - } - else - GMS.lastretval = !GMS.is_alpha_pass; - - if (GMS.lastretval) { - /* for alpha pass, use alpha blend */ - GPUBlendMode alphablend = GMS.alphablend[nr]; - - if (gattribs && GMS.gmatbuf[nr]) { - /* bind glsl material and get attributes */ - Material *mat = GMS.gmatbuf[nr]; - GPUParticleInfo partile_info; - float object_info[3] = {0}; - - float auto_bump_scale; - - GPUMaterial *gpumat = GPU_material_from_blender(GMS.gscene, mat, GMS.is_opensubdiv); - GPU_material_vertex_attributes(gpumat, gattribs); - - if (GMS.dob) { - gpu_get_particle_info(&partile_info); - } - - if ((GPU_get_material_builtins(gpumat) & GPU_OBJECT_INFO) != 0) { - GPU_get_object_info(object_info, mat); - } - - GPU_material_bind( - gpumat, GMS.gob->lay, GMS.glay, 1.0, !(GMS.gob->mode & OB_MODE_TEXTURE_PAINT), - GMS.gviewmat, GMS.gviewinv, GMS.gviewcamtexcofac); - - auto_bump_scale = GMS.gob->derivedFinal != NULL ? GMS.gob->derivedFinal->auto_bump_scale : 1.0f; - GPU_material_bind_uniforms(gpumat, GMS.gob->obmat, GMS.gviewmat, GMS.gob->col, auto_bump_scale, &partile_info, object_info); - GMS.gboundmat = mat; - - if (GMS.is_alpha_pass) glDepthMask(1); - - if (GMS.backface_culling) { - glDisable(GL_CULL_FACE); - } - - if (GMS.use_matcaps) - glColor3f(1.0f, 1.0f, 1.0f); - } - else { - /* or do fixed function opengl material */ - GPU_basic_shader_colors( - GMS.matbuf[nr].diff, - GMS.matbuf[nr].spec, GMS.matbuf[nr].hard, GMS.matbuf[nr].alpha); - - if (GMS.two_sided_lighting) - GPU_basic_shader_bind(GPU_SHADER_LIGHTING | GPU_SHADER_TWO_SIDED); - else - GPU_basic_shader_bind(GPU_SHADER_LIGHTING); - } - - /* set (alpha) blending mode */ - GPU_set_material_alpha_blend(alphablend); - } - - return GMS.lastretval; -} - -int GPU_object_material_visible(int nr, void *attribs) -{ - GPUVertexAttribs *gattribs = attribs; - int visible; - - if (!GMS.matbuf) - return 0; - - if (gattribs) - memset(gattribs, 0, sizeof(*gattribs)); - - if (nr >= GMS.totmat) - nr = 0; - - if (GMS.use_alpha_pass) { - visible = ELEM(GMS.alphablend[nr], GPU_BLEND_SOLID, GPU_BLEND_CLIP); - if (GMS.is_alpha_pass) - visible = !visible; - } - else - visible = !GMS.is_alpha_pass; - - return visible; -} - -void GPU_set_material_alpha_blend(int alphablend) -{ - if (GMS.lastalphablend == alphablend) - return; - - gpu_set_alpha_blend(alphablend); - GMS.lastalphablend = alphablend; -} - -int GPU_get_material_alpha_blend(void) -{ - return GMS.lastalphablend; -} - -void GPU_object_material_unbind(void) -{ - GMS.lastmatnr = -1; - GMS.lastretval = 1; - - if (GMS.gboundmat) { - if (GMS.backface_culling) - glDisable(GL_CULL_FACE); - - if (GMS.is_alpha_pass) glDepthMask(0); - GPU_material_unbind(GPU_material_from_blender(GMS.gscene, GMS.gboundmat, GMS.is_opensubdiv)); - GMS.gboundmat = NULL; - } - else - GPU_basic_shader_bind(GPU_SHADER_USE_COLOR); - - GPU_set_material_alpha_blend(GPU_BLEND_SOLID); -} - -void GPU_material_diffuse_get(int nr, float diff[4]) -{ - /* prevent index to use un-initialized array items */ - if (nr >= GMS.totmat) - nr = 0; - - /* no GPU_begin_object_materials, use default material */ - if (!GMS.matbuf) { - mul_v3_v3fl(diff, &defmaterial.r, defmaterial.ref + defmaterial.emit); - } - else { - copy_v3_v3(diff, GMS.matbuf[nr].diff); - diff[3] = GMS.matbuf[nr].alpha; - } -} - -bool GPU_material_use_matcaps_get(void) -{ - return GMS.use_matcaps; -} - -bool GPU_object_materials_check(void) -{ - return GMS.is_enabled; -} - -void GPU_end_object_materials(void) -{ - GPU_object_material_unbind(); - - GMS.is_enabled = false; - - if (GMS.matbuf && GMS.matbuf != GMS.matbuf_fixed) { - MEM_freeN(GMS.matbuf); - MEM_freeN(GMS.gmatbuf); - MEM_freeN(GMS.alphablend); - } - - GMS.matbuf = NULL; - GMS.gmatbuf = NULL; - GMS.alphablend = NULL; - GMS.two_sided_lighting = false; -} - -/* Lights */ - -int GPU_default_lights(void) -{ - /* initialize */ - if (U.light[0].flag == 0 && U.light[1].flag == 0 && U.light[2].flag == 0) { - U.light[0].flag = 1; - U.light[0].vec[0] = -0.3; U.light[0].vec[1] = 0.3; U.light[0].vec[2] = 0.9; - U.light[0].col[0] = 0.8; U.light[0].col[1] = 0.8; U.light[0].col[2] = 0.8; - U.light[0].spec[0] = 0.5; U.light[0].spec[1] = 0.5; U.light[0].spec[2] = 0.5; - U.light[0].spec[3] = 1.0; - - U.light[1].flag = 0; - U.light[1].vec[0] = 0.5; U.light[1].vec[1] = 0.5; U.light[1].vec[2] = 0.1; - U.light[1].col[0] = 0.4; U.light[1].col[1] = 0.4; U.light[1].col[2] = 0.8; - U.light[1].spec[0] = 0.3; U.light[1].spec[1] = 0.3; U.light[1].spec[2] = 0.5; - U.light[1].spec[3] = 1.0; - - U.light[2].flag = 0; - U.light[2].vec[0] = 0.3; U.light[2].vec[1] = -0.3; U.light[2].vec[2] = -0.2; - U.light[2].col[0] = 0.8; U.light[2].col[1] = 0.5; U.light[2].col[2] = 0.4; - U.light[2].spec[0] = 0.5; U.light[2].spec[1] = 0.4; U.light[2].spec[2] = 0.3; - U.light[2].spec[3] = 1.0; - } - - GPU_basic_shader_light_set_viewer(false); - - int count = 0; - - for (int a = 0; a < 8; a++) { - if (a < 3 && U.light[a].flag) { - GPULightData light = {0}; - - light.type = GPU_LIGHT_SUN; - - normalize_v3_v3(light.direction, U.light[a].vec); - copy_v3_v3(light.diffuse, U.light[a].col); - copy_v3_v3(light.specular, U.light[a].spec); - - GPU_basic_shader_light_set(a, &light); - - count++; - } - else - GPU_basic_shader_light_set(a, NULL); - } - - return count; -} - -int GPU_scene_object_lights(ViewLayer *view_layer, float viewmat[4][4], int ortho) -{ - /* disable all lights */ - for (int count = 0; count < 8; count++) - GPU_basic_shader_light_set(count, NULL); - - /* view direction for specular is not computed correct by default in - * opengl, so we set the settings ourselves */ - GPU_basic_shader_light_set_viewer(!ortho); - - int count = 0; - - for (Base *base = FIRSTBASE(view_layer); base; base = base->next) { - if (base->object->type != OB_LAMP) - continue; - - Lamp *la = base->object->data; - - /* setup lamp transform */ - gpuPushMatrix(); - gpuLoadMatrix(viewmat); - - /* setup light */ - GPULightData light = {0}; - - mul_v3_v3fl(light.diffuse, &la->r, la->energy); - mul_v3_v3fl(light.specular, &la->r, la->energy); - - if (la->type == LA_SUN) { - /* directional sun light */ - light.type = GPU_LIGHT_SUN; - normalize_v3_v3(light.direction, base->object->obmat[2]); - } - else { - /* other lamps with position attenuation */ - copy_v3_v3(light.position, base->object->obmat[3]); - - light.constant_attenuation = 1.0f; - light.linear_attenuation = la->att1 / la->dist; - light.quadratic_attenuation = la->att2 / (la->dist * la->dist); - - if (la->type == LA_SPOT) { - light.type = GPU_LIGHT_SPOT; - negate_v3_v3(light.direction, base->object->obmat[2]); - normalize_v3(light.direction); - light.spot_cutoff = RAD2DEGF(la->spotsize * 0.5f); - light.spot_exponent = 128.0f * la->spotblend; - } - else - light.type = GPU_LIGHT_POINT; - } - - GPU_basic_shader_light_set(count, &light); - - gpuPopMatrix(); - - count++; - if (count == 8) - break; - } - - return count; -} - static void gpu_disable_multisample(void) { #ifdef __linux__ @@ -1798,8 +1116,6 @@ static void gpu_disable_multisample(void) void GPU_state_init(void) { - GPU_default_lights(); - GPU_disable_program_point_size(); glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); @@ -1830,34 +1146,6 @@ void GPU_disable_program_point_size(void) glDisable(GL_PROGRAM_POINT_SIZE); } -#ifdef WITH_OPENSUBDIV -/* Update face-varying variables offset which might be - * different from mesh to mesh sharing the same material. - */ -void GPU_draw_update_fvar_offset(DerivedMesh *dm) -{ - /* Sanity check to be sure we only do this for OpenSubdiv draw. */ - BLI_assert(dm->type == DM_TYPE_CCGDM); - BLI_assert(GMS.is_opensubdiv); - - for (int i = 0; i < GMS.totmat; ++i) { - Material *material = GMS.gmatbuf[i]; - GPUMaterial *gpu_material; - - if (material == NULL) { - continue; - } - - gpu_material = GPU_material_from_blender(GMS.gscene, - material, - GMS.is_opensubdiv); - - GPU_material_update_fvar_offset(gpu_material, dm); - } -} -#endif - - /** \name Framebuffer color depth, for selection codes * \{ */ diff --git a/source/blender/gpu/intern/gpu_init_exit.c b/source/blender/gpu/intern/gpu_init_exit.c index 7a6b1ff6c70..5015d7c2372 100644 --- a/source/blender/gpu/intern/gpu_init_exit.c +++ b/source/blender/gpu/intern/gpu_init_exit.c @@ -30,6 +30,7 @@ */ #include "BLI_sys_types.h" +#include "GPU_buffers.h" #include "GPU_init_exit.h" /* interface */ #include "GPU_immediate.h" #include "GPU_batch.h" @@ -63,6 +64,8 @@ void GPU_init(void) gpu_batch_init(); immInit(); + + GPU_pbvh_fix_linking(); } diff --git a/source/blender/gpu/intern/gpu_lamp.c b/source/blender/gpu/intern/gpu_lamp.c deleted file mode 100644 index f8ca11782a5..00000000000 --- a/source/blender/gpu/intern/gpu_lamp.c +++ /dev/null @@ -1,458 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2006 Blender Foundation. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): Brecht Van Lommel, Clément Foucault. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/gpu/intern/gpu_lamp.c - * \ingroup gpu - * - * Manages Opengl lights. - */ - -#include "MEM_guardedalloc.h" - -#include "DNA_lamp_types.h" -#include "DNA_object_types.h" -#include "DNA_scene_types.h" - -#include "BLI_listbase.h" -#include "BLI_math.h" -#include "BLI_utildefines.h" - -#include "BKE_group.h" - -#include "GPU_framebuffer.h" -#include "GPU_glew.h" -#include "GPU_lamp.h" -#include "GPU_material.h" -#include "GPU_shader.h" -#include "GPU_texture.h" -#include "GPU_batch.h" - -#include "gpu_lamp_private.h" - -bool GPU_lamp_visible(GPULamp *lamp, Material *ma) -{ - if (lamp->hide) - return false; - else if (ma && ma->group) - return BKE_group_object_exists(ma->group, lamp->ob); - else - return true; -} - -static void gpu_lamp_calc_winmat(GPULamp *lamp) -{ - float temp, angle, pixsize, wsize; - - if (lamp->type == LA_SUN) { - wsize = lamp->la->shadow_frustum_size; - orthographic_m4(lamp->winmat, -wsize, wsize, -wsize, wsize, lamp->d, lamp->clipend); - } - else if (lamp->type == LA_SPOT) { - angle = saacos(lamp->spotsi); - temp = 0.5f * lamp->size * cosf(angle) / sinf(angle); - pixsize = lamp->d / temp; - wsize = pixsize * 0.5f * lamp->size; - /* compute shadows according to X and Y scaling factors */ - perspective_m4( - lamp->winmat, - -wsize * lamp->spotvec[0], wsize * lamp->spotvec[0], - -wsize * lamp->spotvec[1], wsize * lamp->spotvec[1], - lamp->d, lamp->clipend); - } -} - -void GPU_lamp_update(GPULamp *lamp, int lay, int hide, float obmat[4][4]) -{ - float mat[4][4]; - float obmat_scale[3]; - - lamp->lay = lay; - lamp->hide = hide; - - normalize_m4_m4_ex(mat, obmat, obmat_scale); - - copy_v3_v3(lamp->vec, mat[2]); - copy_v3_v3(lamp->co, mat[3]); - copy_m4_m4(lamp->obmat, mat); - invert_m4_m4(lamp->imat, mat); - - if (lamp->type == LA_SPOT) { - /* update spotlamp scale on X and Y axis */ - lamp->spotvec[0] = obmat_scale[0] / obmat_scale[2]; - lamp->spotvec[1] = obmat_scale[1] / obmat_scale[2]; - } - - if (GPU_lamp_has_shadow_buffer(lamp)) { - /* makeshadowbuf */ - gpu_lamp_calc_winmat(lamp); - } -} - -void GPU_lamp_update_colors(GPULamp *lamp, float r, float g, float b, float energy) -{ - lamp->energy = energy; - if (lamp->mode & LA_NEG) lamp->energy = -lamp->energy; - - lamp->col[0] = r; - lamp->col[1] = g; - lamp->col[2] = b; -} - -void GPU_lamp_update_distance(GPULamp *lamp, float distance, float att1, float att2, - float coeff_const, float coeff_lin, float coeff_quad) -{ - lamp->dist = distance; - lamp->att1 = att1; - lamp->att2 = att2; - lamp->coeff_const = coeff_const; - lamp->coeff_lin = coeff_lin; - lamp->coeff_quad = coeff_quad; -} - -void GPU_lamp_update_spot(GPULamp *lamp, float spotsize, float spotblend) -{ - lamp->spotsi = cosf(spotsize * 0.5f); - lamp->spotbl = (1.0f - lamp->spotsi) * spotblend; -} - -static void gpu_lamp_from_blender(Scene *scene, Object *ob, Object *par, Lamp *la, GPULamp *lamp) -{ - lamp->scene = scene; - lamp->ob = ob; - lamp->par = par; - lamp->la = la; - - /* add_render_lamp */ - lamp->mode = la->mode; - lamp->type = la->type; - - lamp->energy = la->energy; - if (lamp->mode & LA_NEG) lamp->energy = -lamp->energy; - - lamp->col[0] = la->r; - lamp->col[1] = la->g; - lamp->col[2] = la->b; - - GPU_lamp_update(lamp, ob->lay, (ob->restrictflag & OB_RESTRICT_RENDER), ob->obmat); - - lamp->spotsi = la->spotsize; - if (lamp->mode & LA_HALO) - if (lamp->spotsi > DEG2RADF(170.0f)) - lamp->spotsi = DEG2RADF(170.0f); - lamp->spotsi = cosf(lamp->spotsi * 0.5f); - lamp->spotbl = (1.0f - lamp->spotsi) * la->spotblend; - lamp->k = la->k; - - lamp->dist = la->dist; - lamp->falloff_type = la->falloff_type; - lamp->att1 = la->att1; - lamp->att2 = la->att2; - lamp->coeff_const = la->coeff_const; - lamp->coeff_lin = la->coeff_lin; - lamp->coeff_quad = la->coeff_quad; - lamp->curfalloff = la->curfalloff; - - /* initshadowbuf */ - lamp->bias = 0.02f * la->bias; - lamp->size = la->bufsize; - lamp->d = la->clipsta; - lamp->clipend = la->clipend; - - /* arbitrary correction for the fact we do no soft transition */ - lamp->bias *= 0.25f; -} - -static void gpu_lamp_shadow_free(GPULamp *lamp) -{ - if (lamp->tex) { - GPU_texture_free(lamp->tex); - lamp->tex = NULL; - } - if (lamp->depthtex) { - GPU_texture_free(lamp->depthtex); - lamp->depthtex = NULL; - } - if (lamp->fb) { - GPU_framebuffer_free(lamp->fb); - lamp->fb = NULL; - } - if (lamp->blurtex) { - GPU_texture_free(lamp->blurtex); - lamp->blurtex = NULL; - } - if (lamp->blurfb) { - GPU_framebuffer_free(lamp->blurfb); - lamp->blurfb = NULL; - } -} - -static GPUTexture *gpu_lamp_create_vsm_shadow_map(int size) -{ - return GPU_texture_create_2D_custom(size, size, 2, GPU_RG32F, NULL, NULL); -} - -LampEngineData *GPU_lamp_engine_data_get(Scene *scene, Object *ob, Object *par, struct RenderEngineType *re) -{ - GPULamp *lamp; - LinkData *link; - - for (link = ob->gpulamp.first; link; link = link->next) { - lamp = (GPULamp *)link->data; - - if ((lamp->par == par) && (lamp->scene == scene) && (lamp->re == re)) - return &lamp->data; - } - - lamp = MEM_callocN(sizeof(GPULamp), "GPULamp"); - - link = MEM_callocN(sizeof(LinkData), "GPULampLink"); - link->data = lamp; - BLI_addtail(&ob->gpulamp, link); - - lamp->scene = scene; - lamp->ob = ob; - lamp->par = par; - lamp->la = ob->data; - lamp->re = re; - - return &lamp->data; -} - -GPULamp *GPU_lamp_from_blender(Scene *scene, Object *ob, Object *par) -{ - Lamp *la; - GPULamp *lamp; - LinkData *link; - - for (link = ob->gpulamp.first; link; link = link->next) { - lamp = (GPULamp *)link->data; - - if (lamp->par == par && lamp->scene == scene) - return link->data; - } - - lamp = MEM_callocN(sizeof(GPULamp), "GPULamp"); - - link = MEM_callocN(sizeof(LinkData), "GPULampLink"); - link->data = lamp; - BLI_addtail(&ob->gpulamp, link); - - la = ob->data; - gpu_lamp_from_blender(scene, ob, par, la, lamp); - - if ((la->type == LA_SPOT && (la->mode & (LA_SHAD_BUF | LA_SHAD_RAY))) || - (la->type == LA_SUN && (la->mode & LA_SHAD_RAY))) - { - if (lamp->la->shadowmap_type == LA_SHADMAP_VARIANCE) { - lamp->depthtex = GPU_texture_create_depth(lamp->size, lamp->size, NULL); - lamp->tex = gpu_lamp_create_vsm_shadow_map(lamp->size); - lamp->blurtex = gpu_lamp_create_vsm_shadow_map(lamp->size * 0.5); - - lamp->fb = GPU_framebuffer_create(); - GPU_framebuffer_texture_attach(lamp->fb, lamp->depthtex, 0, 0); - GPU_framebuffer_texture_attach(lamp->fb, lamp->tex, 0, 0); - - lamp->blurfb = GPU_framebuffer_create(); - GPU_framebuffer_texture_attach(lamp->blurfb, lamp->blurtex, 0, 0); - - if (!GPU_framebuffer_check_valid(lamp->fb, NULL) || - !GPU_framebuffer_check_valid(lamp->blurfb, NULL)) - { - gpu_lamp_shadow_free(lamp); - return lamp; - } - } - else { - lamp->tex = GPU_texture_create_depth(lamp->size, lamp->size, NULL); - - GPU_texture_bind(lamp->tex, 0); - GPU_texture_compare_mode(lamp->tex, true); - GPU_texture_filter_mode(lamp->tex, true); - GPU_texture_unbind(lamp->tex); - - lamp->fb = GPU_framebuffer_create(); - GPU_framebuffer_texture_attach(lamp->fb, lamp->tex, 0, 0); - - if (!GPU_framebuffer_check_valid(lamp->fb, NULL)) { - gpu_lamp_shadow_free(lamp); - return lamp; - } - } - - GPU_framebuffer_restore(); - - lamp->shadow_color[0] = la->shdwr; - lamp->shadow_color[1] = la->shdwg; - lamp->shadow_color[2] = la->shdwb; - } - else { - lamp->shadow_color[0] = 1.0; - lamp->shadow_color[1] = 1.0; - lamp->shadow_color[2] = 1.0; - } - - return lamp; -} - -void GPU_lamp_engine_data_free(LampEngineData *led) -{ - for (int i = 0; i < MAX_LAMP_DATA; ++i) { - if (led->storage[i]) { - MEM_freeN(led->storage[i]); - led->storage[i] = NULL; - } - } -} - -void GPU_lamp_free(Object *ob) -{ - GPULamp *lamp; - LinkData *link; - - for (link = ob->gpulamp.first; link; link = link->next) { - lamp = link->data; - - gpu_lamp_shadow_free(lamp); - GPU_lamp_engine_data_free(&lamp->data); - - MEM_freeN(lamp); - } - - BLI_freelistN(&ob->gpulamp); -} - -bool GPU_lamp_has_shadow_buffer(GPULamp *UNUSED(lamp)) -{ - return false; -} - -void GPU_lamp_update_buffer_mats(GPULamp *lamp) -{ - float rangemat[4][4], persmat[4][4]; - - /* initshadowbuf */ - invert_m4_m4(lamp->viewmat, lamp->obmat); - normalize_v3(lamp->viewmat[0]); - normalize_v3(lamp->viewmat[1]); - normalize_v3(lamp->viewmat[2]); - - /* makeshadowbuf */ - mul_m4_m4m4(persmat, lamp->winmat, lamp->viewmat); - - /* opengl depth buffer is range 0.0..1.0 instead of -1.0..1.0 in blender */ - unit_m4(rangemat); - rangemat[0][0] = 0.5f; - rangemat[1][1] = 0.5f; - rangemat[2][2] = 0.5f; - rangemat[3][0] = 0.5f; - rangemat[3][1] = 0.5f; - rangemat[3][2] = 0.5f; - - mul_m4_m4m4(lamp->persmat, rangemat, persmat); -} - -void GPU_lamp_shadow_buffer_bind(GPULamp *lamp, float viewmat[4][4], int *winsize, float winmat[4][4]) -{ - GPU_lamp_update_buffer_mats(lamp); - - /* opengl */ - glDisable(GL_SCISSOR_TEST); - GPU_framebuffer_bind(lamp->fb); - if (lamp->la->shadowmap_type == LA_SHADMAP_VARIANCE) - GPU_shader_bind(GPU_shader_get_builtin_shader(GPU_SHADER_VSM_STORE)); - - /* set matrices */ - copy_m4_m4(viewmat, lamp->viewmat); - copy_m4_m4(winmat, lamp->winmat); - *winsize = lamp->size; -} - -static void gpu_lamp_shadow_blur(GPULamp *lamp) -{ - const float scaleh[2] = {1.0f / GPU_texture_width(lamp->blurtex), 0.0f}; - const float scalev[2] = {0.0f, 1.0f / GPU_texture_height(lamp->tex)}; - - GPUShader *blur_shader = GPU_shader_get_builtin_shader(GPU_SHADER_SEP_GAUSSIAN_BLUR); - - if (!blur_shader) - return; - - int tex_loc = GPU_shader_get_uniform(blur_shader, "textureSource"); - int scale_loc = GPU_shader_get_uniform(blur_shader, "ScaleU"); - - glDisable(GL_DEPTH_TEST); - - GPU_shader_bind(blur_shader); - - /* Blurring horizontally */ - GPU_framebuffer_bind(lamp->blurfb); - GPU_texture_bind(lamp->tex, 0); - GPU_shader_uniform_vector(blur_shader, scale_loc, 2, 1, scaleh); - GPU_shader_uniform_texture(blur_shader, tex_loc, lamp->tex); - GWN_draw_primitive(GL_TRIANGLES, 3); - - /* Blurring vertically */ - GPU_framebuffer_bind(lamp->fb); - GPU_texture_bind(lamp->blurtex, 0); - GPU_shader_uniform_vector(blur_shader, scale_loc, 2, 1, scalev); - GPU_shader_uniform_texture(blur_shader, tex_loc, lamp->blurtex); - GWN_draw_primitive(GL_TRIANGLES, 3); -} - -void GPU_lamp_shadow_buffer_unbind(GPULamp *lamp) -{ - if (lamp->la->shadowmap_type == LA_SHADMAP_VARIANCE) { - GPU_shader_unbind(); - gpu_lamp_shadow_blur(lamp); - } - - GPU_framebuffer_restore(); - glEnable(GL_SCISSOR_TEST); -} - -int GPU_lamp_shadow_buffer_type(GPULamp *lamp) -{ - return lamp->la->shadowmap_type; -} - -int GPU_lamp_shadow_bind_code(GPULamp *lamp) -{ - return lamp->tex ? GPU_texture_opengl_bindcode(lamp->tex) : -1; -} - -float *GPU_lamp_dynpersmat(GPULamp *lamp) -{ - return &lamp->dynpersmat[0][0]; -} - -int GPU_lamp_shadow_layer(GPULamp *lamp) -{ - if (lamp->fb && lamp->tex && (lamp->mode & (LA_LAYER | LA_LAYER_SHADOW))) - return lamp->lay; - else - return -1; -} diff --git a/source/blender/gpu/intern/gpu_lamp_private.h b/source/blender/gpu/intern/gpu_lamp_private.h deleted file mode 100644 index f227ce74e7e..00000000000 --- a/source/blender/gpu/intern/gpu_lamp_private.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2005 Blender Foundation. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): Brecht Van Lommel, Clément Foucault. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file gpu_lamp_private.h - * \ingroup gpu - */ - -#ifndef __GPU_LAMP_PRIVATE_H__ -#define __GPU_LAMP_PRIVATE_H__ - -#include "BLI_sys_types.h" /* for bool */ - -struct GPULamp { - Scene *scene; - Object *ob; - Object *par; - Lamp *la; - struct RenderEngineType *re; - - /* Old Viewport (pre-2.8) */ - int type, mode, lay, hide; - - float dynenergy, dyncol[3]; - float energy, col[3]; - - float co[3], vec[3]; - float dynco[3], dynvec[3]; - float obmat[4][4]; - float imat[4][4]; - float dynimat[4][4]; - - float spotsi, spotbl, k; - float spotvec[2]; - float dyndist, dynatt1, dynatt2; - float dist, att1, att2; - float coeff_const, coeff_lin, coeff_quad; - float shadow_color[3]; - - float bias, d, clipend; - int size; - - int falloff_type; - struct CurveMapping *curfalloff; - - float winmat[4][4]; - float viewmat[4][4]; - float persmat[4][4]; - float dynpersmat[4][4]; - - GPUFrameBuffer *fb; - GPUFrameBuffer *blurfb; - GPUTexture *tex; - GPUTexture *depthtex; - GPUTexture *blurtex; - - /* New viewport */ - struct LampEngineData data; -}; - -#endif /* __GPU_LAMP_PRIVATE_H__ */ diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index eddd2b85829..d5f4f3269ed 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -62,7 +62,6 @@ #include "GPU_extensions.h" #include "GPU_framebuffer.h" -#include "GPU_lamp.h" #include "GPU_material.h" #include "GPU_shader.h" #include "GPU_texture.h" @@ -71,7 +70,6 @@ #include "DRW_engine.h" #include "gpu_codegen.h" -#include "gpu_lamp_private.h" #ifdef WITH_OPENSUBDIV # include "BKE_DerivedMesh.h" @@ -79,25 +77,6 @@ /* Structs */ -typedef enum DynMatProperty { - DYN_LAMP_CO = 1, - DYN_LAMP_VEC = 2, - DYN_LAMP_IMAT = 4, - DYN_LAMP_PERSMAT = 8, -} DynMatProperty; - -static struct GPUWorld { - float mistenabled; - float mistype; - float miststart; - float mistdistance; - float mistintensity; - float mistcol[4]; - float horicol[3]; - float ambcol[4]; - float zencol[3]; -} GPUWorld; - struct GPUMaterial { Scene *scene; /* DEPRECATED was only usefull for lamps */ Material *ma; @@ -136,9 +115,6 @@ struct GPUMaterial { int objectinfoloc; - ListBase lamps; - bool bound; - bool is_opensubdiv; /* XXX: Should be in Material. But it depends on the output node @@ -165,115 +141,8 @@ enum { GPU_DOMAIN_SSS = (1 << 2) }; -/* Forward declaration so shade_light_textures() can use this, while still keeping the code somewhat organized */ -static void texture_rgb_blend( - GPUMaterial *mat, GPUNodeLink *tex, GPUNodeLink *out, GPUNodeLink *fact, GPUNodeLink *facg, - int blendtype, GPUNodeLink **in); - /* Functions */ -static GPUMaterial *GPU_material_construct_begin(Material *ma) -{ - GPUMaterial *material = MEM_callocN(sizeof(GPUMaterial), "GPUMaterial"); - - material->ma = ma; - - return material; -} - -static void gpu_material_set_attrib_id(GPUMaterial *material) -{ - GPUVertexAttribs *attribs = &material->attribs; - GPUPass *pass = material->pass; - if (!pass) { - attribs->totlayer = 0; - return; - } - - GPUShader *shader = GPU_pass_shader(pass); - if (!shader) { - attribs->totlayer = 0; - return; - } - - /* convert from attribute number to the actual id assigned by opengl, - * in case the attrib does not get a valid index back, it was probably - * removed by the glsl compiler by dead code elimination */ - - int b = 0; - for (int a = 0; a < attribs->totlayer; a++) { - char name[32]; - BLI_snprintf(name, sizeof(name), "att%d", attribs->layer[a].attribid); - attribs->layer[a].glindex = GPU_shader_get_attribute(shader, name); - - BLI_snprintf(name, sizeof(name), "att%d_info", attribs->layer[a].attribid); - attribs->layer[a].glinfoindoex = GPU_shader_get_uniform(shader, name); - - if (attribs->layer[a].glindex >= 0) { - attribs->layer[b] = attribs->layer[a]; - b++; - } - } - - attribs->totlayer = b; -} - -static int gpu_material_construct_end(GPUMaterial *material, const char *passname) -{ - if (material->outlink) { - GPUNodeLink *outlink = material->outlink; - material->pass = GPU_generate_pass(&material->nodes, &material->inputs, outlink, - &material->attribs, &material->builtins, material->type, - passname, - material->is_opensubdiv, - GPU_material_use_new_shading_nodes(material)); - - material->status = (material->pass) ? GPU_MAT_SUCCESS : GPU_MAT_FAILED; - - if (!material->pass) - return 0; - - gpu_material_set_attrib_id(material); - - GPUShader *shader = GPU_pass_shader(material->pass); - - if (material->builtins & GPU_VIEW_MATRIX) - material->viewmatloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_VIEW_MATRIX)); - if (material->builtins & GPU_INVERSE_VIEW_MATRIX) - material->invviewmatloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_INVERSE_VIEW_MATRIX)); - if (material->builtins & GPU_OBJECT_MATRIX) - material->obmatloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_OBJECT_MATRIX)); - if (material->builtins & GPU_INVERSE_OBJECT_MATRIX) - material->invobmatloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_INVERSE_OBJECT_MATRIX)); - if (material->builtins & GPU_LOC_TO_VIEW_MATRIX) - material->localtoviewmatloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_LOC_TO_VIEW_MATRIX)); - if (material->builtins & GPU_INVERSE_LOC_TO_VIEW_MATRIX) - material->invlocaltoviewmatloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_INVERSE_LOC_TO_VIEW_MATRIX)); - if (material->builtins & GPU_OBCOLOR) - material->obcolloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_OBCOLOR)); - if (material->builtins & GPU_AUTO_BUMPSCALE) - material->obautobumpscaleloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_AUTO_BUMPSCALE)); - if (material->builtins & GPU_CAMERA_TEXCO_FACTORS) - material->cameratexcofacloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_CAMERA_TEXCO_FACTORS)); - if (material->builtins & GPU_PARTICLE_SCALAR_PROPS) - material->partscalarpropsloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_PARTICLE_SCALAR_PROPS)); - if (material->builtins & GPU_PARTICLE_LOCATION) - material->partcoloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_PARTICLE_LOCATION)); - if (material->builtins & GPU_PARTICLE_VELOCITY) - material->partvel = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_PARTICLE_VELOCITY)); - if (material->builtins & GPU_PARTICLE_ANG_VELOCITY) - material->partangvel = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_PARTICLE_ANG_VELOCITY)); - if (material->builtins & GPU_OBJECT_INFO) - material->objectinfoloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_OBJECT_INFO)); - return 1; - } - else { - GPU_pass_free_nodes(&material->nodes); - } - - return 0; -} - void GPU_material_free(ListBase *gpumaterial) { for (LinkData *link = gpumaterial->first; link; link = link->next) { @@ -300,166 +169,17 @@ void GPU_material_free(ListBase *gpumaterial) GPU_uniformbuffer_free(material->sss_profile); } - BLI_freelistN(&material->lamps); - MEM_freeN(material); } BLI_freelistN(gpumaterial); } -void GPU_material_bind( - GPUMaterial *material, int oblay, int viewlay, double time, int mipmap, - float viewmat[4][4], float viewinv[4][4], float camerafactors[4]) -{ - if (material->pass) { - GPUShader *shader = GPU_pass_shader(material->pass); - - /* handle layer lamps */ - if (material->type == GPU_MATERIAL_TYPE_MESH) { - for (LinkData *nlink = material->lamps.first; nlink; nlink = nlink->next) { - GPULamp *lamp = nlink->data; - - if ((lamp->lay & viewlay) && (!(lamp->mode & LA_LAYER) || (lamp->lay & oblay)) && - GPU_lamp_visible(lamp, material->ma)) - { - lamp->dynenergy = lamp->energy; - copy_v3_v3(lamp->dyncol, lamp->col); - } - else { - lamp->dynenergy = 0.0f; - lamp->dyncol[0] = lamp->dyncol[1] = lamp->dyncol[2] = 0.0f; - } - - if (material->dynproperty & DYN_LAMP_VEC) { - copy_v3_v3(lamp->dynvec, lamp->vec); - normalize_v3(lamp->dynvec); - negate_v3(lamp->dynvec); - mul_mat3_m4_v3(viewmat, lamp->dynvec); - } - - if (material->dynproperty & DYN_LAMP_CO) { - copy_v3_v3(lamp->dynco, lamp->co); - mul_m4_v3(viewmat, lamp->dynco); - } - - if (material->dynproperty & DYN_LAMP_IMAT) { - mul_m4_m4m4(lamp->dynimat, lamp->imat, viewinv); - } - - if (material->dynproperty & DYN_LAMP_PERSMAT) { - /* The lamp matrices are already updated if we're using shadow buffers */ - if (!GPU_lamp_has_shadow_buffer(lamp)) { - GPU_lamp_update_buffer_mats(lamp); - } - mul_m4_m4m4(lamp->dynpersmat, lamp->persmat, viewinv); - } - } - } - - /* note material must be bound before setting uniforms */ - GPU_pass_bind(material->pass, &material->inputs, time, mipmap); - - /* handle per material built-ins */ - if (material->builtins & GPU_VIEW_MATRIX) { - GPU_shader_uniform_vector(shader, material->viewmatloc, 16, 1, (float *)viewmat); - } - if (material->builtins & GPU_INVERSE_VIEW_MATRIX) { - GPU_shader_uniform_vector(shader, material->invviewmatloc, 16, 1, (float *)viewinv); - } - if (material->builtins & GPU_CAMERA_TEXCO_FACTORS) { - if (camerafactors) { - GPU_shader_uniform_vector(shader, material->cameratexcofacloc, 4, 1, (float *)camerafactors); - } - else { - /* use default, no scaling no offset */ - float borders[4] = {1.0f, 1.0f, 0.0f, 0.0f}; - GPU_shader_uniform_vector(shader, material->cameratexcofacloc, 4, 1, (float *)borders); - } - } - - GPU_pass_update_uniforms(material->pass, &material->inputs); - - material->bound = 1; - } -} - GPUBuiltin GPU_get_material_builtins(GPUMaterial *material) { return material->builtins; } -void GPU_material_bind_uniforms( - GPUMaterial *material, float obmat[4][4], float viewmat[4][4], float obcol[4], - float autobumpscale, GPUParticleInfo *pi, float object_info[3]) -{ - if (material->pass) { - GPUShader *shader = GPU_pass_shader(material->pass); - float invmat[4][4], col[4]; - float localtoviewmat[4][4]; - float invlocaltoviewmat[4][4]; - - /* handle per object builtins */ - if (material->builtins & GPU_OBJECT_MATRIX) { - GPU_shader_uniform_vector(shader, material->obmatloc, 16, 1, (float *)obmat); - } - if (material->builtins & GPU_INVERSE_OBJECT_MATRIX) { - invert_m4_m4(invmat, obmat); - GPU_shader_uniform_vector(shader, material->invobmatloc, 16, 1, (float *)invmat); - } - if (material->builtins & GPU_LOC_TO_VIEW_MATRIX) { - if (viewmat) { - mul_m4_m4m4(localtoviewmat, viewmat, obmat); - GPU_shader_uniform_vector(shader, material->localtoviewmatloc, 16, 1, (float *)localtoviewmat); - } - } - if (material->builtins & GPU_INVERSE_LOC_TO_VIEW_MATRIX) { - if (viewmat) { - mul_m4_m4m4(localtoviewmat, viewmat, obmat); - invert_m4_m4(invlocaltoviewmat, localtoviewmat); - GPU_shader_uniform_vector(shader, material->invlocaltoviewmatloc, 16, 1, (float *)invlocaltoviewmat); - } - } - if (material->builtins & GPU_OBCOLOR) { - copy_v4_v4(col, obcol); - CLAMP(col[3], 0.0f, 1.0f); - GPU_shader_uniform_vector(shader, material->obcolloc, 4, 1, col); - } - if (material->builtins & GPU_AUTO_BUMPSCALE) { - GPU_shader_uniform_vector(shader, material->obautobumpscaleloc, 1, 1, &autobumpscale); - } - if (material->builtins & GPU_PARTICLE_SCALAR_PROPS) { - GPU_shader_uniform_vector(shader, material->partscalarpropsloc, 4, 1, pi->scalprops); - } - if (material->builtins & GPU_PARTICLE_LOCATION) { - GPU_shader_uniform_vector(shader, material->partcoloc, 4, 1, pi->location); - } - if (material->builtins & GPU_PARTICLE_VELOCITY) { - GPU_shader_uniform_vector(shader, material->partvel, 3, 1, pi->velocity); - } - if (material->builtins & GPU_PARTICLE_ANG_VELOCITY) { - GPU_shader_uniform_vector(shader, material->partangvel, 3, 1, pi->angular_velocity); - } - if (material->builtins & GPU_OBJECT_INFO) { - GPU_shader_uniform_vector(shader, material->objectinfoloc, 3, 1, object_info); - } - - } -} - -void GPU_material_unbind(GPUMaterial *material) -{ - if (material->pass) { - material->bound = 0; - GPU_pass_unbind(material->pass, &material->inputs); - } -} - -bool GPU_material_bound(GPUMaterial *material) -{ - return material->bound; -} - Scene *GPU_material_scene(GPUMaterial *material) { return material->scene; @@ -831,19 +551,6 @@ void GPU_material_output_link(GPUMaterial *material, GPUNodeLink *link) material->outlink = link; } -void GPU_material_enable_alpha(GPUMaterial *material) -{ - material->alpha = 1; -} - -GPUBlendMode GPU_material_alpha_blend(GPUMaterial *material, float obcol[4]) -{ - if (material->alpha || (material->obcolalpha && obcol[3] < 1.0f)) - return GPU_BLEND_ALPHA; - else - return GPU_BLEND_SOLID; -} - void gpu_material_add_node(GPUMaterial *material, GPUNode *node) { BLI_addtail(&material->nodes, node); @@ -865,16 +572,6 @@ bool GPU_material_do_color_management(GPUMaterial *mat) return true; } -bool GPU_material_use_new_shading_nodes(GPUMaterial *mat) -{ - return BKE_scene_use_new_shading_nodes(mat->scene); -} - -bool GPU_material_use_world_space_shading(GPUMaterial *mat) -{ - return BKE_scene_use_world_space_shading(mat->scene); -} - bool GPU_material_use_domain_surface(GPUMaterial *mat) { return (mat->domain & GPU_DOMAIN_SURFACE); @@ -885,1607 +582,6 @@ bool GPU_material_use_domain_volume(GPUMaterial *mat) return (mat->domain & GPU_DOMAIN_VOLUME); } -static GPUNodeLink *lamp_get_visibility(GPUMaterial *mat, GPULamp *lamp, GPUNodeLink **lv, GPUNodeLink **dist) -{ - GPUNodeLink *visifac; - - /* from get_lamp_visibility */ - if (lamp->type == LA_SUN || lamp->type == LA_HEMI) { - mat->dynproperty |= DYN_LAMP_VEC; - GPU_link(mat, "lamp_visibility_sun_hemi", - GPU_dynamic_uniform(lamp->dynvec, GPU_DYNAMIC_LAMP_DYNVEC, lamp->ob), lv, dist, &visifac); - return visifac; - } - else { - mat->dynproperty |= DYN_LAMP_CO; - GPU_link(mat, "lamp_visibility_other", - GPU_builtin(GPU_VIEW_POSITION), - GPU_dynamic_uniform(lamp->dynco, GPU_DYNAMIC_LAMP_DYNCO, lamp->ob), lv, dist, &visifac); - - if (lamp->type == LA_AREA) - return visifac; - - switch (lamp->falloff_type) { - case LA_FALLOFF_CONSTANT: - break; - case LA_FALLOFF_INVLINEAR: - GPU_link(mat, "lamp_falloff_invlinear", - GPU_dynamic_uniform(&lamp->dist, GPU_DYNAMIC_LAMP_DISTANCE, lamp->ob), *dist, &visifac); - break; - case LA_FALLOFF_INVSQUARE: - GPU_link(mat, "lamp_falloff_invsquare", - GPU_dynamic_uniform(&lamp->dist, GPU_DYNAMIC_LAMP_DISTANCE, lamp->ob), *dist, &visifac); - break; - case LA_FALLOFF_SLIDERS: - GPU_link(mat, "lamp_falloff_sliders", - GPU_dynamic_uniform(&lamp->dist, GPU_DYNAMIC_LAMP_DISTANCE, lamp->ob), - GPU_dynamic_uniform(&lamp->att1, GPU_DYNAMIC_LAMP_ATT1, lamp->ob), - GPU_dynamic_uniform(&lamp->att2, GPU_DYNAMIC_LAMP_ATT2, lamp->ob), *dist, &visifac); - break; - case LA_FALLOFF_INVCOEFFICIENTS: - GPU_link(mat, "lamp_falloff_invcoefficients", - GPU_dynamic_uniform(&lamp->coeff_const, GPU_DYNAMIC_LAMP_COEFFCONST, lamp->ob), - GPU_dynamic_uniform(&lamp->coeff_lin, GPU_DYNAMIC_LAMP_COEFFLIN, lamp->ob), - GPU_dynamic_uniform(&lamp->coeff_quad, GPU_DYNAMIC_LAMP_COEFFQUAD, lamp->ob), *dist, &visifac); - break; - case LA_FALLOFF_CURVE: - { - float *array; - int size; - - curvemapping_initialize(lamp->curfalloff); - curvemapping_table_RGBA(lamp->curfalloff, &array, &size); - GPU_link(mat, "lamp_falloff_curve", - GPU_dynamic_uniform(&lamp->dist, GPU_DYNAMIC_LAMP_DISTANCE, lamp->ob), - GPU_texture(size, array), *dist, &visifac); - - break; - } - } - - if (lamp->mode & LA_SPHERE) - GPU_link(mat, "lamp_visibility_sphere", - GPU_dynamic_uniform(&lamp->dist, GPU_DYNAMIC_LAMP_DISTANCE, lamp->ob), - *dist, visifac, &visifac); - - if (lamp->type == LA_SPOT) { - GPUNodeLink *inpr; - - if (lamp->mode & LA_SQUARE) { - mat->dynproperty |= DYN_LAMP_VEC | DYN_LAMP_IMAT; - GPU_link(mat, "lamp_visibility_spot_square", - GPU_dynamic_uniform(lamp->dynvec, GPU_DYNAMIC_LAMP_DYNVEC, lamp->ob), - GPU_dynamic_uniform((float *)lamp->dynimat, GPU_DYNAMIC_LAMP_DYNIMAT, lamp->ob), - GPU_dynamic_uniform((float *)lamp->spotvec, GPU_DYNAMIC_LAMP_SPOTSCALE, lamp->ob), *lv, &inpr); - } - else { - mat->dynproperty |= DYN_LAMP_VEC | DYN_LAMP_IMAT; - GPU_link(mat, "lamp_visibility_spot_circle", - GPU_dynamic_uniform(lamp->dynvec, GPU_DYNAMIC_LAMP_DYNVEC, lamp->ob), - GPU_dynamic_uniform((float *)lamp->dynimat, GPU_DYNAMIC_LAMP_DYNIMAT, lamp->ob), - GPU_dynamic_uniform((float *)lamp->spotvec, GPU_DYNAMIC_LAMP_SPOTSCALE, lamp->ob), *lv, &inpr); - } - - GPU_link(mat, "lamp_visibility_spot", - GPU_dynamic_uniform(&lamp->spotsi, GPU_DYNAMIC_LAMP_SPOTSIZE, lamp->ob), - GPU_dynamic_uniform(&lamp->spotbl, GPU_DYNAMIC_LAMP_SPOTBLEND, lamp->ob), - inpr, visifac, &visifac); - } - - GPU_link(mat, "lamp_visibility_clamp", visifac, &visifac); - - return visifac; - } -} - -#if 0 -static void area_lamp_vectors(LampRen *lar) -{ - float xsize = 0.5f * lar->area_size, ysize = 0.5f * lar->area_sizey; - - /* make it smaller, so area light can be multisampled */ - float multifac = 1.0f / sqrtf((float)lar->ray_totsamp); - xsize *= multifac; - ysize *= multifac; - - /* corner vectors */ - lar->area[0][0] = lar->co[0] - xsize * lar->mat[0][0] - ysize * lar->mat[1][0]; - lar->area[0][1] = lar->co[1] - xsize * lar->mat[0][1] - ysize * lar->mat[1][1]; - lar->area[0][2] = lar->co[2] - xsize * lar->mat[0][2] - ysize * lar->mat[1][2]; - - /* corner vectors */ - lar->area[1][0] = lar->co[0] - xsize * lar->mat[0][0] + ysize * lar->mat[1][0]; - lar->area[1][1] = lar->co[1] - xsize * lar->mat[0][1] + ysize * lar->mat[1][1]; - lar->area[1][2] = lar->co[2] - xsize * lar->mat[0][2] + ysize * lar->mat[1][2]; - - /* corner vectors */ - lar->area[2][0] = lar->co[0] + xsize * lar->mat[0][0] + ysize * lar->mat[1][0]; - lar->area[2][1] = lar->co[1] + xsize * lar->mat[0][1] + ysize * lar->mat[1][1]; - lar->area[2][2] = lar->co[2] + xsize * lar->mat[0][2] + ysize * lar->mat[1][2]; - - /* corner vectors */ - lar->area[3][0] = lar->co[0] + xsize * lar->mat[0][0] - ysize * lar->mat[1][0]; - lar->area[3][1] = lar->co[1] + xsize * lar->mat[0][1] - ysize * lar->mat[1][1]; - lar->area[3][2] = lar->co[2] + xsize * lar->mat[0][2] - ysize * lar->mat[1][2]; - /* only for correction button size, matrix size works on energy */ - lar->areasize = lar->dist * lar->dist / (4.0f * xsize * ysize); -} -#endif - -static void ramp_blend( - GPUMaterial *mat, GPUNodeLink *fac, GPUNodeLink *col1, GPUNodeLink *col2, int type, - GPUNodeLink **r_col) -{ - static const char *names[] = {"mix_blend", "mix_add", "mix_mult", "mix_sub", - "mix_screen", "mix_div", "mix_diff", "mix_dark", "mix_light", - "mix_overlay", "mix_dodge", "mix_burn", "mix_hue", "mix_sat", - "mix_val", "mix_color", "mix_soft", "mix_linear"}; - - GPU_link(mat, names[type], fac, col1, col2, r_col); -} - -static void BKE_colorband_eval_blend( - GPUMaterial *mat, ColorBand *coba, GPUNodeLink *fac, float rampfac, int type, - GPUNodeLink *incol, GPUNodeLink **r_col) -{ - GPUNodeLink *tmp, *alpha, *col; - float *array; - int size; - - /* do colorband */ - BKE_colorband_evaluate_table_rgba(coba, &array, &size); - GPU_link(mat, "valtorgb", fac, GPU_texture(size, array), &col, &tmp); - - /* use alpha in fac */ - GPU_link(mat, "mtex_alpha_from_col", col, &alpha); - GPU_link(mat, "math_multiply", alpha, GPU_uniform(&rampfac), &fac); - - /* blending method */ - ramp_blend(mat, fac, incol, col, type, r_col); -} - -static void ramp_diffuse_result(GPUShadeInput *shi, GPUNodeLink **diff) -{ - Material *ma = shi->mat; - GPUMaterial *mat = shi->gpumat; - - { - if (ma->ramp_col) { - if (ma->rampin_col == MA_RAMP_IN_RESULT) { - GPUNodeLink *fac; - GPU_link(mat, "ramp_rgbtobw", *diff, &fac); - - /* colorband + blend */ - BKE_colorband_eval_blend(mat, ma->ramp_col, fac, ma->rampfac_col, ma->rampblend_col, *diff, diff); - } - } - } -} - -static void add_to_diffuse( - GPUMaterial *mat, Material *ma, GPUShadeInput *shi, GPUNodeLink *is, GPUNodeLink *rgb, - GPUNodeLink **r_diff) -{ - GPUNodeLink *fac, *tmp, *addcol; - - if (ma->ramp_col && (ma->mode & MA_RAMP_COL)) { - /* MA_RAMP_IN_RESULT is exceptional */ - if (ma->rampin_col == MA_RAMP_IN_RESULT) { - addcol = shi->rgb; - } - else { - /* input */ - switch (ma->rampin_col) { - case MA_RAMP_IN_ENERGY: - GPU_link(mat, "ramp_rgbtobw", rgb, &fac); - break; - case MA_RAMP_IN_SHADER: - fac = is; - break; - case MA_RAMP_IN_NOR: - GPU_link(mat, "vec_math_dot", shi->view, shi->vn, &tmp, &fac); - break; - default: - GPU_link(mat, "set_value_zero", &fac); - break; - } - - /* colorband + blend */ - BKE_colorband_eval_blend(mat, ma->ramp_col, fac, ma->rampfac_col, ma->rampblend_col, shi->rgb, &addcol); - } - } - else - addcol = shi->rgb; - - /* output to */ - GPU_link(mat, "shade_madd", *r_diff, rgb, addcol, r_diff); -} - -static void ramp_spec_result(GPUShadeInput *shi, GPUNodeLink **spec) -{ - Material *ma = shi->mat; - GPUMaterial *mat = shi->gpumat; - - if (ma->ramp_spec && ma->rampin_spec == MA_RAMP_IN_RESULT) { - GPUNodeLink *fac; - GPU_link(mat, "ramp_rgbtobw", *spec, &fac); - - /* colorband + blend */ - BKE_colorband_eval_blend(mat, ma->ramp_spec, fac, ma->rampfac_spec, ma->rampblend_spec, *spec, spec); - } -} - -static void do_specular_ramp(GPUShadeInput *shi, GPUNodeLink *is, GPUNodeLink *t, GPUNodeLink **spec) -{ - Material *ma = shi->mat; - GPUMaterial *mat = shi->gpumat; - GPUNodeLink *fac, *tmp; - - *spec = shi->specrgb; - - /* MA_RAMP_IN_RESULT is exception */ - if (ma->ramp_spec && (ma->rampin_spec != MA_RAMP_IN_RESULT)) { - - /* input */ - switch (ma->rampin_spec) { - case MA_RAMP_IN_ENERGY: - fac = t; - break; - case MA_RAMP_IN_SHADER: - fac = is; - break; - case MA_RAMP_IN_NOR: - GPU_link(mat, "vec_math_dot", shi->view, shi->vn, &tmp, &fac); - break; - default: - GPU_link(mat, "set_value_zero", &fac); - break; - } - - /* colorband + blend */ - BKE_colorband_eval_blend(mat, ma->ramp_spec, fac, ma->rampfac_spec, ma->rampblend_spec, *spec, spec); - } -} - -static void add_user_list(ListBase *list, void *data) -{ - LinkData *link = MEM_callocN(sizeof(LinkData), "GPULinkData"); - link->data = data; - BLI_addtail(list, link); -} - -static void shade_light_textures(GPUMaterial *mat, GPULamp *lamp, GPUNodeLink **rgb) -{ - for (int i = 0; i < MAX_MTEX; ++i) { - MTex *mtex = lamp->la->mtex[i]; - - if (mtex && mtex->tex && (mtex->tex->type & TEX_IMAGE) && mtex->tex->ima) { - mat->dynproperty |= DYN_LAMP_PERSMAT; - - float one = 1.0f; - GPUNodeLink *tex_rgb; - - GPU_link(mat, "shade_light_texture", - GPU_builtin(GPU_VIEW_POSITION), - GPU_image(mtex->tex->ima, &mtex->tex->iuser, false), - GPU_dynamic_uniform((float *)lamp->dynpersmat, GPU_DYNAMIC_LAMP_DYNPERSMAT, lamp->ob), - &tex_rgb); - texture_rgb_blend(mat, tex_rgb, *rgb, GPU_uniform(&one), GPU_uniform(&mtex->colfac), mtex->blendtype, rgb); - } - } -} - -static void shade_one_light(GPUShadeInput *shi, GPUShadeResult *shr, GPULamp *lamp) -{ - Material *ma = shi->mat; - GPUMaterial *mat = shi->gpumat; - GPUNodeLink *lv, *dist, *is, *inp, *i; - GPUNodeLink *outcol, *specfac, *t, *shadfac = NULL, *lcol; - float one = 1.0f; - - if ((lamp->mode & LA_ONLYSHADOW) && !(ma->mode & MA_SHADOW)) - return; - - GPUNodeLink *vn = shi->vn; - GPUNodeLink *view = shi->view; - - GPUNodeLink *visifac = lamp_get_visibility(mat, lamp, &lv, &dist); - -#if 0 - if (ma->mode & MA_TANGENT_V) - GPU_link(mat, "shade_tangent_v", lv, GPU_attribute(CD_TANGENT, ""), &vn); -#endif - - GPU_link(mat, "shade_inp", vn, lv, &inp); - - if (lamp->mode & LA_NO_DIFF) { - GPU_link(mat, "shade_is_no_diffuse", &is); - } - else if (lamp->type == LA_HEMI) { - GPU_link(mat, "shade_is_hemi", inp, &is); - } - else { - if (lamp->type == LA_AREA) { - float area[4][4] = {{0.0f}}, areasize = 0.0f; - - mat->dynproperty |= DYN_LAMP_VEC | DYN_LAMP_CO; - GPU_link(mat, "shade_inp_area", - GPU_builtin(GPU_VIEW_POSITION), - GPU_dynamic_uniform(lamp->dynco, GPU_DYNAMIC_LAMP_DYNCO, lamp->ob), - GPU_dynamic_uniform(lamp->dynvec, GPU_DYNAMIC_LAMP_DYNVEC, lamp->ob), vn, - GPU_uniform((float *)area), - GPU_uniform(&areasize), - GPU_uniform(&lamp->k), &inp); - } - - is = inp; /* Lambert */ - - { - if (ma->diff_shader == MA_DIFF_ORENNAYAR) - GPU_link(mat, "shade_diffuse_oren_nayer", inp, vn, lv, view, - GPU_uniform(&ma->roughness), &is); - else if (ma->diff_shader == MA_DIFF_TOON) - GPU_link(mat, "shade_diffuse_toon", vn, lv, view, - GPU_uniform(&ma->param[0]), GPU_uniform(&ma->param[1]), &is); - else if (ma->diff_shader == MA_DIFF_MINNAERT) - GPU_link(mat, "shade_diffuse_minnaert", inp, vn, view, - GPU_uniform(&ma->darkness), &is); - else if (ma->diff_shader == MA_DIFF_FRESNEL) - GPU_link(mat, "shade_diffuse_fresnel", vn, lv, view, - GPU_uniform(&ma->param[0]), GPU_uniform(&ma->param[1]), &is); - } - } - - if (ma->shade_flag & MA_CUBIC) - GPU_link(mat, "shade_cubic", is, &is); - - i = is; - GPU_link(mat, "shade_visifac", i, visifac, shi->refl, &i); - - GPU_link(mat, "set_rgb", GPU_dynamic_uniform(lamp->dyncol, GPU_DYNAMIC_LAMP_DYNCOL, lamp->ob), &lcol); - shade_light_textures(mat, lamp, &lcol); - GPU_link(mat, "shade_mul_value_v3", - GPU_dynamic_uniform(&lamp->dynenergy, GPU_DYNAMIC_LAMP_DYNENERGY, lamp->ob), lcol, &lcol); - -#if 0 - if (ma->mode & MA_TANGENT_VN) - GPU_link(mat, "shade_tangent_v_spec", GPU_attribute(CD_TANGENT, ""), &vn); -#endif - - /* this replaces if (i > 0.0) conditional until that is supported */ - /* done in shade_visifac now, GPU_link(mat, "mtex_value_clamp_positive", i, &i); */ - - if (ma->mode & MA_SHADOW) { - { - mat->dynproperty |= DYN_LAMP_PERSMAT; - - if (lamp->la->shadowmap_type == LA_SHADMAP_VARIANCE) { - GPU_link(mat, "test_shadowbuf_vsm", - GPU_builtin(GPU_VIEW_POSITION), - GPU_dynamic_texture(lamp->tex, GPU_DYNAMIC_SAMPLER_2DSHADOW, lamp->ob), - GPU_dynamic_uniform((float *)lamp->dynpersmat, GPU_DYNAMIC_LAMP_DYNPERSMAT, lamp->ob), - GPU_uniform(&lamp->bias), GPU_uniform(&lamp->la->bleedbias), inp, &shadfac); - } - else { - GPU_link(mat, "test_shadowbuf", - GPU_builtin(GPU_VIEW_POSITION), - GPU_dynamic_texture(lamp->tex, GPU_DYNAMIC_SAMPLER_2DSHADOW, lamp->ob), - GPU_dynamic_uniform((float *)lamp->dynpersmat, GPU_DYNAMIC_LAMP_DYNPERSMAT, lamp->ob), - GPU_uniform(&lamp->bias), inp, &shadfac); - } - - if (lamp->mode & LA_ONLYSHADOW) { - GPUNodeLink *shadrgb; - GPU_link(mat, "shade_only_shadow", i, shadfac, - GPU_dynamic_uniform(&lamp->dynenergy, GPU_DYNAMIC_LAMP_DYNENERGY, lamp->ob), - GPU_uniform(lamp->shadow_color), &shadrgb); - - if (!(lamp->mode & LA_NO_DIFF)) { - GPU_link(mat, "shade_only_shadow_diffuse", shadrgb, shi->rgb, - shr->diff, &shr->diff); - } - - if (!(lamp->mode & LA_NO_SPEC)) { - GPU_link(mat, "shade_only_shadow_specular", shadrgb, shi->specrgb, - shr->spec, &shr->spec); - } - - add_user_list(&mat->lamps, lamp); - return; - } - } - } - else if (lamp->mode & LA_ONLYSHADOW) { - add_user_list(&mat->lamps, lamp); - return; - } - else - GPU_link(mat, "set_value", GPU_uniform(&one), &shadfac); - - if (GPU_link_changed(shi->refl) || ma->ref != 0.0f) { - if (!(lamp->mode & LA_NO_DIFF)) { - GPUNodeLink *rgb; - GPU_link(mat, "shade_mul_value", i, lcol, &rgb); - GPU_link(mat, "mtex_value_invert", shadfac, &shadfac); - GPU_link(mat, "mix_mult", shadfac, rgb, GPU_uniform(lamp->shadow_color), &rgb); - GPU_link(mat, "mtex_value_invert", shadfac, &shadfac); - add_to_diffuse(mat, ma, shi, is, rgb, &shr->diff); - } - } - - if (!(lamp->mode & LA_NO_SPEC) && !(lamp->mode & LA_ONLYSHADOW) && - (GPU_link_changed(shi->spec) || ma->spec != 0.0f)) - { - if (lamp->type == LA_HEMI) { - GPU_link(mat, "shade_hemi_spec", vn, lv, view, GPU_uniform(&ma->spec), shi->har, visifac, &t); - GPU_link(mat, "shade_add_spec", t, lcol, shi->specrgb, &outcol); - GPU_link(mat, "shade_add_clamped", shr->spec, outcol, &shr->spec); - } - else { - if (ma->spec_shader == MA_SPEC_PHONG) { - GPU_link(mat, "shade_phong_spec", vn, lv, view, shi->har, &specfac); - } - else if (ma->spec_shader == MA_SPEC_COOKTORR) { - GPU_link(mat, "shade_cooktorr_spec", vn, lv, view, shi->har, &specfac); - } - else if (ma->spec_shader == MA_SPEC_BLINN) { - GPU_link(mat, "shade_blinn_spec", vn, lv, view, - GPU_uniform(&ma->refrac), shi->har, &specfac); - } - else if (ma->spec_shader == MA_SPEC_WARDISO) { - GPU_link(mat, "shade_wardiso_spec", vn, lv, view, - GPU_uniform(&ma->rms), &specfac); - } - else { - GPU_link(mat, "shade_toon_spec", vn, lv, view, - GPU_uniform(&ma->param[2]), GPU_uniform(&ma->param[3]), &specfac); - } - - if (lamp->type == LA_AREA) - GPU_link(mat, "shade_spec_area_inp", specfac, inp, &specfac); - - GPU_link(mat, "shade_spec_t", shadfac, shi->spec, visifac, specfac, &t); - - if (ma->mode & MA_RAMP_SPEC) { - GPUNodeLink *spec; - do_specular_ramp(shi, specfac, t, &spec); - GPU_link(mat, "shade_add_spec", t, lcol, spec, &outcol); - GPU_link(mat, "shade_add_clamped", shr->spec, outcol, &shr->spec); - } - else { - GPU_link(mat, "shade_add_spec", t, lcol, shi->specrgb, &outcol); - GPU_link(mat, "shade_add_clamped", shr->spec, outcol, &shr->spec); - } - } - } - - add_user_list(&mat->lamps, lamp); -} - -static void material_lights(GPUShadeInput *shi, GPUShadeResult *shr) -{ - Base *base; - Scene *sce_iter; - - for (SETLOOPER(shi->gpumat->scene, sce_iter, base)) { - Object *ob = base->object; - - if (ob->type == OB_LAMP) { - GPULamp *lamp = GPU_lamp_from_blender(shi->gpumat->scene, ob, NULL); - if (lamp) - shade_one_light(shi, shr, lamp); - } - - /* TODO: won't fix because will be removed. */ -#if 0 - if (ob->transflag & OB_DUPLI) { - ListBase *lb = object_duplilist(G.main->depsgraph, shi->gpumat->scene, ob); - - for (DupliObject *dob = lb->first; dob; dob = dob->next) { - Object *ob_iter = dob->ob; - - if (ob_iter->type == OB_LAMP) { - float omat[4][4]; - copy_m4_m4(omat, ob_iter->obmat); - copy_m4_m4(ob_iter->obmat, dob->mat); - - GPULamp *lamp = GPU_lamp_from_blender(shi->gpumat->scene, ob_iter, ob); - if (lamp) - shade_one_light(shi, shr, lamp); - - copy_m4_m4(ob_iter->obmat, omat); - } - } - - free_object_duplilist(lb); - } -#endif - } - - /* prevent only shadow lamps from producing negative colors.*/ - GPU_link(shi->gpumat, "shade_clamp_positive", shr->spec, &shr->spec); - GPU_link(shi->gpumat, "shade_clamp_positive", shr->diff, &shr->diff); -} - -static void texture_rgb_blend( - GPUMaterial *mat, GPUNodeLink *tex, GPUNodeLink *out, GPUNodeLink *fact, GPUNodeLink *facg, - int blendtype, GPUNodeLink **in) -{ - switch (blendtype) { - case MTEX_BLEND: - GPU_link(mat, "mtex_rgb_blend", out, tex, fact, facg, in); - break; - case MTEX_MUL: - GPU_link(mat, "mtex_rgb_mul", out, tex, fact, facg, in); - break; - case MTEX_SCREEN: - GPU_link(mat, "mtex_rgb_screen", out, tex, fact, facg, in); - break; - case MTEX_OVERLAY: - GPU_link(mat, "mtex_rgb_overlay", out, tex, fact, facg, in); - break; - case MTEX_SUB: - GPU_link(mat, "mtex_rgb_sub", out, tex, fact, facg, in); - break; - case MTEX_ADD: - GPU_link(mat, "mtex_rgb_add", out, tex, fact, facg, in); - break; - case MTEX_DIV: - GPU_link(mat, "mtex_rgb_div", out, tex, fact, facg, in); - break; - case MTEX_DIFF: - GPU_link(mat, "mtex_rgb_diff", out, tex, fact, facg, in); - break; - case MTEX_DARK: - GPU_link(mat, "mtex_rgb_dark", out, tex, fact, facg, in); - break; - case MTEX_LIGHT: - GPU_link(mat, "mtex_rgb_light", out, tex, fact, facg, in); - break; - case MTEX_BLEND_HUE: - GPU_link(mat, "mtex_rgb_hue", out, tex, fact, facg, in); - break; - case MTEX_BLEND_SAT: - GPU_link(mat, "mtex_rgb_sat", out, tex, fact, facg, in); - break; - case MTEX_BLEND_VAL: - GPU_link(mat, "mtex_rgb_val", out, tex, fact, facg, in); - break; - case MTEX_BLEND_COLOR: - GPU_link(mat, "mtex_rgb_color", out, tex, fact, facg, in); - break; - case MTEX_SOFT_LIGHT: - GPU_link(mat, "mtex_rgb_soft", out, tex, fact, facg, in); - break; - case MTEX_LIN_LIGHT: - GPU_link(mat, "mtex_rgb_linear", out, tex, fact, facg, in); - break; - default: - GPU_link(mat, "set_rgb_zero", &in); - break; - } -} - -static void texture_value_blend( - GPUMaterial *mat, GPUNodeLink *tex, GPUNodeLink *out, GPUNodeLink *fact, GPUNodeLink *facg, - int blendtype, GPUNodeLink **in) -{ - switch (blendtype) { - case MTEX_BLEND: - GPU_link(mat, "mtex_value_blend", out, tex, fact, facg, in); - break; - case MTEX_MUL: - GPU_link(mat, "mtex_value_mul", out, tex, fact, facg, in); - break; - case MTEX_SCREEN: - GPU_link(mat, "mtex_value_screen", out, tex, fact, facg, in); - break; - case MTEX_SUB: - GPU_link(mat, "mtex_value_sub", out, tex, fact, facg, in); - break; - case MTEX_ADD: - GPU_link(mat, "mtex_value_add", out, tex, fact, facg, in); - break; - case MTEX_DIV: - GPU_link(mat, "mtex_value_div", out, tex, fact, facg, in); - break; - case MTEX_DIFF: - GPU_link(mat, "mtex_value_diff", out, tex, fact, facg, in); - break; - case MTEX_DARK: - GPU_link(mat, "mtex_value_dark", out, tex, fact, facg, in); - break; - case MTEX_LIGHT: - GPU_link(mat, "mtex_value_light", out, tex, fact, facg, in); - break; - default: - GPU_link(mat, "set_value_zero", &in); - break; - } -} - -static void do_material_tex(GPUShadeInput *shi) -{ - Material *ma = shi->mat; - GPUMaterial *mat = shi->gpumat; - MTex *mtex; - Tex *tex; - GPUNodeLink *texco, *tin, *trgb, *tnor, *tcol, *stencil, *tnorfac; - GPUNodeLink *texco_norm, *texco_orco, *texco_object; - GPUNodeLink *texco_global, *texco_uv = NULL; - GPUNodeLink *newnor, *orn; - float one = 1.0f; - int rgbnor, talpha; - bool init_done = false; - int iBumpSpacePrev = 0; /* Not necessary, quieting gcc warning. */ - GPUNodeLink *vNorg, *vNacc, *fPrevMagnitude; - int iFirstTimeNMap = 1; - bool found_deriv_map = false; - - GPU_link(mat, "set_value", GPU_uniform(&one), &stencil); - - GPU_link(mat, "texco_norm", GPU_builtin(GPU_VIEW_NORMAL), &texco_norm); - GPU_link(mat, "texco_orco", GPU_attribute(CD_ORCO, ""), &texco_orco); - GPU_link(mat, "texco_object", GPU_builtin(GPU_INVERSE_VIEW_MATRIX), - GPU_builtin(GPU_INVERSE_OBJECT_MATRIX), - GPU_builtin(GPU_VIEW_POSITION), &texco_object); -#if 0 - GPU_link(mat, "texco_tangent", GPU_attribute(CD_TANGENT, ""), &texco_tangent); -#endif - GPU_link(mat, "texco_global", GPU_builtin(GPU_INVERSE_VIEW_MATRIX), - GPU_builtin(GPU_VIEW_POSITION), &texco_global); - - orn = texco_norm; - - /* go over texture slots */ - for (int tex_nr = 0; tex_nr < MAX_MTEX; tex_nr++) { - /* separate tex switching */ - if (ma->septex & (1 << tex_nr)) continue; - - if (ma->mtex[tex_nr]) { - mtex = ma->mtex[tex_nr]; - - tex = mtex->tex; - if (tex == NULL) continue; - - /* which coords */ - if (mtex->texco == TEXCO_ORCO) - texco = texco_orco; - else if (mtex->texco == TEXCO_OBJECT) - texco = texco_object; - else if (mtex->texco == TEXCO_NORM) - texco = orn; - else if (mtex->texco == TEXCO_TANGENT) - texco = texco_object; - else if (mtex->texco == TEXCO_GLOB) - texco = texco_global; - else if (mtex->texco == TEXCO_REFL) { - GPU_link(mat, "texco_refl", shi->vn, shi->view, &shi->ref); - texco = shi->ref; - } - else if (mtex->texco == TEXCO_UV) { - if (1) { //!(texco_uv && strcmp(mtex->uvname, lastuvname) == 0)) { - GPU_link(mat, "texco_uv", GPU_attribute(CD_MTFACE, mtex->uvname), &texco_uv); - /*lastuvname = mtex->uvname;*/ /*UNUSED*/ - } - texco = texco_uv; - } - else - continue; - - /* in case of uv, this would just undo a multiplication in texco_uv */ - if (mtex->texco != TEXCO_UV) - GPU_link(mat, "mtex_2d_mapping", texco, &texco); - - if (mtex->size[0] != 1.0f || mtex->size[1] != 1.0f || mtex->size[2] != 1.0f) - GPU_link(mat, "mtex_mapping_size", texco, GPU_uniform(mtex->size), &texco); - - float ofs[3] = { - mtex->ofs[0] + 0.5f - 0.5f * mtex->size[0], - mtex->ofs[1] + 0.5f - 0.5f * mtex->size[1], - 0.0f - }; - - if (ofs[0] != 0.0f || ofs[1] != 0.0f || ofs[2] != 0.0f) - GPU_link(mat, "mtex_mapping_ofs", texco, GPU_uniform(ofs), &texco); - - talpha = 0; - - if (tex && tex->ima && - ((tex->type == TEX_IMAGE) || - ((tex->type == TEX_ENVMAP) && (mtex->texco == TEXCO_REFL)))) - { - if (tex->type == TEX_IMAGE) { - GPU_link(mat, "mtex_image", texco, GPU_image(tex->ima, &tex->iuser, false), &tin, &trgb); - } - else { - GPU_link(mat, "mtex_cube_map_refl", - GPU_cube_map(tex->ima, &tex->iuser, false), shi->view, shi->vn, - GPU_builtin(GPU_INVERSE_VIEW_MATRIX), - GPU_builtin(GPU_VIEW_MATRIX), &tin, &trgb); - } - rgbnor = TEX_RGB; - - talpha = ((tex->imaflag & TEX_USEALPHA) && tex->ima && (tex->ima->flag & IMA_IGNORE_ALPHA) == 0); - } - else { - continue; - } - - /* texture output */ - if ((rgbnor & TEX_RGB) && (mtex->texflag & MTEX_RGBTOINT)) { - GPU_link(mat, "mtex_rgbtoint", trgb, &tin); - rgbnor -= TEX_RGB; - } - - if (mtex->texflag & MTEX_NEGATIVE) { - if (rgbnor & TEX_RGB) - GPU_link(mat, "mtex_rgb_invert", trgb, &trgb); - else - GPU_link(mat, "mtex_value_invert", tin, &tin); - } - - if (mtex->texflag & MTEX_STENCIL) { - if (rgbnor & TEX_RGB) - GPU_link(mat, "mtex_rgb_stencil", stencil, trgb, &stencil, &trgb); - else - GPU_link(mat, "mtex_value_stencil", stencil, tin, &stencil, &tin); - } - - /* mapping */ - if (mtex->mapto & (MAP_COL | MAP_COLSPEC | MAP_COLMIR)) { - /* stencil maps on the texture control slider, not texture intensity value */ - if ((rgbnor & TEX_RGB) == 0) { - GPU_link(mat, "set_rgb", GPU_uniform(&mtex->r), &tcol); - } - else { - GPU_link(mat, "set_rgba", trgb, &tcol); - - if (mtex->mapto & MAP_ALPHA) - GPU_link(mat, "set_value", stencil, &tin); - else if (talpha) - GPU_link(mat, "mtex_alpha_from_col", trgb, &tin); - else - GPU_link(mat, "set_value_one", &tin); - } - - if ((tex->type == TEX_IMAGE) || - ((tex->type == TEX_ENVMAP) && (mtex->texco == TEXCO_REFL))) - { - if (GPU_material_do_color_management(mat)) { - GPU_link(mat, "srgb_to_linearrgb", tcol, &tcol); - } - } - - if (mtex->mapto & MAP_COL) { - GPUNodeLink *colfac; - - if (mtex->colfac == 1.0f) colfac = stencil; - else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->colfac), stencil, &colfac); - - texture_rgb_blend(mat, tcol, shi->rgb, tin, colfac, mtex->blendtype, &shi->rgb); - } - - if (mtex->mapto & MAP_COLSPEC) { - GPUNodeLink *colspecfac; - - if (mtex->colspecfac == 1.0f) colspecfac = stencil; - else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->colspecfac), stencil, &colspecfac); - - texture_rgb_blend(mat, tcol, shi->specrgb, tin, colspecfac, mtex->blendtype, &shi->specrgb); - } - - if (mtex->mapto & MAP_COLMIR) { - GPUNodeLink *colmirfac; - - if (mtex->mirrfac == 1.0f) colmirfac = stencil; - else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->mirrfac), stencil, &colmirfac); - - /* exception for envmap only */ - if (tex->type == TEX_ENVMAP && mtex->blendtype == MTEX_BLEND) { - GPU_link(mat, "mtex_mirror", tcol, shi->refcol, tin, colmirfac, &shi->refcol); - } - else - texture_rgb_blend(mat, tcol, shi->mir, tin, colmirfac, mtex->blendtype, &shi->mir); - } - } - - if (mtex->mapto & MAP_NORM) { - if (tex->type == TEX_IMAGE) { - found_deriv_map = tex->imaflag & TEX_DERIVATIVEMAP; - - if (tex->imaflag & TEX_NORMALMAP) { - /* normalmap image */ - GPU_link(mat, "mtex_normal", texco, GPU_image(tex->ima, &tex->iuser, true), &tnor); - - if (mtex->norfac < 0.0f) - GPU_link(mat, "mtex_negate_texnormal", tnor, &tnor); - - if (mtex->normapspace == MTEX_NSPACE_TANGENT) { - if (iFirstTimeNMap != 0) { - // use unnormalized normal (this is how we bake it - closer to gamedev) - GPUNodeLink *vNegNorm; - GPU_link(mat, "vec_math_negate", - GPU_builtin(GPU_VIEW_NORMAL), &vNegNorm); - GPU_link(mat, "mtex_nspace_tangent", - GPU_attribute(CD_TANGENT, ""), vNegNorm, tnor, &newnor); - iFirstTimeNMap = 0; - } - else { /* otherwise use accumulated perturbations */ - GPU_link(mat, "mtex_nspace_tangent", - GPU_attribute(CD_TANGENT, ""), shi->vn, tnor, &newnor); - } - } - else if (mtex->normapspace == MTEX_NSPACE_OBJECT) { - /* transform normal by object then view matrix */ - GPU_link(mat, "mtex_nspace_object", tnor, &newnor); - } - else if (mtex->normapspace == MTEX_NSPACE_WORLD) { - /* transform normal by view matrix */ - GPU_link(mat, "mtex_nspace_world", GPU_builtin(GPU_VIEW_MATRIX), tnor, &newnor); - } - else { - /* no transform, normal in camera space */ - newnor = tnor; - } - - float norfac = min_ff(fabsf(mtex->norfac), 1.0f); - - if (norfac == 1.0f && !GPU_link_changed(stencil)) { - shi->vn = newnor; - } - else { - tnorfac = GPU_uniform(&norfac); - - if (GPU_link_changed(stencil)) - GPU_link(mat, "math_multiply", tnorfac, stencil, &tnorfac); - - GPU_link(mat, "mtex_blend_normal", tnorfac, shi->vn, newnor, &shi->vn); - } - - } - else if (found_deriv_map || - (mtex->texflag & (MTEX_3TAP_BUMP | MTEX_5TAP_BUMP | MTEX_BICUBIC_BUMP))) - { - /* ntap bumpmap image */ - int iBumpSpace; - float ima_x, ima_y; - - float imag_tspace_dimension_x = 1024.0f; /* only used for texture space variant */ - float aspect = 1.0f; - - GPUNodeLink *vR1, *vR2; - GPUNodeLink *dBs, *dBt, *fDet; - - float hScale = 0.1f; /* compatibility adjustment factor for all bumpspace types */ - if (mtex->texflag & MTEX_BUMP_TEXTURESPACE) - hScale = 13.0f; /* factor for scaling texspace bumps */ - else if (found_deriv_map) - hScale = 1.0f; - - /* resolve texture resolution */ - if ((mtex->texflag & MTEX_BUMP_TEXTURESPACE) || found_deriv_map) { - ImBuf *ibuf = BKE_image_acquire_ibuf(tex->ima, &tex->iuser, NULL); - ima_x = 512.0f; ima_y = 512.0f; /* prevent calling textureSize, glsl 1.3 only */ - if (ibuf) { - ima_x = ibuf->x; - ima_y = ibuf->y; - aspect = (float)ima_y / ima_x; - } - BKE_image_release_ibuf(tex->ima, ibuf, NULL); - } - - /* The negate on norfac is done because the - * normal in the renderer points inward which corresponds - * to inverting the bump map. Should this ever change - * this negate must be removed. */ - float norfac = -hScale * mtex->norfac; - if (found_deriv_map) { - float fVirtDim = sqrtf(fabsf(ima_x * mtex->size[0] * ima_y * mtex->size[1])); - norfac /= MAX2(fVirtDim, FLT_EPSILON); - } - - tnorfac = GPU_uniform(&norfac); - - if (found_deriv_map) - GPU_link(mat, "math_multiply", tnorfac, GPU_builtin(GPU_AUTO_BUMPSCALE), &tnorfac); - - if (GPU_link_changed(stencil)) - GPU_link(mat, "math_multiply", tnorfac, stencil, &tnorfac); - - if (!init_done) { - /* copy shi->vn to vNorg and vNacc, set magnitude to 1 */ - GPU_link(mat, "mtex_bump_normals_init", shi->vn, &vNorg, &vNacc, &fPrevMagnitude); - iBumpSpacePrev = 0; - init_done = true; - } - - // find current bump space - if (mtex->texflag & MTEX_BUMP_OBJECTSPACE) - iBumpSpace = 1; - else if (mtex->texflag & MTEX_BUMP_TEXTURESPACE) - iBumpSpace = 2; - else - iBumpSpace = 4; /* ViewSpace */ - - /* re-initialize if bump space changed */ - if (iBumpSpacePrev != iBumpSpace) { - GPUNodeLink *surf_pos = GPU_builtin(GPU_VIEW_POSITION); - - if (mtex->texflag & MTEX_BUMP_OBJECTSPACE) - GPU_link(mat, "mtex_bump_init_objspace", - surf_pos, vNorg, - GPU_builtin(GPU_VIEW_MATRIX), - GPU_builtin(GPU_INVERSE_VIEW_MATRIX), - GPU_builtin(GPU_OBJECT_MATRIX), - GPU_builtin(GPU_INVERSE_OBJECT_MATRIX), - fPrevMagnitude, vNacc, - &fPrevMagnitude, &vNacc, - &vR1, &vR2, &fDet); - - else if (mtex->texflag & MTEX_BUMP_TEXTURESPACE) - GPU_link(mat, "mtex_bump_init_texturespace", - surf_pos, vNorg, - fPrevMagnitude, vNacc, - &fPrevMagnitude, &vNacc, - &vR1, &vR2, &fDet); - - else - GPU_link(mat, "mtex_bump_init_viewspace", - surf_pos, vNorg, - fPrevMagnitude, vNacc, - &fPrevMagnitude, &vNacc, - &vR1, &vR2, &fDet); - - iBumpSpacePrev = iBumpSpace; - } - - - if (found_deriv_map) { - GPU_link(mat, "mtex_bump_deriv", - texco, GPU_image(tex->ima, &tex->iuser, true), - GPU_uniform(&ima_x), GPU_uniform(&ima_y), tnorfac, - &dBs, &dBt); - } - else if (mtex->texflag & MTEX_3TAP_BUMP) - GPU_link(mat, "mtex_bump_tap3", - texco, GPU_image(tex->ima, &tex->iuser, true), tnorfac, - &dBs, &dBt); - else if (mtex->texflag & MTEX_5TAP_BUMP) - GPU_link(mat, "mtex_bump_tap5", - texco, GPU_image(tex->ima, &tex->iuser, true), tnorfac, - &dBs, &dBt); - else if (mtex->texflag & MTEX_BICUBIC_BUMP) { - if (GPU_bicubic_bump_support()) { - GPU_link(mat, "mtex_bump_bicubic", - texco, GPU_image(tex->ima, &tex->iuser, true), tnorfac, - &dBs, &dBt); - } - else { - GPU_link(mat, "mtex_bump_tap5", - texco, GPU_image(tex->ima, &tex->iuser, true), tnorfac, - &dBs, &dBt); - } - } - - - if (mtex->texflag & MTEX_BUMP_TEXTURESPACE) { - float imag_tspace_dimension_y = aspect * imag_tspace_dimension_x; - GPU_link(mat, "mtex_bump_apply_texspace", - fDet, dBs, dBt, vR1, vR2, - GPU_image(tex->ima, &tex->iuser, true), texco, - GPU_uniform(&imag_tspace_dimension_x), - GPU_uniform(&imag_tspace_dimension_y), vNacc, - &vNacc, &shi->vn); - } - else - GPU_link(mat, "mtex_bump_apply", - fDet, dBs, dBt, vR1, vR2, vNacc, - &vNacc, &shi->vn); - - } - } - - GPU_link(mat, "vec_math_negate", shi->vn, &orn); - } - - if ((mtex->mapto & MAP_VARS)) { - if (rgbnor & TEX_RGB) { - if (talpha) - GPU_link(mat, "mtex_alpha_from_col", trgb, &tin); - else - GPU_link(mat, "mtex_rgbtoint", trgb, &tin); - } - - if (mtex->mapto & MAP_REF) { - GPUNodeLink *difffac; - - if (mtex->difffac == 1.0f) difffac = stencil; - else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->difffac), stencil, &difffac); - - texture_value_blend( - mat, GPU_uniform(&mtex->def_var), shi->refl, tin, difffac, - mtex->blendtype, &shi->refl); - GPU_link(mat, "mtex_value_clamp_positive", shi->refl, &shi->refl); - } - if (mtex->mapto & MAP_SPEC) { - GPUNodeLink *specfac; - - if (mtex->specfac == 1.0f) specfac = stencil; - else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->specfac), stencil, &specfac); - - texture_value_blend( - mat, GPU_uniform(&mtex->def_var), shi->spec, tin, specfac, - mtex->blendtype, &shi->spec); - GPU_link(mat, "mtex_value_clamp_positive", shi->spec, &shi->spec); - } - if (mtex->mapto & MAP_EMIT) { - GPUNodeLink *emitfac; - - if (mtex->emitfac == 1.0f) emitfac = stencil; - else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->emitfac), stencil, &emitfac); - - texture_value_blend( - mat, GPU_uniform(&mtex->def_var), shi->emit, tin, emitfac, - mtex->blendtype, &shi->emit); - GPU_link(mat, "mtex_value_clamp_positive", shi->emit, &shi->emit); - } - if (mtex->mapto & MAP_HAR) { - GPUNodeLink *hardfac; - - if (mtex->hardfac == 1.0f) hardfac = stencil; - else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->hardfac), stencil, &hardfac); - - GPU_link(mat, "mtex_har_divide", shi->har, &shi->har); - texture_value_blend( - mat, GPU_uniform(&mtex->def_var), shi->har, tin, hardfac, - mtex->blendtype, &shi->har); - GPU_link(mat, "mtex_har_multiply_clamp", shi->har, &shi->har); - } - if (mtex->mapto & MAP_ALPHA) { - GPUNodeLink *alphafac; - - if (mtex->alphafac == 1.0f) alphafac = stencil; - else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->alphafac), stencil, &alphafac); - - texture_value_blend( - mat, GPU_uniform(&mtex->def_var), shi->alpha, tin, alphafac, - mtex->blendtype, &shi->alpha); - GPU_link(mat, "mtex_value_clamp", shi->alpha, &shi->alpha); - } - if (mtex->mapto & MAP_AMB) { - GPUNodeLink *ambfac; - - if (mtex->ambfac == 1.0f) ambfac = stencil; - else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->ambfac), stencil, &ambfac); - - texture_value_blend( - mat, GPU_uniform(&mtex->def_var), shi->amb, tin, ambfac, - mtex->blendtype, &shi->amb); - GPU_link(mat, "mtex_value_clamp", shi->amb, &shi->amb); - } - } - } - } -} - -void GPU_shadeinput_set(GPUMaterial *mat, Material *ma, GPUShadeInput *shi) -{ - float one = 1.0f; - - memset(shi, 0, sizeof(*shi)); - - shi->gpumat = mat; - shi->mat = ma; - - GPU_link(mat, "set_rgb", GPU_dynamic_uniform(&ma->r, GPU_DYNAMIC_MAT_DIFFRGB, ma), &shi->rgb); - GPU_link(mat, "set_rgb", GPU_dynamic_uniform(&ma->specr, GPU_DYNAMIC_MAT_SPECRGB, ma), &shi->specrgb); - GPU_link(mat, "set_rgb", GPU_dynamic_uniform(&ma->mirr, GPU_DYNAMIC_MAT_MIR, ma), &shi->mir); - GPU_link(mat, "set_rgba_zero", &shi->refcol); - GPU_link(mat, "shade_norm", GPU_builtin(GPU_VIEW_NORMAL), &shi->vn); - - if (mat->alpha) - GPU_link(mat, "set_value", GPU_dynamic_uniform(&ma->alpha, GPU_DYNAMIC_MAT_ALPHA, ma), &shi->alpha); - else - GPU_link(mat, "set_value", GPU_uniform(&one), &shi->alpha); - - GPU_link(mat, "set_value", GPU_dynamic_uniform(&ma->ref, GPU_DYNAMIC_MAT_REF, ma), &shi->refl); - GPU_link(mat, "set_value", GPU_dynamic_uniform(&ma->spec, GPU_DYNAMIC_MAT_SPEC, ma), &shi->spec); - GPU_link(mat, "set_value", GPU_dynamic_uniform(&ma->emit, GPU_DYNAMIC_MAT_EMIT, ma), &shi->emit); - GPU_link(mat, "set_value", GPU_dynamic_uniform((float *)&ma->har, GPU_DYNAMIC_MAT_HARD, ma), &shi->har); - GPU_link(mat, "set_value", GPU_dynamic_uniform(&ma->amb, GPU_DYNAMIC_MAT_AMB, ma), &shi->amb); - GPU_link(mat, "set_value", GPU_uniform(&ma->spectra), &shi->spectra); - GPU_link(mat, "shade_view", GPU_builtin(GPU_VIEW_POSITION), &shi->view); - GPU_link(mat, "vcol_attribute", GPU_attribute(CD_MCOL, ""), &shi->vcol); - if (GPU_material_do_color_management(mat)) - GPU_link(mat, "srgb_to_linearrgb", shi->vcol, &shi->vcol); - GPU_link(mat, "texco_refl", shi->vn, shi->view, &shi->ref); -} - -void GPU_mist_update_enable(short enable) -{ - GPUWorld.mistenabled = (float)enable; -} - -void GPU_mist_update_values(int type, float start, float dist, float inten, float color[3]) -{ - GPUWorld.mistype = (float)type; - GPUWorld.miststart = start; - GPUWorld.mistdistance = dist; - GPUWorld.mistintensity = inten; - copy_v3_v3(GPUWorld.mistcol, color); - GPUWorld.mistcol[3] = 1.0f; -} - -void GPU_horizon_update_color(float color[3]) -{ - copy_v3_v3(GPUWorld.horicol, color); -} - -void GPU_ambient_update_color(float color[3]) -{ - copy_v3_v3(GPUWorld.ambcol, color); - GPUWorld.ambcol[3] = 1.0f; -} - -void GPU_zenith_update_color(float color[3]) -{ - copy_v3_v3(GPUWorld.zencol, color); -} - -void GPU_shaderesult_set(GPUShadeInput *shi, GPUShadeResult *shr) -{ - GPUMaterial *mat = shi->gpumat; - GPUNodeLink *emit, *ulinfac, *ulogfac, *mistfac; - Material *ma = shi->mat; - World *world = mat->scene->world; - float linfac, logfac; - - memset(shr, 0, sizeof(*shr)); - - if (ma->mode & MA_VERTEXCOLP) - shi->rgb = shi->vcol; - - do_material_tex(shi); - - if (ma->mode & MA_SHLESS) { - GPU_link(mat, "set_rgb", shi->rgb, &shr->diff); - GPU_link(mat, "set_rgb_zero", &shr->spec); - GPU_link(mat, "set_value", shi->alpha, &shr->alpha); - shr->combined = shr->diff; - } - else { - if (GPU_link_changed(shi->emit) || ma->emit != 0.0f) { - if ((ma->mode & (MA_VERTEXCOL | MA_VERTEXCOLP)) == MA_VERTEXCOL) { - GPU_link(mat, "shade_add", shi->emit, shi->vcol, &emit); - GPU_link(mat, "shade_mul", emit, shi->rgb, &shr->diff); - } - else - GPU_link(mat, "shade_mul_value", shi->emit, shi->rgb, &shr->diff); - } - else - GPU_link(mat, "set_rgb_zero", &shr->diff); - - GPU_link(mat, "set_rgb_zero", &shr->spec); - - material_lights(shi, shr); - - shr->combined = shr->diff; - - GPU_link(mat, "set_value", shi->alpha, &shr->alpha); - - if (world) { - /* exposure correction */ - if (world->exp != 0.0f || world->range != 1.0f) { - linfac = 1.0f + powf((2.0f * world->exp + 0.5f), -10); - logfac = logf((linfac - 1.0f) / linfac) / world->range; - - GPU_link(mat, "set_value", GPU_uniform(&linfac), &ulinfac); - GPU_link(mat, "set_value", GPU_uniform(&logfac), &ulogfac); - - GPU_link(mat, "shade_exposure_correct", shr->combined, - ulinfac, ulogfac, &shr->combined); - GPU_link(mat, "shade_exposure_correct", shr->spec, - ulinfac, ulogfac, &shr->spec); - } - - /* environment lighting */ - if ((world->mode & WO_ENV_LIGHT) && - (mat->scene->r.mode & R_SHADOW) && - !BKE_scene_use_new_shading_nodes(mat->scene)) - { - if ((world->ao_env_energy != 0.0f) && (GPU_link_changed(shi->amb) || ma->amb != 0.0f) && - (GPU_link_changed(shi->refl) || ma->ref != 0.0f)) - { - if (world->aocolor != WO_AOPLAIN) { - if (!(is_zero_v3(&world->horr) & is_zero_v3(&world->zenr))) { - GPUNodeLink *fcol, *f; - GPU_link(mat, "math_multiply", shi->amb, shi->refl, &f); - GPU_link(mat, "math_multiply", f, GPU_uniform(&world->ao_env_energy), &f); - GPU_link(mat, "shade_mul_value", f, shi->rgb, &fcol); - GPU_link(mat, "env_apply", shr->combined, - GPU_dynamic_uniform(GPUWorld.horicol, GPU_DYNAMIC_HORIZON_COLOR, NULL), - GPU_dynamic_uniform(GPUWorld.zencol, GPU_DYNAMIC_ZENITH_COLOR, NULL), fcol, - GPU_builtin(GPU_VIEW_MATRIX), shi->vn, &shr->combined); - } - } - else { - GPUNodeLink *f; - GPU_link(mat, "math_multiply", shi->amb, shi->refl, &f); - GPU_link(mat, "math_multiply", f, GPU_uniform(&world->ao_env_energy), &f); - GPU_link(mat, "shade_maddf", shr->combined, f, shi->rgb, &shr->combined); - } - } - } - - /* ambient color */ - if (GPU_link_changed(shi->amb) || ma->amb != 0.0f) { - GPU_link(mat, "shade_maddf", shr->combined, GPU_uniform(&ma->amb), - GPU_dynamic_uniform(GPUWorld.ambcol, GPU_DYNAMIC_AMBIENT_COLOR, NULL), - &shr->combined); - } - } - - if (ma->mode & MA_TRANSP && (ma->mode & (MA_ZTRANSP | MA_RAYTRANSP))) { - if (GPU_link_changed(shi->spectra) || ma->spectra != 0.0f) { - GPU_link(mat, "alpha_spec_correction", shr->spec, shi->spectra, - shi->alpha, &shr->alpha); - } - } - - if (ma->mode & MA_RAMP_COL) ramp_diffuse_result(shi, &shr->combined); - if (ma->mode & MA_RAMP_SPEC) ramp_spec_result(shi, &shr->spec); - - if (GPU_link_changed(shi->refcol)) - GPU_link(mat, "shade_add_mirror", shi->mir, shi->refcol, shr->combined, &shr->combined); - - if (GPU_link_changed(shi->spec) || ma->spec != 0.0f) - GPU_link(mat, "shade_add", shr->combined, shr->spec, &shr->combined); - } - - GPU_link(mat, "mtex_alpha_to_col", shr->combined, shr->alpha, &shr->combined); - - if (ma->shade_flag & MA_OBCOLOR) - GPU_link(mat, "shade_obcolor", shr->combined, GPU_builtin(GPU_OBCOLOR), &shr->combined); - - if (!(ma->mode & MA_NOMIST)) { - GPU_link(mat, "shade_mist_factor", GPU_builtin(GPU_VIEW_POSITION), - GPU_dynamic_uniform(&GPUWorld.mistenabled, GPU_DYNAMIC_MIST_ENABLE, NULL), - GPU_dynamic_uniform(&GPUWorld.miststart, GPU_DYNAMIC_MIST_START, NULL), - GPU_dynamic_uniform(&GPUWorld.mistdistance, GPU_DYNAMIC_MIST_DISTANCE, NULL), - GPU_dynamic_uniform(&GPUWorld.mistype, GPU_DYNAMIC_MIST_TYPE, NULL), - GPU_dynamic_uniform(&GPUWorld.mistintensity, GPU_DYNAMIC_MIST_INTENSITY, NULL), &mistfac); - - GPU_link(mat, "mix_blend", mistfac, shr->combined, - GPU_dynamic_uniform(GPUWorld.mistcol, GPU_DYNAMIC_MIST_COLOR, NULL), &shr->combined); - } - - if (!mat->alpha) { - if (world && (GPU_link_changed(shr->alpha) || ma->alpha != 1.0f)) - GPU_link(mat, "shade_world_mix", GPU_dynamic_uniform(GPUWorld.horicol, GPU_DYNAMIC_HORIZON_COLOR, NULL), - shr->combined, &shr->combined); - - GPU_link(mat, "shade_alpha_opaque", shr->combined, &shr->combined); - } - - if (ma->shade_flag & MA_OBCOLOR) { - mat->obcolalpha = 1; - GPU_link(mat, "shade_alpha_obcolor", shr->combined, GPU_builtin(GPU_OBCOLOR), &shr->combined); - } -} - -static GPUNodeLink *GPU_blender_material(GPUMaterial *mat, Material *ma) -{ - GPUShadeInput shi; - GPUShadeResult shr; - - GPU_shadeinput_set(mat, ma, &shi); - GPU_shaderesult_set(&shi, &shr); - - return shr.combined; -} - -static GPUNodeLink *gpu_material_diffuse_bsdf(GPUMaterial *mat, Material *ma) -{ - static float roughness = 0.0f; - GPUNodeLink *outlink; - - GPU_link(mat, "node_bsdf_diffuse", - GPU_uniform(&ma->r), GPU_uniform(&roughness), GPU_builtin(GPU_VIEW_NORMAL), &outlink); - - return outlink; -} - -static GPUNodeLink *gpu_material_preview_matcap(GPUMaterial *mat, Material *ma) -{ - GPUNodeLink *outlink; - - /* some explanations here: - * matcap normal holds the normal remapped to the 0.0 - 1.0 range. To take advantage of flat shading, we abuse - * the built in secondary color of opengl. Color is just the regular color, which should include mask value too. - * This also needs flat shading so we use the primary opengl color built-in */ - GPU_link(mat, "material_preview_matcap", GPU_uniform(&ma->r), GPU_image_preview(ma->preview), - GPU_opengl_builtin(GPU_MATCAP_NORMAL), GPU_opengl_builtin(GPU_COLOR), &outlink); - - return outlink; -} - -/* new solid draw mode with glsl matcaps */ -GPUMaterial *GPU_material_matcap(Scene *scene, Material *ma, bool use_opensubdiv) -{ - GPUMaterial *mat; - GPUNodeLink *outlink; - LinkData *link; - - for (link = ma->gpumaterial.first; link; link = link->next) { - GPUMaterial *current_material = (GPUMaterial *)link->data; - if (current_material->scene == scene && - current_material->is_opensubdiv == use_opensubdiv) - { - return current_material; - } - } - - /* allocate material */ - mat = GPU_material_construct_begin(ma); - mat->scene = scene; - mat->type = GPU_MATERIAL_TYPE_MESH; - mat->is_opensubdiv = use_opensubdiv; - - if (ma->preview && ma->preview->rect[0]) { - outlink = gpu_material_preview_matcap(mat, ma); - } - else { - outlink = gpu_material_diffuse_bsdf(mat, ma); - } - - GPU_material_output_link(mat, outlink); - - gpu_material_construct_end(mat, "matcap_pass"); - - /* note that even if building the shader fails in some way, we still keep - * it to avoid trying to compile again and again, and simple do not use - * the actual shader on drawing */ - - link = MEM_callocN(sizeof(LinkData), "GPUMaterialLink"); - link->data = mat; - BLI_addtail(&ma->gpumaterial, link); - - return mat; -} - -static void do_world_tex(GPUShadeInput *shi, struct World *wo, GPUNodeLink **hor, GPUNodeLink **zen, GPUNodeLink **blend) -{ - GPUMaterial *mat = shi->gpumat; - GPUNodeLink *texco, *tin, *trgb, *stencil, *tcol, *zenfac; - MTex *mtex; - Tex *tex; - float ofs[3], zero = 0.0f; - int tex_nr, rgbnor; - - GPU_link(mat, "set_value_one", &stencil); - /* go over texture slots */ - for (tex_nr = 0; tex_nr < MAX_MTEX; tex_nr++) { - if (wo->mtex[tex_nr]) { - mtex = wo->mtex[tex_nr]; - tex = mtex->tex; - if (tex == NULL || !tex->ima || (tex->type != TEX_IMAGE && tex->type != TEX_ENVMAP)) - continue; - /* which coords */ - if (mtex->texco == TEXCO_VIEW || mtex->texco == TEXCO_GLOB) { - if (tex->type == TEX_IMAGE) - texco = GPU_builtin(GPU_VIEW_POSITION); - else if (tex->type == TEX_ENVMAP) - GPU_link(mat, "background_transform_to_world", GPU_builtin(GPU_VIEW_POSITION), &texco); - } - else if (mtex->texco == TEXCO_EQUIRECTMAP || mtex->texco == TEXCO_ANGMAP) { - if ((tex->type == TEX_IMAGE && wo->skytype & WO_SKYREAL) || tex->type == TEX_ENVMAP) - GPU_link(mat, "background_transform_to_world", GPU_builtin(GPU_VIEW_POSITION), &texco); - else - texco = GPU_builtin(GPU_VIEW_POSITION); - } - else - continue; - GPU_link(mat, "texco_norm", texco, &texco); - if (tex->type == TEX_IMAGE && !(wo->skytype & WO_SKYREAL)) { - GPU_link(mat, "mtex_2d_mapping", texco, &texco); - } - if (mtex->size[0] != 1.0f || mtex->size[1] != 1.0f || mtex->size[2] != 1.0f) { - float size[3] = { mtex->size[0], mtex->size[1], mtex->size[2] }; - if (tex->type == TEX_ENVMAP) { - size[1] = mtex->size[2]; - size[2] = mtex->size[1]; - } - GPU_link(mat, "mtex_mapping_size", texco, GPU_uniform(size), &texco); - } - ofs[0] = mtex->ofs[0] + 0.5f - 0.5f * mtex->size[0]; - if (tex->type == TEX_ENVMAP) { - ofs[1] = -mtex->ofs[2] + 0.5f - 0.5f * mtex->size[2]; - ofs[2] = mtex->ofs[1] + 0.5f - 0.5f * mtex->size[1]; - } - else { - ofs[1] = mtex->ofs[1] + 0.5f - 0.5f * mtex->size[1]; - ofs[2] = 0.0; - } - if (ofs[0] != 0.0f || ofs[1] != 0.0f || ofs[2] != 0.0f) - GPU_link(mat, "mtex_mapping_ofs", texco, GPU_uniform(ofs), &texco); - if (mtex->texco == TEXCO_EQUIRECTMAP) { - GPU_link(mat, "node_tex_environment_equirectangular", texco, GPU_image(tex->ima, &tex->iuser, false), &trgb); - } - else if (mtex->texco == TEXCO_ANGMAP) { - GPU_link(mat, "node_tex_environment_mirror_ball", texco, GPU_image(tex->ima, &tex->iuser, false), &trgb); - } - else { - if (tex->type == TEX_ENVMAP) - GPU_link(mat, "mtex_cube_map", texco, GPU_cube_map(tex->ima, &tex->iuser, false), &tin, &trgb); - else if (tex->type == TEX_IMAGE) - GPU_link(mat, "mtex_image", texco, GPU_image(tex->ima, &tex->iuser, false), &tin, &trgb); - } - rgbnor = TEX_RGB; - if (tex->type == TEX_IMAGE || tex->type == TEX_ENVMAP) - if (GPU_material_do_color_management(mat)) - GPU_link(mat, "srgb_to_linearrgb", trgb, &trgb); - /* texture output */ - if ((rgbnor & TEX_RGB) && (mtex->texflag & MTEX_RGBTOINT)) { - GPU_link(mat, "mtex_rgbtoint", trgb, &tin); - rgbnor -= TEX_RGB; - } - if (mtex->texflag & MTEX_NEGATIVE) { - if (rgbnor & TEX_RGB) - GPU_link(mat, "mtex_rgb_invert", trgb, &trgb); - else - GPU_link(mat, "mtex_value_invert", tin, &tin); - } - if (mtex->texflag & MTEX_STENCIL) { - if (rgbnor & TEX_RGB) - GPU_link(mat, "mtex_rgb_stencil", stencil, trgb, &stencil, &trgb); - else - GPU_link(mat, "mtex_value_stencil", stencil, tin, &stencil, &tin); - } - else { - if (rgbnor & TEX_RGB) - GPU_link(mat, "mtex_alpha_multiply_value", trgb, stencil, &trgb); - else - GPU_link(mat, "math_multiply", stencil, tin, &tin); - } - /* color mapping */ - if (mtex->mapto & (WOMAP_HORIZ + WOMAP_ZENUP + WOMAP_ZENDOWN)) { - if ((rgbnor & TEX_RGB) == 0) - GPU_link(mat, "set_rgb", GPU_uniform(&mtex->r), &trgb); - else - GPU_link(mat, "mtex_alpha_from_col", trgb, &tin); - GPU_link(mat, "set_rgb", trgb, &tcol); - if (mtex->mapto & WOMAP_HORIZ) { - texture_rgb_blend(mat, tcol, *hor, tin, GPU_uniform(&mtex->colfac), mtex->blendtype, hor); - } - if (mtex->mapto & (WOMAP_ZENUP + WOMAP_ZENDOWN)) { - GPU_link(mat, "set_value_zero", &zenfac); - if (wo->skytype & WO_SKYREAL) { - if (mtex->mapto & WOMAP_ZENUP) { - if (mtex->mapto & WOMAP_ZENDOWN) { - GPU_link(mat, "world_zen_mapping", shi->view, GPU_uniform(&mtex->zenupfac), - GPU_uniform(&mtex->zendownfac), &zenfac); - } - else { - GPU_link(mat, "world_zen_mapping", shi->view, GPU_uniform(&mtex->zenupfac), - GPU_uniform(&zero), &zenfac); - } - } - else if (mtex->mapto & WOMAP_ZENDOWN) { - GPU_link(mat, "world_zen_mapping", shi->view, GPU_uniform(&zero), - GPU_uniform(&mtex->zendownfac), &zenfac); - } - } - else { - if (mtex->mapto & WOMAP_ZENUP) - GPU_link(mat, "set_value", GPU_uniform(&mtex->zenupfac), &zenfac); - else if (mtex->mapto & WOMAP_ZENDOWN) - GPU_link(mat, "set_value", GPU_uniform(&mtex->zendownfac), &zenfac); - } - texture_rgb_blend(mat, tcol, *zen, tin, zenfac, mtex->blendtype, zen); - } - } - if (mtex->mapto & WOMAP_BLEND && wo->skytype & WO_SKYBLEND) { - if (rgbnor & TEX_RGB) - GPU_link(mat, "mtex_rgbtoint", trgb, &tin); - texture_value_blend(mat, GPU_uniform(&mtex->def_var), *blend, tin, GPU_uniform(&mtex->blendfac), mtex->blendtype, blend); - } - } - } -} - -static void gpu_material_old_world(struct GPUMaterial *mat, struct World *wo) -{ - GPUShadeInput shi; - GPUShadeResult shr; - GPUNodeLink *hor, *zen, *ray, *blend; - - shi.gpumat = mat; - - for (int i = 0; i < MAX_MTEX; i++) { - if (wo->mtex[i] && wo->mtex[i]->tex) { - wo->skytype |= WO_SKYTEX; - break; - } - } - if ((wo->skytype & (WO_SKYBLEND + WO_SKYTEX)) == 0) { - GPU_link(mat, "set_rgb", GPU_dynamic_uniform(&wo->horr, GPU_DYNAMIC_HORIZON_COLOR, NULL), &shr.combined); - } - else { - GPU_link(mat, "set_rgb_zero", &shi.rgb); - GPU_link(mat, "background_transform_to_world", GPU_builtin(GPU_VIEW_POSITION), &ray); - if (wo->skytype & WO_SKYPAPER) - GPU_link(mat, "world_paper_view", GPU_builtin(GPU_VIEW_POSITION), &shi.view); - else - GPU_link(mat, "shade_view", ray, &shi.view); - if (wo->skytype & WO_SKYBLEND) { - if (wo->skytype & WO_SKYPAPER) { - if (wo->skytype & WO_SKYREAL) - GPU_link(mat, "world_blend_paper_real", GPU_builtin(GPU_VIEW_POSITION), &blend); - else - GPU_link(mat, "world_blend_paper", GPU_builtin(GPU_VIEW_POSITION), &blend); - } - else { - if (wo->skytype & WO_SKYREAL) - GPU_link(mat, "world_blend_real", ray, &blend); - else - GPU_link(mat, "world_blend", ray, &blend); - } - } - else { - GPU_link(mat, "set_value_zero", &blend); - } - GPU_link(mat, "set_rgb", GPU_dynamic_uniform(&wo->horr, GPU_DYNAMIC_HORIZON_COLOR, NULL), &hor); - GPU_link(mat, "set_rgb", GPU_dynamic_uniform(&wo->zenr, GPU_DYNAMIC_ZENITH_COLOR, NULL), &zen); - do_world_tex(&shi, wo, &hor, &zen, &blend); - if (wo->skytype & WO_SKYBLEND) - GPU_link(mat, "node_mix_shader", blend, hor, zen, &shi.rgb); - else - GPU_link(mat, "set_rgb", hor, &shi.rgb); - GPU_link(mat, "set_rgb", shi.rgb, &shr.combined); - } - GPU_material_output_link(mat, shr.combined); -} - -GPUMaterial *GPU_material_world(struct Scene *scene, struct World *wo) -{ - LinkData *link; - GPUMaterial *mat; - - for (link = wo->gpumaterial.first; link; link = link->next) - if (((GPUMaterial *)link->data)->scene == scene) - return link->data; - - /* allocate material */ - mat = GPU_material_construct_begin(NULL); - mat->scene = scene; - mat->type = GPU_MATERIAL_TYPE_WORLD; - - /* create nodes */ - if (BKE_scene_use_new_shading_nodes(scene) && wo->nodetree && wo->use_nodes) { - ntreeGPUMaterialNodes(wo->nodetree, mat, NODE_NEW_SHADING); - } - else { - gpu_material_old_world(mat, wo); - } - - if (GPU_material_do_color_management(mat)) - if (mat->outlink) - GPU_link(mat, "linearrgb_to_srgb", mat->outlink, &mat->outlink); - - gpu_material_construct_end(mat, wo->id.name); - - /* note that even if building the shader fails in some way, we still keep - * it to avoid trying to compile again and again, and simple do not use - * the actual shader on drawing */ - - link = MEM_callocN(sizeof(LinkData), "GPUMaterialLink"); - link->data = mat; - BLI_addtail(&wo->gpumaterial, link); - - return mat; -} - GPUMaterial *GPU_material_from_nodetree_find( ListBase *gpumaterials, const void *engine_type, int options) { @@ -2502,15 +598,12 @@ GPUMaterial *GPU_material_from_nodetree_find( } /** - * TODO: This is supposed to replace GPU_material_from_blender/_world in the future - * * \note Caller must use #GPU_material_from_nodetree_find to re-use existing materials, * This is enforced since constructing other arguments to this function may be expensive * so only do this when they are needed. */ GPUMaterial *GPU_material_from_nodetree( - Scene *scene, struct bNodeTree *ntree, ListBase *gpumaterials, const void *engine_type, int options, - const char *vert_code, const char *geom_code, const char *frag_lib, const char *defines, bool deferred) + Scene *scene, struct bNodeTree *ntree, ListBase *gpumaterials, const void *engine_type, int options) { LinkData *link; bool has_volume_output, has_surface_output; @@ -2534,10 +627,7 @@ GPUMaterial *GPU_material_from_nodetree( mat->domain |= GPU_DOMAIN_VOLUME; } - if (!deferred) { - GPU_material_generate_pass(mat, vert_code, geom_code, frag_lib, defines); - } - else if (mat->outlink) { + if (mat->outlink) { /* Prune the unused nodes and extract attribs before compiling so the * generated VBOs are ready to accept the future shader. */ GPU_nodes_prune(&mat->nodes, mat->outlink); @@ -2556,7 +646,6 @@ GPUMaterial *GPU_material_from_nodetree( return mat; } -/* Calls this function if /a mat was created with deferred compilation. */ void GPU_material_generate_pass( GPUMaterial *mat, const char *vert_code, const char *geom_code, const char *frag_lib, const char *defines) { @@ -2571,74 +660,8 @@ void GPU_material_generate_pass( } } -GPUMaterial *GPU_material_from_blender(Scene *scene, Material *ma, bool use_opensubdiv) -{ - GPUMaterial *mat; - GPUNodeLink *outlink; - LinkData *link; - - for (link = ma->gpumaterial.first; link; link = link->next) { - GPUMaterial *current_material = (GPUMaterial *)link->data; - if (current_material->scene == scene && - current_material->is_opensubdiv == use_opensubdiv) - { - return current_material; - } - } - - /* allocate material */ - mat = GPU_material_construct_begin(ma); - mat->scene = scene; - mat->type = GPU_MATERIAL_TYPE_MESH; - mat->is_opensubdiv = use_opensubdiv; - - /* render pipeline option */ - bool new_shading_nodes = BKE_scene_use_new_shading_nodes(scene); - if (!new_shading_nodes && (ma->mode & MA_TRANSP)) - GPU_material_enable_alpha(mat); - else if (new_shading_nodes && ma->alpha < 1.0f) - GPU_material_enable_alpha(mat); - - if (ma->nodetree && ma->use_nodes) { - /* create nodes */ - if (new_shading_nodes) - ntreeGPUMaterialNodes(ma->nodetree, mat, NODE_NEW_SHADING); - else - ntreeGPUMaterialNodes(ma->nodetree, mat, NODE_OLD_SHADING); - } - else { - if (new_shading_nodes) { - /* create simple diffuse material instead of nodes */ - outlink = gpu_material_diffuse_bsdf(mat, ma); - } - else { - /* create blender material */ - outlink = GPU_blender_material(mat, ma); - } - - GPU_material_output_link(mat, outlink); - } - - if (GPU_material_do_color_management(mat)) - if (mat->outlink) - GPU_link(mat, "linearrgb_to_srgb", mat->outlink, &mat->outlink); - - gpu_material_construct_end(mat, ma->id.name); - - /* note that even if building the shader fails in some way, we still keep - * it to avoid trying to compile again and again, and simple do not use - * the actual shader on drawing */ - - link = MEM_callocN(sizeof(LinkData), "GPUMaterialLink"); - link->data = mat; - BLI_addtail(&ma->gpumaterial, link); - - return mat; -} - void GPU_materials_free(void) { - Object *ob; Material *ma; World *wo; extern Material defmaterial; @@ -2650,307 +673,4 @@ void GPU_materials_free(void) GPU_material_free(&wo->gpumaterial); GPU_material_free(&defmaterial.gpumaterial); - - for (ob = G.main->object.first; ob; ob = ob->id.next) - GPU_lamp_free(ob); -} - -/* Lamps and shadow buffers */ - -GPUNodeLink *GPU_lamp_get_data( - GPUMaterial *mat, GPULamp *lamp, - GPUNodeLink **r_col, GPUNodeLink **r_lv, GPUNodeLink **r_dist, GPUNodeLink **r_shadow, GPUNodeLink **r_energy) -{ - GPUNodeLink *visifac; - - *r_col = GPU_dynamic_uniform(lamp->dyncol, GPU_DYNAMIC_LAMP_DYNCOL, lamp->ob); - *r_energy = GPU_dynamic_uniform(&lamp->dynenergy, GPU_DYNAMIC_LAMP_DYNENERGY, lamp->ob); - visifac = lamp_get_visibility(mat, lamp, r_lv, r_dist); - - shade_light_textures(mat, lamp, r_col); - - if (GPU_lamp_has_shadow_buffer(lamp)) { - GPUNodeLink *vn, *inp; - - GPU_link(mat, "shade_norm", GPU_builtin(GPU_VIEW_NORMAL), &vn); - GPU_link(mat, "shade_inp", vn, *r_lv, &inp); - mat->dynproperty |= DYN_LAMP_PERSMAT; - - if (lamp->la->shadowmap_type == LA_SHADMAP_VARIANCE) { - GPU_link(mat, "shadows_only_vsm", - GPU_builtin(GPU_VIEW_POSITION), - GPU_dynamic_texture(lamp->tex, GPU_DYNAMIC_SAMPLER_2DSHADOW, lamp->ob), - GPU_dynamic_uniform((float *)lamp->dynpersmat, GPU_DYNAMIC_LAMP_DYNPERSMAT, lamp->ob), - GPU_uniform(&lamp->bias), GPU_uniform(&lamp->la->bleedbias), - GPU_uniform(lamp->shadow_color), inp, r_shadow); - } - else { - GPU_link(mat, "shadows_only", - GPU_builtin(GPU_VIEW_POSITION), - GPU_dynamic_texture(lamp->tex, GPU_DYNAMIC_SAMPLER_2DSHADOW, lamp->ob), - GPU_dynamic_uniform((float *)lamp->dynpersmat, GPU_DYNAMIC_LAMP_DYNPERSMAT, lamp->ob), - GPU_uniform(&lamp->bias), GPU_uniform(lamp->shadow_color), inp, r_shadow); - } - } - else { - GPU_link(mat, "set_rgb_one", r_shadow); - } - - /* ensure shadow buffer and lamp textures will be updated */ - add_user_list(&mat->lamps, lamp); - - return visifac; -} - -/* export the GLSL shader */ - -GPUShaderExport *GPU_shader_export(struct Scene *scene, struct Material *ma) -{ - static struct { - GPUBuiltin gputype; - GPUDynamicType dynamictype; - GPUDataType datatype; - } builtins[] = { - { GPU_VIEW_MATRIX, GPU_DYNAMIC_OBJECT_VIEWMAT, GPU_DATA_16F }, - { GPU_INVERSE_VIEW_MATRIX, GPU_DYNAMIC_OBJECT_VIEWIMAT, GPU_DATA_16F }, - { GPU_OBJECT_MATRIX, GPU_DYNAMIC_OBJECT_MAT, GPU_DATA_16F }, - { GPU_INVERSE_OBJECT_MATRIX, GPU_DYNAMIC_OBJECT_IMAT, GPU_DATA_16F }, - { GPU_LOC_TO_VIEW_MATRIX, GPU_DYNAMIC_OBJECT_LOCTOVIEWMAT, GPU_DATA_16F }, - { GPU_INVERSE_LOC_TO_VIEW_MATRIX, GPU_DYNAMIC_OBJECT_LOCTOVIEWIMAT, GPU_DATA_16F }, - { GPU_OBCOLOR, GPU_DYNAMIC_OBJECT_COLOR, GPU_DATA_4F }, - { GPU_AUTO_BUMPSCALE, GPU_DYNAMIC_OBJECT_AUTOBUMPSCALE, GPU_DATA_1F }, - { 0 } - }; - - GPUShaderExport *shader = NULL; - GPUInput *input; - int liblen, fraglen; - - /* TODO(sergey): How to determine whether we need OSD or not here? */ - GPUMaterial *mat = GPU_material_from_blender(scene, ma, false); - GPUPass *pass = (mat) ? mat->pass : NULL; - - if (pass && pass->fragmentcode && pass->vertexcode) { - shader = MEM_callocN(sizeof(GPUShaderExport), "GPUShaderExport"); - - for (input = mat->inputs.first; input; input = input->next) { - GPUInputUniform *uniform = MEM_callocN(sizeof(GPUInputUniform), "GPUInputUniform"); - - if (input->ima) { - /* image sampler uniform */ - uniform->type = GPU_DYNAMIC_SAMPLER_2DIMAGE; - uniform->datatype = GPU_DATA_1I; - uniform->image = input->ima; - uniform->texnumber = input->texid; - BLI_strncpy(uniform->varname, input->shadername, sizeof(uniform->varname)); - } - else if (input->tex) { - /* generated buffer */ - uniform->texnumber = input->texid; - uniform->datatype = GPU_DATA_1I; - BLI_strncpy(uniform->varname, input->shadername, sizeof(uniform->varname)); - - switch (input->textype) { - case GPU_SHADOW2D: - uniform->type = GPU_DYNAMIC_SAMPLER_2DSHADOW; - uniform->lamp = input->dynamicdata; - break; - case GPU_TEX2D: - if (GPU_texture_opengl_bindcode(input->tex)) { - uniform->type = GPU_DYNAMIC_SAMPLER_2DBUFFER; - glBindTexture(GL_TEXTURE_2D, GPU_texture_opengl_bindcode(input->tex)); - uniform->texsize = GPU_texture_width(input->tex) * GPU_texture_height(input->tex); - uniform->texpixels = MEM_mallocN(uniform->texsize * 4, "RGBApixels"); - glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, uniform->texpixels); - glBindTexture(GL_TEXTURE_2D, 0); - } - break; - - case GPU_NONE: - case GPU_TEX3D: - case GPU_TEXCUBE: - case GPU_FLOAT: - case GPU_VEC2: - case GPU_VEC3: - case GPU_VEC4: - case GPU_MAT3: - case GPU_MAT4: - case GPU_CLOSURE: - case GPU_ATTRIB: - break; - } - } - else { - uniform->type = input->dynamictype; - BLI_strncpy(uniform->varname, input->shadername, sizeof(uniform->varname)); - switch (input->type) { - case GPU_FLOAT: - uniform->datatype = GPU_DATA_1F; - break; - case GPU_VEC2: - uniform->datatype = GPU_DATA_2F; - break; - case GPU_VEC3: - uniform->datatype = GPU_DATA_3F; - break; - case GPU_VEC4: - uniform->datatype = GPU_DATA_4F; - break; - case GPU_MAT3: - uniform->datatype = GPU_DATA_9F; - break; - case GPU_MAT4: - uniform->datatype = GPU_DATA_16F; - break; - - case GPU_NONE: - case GPU_CLOSURE: - case GPU_TEX2D: - case GPU_TEX3D: - case GPU_TEXCUBE: - case GPU_SHADOW2D: - case GPU_ATTRIB: - break; - } - - if (GPU_DYNAMIC_GROUP_FROM_TYPE(uniform->type) == GPU_DYNAMIC_GROUP_LAMP) - uniform->lamp = input->dynamicdata; - - if (GPU_DYNAMIC_GROUP_FROM_TYPE(uniform->type) == GPU_DYNAMIC_GROUP_MAT) - uniform->material = input->dynamicdata; - } - - if (uniform->type != GPU_DYNAMIC_NONE) - BLI_addtail(&shader->uniforms, uniform); - else - MEM_freeN(uniform); - } - - /* process builtin uniform */ - for (int i = 0; builtins[i].gputype; i++) { - if (mat->builtins & builtins[i].gputype) { - GPUInputUniform *uniform = MEM_callocN(sizeof(GPUInputUniform), "GPUInputUniform"); - uniform->type = builtins[i].dynamictype; - uniform->datatype = builtins[i].datatype; - BLI_strncpy(uniform->varname, GPU_builtin_name(builtins[i].gputype), sizeof(uniform->varname)); - BLI_addtail(&shader->uniforms, uniform); - } - } - - /* now link fragment shader with library shader */ - /* TBD: remove the function that are not used in the main function */ - liblen = (pass->libcode) ? strlen(pass->libcode) : 0; - fraglen = strlen(pass->fragmentcode); - shader->fragment = (char *)MEM_mallocN(liblen + fraglen + 1, "GPUFragShader"); - if (pass->libcode) - memcpy(shader->fragment, pass->libcode, liblen); - memcpy(&shader->fragment[liblen], pass->fragmentcode, fraglen); - shader->fragment[liblen + fraglen] = 0; - - // export the attribute - for (int i = 0; i < mat->attribs.totlayer; i++) { - GPUInputAttribute *attribute = MEM_callocN(sizeof(GPUInputAttribute), "GPUInputAttribute"); - attribute->type = mat->attribs.layer[i].type; - attribute->number = mat->attribs.layer[i].glindex; - BLI_snprintf(attribute->varname, sizeof(attribute->varname), "att%d", mat->attribs.layer[i].attribid); - - switch (attribute->type) { - case CD_TANGENT: - attribute->datatype = GPU_DATA_4F; - break; - case CD_MTFACE: - attribute->datatype = GPU_DATA_2F; - attribute->name = mat->attribs.layer[i].name; - break; - case CD_MCOL: - attribute->datatype = GPU_DATA_4UB; - attribute->name = mat->attribs.layer[i].name; - break; - case CD_ORCO: - attribute->datatype = GPU_DATA_3F; - break; - } - - if (attribute->datatype != GPU_DATA_NONE) - BLI_addtail(&shader->attributes, attribute); - else - MEM_freeN(attribute); - } - - /* export the vertex shader */ - shader->vertex = BLI_strdup(pass->vertexcode); - } - - return shader; -} - -void GPU_free_shader_export(GPUShaderExport *shader) -{ - if (shader == NULL) - return; - - for (GPUInputUniform *uniform = shader->uniforms.first; uniform; uniform = uniform->next) - if (uniform->texpixels) - MEM_freeN(uniform->texpixels); - - BLI_freelistN(&shader->uniforms); - BLI_freelistN(&shader->attributes); - - if (shader->vertex) - MEM_freeN(shader->vertex); - if (shader->fragment) - MEM_freeN(shader->fragment); - - MEM_freeN(shader); } - -#ifdef WITH_OPENSUBDIV -void GPU_material_update_fvar_offset(GPUMaterial *gpu_material, - DerivedMesh *dm) -{ - GPUPass *pass = gpu_material->pass; - GPUShader *shader = (pass != NULL ? pass->shader : NULL); - ListBase *inputs = (pass != NULL ? &gpu_material->inputs : NULL); - GPUInput *input; - - if (shader == NULL) { - return; - } - - GPU_shader_bind(shader); - - for (input = inputs->first; - input != NULL; - input = input->next) - { - if (input->source == GPU_SOURCE_ATTRIB && - input->attribtype == CD_MTFACE) - { - char name[64]; - /* TODO(sergey): This will work for until names are - * consistent, we'll need to solve this somehow in the future. - */ - int layer_index; - int location; - - if (input->attribname[0] != '\0') { - layer_index = CustomData_get_named_layer(&dm->loopData, - CD_MLOOPUV, - input->attribname); - } - else { - layer_index = CustomData_get_active_layer(&dm->loopData, - CD_MLOOPUV); - } - - BLI_snprintf(name, sizeof(name), - "fvar%d_offset", - input->attribid); - location = GPU_shader_get_uniform(shader, name); - GPU_shader_uniform_int(shader, location, layer_index); - } - } - - GPU_shader_unbind(); -} -#endif diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader.c index 319305fc02b..f88b00dfb93 100644 --- a/source/blender/gpu/intern/gpu_shader.c +++ b/source/blender/gpu/intern/gpu_shader.c @@ -213,8 +213,7 @@ static void gpu_shader_standard_extensions(char defines[MAX_EXT_DEFINE_LENGTH]) } static void gpu_shader_standard_defines(char defines[MAX_DEFINE_LENGTH], - bool use_opensubdiv, - bool use_new_shading) + bool use_opensubdiv) { /* some useful defines to detect GPU type */ if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_ANY, GPU_DRIVER_ANY)) { @@ -253,10 +252,6 @@ static void gpu_shader_standard_defines(char defines[MAX_DEFINE_LENGTH], UNUSED_VARS(use_opensubdiv); #endif - if (use_new_shading) { - strcat(defines, "#define USE_NEW_SHADING\n"); - } - return; } @@ -364,8 +359,7 @@ GPUShader *GPU_shader_create_ex(const char *vertexcode, } gpu_shader_standard_defines(standard_defines, - use_opensubdiv, - (flags & GPU_SHADER_FLAGS_NEW_SHADING) != 0); + use_opensubdiv); gpu_shader_standard_extensions(standard_extensions); if (vertexcode) { diff --git a/source/blender/gpu/shaders/gpu_shader_geometry.glsl b/source/blender/gpu/shaders/gpu_shader_geometry.glsl index 7586050b258..705b79cbf56 100644 --- a/source/blender/gpu/shaders/gpu_shader_geometry.glsl +++ b/source/blender/gpu/shaders/gpu_shader_geometry.glsl @@ -32,17 +32,12 @@ uniform int osd_fvar_count; tessCoord.t); \ } -#ifdef USE_NEW_SHADING # define INTERP_FACE_VARYING_ATT_2(result, fvarOffset, tessCoord) \ { \ vec2 tmp; \ INTERP_FACE_VARYING_2(tmp, fvarOffset, tessCoord); \ result = vec3(tmp, 0); \ } -#else -# define INTERP_FACE_VARYING_ATT_2(result, fvarOffset, tessCoord) \ - INTERP_FACE_VARYING_2(result, fvarOffset, tessCoord) -#endif uniform samplerBuffer FVarDataBuffer; uniform isamplerBuffer FVarDataOffsetBuffer; diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl index d3bc1f0ef8e..5eac8ca8f51 100644 --- a/source/blender/gpu/shaders/gpu_shader_material.glsl +++ b/source/blender/gpu/shaders/gpu_shader_material.glsl @@ -41,11 +41,7 @@ Closure nodetree_exec(void); /* Prototype */ float convert_rgba_to_float(vec4 color) { -#ifdef USE_NEW_SHADING return dot(color.rgb, vec3(0.2126, 0.7152, 0.0722)); -#else - return (color.r + color.g + color.b) * 0.333333; -#endif } float exp_blender(float f) @@ -866,11 +862,7 @@ void valtorgb(float fac, sampler2D colormap, out vec4 outcol, out float outalpha void rgbtobw(vec4 color, out float outval) { -#ifdef USE_NEW_SHADING vec3 factors = vec3(0.2126, 0.7152, 0.0722); -#else - vec3 factors = vec3(0.35, 0.45, 0.2); /* keep these factors in sync with texture.h:RGBTOBW */ -#endif outval = dot(color.rgb, factors); } diff --git a/source/blender/gpu/shaders/gpu_shader_vertex.glsl b/source/blender/gpu/shaders/gpu_shader_vertex.glsl index 4ebd10d514f..2a6c137e195 100644 --- a/source/blender/gpu/shaders/gpu_shader_vertex.glsl +++ b/source/blender/gpu/shaders/gpu_shader_vertex.glsl @@ -47,11 +47,7 @@ void srgb_to_linearrgb(vec4 col_from, out vec4 col_to) bool is_srgb(int info) { -#ifdef USE_NEW_SHADING return (info == 1)? true: false; -#else - return false; -#endif } void set_var_from_attr(float attr, int info, out float var) diff --git a/source/blender/gpu/shaders/gpu_shader_vertex_world.glsl b/source/blender/gpu/shaders/gpu_shader_vertex_world.glsl index 89a2f391a12..af2e4ba19a2 100644 --- a/source/blender/gpu/shaders/gpu_shader_vertex_world.glsl +++ b/source/blender/gpu/shaders/gpu_shader_vertex_world.glsl @@ -29,11 +29,7 @@ void srgb_to_linearrgb(vec4 col_from, out vec4 col_to) bool is_srgb(int info) { -#ifdef USE_NEW_SHADING return (info == 1)? true: false; -#else - return false; -#endif } void set_var_from_attr(float attr, int info, out float var) diff --git a/source/blender/makesdna/DNA_dynamicpaint_types.h b/source/blender/makesdna/DNA_dynamicpaint_types.h index 17553e98817..ecdcb2398ac 100644 --- a/source/blender/makesdna/DNA_dynamicpaint_types.h +++ b/source/blender/makesdna/DNA_dynamicpaint_types.h @@ -177,7 +177,7 @@ typedef struct DynamicPaintCanvasSettings { /* flags */ enum { MOD_DPAINT_PART_RAD = 1 << 0, /* use particle radius */ - MOD_DPAINT_USE_MATERIAL = 1 << 1, /* use object material */ + //MOD_DPAINT_USE_MATERIAL = 1 << 1, /* DNA_DEPRECATED */ MOD_DPAINT_ABS_ALPHA = 1 << 2, /* don't increase alpha unless paint alpha is higher than existing */ MOD_DPAINT_ERASE = 1 << 3, /* removes paint */ @@ -231,7 +231,6 @@ typedef struct DynamicPaintBrushSettings { struct DynamicPaintModifierData *pmd; /* for fast RNA access */ struct DerivedMesh *dm; struct ParticleSystem *psys; - struct Material *mat; int flags; int collision; diff --git a/source/blender/makesdna/DNA_lamp_types.h b/source/blender/makesdna/DNA_lamp_types.h index 92703fa2d3b..68453e5f189 100644 --- a/source/blender/makesdna/DNA_lamp_types.h +++ b/source/blender/makesdna/DNA_lamp_types.h @@ -67,42 +67,17 @@ typedef struct Lamp { short pad2; float clipsta, clipend; - float bias, soft, compressthresh, bleedbias, bleedexp; + float bias, soft, bleedbias, bleedexp; short bufsize, samp, buffers, filtertype; char bufflag, buftype; - short ray_samp, ray_sampy, ray_sampz; - short ray_samp_type; short area_shape; float area_size, area_sizey, area_sizez; - float adapt_thresh; - short ray_samp_method; - short shadowmap_type; /* texact is for buttons */ short texact, shadhalostep; - /* sun/sky */ - short sun_effect_type; - short skyblendtype; - float horizon_brightness; - float spread; - float sun_brightness; - float sun_size; - float backscattered_light; - float sun_intensity; - float atm_turbidity; - float atm_inscattering_factor; - float atm_extinction_factor; - float atm_distance_factor; - float skyblendfac; - float sky_exposure; - float shadow_frustum_size; /* BGE Only */ - short sky_colorspace; - char pad4[2]; - struct Ipo *ipo DNA_DEPRECATED; /* old animation system, deprecated for 2.5 */ - struct MTex *mtex[18]; /* MAX_MTEX */ short pr_texture, use_nodes; char pad6[4]; @@ -139,37 +114,28 @@ typedef struct Lamp { /* mode */ #define LA_SHAD_BUF (1 << 0) -#define LA_HALO (1 << 1) -#define LA_LAYER (1 << 2) -#define LA_QUAD (1 << 3) /* no longer used */ -#define LA_NEG (1 << 4) -#define LA_ONLYSHADOW (1 << 5) -#define LA_SPHERE (1 << 6) +/* #define LA_HALO (1 << 1) */ /* not used anymore */ +/* #define LA_LAYER (1 << 2) */ /* not used anymore */ +/* #define LA_QUAD (1 << 3) */ /* not used anymore */ +/* #define LA_NEG (1 << 4) */ /* not used anymore */ +/* #define LA_ONLYSHADOW(1 << 5) */ /* not used anymore */ +/* #define LA_SPHERE (1 << 6) */ /* not used anymore */ #define LA_SQUARE (1 << 7) -#define LA_TEXTURE (1 << 8) -#define LA_OSATEX (1 << 9) +/* #define LA_TEXTURE (1 << 8) */ /* not used anymore */ +/* #define LA_OSATEX (1 << 9) */ /* not used anymore */ /* #define LA_DEEP_SHADOW (1 << 10) */ /* not used anywhere */ -#define LA_NO_DIFF (1 << 11) -#define LA_NO_SPEC (1 << 12) +/* #define LA_NO_DIFF (1 << 11) */ /* not used anywhere */ +/* #define LA_NO_SPEC (1 << 12) */ /* not used anywhere */ #define LA_SHAD_RAY (1 << 13) /* yafray: lamp shadowbuffer flag, softlight */ /* Since it is used with LOCAL lamp, can't use LA_SHAD */ -/* #define LA_YF_SOFT (1 << 14) */ /* no longer used */ -#define LA_LAYER_SHADOW (1 << 15) -#define LA_SHAD_TEX (1 << 16) +/* #define LA_YF_SOFT (1 << 14) */ /* not used anymore */ +/* #define LA_LAYER_SHADOW (1 << 15) */ /* not used anymore */ +/* #define LA_SHAD_TEX (1 << 16) */ /* not used anymore */ #define LA_SHOW_CONE (1 << 17) -#define LA_SHOW_SHADOW_BOX (1 << 18) +/* #define LA_SHOW_SHADOW_BOX (1 << 18) */ #define LA_SHAD_CONTACT (1 << 19) -/* layer_shadow */ -#define LA_LAYER_SHADOW_BOTH 0 -#define LA_LAYER_SHADOW_CAST 1 -#define LA_LAYER_SHADOW_RECEIVE 2 - -/* sun effect type*/ -#define LA_SUN_EFFECT_SKY 1 -#define LA_SUN_EFFECT_AP 2 - /* falloff_type */ #define LA_FALLOFF_CONSTANT 0 #define LA_FALLOFF_INVLINEAR 1 @@ -178,47 +144,11 @@ typedef struct Lamp { #define LA_FALLOFF_SLIDERS 4 #define LA_FALLOFF_INVCOEFFICIENTS 5 - -/* buftype, no flag */ -#define LA_SHADBUF_REGULAR 0 -#define LA_SHADBUF_IRREGULAR 1 -#define LA_SHADBUF_HALFWAY 2 -#define LA_SHADBUF_DEEP 3 - -/* bufflag, auto clipping */ -#define LA_SHADBUF_AUTO_START 1 -#define LA_SHADBUF_AUTO_END 2 - -/* filtertype */ -#define LA_SHADBUF_BOX 0 -#define LA_SHADBUF_TENT 1 -#define LA_SHADBUF_GAUSS 2 - /* area shape */ #define LA_AREA_SQUARE 0 #define LA_AREA_RECT 1 #define LA_AREA_CUBE 2 #define LA_AREA_BOX 3 -/* ray_samp_method */ -#define LA_SAMP_CONSTANT 0 -#define LA_SAMP_HALTON 1 -#define LA_SAMP_HAMMERSLEY 2 - - -/* ray_samp_type */ -// #define LA_SAMP_ROUND 1 // UNUSED -#define LA_SAMP_UMBRA 2 -#define LA_SAMP_DITHER 4 -#define LA_SAMP_JITTER 8 - -/* mapto */ -#define LAMAP_COL 1 -#define LAMAP_SHAD 2 - -/* shadowmap_type */ -#define LA_SHADMAP_SIMPLE 0 -#define LA_SHADMAP_VARIANCE 1 - #endif /* __DNA_LAMP_TYPES_H__ */ diff --git a/source/blender/makesdna/DNA_material_types.h b/source/blender/makesdna/DNA_material_types.h index b6f74c7e6f7..564e6aee3fc 100644 --- a/source/blender/makesdna/DNA_material_types.h +++ b/source/blender/makesdna/DNA_material_types.h @@ -40,45 +40,17 @@ #define MAX_MTEX 18 #endif -struct MTex; struct Image; -struct ColorBand; -struct Group; struct bNodeTree; struct AnimData; struct Ipo; /* WATCH IT: change type? also make changes in ipo.h */ -typedef struct VolumeSettings { - float density; - float emission; - float scattering; - float reflection; - - float emission_col[3]; - float transmission_col[3]; - float reflection_col[3]; - - float density_scale; - float depth_cutoff; - float asymmetry; - - short stepsize_type; - short shadeflag; - short shade_type; - short precache_resolution; - - float stepsize; - float ms_diff; - float ms_intensity; - float ms_spread; -} VolumeSettings; - typedef struct TexPaintSlot { struct Image *ima; /* image to be painted on */ char *uvname; /* customdata index for uv layer, MAX_NAME*/ - int index; /* index for mtex slot in material for blender internal */ + int valid; /* do we have a valid image and UV map */ int pad; } TexPaintSlot; @@ -96,127 +68,49 @@ typedef struct Material { ID id; struct AnimData *adt; /* animation data (must be immediately after id for utilities to use it) */ - short material_type, flag; - /* note, keep this below synced with render_types.h */ + short flag, pad1[7]; + + /* Colors from Blender Internal that we are still using. */ float r, g, b; float specr, specg, specb; - float mirr, mirg, mirb; - float ambr, ambb, ambg; - float amb, emit, ang, spectra, ray_mirror; - float alpha, ref, spec, zoffs, add; - float translucency; - /* end synced with render_types.h */ - - struct VolumeSettings vol; - - float fresnel_mir, fresnel_mir_i; - float fresnel_tra, fresnel_tra_i; - float filter; /* filter added, for raytrace transparency and transmissivity */ - float tx_limit, tx_falloff; - short ray_depth, ray_depth_tra; - short har; - char seed1, seed2; - - float gloss_mir, gloss_tra; - short samp_gloss_mir, samp_gloss_tra; - float adapt_thresh_mir, adapt_thresh_tra; - float aniso_gloss_mir; - float dist_mir; - short fadeto_mir; - short shade_flag; /* like Cubic interpolation */ - - int mode, mode_l; /* mode_l is the or-ed result of all layer modes */ - int mode2, mode2_l; /* additional mode flags */ - short flarec, starc, linec, ringc; - float hasize, flaresize, subsize, flareboost; - float strand_sta, strand_end, strand_ease, strand_surfnor; - float strand_min, strand_widthfade; - char strand_uvname[64]; /* MAX_CUSTOMDATA_LAYER_NAME */ - - float sbias; /* shadow bias to prevent terminator prob */ - float lbias; /* factor to multiply lampbias with (0.0 = no mult) */ - float shad_alpha; /* in use for irregular shadowbuffer */ - int septex; - - /* for buttons and render*/ - char rgbsel, texact, pr_type, use_nodes; - short pr_lamp, pr_texture, ml_flag; /* ml_flag is for disable base material */ - - /* mapping */ - char mapflag, pad; - - /* shaders */ - short diff_shader, spec_shader; - float roughness, refrac; - /* XXX param[4] needs review and improvement (shader system as whole anyway) - * This is nasty reused variable for different goals and not easy to RNAify nicely. -jesterKing */ - float param[4]; /* size, smooth, size, smooth, for toonshader, 0 (fac) and 1 (fresnel) also for fresnel shader */ - float rms; - float darkness; - - /* runtime - OR'd from 'mtex' */ - short texco, mapto; - - /* ramp colors */ - struct ColorBand *ramp_col; - struct ColorBand *ramp_spec; - char rampin_col, rampin_spec; - char rampblend_col, rampblend_spec; - short ramp_show, pad3; - float rampfac_col, rampfac_spec; - - struct MTex *mtex[18]; /* MAX_MTEX */ - struct bNodeTree *nodetree; - struct Ipo *ipo DNA_DEPRECATED; /* old animation system, deprecated for 2.5 */ - struct Group *group; /* light group */ - struct PreviewImage *preview; + float alpha, ray_mirror, spec, gloss_mir; - /* dynamic properties */ - float friction, fh, reflect; - float fhdist, xyfrict; - short dynamode, pad2; + /* Ror buttons and render. */ + char pr_type, use_nodes; + short pr_lamp, pr_texture; - /* subsurface scattering */ - float sss_radius[3], sss_col[3]; - float sss_error, sss_scale, sss_ior; - float sss_colfac, sss_texfac; - float sss_front, sss_back; - short sss_flag, sss_preset; + /* Index for render passes. */ + short index; - int mapto_textured; /* render-time cache to optimize texture lookups */ - short shadowonly_flag; /* "shadowsonly" type */ - short index; /* custom index for render passes */ + struct bNodeTree *nodetree; + struct Ipo *ipo DNA_DEPRECATED; /* old animation system, deprecated for 2.5 */ + struct PreviewImage *preview; - /* Freestyle line settings */ + /* Freestyle line settings. */ float line_col[4]; short line_priority; short vcol_alpha; - /* texture painting */ + /* Texture painting slots. */ short paint_active_slot; short paint_clone_slot; short tot_slots; - short pad4[3]; - - /* multiple tangent (Normal Map node) */ - char nmap_tangent_names[9][64]; /* [MAX_MTFACE+1][MAX_NAME]; +1 for empty name */ - int nmap_tangent_names_count, pad5; + short pad2[3]; - /* Transparency */ + /* Transparency. */ float alpha_threshold; float refract_depth; char blend_method; char blend_shadow; char blend_flag; - char pad6[5]; + char pad3[5]; - /* image to use for image/uv space, also bake target - * (not to be used shading/rendering pipeline, this is editor featyure only!). */ - struct Image *edit_image; + /* Cached slots for texture painting, must be refreshed in + * refresh_texpaint_image_cache before using. */ + struct TexPaintSlot *texpaintslot; - struct TexPaintSlot *texpaintslot; /* cached slot for painting. Make sure to recalculate before use - * with refresh_texpaint_image_cache */ - ListBase gpumaterial; /* runtime */ + /* Runtime cache for GLSL materials. */ + ListBase gpumaterial; } Material; /* **************** MATERIAL ********************* */ @@ -227,12 +121,6 @@ typedef struct Material { * -1 because for active material we store the index + 1 */ #define MAXMAT (32767-1) -/* material_type */ -#define MA_TYPE_SURFACE 0 -#define MA_TYPE_HALO 1 -#define MA_TYPE_VOLUME 2 -#define MA_TYPE_WIRE 3 - /* flag */ /* for render */ #define MA_IS_USED 1 @@ -244,101 +132,7 @@ typedef struct Material { */ #define MA_DS_SHOW_TEXS 4 -/* mode (is int) */ -#define MA_TRACEBLE 1 -#define MA_SHADOW 2 -#define MA_SHLESS 4 -#define MA_WIRE 8 /* deprecated */ -#define MA_VERTEXCOL 16 -#define MA_HALO_SOFT 16 -#define MA_HALO 32 /* deprecated */ -#define MA_ZTRANSP 64 -#define MA_VERTEXCOLP 128 -#define MA_ZINV 256 -#define MA_HALO_RINGS 256 -#define MA_ENV 512 -#define MA_HALO_LINES 512 -#define MA_ONLYSHADOW 1024 -#define MA_HALO_XALPHA 1024 -#define MA_STAR 0x800 -// #define MA_FACETEXTURE 0x800 /* deprecated */ -#define MA_HALOTEX 0x1000 -#define MA_HALOPUNO 0x2000 -#define MA_ONLYCAST 0x2000 -#define MA_NOMIST 0x4000 -#define MA_HALO_SHADE 0x4000 -#define MA_HALO_FLARE 0x8000 -#define MA_TRANSP 0x10000 -#define MA_RAYTRANSP 0x20000 -#define MA_RAYMIRROR 0x40000 -#define MA_SHADOW_TRA 0x80000 -#define MA_RAMP_COL 0x100000 -#define MA_RAMP_SPEC 0x200000 -#define MA_RAYBIAS 0x400000 -#define MA_FULL_OSA 0x800000 -#define MA_TANGENT_STR 0x1000000 -#define MA_SHADBUF 0x2000000 - /* note; we drop MA_TANGENT_STR later to become tangent_u */ -#define MA_TANGENT_V 0x4000000 -/* qdn: a bit clumsy this, tangents needed for normal maps separated from shading */ -#define MA_NORMAP_TANG 0x8000000 -#define MA_GROUP_NOLAY 0x10000000 -// #define MA_FACETEXTURE_ALPHA 0x20000000 /* deprecated */ -#define MA_STR_B_UNITS 0x40000000 -#define MA_STR_SURFDIFF 0x80000000 - -#define MA_MODE_MASK 0x6fffffff /* all valid mode bits */ -#define MA_MODE_PIPELINE (MA_TRANSP | MA_ZTRANSP | MA_RAYTRANSP \ - | MA_TRACEBLE | MA_FULL_OSA | MA_ENV | MA_ZINV \ - | MA_ONLYCAST | MA_SHADBUF) - -/* mode2 (is int) */ -#define MA_CASTSHADOW (1 << 0) -#define MA_MODE2_PIPELINE (MA_CASTSHADOW) -#define MA_TANGENT_CONCRETE (1 << 1) - -/* mapflag */ -#define MA_MAPFLAG_UVPROJECT (1 << 0) - -/* ray mirror fadeout */ -#define MA_RAYMIR_FADETOSKY 0 -#define MA_RAYMIR_FADETOMAT 1 - -/* shadowonly_flag */ -#define MA_SO_OLD 0 -#define MA_SO_SHADOW 1 -#define MA_SO_SHADED 2 - -/* shade_flag */ -#define MA_CUBIC 1 -#define MA_OBCOLOR 2 -#define MA_APPROX_OCCLUSION 4 -#define MA_GROUP_LOCAL 8 - -/* diff_shader */ -#define MA_DIFF_LAMBERT 0 -#define MA_DIFF_ORENNAYAR 1 -#define MA_DIFF_TOON 2 -#define MA_DIFF_MINNAERT 3 -#define MA_DIFF_FRESNEL 4 - -/* spec_shader */ -#define MA_SPEC_COOKTORR 0 -#define MA_SPEC_PHONG 1 -#define MA_SPEC_BLINN 2 -#define MA_SPEC_TOON 3 -#define MA_SPEC_WARDISO 4 - -/* dynamode */ -// #define MA_DRAW_DYNABUTS 1 /* deprecated */ -#define MA_FH_NOR 2 - /* ramps */ -#define MA_RAMP_IN_SHADER 0 -#define MA_RAMP_IN_ENERGY 1 -#define MA_RAMP_IN_NOR 2 -#define MA_RAMP_IN_RESULT 3 - #define MA_RAMP_BLEND 0 #define MA_RAMP_ADD 1 #define MA_RAMP_MULT 2 @@ -380,38 +174,7 @@ typedef struct Material { /* mapto */ #define MAP_COL 1 -#define MAP_NORM 2 -#define MAP_COLSPEC 4 -#define MAP_COLMIR 8 -#define MAP_VARS (0xFFF0) -#define MAP_REF 16 -#define MAP_SPEC 32 -#define MAP_EMIT 64 #define MAP_ALPHA 128 -#define MAP_HAR 256 -#define MAP_RAYMIRR 512 -#define MAP_TRANSLU 1024 -#define MAP_AMB 2048 -#define MAP_DISPLACE 4096 -#define MAP_WARP 8192 -// #define MAP_LAYER 16384 /* unused */ - -/* volume mapto - reuse definitions for now - a bit naughty! */ -#define MAP_DENSITY 128 -#define MAP_EMISSION 64 -#define MAP_EMISSION_COL 1 -#define MAP_SCATTERING 16 -#define MAP_TRANSMISSION_COL 8 -#define MAP_REFLECTION_COL 4 -#define MAP_REFLECTION 32 - - -/* mapto for halo */ -//#define MAP_HA_COL 1 -//#define MAP_HA_ALPHA 128 -//#define MAP_HA_HAR 256 -//#define MAP_HA_SIZE 2 -//#define MAP_HA_ADD 64 /* pmapto */ /* init */ @@ -444,25 +207,6 @@ typedef struct Material { #define MA_HAIR 10 #define MA_ATMOS 11 -/* sss_flag */ -#define MA_DIFF_SSS 1 - -/* vol_stepsize_type */ -#define MA_VOL_STEP_RANDOMIZED 0 -#define MA_VOL_STEP_CONSTANT 1 -#define MA_VOL_STEP_ADAPTIVE 2 - -/* vol_shadeflag */ -#define MA_VOL_RECV_EXT_SHADOW 1 -#define MA_VOL_PRECACHESHADING 8 - -/* vol_shading_type */ -#define MA_VOL_SHADE_SHADELESS 0 -#define MA_VOL_SHADE_SHADOWED 2 -#define MA_VOL_SHADE_SHADED 1 -#define MA_VOL_SHADE_MULTIPLE 3 -#define MA_VOL_SHADE_SHADEDPLUSMULTIPLE 4 - /* blend_method */ enum { MA_BM_SOLID, diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 64e6ce3d522..a7f9acb8a42 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -419,7 +419,6 @@ typedef struct UVProjectModifierData { /* the objects which do the projecting */ struct Object *projectors[10]; /* MOD_UVPROJECT_MAXPROJECTORS */ - struct Image *image; /* the image to project */ int pad2; int num_projectors; float aspectx, aspecty; diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index 63eecebf44a..b5a3752072b 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -653,11 +653,6 @@ typedef struct NodeTwoFloats { float x, y; } NodeTwoFloats; -typedef struct NodeGeometry { - char uvname[64]; /* MAX_CUSTOMDATA_LAYER_NAME */ - char colname[64]; -} NodeGeometry; - typedef struct NodeVertexCol { char name[64]; } NodeVertexCol; diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index bb17b10b299..0f9cbc06fa8 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -442,8 +442,6 @@ enum { OB_MATERIAL = 4, OB_TEXTURE = 5, OB_RENDER = 6, - - OB_PAINT = 100, /* temporary used in draw code */ }; /* dtx: flags (short) */ diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 18502158e4b..8a09cced24b 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -571,29 +571,14 @@ typedef struct RenderData { float framelen, blurfac; - /** For UR edge rendering: give the edges this color */ - float edgeR, edgeG, edgeB; - - - /* standalone player */ // XXX deprecated since 2.5 - short fullscreen DNA_DEPRECATED, xplay DNA_DEPRECATED, yplay DNA_DEPRECATED; - short freqplay DNA_DEPRECATED; - /* standalone player */ // XXX deprecated since 2.5 - short depth DNA_DEPRECATED, attrib DNA_DEPRECATED; - - int frame_step; /* frames to jump during render/playback */ short stereomode DNA_DEPRECATED; /* standalone player stereo settings */ // XXX deprecated since 2.5 short dimensionspreset; /* for the dimensions presets menu */ - short filtertype; /* filter is box, tent, gauss, mitch, etc */ - short size; /* size in % */ - short maximsize DNA_DEPRECATED; /* max in Kb */ - short pad6; /* from buttons: */ @@ -607,15 +592,6 @@ typedef struct RenderData { int ysch; /** - * The number of part to use in the x direction - */ - short xparts DNA_DEPRECATED; - /** - * The number of part to use in the y direction - */ - short yparts DNA_DEPRECATED; - - /** * render tile dimensions */ int tilex, tiley; @@ -640,22 +616,6 @@ typedef struct RenderData { int mode; /** - * Flags for raytrace settings. Use bit-masking to access the settings. - */ - int raytrace_options; - - /** - * Raytrace acceleration structure - */ - short raytrace_structure; - - short pad1; - - /* octree resolution */ - short ocres; - short pad4; - - /** * What to do with the sky/background. Picks sky/premul/key * blending for the background */ @@ -666,7 +626,7 @@ typedef struct RenderData { */ short osa; - short frs_sec, edgeint; + short frs_sec, pad[7]; /* safety, border and display rect */ @@ -676,9 +636,7 @@ typedef struct RenderData { /* information on different layers to be rendered */ ListBase layers DNA_DEPRECATED; /* Converted to Scene->view_layers. */ short actlay DNA_DEPRECATED; /* Converted to Scene->active_layer. */ - - /* number of mblur samples */ - short mblur_samples; + short pad1; /** * Adjustment factors for the aspect ratio in the x direction, was a short in 2.45 @@ -695,18 +653,13 @@ typedef struct RenderData { /* color management settings - color profiles, gamma correction, etc */ int color_mgt_flag; - /** post-production settings. deprecated, but here for upwards compat (initialized to 1) */ - float postgamma, posthue, postsat; - /* Dither noise intensity */ float dither_intensity; /* Bake Render options */ - short bake_osa, bake_filter, bake_mode, bake_flag; - short bake_normal_space, bake_quad_split; - float bake_maxdist, bake_biasdist; - short bake_samples, bake_pad; - float bake_user_scale, bake_pad1; + short bake_mode, bake_flag; + short bake_filter, bake_samples; + float bake_biasdist, bake_user_scale; /* path to render output */ char pic[1024]; /* 1024 = FILE_MAX */ @@ -729,21 +682,11 @@ typedef struct RenderData { char pad5[5]; /* render simplify */ - int simplify_flag; short simplify_subsurf; short simplify_subsurf_render; - short simplify_shadowsamples, pad9; + short pad9, pad10; float simplify_particles; float simplify_particles_render; - float simplify_aosss; - - /* cineon */ - short cineonwhite DNA_DEPRECATED, cineonblack DNA_DEPRECATED; /*deprecated*/ - float cineongamma DNA_DEPRECATED; /*deprecated*/ - - /* jpeg2000 */ - short jp2_preset DNA_DEPRECATED, jp2_depth DNA_DEPRECATED; /*deprecated*/ - int rpad3; /* Freestyle line thickness options */ int line_thickness_mode; @@ -751,6 +694,7 @@ typedef struct RenderData { /* render engine */ char engine[32]; + int pad2; /* Cycles baking */ struct BakeData bake; @@ -1540,25 +1484,25 @@ typedef struct Scene { /* RenderData.mode */ #define R_OSA 0x0001 -#define R_SHADOW 0x0002 -#define R_GAMMA 0x0004 -#define R_ORTHO 0x0008 -#define R_ENVMAP 0x0010 -#define R_EDGE 0x0020 -#define R_FIELDS 0x0040 -#define R_FIELDSTILL 0x0080 +/* #define R_SHADOW 0x0002 */ +/* #define R_GAMMA 0x0004 */ +#define R_ORTHO 0x0008 +/* #define R_ENVMAP 0x0010 */ +/* #define R_EDGE 0x0020 */ +/* #define R_FIELDS 0x0040 */ +/*#define R_FIELDSTILL 0x0080 */ /*#define R_RADIO 0x0100 */ /* deprecated */ #define R_BORDER 0x0200 -#define R_PANORAMA 0x0400 /* deprecated as scene option, still used in renderer */ +#define R_PANORAMA 0x0400 #define R_CROP 0x0800 /* Disable camera switching: runtime (DURIAN_CAMERA_SWITCH) */ #define R_NO_CAMERA_SWITCH 0x1000 -#define R_ODDFIELD 0x2000 +/* #define R_ODDFIELD 0x2000 */ #define R_MBLUR 0x4000 /* unified was here */ -#define R_RAYTRACE 0x10000 +/* #define R_RAYTRACE 0x10000 */ /* R_GAUSS is obsolete, but used to retrieve setting from old files */ -#define R_GAUSS 0x20000 +/* #define R_GAUSS 0x20000 */ /* fbuf obsolete... */ /*#define R_FBUF 0x40000*/ /* threads obsolete... is there for old files, now use for autodetect threads */ @@ -1566,14 +1510,14 @@ typedef struct Scene { /* Use the same flag for autothreads */ #define R_FIXED_THREADS 0x80000 -#define R_SPEED 0x100000 -#define R_SSS 0x200000 +/* #define R_SPEED 0x100000 */ +/* #define R_SSS 0x200000 */ #define R_NO_OVERWRITE 0x400000 /* skip existing files */ #define R_TOUCH 0x800000 /* touch files before rendering */ #define R_SIMPLIFY 0x1000000 #define R_EDGE_FRS 0x2000000 /* R_EDGE reserved for Freestyle */ #define R_PERSISTENT_DATA 0x4000000 /* keep data around for re-render */ -#define R_USE_WS_SHADING 0x8000000 /* use world space interpretation of lighting data */ +/* #define R_USE_WS_SHADING 0x8000000 */ /* use world space interpretation of lighting data */ /* RenderData.seq_flag */ enum { @@ -1590,7 +1534,7 @@ enum { #define R_OUTPUT_NONE 3 /*#define R_OUTPUT_FORKED 4*/ -/* RenderData.filtertype */ +/* RenderData.filtertype (used for nodes) */ #define R_FILTER_BOX 0 #define R_FILTER_TENT 1 #define R_FILTER_QUAD 2 @@ -1598,19 +1542,7 @@ enum { #define R_FILTER_CATROM 4 #define R_FILTER_GAUSS 5 #define R_FILTER_MITCH 6 -#define R_FILTER_FAST_GAUSS 7 /* note, this is only used for nodes at the moment */ - -/* RenderData.raytrace_structure */ -#define R_RAYSTRUCTURE_AUTO 0 -#define R_RAYSTRUCTURE_OCTREE 1 -#define R_RAYSTRUCTURE_BLIBVH 2 /* removed */ -#define R_RAYSTRUCTURE_VBVH 3 -#define R_RAYSTRUCTURE_SIMD_SVBVH 4 /* needs SIMD */ -#define R_RAYSTRUCTURE_SIMD_QBVH 5 /* needs SIMD */ - -/* RenderData.raytrace_options */ -#define R_RAYTRACE_USE_LOCAL_COORDS 0x0001 -#define R_RAYTRACE_USE_INSTANCES 0x0002 +#define R_FILTER_FAST_GAUSS 7 /* RenderData.scemode (int now) */ #define R_DOSEQ 0x0001 @@ -1622,12 +1554,12 @@ enum { #define R_MATNODE_PREVIEW 0x0020 #define R_DOCOMP 0x0040 #define R_COMP_CROP 0x0080 -#define R_FREE_IMAGE 0x0100 +/* #define R_FREE_IMAGE 0x0100 */ #define R_SINGLE_LAYER 0x0200 #define R_EXR_TILE_FILE 0x0400 /* #define R_COMP_FREE 0x0800 */ #define R_NO_IMAGE_LOAD 0x1000 -#define R_NO_TEX 0x2000 +/* #define R_NO_TEX 0x2000 */ #define R_NO_FRAME_UPDATE 0x4000 #define R_FULL_SAMPLE 0x8000 /* #define R_DEPRECATED 0x10000 */ @@ -1690,12 +1622,12 @@ enum { /* bake_mode: same as RE_BAKE_xxx defines */ /* RenderData.bake_flag */ #define R_BAKE_CLEAR 1 -#define R_BAKE_OSA 2 +/* #define R_BAKE_OSA 2 */ /* deprecated */ #define R_BAKE_TO_ACTIVE 4 -#define R_BAKE_NORMALIZE 8 +/* #define R_BAKE_NORMALIZE 8 */ /* deprecated */ #define R_BAKE_MULTIRES 16 #define R_BAKE_LORES_MESH 32 -#define R_BAKE_VCOL 64 +/* #define R_BAKE_VCOL 64 */ /* deprecated */ #define R_BAKE_USERSCALE 128 #define R_BAKE_CAGE 256 #define R_BAKE_SPLIT_MAT 512 @@ -1707,9 +1639,6 @@ enum { #define R_BAKE_SPACE_OBJECT 2 #define R_BAKE_SPACE_TANGENT 3 -/* RenderData.simplify_flag */ -#define R_SIMPLE_NO_TRIANGULATE 1 - /* RenderData.line_thickness_mode */ #define R_LINE_THICKNESS_ABSOLUTE 1 #define R_LINE_THICKNESS_RELATIVE 2 @@ -1717,7 +1646,6 @@ enum { /* sequencer seq_prev_type seq_rend_type */ /* RenderData.engine (scene.c) */ -extern const char *RE_engine_id_BLENDER_RENDER; extern const char *RE_engine_id_BLENDER_CLAY; extern const char *RE_engine_id_BLENDER_EEVEE; extern const char *RE_engine_id_BLENDER_WORKBENCH; diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index d763c7ca4f9..904ffc959d8 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -124,11 +124,9 @@ typedef struct SpaceButs { short mainb, mainbo, mainbuser; /* context tabs */ short re_align, align; /* align for panels */ short preview; /* preview is signal to refresh */ - /* texture context selector (material, lamp, particles, world, other) */ - short texture_context, texture_context_prev; char flag; char collection_context; - char pad[6]; + char pad[2]; void *path; /* runtime */ int pathflag, dataicon; /* runtime */ @@ -200,16 +198,6 @@ typedef enum eSpaceButtons_Flag { SB_SHADING_CONTEXT = (1 << 4), } eSpaceButtons_Flag; -/* sbuts->texture_context */ -typedef enum eSpaceButtons_Texture_Context { - SB_TEXC_MATERIAL = 0, - SB_TEXC_WORLD = 1, - SB_TEXC_LAMP = 2, - SB_TEXC_PARTICLES = 3, - SB_TEXC_OTHER = 4, - SB_TEXC_LINESTYLE = 5, -} eSpaceButtons_Texture_Context; - /* sbuts->collection_context */ typedef enum eSpaceButtons_Collection_Context { SB_COLLECTION_CTX_VIEW_LAYER = 0, @@ -1217,14 +1205,14 @@ typedef enum eSpaceNode_Flag { SNODE_AUTO_RENDER = (1 << 5), // SNODE_SHOW_HIGHLIGHT = (1 << 6), DNA_DEPRECATED // SNODE_USE_HIDDEN_PREVIEW = (1 << 10), DNA_DEPRECATED December2013 - SNODE_NEW_SHADERS = (1 << 11), +// SNODE_NEW_SHADERS = (1 << 11), DNA_DEPRECATED SNODE_PIN = (1 << 12), SNODE_SKIP_INSOFFSET = (1 << 13), /* automatically offset following nodes in a chain on insertion */ } eSpaceNode_Flag; /* snode->texfrom */ typedef enum eSpaceNode_TexFrom { - SNODE_TEX_OBJECT = 0, + /* SNODE_TEX_OBJECT = 0, */ SNODE_TEX_WORLD = 1, SNODE_TEX_BRUSH = 2, SNODE_TEX_LINESTYLE = 3, diff --git a/source/blender/makesdna/DNA_texture_types.h b/source/blender/makesdna/DNA_texture_types.h index 0eb54a9b5b3..f5267f20d2c 100644 --- a/source/blender/makesdna/DNA_texture_types.h +++ b/source/blender/makesdna/DNA_texture_types.h @@ -45,13 +45,11 @@ extern "C" { struct AnimData; struct Ipo; struct ColorBand; -struct EnvMap; struct Object; struct Tex; struct Image; struct PreviewImage; struct ImBuf; -struct Ocean; struct CurveMapping; typedef struct MTex { @@ -121,21 +119,6 @@ typedef struct ColorBand { CBData data[32]; } ColorBand; -typedef struct EnvMap { - struct Object *object; - struct Image *ima; /* type ENV_LOAD */ - struct ImBuf *cube[6]; /* these images are dynamic, not part of the main struct */ - float imat[4][4]; - float obimat[3][3]; - short type, stype; - float clipsta, clipend; - float viewscale; /* viewscale is for planar envmaps to zoom in or out */ - unsigned int notlay; - short cuberes, depth; - int ok, lastframe; - short recalc, lastsize; -} EnvMap; - typedef struct PointDensity { short flag; @@ -172,38 +155,6 @@ typedef struct PointDensity { struct CurveMapping *falloff_curve; /* falloff density curve */ } PointDensity; -typedef struct VoxelData { - int resol[3]; - int interp_type; - short file_format; - short flag; - short extend; - short smoked_type; - short hair_type; - short data_type; - int _pad; - - struct Object *object; /* for rendering smoke sims */ - float int_multiplier; - int still_frame; - char source_path[1024]; /* 1024 = FILE_MAX */ - - /* temporary data */ - float *dataset; - int cachedframe; - int ok; - -} VoxelData; - -typedef struct OceanTex { - struct Object *object; - char oceanmod[64]; - - int output; - int pad; - -} OceanTex; - typedef struct Tex { ID id; struct AnimData *adt; /* animation data (must be immediately after id for utilities to use it) */ @@ -254,11 +205,7 @@ typedef struct Tex { struct Ipo *ipo DNA_DEPRECATED; /* old animation system, deprecated for 2.5 */ struct Image *ima; struct ColorBand *coba; - struct EnvMap *env; struct PreviewImage *preview; - struct PointDensity *pd; - struct VoxelData *vd; - struct OceanTex *ot; char use_nodes; char pad[7]; @@ -316,13 +263,13 @@ typedef struct ColorMapping { #define TEX_NOISE 7 #define TEX_IMAGE 8 //#define TEX_PLUGIN 9 /* Deprecated */ -#define TEX_ENVMAP 10 +//#define TEX_ENVMAP 10 /* Deprecated */ #define TEX_MUSGRAVE 11 #define TEX_VORONOI 12 #define TEX_DISTNOISE 13 -#define TEX_POINTDENSITY 14 -#define TEX_VOXELDATA 15 -#define TEX_OCEAN 16 +//#define TEX_POINTDENSITY 14 /* Deprecated */ +//#define TEX_VOXELDATA 15 /* Deprecated */ +//#define TEX_OCEAN 16 /* Deprecated */ /* musgrave stype */ #define TEX_MFRACTAL 0 @@ -549,22 +496,6 @@ enum { COLBAND_HUE_CCW = 3, }; -/* **************** EnvMap ********************* */ - -/* type */ -#define ENV_CUBE 0 -#define ENV_PLANE 1 -#define ENV_SPHERE 2 - -/* stype */ -#define ENV_STATIC 0 -#define ENV_ANIM 1 -#define ENV_LOAD 2 - -/* ok */ -#define ENV_NORMAL 1 -#define ENV_OSA 2 - /* **************** PointDensity ********************* */ /* source */ @@ -592,9 +523,9 @@ enum { /* noise_influence */ #define TEX_PD_NOISE_STATIC 0 -#define TEX_PD_NOISE_VEL 1 -#define TEX_PD_NOISE_AGE 2 -#define TEX_PD_NOISE_TIME 3 +/* #define TEX_PD_NOISE_VEL 1 */ /* Deprecated */ +/* #define TEX_PD_NOISE_AGE 2 */ /* Deprecated */ +/* #define TEX_PD_NOISE_TIME 3 */ /* Deprecated */ /* color_source */ enum { @@ -613,55 +544,6 @@ enum { #define POINT_DATA_LIFE 2 #define POINT_DATA_COLOR 4 -/******************** Voxel Data *****************************/ -/* flag */ -#define TEX_VD_STILL 1 - -/* interpolation */ -#define TEX_VD_NEARESTNEIGHBOR 0 -#define TEX_VD_LINEAR 1 -#define TEX_VD_QUADRATIC 2 -#define TEX_VD_TRICUBIC_CATROM 3 -#define TEX_VD_TRICUBIC_BSPLINE 4 -#define TEX_VD_TRICUBIC_SLOW 5 - -/* file format */ -#define TEX_VD_BLENDERVOXEL 0 -#define TEX_VD_RAW_8BIT 1 -#define TEX_VD_RAW_16BIT 2 -#define TEX_VD_IMAGE_SEQUENCE 3 -#define TEX_VD_SMOKE 4 -#define TEX_VD_HAIR 5 -/* for voxels which use VoxelData->source_path */ -#define TEX_VD_IS_SOURCE_PATH(_format) (ELEM(_format, TEX_VD_BLENDERVOXEL, TEX_VD_RAW_8BIT, TEX_VD_RAW_16BIT)) - -/* smoke data types */ -#define TEX_VD_SMOKEDENSITY 0 -#define TEX_VD_SMOKEHEAT 1 -#define TEX_VD_SMOKEVEL 2 -#define TEX_VD_SMOKEFLAME 3 - -#define TEX_VD_HAIRDENSITY 0 -#define TEX_VD_HAIRVELOCITY 1 -#define TEX_VD_HAIRENERGY 2 -#define TEX_VD_HAIRRESTDENSITY 3 - -/* data_type */ -#define TEX_VD_INTENSITY 0 -#define TEX_VD_RGBA_PREMUL 1 - -/******************** Ocean *****************************/ -/* output */ -#define TEX_OCN_DISPLACEMENT 1 -#define TEX_OCN_FOAM 2 -#define TEX_OCN_JPLUS 3 -#define TEX_OCN_EMINUS 4 -#define TEX_OCN_EPLUS 5 - -/* flag */ -#define TEX_OCN_GENERATE_NORMALS 1 -#define TEX_OCN_XZ 2 - #ifdef __cplusplus } #endif diff --git a/source/blender/makesdna/DNA_world_types.h b/source/blender/makesdna/DNA_world_types.h index f30ffa84b73..ac93033609d 100644 --- a/source/blender/makesdna/DNA_world_types.h +++ b/source/blender/makesdna/DNA_world_types.h @@ -56,8 +56,6 @@ typedef struct World { short texact, mistype; float horr, horg, horb; - float zenr, zeng, zenb; - float ambr, ambg, ambb; /** * Exposure= mult factor. unused now, but maybe back later. Kept in to be upward compat. @@ -67,42 +65,22 @@ typedef struct World { float exposure, exp, range; float linfac, logfac; - short skytype; /** * Some world modes * bit 0: Do mist - * bit 1: Do stars - * bit 2: (reserved) depth of field - * bit 3: (gameengine): Activity culling is enabled. - * bit 4: ambient occlusion - * bit 5: (gameengine) : enable Bullet DBVT tree for view frustum culling */ short mode; // partially moved to scene->gamedata in 2.5 - short pad2[2]; + short pad2[3]; float misi, miststa, mistdist, misthi; - /* unused now: DOF */ - short dofsta, dofend, dofmin, dofmax; - /* ambient occlusion */ - float aodist, aodistfac, aoenergy, aobias; - short aomode, aosamp, aomix, aocolor; - float ao_adapt_thresh, ao_adapt_speed_fac; - float ao_approx_error, ao_approx_correction; - float ao_indirect_energy, ao_env_energy, ao_pad2; - short ao_indirect_bounces, ao_pad; - short ao_samp_method, ao_gather_method, ao_approx_passes; - - /* assorted settings (in the middle of ambient occlusion settings for padding reasons) */ - short flag; - - /* ambient occlusion (contd...) */ - float *aosphere, *aotables; + float aodist, aoenergy; + /* assorted settings */ + short flag, pad3[3]; struct Ipo *ipo DNA_DEPRECATED; /* old animation system, deprecated for 2.5 */ - struct MTex *mtex[18]; /* MAX_MTEX */ short pr_texture, use_nodes, pad; short update_flag; /* XXX temporary flag waiting for depsgraph proper tagging */ @@ -118,33 +96,15 @@ typedef struct World { /* **************** WORLD ********************* */ -/* skytype */ -#define WO_SKYBLEND 1 -#define WO_SKYREAL 2 -#define WO_SKYPAPER 4 -/* while render: */ -#define WO_SKYTEX 8 -#define WO_ZENUP 16 - /* mode */ #define WO_MIST 1 //#define WO_STARS 2 /* deprecated */ /*#define WO_DOF 4*/ //#define WO_ACTIVITY_CULLING 8 /* deprecated */ -#define WO_ENV_LIGHT 16 +//#define WO_ENV_LIGHT 16 //#define WO_DBVT_CULLING 32 /* deprecated */ #define WO_AMB_OCC 64 -#define WO_INDIRECT_LIGHT 128 - -/* aomix */ -enum { - WO_AOADD = 0, -#ifdef DNA_DEPRECATED - WO_AOSUB = 1, /* deprecated */ - WO_AOADDSUB = 2, /* deprecated */ -#endif - WO_AOMUL = 3, -}; +//#define WO_INDIRECT_LIGHT 128 enum { WO_MIST_QUADRATIC = 0, @@ -152,38 +112,6 @@ enum { WO_MIST_INVERSE_QUADRATIC = 2, }; -/* ao_samp_method - methods for sampling the AO hemi */ -#define WO_AOSAMP_CONSTANT 0 -#define WO_AOSAMP_HALTON 1 -#define WO_AOSAMP_HAMMERSLEY 2 - -/* aomode (use distances & random sampling modes) */ -#define WO_AODIST 1 -#define WO_AORNDSMP 2 -#define WO_AOCACHE 4 - -/* aocolor */ -#define WO_AOPLAIN 0 -#define WO_AOSKYCOL 1 -#define WO_AOSKYTEX 2 - -/* ao_gather_method */ -#define WO_AOGATHER_RAYTRACE 0 -#define WO_AOGATHER_APPROX 1 - -/* texco (also in DNA_material_types.h) */ -#define TEXCO_ANGMAP 64 -#define TEXCO_H_SPHEREMAP 256 -#define TEXCO_H_TUBEMAP 1024 -#define TEXCO_EQUIRECTMAP 2048 - -/* mapto */ -#define WOMAP_BLEND 1 -#define WOMAP_HORIZ 2 -#define WOMAP_ZENUP 4 -#define WOMAP_ZENDOWN 8 -// #define WOMAP_MIST 16 /* Deprecated */ - /* flag */ #define WO_DS_EXPAND (1<<0) /* NOTE: this must have the same value as MA_DS_SHOW_TEXS, diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index ec4dca98387..6cc91a7d149 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -234,8 +234,6 @@ extern StructRNA RNA_EffectSequence; extern StructRNA RNA_EffectorWeights; extern StructRNA RNA_EnumProperty; extern StructRNA RNA_EnumPropertyItem; -extern StructRNA RNA_EnvironmentMap; -extern StructRNA RNA_EnvironmentMapTexture; extern StructRNA RNA_Event; extern StructRNA RNA_ExplodeModifier; extern StructRNA RNA_ExpressionController; @@ -382,15 +380,8 @@ extern StructRNA RNA_MarbleTexture; extern StructRNA RNA_MaskModifier; extern StructRNA RNA_MaskSequence; extern StructRNA RNA_Material; -extern StructRNA RNA_MaterialHalo; -extern StructRNA RNA_MaterialPhysics; extern StructRNA RNA_MaterialRaytraceMirror; -extern StructRNA RNA_MaterialRaytraceTransparency; extern StructRNA RNA_MaterialSlot; -extern StructRNA RNA_MaterialStrand; -extern StructRNA RNA_MaterialSubsurfaceScattering; -extern StructRNA RNA_MaterialTextureSlot; -extern StructRNA RNA_MaterialVolume; extern StructRNA RNA_Mask; extern StructRNA RNA_MaskLayer; extern StructRNA RNA_Menu; @@ -484,8 +475,6 @@ extern StructRNA RNA_ParticleSystemModifier; extern StructRNA RNA_ParticleTarget; extern StructRNA RNA_PivotConstraint; extern StructRNA RNA_PointCache; -extern StructRNA RNA_PointDensity; -extern StructRNA RNA_PointDensityTexture; extern StructRNA RNA_PointLamp; extern StructRNA RNA_PointerProperty; extern StructRNA RNA_Pose; @@ -696,8 +685,6 @@ extern StructRNA RNA_VertexGroup; extern StructRNA RNA_VertexGroupElement; extern StructRNA RNA_VertexPaint; extern StructRNA RNA_VoronoiTexture; -extern StructRNA RNA_VoxelData; -extern StructRNA RNA_VoxelDataTexture; extern StructRNA RNA_WarpModifier; extern StructRNA RNA_WaveModifier; extern StructRNA RNA_VertexWeightEditModifier; diff --git a/source/blender/makesrna/intern/rna_color.c b/source/blender/makesrna/intern/rna_color.c index d9b7a58de04..f895cfbbf0c 100644 --- a/source/blender/makesrna/intern/rna_color.c +++ b/source/blender/makesrna/intern/rna_color.c @@ -160,17 +160,6 @@ static char *rna_ColorRamp_path(PointerRNA *ptr) ID *id = ptr->id.data; switch (GS(id->name)) { - case ID_MA: /* material has 2 cases - diffuse and specular */ - { - Material *ma = (Material *)id; - - if (ptr->data == ma->ramp_col) - path = BLI_strdup("diffuse_ramp"); - else if (ptr->data == ma->ramp_spec) - path = BLI_strdup("specular_ramp"); - break; - } - case ID_NT: { bNodeTree *ntree = (bNodeTree *)id; @@ -245,22 +234,6 @@ static char *rna_ColorRampElement_path(PointerRNA *ptr) ID *id = ptr->id.data; switch (GS(id->name)) { - case ID_MA: /* 2 cases for material - diffuse and spec */ - { - Material *ma = (Material *)id; - - /* try diffuse first */ - if (ma->ramp_col) { - RNA_pointer_create(id, &RNA_ColorRamp, ma->ramp_col, &ramp_ptr); - COLRAMP_GETPATH; - } - /* try specular if not diffuse */ - if (!path && ma->ramp_spec) { - RNA_pointer_create(id, &RNA_ColorRamp, ma->ramp_spec, &ramp_ptr); - COLRAMP_GETPATH; - } - break; - } case ID_NT: { bNodeTree *ntree = (bNodeTree *)id; diff --git a/source/blender/makesrna/intern/rna_dynamicpaint.c b/source/blender/makesrna/intern/rna_dynamicpaint.c index 466a01a7271..aeb845ddcf7 100644 --- a/source/blender/makesrna/intern/rna_dynamicpaint.c +++ b/source/blender/makesrna/intern/rna_dynamicpaint.c @@ -825,18 +825,6 @@ static void rna_def_dynamic_paint_brush_settings(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Paint Alpha", "Paint alpha"); RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_DynamicPaint_redoModifier"); - prop = RNA_def_property(srna, "use_material", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_DPAINT_USE_MATERIAL); - RNA_def_property_ui_text(prop, "Use object material", "Use object material to define color and influence"); - RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_DynamicPaint_redoModifier"); - - prop = RNA_def_property(srna, "material", PROP_POINTER, PROP_NONE); - RNA_def_property_pointer_sdna(prop, NULL, "mat"); - RNA_def_property_ui_text(prop, "Material", - "Material to use (if not defined, material linked to the mesh is used)"); - RNA_def_property_flag(prop, PROP_EDITABLE); - RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_DynamicPaint_redoModifier"); - prop = RNA_def_property(srna, "use_absolute_alpha", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_DPAINT_ABS_ALPHA); RNA_def_property_ui_text(prop, "Absolute Alpha", diff --git a/source/blender/makesrna/intern/rna_lamp.c b/source/blender/makesrna/intern/rna_lamp.c index 9e28e31057d..7e437a8a51f 100644 --- a/source/blender/makesrna/intern/rna_lamp.c +++ b/source/blender/makesrna/intern/rna_lamp.c @@ -63,33 +63,6 @@ static void rna_Lamp_buffer_size_set(PointerRNA *ptr, int value) la->bufsize &= (~15); /* round to multiple of 16 */ } -static PointerRNA rna_Lamp_sky_settings_get(PointerRNA *ptr) -{ - return rna_pointer_inherit_refine(ptr, &RNA_LampSkySettings, ptr->id.data); -} - -static void rna_Lamp_mtex_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) -{ - Lamp *la = (Lamp *)ptr->data; - rna_iterator_array_begin(iter, (void *)la->mtex, sizeof(MTex *), MAX_MTEX, 0, NULL); -} - -static PointerRNA rna_Lamp_active_texture_get(PointerRNA *ptr) -{ - Lamp *la = (Lamp *)ptr->data; - Tex *tex; - - tex = give_current_lamp_texture(la); - return rna_pointer_inherit_refine(ptr, &RNA_Texture, tex); -} - -static void rna_Lamp_active_texture_set(PointerRNA *ptr, PointerRNA value) -{ - Lamp *la = (Lamp *)ptr->data; - - set_current_lamp_texture(la, value.data); -} - static int rna_use_shadow_get(PointerRNA *ptr) { Lamp *la = (Lamp *)ptr->data; @@ -147,14 +120,6 @@ static void rna_Lamp_draw_update(Main *UNUSED(bmain), Scene *UNUSED(scene), Poin WM_main_add_notifier(NC_LAMP | ND_LIGHTING_DRAW, la); } -static void rna_Lamp_sky_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) -{ - Lamp *la = ptr->id.data; - - DEG_id_tag_update(&la->id, 0); - WM_main_add_notifier(NC_LAMP | ND_SKY, la); -} - static void rna_Lamp_use_nodes_update(bContext *C, PointerRNA *ptr) { Lamp *la = (Lamp *)ptr->data; @@ -176,167 +141,6 @@ const EnumPropertyItem rna_enum_lamp_type_items[] = { {0, NULL, 0, NULL, NULL} }; -static void rna_def_lamp_mtex(BlenderRNA *brna) -{ - StructRNA *srna; - PropertyRNA *prop; - - static const EnumPropertyItem prop_texture_coordinates_items[] = { - {TEXCO_GLOB, "GLOBAL", 0, "Global", "Use global coordinates for the texture coordinates"}, - {TEXCO_VIEW, "VIEW", 0, "View", "Use view coordinates for the texture coordinates"}, - {TEXCO_OBJECT, "OBJECT", 0, "Object", "Use linked object's coordinates for texture coordinates"}, - {0, NULL, 0, NULL, NULL} - }; - - srna = RNA_def_struct(brna, "LampTextureSlot", "TextureSlot"); - RNA_def_struct_sdna(srna, "MTex"); - RNA_def_struct_ui_text(srna, "Lamp Texture Slot", "Texture slot for textures in a Lamp data-block"); - - prop = RNA_def_property(srna, "texture_coords", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "texco"); - RNA_def_property_enum_items(prop, prop_texture_coordinates_items); - RNA_def_property_ui_text(prop, "Texture Coordinates", ""); - - prop = RNA_def_property(srna, "object", PROP_POINTER, PROP_NONE); - RNA_def_property_pointer_sdna(prop, NULL, "object"); - RNA_def_property_struct_type(prop, "Object"); - RNA_def_property_flag(prop, PROP_EDITABLE); - RNA_def_property_ui_text(prop, "Object", "Object to use for mapping with Object texture coordinates"); - - prop = RNA_def_property(srna, "use_map_color", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mapto", LAMAP_COL); - RNA_def_property_ui_text(prop, "Color", "Let the texture affect the basic color of the lamp"); - RNA_def_property_update(prop, 0, "rna_Lamp_update"); - - prop = RNA_def_property(srna, "use_map_shadow", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mapto", LAMAP_SHAD); - RNA_def_property_ui_text(prop, "Shadow", "Let the texture affect the shadow color of the lamp"); - RNA_def_property_update(prop, 0, "rna_Lamp_update"); - - prop = RNA_def_property(srna, "color_factor", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "colfac"); - RNA_def_property_ui_range(prop, 0, 1, 10, 3); - RNA_def_property_ui_text(prop, "Color Factor", "Amount texture affects color values"); - RNA_def_property_update(prop, 0, "rna_Lamp_update"); - - prop = RNA_def_property(srna, "shadow_factor", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "shadowfac"); - RNA_def_property_ui_range(prop, 0, 1, 10, 3); - RNA_def_property_ui_text(prop, "Shadow Factor", "Amount texture affects shadow"); - RNA_def_property_update(prop, 0, "rna_Lamp_update"); -} - -static void rna_def_lamp_sky_settings(BlenderRNA *brna) -{ - StructRNA *srna; - PropertyRNA *prop; - - static const EnumPropertyItem prop_skycolorspace_items[] = { - {0, "SMPTE", 0, "SMPTE", ""}, - {1, "REC709", 0, "REC709", ""}, - {2, "CIE", 0, "CIE", ""}, - {0, NULL, 0, NULL, NULL} - }; - - srna = RNA_def_struct(brna, "LampSkySettings", NULL); - RNA_def_struct_sdna(srna, "Lamp"); - RNA_def_struct_nested(brna, srna, "SunLamp"); - RNA_def_struct_ui_text(srna, "Lamp Sky Settings", "Sky related settings for a sun lamp"); - - prop = RNA_def_property(srna, "sky_color_space", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "sky_colorspace"); - RNA_def_property_enum_items(prop, prop_skycolorspace_items); - RNA_def_property_ui_text(prop, "Sky Color Space", "Color space to use for internal XYZ->RGB color conversion"); - RNA_def_property_update(prop, 0, "rna_Lamp_sky_update"); - - prop = RNA_def_property(srna, "sky_blend_type", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "skyblendtype"); - RNA_def_property_enum_items(prop, rna_enum_ramp_blend_items); - RNA_def_property_ui_text(prop, "Sky Blend Mode", "Blend mode for combining sun sky with world sky"); - RNA_def_property_update(prop, 0, "rna_Lamp_sky_update"); - - /* Number values */ - - prop = RNA_def_property(srna, "horizon_brightness", PROP_FLOAT, PROP_NONE); - RNA_def_property_range(prop, 0.0f, 20.0f); - RNA_def_property_ui_text(prop, "Horizon Brightness", "Horizon brightness"); - RNA_def_property_update(prop, 0, "rna_Lamp_sky_update"); - - prop = RNA_def_property(srna, "spread", PROP_FLOAT, PROP_NONE); - RNA_def_property_range(prop, 0.0f, 10.0f); - RNA_def_property_ui_text(prop, "Horizon Spread", "Horizon Spread"); - RNA_def_property_update(prop, 0, "rna_Lamp_sky_update"); - - prop = RNA_def_property(srna, "sun_brightness", PROP_FLOAT, PROP_NONE); - RNA_def_property_range(prop, 0.0f, 10.0f); - RNA_def_property_ui_text(prop, "Sun Brightness", "Sun brightness"); - RNA_def_property_update(prop, 0, "rna_Lamp_sky_update"); - - prop = RNA_def_property(srna, "sun_size", PROP_FLOAT, PROP_NONE); - RNA_def_property_range(prop, 0.0f, 10.0f); - RNA_def_property_ui_text(prop, "Sun Size", "Sun size"); - RNA_def_property_update(prop, 0, "rna_Lamp_sky_update"); - - prop = RNA_def_property(srna, "backscattered_light", PROP_FLOAT, PROP_NONE); - RNA_def_property_range(prop, -1.0f, 1.0f); - RNA_def_property_ui_text(prop, "Backscattered Light", "Backscattered light"); - RNA_def_property_update(prop, 0, "rna_Lamp_sky_update"); - - prop = RNA_def_property(srna, "sun_intensity", PROP_FLOAT, PROP_NONE); - RNA_def_property_range(prop, 0.0f, 10.0f); - RNA_def_property_ui_text(prop, "Sun Intensity", "Sun intensity"); - RNA_def_property_update(prop, 0, "rna_Lamp_sky_update"); - - prop = RNA_def_property(srna, "atmosphere_turbidity", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "atm_turbidity"); - RNA_def_property_range(prop, 1.0f, 30.0f); - RNA_def_property_ui_range(prop, 2.0f, 10.0f, 1, 2); - RNA_def_property_ui_text(prop, "Atmosphere Turbidity", "Sky turbidity"); - RNA_def_property_update(prop, 0, "rna_Lamp_sky_update"); - - prop = RNA_def_property(srna, "atmosphere_inscattering", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "atm_inscattering_factor"); - RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_ui_text(prop, "Atmosphere Inscatter", "Scatter contribution factor"); - RNA_def_property_update(prop, 0, "rna_Lamp_sky_update"); - - prop = RNA_def_property(srna, "atmosphere_extinction", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "atm_extinction_factor"); - RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_ui_text(prop, "Atmosphere Extinction", "Extinction scattering contribution factor"); - RNA_def_property_update(prop, 0, "rna_Lamp_sky_update"); - - prop = RNA_def_property(srna, "atmosphere_distance_factor", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "atm_distance_factor"); - RNA_def_property_range(prop, 0.0f, 500.0f); - RNA_def_property_ui_text(prop, "Atmosphere Distance Factor", - "Multiplier to convert blender units to physical distance"); - RNA_def_property_update(prop, 0, "rna_Lamp_sky_update"); - - prop = RNA_def_property(srna, "sky_blend", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "skyblendfac"); - RNA_def_property_range(prop, 0.0f, 2.0f); - RNA_def_property_ui_text(prop, "Sky Blend", "Blend factor with sky"); - RNA_def_property_update(prop, 0, "rna_Lamp_sky_update"); - - prop = RNA_def_property(srna, "sky_exposure", PROP_FLOAT, PROP_NONE); - RNA_def_property_range(prop, 0.0f, 20.0f); - RNA_def_property_ui_text(prop, "Sky Exposure", "Strength of sky shading exponential exposure correction"); - RNA_def_property_update(prop, 0, "rna_Lamp_sky_update"); - - /* boolean */ - - prop = RNA_def_property(srna, "use_sky", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "sun_effect_type", LA_SUN_EFFECT_SKY); - RNA_def_property_ui_text(prop, "Sky", "Apply sun effect on sky"); - RNA_def_property_update(prop, 0, "rna_Lamp_sky_update"); - - prop = RNA_def_property(srna, "use_atmosphere", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "sun_effect_type", LA_SUN_EFFECT_AP); - RNA_def_property_ui_text(prop, "Atmosphere", "Apply sun effect on atmosphere"); - RNA_def_property_update(prop, 0, "rna_Lamp_sky_update"); -} - static void rna_def_lamp(BlenderRNA *brna) { StructRNA *srna; @@ -372,26 +176,6 @@ static void rna_def_lamp(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Color", "Light color"); RNA_def_property_update(prop, 0, "rna_Lamp_draw_update"); - prop = RNA_def_property(srna, "use_own_layer", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mode", LA_LAYER); - RNA_def_property_ui_text(prop, "Layer", "Illuminate objects only on the same layers the lamp is on"); - RNA_def_property_update(prop, 0, "rna_Lamp_update"); - - prop = RNA_def_property(srna, "use_negative", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mode", LA_NEG); - RNA_def_property_ui_text(prop, "Negative", "Cast negative light"); - RNA_def_property_update(prop, 0, "rna_Lamp_update"); - - prop = RNA_def_property(srna, "use_specular", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_negative_sdna(prop, NULL, "mode", LA_NO_SPEC); - RNA_def_property_ui_text(prop, "Specular", "Create specular highlights"); - RNA_def_property_update(prop, 0, "rna_Lamp_update"); - - prop = RNA_def_property(srna, "use_diffuse", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_negative_sdna(prop, NULL, "mode", LA_NO_DIFF); - RNA_def_property_ui_text(prop, "Diffuse", "Do diffuse shading"); - RNA_def_property_update(prop, 0, "rna_Lamp_update"); - /* nodes */ prop = RNA_def_property(srna, "node_tree", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "nodetree"); @@ -406,11 +190,6 @@ static void rna_def_lamp(BlenderRNA *brna) /* common */ rna_def_animdata_common(srna); - - /* textures */ - rna_def_mtex_common(brna, srna, "rna_Lamp_mtex_begin", "rna_Lamp_active_texture_get", - "rna_Lamp_active_texture_set", NULL, "LampTextureSlot", "LampTextureSlots", - "rna_Lamp_draw_update", "rna_Lamp_draw_update"); } static void rna_def_lamp_falloff(StructRNA *srna) @@ -437,11 +216,6 @@ static void rna_def_lamp_falloff(StructRNA *srna) RNA_def_property_ui_text(prop, "Falloff Curve", "Custom Lamp Falloff Curve"); RNA_def_property_update(prop, 0, "rna_Lamp_update"); - prop = RNA_def_property(srna, "use_sphere", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mode", LA_SPHERE); - RNA_def_property_ui_text(prop, "Sphere", "Set light intensity to zero beyond lamp distance"); - RNA_def_property_update(prop, 0, "rna_Lamp_draw_update"); - prop = RNA_def_property(srna, "linear_attenuation", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "att1"); RNA_def_property_range(prop, 0.0f, 1.0f); @@ -476,79 +250,14 @@ static void rna_def_lamp_falloff(StructRNA *srna) RNA_def_property_update(prop, 0, "rna_Lamp_draw_update"); } -static void rna_def_lamp_shadow(StructRNA *srna, int spot, int area, int sun) +static void rna_def_lamp_shadow(StructRNA *srna, int sun) { PropertyRNA *prop; - static const EnumPropertyItem prop_shadow_items[] = { - {0, "NOSHADOW", 0, "No Shadow", ""}, - {LA_SHAD_RAY, "RAY_SHADOW", 0, "Ray Shadow", "Use ray tracing for shadow"}, - {0, NULL, 0, NULL, NULL} - }; - - static const EnumPropertyItem prop_spot_shadow_items[] = { - {0, "NOSHADOW", 0, "No Shadow", ""}, - {LA_SHAD_BUF, "BUFFER_SHADOW", 0, "Buffer Shadow", "Let spotlight produce shadows using shadow buffer"}, - {LA_SHAD_RAY, "RAY_SHADOW", 0, "Ray Shadow", "Use ray tracing for shadow"}, - {0, NULL, 0, NULL, NULL} - }; - - static const EnumPropertyItem prop_ray_sampling_method_items[] = { - {LA_SAMP_HALTON, "ADAPTIVE_QMC", 0, "Adaptive QMC", ""}, - {LA_SAMP_HAMMERSLEY, "CONSTANT_QMC", 0, "Constant QMC", ""}, - {0, NULL, 0, NULL, NULL} - }; - - static const EnumPropertyItem prop_spot_ray_sampling_method_items[] = { - {LA_SAMP_HALTON, "ADAPTIVE_QMC", 0, "Adaptive QMC", ""}, - {LA_SAMP_HAMMERSLEY, "CONSTANT_QMC", 0, "Constant QMC", ""}, - {LA_SAMP_CONSTANT, "CONSTANT_JITTERED", 0, "Constant Jittered", ""}, - {0, NULL, 0, NULL, NULL} - }; - - static const EnumPropertyItem prop_shadbuftype_items[] = { - {LA_SHADBUF_REGULAR, "REGULAR", 0, "Classical", "Classic shadow buffer"}, - {LA_SHADBUF_HALFWAY, "HALFWAY", 0, "Classic-Halfway", - "Regular buffer, averaging the closest and 2nd closest Z value to reducing " - "bias artifacts"}, - {LA_SHADBUF_IRREGULAR, "IRREGULAR", 0, "Irregular", - "Irregular buffer produces sharp shadow always, but it doesn't show up for raytracing"}, - {LA_SHADBUF_DEEP, "DEEP", 0, "Deep", - "Deep shadow buffer supports transparency and better filtering, at the cost of " - "more memory usage and processing time"}, - {0, NULL, 0, NULL, NULL} - }; - - static const EnumPropertyItem prop_shadbuffiltertype_items[] = { - {LA_SHADBUF_BOX, "BOX", 0, "Box", "Apply the Box filter to shadow buffer samples"}, - {LA_SHADBUF_TENT, "TENT", 0, "Tent", "Apply the Tent Filter to shadow buffer samples"}, - {LA_SHADBUF_GAUSS, "GAUSS", 0, "Gauss", "Apply the Gauss filter to shadow buffer samples"}, - {0, NULL, 0, NULL, NULL} - }; - - static const EnumPropertyItem prop_numbuffer_items[] = { - {1, "BUFFERS_1", 0, "1", "Only one buffer rendered"}, - {4, "BUFFERS_4", 0, "4", "Render 4 buffers for better AA, this quadruples memory usage"}, - {9, "BUFFERS_9", 0, "9", "Render 9 buffers for better AA, this uses nine times more memory"}, - {0, NULL, 0, NULL, NULL} - }; - - /* GE only */ - static const EnumPropertyItem prop_ge_shadowbuffer_type_items[] = { - {LA_SHADMAP_SIMPLE, "SIMPLE", 0, "Simple", "Simple shadow maps"}, - {LA_SHADMAP_VARIANCE, "VARIANCE", 0, "Variance", "Variance shadow maps"}, - {0, NULL, 0, NULL, NULL} - }; - prop = RNA_def_property(srna, "use_shadow", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_funcs(prop, "rna_use_shadow_get", "rna_use_shadow_set"); RNA_def_property_update(prop, 0, "rna_Lamp_draw_update"); - prop = RNA_def_property(srna, "shadow_method", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_bitflag_sdna(prop, NULL, "mode"); - RNA_def_property_enum_items(prop, (spot) ? prop_spot_shadow_items : prop_shadow_items); - RNA_def_property_update(prop, 0, "rna_Lamp_draw_update"); - prop = RNA_def_property(srna, "shadow_buffer_size", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "bufsize"); RNA_def_property_range(prop, 128, 10240); @@ -558,19 +267,6 @@ static void rna_def_lamp_shadow(StructRNA *srna, int spot, int area, int sun) RNA_def_property_int_funcs(prop, NULL, "rna_Lamp_buffer_size_set", NULL); RNA_def_property_update(prop, 0, "rna_Lamp_update"); - prop = RNA_def_property(srna, "shadow_filter_type", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "filtertype"); - RNA_def_property_enum_items(prop, prop_shadbuffiltertype_items); - RNA_def_property_ui_text(prop, "Shadow Filter Type", "Type of shadow filter (Buffer Shadows)"); - RNA_def_property_update(prop, 0, "rna_Lamp_update"); - - prop = RNA_def_property(srna, "shadow_sample_buffers", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "buffers"); - RNA_def_property_enum_items(prop, prop_numbuffer_items); - RNA_def_property_ui_text(prop, "Shadow Sample Buffers", - "Number of shadow buffers to render for better AA, this increases memory usage"); - RNA_def_property_update(prop, 0, "rna_Lamp_update"); - prop = RNA_def_property(srna, "shadow_buffer_clip_start", PROP_FLOAT, PROP_DISTANCE); RNA_def_property_float_sdna(prop, NULL, "clipsta"); RNA_def_property_range(prop, 0.0f, 9999.0f); @@ -616,77 +312,12 @@ static void rna_def_lamp_shadow(StructRNA *srna, int spot, int area, int sun) RNA_def_property_ui_text(prop, "Samples", "Number of shadow buffer samples"); RNA_def_property_update(prop, 0, "rna_Lamp_update"); - prop = RNA_def_property(srna, "shadow_buffer_type", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "buftype"); - RNA_def_property_enum_items(prop, prop_shadbuftype_items); - RNA_def_property_ui_text(prop, "Shadow Buffer Type", "Type of shadow buffer"); - RNA_def_property_update(prop, 0, "rna_Lamp_update"); - - prop = RNA_def_property(srna, "ge_shadow_buffer_type", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "shadowmap_type"); - RNA_def_property_enum_items(prop, prop_ge_shadowbuffer_type_items); - RNA_def_property_ui_text(prop, "Shadow Map Type", "The shadow mapping algorithm used"); - RNA_def_property_update(prop, 0, "rna_Lamp_update"); - - - prop = RNA_def_property(srna, "use_auto_clip_start", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "bufflag", LA_SHADBUF_AUTO_START); - RNA_def_property_ui_text(prop, "Autoclip Start", - "Automatic calculation of clipping-start, based on visible vertices"); - RNA_def_property_update(prop, 0, "rna_Lamp_draw_update"); - - prop = RNA_def_property(srna, "use_auto_clip_end", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "bufflag", LA_SHADBUF_AUTO_END); - RNA_def_property_ui_text(prop, "Autoclip End", "Automatic calculation of clipping-end, based on visible vertices"); - RNA_def_property_update(prop, 0, "rna_Lamp_draw_update"); - - prop = RNA_def_property(srna, "compression_threshold", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "compressthresh"); - RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_ui_text(prop, "Compress", "Deep shadow map compression threshold"); - RNA_def_property_update(prop, 0, "rna_Lamp_update"); - prop = RNA_def_property(srna, "shadow_color", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "shdwr"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Shadow Color", "Color of shadows cast by the lamp"); RNA_def_property_update(prop, 0, "rna_Lamp_update"); - prop = RNA_def_property(srna, "use_only_shadow", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mode", LA_ONLYSHADOW); - RNA_def_property_ui_text(prop, "Only Shadow", "Cast shadows only, without illuminating objects"); - RNA_def_property_update(prop, 0, "rna_Lamp_update"); - - prop = RNA_def_property(srna, "shadow_ray_sample_method", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "ray_samp_method"); - RNA_def_property_enum_items(prop, (area) ? prop_spot_ray_sampling_method_items : prop_ray_sampling_method_items); - RNA_def_property_ui_text(prop, "Shadow Ray Sampling Method", - "Method for generating shadow samples: Adaptive QMC is fastest, " - "Constant QMC is less noisy but slower"); - RNA_def_property_update(prop, 0, "rna_Lamp_update"); - - prop = RNA_def_property(srna, (area) ? "shadow_ray_samples_x" : "shadow_ray_samples", PROP_INT, PROP_NONE); - RNA_def_property_int_sdna(prop, NULL, "ray_samp"); - RNA_def_property_range(prop, 1, 64); - RNA_def_property_ui_text(prop, (area) ? "Shadow Ray Samples" : "Shadow Ray Samples X", - "Number of samples taken extra (samples x samples)"); - RNA_def_property_update(prop, 0, "rna_Lamp_update"); - - if (area) { - prop = RNA_def_property(srna, "shadow_ray_samples_y", PROP_INT, PROP_NONE); - RNA_def_property_int_sdna(prop, NULL, "ray_sampy"); - RNA_def_property_range(prop, 1, 64); - RNA_def_property_ui_text(prop, "Shadow Ray Samples Y", - "Number of samples taken extra (samples x samples)"); - RNA_def_property_update(prop, 0, "rna_Lamp_update"); - } - - prop = RNA_def_property(srna, "shadow_adaptive_threshold", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "adapt_thresh"); - RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_ui_text(prop, "Shadow Adaptive Threshold", "Threshold for Adaptive Sampling (Raytraced shadows)"); - RNA_def_property_update(prop, 0, "rna_Lamp_update"); - prop = RNA_def_property(srna, "shadow_soft_size", PROP_FLOAT, PROP_DISTANCE); RNA_def_property_float_sdna(prop, NULL, "area_size"); RNA_def_property_range(prop, 0.0f, FLT_MAX); @@ -694,11 +325,6 @@ static void rna_def_lamp_shadow(StructRNA *srna, int spot, int area, int sun) RNA_def_property_ui_text(prop, "Shadow Soft Size", "Light size for ray shadow sampling (Raytraced shadows)"); RNA_def_property_update(prop, 0, "rna_Lamp_update"); - prop = RNA_def_property(srna, "use_shadow_layer", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mode", LA_LAYER_SHADOW); - RNA_def_property_ui_text(prop, "Shadow Layer", "Objects on the same layers only cast shadows"); - RNA_def_property_update(prop, 0, "rna_Lamp_update"); - /* Eevee */ prop = RNA_def_property(srna, "use_contact_shadow", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "mode", LA_SHAD_CONTACT); @@ -771,7 +397,7 @@ static void rna_def_point_lamp(BlenderRNA *brna) RNA_def_struct_ui_icon(srna, ICON_LAMP_POINT); rna_def_lamp_falloff(srna); - rna_def_lamp_shadow(srna, 0, 0, 0); + rna_def_lamp_shadow(srna, 0); } static void rna_def_area_lamp(BlenderRNA *brna) @@ -790,24 +416,9 @@ static void rna_def_area_lamp(BlenderRNA *brna) RNA_def_struct_ui_text(srna, "Area Lamp", "Directional area lamp"); RNA_def_struct_ui_icon(srna, ICON_LAMP_AREA); - rna_def_lamp_shadow(srna, 0, 1, 0); + rna_def_lamp_shadow(srna, 0); rna_def_lamp_falloff(srna); - prop = RNA_def_property(srna, "use_umbra", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "ray_samp_type", LA_SAMP_UMBRA); - RNA_def_property_ui_text(prop, "Umbra", "Emphasize parts that are fully shadowed (Constant Jittered sampling)"); - RNA_def_property_update(prop, 0, "rna_Lamp_update"); - - prop = RNA_def_property(srna, "use_dither", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "ray_samp_type", LA_SAMP_DITHER); - RNA_def_property_ui_text(prop, "Dither", "Use 2x2 dithering for sampling (Constant Jittered sampling)"); - RNA_def_property_update(prop, 0, "rna_Lamp_update"); - - prop = RNA_def_property(srna, "use_jitter", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "ray_samp_type", LA_SAMP_JITTER); - RNA_def_property_ui_text(prop, "Jitter", "Use noise for sampling (Constant Jittered sampling)"); - RNA_def_property_update(prop, 0, "rna_Lamp_update"); - prop = RNA_def_property(srna, "shape", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "area_shape"); RNA_def_property_enum_items(prop, prop_areashape_items); @@ -828,12 +439,6 @@ static void rna_def_area_lamp(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Size Y", "Size of the area of the area Lamp in the Y direction for Rectangle shapes"); RNA_def_property_update(prop, 0, "rna_Lamp_draw_update"); - - prop = RNA_def_property(srna, "gamma", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "k"); - RNA_def_property_ui_range(prop, 0.001, 2.0, 0.1, 3); - RNA_def_property_ui_text(prop, "Gamma", "Light gamma correction value"); - RNA_def_property_update(prop, 0, "rna_Lamp_draw_update"); } static void rna_def_spot_lamp(BlenderRNA *brna) @@ -847,30 +452,13 @@ static void rna_def_spot_lamp(BlenderRNA *brna) RNA_def_struct_ui_icon(srna, ICON_LAMP_SPOT); rna_def_lamp_falloff(srna); - rna_def_lamp_shadow(srna, 1, 0, 0); + rna_def_lamp_shadow(srna, 0); prop = RNA_def_property(srna, "use_square", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "mode", LA_SQUARE); RNA_def_property_ui_text(prop, "Square", "Cast a square spot light shape"); RNA_def_property_update(prop, 0, "rna_Lamp_draw_update"); - prop = RNA_def_property(srna, "use_halo", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mode", LA_HALO); - RNA_def_property_ui_text(prop, "Halo", "Render spotlight with a volumetric halo"); - RNA_def_property_update(prop, 0, "rna_Lamp_update"); - - prop = RNA_def_property(srna, "halo_intensity", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "haint"); - RNA_def_property_ui_range(prop, 0, 5.0, 0.1, 3); - RNA_def_property_ui_text(prop, "Halo Intensity", "Brightness of the spotlight's halo cone"); - RNA_def_property_update(prop, 0, "rna_Lamp_update"); - - prop = RNA_def_property(srna, "halo_step", PROP_INT, PROP_NONE); - RNA_def_property_int_sdna(prop, NULL, "shadhalostep"); - RNA_def_property_range(prop, 0, 12); - RNA_def_property_ui_text(prop, "Halo Step", "Volumetric halo sampling frequency"); - RNA_def_property_update(prop, 0, "rna_Lamp_update"); - prop = RNA_def_property(srna, "spot_blend", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "spotblend"); RNA_def_property_range(prop, 0.0f, 1.0f); @@ -893,36 +481,13 @@ static void rna_def_spot_lamp(BlenderRNA *brna) static void rna_def_sun_lamp(BlenderRNA *brna) { StructRNA *srna; - PropertyRNA *prop; srna = RNA_def_struct(brna, "SunLamp", "Lamp"); RNA_def_struct_sdna(srna, "Lamp"); RNA_def_struct_ui_text(srna, "Sun Lamp", "Constant direction parallel ray lamp"); RNA_def_struct_ui_icon(srna, ICON_LAMP_SUN); - rna_def_lamp_shadow(srna, 0, 0, 1); - - /* sky */ - prop = RNA_def_property(srna, "sky", PROP_POINTER, PROP_NONE); - RNA_def_property_flag(prop, PROP_NEVER_NULL); - RNA_def_property_struct_type(prop, "LampSkySettings"); - RNA_def_property_pointer_funcs(prop, "rna_Lamp_sky_settings_get", NULL, NULL, NULL); - RNA_def_property_ui_text(prop, "Sky Settings", "Sky related settings for sun lamps"); - - rna_def_lamp_sky_settings(brna); - - /* BGE Only */ - prop = RNA_def_property(srna, "shadow_frustum_size", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "shadow_frustum_size"); - RNA_def_property_ui_range(prop, 0.001, 100.0, 2, 1); - RNA_def_property_ui_text(prop, "Frustum Size", "Size of the frustum used for creating the shadow map"); - RNA_def_property_update(prop, 0, "rna_Lamp_draw_update"); - - prop = RNA_def_property(srna, "show_shadow_box", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mode", LA_SHOW_SHADOW_BOX); - RNA_def_property_ui_text(prop, "Show Shadow Box", - "Draw a box in 3D view to visualize which objects are contained in it"); - RNA_def_property_update(prop, 0, "rna_Lamp_draw_update"); + rna_def_lamp_shadow(srna, 1); } static void rna_def_hemi_lamp(BlenderRNA *brna) @@ -943,7 +508,6 @@ void RNA_def_lamp(BlenderRNA *brna) rna_def_spot_lamp(brna); rna_def_sun_lamp(brna); rna_def_hemi_lamp(brna); - rna_def_lamp_mtex(brna); } #endif diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c index d800022ec82..0621c1e1ad6 100644 --- a/source/blender/makesrna/intern/rna_material.c +++ b/source/blender/makesrna/intern/rna_material.c @@ -38,22 +38,6 @@ #include "WM_api.h" #include "WM_types.h" -static const EnumPropertyItem prop_texture_coordinates_items[] = { - {TEXCO_GLOB, "GLOBAL", 0, "Global", "Use global coordinates for the texture coordinates"}, - {TEXCO_OBJECT, "OBJECT", 0, "Object", "Use linked object's coordinates for texture coordinates"}, - {TEXCO_UV, "UV", 0, "UV", "Use UV coordinates for texture coordinates"}, - {TEXCO_ORCO, "ORCO", 0, "Generated", "Use the original undeformed coordinates of the object"}, - {TEXCO_STRAND, "STRAND", 0, "Strand / Particle", - "Use normalized strand texture coordinate (1D) or particle age (X) and trail position (Y)"}, - {TEXCO_WINDOW, "WINDOW", 0, "Window", "Use screen coordinates as texture coordinates"}, - {TEXCO_NORM, "NORMAL", 0, "Normal", "Use normal vector as texture coordinates"}, - {TEXCO_REFL, "REFLECTION", 0, "Reflection", "Use reflection vector as texture coordinates"}, - {TEXCO_STRESS, "STRESS", 0, "Stress", - "Use the difference of edge lengths compared to original coordinates of the mesh"}, - {TEXCO_TANGENT, "TANGENT", 0, "Tangent", "Use the optional tangent vector as texture coordinates"}, - {0, NULL, 0, NULL, NULL} -}; - const EnumPropertyItem rna_enum_ramp_blend_items[] = { {MA_RAMP_BLEND, "MIX", 0, "Mix", ""}, {MA_RAMP_ADD, "ADD", 0, "Add", ""}, @@ -133,42 +117,6 @@ static PointerRNA rna_Material_mirror_get(PointerRNA *ptr) return rna_pointer_inherit_refine(ptr, &RNA_MaterialRaytraceMirror, ptr->id.data); } -static PointerRNA rna_Material_transp_get(PointerRNA *ptr) -{ - return rna_pointer_inherit_refine(ptr, &RNA_MaterialRaytraceTransparency, ptr->id.data); -} - -static PointerRNA rna_Material_halo_get(PointerRNA *ptr) -{ - return rna_pointer_inherit_refine(ptr, &RNA_MaterialHalo, ptr->id.data); -} - -static PointerRNA rna_Material_sss_get(PointerRNA *ptr) -{ - return rna_pointer_inherit_refine(ptr, &RNA_MaterialSubsurfaceScattering, ptr->id.data); -} - -static PointerRNA rna_Material_strand_get(PointerRNA *ptr) -{ - return rna_pointer_inherit_refine(ptr, &RNA_MaterialStrand, ptr->id.data); -} - -static void rna_Material_type_set(PointerRNA *ptr, int value) -{ - Material *ma = (Material *)ptr->data; - - if (ma->material_type == MA_TYPE_HALO && value != MA_TYPE_HALO) - ma->mode &= ~(MA_STAR | MA_HALO_XALPHA | MA_ZINV | MA_ENV); - - ma->material_type = value; -} - -static void rna_Material_mtex_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) -{ - Material *ma = (Material *)ptr->data; - rna_iterator_array_begin(iter, (void *)ma->mtex, sizeof(MTex *), MAX_MTEX, 0, NULL); -} - static void rna_Material_texpaint_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) { Material *ma = (Material *)ptr->data; @@ -229,124 +177,6 @@ static void rna_Material_active_paint_texture_index_update(Main *bmain, Scene *s WM_main_add_notifier(NC_MATERIAL | ND_SHADING, ma); } -static PointerRNA rna_Material_active_texture_get(PointerRNA *ptr) -{ - Material *ma = (Material *)ptr->data; - Tex *tex; - - tex = give_current_material_texture(ma); - return rna_pointer_inherit_refine(ptr, &RNA_Texture, tex); -} - -static void rna_Material_active_texture_set(PointerRNA *ptr, PointerRNA value) -{ - Material *ma = (Material *)ptr->data; - - set_current_material_texture(ma, value.data); -} - -static int rna_Material_active_texture_editable(PointerRNA *ptr, const char **UNUSED(r_info)) -{ - Material *ma = (Material *)ptr->id.data; - - return has_current_material_texture(ma) ? PROP_EDITABLE : 0; -} - -static PointerRNA rna_Material_active_node_material_get(PointerRNA *ptr) -{ - Material *ma = give_node_material((Material *)ptr->data); - return rna_pointer_inherit_refine(ptr, &RNA_Material, ma); -} - -static void rna_Material_active_node_material_set(PointerRNA *ptr, PointerRNA value) -{ - Material *ma = (Material *)ptr->data; - Material *ma_act = value.data; - - nodeSetActiveID(ma->nodetree, ID_MA, &ma_act->id); -} - -static void rna_MaterialStrand_start_size_range(PointerRNA *ptr, float *min, float *max, - float *UNUSED(softmin), float *UNUSED(softmax)) -{ - Material *ma = (Material *)ptr->id.data; - - if (ma->mode & MA_STR_B_UNITS) { - *min = 0.0001f; - *max = 2.0f; - } - else { - *min = 0.25f; - *max = 20.0f; - } -} - -static void rna_MaterialStrand_end_size_range(PointerRNA *ptr, float *min, float *max, - float *UNUSED(softmin), float *UNUSED(softmax)) -{ - Material *ma = (Material *)ptr->id.data; - - if (ma->mode & MA_STR_B_UNITS) { - *min = 0.0001f; - *max = 1.0f; - } - else { - *min = 0.25f; - *max = 10.0f; - } -} - -static int rna_MaterialTextureSlot_use_get(PointerRNA *ptr) -{ - Material *ma = (Material *)ptr->id.data; - MTex *mtex = (MTex *)ptr->data; - int a; - - for (a = 0; a < MAX_MTEX; a++) - if (ma->mtex[a] == mtex) - return (ma->septex & (1 << a)) == 0; - - return 0; -} - -static void rna_MaterialTextureSlot_use_set(PointerRNA *ptr, int value) -{ - Material *ma = (Material *)ptr->id.data; - MTex *mtex = (MTex *)ptr->data; - int a; - - for (a = 0; a < MAX_MTEX; a++) { - if (ma->mtex[a] == mtex) { - if (value) - ma->septex &= ~(1 << a); - else - ma->septex |= (1 << a); - } - } -} - -static void rna_Material_use_diffuse_ramp_set(PointerRNA *ptr, int value) -{ - Material *ma = (Material *)ptr->data; - - if (value) ma->mode |= MA_RAMP_COL; - else ma->mode &= ~MA_RAMP_COL; - - if ((ma->mode & MA_RAMP_COL) && ma->ramp_col == NULL) - ma->ramp_col = BKE_colorband_add(false); -} - -static void rna_Material_use_specular_ramp_set(PointerRNA *ptr, int value) -{ - Material *ma = (Material *)ptr->data; - - if (value) ma->mode |= MA_RAMP_SPEC; - else ma->mode &= ~MA_RAMP_SPEC; - - if ((ma->mode & MA_RAMP_SPEC) && ma->ramp_spec == NULL) - ma->ramp_spec = BKE_colorband_add(false); -} - static void rna_Material_use_nodes_update(bContext *C, PointerRNA *ptr) { Material *ma = (Material *)ptr->data; @@ -359,36 +189,6 @@ static void rna_Material_use_nodes_update(bContext *C, PointerRNA *ptr) rna_Material_draw_update(bmain, CTX_data_scene(C), ptr); } -static const EnumPropertyItem *rna_Material_texture_coordinates_itemf(bContext *UNUSED(C), PointerRNA *ptr, - PropertyRNA *UNUSED(prop), bool *r_free) -{ - Material *ma = (Material *)ptr->id.data; - EnumPropertyItem *item = NULL; - int totitem = 0; - - RNA_enum_items_add_value(&item, &totitem, prop_texture_coordinates_items, TEXCO_GLOB); - RNA_enum_items_add_value(&item, &totitem, prop_texture_coordinates_items, TEXCO_OBJECT); - RNA_enum_items_add_value(&item, &totitem, prop_texture_coordinates_items, TEXCO_ORCO); - - if (ma->material_type == MA_TYPE_VOLUME) { - /* pass */ - } - else if (ELEM(ma->material_type, MA_TYPE_SURFACE, MA_TYPE_HALO, MA_TYPE_WIRE)) { - RNA_enum_items_add_value(&item, &totitem, prop_texture_coordinates_items, TEXCO_UV); - RNA_enum_items_add_value(&item, &totitem, prop_texture_coordinates_items, TEXCO_STRAND); - RNA_enum_items_add_value(&item, &totitem, prop_texture_coordinates_items, TEXCO_WINDOW); - RNA_enum_items_add_value(&item, &totitem, prop_texture_coordinates_items, TEXCO_NORM); - RNA_enum_items_add_value(&item, &totitem, prop_texture_coordinates_items, TEXCO_REFL); - RNA_enum_items_add_value(&item, &totitem, prop_texture_coordinates_items, TEXCO_STRESS); - RNA_enum_items_add_value(&item, &totitem, prop_texture_coordinates_items, TEXCO_TANGENT); - } - - RNA_enum_item_end(&item, &totitem); - *r_free = true; - - return item; -} - MTex *rna_mtex_texture_slots_add(ID *self_id, struct bContext *C, ReportList *reports) { MTex *mtex = BKE_texture_mtex_add_id(self_id, -1); @@ -450,406 +250,10 @@ void rna_mtex_texture_slots_clear(ID *self_id, struct bContext *C, ReportList *r #else -static void rna_def_material_mtex(BlenderRNA *brna) -{ - StructRNA *srna; - PropertyRNA *prop; - - static const EnumPropertyItem prop_mapping_items[] = { - {MTEX_FLAT, "FLAT", 0, "Flat", "Map X and Y coordinates directly"}, - {MTEX_CUBE, "CUBE", 0, "Cube", "Map using the normal vector"}, - {MTEX_TUBE, "TUBE", 0, "Tube", "Map with Z as central axis"}, - {MTEX_SPHERE, "SPHERE", 0, "Sphere", "Map with Z as central axis"}, - {0, NULL, 0, NULL, NULL} - }; - - static const EnumPropertyItem prop_x_mapping_items[] = { - {0, "NONE", 0, "None", ""}, - {1, "X", 0, "X", ""}, - {2, "Y", 0, "Y", ""}, - {3, "Z", 0, "Z", ""}, - {0, NULL, 0, NULL, NULL} - }; - - static const EnumPropertyItem prop_y_mapping_items[] = { - {0, "NONE", 0, "None", ""}, - {1, "X", 0, "X", ""}, - {2, "Y", 0, "Y", ""}, - {3, "Z", 0, "Z", ""}, - {0, NULL, 0, NULL, NULL} - }; - - static const EnumPropertyItem prop_z_mapping_items[] = { - {0, "NONE", 0, "None", ""}, - {1, "X", 0, "X", ""}, - {2, "Y", 0, "Y", ""}, - {3, "Z", 0, "Z", ""}, - {0, NULL, 0, NULL, NULL} - }; - - static const EnumPropertyItem prop_normal_map_space_items[] = { - {MTEX_NSPACE_CAMERA, "CAMERA", 0, "Camera", ""}, - {MTEX_NSPACE_WORLD, "WORLD", 0, "World", ""}, - {MTEX_NSPACE_OBJECT, "OBJECT", 0, "Object", ""}, - {MTEX_NSPACE_TANGENT, "TANGENT", 0, "Tangent", ""}, - {0, NULL, 0, NULL, NULL} - }; - - static const EnumPropertyItem prop_bump_method_items[] = { - {0, "BUMP_ORIGINAL", 0, "Original", ""}, - {MTEX_COMPAT_BUMP, "BUMP_COMPATIBLE", 0, "Compatible", ""}, - {MTEX_3TAP_BUMP, "BUMP_LOW_QUALITY", 0, "Low Quality", "Use 3 tap filtering"}, - {MTEX_5TAP_BUMP, "BUMP_MEDIUM_QUALITY", 0, "Medium Quality", "Use 5 tap filtering"}, - {MTEX_BICUBIC_BUMP, "BUMP_BEST_QUALITY", 0, - "Best Quality", "Use bicubic filtering (requires OpenGL 3.0+, it will fall back on " - "medium setting for other systems)"}, - {0, NULL, 0, NULL, NULL} - }; - - static const EnumPropertyItem prop_bump_space_items[] = { - {0, "BUMP_VIEWSPACE", 0, "ViewSpace", ""}, - {MTEX_BUMP_OBJECTSPACE, "BUMP_OBJECTSPACE", 0, "ObjectSpace", ""}, - {MTEX_BUMP_TEXTURESPACE, "BUMP_TEXTURESPACE", 0, "TextureSpace", ""}, - {0, NULL, 0, NULL, NULL} - }; - - srna = RNA_def_struct(brna, "MaterialTextureSlot", "TextureSlot"); - RNA_def_struct_sdna(srna, "MTex"); - RNA_def_struct_ui_text(srna, "Material Texture Slot", "Texture slot for textures in a Material data-block"); - - prop = RNA_def_property(srna, "texture_coords", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "texco"); - RNA_def_property_enum_items(prop, prop_texture_coordinates_items); - RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_Material_texture_coordinates_itemf"); - RNA_def_property_ui_text(prop, "Texture Coordinates", ""); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "object", PROP_POINTER, PROP_NONE); - RNA_def_property_pointer_sdna(prop, NULL, "object"); - RNA_def_property_struct_type(prop, "Object"); - RNA_def_property_flag(prop, PROP_EDITABLE); - RNA_def_property_ui_text(prop, "Object", "Object to use for mapping with Object texture coordinates"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "uv_layer", PROP_STRING, PROP_NONE); - RNA_def_property_string_sdna(prop, NULL, "uvname"); - RNA_def_property_ui_text(prop, "UV Map", "UV map to use for mapping with UV texture coordinates"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "use_from_dupli", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "texflag", MTEX_DUPLI_MAPTO); - RNA_def_property_ui_text(prop, "From Dupli", - "Dupli's instanced from verts, faces or particles, inherit texture coordinate " - "from their parent"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "use_map_to_bounds", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "texflag", MTEX_MAPTO_BOUNDS); - RNA_def_property_ui_text(prop, "Map to Bounds", - "Map coordinates in object bounds"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "use_from_original", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "texflag", MTEX_OB_DUPLI_ORIG); - RNA_def_property_ui_text(prop, "From Original", - "Dupli's derive their object coordinates from the original object's transformation"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "use_map_color_diffuse", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_COL); - RNA_def_property_ui_text(prop, "Diffuse Color", "The texture affects basic color of the material"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "use_map_normal", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_NORM); - RNA_def_property_ui_text(prop, "Normal", "The texture affects the rendered normal"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "use_map_color_spec", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_COLSPEC); - RNA_def_property_ui_text(prop, "Specular Color", "The texture affects the specularity color"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "use_map_mirror", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_COLMIR); - RNA_def_property_ui_text(prop, "Mirror", "The texture affects the mirror color"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "use_map_diffuse", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_REF); - RNA_def_property_ui_text(prop, "Diffuse", "The texture affects the value of diffuse reflectivity"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "use_map_specular", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_SPEC); - RNA_def_property_ui_text(prop, "Specular", "The texture affects the value of specular reflectivity"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "use_map_ambient", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_AMB); - RNA_def_property_ui_text(prop, "Ambient", "The texture affects the value of ambient"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "use_map_hardness", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_HAR); - RNA_def_property_ui_text(prop, "Hardness", "The texture affects the hardness value"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "use_map_raymir", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_RAYMIRR); - RNA_def_property_ui_text(prop, "Ray-Mirror", "The texture affects the ray-mirror value"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "use_map_alpha", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_ALPHA); - RNA_def_property_ui_text(prop, "Alpha", "The texture affects the alpha value"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "use_map_emit", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_EMIT); - RNA_def_property_ui_text(prop, "Emit", "The texture affects the emit value"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "use_map_translucency", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_TRANSLU); - RNA_def_property_ui_text(prop, "Translucency", "The texture affects the translucency value"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "use_map_displacement", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_DISPLACE); - RNA_def_property_ui_text(prop, "Displacement", "Let the texture displace the surface"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "use_map_warp", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_WARP); - RNA_def_property_ui_text(prop, "Warp", "Let the texture warp texture coordinates of next channels"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "mapping_x", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "projx"); - RNA_def_property_enum_items(prop, prop_x_mapping_items); - RNA_def_property_ui_text(prop, "X Mapping", ""); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "mapping_y", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "projy"); - RNA_def_property_enum_items(prop, prop_y_mapping_items); - RNA_def_property_ui_text(prop, "Y Mapping", ""); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "mapping_z", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "projz"); - RNA_def_property_enum_items(prop, prop_z_mapping_items); - RNA_def_property_ui_text(prop, "Z Mapping", ""); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "mapping", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_items(prop, prop_mapping_items); - RNA_def_property_ui_text(prop, "Mapping", ""); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "normal_map_space", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "normapspace"); - RNA_def_property_enum_items(prop, prop_normal_map_space_items); - RNA_def_property_ui_text(prop, "Normal Map Space", "Set space of normal map image"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "normal_factor", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "norfac"); - RNA_def_property_ui_range(prop, -5, 5, 10, 3); - RNA_def_property_ui_text(prop, "Normal Factor", "Amount texture affects normal values"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "displacement_factor", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "dispfac"); - RNA_def_property_ui_range(prop, -1, 1, 10, 3); - RNA_def_property_ui_text(prop, "Displacement Factor", "Amount texture displaces the surface"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "warp_factor", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "warpfac"); - RNA_def_property_ui_range(prop, 0, 1, 10, 3); - RNA_def_property_ui_text(prop, "Warp Factor", "Amount texture affects texture coordinates of next channels"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "specular_color_factor", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "colspecfac"); - RNA_def_property_ui_range(prop, 0, 1, 10, 3); - RNA_def_property_ui_text(prop, "Specular Color Factor", "Amount texture affects specular color"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "diffuse_color_factor", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "colfac"); - RNA_def_property_ui_range(prop, 0, 1, 10, 3); - RNA_def_property_ui_text(prop, "Diffuse Color Factor", "Amount texture affects diffuse color"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "mirror_factor", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "mirrfac"); - RNA_def_property_ui_range(prop, 0, 1, 10, 3); - RNA_def_property_ui_text(prop, "Mirror Factor", "Amount texture affects mirror color"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "alpha_factor", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "alphafac"); - RNA_def_property_ui_range(prop, -1, 1, 10, 3); - RNA_def_property_ui_text(prop, "Alpha Factor", "Amount texture affects alpha"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "diffuse_factor", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "difffac"); - RNA_def_property_ui_range(prop, -1, 1, 10, 3); - RNA_def_property_ui_text(prop, "Diffuse Factor", "Amount texture affects diffuse reflectivity"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "specular_factor", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "specfac"); - RNA_def_property_ui_range(prop, -1, 1, 10, 3); - RNA_def_property_ui_text(prop, "Specular Factor", "Amount texture affects specular reflectivity"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "emit_factor", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "emitfac"); - RNA_def_property_ui_range(prop, -1, 1, 10, 3); - RNA_def_property_ui_text(prop, "Emit Factor", "Amount texture affects emission"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "hardness_factor", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "hardfac"); - RNA_def_property_ui_range(prop, -1, 1, 10, 3); - RNA_def_property_ui_text(prop, "Hardness Factor", "Amount texture affects hardness"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "raymir_factor", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "raymirrfac"); - RNA_def_property_ui_range(prop, -1, 1, 10, 3); - RNA_def_property_ui_text(prop, "Ray Mirror Factor", "Amount texture affects ray mirror"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "translucency_factor", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "translfac"); - RNA_def_property_ui_range(prop, -1, 1, 10, 3); - RNA_def_property_ui_text(prop, "Translucency Factor", "Amount texture affects translucency"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "ambient_factor", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "ambfac"); - RNA_def_property_ui_range(prop, -1, 1, 10, 3); - RNA_def_property_ui_text(prop, "Ambient Factor", "Amount texture affects ambient"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - /* volume material */ - prop = RNA_def_property(srna, "use_map_color_emission", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_EMISSION_COL); - RNA_def_property_ui_text(prop, "Emission Color", "The texture affects the color of emission"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "use_map_color_reflection", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_REFLECTION_COL); - RNA_def_property_ui_text(prop, "Reflection Color", "The texture affects the color of scattered light"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "use_map_color_transmission", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_TRANSMISSION_COL); - RNA_def_property_ui_text(prop, "Transmission Color", - "The texture affects the result color after other light has been scattered/absorbed"); - RNA_def_property_update(prop, NC_TEXTURE, NULL); - - prop = RNA_def_property(srna, "use_map_density", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_DENSITY); - RNA_def_property_ui_text(prop, "Density", "The texture affects the volume's density"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "use_map_emission", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_EMISSION); - RNA_def_property_ui_text(prop, "Emission", "The texture affects the volume's emission"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "use_map_scatter", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_SCATTERING); - RNA_def_property_ui_text(prop, "Scattering", "The texture affects the volume's scattering"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "use_map_reflect", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_REFLECTION); - RNA_def_property_ui_text(prop, "Reflection", "The texture affects the reflected light's brightness"); - RNA_def_property_update(prop, NC_TEXTURE, NULL); - - prop = RNA_def_property(srna, "emission_color_factor", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "colemitfac"); - RNA_def_property_ui_range(prop, 0, 1, 10, 3); - RNA_def_property_ui_text(prop, "Emission Color Factor", "Amount texture affects emission color"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "reflection_color_factor", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "colreflfac"); - RNA_def_property_ui_range(prop, 0, 1, 10, 3); - RNA_def_property_ui_text(prop, "Reflection Color Factor", "Amount texture affects color of out-scattered light"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "transmission_color_factor", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "coltransfac"); - RNA_def_property_ui_range(prop, 0, 1, 10, 3); - RNA_def_property_ui_text(prop, "Transmission Color Factor", - "Amount texture affects result color after light has been scattered/absorbed"); - RNA_def_property_update(prop, NC_TEXTURE, NULL); - - prop = RNA_def_property(srna, "density_factor", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "densfac"); - RNA_def_property_ui_range(prop, 0, 1, 10, 3); - RNA_def_property_ui_text(prop, "Density Factor", "Amount texture affects density"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "emission_factor", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "emitfac"); - RNA_def_property_ui_range(prop, 0, 1, 10, 3); - RNA_def_property_ui_text(prop, "Emission Factor", "Amount texture affects emission"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "scattering_factor", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "scatterfac"); - RNA_def_property_ui_range(prop, 0, 1, 10, 3); - RNA_def_property_ui_text(prop, "Scattering Factor", "Amount texture affects scattering"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "reflection_factor", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "reflfac"); - RNA_def_property_ui_range(prop, 0, 1, 10, 3); - RNA_def_property_ui_text(prop, "Reflection Factor", "Amount texture affects brightness of out-scattered light"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - /* end volume material */ - - prop = RNA_def_property(srna, "use", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_funcs(prop, "rna_MaterialTextureSlot_use_get", "rna_MaterialTextureSlot_use_set"); - RNA_def_property_ui_text(prop, "Enabled", "Enable this material texture slot"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "bump_method", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_bitflag_sdna(prop, NULL, "texflag"); - RNA_def_property_enum_items(prop, prop_bump_method_items); - RNA_def_property_ui_text(prop, "Bump Method", "Method to use for bump mapping"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "bump_objectspace", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_bitflag_sdna(prop, NULL, "texflag"); - RNA_def_property_enum_items(prop, prop_bump_space_items); - RNA_def_property_ui_text(prop, "Bump Space", "Space to apply bump mapping in"); - RNA_def_property_update(prop, 0, "rna_Material_update"); -} - static void rna_def_material_colors(StructRNA *srna) { PropertyRNA *prop; - static const EnumPropertyItem prop_ramp_input_items[] = { - {MA_RAMP_IN_SHADER, "SHADER", 0, "Shader", ""}, - {MA_RAMP_IN_ENERGY, "ENERGY", 0, "Energy", ""}, - {MA_RAMP_IN_NOR, "NORMAL", 0, "Normal", ""}, - {MA_RAMP_IN_RESULT, "RESULT", 0, "Result", ""}, - {0, NULL, 0, NULL, NULL} - }; - prop = RNA_def_property(srna, "diffuse_color", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "r"); RNA_def_property_array(prop, 3); @@ -862,84 +266,17 @@ static void rna_def_material_colors(StructRNA *srna) RNA_def_property_ui_text(prop, "Specular Color", "Specular color of the material"); RNA_def_property_update(prop, 0, "rna_Material_draw_update"); - prop = RNA_def_property(srna, "mirror_color", PROP_FLOAT, PROP_COLOR); - RNA_def_property_float_sdna(prop, NULL, "mirr"); - RNA_def_property_array(prop, 3); - RNA_def_property_ui_text(prop, "Mirror Color", "Mirror color of the material"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - + prop = RNA_def_property(srna, "specular_intensity", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_sdna(prop, NULL, "spec"); + RNA_def_property_range(prop, 0, 1); + RNA_def_property_ui_text(prop, "Specular Intensity", "How intense (bright) the specular reflection is"); + RNA_def_property_update(prop, 0, "rna_Material_draw_update"); + prop = RNA_def_property(srna, "alpha", PROP_FLOAT, PROP_FACTOR); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Alpha", "Alpha transparency of the material"); RNA_def_property_update(prop, 0, "rna_Material_draw_update"); - prop = RNA_def_property(srna, "specular_alpha", PROP_FLOAT, PROP_FACTOR); - RNA_def_property_float_sdna(prop, NULL, "spectra"); - RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_ui_text(prop, "Specular Alpha", "Alpha transparency for specular areas"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - /* Color bands */ - prop = RNA_def_property(srna, "use_diffuse_ramp", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_RAMP_COL); - RNA_def_property_boolean_funcs(prop, NULL, "rna_Material_use_diffuse_ramp_set"); - RNA_def_property_ui_text(prop, "Use Diffuse Ramp", "Toggle diffuse ramp operations"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "diffuse_ramp", PROP_POINTER, PROP_NONE); - RNA_def_property_pointer_sdna(prop, NULL, "ramp_col"); - RNA_def_property_struct_type(prop, "ColorRamp"); - RNA_def_property_ui_text(prop, "Diffuse Ramp", "Color ramp used to affect diffuse shading"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "use_specular_ramp", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_RAMP_SPEC); - RNA_def_property_boolean_funcs(prop, NULL, "rna_Material_use_specular_ramp_set"); - RNA_def_property_ui_text(prop, "Use Specular Ramp", "Toggle specular ramp operations"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "specular_ramp", PROP_POINTER, PROP_NONE); - RNA_def_property_pointer_sdna(prop, NULL, "ramp_spec"); - RNA_def_property_struct_type(prop, "ColorRamp"); - RNA_def_property_ui_text(prop, "Specular Ramp", "Color ramp used to affect specular shading"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "diffuse_ramp_blend", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "rampblend_col"); - RNA_def_property_enum_items(prop, rna_enum_ramp_blend_items); - RNA_def_property_ui_text(prop, "Diffuse Ramp Blend", "Blending method of the ramp and the diffuse color"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "specular_ramp_blend", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "rampblend_spec"); - RNA_def_property_enum_items(prop, rna_enum_ramp_blend_items); - RNA_def_property_ui_text(prop, "Specular Ramp Blend", "Blending method of the ramp and the specular color"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "diffuse_ramp_input", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "rampin_col"); - RNA_def_property_enum_items(prop, prop_ramp_input_items); - RNA_def_property_ui_text(prop, "Diffuse Ramp Input", "How the ramp maps on the surface"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "specular_ramp_input", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "rampin_spec"); - RNA_def_property_enum_items(prop, prop_ramp_input_items); - RNA_def_property_ui_text(prop, "Specular Ramp Input", "How the ramp maps on the surface"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "diffuse_ramp_factor", PROP_FLOAT, PROP_FACTOR); - RNA_def_property_float_sdna(prop, NULL, "rampfac_col"); - RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_ui_text(prop, "Diffuse Ramp Factor", "Blending factor (also uses alpha in Colorband)"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "specular_ramp_factor", PROP_FLOAT, PROP_FACTOR); - RNA_def_property_float_sdna(prop, NULL, "rampfac_spec"); - RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_ui_text(prop, "Specular Ramp Factor", "Blending factor (also uses alpha in Colorband)"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - /* Freestyle line color */ prop = RNA_def_property(srna, "line_color", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "line_col"); @@ -955,724 +292,28 @@ static void rna_def_material_colors(StructRNA *srna) RNA_def_property_update(prop, 0, "rna_Material_update"); } -static void rna_def_material_diffuse(StructRNA *srna) -{ - PropertyRNA *prop; - - static const EnumPropertyItem prop_diff_shader_items[] = { - {MA_DIFF_LAMBERT, "LAMBERT", 0, "Lambert", "Use a Lambertian shader"}, - {MA_DIFF_ORENNAYAR, "OREN_NAYAR", 0, "Oren-Nayar", "Use an Oren-Nayar shader"}, - {MA_DIFF_TOON, "TOON", 0, "Toon", "Use a toon shader"}, - {MA_DIFF_MINNAERT, "MINNAERT", 0, "Minnaert", "Use a Minnaert shader"}, - {MA_DIFF_FRESNEL, "FRESNEL", 0, "Fresnel", "Use a Fresnel shader"}, - {0, NULL, 0, NULL, NULL} - }; - - prop = RNA_def_property(srna, "diffuse_shader", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "diff_shader"); - RNA_def_property_enum_items(prop, prop_diff_shader_items); - RNA_def_property_ui_text(prop, "Diffuse Shader Model", ""); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "diffuse_intensity", PROP_FLOAT, PROP_FACTOR); - RNA_def_property_float_sdna(prop, NULL, "ref"); - RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_ui_text(prop, "Diffuse Intensity", "Amount of diffuse reflection"); - RNA_def_property_update(prop, 0, "rna_Material_draw_update"); - - prop = RNA_def_property(srna, "roughness", PROP_FLOAT, PROP_NONE); - RNA_def_property_range(prop, 0.0f, 3.14f); - RNA_def_property_ui_text(prop, "Roughness", "Oren-Nayar Roughness"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "diffuse_toon_size", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "param[0]"); - RNA_def_property_range(prop, 0.0f, 3.14f); - RNA_def_property_ui_text(prop, "Diffuse Toon Size", "Size of diffuse toon area"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "diffuse_toon_smooth", PROP_FLOAT, PROP_FACTOR); - RNA_def_property_float_sdna(prop, NULL, "param[1]"); - RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_ui_text(prop, "Diffuse Toon Smooth", "Smoothness of diffuse toon area"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "diffuse_fresnel", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "param[1]"); - RNA_def_property_range(prop, 0.0f, 5.0f); - RNA_def_property_ui_text(prop, "Diffuse Fresnel", "Power of Fresnel"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "diffuse_fresnel_factor", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "param[0]"); - RNA_def_property_range(prop, 0.0f, 5.0f); - RNA_def_property_ui_text(prop, "Diffuse Fresnel Factor", "Blending factor of Fresnel"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "darkness", PROP_FLOAT, PROP_NONE); - RNA_def_property_range(prop, 0.0f, 2.0f); - RNA_def_property_ui_text(prop, "Darkness", "Minnaert darkness"); - RNA_def_property_update(prop, 0, "rna_Material_update"); -} - static void rna_def_material_raymirror(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; - static const EnumPropertyItem prop_fadeto_mir_items[] = { - {MA_RAYMIR_FADETOSKY, "FADE_TO_SKY", 0, "Sky", ""}, - {MA_RAYMIR_FADETOMAT, "FADE_TO_MATERIAL", 0, "Material", ""}, - {0, NULL, 0, NULL, NULL} - }; - srna = RNA_def_struct(brna, "MaterialRaytraceMirror", NULL); RNA_def_struct_sdna(srna, "Material"); RNA_def_struct_nested(brna, srna, "Material"); RNA_def_struct_ui_text(srna, "Material Raytrace Mirror", "Raytraced reflection settings for a Material data-block"); - prop = RNA_def_property(srna, "use", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_RAYMIRROR); /* use bitflags */ - RNA_def_property_ui_text(prop, "Enabled", "Enable raytraced reflections"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - prop = RNA_def_property(srna, "reflect_factor", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "ray_mirror"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Reflectivity", "Amount of mirror reflection for raytrace"); RNA_def_property_update(prop, 0, "rna_Material_update"); - prop = RNA_def_property(srna, "fresnel", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "fresnel_mir"); - RNA_def_property_range(prop, 0.0f, 5.0f); - RNA_def_property_ui_text(prop, "Fresnel", "Power of Fresnel for mirror reflection"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "fresnel_factor", PROP_FLOAT, PROP_FACTOR); - RNA_def_property_float_sdna(prop, NULL, "fresnel_mir_i"); - RNA_def_property_range(prop, 0.0f, 5.0f); - RNA_def_property_ui_text(prop, "Fresnel Factor", "Blending factor for Fresnel"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - prop = RNA_def_property(srna, "gloss_factor", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "gloss_mir"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Gloss Amount", "The shininess of the reflection (values < 1.0 give diffuse, blurry reflections)"); RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "gloss_anisotropic", PROP_FLOAT, PROP_FACTOR); - RNA_def_property_float_sdna(prop, NULL, "aniso_gloss_mir"); - RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_ui_text(prop, "Gloss Anisotropy", - "The shape of the reflection, from 0.0 (circular) to 1.0 " - "(fully stretched along the tangent"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "gloss_samples", PROP_INT, PROP_NONE); - RNA_def_property_int_sdna(prop, NULL, "samp_gloss_mir"); - RNA_def_property_range(prop, 0, 1024); - RNA_def_property_ui_text(prop, "Gloss Samples", "Number of cone samples averaged for blurry reflections"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "gloss_threshold", PROP_FLOAT, PROP_FACTOR); - RNA_def_property_float_sdna(prop, NULL, "adapt_thresh_mir"); - RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_ui_text(prop, "Gloss Threshold", - "Threshold for adaptive sampling (if a sample contributes less than " - "this amount [as a percentage], sampling is stopped)"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "depth", PROP_INT, PROP_UNSIGNED); - RNA_def_property_int_sdna(prop, NULL, "ray_depth"); - RNA_def_property_ui_range(prop, 0, 100, 1, 3); - RNA_def_property_ui_text(prop, "Depth", "Maximum allowed number of light inter-reflections"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "distance", PROP_FLOAT, PROP_DISTANCE); - RNA_def_property_float_sdna(prop, NULL, "dist_mir"); - RNA_def_property_range(prop, 0.0f, 10000.0f); - RNA_def_property_ui_text(prop, "Maximum Distance", - "Maximum distance of reflected rays (reflections further than this " - "range fade to sky color or material color)"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "fade_to", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "fadeto_mir"); - RNA_def_property_enum_items(prop, prop_fadeto_mir_items); - RNA_def_property_ui_text(prop, "Fade-out Color", - "The color that rays with no intersection within the Max Distance take " - "(material color can be best for indoor scenes, sky color for outdoor)"); - RNA_def_property_update(prop, 0, "rna_Material_update"); -} - -static void rna_def_material_raytra(BlenderRNA *brna) -{ - StructRNA *srna; - PropertyRNA *prop; - - srna = RNA_def_struct(brna, "MaterialRaytraceTransparency", NULL); - RNA_def_struct_sdna(srna, "Material"); - RNA_def_struct_nested(brna, srna, "Material"); - RNA_def_struct_ui_text(srna, "Material Raytrace Transparency", - "Raytraced refraction settings for a Material data-block"); - - prop = RNA_def_property(srna, "ior", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "ang"); - RNA_def_property_range(prop, 0.25f, 4.0f); - RNA_def_property_ui_text(prop, "IOR", "Angular index of refraction for raytraced refraction"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "fresnel", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "fresnel_tra"); - RNA_def_property_range(prop, 0.0f, 5.0f); - RNA_def_property_ui_text(prop, "Fresnel", "Power of Fresnel for transparency (Ray or ZTransp)"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "fresnel_factor", PROP_FLOAT, PROP_FACTOR); - RNA_def_property_float_sdna(prop, NULL, "fresnel_tra_i"); - RNA_def_property_range(prop, 1.0f, 5.0f); - RNA_def_property_ui_text(prop, "Fresnel Factor", "Blending factor for Fresnel"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "gloss_factor", PROP_FLOAT, PROP_FACTOR); - RNA_def_property_float_sdna(prop, NULL, "gloss_tra"); - RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_ui_text(prop, "Gloss Amount", - "The clarity of the refraction. Values < 1.0 give diffuse, blurry refractions"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "gloss_samples", PROP_INT, PROP_NONE); - RNA_def_property_int_sdna(prop, NULL, "samp_gloss_tra"); - RNA_def_property_range(prop, 0, 1024); - RNA_def_property_ui_text(prop, "Gloss Samples", "Number of cone samples averaged for blurry refractions"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "gloss_threshold", PROP_FLOAT, PROP_FACTOR); - RNA_def_property_float_sdna(prop, NULL, "adapt_thresh_tra"); - RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_ui_text(prop, "Gloss Threshold", - "Threshold for adaptive sampling. If a sample contributes less than " - "this amount (as a percentage), sampling is stopped"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "depth", PROP_INT, PROP_UNSIGNED); - RNA_def_property_int_sdna(prop, NULL, "ray_depth_tra"); - RNA_def_property_ui_range(prop, 0, 100, 1, 3); - RNA_def_property_ui_text(prop, "Depth", "Maximum allowed number of light inter-refractions"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "filter", PROP_FLOAT, PROP_FACTOR); - RNA_def_property_float_sdna(prop, NULL, "filter"); - RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_ui_text(prop, "Filter", - "Amount to blend in the material's diffuse color in raytraced " - "transparency (simulating absorption)"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "depth_max", PROP_FLOAT, PROP_DISTANCE); - RNA_def_property_float_sdna(prop, NULL, "tx_limit"); - RNA_def_property_range(prop, 0.0f, 100.0f); - RNA_def_property_ui_text(prop, "Limit", - "Maximum depth for light to travel through the transparent material " - "before becoming fully filtered (0.0 is disabled)"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "falloff", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "tx_falloff"); - RNA_def_property_range(prop, 0.1f, 10.0f); - RNA_def_property_ui_text(prop, "Falloff", "Falloff power for transmissivity filter effect (1.0 is linear)"); - RNA_def_property_update(prop, 0, "rna_Material_update"); -} - -static void rna_def_material_volume(BlenderRNA *brna) -{ - StructRNA *srna; - PropertyRNA *prop; - - static const EnumPropertyItem prop_lighting_items[] = { - {MA_VOL_SHADE_SHADELESS, "SHADELESS", 0, "Shadeless", "Do not calculate lighting and shadows"}, - {MA_VOL_SHADE_SHADOWED, "SHADOWED", 0, "Shadowed", ""}, - {MA_VOL_SHADE_SHADED, "SHADED", 0, "Shaded", ""}, - {MA_VOL_SHADE_MULTIPLE, "MULTIPLE_SCATTERING", 0, "Multiple Scattering", ""}, - {MA_VOL_SHADE_SHADEDPLUSMULTIPLE, "SHADED_PLUS_MULTIPLE_SCATTERING", 0, "Shaded + Multiple Scattering", ""}, - {0, NULL, 0, NULL, NULL} - }; - - static const EnumPropertyItem prop_stepsize_items[] = { - {MA_VOL_STEP_RANDOMIZED, "RANDOMIZED", 0, "Randomized", ""}, - {MA_VOL_STEP_CONSTANT, "CONSTANT", 0, "Constant", ""}, - /*{MA_VOL_STEP_ADAPTIVE, "ADAPTIVE", 0, "Adaptive", ""}, */ - {0, NULL, 0, NULL, NULL} - }; - - srna = RNA_def_struct(brna, "MaterialVolume", NULL); - RNA_def_struct_sdna(srna, "VolumeSettings"); - RNA_def_struct_nested(brna, srna, "Material"); - RNA_def_struct_ui_text(srna, "Material Volume", "Volume rendering settings for a Material data-block"); - - prop = RNA_def_property(srna, "step_method", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "stepsize_type"); - RNA_def_property_enum_items(prop, prop_stepsize_items); - RNA_def_property_ui_text(prop, "Step Calculation", "Method of calculating the steps through the volume"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "step_size", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "stepsize"); - RNA_def_property_range(prop, 0.0f, FLT_MAX); - RNA_def_property_ui_range(prop, 0.001f, 1.0f, 1, 3); - RNA_def_property_ui_text(prop, "Step Size", "Distance between subsequent volume depth samples"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "light_method", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "shade_type"); - RNA_def_property_enum_items(prop, prop_lighting_items); - RNA_def_property_ui_text(prop, "Lighting Mode", - "Method of shading, attenuating, and scattering light through the volume"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "use_external_shadows", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "shadeflag", MA_VOL_RECV_EXT_SHADOW); /* use bitflags */ - RNA_def_property_ui_text(prop, "External Shadows", "Receive shadows from sources outside the volume (temporary)"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "use_light_cache", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "shadeflag", MA_VOL_PRECACHESHADING); /* use bitflags */ - RNA_def_property_ui_text(prop, "Light Cache", - "Pre-calculate the shading information into a voxel grid, " - "speeds up shading at slightly less accuracy"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "cache_resolution", PROP_INT, PROP_NONE); - RNA_def_property_int_sdna(prop, NULL, "precache_resolution"); - RNA_def_property_range(prop, 1, 1024); - RNA_def_property_ui_text(prop, "Resolution", - "Resolution of the voxel grid, low resolutions are faster, " - "high resolutions use more memory"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "ms_diffusion", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "ms_diff"); - RNA_def_property_range(prop, 0.0f, FLT_MAX); - RNA_def_property_ui_text(prop, "Diffusion", "Diffusion factor, the strength of the blurring effect"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "ms_spread", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "ms_spread"); - RNA_def_property_range(prop, 0, FLT_MAX); - RNA_def_property_ui_range(prop, 0.0f, 1.0f, 1, 3); - RNA_def_property_ui_text(prop, "Spread", "Proportional distance over which the light is diffused"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "ms_intensity", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "ms_intensity"); - RNA_def_property_range(prop, 0.0f, FLT_MAX); - RNA_def_property_ui_text(prop, "Intensity", "Multiplier for multiple scattered light energy"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "depth_threshold", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "depth_cutoff"); - RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_ui_text(prop, "Depth Cutoff", - "Stop ray marching early if transmission drops below this luminance - " - "higher values give speedups in dense volumes at the expense of accuracy"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "density", PROP_FLOAT, PROP_FACTOR); - RNA_def_property_float_sdna(prop, NULL, "density"); - RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_ui_text(prop, "Density", "The base density of the volume"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "density_scale", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "density_scale"); - RNA_def_property_range(prop, 0.0f, FLT_MAX); - RNA_def_property_ui_range(prop, 0.0f, 10.0f, 1, 3); - RNA_def_property_ui_text(prop, "Density Scale", "Multiplier for the material's density"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "scattering", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "scattering"); - RNA_def_property_range(prop, 0.0f, FLT_MAX); - RNA_def_property_ui_range(prop, 0.0f, 10.0f, 1, 3); - RNA_def_property_ui_text(prop, "Scattering", - "Amount of light that gets scattered out by the volume - " - "the more out-scattering, the shallower the light will penetrate"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "transmission_color", PROP_FLOAT, PROP_COLOR); - RNA_def_property_float_sdna(prop, NULL, "transmission_col"); - RNA_def_property_array(prop, 3); - RNA_def_property_ui_text(prop, "Transmission Color", - "Result color of the volume, after other light has been scattered/absorbed"); - RNA_def_property_update(prop, 0, "rna_Material_draw_update"); - - prop = RNA_def_property(srna, "reflection_color", PROP_FLOAT, PROP_COLOR); - RNA_def_property_float_sdna(prop, NULL, "reflection_col"); - RNA_def_property_array(prop, 3); - RNA_def_property_ui_text(prop, "Reflection Color", - "Color of light scattered out of the volume (does not affect transmission)"); - RNA_def_property_update(prop, 0, "rna_Material_draw_update"); - - prop = RNA_def_property(srna, "reflection", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "reflection"); - RNA_def_property_range(prop, 0.0f, FLT_MAX); - RNA_def_property_ui_range(prop, 0.0f, 100.0f, 1, 3); - RNA_def_property_ui_text(prop, "Reflection", - "Multiplier to make out-scattered light brighter or darker (non-physically correct)"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "emission_color", PROP_FLOAT, PROP_COLOR); - RNA_def_property_float_sdna(prop, NULL, "emission_col"); - RNA_def_property_array(prop, 3); - RNA_def_property_ui_text(prop, "Emission Color", "Color of emitted light"); - RNA_def_property_update(prop, 0, "rna_Material_draw_update"); - - prop = RNA_def_property(srna, "emission", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "emission"); - RNA_def_property_range(prop, 0.0f, FLT_MAX); - RNA_def_property_ui_range(prop, 0.0f, 10.0f, 1, 3); - RNA_def_property_ui_text(prop, "Emission", "Amount of light that gets emitted by the volume"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "asymmetry", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "asymmetry"); - RNA_def_property_range(prop, -1.0f, 1.0f); - RNA_def_property_ui_text(prop, "Asymmetry", - "Back scattering (-1.0) to Forward scattering (1.0) and the range in between"); - RNA_def_property_update(prop, 0, "rna_Material_update"); -} - - -static void rna_def_material_halo(BlenderRNA *brna) -{ - StructRNA *srna; - PropertyRNA *prop; - - srna = RNA_def_struct(brna, "MaterialHalo", NULL); - RNA_def_struct_sdna(srna, "Material"); - RNA_def_struct_nested(brna, srna, "Material"); - RNA_def_struct_ui_text(srna, "Material Halo", "Halo particle effect settings for a Material data-block"); - - prop = RNA_def_property(srna, "size", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "hasize"); - RNA_def_property_range(prop, 0.0f, 100.0f); - RNA_def_property_ui_text(prop, "Size", "Dimension of the halo"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "hardness", PROP_INT, PROP_NONE); - RNA_def_property_int_sdna(prop, NULL, "har"); - RNA_def_property_range(prop, 0, 127); - RNA_def_property_ui_text(prop, "Hardness", "Hardness of the halo"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "add", PROP_FLOAT, PROP_FACTOR); - RNA_def_property_float_sdna(prop, NULL, "add"); - RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_ui_text(prop, "Add", "Strength of the add effect"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "ring_count", PROP_INT, PROP_NONE); - RNA_def_property_int_sdna(prop, NULL, "ringc"); - RNA_def_property_range(prop, 0, 24); - RNA_def_property_ui_text(prop, "Rings", "Number of rings rendered over the halo"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "line_count", PROP_INT, PROP_NONE); - RNA_def_property_int_sdna(prop, NULL, "linec"); - RNA_def_property_range(prop, 0, 250); - RNA_def_property_ui_text(prop, "Line Number", "Number of star shaped lines rendered over the halo"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "star_tip_count", PROP_INT, PROP_NONE); - RNA_def_property_int_sdna(prop, NULL, "starc"); - RNA_def_property_range(prop, 3, 50); - RNA_def_property_ui_text(prop, "Star Tips", "Number of points on the star shaped halo"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "seed", PROP_INT, PROP_NONE); - RNA_def_property_int_sdna(prop, NULL, "seed1"); - RNA_def_property_range(prop, 0, 255); - RNA_def_property_ui_text(prop, "Seed", "Randomize ring dimension and line location"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "use_flare_mode", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_HALO_FLARE); /* use bitflags */ - RNA_def_property_ui_text(prop, "Flare", "Render halo as a lens flare"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "flare_size", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "flaresize"); - RNA_def_property_range(prop, 0.1f, 25.0f); - RNA_def_property_ui_text(prop, "Flare Size", "Factor by which the flare is larger than the halo"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "flare_subflare_size", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "subsize"); - RNA_def_property_range(prop, 0.1f, 25.0f); - RNA_def_property_ui_text(prop, "Flare Subsize", "Dimension of the sub-flares, dots and circles"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "flare_boost", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "flareboost"); - RNA_def_property_range(prop, 0.1f, 10.0f); - RNA_def_property_ui_text(prop, "Flare Boost", "Give the flare extra strength"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "flare_seed", PROP_INT, PROP_NONE); - RNA_def_property_int_sdna(prop, NULL, "seed2"); - RNA_def_property_range(prop, 0, 255); - RNA_def_property_ui_text(prop, "Flare Seed", "Offset in the flare seed table"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "flare_subflare_count", PROP_INT, PROP_NONE); - RNA_def_property_int_sdna(prop, NULL, "flarec"); - RNA_def_property_range(prop, 1, 32); - RNA_def_property_ui_text(prop, "Flares Sub", "Number of sub-flares"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "use_ring", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_HALO_RINGS); - RNA_def_property_ui_text(prop, "Rings", "Render rings over halo"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "use_lines", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_HALO_LINES); - RNA_def_property_ui_text(prop, "Lines", "Render star shaped lines over halo"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "use_star", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_STAR); - RNA_def_property_ui_text(prop, "Star", "Render halo as a star"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "use_texture", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_HALOTEX); - RNA_def_property_ui_text(prop, "Texture", "Give halo a texture"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "use_vertex_normal", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_HALOPUNO); - RNA_def_property_ui_text(prop, "Vertex Normal", "Use the vertex normal to specify the dimension of the halo"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "use_extreme_alpha", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_HALO_XALPHA); - RNA_def_property_ui_text(prop, "Extreme Alpha", "Use extreme alpha"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "use_shaded", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_HALO_SHADE); - RNA_def_property_ui_text(prop, "Shaded", "Let halo receive light and shadows from external objects"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "use_soft", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_HALO_SOFT); - RNA_def_property_ui_text(prop, "Soft", "Soften the edges of halos at intersections with other geometry"); - RNA_def_property_update(prop, 0, "rna_Material_update"); -} - -static void rna_def_material_sss(BlenderRNA *brna) -{ - StructRNA *srna; - PropertyRNA *prop; - - srna = RNA_def_struct(brna, "MaterialSubsurfaceScattering", NULL); - RNA_def_struct_sdna(srna, "Material"); - RNA_def_struct_nested(brna, srna, "Material"); - RNA_def_struct_ui_text(srna, "Material Subsurface Scattering", - "Diffuse subsurface scattering settings for a Material data-block"); - - prop = RNA_def_property(srna, "radius", PROP_FLOAT, PROP_COLOR | PROP_UNIT_LENGTH); - RNA_def_property_float_sdna(prop, NULL, "sss_radius"); - RNA_def_property_range(prop, 0.001, FLT_MAX); - RNA_def_property_ui_range(prop, 0.001, 10000, 1, 3); - RNA_def_property_ui_text(prop, "Radius", "Mean red/green/blue scattering path length"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR); - RNA_def_property_float_sdna(prop, NULL, "sss_col"); - RNA_def_property_ui_text(prop, "Color", "Scattering color"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "error_threshold", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "sss_error"); - RNA_def_property_ui_range(prop, 0.0001, 10, 1, 3); - RNA_def_property_ui_text(prop, "Error Tolerance", "Error tolerance (low values are slower and higher quality)"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "scale", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "sss_scale"); - RNA_def_property_ui_range(prop, 0.001, 1000, 1, 3); - RNA_def_property_ui_text(prop, "Scale", "Object scale factor"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "ior", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "sss_ior"); - RNA_def_property_ui_range(prop, 0.1, 2, 1, 3); - RNA_def_property_ui_text(prop, "IOR", "Index of refraction (higher values are denser)"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "color_factor", PROP_FLOAT, PROP_FACTOR); - RNA_def_property_float_sdna(prop, NULL, "sss_colfac"); - RNA_def_property_ui_range(prop, 0, 1, 10, 3); - RNA_def_property_ui_text(prop, "Color Factor", "Blend factor for SSS colors"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "texture_factor", PROP_FLOAT, PROP_FACTOR); - RNA_def_property_float_sdna(prop, NULL, "sss_texfac"); - RNA_def_property_ui_range(prop, 0, 1, 10, 3); - RNA_def_property_ui_text(prop, "Texture Factor", "Texture scattering blend factor"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "front", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "sss_front"); - RNA_def_property_range(prop, 0, 2); - RNA_def_property_ui_text(prop, "Front", "Front scattering weight"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "back", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "sss_back"); - RNA_def_property_range(prop, 0, 10); - RNA_def_property_ui_text(prop, "Back", "Back scattering weight"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "use", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "sss_flag", MA_DIFF_SSS); - RNA_def_property_ui_text(prop, "Enabled", "Enable diffuse subsurface scattering effects in a material"); - RNA_def_property_update(prop, 0, "rna_Material_update"); -} - -static void rna_def_material_specularity(StructRNA *srna) -{ - PropertyRNA *prop; - - static const EnumPropertyItem prop_specular_shader_items[] = { - {MA_SPEC_COOKTORR, "COOKTORR", 0, "CookTorr", "Use a Cook-Torrance shader"}, - {MA_SPEC_PHONG, "PHONG", 0, "Phong", "Use a Phong shader"}, - {MA_SPEC_BLINN, "BLINN", 0, "Blinn", "Use a Blinn shader"}, - {MA_SPEC_TOON, "TOON", 0, "Toon", "Use a toon shader"}, - {MA_SPEC_WARDISO, "WARDISO", 0, "WardIso", "Use a Ward anisotropic shader"}, - {0, NULL, 0, NULL, NULL} - }; - - prop = RNA_def_property(srna, "specular_shader", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "spec_shader"); - RNA_def_property_enum_items(prop, prop_specular_shader_items); - RNA_def_property_ui_text(prop, "Specular Shader Model", ""); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "specular_intensity", PROP_FLOAT, PROP_FACTOR); - RNA_def_property_float_sdna(prop, NULL, "spec"); - RNA_def_property_range(prop, 0, 1); - RNA_def_property_ui_text(prop, "Specular Intensity", "How intense (bright) the specular reflection is"); - RNA_def_property_update(prop, 0, "rna_Material_draw_update"); - - /* NOTE: "har", "param", etc are used for multiple purposes depending on - * settings. This should be fixed in DNA once, for RNA we just expose them - * multiple times, which may give somewhat strange changes in the outliner, - * but in the UI they are never visible at the same time. */ - - prop = RNA_def_property(srna, "specular_hardness", PROP_INT, PROP_NONE); - RNA_def_property_int_sdna(prop, NULL, "har"); - RNA_def_property_range(prop, 1, 511); - RNA_def_property_ui_text(prop, "Specular Hardness", "How hard (sharp) the specular reflection is"); - RNA_def_property_update(prop, 0, "rna_Material_draw_update"); - - prop = RNA_def_property(srna, "specular_ior", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "refrac"); - RNA_def_property_range(prop, 1, 10); - RNA_def_property_ui_text(prop, "Specular IOR", "Specular index of refraction"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "specular_toon_size", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "param[2]"); - RNA_def_property_range(prop, 0.0f, 1.53f); - RNA_def_property_ui_text(prop, "Specular Toon Size", "Size of specular toon area"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "specular_toon_smooth", PROP_FLOAT, PROP_FACTOR); - RNA_def_property_float_sdna(prop, NULL, "param[3]"); - RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_ui_text(prop, "Specular Toon Smooth", "Smoothness of specular toon area"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "specular_slope", PROP_FLOAT, PROP_FACTOR); - RNA_def_property_float_sdna(prop, NULL, "rms"); - RNA_def_property_range(prop, 0, 0.4); - RNA_def_property_ui_text(prop, "Specular Slope", "The standard deviation of surface slope"); - RNA_def_property_update(prop, 0, "rna_Material_update"); -} - -static void rna_def_material_strand(BlenderRNA *brna) -{ - StructRNA *srna; - PropertyRNA *prop; - - srna = RNA_def_struct(brna, "MaterialStrand", NULL); - RNA_def_struct_sdna(srna, "Material"); - RNA_def_struct_nested(brna, srna, "Material"); - RNA_def_struct_ui_text(srna, "Material Strand", "Strand settings for a Material data-block"); - - prop = RNA_def_property(srna, "use_tangent_shading", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_TANGENT_STR); - RNA_def_property_ui_text(prop, "Tangent Shading", "Use direction of strands as normal for tangent-shading"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - /* this flag is only set when rendering, not to be edited manually */ - prop = RNA_def_property(srna, "use_surface_diffuse", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_STR_SURFDIFF); - RNA_def_property_clear_flag(prop, PROP_EDITABLE); - RNA_def_property_ui_text(prop, "Surface Diffuse", "Make diffuse shading more similar to shading the surface"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "blend_distance", PROP_FLOAT, PROP_DISTANCE); - RNA_def_property_float_sdna(prop, NULL, "strand_surfnor"); - RNA_def_property_range(prop, 0, 10); - RNA_def_property_ui_text(prop, "Blend Distance", "Worldspace distance over which to blend in the surface normal"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "use_blender_units", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_STR_B_UNITS); - RNA_def_property_ui_text(prop, "Blender Units", "Use Blender units for widths instead of pixels"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "root_size", PROP_FLOAT, PROP_UNSIGNED); - RNA_def_property_float_sdna(prop, NULL, "strand_sta"); - RNA_def_property_float_funcs(prop, NULL, NULL, "rna_MaterialStrand_start_size_range"); - RNA_def_property_ui_range(prop, 0, 10.0f, 10, 5); - RNA_def_property_ui_text(prop, "Root Size", "Start size of strands in pixels or Blender units"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "tip_size", PROP_FLOAT, PROP_UNSIGNED); - RNA_def_property_float_sdna(prop, NULL, "strand_end"); - RNA_def_property_ui_range(prop, 0, 10.0f, 10, 5); - RNA_def_property_float_funcs(prop, NULL, NULL, "rna_MaterialStrand_end_size_range"); - RNA_def_property_ui_text(prop, "Tip Size", "End size of strands in pixels or Blender units"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "size_min", PROP_FLOAT, PROP_UNSIGNED); - RNA_def_property_float_sdna(prop, NULL, "strand_min"); - RNA_def_property_range(prop, 0.001, 10); - RNA_def_property_ui_text(prop, "Minimum Size", "Minimum size of strands in pixels"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "shape", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "strand_ease"); - RNA_def_property_range(prop, -0.9, 0.9); - RNA_def_property_ui_text(prop, "Shape", "Positive values make strands rounder, negative ones make strands spiky"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "width_fade", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "strand_widthfade"); - RNA_def_property_range(prop, 0, 2); - RNA_def_property_ui_text(prop, "Width Fade", "Transparency along the width of the strand"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "uv_layer", PROP_STRING, PROP_NONE); - RNA_def_property_string_sdna(prop, NULL, "strand_uvname"); - RNA_def_property_ui_text(prop, "UV Map", "Name of UV map to override"); - RNA_def_property_update(prop, 0, "rna_Material_update"); } void RNA_def_material(BlenderRNA *brna) @@ -1680,20 +321,6 @@ void RNA_def_material(BlenderRNA *brna) StructRNA *srna; PropertyRNA *prop; - static const EnumPropertyItem prop_type_items[] = { - {MA_TYPE_SURFACE, "SURFACE", 0, "Surface", "Render object as a surface"}, - {MA_TYPE_WIRE, "WIRE", 0, "Wire", "Render the edges of faces as wires (not supported in raytracing)"}, - {MA_TYPE_VOLUME, "VOLUME", 0, "Volume", "Render object as a volume"}, - {MA_TYPE_HALO, "HALO", 0, "Halo", "Render object as halo particles"}, - {0, NULL, 0, NULL, NULL} - }; - static const EnumPropertyItem transparency_items[] = { - {0, "MASK", 0, "Mask", "Mask the background"}, - {MA_ZTRANSP, "Z_TRANSPARENCY", 0, "Z Transparency", "Use alpha buffer for transparent faces"}, - {MA_RAYTRANSP, "RAYTRACE", 0, "Raytrace", "Use raytracing for transparent refraction rendering"}, - {0, NULL, 0, NULL, NULL} - }; - /* Render Preview Types */ static const EnumPropertyItem preview_type_items[] = { {MA_FLAT, "FLAT", ICON_MATPLANE, "Flat", "Flat XY plane"}, @@ -1705,14 +332,6 @@ void RNA_def_material(BlenderRNA *brna) {0, NULL, 0, NULL, NULL} }; - static const EnumPropertyItem prop_shadows_only_items[] = { - {MA_SO_OLD, "SHADOW_ONLY_OLD", 0, "Shadow and Distance", "Old shadow only method"}, - {MA_SO_SHADOW, "SHADOW_ONLY", 0, "Shadow Only", "Improved shadow only method"}, - {MA_SO_SHADED, "SHADOW_ONLY_SHADED", 0, "Shadow and Shading", - "Improved shadow only method which also renders lightless areas as shadows"}, - {0, NULL, 0, NULL, NULL} - }; - static EnumPropertyItem prop_eevee_blend_items[] = { {MA_BM_SOLID, "OPAQUE", 0, "Opaque", "Render surface without transparency"}, {MA_BM_ADD, "ADD", 0, "Additive", "Render surface and blend the result with additive blending"}, @@ -1736,24 +355,6 @@ void RNA_def_material(BlenderRNA *brna) "Material data-block to define the appearance of geometric objects for rendering"); RNA_def_struct_ui_icon(srna, ICON_MATERIAL_DATA); - prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "material_type"); - RNA_def_property_enum_items(prop, prop_type_items); - RNA_def_property_ui_text(prop, "Type", "Material type defining how the object is rendered"); - RNA_def_property_enum_funcs(prop, NULL, "rna_Material_type_set", NULL); - RNA_def_property_update(prop, 0, "rna_Material_draw_update"); - - prop = RNA_def_property(srna, "use_transparency", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_TRANSP); - RNA_def_property_ui_text(prop, "Transparency", "Render material as transparent"); - RNA_def_property_update(prop, 0, "rna_Material_draw_update"); - - prop = RNA_def_property(srna, "transparency_method", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_bitflag_sdna(prop, NULL, "mode"); - RNA_def_property_enum_items(prop, transparency_items); - RNA_def_property_ui_text(prop, "Transparency Method", "Method to use for rendering transparency"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - /* Blending (only Eevee for now) */ prop = RNA_def_property(srna, "blend_method", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, prop_eevee_blend_items); @@ -1806,203 +407,11 @@ void RNA_def_material(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Preview render type", "Type of preview render"); RNA_def_property_update(prop, 0, "rna_Material_update_previews"); - prop = RNA_def_property(srna, "ambient", PROP_FLOAT, PROP_FACTOR); - RNA_def_property_float_sdna(prop, NULL, "amb"); - RNA_def_property_range(prop, 0, 1); - RNA_def_property_ui_text(prop, "Ambient", "Amount of global ambient color the material receives"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "emit", PROP_FLOAT, PROP_NONE); - RNA_def_property_range(prop, 0, FLT_MAX); - RNA_def_property_ui_range(prop, 0, 2.0f, 1, 2); - RNA_def_property_ui_text(prop, "Emit", "Amount of light to emit"); - RNA_def_property_update(prop, 0, "rna_Material_draw_update"); - - prop = RNA_def_property(srna, "translucency", PROP_FLOAT, PROP_FACTOR); - RNA_def_property_range(prop, 0, 1); - RNA_def_property_ui_text(prop, "Translucency", "Amount of diffuse shading on the back side"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "use_cubic", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "shade_flag", MA_CUBIC); - RNA_def_property_ui_text(prop, "Cubic Interpolation", - "Use cubic interpolation for diffuse values, for smoother transitions"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "use_object_color", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "shade_flag", MA_OBCOLOR); - RNA_def_property_ui_text(prop, "Object Color", "Modulate the result with a per-object color"); - RNA_def_property_update(prop, 0, "rna_Material_draw_update"); - - prop = RNA_def_property(srna, "shadow_ray_bias", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "sbias"); - RNA_def_property_range(prop, 0, 0.25); - RNA_def_property_ui_text(prop, "Shadow Ray Bias", - "Shadow raytracing bias to prevent terminator problems on shadow boundary"); - - prop = RNA_def_property(srna, "shadow_buffer_bias", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "lbias"); - RNA_def_property_range(prop, 0, 10); - RNA_def_property_ui_text(prop, "Shadow Buffer Bias", "Factor to multiply shadow buffer bias with (0 is ignore)"); - - prop = RNA_def_property(srna, "shadow_cast_alpha", PROP_FLOAT, PROP_FACTOR); - RNA_def_property_float_sdna(prop, NULL, "shad_alpha"); - RNA_def_property_range(prop, 0.001, 1); - RNA_def_property_ui_text(prop, "Shadow Casting Alpha", - "Shadow casting alpha, in use for Irregular and Deep shadow buffer"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "light_group", PROP_POINTER, PROP_NONE); - RNA_def_property_pointer_sdna(prop, NULL, "group"); - RNA_def_property_struct_type(prop, "Group"); - RNA_def_property_flag(prop, PROP_EDITABLE); - RNA_def_property_ui_text(prop, "Light Group", "Limit lighting to lamps in this Group"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "edit_image", PROP_POINTER, PROP_NONE); - RNA_def_property_pointer_sdna(prop, NULL, "edit_image"); - RNA_def_property_struct_type(prop, "Image"); - RNA_def_property_flag(prop, PROP_EDITABLE); - RNA_def_property_ui_text(prop, "Edit Image", "Image to use for UV-mapping"); - prop = RNA_def_property(srna, "pass_index", PROP_INT, PROP_UNSIGNED); RNA_def_property_int_sdna(prop, NULL, "index"); RNA_def_property_ui_text(prop, "Pass Index", "Index number for the \"Material Index\" render pass"); RNA_def_property_update(prop, NC_OBJECT, "rna_Material_update"); - /* flags */ - - prop = RNA_def_property(srna, "use_light_group_exclusive", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_GROUP_NOLAY); - RNA_def_property_ui_text(prop, "Light Group Exclusive", - "Material uses the light group exclusively - these lamps are excluded " - "from other scene lighting"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "use_light_group_local", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "shade_flag", MA_GROUP_LOCAL); - RNA_def_property_ui_text(prop, "Light Group Local", "When linked in, material uses local light group with the same name"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "use_raytrace", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_TRACEBLE); - RNA_def_property_ui_text(prop, "Traceable", - "Include this material and geometry that uses it in raytracing calculations"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "use_shadows", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_SHADOW); - RNA_def_property_ui_text(prop, "Shadows", "Allow this material to receive shadows"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "use_shadeless", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_SHLESS); - RNA_def_property_ui_text(prop, "Shadeless", "Make this material insensitive to light or shadow"); - RNA_def_property_update(prop, 0, "rna_Material_draw_update"); - - prop = RNA_def_property(srna, "use_vertex_color_light", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_VERTEXCOL); - RNA_def_property_ui_text(prop, "Vertex Color Light", "Add vertex colors as additional lighting"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "use_vertex_color_paint", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_VERTEXCOLP); - RNA_def_property_ui_text(prop, "Vertex Color Paint", - "Replace object base color with vertex colors (multiply with " - "'texture face' face assigned textures)"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "invert_z", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_ZINV); - RNA_def_property_ui_text(prop, "Invert Z Depth", - "Render material's faces with an inverted Z buffer (scanline only)"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "offset_z", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "zoffs"); - RNA_def_property_ui_text(prop, "Z Offset", "Give faces an artificial offset in the Z buffer for Z transparency"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "use_sky", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_ENV); - RNA_def_property_ui_text(prop, "Sky", - "Render this material with zero alpha, with sky background in place (scanline only)"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "use_only_shadow", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_ONLYSHADOW); - RNA_def_property_ui_text(prop, "Only Shadow", - "Render shadows as the material's alpha value, making the material " - "transparent except for shadowed areas"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "shadow_only_type", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_bitflag_sdna(prop, NULL, "shadowonly_flag"); - RNA_def_property_enum_items(prop, prop_shadows_only_items); - RNA_def_property_ui_text(prop, "Shadow Type", "How to draw shadows"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "use_cast_shadows", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mode2", MA_CASTSHADOW); - RNA_def_property_ui_text(prop, "Cast Shadows", - "Allow this material to cast shadows"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "use_cast_shadows_only", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_ONLYCAST); - RNA_def_property_ui_text(prop, "Cast Shadows Only", - "Make objects with this material appear invisible (not rendered), only casting shadows"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "use_mist", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_negative_sdna(prop, NULL, "mode", MA_NOMIST); - RNA_def_property_ui_text(prop, "Use Mist", "Use mist with this material (in world settings)"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "use_transparent_shadows", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_SHADOW_TRA); - RNA_def_property_ui_text(prop, "Receive Transparent Shadows", - "Allow this object to receive transparent shadows cast through other objects"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "use_ray_shadow_bias", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_RAYBIAS); - RNA_def_property_ui_text(prop, "Ray Shadow Bias", - "Prevent raytraced shadow errors on surfaces with smooth shaded normals " - "(terminator problem)"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "use_full_oversampling", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_FULL_OSA); - RNA_def_property_ui_text(prop, "Full Oversampling", - "Force this material to render full shading/textures for all anti-aliasing samples"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "use_cast_buffer_shadows", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_SHADBUF); - RNA_def_property_ui_text(prop, "Cast Buffer Shadows", - "Allow this material to cast shadows from shadow buffer lamps"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "use_cast_approximate", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "shade_flag", MA_APPROX_OCCLUSION); - RNA_def_property_ui_text(prop, "Cast Approximate", - "Allow this material to cast shadows when using approximate ambient occlusion"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "use_tangent_shading", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_TANGENT_V); - RNA_def_property_ui_text(prop, "Tangent Shading", - "Use the material's tangent vector instead of the normal for shading " - "- for anisotropic shading effects"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "use_uv_project", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mapflag", MA_MAPFLAG_UVPROJECT); - RNA_def_property_ui_text(prop, "UV Project", - "Use to ensure UV interpolation is correct for camera projections (use with UV project modifier)"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - /* nested structs */ prop = RNA_def_property(srna, "raytrace_mirror", PROP_POINTER, PROP_NONE); RNA_def_property_flag(prop, PROP_NEVER_NULL); @@ -2010,36 +419,6 @@ void RNA_def_material(BlenderRNA *brna) RNA_def_property_pointer_funcs(prop, "rna_Material_mirror_get", NULL, NULL, NULL); RNA_def_property_ui_text(prop, "Raytrace Mirror", "Raytraced reflection settings for the material"); - prop = RNA_def_property(srna, "raytrace_transparency", PROP_POINTER, PROP_NONE); - RNA_def_property_flag(prop, PROP_NEVER_NULL); - RNA_def_property_struct_type(prop, "MaterialRaytraceTransparency"); - RNA_def_property_pointer_funcs(prop, "rna_Material_transp_get", NULL, NULL, NULL); - RNA_def_property_ui_text(prop, "Raytrace Transparency", "Raytraced transparency settings for the material"); - - prop = RNA_def_property(srna, "volume", PROP_POINTER, PROP_NONE); - RNA_def_property_flag(prop, PROP_NEVER_NULL); - RNA_def_property_pointer_sdna(prop, NULL, "vol"); - RNA_def_property_struct_type(prop, "MaterialVolume"); - RNA_def_property_ui_text(prop, "Volume", "Volume settings for the material"); - - prop = RNA_def_property(srna, "halo", PROP_POINTER, PROP_NONE); - RNA_def_property_flag(prop, PROP_NEVER_NULL); - RNA_def_property_struct_type(prop, "MaterialHalo"); - RNA_def_property_pointer_funcs(prop, "rna_Material_halo_get", NULL, NULL, NULL); - RNA_def_property_ui_text(prop, "Halo", "Halo settings for the material"); - - prop = RNA_def_property(srna, "subsurface_scattering", PROP_POINTER, PROP_NONE); - RNA_def_property_flag(prop, PROP_NEVER_NULL); - RNA_def_property_struct_type(prop, "MaterialSubsurfaceScattering"); - RNA_def_property_pointer_funcs(prop, "rna_Material_sss_get", NULL, NULL, NULL); - RNA_def_property_ui_text(prop, "Subsurface Scattering", "Subsurface scattering settings for the material"); - - prop = RNA_def_property(srna, "strand", PROP_POINTER, PROP_NONE); - RNA_def_property_flag(prop, PROP_NEVER_NULL); - RNA_def_property_struct_type(prop, "MaterialStrand"); - RNA_def_property_pointer_funcs(prop, "rna_Material_strand_get", NULL, NULL, NULL); - RNA_def_property_ui_text(prop, "Strand", "Strand settings for the material"); - /* nodetree */ prop = RNA_def_property(srna, "node_tree", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "nodetree"); @@ -2052,41 +431,12 @@ void RNA_def_material(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Use Nodes", "Use shader nodes to render the material"); RNA_def_property_update(prop, 0, "rna_Material_use_nodes_update"); - prop = RNA_def_property(srna, "active_node_material", PROP_POINTER, PROP_NONE); - RNA_def_property_struct_type(prop, "Material"); - RNA_def_property_flag(prop, PROP_EDITABLE); - RNA_def_property_pointer_funcs(prop, "rna_Material_active_node_material_get", - "rna_Material_active_node_material_set", NULL, NULL); - RNA_def_property_ui_text(prop, "Material", "Active node material"); - RNA_def_property_update(prop, NC_MATERIAL, NULL); - /* common */ rna_def_animdata_common(srna); - rna_def_mtex_common(brna, srna, "rna_Material_mtex_begin", "rna_Material_active_texture_get", - "rna_Material_active_texture_set", "rna_Material_active_texture_editable", - "MaterialTextureSlot", "MaterialTextureSlots", "rna_Material_update", "rna_Material_update"); - rna_def_texpaint_slots(brna, srna); - /* only material has this one */ - prop = RNA_def_property(srna, "use_textures", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_negative_sdna(prop, NULL, "septex", 1); - RNA_def_property_array(prop, 18); - RNA_def_property_ui_text(prop, "Use Textures", "Enable/Disable each texture"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - rna_def_material_colors(srna); - rna_def_material_diffuse(srna); - rna_def_material_specularity(srna); - - /* nested structs */ rna_def_material_raymirror(brna); - rna_def_material_raytra(brna); - rna_def_material_volume(brna); - rna_def_material_halo(brna); - rna_def_material_sss(brna); - rna_def_material_mtex(brna); - rna_def_material_strand(brna); RNA_api_material(srna); } @@ -2169,9 +519,9 @@ static void rna_def_tex_slot(BlenderRNA *brna) RNA_def_property_ui_text(prop, "UV Map", "Name of UV map"); RNA_def_property_update(prop, NC_GEOM | ND_DATA, "rna_Material_update"); - prop = RNA_def_property(srna, "index", PROP_INT, PROP_NONE); + prop = RNA_def_property(srna, "valid", PROP_BOOLEAN, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_EDITABLE); - RNA_def_property_ui_text(prop, "Index", "Index of MTex slot in the material"); + RNA_def_property_ui_text(prop, "Valid", "Slot has a valid image and UV map"); } diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index 86f69606bb1..94e3359737b 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -2284,11 +2284,6 @@ static void rna_def_modifier_uvproject(BlenderRNA *brna) "rna_iterator_array_end", "rna_iterator_array_get", NULL, NULL, NULL, NULL); RNA_def_property_ui_text(prop, "Projectors", ""); - prop = RNA_def_property(srna, "image", PROP_POINTER, PROP_NONE); - RNA_def_property_ui_text(prop, "Image", ""); - RNA_def_property_flag(prop, PROP_EDITABLE); - RNA_def_property_update(prop, 0, "rna_Modifier_update"); - prop = RNA_def_property(srna, "aspect_x", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "aspectx"); RNA_def_property_flag(prop, PROP_PROPORTIONAL); diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 40c36b9bd44..79a1ce73071 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -2339,14 +2339,6 @@ static void rna_NodeSocketStandard_value_update(struct bContext *C, PointerRNA * /* fall back to searching node in the tree */ nodeFindNode(ntree, sock, &node, NULL); } - - if (node) { - nodeSynchronizeID(node, true); - - /* extra update for sockets that get synced to material */ - if (node->id && ELEM(node->type, SH_NODE_MATERIAL, SH_NODE_MATERIAL_EXT)) - WM_main_add_notifier(NC_MATERIAL | ND_SHADING_DRAW, node->id); - } } @@ -2502,17 +2494,6 @@ static void rna_Node_tex_image_update(Main *bmain, Scene *UNUSED(scene), Pointer WM_main_add_notifier(NC_IMAGE, NULL); } -static void rna_Node_material_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr) -{ - bNodeTree *ntree = (bNodeTree *)ptr->id.data; - bNode *node = (bNode *)ptr->data; - - if (node->id) - nodeSetActive(ntree, node); - - ED_node_tag_update_nodetree(bmain, ntree, node); -} - static void rna_NodeGroup_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr) { bNodeTree *ntree = (bNodeTree *)ptr->id.data; @@ -3548,33 +3529,6 @@ static void def_sh_output_linestyle(StructRNA *srna) def_mix_rgb(srna); } -static void def_sh_material(StructRNA *srna) -{ - PropertyRNA *prop; - - prop = RNA_def_property(srna, "material", PROP_POINTER, PROP_NONE); - RNA_def_property_pointer_sdna(prop, NULL, "id"); - RNA_def_property_struct_type(prop, "Material"); - RNA_def_property_flag(prop, PROP_EDITABLE); - RNA_def_property_ui_text(prop, "Material", ""); - RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_material_update"); - - prop = RNA_def_property(srna, "use_diffuse", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "custom1", SH_NODE_MAT_DIFF); - RNA_def_property_ui_text(prop, "Diffuse", "Material Node outputs Diffuse"); - RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); - - prop = RNA_def_property(srna, "use_specular", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "custom1", SH_NODE_MAT_SPEC); - RNA_def_property_ui_text(prop, "Specular", "Material Node outputs Specular"); - RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); - - prop = RNA_def_property(srna, "invert_normal", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "custom1", SH_NODE_MAT_NEG); - RNA_def_property_ui_text(prop, "Invert Normal", "Material Node uses inverted normal"); - RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); -} - static void def_sh_mapping(StructRNA *srna) { static const EnumPropertyItem prop_vect_type_items[] = { @@ -3637,36 +3591,6 @@ static void def_sh_mapping(StructRNA *srna) RNA_def_property_update(prop, 0, "rna_Mapping_Node_update"); } -static void def_sh_geometry(StructRNA *srna) -{ - PropertyRNA *prop; - - RNA_def_struct_sdna_from(srna, "NodeGeometry", "storage"); - - prop = RNA_def_property(srna, "uv_layer", PROP_STRING, PROP_NONE); - RNA_def_property_string_sdna(prop, NULL, "uvname"); - RNA_def_property_ui_text(prop, "UV Map", ""); - RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); - - prop = RNA_def_property(srna, "color_layer", PROP_STRING, PROP_NONE); - RNA_def_property_string_sdna(prop, NULL, "colname"); - RNA_def_property_ui_text(prop, "Vertex Color Layer", ""); - RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); -} - -static void def_sh_lamp(StructRNA *srna) -{ - PropertyRNA *prop; - - prop = RNA_def_property(srna, "lamp_object", PROP_POINTER, PROP_NONE); - RNA_def_property_pointer_sdna(prop, NULL, "id"); - RNA_def_property_struct_type(prop, "Object"); - RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT); - RNA_def_property_pointer_funcs(prop, NULL, NULL, NULL, "rna_Lamp_object_poll"); - RNA_def_property_ui_text(prop, "Lamp Object", ""); - RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); -} - static void def_sh_attribute(StructRNA *srna) { PropertyRNA *prop; diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 339465d1ac0..069e103c5e4 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -1046,17 +1046,6 @@ static int rna_RenderSettings_is_movie_format_get(PointerRNA *ptr) return BKE_imtype_is_movie(rd->im_format.imtype); } -static int rna_RenderSettings_save_buffers_get(PointerRNA *ptr) -{ - RenderData *rd = (RenderData *)ptr->data; - Scene *scene = (Scene *)ptr->id.data; - - if (!BKE_scene_use_new_shading_nodes(scene)) - return (rd->scemode & (R_EXR_TILE_FILE | R_FULL_SAMPLE)) != 0; - else - return (rd->scemode & R_EXR_TILE_FILE) != 0; -} - static void rna_ImageFormatSettings_file_format_set(PointerRNA *ptr, int value) { ImageFormatData *imf = (ImageFormatData *)ptr->data; @@ -1448,12 +1437,6 @@ static int rna_RenderSettings_multiple_engines_get(PointerRNA *UNUSED(ptr)) return (BLI_listbase_count(&R_engines) > 1); } -static int rna_RenderSettings_use_shading_nodes_get(PointerRNA *ptr) -{ - Scene *scene = (Scene *)ptr->id.data; - return BKE_scene_use_new_shading_nodes(scene); -} - static int rna_RenderSettings_use_spherical_stereo_get(PointerRNA *ptr) { Scene *scene = (Scene *)ptr->id.data; @@ -3462,18 +3445,6 @@ void rna_def_view_layer_common(StructRNA *srna, int scene) if (scene) RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_ViewLayer_pass_update"); else RNA_def_property_clear_flag(prop, PROP_EDITABLE); - prop = RNA_def_property(srna, "use_pass_color", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "passflag", SCE_PASS_RGBA); - RNA_def_property_ui_text(prop, "Color", "Deliver shade-less color pass"); - if (scene) RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_ViewLayer_pass_update"); - else RNA_def_property_clear_flag(prop, PROP_EDITABLE); - - prop = RNA_def_property(srna, "use_pass_diffuse", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "passflag", SCE_PASS_DIFFUSE); - RNA_def_property_ui_text(prop, "Diffuse", "Deliver diffuse pass"); - if (scene) RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_ViewLayer_pass_update"); - else RNA_def_property_clear_flag(prop, PROP_EDITABLE); - prop = RNA_def_property(srna, "use_pass_specular", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "passflag", SCE_PASS_SPEC); RNA_def_property_ui_text(prop, "Specular", "Deliver specular pass"); @@ -3492,18 +3463,6 @@ void rna_def_view_layer_common(StructRNA *srna, int scene) if (scene) RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_ViewLayer_pass_update"); else RNA_def_property_clear_flag(prop, PROP_EDITABLE); - prop = RNA_def_property(srna, "use_pass_reflection", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "passflag", SCE_PASS_REFLECT); - RNA_def_property_ui_text(prop, "Reflection", "Deliver raytraced reflection pass"); - if (scene) RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_ViewLayer_pass_update"); - else RNA_def_property_clear_flag(prop, PROP_EDITABLE); - - prop = RNA_def_property(srna, "use_pass_refraction", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "passflag", SCE_PASS_REFRACT); - RNA_def_property_ui_text(prop, "Refraction", "Deliver raytraced refraction pass"); - if (scene) RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_ViewLayer_pass_update"); - else RNA_def_property_clear_flag(prop, PROP_EDITABLE); - prop = RNA_def_property(srna, "use_pass_emit", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "passflag", SCE_PASS_EMIT); RNA_def_property_ui_text(prop, "Emit", "Deliver emission pass"); @@ -3522,62 +3481,6 @@ void rna_def_view_layer_common(StructRNA *srna, int scene) if (scene) RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_ViewLayer_pass_update"); else RNA_def_property_clear_flag(prop, PROP_EDITABLE); - prop = RNA_def_property(srna, "exclude_specular", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "pass_xor", SCE_PASS_SPEC); - RNA_def_property_ui_text(prop, "Specular Exclude", "Exclude specular pass from combined"); - RNA_def_property_ui_icon(prop, ICON_RESTRICT_RENDER_OFF, 1); - if (scene) RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_ViewLayer_pass_update"); - else RNA_def_property_clear_flag(prop, PROP_EDITABLE); - - prop = RNA_def_property(srna, "exclude_shadow", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "pass_xor", SCE_PASS_SHADOW); - RNA_def_property_ui_text(prop, "Shadow Exclude", "Exclude shadow pass from combined"); - RNA_def_property_ui_icon(prop, ICON_RESTRICT_RENDER_OFF, 1); - if (scene) RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_ViewLayer_pass_update"); - else RNA_def_property_clear_flag(prop, PROP_EDITABLE); - - prop = RNA_def_property(srna, "exclude_ambient_occlusion", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "pass_xor", SCE_PASS_AO); - RNA_def_property_ui_text(prop, "AO Exclude", "Exclude AO pass from combined"); - RNA_def_property_ui_icon(prop, ICON_RESTRICT_RENDER_OFF, 1); - if (scene) RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_ViewLayer_pass_update"); - else RNA_def_property_clear_flag(prop, PROP_EDITABLE); - - prop = RNA_def_property(srna, "exclude_reflection", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "pass_xor", SCE_PASS_REFLECT); - RNA_def_property_ui_text(prop, "Reflection Exclude", "Exclude raytraced reflection pass from combined"); - RNA_def_property_ui_icon(prop, ICON_RESTRICT_RENDER_OFF, 1); - if (scene) RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_ViewLayer_pass_update"); - else RNA_def_property_clear_flag(prop, PROP_EDITABLE); - - prop = RNA_def_property(srna, "exclude_refraction", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "pass_xor", SCE_PASS_REFRACT); - RNA_def_property_ui_text(prop, "Refraction Exclude", "Exclude raytraced refraction pass from combined"); - RNA_def_property_ui_icon(prop, ICON_RESTRICT_RENDER_OFF, 1); - if (scene) RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_ViewLayer_pass_update"); - else RNA_def_property_clear_flag(prop, PROP_EDITABLE); - - prop = RNA_def_property(srna, "exclude_emit", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "pass_xor", SCE_PASS_EMIT); - RNA_def_property_ui_text(prop, "Emit Exclude", "Exclude emission pass from combined"); - RNA_def_property_ui_icon(prop, ICON_RESTRICT_RENDER_OFF, 1); - if (scene) RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_ViewLayer_pass_update"); - else RNA_def_property_clear_flag(prop, PROP_EDITABLE); - - prop = RNA_def_property(srna, "exclude_environment", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "pass_xor", SCE_PASS_ENVIRONMENT); - RNA_def_property_ui_text(prop, "Environment Exclude", "Exclude environment pass from combined"); - RNA_def_property_ui_icon(prop, ICON_RESTRICT_RENDER_OFF, 1); - if (scene) RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_ViewLayer_pass_update"); - else RNA_def_property_clear_flag(prop, PROP_EDITABLE); - - prop = RNA_def_property(srna, "exclude_indirect", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "pass_xor", SCE_PASS_INDIRECT); - RNA_def_property_ui_text(prop, "Indirect Exclude", "Exclude indirect pass from combined"); - RNA_def_property_ui_icon(prop, ICON_RESTRICT_RENDER_OFF, 1); - if (scene) RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_ViewLayer_pass_update"); - else RNA_def_property_clear_flag(prop, PROP_EDITABLE); - prop = RNA_def_property(srna, "use_pass_diffuse_direct", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "passflag", SCE_PASS_DIFFUSE_DIRECT); RNA_def_property_ui_text(prop, "Diffuse Direct", "Deliver diffuse direct pass"); @@ -4993,17 +4896,6 @@ static void rna_def_scene_render_data(BlenderRNA *brna) StructRNA *srna; PropertyRNA *prop; - static const EnumPropertyItem pixel_filter_items[] = { - {R_FILTER_BOX, "BOX", 0, "Box", "Use a box filter for anti-aliasing"}, - {R_FILTER_TENT, "TENT", 0, "Tent", "Use a tent filter for anti-aliasing"}, - {R_FILTER_QUAD, "QUADRATIC", 0, "Quadratic", "Use a quadratic filter for anti-aliasing"}, - {R_FILTER_CUBIC, "CUBIC", 0, "Cubic", "Use a cubic filter for anti-aliasing"}, - {R_FILTER_CATROM, "CATMULLROM", 0, "Catmull-Rom", "Use a Catmull-Rom filter for anti-aliasing"}, - {R_FILTER_GAUSS, "GAUSSIAN", 0, "Gaussian", "Use a Gaussian filter for anti-aliasing"}, - {R_FILTER_MITCH, "MITCHELL", 0, "Mitchell-Netravali", "Use a Mitchell-Netravali filter for anti-aliasing"}, - {0, NULL, 0, NULL, NULL} - }; - static const EnumPropertyItem alpha_mode_items[] = { {R_ADDSKY, "SKY", 0, "Sky", "Transparent pixels are filled with sky color"}, {R_ALPHAPREMUL, "TRANSPARENT", 0, "Transparent", "World background is transparent with premultiplied alpha"}, @@ -5017,41 +4909,15 @@ static void rna_def_scene_render_data(BlenderRNA *brna) {R_OUTPUT_NONE, "NONE", 0, "Keep UI", "Images are rendered without forcing UI changes"}, {0, NULL, 0, NULL, NULL} }; - + /* Bake */ static const EnumPropertyItem bake_mode_items[] = { - {RE_BAKE_ALL, "FULL", 0, "Full Render", "Bake everything"}, - {RE_BAKE_AO, "AO", 0, "Ambient Occlusion", "Bake ambient occlusion"}, - {RE_BAKE_SHADOW, "SHADOW", 0, "Shadow", "Bake shadows"}, + //{RE_BAKE_AO, "AO", 0, "Ambient Occlusion", "Bake ambient occlusion"}, {RE_BAKE_NORMALS, "NORMALS", 0, "Normals", "Bake normals"}, - {RE_BAKE_TEXTURE, "TEXTURE", 0, "Textures", "Bake textures"}, {RE_BAKE_DISPLACEMENT, "DISPLACEMENT", 0, "Displacement", "Bake displacement"}, - {RE_BAKE_DERIVATIVE, "DERIVATIVE", 0, "Derivative", "Bake derivative map"}, - {RE_BAKE_VERTEX_COLORS, "VERTEX_COLORS", 0, "Vertex Colors", "Bake vertex colors"}, - {RE_BAKE_EMIT, "EMIT", 0, "Emission", "Bake Emit values (glow)"}, - {RE_BAKE_ALPHA, "ALPHA", 0, "Alpha", "Bake Alpha values (transparency)"}, - {RE_BAKE_MIRROR_INTENSITY, "MIRROR_INTENSITY", 0, "Mirror Intensity", "Bake Mirror values"}, - {RE_BAKE_MIRROR_COLOR, "MIRROR_COLOR", 0, "Mirror Colors", "Bake Mirror colors"}, - {RE_BAKE_SPEC_INTENSITY, "SPEC_INTENSITY", 0, "Specular Intensity", "Bake Specular values"}, - {RE_BAKE_SPEC_COLOR, "SPEC_COLOR", 0, "Specular Colors", "Bake Specular colors"}, {0, NULL, 0, NULL, NULL} }; - static const EnumPropertyItem bake_normal_space_items[] = { - {R_BAKE_SPACE_CAMERA, "CAMERA", 0, "Camera", "Bake the normals in camera space"}, - {R_BAKE_SPACE_WORLD, "WORLD", 0, "World", "Bake the normals in world space"}, - {R_BAKE_SPACE_OBJECT, "OBJECT", 0, "Object", "Bake the normals in object space"}, - {R_BAKE_SPACE_TANGENT, "TANGENT", 0, "Tangent", "Bake the normals in tangent space"}, - {0, NULL, 0, NULL, NULL} - }; - - static const EnumPropertyItem bake_qyad_split_items[] = { - {0, "AUTO", 0, "Automatic", "Split quads to give the least distortion while baking"}, - {1, "FIXED", 0, "Fixed", "Split quads predictably (0,1,2) (0,2,3)"}, - {2, "FIXED_ALT", 0, "Fixed Alternate", "Split quads predictably (1,2,3) (1,3,0)"}, - {0, NULL, 0, NULL, NULL} - }; - static const EnumPropertyItem pixel_size_items[] = { {0, "AUTO", 0, "Automatic", "Automatic pixel size, depends on the UI scale"}, {1, "1", 0, "1x", "Render at full resolution"}, @@ -5061,23 +4927,6 @@ static void rna_def_scene_render_data(BlenderRNA *brna) {0, NULL, 0, NULL, NULL} }; - static const EnumPropertyItem octree_resolution_items[] = { - {64, "64", 0, "64", ""}, - {128, "128", 0, "128", ""}, - {256, "256", 0, "256", ""}, - {512, "512", 0, "512", ""}, - {0, NULL, 0, NULL, NULL} - }; - - static const EnumPropertyItem raytrace_structure_items[] = { - {R_RAYSTRUCTURE_AUTO, "AUTO", 0, "Auto", "Automatically select acceleration structure"}, - {R_RAYSTRUCTURE_OCTREE, "OCTREE", 0, "Octree", "Use old Octree structure"}, - {R_RAYSTRUCTURE_VBVH, "VBVH", 0, "vBVH", "Use vBVH"}, - {R_RAYSTRUCTURE_SIMD_SVBVH, "SIMD_SVBVH", 0, "SIMD SVBVH", "Use SIMD SVBVH"}, - {R_RAYSTRUCTURE_SIMD_QBVH, "SIMD_QBVH", 0, "SIMD QBVH", "Use SIMD QBVH"}, - {0, NULL, 0, NULL, NULL} - }; - static const EnumPropertyItem fixed_oversample_items[] = { {5, "5", 0, "5", ""}, {8, "8", 0, "8", ""}, @@ -5085,13 +4934,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna) {16, "16", 0, "16", ""}, {0, NULL, 0, NULL, NULL} }; - - static const EnumPropertyItem field_order_items[] = { - {0, "EVEN_FIRST", 0, "Upper First", "Upper field first"}, - {R_ODDFIELD, "ODD_FIRST", 0, "Lower First", "Lower field first"}, - {0, NULL, 0, NULL, NULL} - }; - + static const EnumPropertyItem threads_mode_items[] = { {0, "AUTO", 0, "Auto-detect", "Automatically determine the number of threads, based on CPUs"}, {R_FIXED_THREADS, "FIXED", 0, "Fixed", "Manually determine the number of threads"}, @@ -5250,50 +5093,11 @@ static void rna_def_scene_render_data(BlenderRNA *brna) "Amount of dithering noise added to the rendered image to break up banding"); RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); - prop = RNA_def_property(srna, "pixel_filter_type", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "filtertype"); - RNA_def_property_enum_items(prop, pixel_filter_items); - RNA_def_property_ui_text(prop, "Pixel Filter", "Reconstruction filter used for combining anti-aliasing samples"); - RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); - - prop = RNA_def_property(srna, "filter_size", PROP_FLOAT, PROP_PIXEL); - RNA_def_property_float_sdna(prop, NULL, "gauss"); - RNA_def_property_range(prop, 0.0f, 500.0f); - RNA_def_property_ui_range(prop, 0.01f, 10.0f, 1, 2); - RNA_def_property_ui_text(prop, "Filter Size", "Width over which the reconstruction filter combines samples"); - RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); - prop = RNA_def_property(srna, "alpha_mode", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "alphamode"); RNA_def_property_enum_items(prop, alpha_mode_items); RNA_def_property_ui_text(prop, "Alpha Mode", "Representation of alpha information in the RGBA pixels"); RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_glsl_update"); - - prop = RNA_def_property(srna, "octree_resolution", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "ocres"); - RNA_def_property_enum_items(prop, octree_resolution_items); - RNA_def_property_ui_text(prop, "Octree Resolution", - "Resolution of raytrace accelerator, use higher resolutions for larger scenes"); - RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); - - prop = RNA_def_property(srna, "raytrace_method", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "raytrace_structure"); - RNA_def_property_enum_items(prop, raytrace_structure_items); - RNA_def_property_ui_text(prop, "Raytrace Acceleration Structure", "Type of raytrace accelerator structure"); - RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); - - prop = RNA_def_property(srna, "use_instances", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "raytrace_options", R_RAYTRACE_USE_INSTANCES); - RNA_def_property_ui_text(prop, "Use Instances", - "Instance support leads to effective memory reduction when using duplicates"); - RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); - - prop = RNA_def_property(srna, "use_local_coords", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "raytrace_options", R_RAYTRACE_USE_LOCAL_COORDS); - RNA_def_property_ui_text(prop, "Use Local Coords", - "Vertex coordinates are stored locally on each primitive " - "(increases memory usage, but may have impact on speed)"); - RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); prop = RNA_def_property(srna, "use_antialiasing", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "mode", R_OSA); @@ -5306,73 +5110,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna) RNA_def_property_enum_items(prop, fixed_oversample_items); RNA_def_property_ui_text(prop, "Anti-Aliasing Samples", "Amount of anti-aliasing samples per pixel"); RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); - - prop = RNA_def_property(srna, "use_fields", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mode", R_FIELDS); - RNA_def_property_ui_text(prop, "Fields", "Render image to two fields per frame, for interlaced TV output"); - RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); - - prop = RNA_def_property(srna, "field_order", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_bitflag_sdna(prop, NULL, "mode"); - RNA_def_property_enum_items(prop, field_order_items); - RNA_def_property_ui_text(prop, "Field Order", - "Order of video fields (select which lines get rendered first, " - "to create smooth motion for TV output)"); - RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); - - prop = RNA_def_property(srna, "use_fields_still", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mode", R_FIELDSTILL); - RNA_def_property_ui_text(prop, "Fields Still", "Disable the time difference between fields"); - RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); - - /* rendering features */ - prop = RNA_def_property(srna, "use_shadows", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mode", R_SHADOW); - RNA_def_property_ui_text(prop, "Shadows", "Calculate shadows while rendering"); - RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_glsl_update"); - - prop = RNA_def_property(srna, "use_envmaps", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mode", R_ENVMAP); - RNA_def_property_ui_text(prop, "Environment Maps", "Calculate environment maps while rendering"); - RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_glsl_update"); - - prop = RNA_def_property(srna, "use_sss", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mode", R_SSS); - RNA_def_property_ui_text(prop, "Subsurface Scattering", "Calculate sub-surface scattering in materials rendering"); - RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_glsl_update"); - prop = RNA_def_property(srna, "use_world_space_shading", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mode", R_USE_WS_SHADING); - RNA_def_property_ui_text(prop, "World Space Shading", "Use world space interpretation of lighting data for node materials"); - RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_glsl_update"); - - prop = RNA_def_property(srna, "use_raytrace", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mode", R_RAYTRACE); - RNA_def_property_ui_text(prop, "Raytracing", - "Pre-calculate the raytrace accelerator and render raytracing effects"); - RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_glsl_update"); - - prop = RNA_def_property(srna, "use_textures", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_negative_sdna(prop, NULL, "scemode", R_NO_TEX); - RNA_def_property_ui_text(prop, "Textures", "Use textures to affect material properties"); - RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_glsl_update"); - - prop = RNA_def_property(srna, "use_edge_enhance", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mode", R_EDGE); - RNA_def_property_ui_text(prop, "Edge", "Create a toon outline around the edges of geometry"); - RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_glsl_update"); - - prop = RNA_def_property(srna, "edge_threshold", PROP_INT, PROP_NONE); - RNA_def_property_int_sdna(prop, NULL, "edgeint"); - RNA_def_property_range(prop, 0, 255); - RNA_def_property_ui_text(prop, "Edge Threshold", "Threshold for drawing outlines on geometry edges"); - RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_glsl_update"); - - prop = RNA_def_property(srna, "edge_color", PROP_FLOAT, PROP_COLOR); - RNA_def_property_float_sdna(prop, NULL, "edgeR"); - RNA_def_property_array(prop, 3); - RNA_def_property_ui_text(prop, "Edge Color", "Edge color"); - RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_glsl_update"); prop = RNA_def_property(srna, "use_freestyle", PROP_BOOLEAN, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); @@ -5404,13 +5142,6 @@ static void rna_def_scene_render_data(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_glsl_update"); - prop = RNA_def_property(srna, "motion_blur_samples", PROP_INT, PROP_NONE); - RNA_def_property_int_sdna(prop, NULL, "mblur_samples"); - RNA_def_property_range(prop, 1, 32); - RNA_def_property_ui_text(prop, "Motion Samples", "Number of scene samples to take with motion blur"); - RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_glsl_update"); - prop = RNA_def_property(srna, "motion_blur_shutter", PROP_FLOAT, PROP_UNSIGNED); RNA_def_property_float_sdna(prop, NULL, "blurfac"); RNA_def_property_ui_range(prop, 0.01f, 2.0f, 1, 2); @@ -5427,12 +5158,8 @@ static void rna_def_scene_render_data(BlenderRNA *brna) prop = RNA_def_property(srna, "use_border", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "mode", R_BORDER); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_ui_text(prop, "Border", - "Render a user-defined border region, within the frame size " - "(note that this disables save_buffers and full_sample)"); + RNA_def_property_ui_text(prop, "Border", "Render a user-defined border region, within the frame size "); RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); - - prop = RNA_def_property(srna, "border_min_x", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "border.xmin"); @@ -5520,15 +5247,8 @@ static void rna_def_scene_render_data(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Movie Format", "When true the format is a movie"); - prop = RNA_def_property(srna, "use_free_image_textures", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "scemode", R_FREE_IMAGE); - RNA_def_property_ui_text(prop, "Free Image Textures", - "Free all image textures from memory after render, to save memory before compositing"); - RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); - prop = RNA_def_property(srna, "use_save_buffers", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "scemode", R_EXR_TILE_FILE); - RNA_def_property_boolean_funcs(prop, "rna_RenderSettings_save_buffers_get", NULL); RNA_def_property_ui_text(prop, "Save Buffers", "Save tiles for all RenderLayers and SceneNodes to files in the temp directory " "(saves memory, required for Full Sample)"); @@ -5576,46 +5296,17 @@ static void rna_def_scene_render_data(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Bake Mode", "Choose shading information to bake into the image"); RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); - prop = RNA_def_property(srna, "bake_normal_space", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_bitflag_sdna(prop, NULL, "bake_normal_space"); - RNA_def_property_enum_items(prop, bake_normal_space_items); - RNA_def_property_ui_text(prop, "Normal Space", "Choose normal space for baking"); - RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); - - prop = RNA_def_property(srna, "bake_quad_split", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_items(prop, bake_qyad_split_items); - RNA_def_property_ui_text(prop, "Quad Split", "Choose the method used to split a quad into 2 triangles for baking"); - RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); - - prop = RNA_def_property(srna, "bake_aa_mode", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_bitflag_sdna(prop, NULL, "bake_osa"); - RNA_def_property_enum_items(prop, fixed_oversample_items); - RNA_def_property_ui_text(prop, "Anti-Aliasing Level", ""); - RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); - prop = RNA_def_property(srna, "use_bake_selected_to_active", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "bake_flag", R_BAKE_TO_ACTIVE); RNA_def_property_ui_text(prop, "Selected to Active", "Bake shading on the surface of selected objects to the active object"); RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); - prop = RNA_def_property(srna, "use_bake_normalize", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "bake_flag", R_BAKE_NORMALIZE); - RNA_def_property_ui_text(prop, "Normalized", - "With displacement normalize to the distance, with ambient occlusion " - "normalize without using material settings"); - RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); - prop = RNA_def_property(srna, "use_bake_clear", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "bake_flag", R_BAKE_CLEAR); RNA_def_property_ui_text(prop, "Clear", "Clear Images before baking"); RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); - prop = RNA_def_property(srna, "use_bake_antialiasing", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "bake_flag", R_BAKE_OSA); - RNA_def_property_ui_text(prop, "Anti-Aliasing", "Enables Anti-aliasing"); - RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); - prop = RNA_def_property(srna, "bake_margin", PROP_INT, PROP_PIXEL); RNA_def_property_int_sdna(prop, NULL, "bake_filter"); RNA_def_property_range(prop, 0, 64); @@ -5623,13 +5314,6 @@ static void rna_def_scene_render_data(BlenderRNA *brna) "Extends the baked result as a post process filter"); RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); - prop = RNA_def_property(srna, "bake_distance", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "bake_maxdist"); - RNA_def_property_range(prop, 0.0, 1000.0); - RNA_def_property_ui_text(prop, "Distance", - "Maximum distance from active object to other object (in blender units)"); - RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); - prop = RNA_def_property(srna, "bake_bias", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "bake_biasdist"); RNA_def_property_range(prop, 0.0, 1000.0); @@ -5654,12 +5338,6 @@ static void rna_def_scene_render_data(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Samples", "Number of samples used for ambient occlusion baking from multires"); RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); - prop = RNA_def_property(srna, "use_bake_to_vertex_color", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "bake_flag", R_BAKE_VCOL); - RNA_def_property_ui_text(prop, "Bake to Vertex Color", - "Bake to vertex colors instead of to a UV-mapped image"); - RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); - prop = RNA_def_property(srna, "use_bake_user_scale", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "bake_flag", R_BAKE_USERSCALE); RNA_def_property_ui_text(prop, "User scale", "Use a user scale for the derivative map"); @@ -5858,11 +5536,6 @@ static void rna_def_scene_render_data(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Multiple Engines", "More than one rendering engine is available"); - prop = RNA_def_property(srna, "use_shading_nodes", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_funcs(prop, "rna_RenderSettings_use_shading_nodes_get", NULL); - RNA_def_property_clear_flag(prop, PROP_EDITABLE); - RNA_def_property_ui_text(prop, "Use Shading Nodes", "Active render engine uses new shading nodes system"); - prop = RNA_def_property(srna, "use_spherical_stereo", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_funcs(prop, "rna_RenderSettings_use_spherical_stereo_get", NULL); RNA_def_property_clear_flag(prop, PROP_EDITABLE); @@ -5896,21 +5569,6 @@ static void rna_def_scene_render_data(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Simplify Child Particles", "Global child particles percentage during rendering"); RNA_def_property_update(prop, 0, "rna_Scene_simplify_update"); - prop = RNA_def_property(srna, "simplify_shadow_samples", PROP_INT, PROP_UNSIGNED); - RNA_def_property_int_sdna(prop, NULL, "simplify_shadowsamples"); - RNA_def_property_ui_range(prop, 1, 16, 1, -1); - RNA_def_property_ui_text(prop, "Simplify Shadow Samples", "Global maximum shadow samples"); - RNA_def_property_update(prop, 0, "rna_Scene_simplify_update"); - - prop = RNA_def_property(srna, "simplify_ao_sss", PROP_FLOAT, PROP_FACTOR); - RNA_def_property_float_sdna(prop, NULL, "simplify_aosss"); - RNA_def_property_ui_text(prop, "Simplify AO and SSS", "Global approximate AO and SSS quality factor"); - RNA_def_property_update(prop, 0, "rna_Scene_simplify_update"); - - prop = RNA_def_property(srna, "use_simplify_triangulate", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "simplify_flag", R_SIMPLE_NO_TRIANGULATE); - RNA_def_property_ui_text(prop, "Skip Quad to Triangles", "Disable non-planar quads being triangulated"); - /* persistent data */ prop = RNA_def_property(srna, "use_persistent_data", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "mode", R_PERSISTENT_DATA); diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.c b/source/blender/makesrna/intern/rna_sculpt_paint.c index 49edc742a4b..03a728120eb 100644 --- a/source/blender/makesrna/intern/rna_sculpt_paint.c +++ b/source/blender/makesrna/intern/rna_sculpt_paint.c @@ -111,8 +111,6 @@ const EnumPropertyItem rna_enum_symmetrize_direction_items[] = { #include "DEG_depsgraph.h" -#include "GPU_buffers.h" - #include "ED_particle.h" static void rna_GPencil_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *UNUSED(ptr)) @@ -371,7 +369,6 @@ static void rna_ImaPaint_mode_update(bContext *C, PointerRNA *UNUSED(ptr)) BKE_texpaint_slots_refresh_object(scene, ob); /* we assume that changing the current mode will invalidate the uv layers so we need to refresh display */ - GPU_drawobject_free(ob->derivedFinal); BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL); WM_main_add_notifier(NC_OBJECT | ND_DRAW, NULL); } @@ -384,7 +381,6 @@ static void rna_ImaPaint_stencil_update(bContext *C, PointerRNA *UNUSED(ptr)) Object *ob = OBACT(view_layer); if (ob && ob->type == OB_MESH) { - GPU_drawobject_free(ob->derivedFinal); BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL); WM_main_add_notifier(NC_OBJECT | ND_DRAW, NULL); } @@ -416,7 +412,6 @@ static void rna_ImaPaint_canvas_update(bContext *C, PointerRNA *UNUSED(ptr)) } if (ob && ob->type == OB_MESH) { - GPU_drawobject_free(ob->derivedFinal); BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL); WM_main_add_notifier(NC_OBJECT | ND_DRAW, NULL); } diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 7d121f76016..01d7ba4d0a3 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -216,17 +216,6 @@ static const EnumPropertyItem buttons_context_items[] = { {0, NULL, 0, NULL, NULL} }; -/* Actually populated dynamically trough a function, but helps for context-less access (e.g. doc, i18n...). */ -static const EnumPropertyItem buttons_texture_context_items[] = { - {SB_TEXC_MATERIAL, "MATERIAL", ICON_MATERIAL, "", "Show material textures"}, - {SB_TEXC_WORLD, "WORLD", ICON_WORLD, "", "Show world textures"}, - {SB_TEXC_LAMP, "LAMP", ICON_LAMP, "", "Show lamp textures"}, - {SB_TEXC_PARTICLES, "PARTICLES", ICON_PARTICLES, "", "Show particles textures"}, - {SB_TEXC_LINESTYLE, "LINESTYLE", ICON_LINE_DATA, "", "Show linestyle textures"}, - {SB_TEXC_OTHER, "OTHER", ICON_TEXTURE, "", "Show other data textures"}, - {0, NULL, 0, NULL, NULL} -}; - static const EnumPropertyItem buttons_collection_context_items[] = { {SB_COLLECTION_CTX_VIEW_LAYER, "VIEW_LAYER", ICON_RENDERLAYERS, "", "Show material textures"}, {SB_COLLECTION_CTX_GROUP, "GROUP", ICON_GROUP, "", "Show world textures"}, @@ -1147,50 +1136,6 @@ static void rna_SpaceProperties_align_set(PointerRNA *ptr, int value) sbuts->re_align = 1; } -static const EnumPropertyItem *rna_SpaceProperties_texture_context_itemf( - bContext *C, PointerRNA *UNUSED(ptr), - PropertyRNA *UNUSED(prop), bool *r_free) -{ - EnumPropertyItem *item = NULL; - int totitem = 0; - - if (ED_texture_context_check_world(C)) { - RNA_enum_items_add_value(&item, &totitem, buttons_texture_context_items, SB_TEXC_WORLD); - } - - if (ED_texture_context_check_lamp(C)) { - RNA_enum_items_add_value(&item, &totitem, buttons_texture_context_items, SB_TEXC_LAMP); - } - else if (ED_texture_context_check_material(C)) { - RNA_enum_items_add_value(&item, &totitem, buttons_texture_context_items, SB_TEXC_MATERIAL); - } - - if (ED_texture_context_check_particles(C)) { - RNA_enum_items_add_value(&item, &totitem, buttons_texture_context_items, SB_TEXC_PARTICLES); - } - - if (ED_texture_context_check_linestyle(C)) { - RNA_enum_items_add_value(&item, &totitem, buttons_texture_context_items, SB_TEXC_LINESTYLE); - } - - if (ED_texture_context_check_others(C)) { - RNA_enum_items_add_value(&item, &totitem, buttons_texture_context_items, SB_TEXC_OTHER); - } - - RNA_enum_item_end(&item, &totitem); - *r_free = true; - - return item; -} - -static void rna_SpaceProperties_texture_context_set(PointerRNA *ptr, int value) -{ - SpaceButs *sbuts = (SpaceButs *)(ptr->data); - - /* User action, no need to keep "better" value in prev here! */ - sbuts->texture_context = sbuts->texture_context_prev = value; -} - /* Space Console */ static void rna_ConsoleLine_body_get(PointerRNA *ptr, char *value) { @@ -2773,18 +2718,6 @@ static void rna_def_space_buttons(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Align", "Arrangement of the panels"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_PROPERTIES, NULL); - prop = RNA_def_property(srna, "texture_context", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_items(prop, buttons_texture_context_items); - RNA_def_property_enum_funcs(prop, NULL, "rna_SpaceProperties_texture_context_set", - "rna_SpaceProperties_texture_context_itemf"); - RNA_def_property_ui_text(prop, "Texture Context", "Type of texture data to display and edit"); - RNA_def_property_update(prop, NC_TEXTURE, NULL); - - prop = RNA_def_property(srna, "use_limited_texture_context", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", SB_TEX_USER_LIMITED); - RNA_def_property_ui_text(prop, "Limited Texture Context", - "Use the limited version of texture user (for 'old shading' mode)"); - prop = RNA_def_property(srna, "collection_context", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, buttons_collection_context_items); RNA_def_property_ui_text(prop, "Collection Context", "Which collection we want to show"); @@ -4148,7 +4081,6 @@ static void rna_def_space_node(BlenderRNA *brna) PropertyRNA *prop; static const EnumPropertyItem texture_id_type_items[] = { - {SNODE_TEX_OBJECT, "OBJECT", ICON_OBJECT_DATA, "Object", "Edit texture nodes from Object"}, {SNODE_TEX_WORLD, "WORLD", ICON_WORLD_DATA, "World", "Edit texture nodes from World"}, {SNODE_TEX_BRUSH, "BRUSH", ICON_BRUSH_DATA, "Brush", "Edit texture nodes from Brush"}, #ifdef WITH_FREESTYLE diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c index 42e3e2c83fb..5449b67c040 100644 --- a/source/blender/makesrna/intern/rna_texture.c +++ b/source/blender/makesrna/intern/rna_texture.c @@ -67,19 +67,14 @@ const EnumPropertyItem rna_enum_texture_type_items[] = { {TEX_CLOUDS, "CLOUDS", ICON_TEXTURE, "Clouds", "Procedural - create a cloud-like fractal noise texture"}, {TEX_DISTNOISE, "DISTORTED_NOISE", ICON_TEXTURE, "Distorted Noise", "Procedural - noise texture distorted by two noise algorithms"}, - {TEX_ENVMAP, "ENVIRONMENT_MAP", ICON_IMAGE_DATA, - "Environment Map", "Create a render of the environment mapped to a texture"}, {TEX_IMAGE, "IMAGE", ICON_IMAGE_DATA, "Image or Movie", "Allow for images or movies to be used as textures"}, {TEX_MAGIC, "MAGIC", ICON_TEXTURE, "Magic", "Procedural - color texture based on trigonometric functions"}, {TEX_MARBLE, "MARBLE", ICON_TEXTURE, "Marble", "Procedural - marble-like noise texture with wave generated bands"}, {TEX_MUSGRAVE, "MUSGRAVE", ICON_TEXTURE, "Musgrave", "Procedural - highly flexible fractal noise texture"}, {TEX_NOISE, "NOISE", ICON_TEXTURE, "Noise", "Procedural - random noise, gives a different result every time, for every frame, for every pixel"}, - {TEX_OCEAN, "OCEAN", ICON_TEXTURE, "Ocean", "Use a texture generated by an Ocean modifier"}, - {TEX_POINTDENSITY, "POINT_DENSITY", ICON_TEXTURE, "Point Density", ""}, {TEX_STUCCI, "STUCCI", ICON_TEXTURE, "Stucci", "Procedural - create a fractal noise texture"}, {TEX_VORONOI, "VORONOI", ICON_TEXTURE, "Voronoi", "Procedural - create cell-like patterns based on Worley noise"}, - {TEX_VOXELDATA, "VOXEL_DATA", ICON_TEXTURE, "Voxel Data", "Create a 3D texture based on volumetric data"}, {TEX_WOOD, "WOOD", ICON_TEXTURE, "Wood", "Procedural - wave generated bands or rings, with optional noise"}, {0, NULL, 0, NULL, NULL} }; @@ -134,8 +129,6 @@ static StructRNA *rna_Texture_refine(struct PointerRNA *ptr) return &RNA_CloudsTexture; case TEX_DISTNOISE: return &RNA_DistortedNoiseTexture; - case TEX_ENVMAP: - return &RNA_EnvironmentMapTexture; case TEX_IMAGE: return &RNA_ImageTexture; case TEX_MAGIC: @@ -146,18 +139,12 @@ static StructRNA *rna_Texture_refine(struct PointerRNA *ptr) return &RNA_MusgraveTexture; case TEX_NOISE: return &RNA_NoiseTexture; - case TEX_POINTDENSITY: - return &RNA_PointDensityTexture; case TEX_STUCCI: return &RNA_StucciTexture; case TEX_VORONOI: return &RNA_VoronoiTexture; - case TEX_VOXELDATA: - return &RNA_VoxelDataTexture; case TEX_WOOD: return &RNA_WoodTexture; - case TEX_OCEAN: - return &RNA_OceanTexture; default: return &RNA_Texture; } @@ -192,25 +179,6 @@ static void rna_Color_mapping_update(Main *UNUSED(bmain), Scene *UNUSED(scene), /* nothing to do */ } -static void rna_Texture_voxeldata_update(Main *bmain, Scene *scene, PointerRNA *ptr) -{ - Tex *tex = ptr->id.data; - - tex->vd->ok = 0; - rna_Texture_update(bmain, scene, ptr); -} - -static void rna_Texture_voxeldata_image_update(Main *bmain, Scene *scene, PointerRNA *ptr) -{ - Tex *tex = ptr->id.data; - - if (tex->ima) { /* may be getting cleared too */ - tex->ima->source = IMA_SRC_SEQUENCE; - } - rna_Texture_voxeldata_update(bmain, scene, ptr); -} - - /* Used for Texture Properties, used (also) for/in Nodes */ static void rna_Texture_nodes_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) { @@ -433,54 +401,6 @@ static void rna_ImageTexture_mipmap_set(PointerRNA *ptr, int value) else tex->imaflag &= ~TEX_MIPMAP; } -static void rna_Envmap_update_generic(Main *bmain, Scene *scene, PointerRNA *ptr) -{ - Tex *tex = ptr->id.data; - if (tex->env) { - ED_preview_kill_jobs(bmain->wm.first, bmain); - BKE_texture_envmap_free_data(tex->env); - } - rna_Texture_update(bmain, scene, ptr); -} - -static PointerRNA rna_PointDensity_psys_get(PointerRNA *ptr) -{ - PointDensity *pd = ptr->data; - Object *ob = pd->object; - ParticleSystem *psys = NULL; - PointerRNA value; - - if (ob && pd->psys) - psys = BLI_findlink(&ob->particlesystem, pd->psys - 1); - - RNA_pointer_create(&ob->id, &RNA_ParticleSystem, psys, &value); - return value; -} - -static void rna_PointDensity_psys_set(PointerRNA *ptr, PointerRNA value) -{ - PointDensity *pd = ptr->data; - Object *ob = pd->object; - - if (ob && value.id.data == ob) - pd->psys = BLI_findindex(&ob->particlesystem, value.data) + 1; -} - -static char *rna_PointDensity_path(PointerRNA *UNUSED(ptr)) -{ - return BLI_sprintfN("point_density"); -} - -static char *rna_VoxelData_path(PointerRNA *UNUSED(ptr)) -{ - return BLI_sprintfN("voxel_data"); -} - -static char *rna_OceanTex_path(PointerRNA *UNUSED(ptr)) -{ - return BLI_sprintfN("ocean"); -} - #else static void rna_def_texmapping(BlenderRNA *brna) @@ -779,94 +699,6 @@ static void rna_def_filter_common(StructRNA *srna) RNA_def_property_update(prop, 0, "rna_Texture_update"); } -static void rna_def_environment_map(BlenderRNA *brna) -{ - StructRNA *srna; - PropertyRNA *prop; - - static const EnumPropertyItem prop_source_items[] = { - {ENV_STATIC, "STATIC", 0, "Static", "Calculate environment map only once"}, - {ENV_ANIM, "ANIMATED", 0, "Animated", "Calculate environment map at each rendering"}, - {ENV_LOAD, "IMAGE_FILE", 0, "Image File", "Load a saved environment map image from disk"}, - {0, NULL, 0, NULL, NULL} - }; - - static const EnumPropertyItem prop_mapping_items[] = { - {ENV_CUBE, "CUBE", 0, "Cube", "Use environment map with six cube sides"}, - {ENV_PLANE, "PLANE", 0, "Plane", "Only one side is rendered, with Z axis pointing in direction of image"}, - {0, NULL, 0, NULL, NULL} - }; - - srna = RNA_def_struct(brna, "EnvironmentMap", NULL); - RNA_def_struct_sdna(srna, "EnvMap"); - RNA_def_struct_ui_text(srna, "EnvironmentMap", - "Environment map created by the renderer and cached for subsequent renders"); - - prop = RNA_def_property(srna, "source", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "stype"); - RNA_def_property_enum_items(prop, prop_source_items); - RNA_def_property_ui_text(prop, "Source", ""); - RNA_def_property_update(prop, 0, "rna_Envmap_update_generic"); - - prop = RNA_def_property(srna, "viewpoint_object", PROP_POINTER, PROP_NONE); - RNA_def_property_pointer_sdna(prop, NULL, "object"); - RNA_def_property_ui_text(prop, "Viewpoint Object", "Object to use as the environment map's viewpoint location"); - RNA_def_property_flag(prop, PROP_EDITABLE); - RNA_def_property_update(prop, 0, "rna_Texture_update"); - - prop = RNA_def_property(srna, "mapping", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "type"); - RNA_def_property_enum_items(prop, prop_mapping_items); - RNA_def_property_ui_text(prop, "Mapping", ""); - RNA_def_property_update(prop, 0, "rna_Texture_update"); - - prop = RNA_def_property(srna, "clip_start", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "clipsta"); - RNA_def_property_range(prop, 0.001, FLT_MAX); - RNA_def_property_ui_range(prop, 0.01, 50, 100, 2); - RNA_def_property_ui_text(prop, "Clip Start", "Objects nearer than this are not visible to map"); - RNA_def_property_update(prop, 0, "rna_Texture_update"); - - prop = RNA_def_property(srna, "clip_end", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "clipend"); - RNA_def_property_range(prop, 0.01, FLT_MAX); - RNA_def_property_ui_range(prop, 0.10, 20000, 100, 2); - RNA_def_property_ui_text(prop, "Clip End", "Objects further than this are not visible to map"); - RNA_def_property_update(prop, 0, "rna_Texture_update"); - - prop = RNA_def_property(srna, "zoom", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "viewscale"); - RNA_def_property_range(prop, 0.1, 5.0); - RNA_def_property_ui_range(prop, 0.5, 1.5, 1, 2); - RNA_def_property_ui_text(prop, "Zoom", ""); - RNA_def_property_update(prop, 0, "rna_Texture_update"); - - prop = RNA_def_property(srna, "layers_ignore", PROP_BOOLEAN, PROP_LAYER_MEMBER); - RNA_def_property_boolean_sdna(prop, NULL, "notlay", 1); - RNA_def_property_array(prop, 20); - RNA_def_property_ui_text(prop, "Ignore Layers", - "Hide objects on these layers when generating the Environment Map"); - RNA_def_property_update(prop, 0, "rna_Texture_update"); - - prop = RNA_def_property(srna, "resolution", PROP_INT, PROP_UNSIGNED); - RNA_def_property_int_sdna(prop, NULL, "cuberes"); - RNA_def_property_range(prop, 50, 4096); - RNA_def_property_ui_text(prop, "Resolution", "Pixel resolution of the rendered environment map"); - RNA_def_property_update(prop, 0, "rna_Texture_update"); - - prop = RNA_def_property(srna, "depth", PROP_INT, PROP_UNSIGNED); - RNA_def_property_range(prop, 0, 5); - RNA_def_property_ui_text(prop, "Depth", "Number of times a map will be rendered recursively (mirror effects)"); - RNA_def_property_update(prop, 0, "rna_Texture_update"); - - prop = RNA_def_property(srna, "is_valid", PROP_BOOLEAN, 0); - RNA_def_property_boolean_sdna(prop, NULL, "ok", 2); - RNA_def_property_clear_flag(prop, PROP_EDITABLE); - RNA_def_property_ui_text(prop, "Validity", "True if this map is ready for use, False if it needs rendering"); - - RNA_api_environment_map(srna); -} - static const EnumPropertyItem prop_noise_basis_items[] = { {TEX_BLENDER, "BLENDER_ORIGINAL", 0, "Blender Original", "Noise algorithm - Blender original: Smooth interpolated noise"}, @@ -1372,43 +1204,6 @@ static void rna_def_texture_image(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "imaflag", TEX_NORMALMAP); RNA_def_property_ui_text(prop, "Normal Map", "Use image RGB values for normal mapping"); RNA_def_property_update(prop, 0, "rna_Texture_update"); - - /* Derivative Map */ - prop = RNA_def_property(srna, "use_derivative_map", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "imaflag", TEX_DERIVATIVEMAP); - RNA_def_property_ui_text(prop, "Derivative Map", "Use red and green as derivative values"); - RNA_def_property_update(prop, 0, "rna_Texture_update"); -} - -static void rna_def_texture_environment_map(BlenderRNA *brna) -{ - StructRNA *srna; - PropertyRNA *prop; - - srna = RNA_def_struct(brna, "EnvironmentMapTexture", "Texture"); - RNA_def_struct_ui_text(srna, "Environment Map", "Environment map texture"); - RNA_def_struct_sdna(srna, "Tex"); - - prop = RNA_def_property(srna, "image", PROP_POINTER, PROP_NONE); - RNA_def_property_pointer_sdna(prop, NULL, "ima"); - RNA_def_property_struct_type(prop, "Image"); - RNA_def_property_flag(prop, PROP_EDITABLE); - RNA_def_property_ui_text(prop, "Image", "Source image file to read the environment map from"); - RNA_def_property_update(prop, 0, "rna_Envmap_update_generic"); - - prop = RNA_def_property(srna, "image_user", PROP_POINTER, PROP_NEVER_NULL); - RNA_def_property_pointer_sdna(prop, NULL, "iuser"); - RNA_def_property_ui_text(prop, "Image User", - "Parameters defining which layer, pass and frame of the image is displayed"); - RNA_def_property_update(prop, 0, "rna_Texture_update"); - - rna_def_filter_common(srna); - - prop = RNA_def_property(srna, "environment_map", PROP_POINTER, PROP_NONE); - RNA_def_property_pointer_sdna(prop, NULL, "env"); - RNA_def_property_struct_type(prop, "EnvironmentMap"); - RNA_def_property_ui_text(prop, "Environment Map", "Get the environment map associated with this texture"); - RNA_def_property_update(prop, 0, "rna_Texture_update"); } static void rna_def_texture_musgrave(BlenderRNA *brna) @@ -1633,407 +1428,6 @@ static void rna_def_texture_distorted_noise(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_Texture_update"); } -static void rna_def_texture_pointdensity(BlenderRNA *brna) -{ - StructRNA *srna; - PropertyRNA *prop; - - static const EnumPropertyItem point_source_items[] = { - {TEX_PD_PSYS, "PARTICLE_SYSTEM", 0, "Particle System", "Generate point density from a particle system"}, - {TEX_PD_OBJECT, "OBJECT", 0, "Object Vertices", "Generate point density from an object's vertices"}, - /*{TEX_PD_FILE, "FILE", 0, "File", ""}, */ - {0, NULL, 0, NULL, NULL} - }; - - static const EnumPropertyItem particle_cache_items[] = { - {TEX_PD_OBJECTLOC, "OBJECT_LOCATION", 0, "Emit Object Location", ""}, - {TEX_PD_OBJECTSPACE, "OBJECT_SPACE", 0, "Emit Object Space", ""}, - {TEX_PD_WORLDSPACE, "WORLD_SPACE", 0, "Global Space", ""}, - {0, NULL, 0, NULL, NULL} - }; - - static const EnumPropertyItem vertex_cache_items[] = { - {TEX_PD_OBJECTLOC, "OBJECT_LOCATION", 0, "Object Location", ""}, - {TEX_PD_OBJECTSPACE, "OBJECT_SPACE", 0, "Object Space", ""}, - {TEX_PD_WORLDSPACE, "WORLD_SPACE", 0, "Global Space", ""}, - {0, NULL, 0, NULL, NULL} - }; - - static const EnumPropertyItem falloff_items[] = { - {TEX_PD_FALLOFF_STD, "STANDARD", 0, "Standard", ""}, - {TEX_PD_FALLOFF_SMOOTH, "SMOOTH", 0, "Smooth", ""}, - {TEX_PD_FALLOFF_SOFT, "SOFT", 0, "Soft", ""}, - {TEX_PD_FALLOFF_CONSTANT, "CONSTANT", 0, "Constant", "Density is constant within lookup radius"}, - {TEX_PD_FALLOFF_ROOT, "ROOT", 0, "Root", ""}, - {TEX_PD_FALLOFF_PARTICLE_AGE, "PARTICLE_AGE", 0, "Particle Age", ""}, - {TEX_PD_FALLOFF_PARTICLE_VEL, "PARTICLE_VELOCITY", 0, "Particle Velocity", ""}, - {0, NULL, 0, NULL, NULL} - }; - - static const EnumPropertyItem particle_color_source_items[] = { - {TEX_PD_COLOR_CONSTANT, "CONSTANT", 0, "Constant", ""}, - {TEX_PD_COLOR_PARTAGE, "PARTICLE_AGE", 0, "Particle Age", "Lifetime mapped as 0.0 - 1.0 intensity"}, - {TEX_PD_COLOR_PARTSPEED, "PARTICLE_SPEED", 0, "Particle Speed", - "Particle speed (absolute magnitude of velocity) mapped as 0.0-1.0 intensity"}, - {TEX_PD_COLOR_PARTVEL, "PARTICLE_VELOCITY", 0, "Particle Velocity", "XYZ velocity mapped to RGB colors"}, - {0, NULL, 0, NULL, NULL} - }; - - static const EnumPropertyItem vertex_color_source_items[] = { - {TEX_PD_COLOR_CONSTANT, "CONSTANT", 0, "Constant", ""}, - {TEX_PD_COLOR_VERTCOL, "VERTEX_COLOR", 0, "Vertex Color", "Vertex color layer"}, - {TEX_PD_COLOR_VERTWEIGHT, "VERTEX_WEIGHT", 0, "Vertex Weight", "Vertex group weight"}, - {TEX_PD_COLOR_VERTNOR, "VERTEX_NORMAL", 0, "Vertex Normal", "XYZ normal vector mapped to RGB colors"}, - {0, NULL, 0, NULL, NULL} - }; - - static const EnumPropertyItem turbulence_influence_items[] = { - {TEX_PD_NOISE_STATIC, "STATIC", 0, "Static", - "Noise patterns will remain unchanged, faster and suitable for stills"}, - {TEX_PD_NOISE_VEL, "PARTICLE_VELOCITY", 0, "Particle Velocity", - "Turbulent noise driven by particle velocity"}, - {TEX_PD_NOISE_AGE, "PARTICLE_AGE", 0, "Particle Age", - "Turbulent noise driven by the particle's age between birth and death"}, - {TEX_PD_NOISE_TIME, "GLOBAL_TIME", 0, "Global Time", "Turbulent noise driven by the global current frame"}, - {0, NULL, 0, NULL, NULL} - }; - - srna = RNA_def_struct(brna, "PointDensity", NULL); - RNA_def_struct_sdna(srna, "PointDensity"); - RNA_def_struct_ui_text(srna, "PointDensity", "Point density settings"); - RNA_def_struct_path_func(srna, "rna_PointDensity_path"); - - prop = RNA_def_property(srna, "point_source", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "source"); - RNA_def_property_enum_items(prop, point_source_items); - RNA_def_property_ui_text(prop, "Point Source", "Point data to use as renderable point density"); - RNA_def_property_update(prop, 0, "rna_Texture_update"); - - prop = RNA_def_property(srna, "object", PROP_POINTER, PROP_NONE); - RNA_def_property_pointer_sdna(prop, NULL, "object"); - RNA_def_property_ui_text(prop, "Object", "Object to take point data from"); - RNA_def_property_flag(prop, PROP_EDITABLE); - RNA_def_property_update(prop, 0, "rna_Texture_update"); - - prop = RNA_def_property(srna, "particle_system", PROP_POINTER, PROP_NONE); - RNA_def_property_ui_text(prop, "Particle System", "Particle System to render as points"); - RNA_def_property_struct_type(prop, "ParticleSystem"); - RNA_def_property_pointer_funcs(prop, "rna_PointDensity_psys_get", "rna_PointDensity_psys_set", NULL, NULL); - RNA_def_property_flag(prop, PROP_EDITABLE); - RNA_def_property_update(prop, 0, "rna_Texture_update"); - - prop = RNA_def_property(srna, "particle_cache_space", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "psys_cache_space"); - RNA_def_property_enum_items(prop, particle_cache_items); - RNA_def_property_ui_text(prop, "Particle Cache", "Coordinate system to cache particles in"); - RNA_def_property_update(prop, 0, "rna_Texture_update"); - - prop = RNA_def_property(srna, "vertex_cache_space", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "ob_cache_space"); - RNA_def_property_enum_items(prop, vertex_cache_items); - RNA_def_property_ui_text(prop, "Vertices Cache", "Coordinate system to cache vertices in"); - RNA_def_property_update(prop, 0, "rna_Texture_update"); - - prop = RNA_def_property(srna, "radius", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "radius"); - RNA_def_property_range(prop, 0.001, FLT_MAX); - RNA_def_property_ui_text(prop, "Radius", "Radius from the shaded sample to look for points within"); - RNA_def_property_update(prop, 0, "rna_Texture_update"); - - prop = RNA_def_property(srna, "falloff", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "falloff_type"); - RNA_def_property_enum_items(prop, falloff_items); - RNA_def_property_ui_text(prop, "Falloff", "Method of attenuating density by distance from the point"); - RNA_def_property_update(prop, 0, "rna_Texture_update"); - - prop = RNA_def_property(srna, "falloff_soft", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "falloff_softness"); - RNA_def_property_range(prop, 0.01, FLT_MAX); - RNA_def_property_ui_text(prop, "Softness", "Softness of the 'soft' falloff option"); - RNA_def_property_update(prop, 0, "rna_Texture_update"); - - prop = RNA_def_property(srna, "particle_color_source", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "color_source"); - RNA_def_property_enum_items(prop, particle_color_source_items); - RNA_def_property_ui_text(prop, "Color Source", "Data to derive color results from"); - RNA_def_property_update(prop, 0, "rna_Texture_update"); - - prop = RNA_def_property(srna, "vertex_color_source", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "ob_color_source"); - RNA_def_property_enum_items(prop, vertex_color_source_items); - RNA_def_property_ui_text(prop, "Color Source", "Data to derive color results from"); - RNA_def_property_update(prop, 0, "rna_Texture_update"); - - prop = RNA_def_property(srna, "vertex_attribute_name", PROP_STRING, PROP_NONE); - RNA_def_property_ui_text(prop, "Vertex Attribute Name", "Vertex attribute to use for color"); - RNA_def_property_update(prop, 0, "rna_Texture_update"); - - prop = RNA_def_property(srna, "speed_scale", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "speed_scale"); - RNA_def_property_range(prop, 0.001, 100.0); - RNA_def_property_ui_text(prop, "Scale", "Multiplier to bring particle speed within an acceptable range"); - RNA_def_property_update(prop, 0, "rna_Texture_update"); - - prop = RNA_def_property(srna, "falloff_speed_scale", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "falloff_speed_scale"); - RNA_def_property_range(prop, 0.001, 100.0); - RNA_def_property_ui_text(prop, "Velocity Scale", "Multiplier to bring particle speed within an acceptable range"); - RNA_def_property_update(prop, 0, "rna_Texture_update"); - - - prop = RNA_def_property(srna, "color_ramp", PROP_POINTER, PROP_NEVER_NULL); - RNA_def_property_pointer_sdna(prop, NULL, "coba"); - RNA_def_property_struct_type(prop, "ColorRamp"); - RNA_def_property_ui_text(prop, "Color Ramp", ""); - RNA_def_property_update(prop, 0, "rna_Texture_update"); - - prop = RNA_def_property(srna, "falloff_curve", PROP_POINTER, PROP_NEVER_NULL); - RNA_def_property_pointer_sdna(prop, NULL, "falloff_curve"); - RNA_def_property_struct_type(prop, "CurveMapping"); - RNA_def_property_ui_text(prop, "Falloff Curve", ""); - RNA_def_property_update(prop, 0, "rna_Texture_update"); - - prop = RNA_def_property(srna, "use_falloff_curve", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", TEX_PD_FALLOFF_CURVE); - RNA_def_property_ui_text(prop, "Falloff Curve", "Use a custom falloff curve"); - RNA_def_property_update(prop, 0, "rna_Texture_update"); - - /* Turbulence */ - prop = RNA_def_property(srna, "use_turbulence", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", TEX_PD_TURBULENCE); - RNA_def_property_ui_text(prop, "Turbulence", "Add directed noise to the density at render-time"); - RNA_def_property_update(prop, 0, "rna_Texture_update"); - - prop = RNA_def_property(srna, "turbulence_scale", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "noise_size"); - RNA_def_property_range(prop, 0.01, FLT_MAX); - RNA_def_property_ui_text(prop, "Size", "Scale of the added turbulent noise"); - RNA_def_property_update(prop, 0, "rna_Texture_update"); - - prop = RNA_def_property(srna, "turbulence_strength", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "noise_fac"); - RNA_def_property_range(prop, 0.01, FLT_MAX); - RNA_def_property_ui_text(prop, "Turbulence Strength", "Strength of the added turbulent noise"); - RNA_def_property_update(prop, 0, "rna_Texture_update"); - - prop = RNA_def_property(srna, "turbulence_depth", PROP_INT, PROP_NONE); - RNA_def_property_int_sdna(prop, NULL, "noise_depth"); - RNA_def_property_range(prop, 0, 30); - RNA_def_property_ui_text(prop, "Depth", "Level of detail in the added turbulent noise"); - RNA_def_property_update(prop, 0, "rna_Texture_update"); - - prop = RNA_def_property(srna, "turbulence_influence", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "noise_influence"); - RNA_def_property_enum_items(prop, turbulence_influence_items); - RNA_def_property_ui_text(prop, "Turbulence Influence", "Method for driving added turbulent noise"); - RNA_def_property_update(prop, 0, "rna_Texture_update"); - - prop = RNA_def_property(srna, "noise_basis", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "noise_basis"); - RNA_def_property_enum_items(prop, prop_noise_basis_items); - RNA_def_property_ui_text(prop, "Noise Basis", "Noise formula used for turbulence"); - RNA_def_property_update(prop, 0, "rna_Texture_update"); - - - srna = RNA_def_struct(brna, "PointDensityTexture", "Texture"); - RNA_def_struct_sdna(srna, "Tex"); - RNA_def_struct_ui_text(srna, "Point Density", "Settings for the Point Density texture"); - - prop = RNA_def_property(srna, "point_density", PROP_POINTER, PROP_NONE); - RNA_def_property_pointer_sdna(prop, NULL, "pd"); - RNA_def_property_struct_type(prop, "PointDensity"); - RNA_def_property_ui_text(prop, "Point Density", "The point density settings associated with this texture"); - RNA_def_property_update(prop, 0, "rna_Texture_update"); -} - -static void rna_def_texture_voxeldata(BlenderRNA *brna) -{ - StructRNA *srna; - PropertyRNA *prop; - - static const EnumPropertyItem interpolation_type_items[] = { - {TEX_VD_NEARESTNEIGHBOR, "NEREASTNEIGHBOR", 0, "Nearest Neighbor", - "No interpolation, fast but blocky and low quality"}, - {TEX_VD_LINEAR, "TRILINEAR", 0, "Linear", "Good smoothness and speed"}, - {TEX_VD_QUADRATIC, "QUADRATIC", 0, "Quadratic", "Mid-range quality and speed"}, - {TEX_VD_TRICUBIC_CATROM, "TRICUBIC_CATROM", 0, "Cubic Catmull-Rom", "High quality interpolation, but slower"}, - {TEX_VD_TRICUBIC_BSPLINE, "TRICUBIC_BSPLINE", 0, "Cubic B-Spline", - "Smoothed high quality interpolation, but slower"}, - {0, NULL, 0, NULL, NULL} - }; - - static const EnumPropertyItem file_format_items[] = { - {TEX_VD_BLENDERVOXEL, "BLENDER_VOXEL", 0, "Blender Voxel", "Default binary voxel file format"}, - {TEX_VD_RAW_8BIT, "RAW_8BIT", 0, "8 bit RAW", "8 bit grayscale binary data"}, - /*{TEX_VD_RAW_16BIT, "RAW_16BIT", 0, "16 bit RAW", ""}, */ - {TEX_VD_IMAGE_SEQUENCE, "IMAGE_SEQUENCE", 0, "Image Sequence", - "Generate voxels from a sequence of image slices"}, - {TEX_VD_SMOKE, "SMOKE", 0, "Smoke", "Render voxels from a Blender smoke simulation"}, - {TEX_VD_HAIR, "HAIR", 0, "Hair", "Render voxels from a Blender hair simulation"}, - {0, NULL, 0, NULL, NULL} - }; - - static const EnumPropertyItem voxeldata_extension[] = { - {TEX_EXTEND, "EXTEND", 0, "Extend", "Extend by repeating edge pixels of the image"}, - {TEX_CLIP, "CLIP", 0, "Clip", "Clip to image size and set exterior pixels as transparent"}, - {TEX_REPEAT, "REPEAT", 0, "Repeat", "Cause the image to repeat horizontally and vertically"}, - {0, NULL, 0, NULL, NULL} - }; - - static const EnumPropertyItem smoked_type_items[] = { - {TEX_VD_SMOKEDENSITY, "SMOKEDENSITY", 0, "Smoke", "Use smoke density and color as texture data"}, - {TEX_VD_SMOKEFLAME, "SMOKEFLAME", 0, "Flame", "Use flame temperature as texture data"}, - {TEX_VD_SMOKEHEAT, "SMOKEHEAT", 0, "Heat", "Use smoke heat as texture data. Values from -2.0 to 2.0 are used"}, - {TEX_VD_SMOKEVEL, "SMOKEVEL", 0, "Velocity", "Use smoke velocity as texture data"}, - {0, NULL, 0, NULL, NULL} - }; - - static const EnumPropertyItem hair_type_items[] = { - {TEX_VD_HAIRDENSITY, "HAIRDENSITY", 0, "Density", "Use hair density as texture data"}, - {TEX_VD_HAIRRESTDENSITY, "HAIRRESTDENSITY", 0, "Rest Density", "Use hair rest density as texture data"}, - {TEX_VD_HAIRVELOCITY, "HAIRVELOCITY", 0, "Velocity", "Use hair velocity as texture data"}, - {TEX_VD_HAIRENERGY, "HAIRENERGY", 0, "Energy", "Use potential hair energy as texture data"}, - {0, NULL, 0, NULL, NULL} - }; - - srna = RNA_def_struct(brna, "VoxelData", NULL); - RNA_def_struct_sdna(srna, "VoxelData"); - RNA_def_struct_ui_text(srna, "VoxelData", "Voxel data settings"); - RNA_def_struct_path_func(srna, "rna_VoxelData_path"); - - prop = RNA_def_property(srna, "interpolation", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "interp_type"); - RNA_def_property_enum_items(prop, interpolation_type_items); - RNA_def_property_ui_text(prop, "Interpolation", "Method to interpolate/smooth values between voxel cells"); - RNA_def_property_update(prop, 0, "rna_Texture_update"); - - prop = RNA_def_property(srna, "smoke_data_type", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "smoked_type"); - RNA_def_property_enum_items(prop, smoked_type_items); - RNA_def_property_ui_text(prop, "Source", "Simulation value to be used as a texture"); - RNA_def_property_update(prop, 0, "rna_Texture_voxeldata_update"); - - prop = RNA_def_property(srna, "hair_data_type", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "hair_type"); - RNA_def_property_enum_items(prop, hair_type_items); - RNA_def_property_ui_text(prop, "Source", "Simulation value to be used as a texture"); - RNA_def_property_update(prop, 0, "rna_Texture_voxeldata_update"); - - prop = RNA_def_property(srna, "extension", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "extend"); - RNA_def_property_enum_items(prop, voxeldata_extension); - RNA_def_property_ui_text(prop, "Extension", "How the texture is extrapolated past its original bounds"); - RNA_def_property_update(prop, 0, "rna_Texture_update"); - - prop = RNA_def_property(srna, "intensity", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "int_multiplier"); - RNA_def_property_range(prop, 0.01, FLT_MAX); - RNA_def_property_ui_text(prop, "Intensity", "Multiplier for intensity values"); - RNA_def_property_update(prop, 0, "rna_Texture_update"); - - prop = RNA_def_property(srna, "file_format", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "file_format"); - RNA_def_property_enum_items(prop, file_format_items); - RNA_def_property_ui_text(prop, "File Format", "Format of the source data set to render"); - RNA_def_property_update(prop, 0, "rna_Texture_voxeldata_update"); - - prop = RNA_def_property(srna, "filepath", PROP_STRING, PROP_FILEPATH); - RNA_def_property_string_sdna(prop, NULL, "source_path"); - RNA_def_property_ui_text(prop, "Source Path", "The external source data file to use"); - RNA_def_property_update(prop, 0, "rna_Texture_voxeldata_update"); - - prop = RNA_def_property(srna, "resolution", PROP_INT, PROP_NONE); - RNA_def_property_int_sdna(prop, NULL, "resol"); - RNA_def_property_range(prop, 1, 100000); - RNA_def_property_ui_text(prop, "Resolution", "Resolution of the voxel grid"); - RNA_def_property_update(prop, 0, "rna_Texture_voxeldata_update"); - - prop = RNA_def_property(srna, "use_still_frame", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", TEX_VD_STILL); - RNA_def_property_ui_text(prop, "Still Frame Only", "Always render a still frame from the voxel data sequence"); - RNA_def_property_update(prop, 0, "rna_Texture_voxeldata_update"); - - prop = RNA_def_property(srna, "still_frame", PROP_INT, PROP_NONE); - RNA_def_property_int_sdna(prop, NULL, "still_frame"); - RNA_def_property_range(prop, -MAXFRAME, MAXFRAME); - RNA_def_property_ui_text(prop, "Still Frame Number", "The frame number to always use"); - RNA_def_property_update(prop, 0, "rna_Texture_voxeldata_update"); - - prop = RNA_def_property(srna, "domain_object", PROP_POINTER, PROP_NONE); - RNA_def_property_pointer_sdna(prop, NULL, "object"); - RNA_def_property_ui_text(prop, "Domain Object", "Object used as the smoke simulation domain"); - RNA_def_property_flag(prop, PROP_EDITABLE); - RNA_def_property_update(prop, 0, "rna_Texture_voxeldata_update"); - - - srna = RNA_def_struct(brna, "VoxelDataTexture", "Texture"); - RNA_def_struct_sdna(srna, "Tex"); - RNA_def_struct_ui_text(srna, "Voxel Data", "Settings for the Voxel Data texture"); - - prop = RNA_def_property(srna, "voxel_data", PROP_POINTER, PROP_NONE); - RNA_def_property_pointer_sdna(prop, NULL, "vd"); - RNA_def_property_struct_type(prop, "VoxelData"); - RNA_def_property_ui_text(prop, "Voxel Data", "The voxel data associated with this texture"); - RNA_def_property_update(prop, 0, "rna_Texture_update"); - - prop = RNA_def_property(srna, "image", PROP_POINTER, PROP_NONE); - RNA_def_property_pointer_sdna(prop, NULL, "ima"); - RNA_def_property_struct_type(prop, "Image"); - RNA_def_property_flag(prop, PROP_EDITABLE); - RNA_def_property_ui_text(prop, "Image", ""); - RNA_def_property_update(prop, 0, "rna_Texture_voxeldata_image_update"); - - prop = RNA_def_property(srna, "image_user", PROP_POINTER, PROP_NEVER_NULL); - RNA_def_property_pointer_sdna(prop, NULL, "iuser"); - RNA_def_property_ui_text(prop, "Image User", - "Parameters defining which layer, pass and frame of the image is displayed"); - RNA_def_property_update(prop, 0, "rna_Texture_voxeldata_update"); -} - -static void rna_def_texture_ocean(BlenderRNA *brna) -{ - StructRNA *srna; - PropertyRNA *prop; - - static const EnumPropertyItem ocean_output_items[] = { - {TEX_OCN_DISPLACEMENT, "DISPLACEMENT", 0, "Displacement", "Output XYZ displacement in RGB channels"}, - /*{TEX_OCN_NORMALS, "NORMALS", 0, "Normals", "Outputs wave normals"}, *//* these are in nor channel now */ - {TEX_OCN_FOAM, "FOAM", 0, "Foam", "Output Foam (wave overlap) amount in single channel"}, - {TEX_OCN_JPLUS, "JPLUS", 0, "Eigenvalues", "Positive Eigenvalues"}, - {TEX_OCN_EMINUS, "EMINUS", 0, "Eigenvectors (-)", "Negative Eigenvectors"}, - {TEX_OCN_EPLUS, "EPLUS", 0, "Eigenvectors (+)", "Positive Eigenvectors"}, - {0, NULL, 0, NULL, NULL} - }; - - srna = RNA_def_struct(brna, "OceanTexData", NULL); - RNA_def_struct_sdna(srna, "OceanTex"); - RNA_def_struct_ui_text(srna, "Ocean", "Ocean Texture settings"); - RNA_def_struct_path_func(srna, "rna_OceanTex_path"); - - prop = RNA_def_property(srna, "output", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "output"); - RNA_def_property_enum_items(prop, ocean_output_items); - RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_ui_text(prop, "Output", "The data that is output by the texture"); - RNA_def_property_update(prop, 0, "rna_Texture_update"); - - prop = RNA_def_property(srna, "ocean_object", PROP_POINTER, PROP_NONE); - RNA_def_property_pointer_sdna(prop, NULL, "object"); - RNA_def_property_ui_text(prop, "Modifier Object", "Object containing the ocean modifier"); - RNA_def_property_flag(prop, PROP_EDITABLE); - RNA_def_property_update(prop, 0, "rna_Texture_update"); - - srna = RNA_def_struct(brna, "OceanTexture", "Texture"); - RNA_def_struct_sdna(srna, "Tex"); - RNA_def_struct_ui_text(srna, "Ocean", "Settings for the Ocean texture"); - - prop = RNA_def_property(srna, "ocean", PROP_POINTER, PROP_NONE); - RNA_def_property_pointer_sdna(prop, NULL, "ot"); - RNA_def_property_struct_type(prop, "OceanTexData"); - RNA_def_property_ui_text(prop, "Ocean", "The ocean data associated with this texture"); - RNA_def_property_update(prop, 0, "rna_Texture_update"); -} - static void rna_def_texture(BlenderRNA *brna) { StructRNA *srna; @@ -2134,13 +1528,9 @@ static void rna_def_texture(BlenderRNA *brna) rna_def_texture_stucci(brna); rna_def_texture_noise(brna); rna_def_texture_image(brna); - rna_def_texture_environment_map(brna); rna_def_texture_musgrave(brna); rna_def_texture_voronoi(brna); rna_def_texture_distorted_noise(brna); - rna_def_texture_pointdensity(brna); - rna_def_texture_voxeldata(brna); - rna_def_texture_ocean(brna); /* XXX add more types here .. */ RNA_api_texture(srna); @@ -2150,7 +1540,6 @@ void RNA_def_texture(BlenderRNA *brna) { rna_def_texture(brna); rna_def_mtex(brna); - rna_def_environment_map(brna); rna_def_texmapping(brna); rna_def_colormapping(brna); } diff --git a/source/blender/makesrna/intern/rna_texture_api.c b/source/blender/makesrna/intern/rna_texture_api.c index a8fcf0ca3b6..1d513a494d7 100644 --- a/source/blender/makesrna/intern/rna_texture_api.c +++ b/source/blender/makesrna/intern/rna_texture_api.c @@ -45,30 +45,6 @@ #include "RE_pipeline.h" #include "RE_shader_ext.h" -static void save_envmap(struct EnvMap *env, bContext *C, ReportList *reports, const char *filepath, - struct Scene *scene, float layout[12]) -{ - if (scene == NULL) { - scene = CTX_data_scene(C); - } - - RE_WriteEnvmapResult(reports, scene, env, filepath, scene->r.im_format.imtype, layout); -} - -static void clear_envmap(struct EnvMap *env, bContext *C) -{ - Main *bmain = CTX_data_main(C); - Tex *tex; - - BKE_texture_envmap_free_data(env); - - for (tex = bmain->tex.first; tex; tex = tex->id.next) - if (tex->env == env) { - WM_event_add_notifier(C, NC_TEXTURE | NA_EDITED, tex); - break; - } -} - static void texture_evaluate(struct Tex *tex, float value[3], float r_color[4]) { TexResult texres = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL}; @@ -102,31 +78,4 @@ void RNA_api_texture(StructRNA *srna) } -void RNA_api_environment_map(StructRNA *srna) -{ - FunctionRNA *func; - PropertyRNA *parm; - - static const float default_layout[] = {0, 0, 1, 0, 2, 0, 0, 1, 1, 1, 2, 1}; - - func = RNA_def_function(srna, "clear", "clear_envmap"); - RNA_def_function_ui_description(func, "Discard the environment map and free it from memory"); - RNA_def_function_flag(func, FUNC_USE_CONTEXT); - - - func = RNA_def_function(srna, "save", "save_envmap"); - RNA_def_function_ui_description(func, "Save the environment map to disc using the scene render settings"); - RNA_def_function_flag(func, FUNC_USE_CONTEXT | FUNC_USE_REPORTS); - - parm = RNA_def_string_file_name(func, "filepath", NULL, FILE_MAX, "File path", "Location of the output file"); - RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); - - RNA_def_pointer(func, "scene", "Scene", "", "Overrides the scene from which image parameters are taken"); - - RNA_def_float_array(func, "layout", 12, default_layout, 0.0f, 1000.0f, "File layout", - "Flat array describing the X,Y position of each cube face in the " - "output image, where 1 is the size of a face - order is [+Z -Z +Y -X -Y +X] " - "(use -1 to skip a face)", 0.0f, 1000.0f); -} - #endif diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index fe69b91e833..2645dc081c8 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -52,7 +52,6 @@ #include "WM_types.h" #include "BLT_lang.h" -#include "GPU_buffers.h" #ifdef WITH_OPENSUBDIV static const EnumPropertyItem opensubdiv_compute_type_items[] = { diff --git a/source/blender/makesrna/intern/rna_world.c b/source/blender/makesrna/intern/rna_world.c index e78355ee426..92fbbd61898 100644 --- a/source/blender/makesrna/intern/rna_world.c +++ b/source/blender/makesrna/intern/rna_world.c @@ -64,28 +64,6 @@ static PointerRNA rna_World_mist_get(PointerRNA *ptr) return rna_pointer_inherit_refine(ptr, &RNA_WorldMistSettings, ptr->id.data); } -static void rna_World_mtex_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) -{ - World *wo = (World *)ptr->data; - rna_iterator_array_begin(iter, (void *)wo->mtex, sizeof(MTex *), MAX_MTEX, 0, NULL); -} - -static PointerRNA rna_World_active_texture_get(PointerRNA *ptr) -{ - World *wo = (World *)ptr->data; - Tex *tex; - - tex = give_current_world_texture(wo); - return rna_pointer_inherit_refine(ptr, &RNA_Texture, tex); -} - -static void rna_World_active_texture_set(PointerRNA *ptr, PointerRNA value) -{ - World *wo = (World *)ptr->data; - - set_current_world_texture(wo, value.data); -} - static void rna_World_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) { World *wo = ptr->id.data; @@ -129,117 +107,11 @@ static void rna_World_use_nodes_update(bContext *C, PointerRNA *ptr) #else -static void rna_def_world_mtex(BlenderRNA *brna) -{ - StructRNA *srna; - PropertyRNA *prop; - - static const EnumPropertyItem texco_items[] = { - {TEXCO_VIEW, "VIEW", 0, "View", "Use view vector for the texture coordinates"}, - {TEXCO_GLOB, "GLOBAL", 0, "Global", "Use global coordinates for the texture coordinates (interior mist)"}, - {TEXCO_ANGMAP, "ANGMAP", 0, "AngMap", "Use 360 degree angular coordinates, e.g. for spherical light probes"}, - {TEXCO_H_SPHEREMAP, "SPHERE", 0, "Sphere", "For 360 degree panorama sky, spherical mapped, only top half"}, - {TEXCO_EQUIRECTMAP, "EQUIRECT", 0, "Equirectangular", "For 360 degree panorama sky, equirectangular mapping"}, - {TEXCO_H_TUBEMAP, "TUBE", 0, "Tube", "For 360 degree panorama sky, cylindrical mapped, only top half"}, - {TEXCO_OBJECT, "OBJECT", 0, "Object", "Use linked object's coordinates for texture coordinates"}, - {0, NULL, 0, NULL, NULL} - }; - - srna = RNA_def_struct(brna, "WorldTextureSlot", "TextureSlot"); - RNA_def_struct_sdna(srna, "MTex"); - RNA_def_struct_ui_text(srna, "World Texture Slot", "Texture slot for textures in a World data-block"); - - /* map to */ - prop = RNA_def_property(srna, "use_map_blend", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mapto", WOMAP_BLEND); - RNA_def_property_ui_text(prop, "Blend", "Affect the color progression of the background"); - RNA_def_property_update(prop, 0, "rna_World_update"); - - prop = RNA_def_property(srna, "use_map_horizon", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mapto", WOMAP_HORIZ); - RNA_def_property_ui_text(prop, "Horizon", "Affect the color of the horizon"); - RNA_def_property_update(prop, 0, "rna_World_update"); - - prop = RNA_def_property(srna, "use_map_zenith_up", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mapto", WOMAP_ZENUP); - RNA_def_property_ui_text(prop, "Zenith Up", "Affect the color of the zenith above"); - RNA_def_property_update(prop, 0, "rna_World_update"); - - prop = RNA_def_property(srna, "use_map_zenith_down", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mapto", WOMAP_ZENDOWN); - RNA_def_property_ui_text(prop, "Zenith Down", "Affect the color of the zenith below"); - RNA_def_property_update(prop, 0, "rna_World_update"); - - prop = RNA_def_property(srna, "texture_coords", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "texco"); - RNA_def_property_enum_items(prop, texco_items); - RNA_def_property_ui_text(prop, "Texture Coordinates", - "Texture coordinates used to map the texture onto the background"); - RNA_def_property_update(prop, 0, "rna_World_update"); - - prop = RNA_def_property(srna, "object", PROP_POINTER, PROP_NONE); - RNA_def_property_pointer_sdna(prop, NULL, "object"); - RNA_def_property_struct_type(prop, "Object"); - RNA_def_property_flag(prop, PROP_EDITABLE); - RNA_def_property_ui_text(prop, "Object", "Object to use for mapping with Object texture coordinates"); - RNA_def_property_update(prop, 0, "rna_World_update"); - - prop = RNA_def_property(srna, "blend_factor", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "blendfac"); - RNA_def_property_ui_range(prop, 0, 1, 10, 3); - RNA_def_property_ui_text(prop, "Blend Factor", "Amount texture affects color progression of the background"); - RNA_def_property_update(prop, 0, "rna_World_update"); - - prop = RNA_def_property(srna, "horizon_factor", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "colfac"); - RNA_def_property_ui_range(prop, 0, 1, 10, 3); - RNA_def_property_ui_text(prop, "Horizon Factor", "Amount texture affects color of the horizon"); - RNA_def_property_update(prop, 0, "rna_World_update"); - - prop = RNA_def_property(srna, "zenith_up_factor", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "zenupfac"); - RNA_def_property_ui_range(prop, 0, 1, 10, 3); - RNA_def_property_ui_text(prop, "Zenith Up Factor", "Amount texture affects color of the zenith above"); - RNA_def_property_update(prop, 0, "rna_World_update"); - - prop = RNA_def_property(srna, "zenith_down_factor", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "zendownfac"); - RNA_def_property_ui_range(prop, 0, 1, 10, 3); - RNA_def_property_ui_text(prop, "Zenith Down Factor", "Amount texture affects color of the zenith below"); - RNA_def_property_update(prop, 0, "rna_World_update"); -} - static void rna_def_lighting(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; - static const EnumPropertyItem blend_mode_items[] = { - {WO_AOMUL, "MULTIPLY", 0, "Multiply", "Multiply direct lighting with ambient occlusion, darkening the result"}, - {WO_AOADD, "ADD", 0, "Add", "Add light and shadow"}, - {0, NULL, 0, NULL, NULL} - }; - - static const EnumPropertyItem prop_color_items[] = { - {WO_AOPLAIN, "PLAIN", 0, "White", "Plain diffuse energy (white.)"}, - {WO_AOSKYCOL, "SKY_COLOR", 0, "Sky Color", "Use horizon and zenith color for diffuse energy"}, - {WO_AOSKYTEX, "SKY_TEXTURE", 0, "Sky Texture", "Does full Sky texture render for diffuse energy"}, - {0, NULL, 0, NULL, NULL} - }; - - static const EnumPropertyItem prop_sample_method_items[] = { - {WO_AOSAMP_CONSTANT, "CONSTANT_JITTERED", 0, "Constant Jittered", "Fastest and gives the most noise"}, - {WO_AOSAMP_HALTON, "ADAPTIVE_QMC", 0, "Adaptive QMC", "Fast in high-contrast areas"}, - {WO_AOSAMP_HAMMERSLEY, "CONSTANT_QMC", 0, "Constant QMC", "Best quality"}, - {0, NULL, 0, NULL, NULL} - }; - - static const EnumPropertyItem prop_gather_method_items[] = { - {WO_AOGATHER_RAYTRACE, "RAYTRACE", 0, "Raytrace", "Accurate, but slow when noise-free results are required"}, - {WO_AOGATHER_APPROX, "APPROXIMATE", 0, "Approximate", "Inaccurate, but faster and without noise"}, - {0, NULL, 0, NULL, NULL} - }; - srna = RNA_def_struct(brna, "WorldLighting", NULL); RNA_def_struct_sdna(srna, "World"); RNA_def_struct_nested(brna, srna, "World"); @@ -259,135 +131,12 @@ static void rna_def_lighting(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Factor", "Factor for ambient occlusion blending"); RNA_def_property_update(prop, 0, "rna_World_update"); - prop = RNA_def_property(srna, "ao_blend_type", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "aomix"); - RNA_def_property_enum_items(prop, blend_mode_items); - RNA_def_property_ui_text(prop, "Blend Mode", "Defines how AO mixes with material shading"); - RNA_def_property_update(prop, 0, "rna_World_update"); - - /* environment lighting */ - prop = RNA_def_property(srna, "use_environment_light", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mode", WO_ENV_LIGHT); - RNA_def_property_ui_text(prop, "Use Environment Lighting", "Add light coming from the environment"); - RNA_def_property_update(prop, 0, "rna_World_draw_update"); - - prop = RNA_def_property(srna, "environment_energy", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "ao_env_energy"); - RNA_def_property_ui_range(prop, 0, FLT_MAX, 1, 3); - RNA_def_property_ui_text(prop, "Environment Color", "Defines the strength of environment light"); - RNA_def_property_update(prop, 0, "rna_World_draw_update"); - - prop = RNA_def_property(srna, "environment_color", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "aocolor"); - RNA_def_property_enum_items(prop, prop_color_items); - RNA_def_property_ui_text(prop, "Environment Color", "Defines where the color of the environment light comes from"); - RNA_def_property_update(prop, 0, "rna_World_draw_update"); - - /* indirect lighting */ - prop = RNA_def_property(srna, "use_indirect_light", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mode", WO_INDIRECT_LIGHT); - RNA_def_property_ui_text(prop, "Use Indirect Lighting", "Add indirect light bouncing of surrounding objects"); - RNA_def_property_update(prop, 0, "rna_World_update"); - - prop = RNA_def_property(srna, "indirect_factor", PROP_FLOAT, PROP_FACTOR); - RNA_def_property_float_sdna(prop, NULL, "ao_indirect_energy"); - RNA_def_property_range(prop, 0, INT_MAX); - RNA_def_property_ui_range(prop, 0, 1, 0.1, 2); - RNA_def_property_ui_text(prop, "Indirect Factor", "Factor for how much surrounding objects contribute to light"); - RNA_def_property_update(prop, 0, "rna_World_update"); - - prop = RNA_def_property(srna, "indirect_bounces", PROP_INT, PROP_UNSIGNED); - RNA_def_property_int_sdna(prop, NULL, "ao_indirect_bounces"); - RNA_def_property_range(prop, 1, SHRT_MAX); - RNA_def_property_ui_text(prop, "Bounces", "Number of indirect diffuse light bounces"); - RNA_def_property_update(prop, 0, "rna_World_update"); - - /* gathering parameters */ - prop = RNA_def_property(srna, "gather_method", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "ao_gather_method"); - RNA_def_property_enum_items(prop, prop_gather_method_items); - RNA_def_property_ui_text(prop, "Gather Method", ""); - RNA_def_property_update(prop, 0, "rna_World_update"); - - prop = RNA_def_property(srna, "passes", PROP_INT, PROP_NONE); - RNA_def_property_int_sdna(prop, NULL, "ao_approx_passes"); - RNA_def_property_range(prop, 0, 10); - RNA_def_property_ui_text(prop, "Passes", "Number of preprocessing passes to reduce over-occlusion"); - RNA_def_property_update(prop, 0, "rna_World_update"); - prop = RNA_def_property(srna, "distance", PROP_FLOAT, PROP_DISTANCE); RNA_def_property_float_sdna(prop, NULL, "aodist"); RNA_def_property_ui_text(prop, "Distance", "Length of rays, defines how far away other faces give occlusion effect"); RNA_def_property_update(prop, 0, "rna_World_update"); - prop = RNA_def_property(srna, "falloff_strength", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "aodistfac"); - RNA_def_property_ui_text(prop, "Strength", - "Attenuation falloff strength, the higher, the less influence distant objects have"); - RNA_def_property_update(prop, 0, "rna_World_update"); - - prop = RNA_def_property(srna, "bias", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "aobias"); - RNA_def_property_range(prop, 0, 0.5); - RNA_def_property_ui_text(prop, "Bias", - "Bias (in radians) to prevent smoothed faces from showing banding " - "(for Raytrace Constant Jittered)"); - RNA_def_property_update(prop, 0, "rna_World_update"); - - prop = RNA_def_property(srna, "threshold", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "ao_adapt_thresh"); - RNA_def_property_range(prop, 0, 1); - RNA_def_property_ui_text(prop, "Threshold", - "Samples below this threshold will be considered fully shadowed/unshadowed and skipped " - "(for Raytrace Adaptive QMC)"); - RNA_def_property_update(prop, 0, "rna_World_update"); - - prop = RNA_def_property(srna, "adapt_to_speed", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "ao_adapt_speed_fac"); - RNA_def_property_range(prop, 0, 1); - RNA_def_property_ui_text(prop, "Adapt To Speed", - "Use the speed vector pass to reduce AO samples in fast moving pixels - " - "higher values result in more aggressive sample reduction " - "(requires Vec pass enabled, for Raytrace Adaptive QMC)"); - RNA_def_property_update(prop, 0, "rna_World_update"); - - prop = RNA_def_property(srna, "error_threshold", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "ao_approx_error"); - RNA_def_property_range(prop, 0.0001, 10); - RNA_def_property_ui_text(prop, "Error Tolerance", "Low values are slower and higher quality"); - RNA_def_property_update(prop, 0, "rna_World_update"); - - prop = RNA_def_property(srna, "correction", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "ao_approx_correction"); - RNA_def_property_range(prop, 0, 1); - RNA_def_property_ui_range(prop, 0, 1, 0.1, 2); - RNA_def_property_ui_text(prop, "Correction", "Ad-hoc correction for over-occlusion due to the approximation"); - RNA_def_property_update(prop, 0, "rna_World_update"); - - prop = RNA_def_property(srna, "use_falloff", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "aomode", WO_AODIST); - RNA_def_property_ui_text(prop, "Falloff", "Distance will be used to attenuate shadows"); - RNA_def_property_update(prop, 0, "rna_World_update"); - - prop = RNA_def_property(srna, "use_cache", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "aomode", WO_AOCACHE); - RNA_def_property_ui_text(prop, "Pixel Cache", - "Cache AO results in pixels and interpolate over neighboring pixels for speedup"); - RNA_def_property_update(prop, 0, "rna_World_update"); - - prop = RNA_def_property(srna, "samples", PROP_INT, PROP_NONE); - RNA_def_property_int_sdna(prop, NULL, "aosamp"); - RNA_def_property_range(prop, 1, 128); - RNA_def_property_ui_text(prop, "Samples", - "Amount of ray samples. Higher values give smoother results and longer rendering times"); - RNA_def_property_update(prop, 0, "rna_World_update"); - - prop = RNA_def_property(srna, "sample_method", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "ao_samp_method"); - RNA_def_property_enum_items(prop, prop_sample_method_items); - RNA_def_property_ui_text(prop, "Sample Method", "Method for generating shadow samples (for Raytrace)"); - RNA_def_property_update(prop, 0, "rna_World_update"); } static void rna_def_world_mist(BlenderRNA *brna) @@ -456,9 +205,6 @@ void RNA_def_world(BlenderRNA *brna) RNA_def_struct_ui_icon(srna, ICON_WORLD_DATA); rna_def_animdata_common(srna); - rna_def_mtex_common(brna, srna, "rna_World_mtex_begin", "rna_World_active_texture_get", - "rna_World_active_texture_set", NULL, "WorldTextureSlot", "WorldTextureSlots", - "rna_World_update", "rna_World_update"); /* colors */ prop = RNA_def_property(srna, "horizon_color", PROP_FLOAT, PROP_COLOR); @@ -469,47 +215,6 @@ void RNA_def_world(BlenderRNA *brna) /* render-only uses this */ RNA_def_property_update(prop, 0, "rna_World_draw_update"); - prop = RNA_def_property(srna, "zenith_color", PROP_FLOAT, PROP_COLOR); - RNA_def_property_float_sdna(prop, NULL, "zenr"); - RNA_def_property_array(prop, 3); - RNA_def_property_ui_text(prop, "Zenith Color", "Color at the zenith"); - RNA_def_property_update(prop, 0, "rna_World_draw_update"); - - prop = RNA_def_property(srna, "ambient_color", PROP_FLOAT, PROP_COLOR); - RNA_def_property_float_sdna(prop, NULL, "ambr"); - RNA_def_property_array(prop, 3); - RNA_def_property_ui_text(prop, "Ambient Color", "Ambient color of the world"); - RNA_def_property_update(prop, 0, "rna_World_draw_update"); - - /* exp, range */ - prop = RNA_def_property(srna, "exposure", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "exp"); - RNA_def_property_range(prop, 0.0, 1.0); - RNA_def_property_ui_text(prop, "Exposure", "Amount of exponential color correction for light"); - RNA_def_property_update(prop, 0, "rna_World_update"); - - prop = RNA_def_property(srna, "color_range", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "range"); - RNA_def_property_range(prop, 0.2, 5.0); - RNA_def_property_ui_text(prop, "Range", "The color range that will be mapped to 0-1"); - RNA_def_property_update(prop, 0, "rna_World_update"); - - /* sky type */ - prop = RNA_def_property(srna, "use_sky_blend", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "skytype", WO_SKYBLEND); - RNA_def_property_ui_text(prop, "Blend Sky", "Render background with natural progression from horizon to zenith"); - RNA_def_property_update(prop, NC_WORLD | ND_WORLD_DRAW, "rna_World_update"); - - prop = RNA_def_property(srna, "use_sky_paper", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "skytype", WO_SKYPAPER); - RNA_def_property_ui_text(prop, "Paper Sky", "Flatten blend or texture coordinates"); - RNA_def_property_update(prop, NC_WORLD | ND_WORLD_DRAW, "rna_World_update"); - - prop = RNA_def_property(srna, "use_sky_real", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "skytype", WO_SKYREAL); - RNA_def_property_ui_text(prop, "Real Sky", "Render background with a real horizon, relative to the camera angle"); - RNA_def_property_update(prop, NC_WORLD | ND_WORLD_DRAW, "rna_World_update"); - /* nested structs */ prop = RNA_def_property(srna, "light_settings", PROP_POINTER, PROP_NONE); RNA_def_property_flag(prop, PROP_NEVER_NULL); @@ -537,7 +242,6 @@ void RNA_def_world(BlenderRNA *brna) rna_def_lighting(brna); rna_def_world_mist(brna); - rna_def_world_mtex(brna); } #endif diff --git a/source/blender/modifiers/intern/MOD_dynamicpaint.c b/source/blender/modifiers/intern/MOD_dynamicpaint.c index 4335d488656..97e2bf42d66 100644 --- a/source/blender/modifiers/intern/MOD_dynamicpaint.c +++ b/source/blender/modifiers/intern/MOD_dynamicpaint.c @@ -68,9 +68,6 @@ static void copyData(ModifierData *md, ModifierData *target) id_us_plus((ID *)surface->init_texture); } } - if (tpmd->brush) { - id_us_plus((ID *)tpmd->brush->mat); - } } static void freeData(ModifierData *md) @@ -105,12 +102,6 @@ static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md) } } } - - if (pmd->brush) { - if (pmd->brush->flags & MOD_DPAINT_USE_MATERIAL) { - dataMask |= CD_MASK_MLOOPUV; - } - } return dataMask; } @@ -169,9 +160,6 @@ static void foreachIDLink(ModifierData *md, Object *ob, } } } - if (pmd->brush) { - walk(userData, ob, (ID **)&pmd->brush->mat, IDWALK_CB_USER); - } } static void foreachTexLink(ModifierData *UNUSED(md), Object *UNUSED(ob), diff --git a/source/blender/modifiers/intern/MOD_explode.c b/source/blender/modifiers/intern/MOD_explode.c index 041289bf70a..4c04eadb265 100644 --- a/source/blender/modifiers/intern/MOD_explode.c +++ b/source/blender/modifiers/intern/MOD_explode.c @@ -147,7 +147,7 @@ static void createFacepa(ExplodeModifierData *emd, /* make tree of emitter locations */ tree = BLI_kdtree_new(totpart); for (p = 0, pa = psys->particles; p < totpart; p++, pa++) { - psys_particle_on_emitter(psmd, psys->part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, co, NULL, NULL, NULL, NULL, NULL); + psys_particle_on_emitter(psmd, psys->part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, co, NULL, NULL, NULL, NULL); BLI_kdtree_insert(tree, p, co); } BLI_kdtree_balance(tree); diff --git a/source/blender/modifiers/intern/MOD_uvproject.c b/source/blender/modifiers/intern/MOD_uvproject.c index 386417e092a..cdad0a46dde 100644 --- a/source/blender/modifiers/intern/MOD_uvproject.c +++ b/source/blender/modifiers/intern/MOD_uvproject.c @@ -75,8 +75,6 @@ static void copyData(ModifierData *md, ModifierData *target) UVProjectModifierData *tumd = (UVProjectModifierData *) target; modifier_copyData_generic(md, target); - - id_us_plus((ID *)tumd->image); } static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *UNUSED(md)) @@ -104,8 +102,6 @@ static void foreachIDLink(ModifierData *md, Object *ob, { UVProjectModifierData *umd = (UVProjectModifierData *) md; - walk(userData, ob, (ID **)&umd->image, IDWALK_CB_USER); - foreachObjectLink(md, ob, (ObjectWalkFunc)walk, userData); } @@ -133,7 +129,6 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd, float (*coords)[3], (*co)[3]; MLoopUV *mloop_uv; int i, numVerts, numPolys, numLoops; - Image *image = umd->image; MPoly *mpoly, *mp; MLoop *mloop; Projector projectors[MOD_UVPROJECT_MAXPROJECTORS]; @@ -238,84 +233,73 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd, mpoly = dm->getPolyArray(dm); mloop = dm->getLoopArray(dm); - Image **ob_image_array = NULL; - if (image) { - ob_image_array = BKE_object_material_edit_image_get_array(ob); - } - - /* apply coords as UVs, and apply image if tfaces are new */ + /* apply coords as UVs */ for (i = 0, mp = mpoly; i < numPolys; ++i, ++mp) { - if (!image || (mp->mat_nr < ob->totcol ? ob_image_array[mp->mat_nr] : NULL) == image) { - if (num_projectors == 1) { - if (projectors[0].uci) { - unsigned int fidx = mp->totloop - 1; - do { - unsigned int lidx = mp->loopstart + fidx; - unsigned int vidx = mloop[lidx].v; - BLI_uvproject_from_camera(mloop_uv[lidx].uv, coords[vidx], projectors[0].uci); - } while (fidx--); - } - else { - /* apply transformed coords as UVs */ - unsigned int fidx = mp->totloop - 1; - do { - unsigned int lidx = mp->loopstart + fidx; - unsigned int vidx = mloop[lidx].v; - copy_v2_v2(mloop_uv[lidx].uv, coords[vidx]); - } while (fidx--); - } + if (num_projectors == 1) { + if (projectors[0].uci) { + unsigned int fidx = mp->totloop - 1; + do { + unsigned int lidx = mp->loopstart + fidx; + unsigned int vidx = mloop[lidx].v; + BLI_uvproject_from_camera(mloop_uv[lidx].uv, coords[vidx], projectors[0].uci); + } while (fidx--); } else { - /* multiple projectors, select the closest to face normal direction */ - float face_no[3]; - int j; - Projector *best_projector; - float best_dot; - - /* get the untransformed face normal */ - BKE_mesh_calc_poly_normal_coords(mp, mloop + mp->loopstart, (const float (*)[3])coords, face_no); - - /* find the projector which the face points at most directly - * (projector normal with largest dot product is best) - */ - best_dot = dot_v3v3(projectors[0].normal, face_no); - best_projector = &projectors[0]; - - for (j = 1; j < num_projectors; ++j) { - float tmp_dot = dot_v3v3(projectors[j].normal, - face_no); - if (tmp_dot > best_dot) { - best_dot = tmp_dot; - best_projector = &projectors[j]; - } + /* apply transformed coords as UVs */ + unsigned int fidx = mp->totloop - 1; + do { + unsigned int lidx = mp->loopstart + fidx; + unsigned int vidx = mloop[lidx].v; + copy_v2_v2(mloop_uv[lidx].uv, coords[vidx]); + } while (fidx--); + } + } + else { + /* multiple projectors, select the closest to face normal direction */ + float face_no[3]; + int j; + Projector *best_projector; + float best_dot; + + /* get the untransformed face normal */ + BKE_mesh_calc_poly_normal_coords(mp, mloop + mp->loopstart, (const float (*)[3])coords, face_no); + + /* find the projector which the face points at most directly + * (projector normal with largest dot product is best) + */ + best_dot = dot_v3v3(projectors[0].normal, face_no); + best_projector = &projectors[0]; + + for (j = 1; j < num_projectors; ++j) { + float tmp_dot = dot_v3v3(projectors[j].normal, + face_no); + if (tmp_dot > best_dot) { + best_dot = tmp_dot; + best_projector = &projectors[j]; } + } - if (best_projector->uci) { - unsigned int fidx = mp->totloop - 1; - do { - unsigned int lidx = mp->loopstart + fidx; - unsigned int vidx = mloop[lidx].v; - BLI_uvproject_from_camera(mloop_uv[lidx].uv, coords[vidx], best_projector->uci); - } while (fidx--); - } - else { - unsigned int fidx = mp->totloop - 1; - do { - unsigned int lidx = mp->loopstart + fidx; - unsigned int vidx = mloop[lidx].v; - mul_v2_project_m4_v3(mloop_uv[lidx].uv, best_projector->projmat, coords[vidx]); - } while (fidx--); - } + if (best_projector->uci) { + unsigned int fidx = mp->totloop - 1; + do { + unsigned int lidx = mp->loopstart + fidx; + unsigned int vidx = mloop[lidx].v; + BLI_uvproject_from_camera(mloop_uv[lidx].uv, coords[vidx], best_projector->uci); + } while (fidx--); + } + else { + unsigned int fidx = mp->totloop - 1; + do { + unsigned int lidx = mp->loopstart + fidx; + unsigned int vidx = mloop[lidx].v; + mul_v2_project_m4_v3(mloop_uv[lidx].uv, best_projector->projmat, coords[vidx]); + } while (fidx--); } } } MEM_freeN(coords); - if (ob_image_array) { - MEM_freeN(ob_image_array); - } - if (free_uci) { int j; for (j = 0; j < num_projectors; ++j) { diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt index ee70fcf510f..efe7db088f8 100644 --- a/source/blender/nodes/CMakeLists.txt +++ b/source/blender/nodes/CMakeLists.txt @@ -135,22 +135,17 @@ set(SRC shader/nodes/node_shader_curves.c shader/nodes/node_shader_gamma.c shader/nodes/node_shader_brightness.c - shader/nodes/node_shader_geom.c shader/nodes/node_shader_hueSatVal.c shader/nodes/node_shader_invert.c - shader/nodes/node_shader_lamp.c shader/nodes/node_shader_mapping.c - shader/nodes/node_shader_material.c shader/nodes/node_shader_math.c shader/nodes/node_shader_mixRgb.c shader/nodes/node_shader_normal.c - shader/nodes/node_shader_output.c shader/nodes/node_shader_rgb.c shader/nodes/node_shader_sepcombRGB.c shader/nodes/node_shader_sepcombHSV.c shader/nodes/node_shader_sepcombXYZ.c shader/nodes/node_shader_squeeze.c - shader/nodes/node_shader_texture.c shader/nodes/node_shader_valToRgb.c shader/nodes/node_shader_value.c shader/nodes/node_shader_wireframe.c diff --git a/source/blender/nodes/NOD_shader.h b/source/blender/nodes/NOD_shader.h index a507fdbd787..e411ceb6a23 100644 --- a/source/blender/nodes/NOD_shader.h +++ b/source/blender/nodes/NOD_shader.h @@ -44,20 +44,15 @@ void register_node_tree_type_sh(void); void register_node_type_sh_group(void); -void register_node_type_sh_output(void); -void register_node_type_sh_material(void); void register_node_type_sh_camera(void); -void register_node_type_sh_lamp(void); void register_node_type_sh_value(void); void register_node_type_sh_rgb(void); void register_node_type_sh_mix_rgb(void); void register_node_type_sh_valtorgb(void); void register_node_type_sh_rgbtobw(void); -void register_node_type_sh_texture(void); void register_node_type_sh_normal(void); void register_node_type_sh_gamma(void); void register_node_type_sh_brightcontrast(void); -void register_node_type_sh_geom(void); void register_node_type_sh_mapping(void); void register_node_type_sh_curve_vec(void); void register_node_type_sh_curve_rgb(void); @@ -65,7 +60,6 @@ void register_node_type_sh_math(void); void register_node_type_sh_vect_math(void); void register_node_type_sh_squeeze(void); void register_node_type_sh_dynamic(void); -void register_node_type_sh_material_ext(void); void register_node_type_sh_invert(void); void register_node_type_sh_seprgb(void); void register_node_type_sh_combrgb(void); diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h index 44713a7a000..299c3a627ee 100644 --- a/source/blender/nodes/NOD_static_types.h +++ b/source/blender/nodes/NOD_static_types.h @@ -40,27 +40,21 @@ DefNode( Node, NODE_GROUP_INPUT, def_group_input, "GROUP DefNode( Node, NODE_GROUP_OUTPUT, def_group_output, "GROUP_OUTPUT", GroupOutput, "Group Output", "" ) DefNode( Node, NODE_REROUTE, 0, "REROUTE", Reroute, "Reroute", "" ) -DefNode( ShaderNode, SH_NODE_OUTPUT, def_sh_output, "OUTPUT", Output, "Output", "" ) -DefNode( ShaderNode, SH_NODE_MATERIAL, def_sh_material, "MATERIAL", Material, "Material", "" ) DefNode( ShaderNode, SH_NODE_RGB, 0, "RGB", RGB, "RGB", "" ) DefNode( ShaderNode, SH_NODE_VALUE, 0, "VALUE", Value, "Value", "" ) DefNode( ShaderNode, SH_NODE_MIX_RGB, def_mix_rgb, "MIX_RGB", MixRGB, "MixRGB", "" ) DefNode( ShaderNode, SH_NODE_VALTORGB, def_colorramp, "VALTORGB", ValToRGB, "ColorRamp", "" ) DefNode( ShaderNode, SH_NODE_RGBTOBW, 0, "RGBTOBW", RGBToBW, "RGB to BW", "" ) -DefNode( ShaderNode, SH_NODE_TEXTURE, def_texture, "TEXTURE", Texture, "Texture", "" ) DefNode( ShaderNode, SH_NODE_NORMAL, 0, "NORMAL", Normal, "Normal", "" ) DefNode( ShaderNode, SH_NODE_GAMMA, 0, "GAMMA", Gamma, "Gamma", "" ) DefNode( ShaderNode, SH_NODE_BRIGHTCONTRAST, 0, "BRIGHTCONTRAST", BrightContrast, "Bright Contrast", "" ) -DefNode( ShaderNode, SH_NODE_GEOMETRY, def_sh_geometry, "GEOMETRY", Geometry, "Geometry", "" ) DefNode( ShaderNode, SH_NODE_MAPPING, def_sh_mapping, "MAPPING", Mapping, "Mapping", "" ) DefNode( ShaderNode, SH_NODE_CURVE_VEC, def_vector_curve, "CURVE_VEC", VectorCurve, "Vector Curves", "" ) DefNode( ShaderNode, SH_NODE_CURVE_RGB, def_rgb_curve, "CURVE_RGB", RGBCurve, "RGB Curves", "" ) DefNode( ShaderNode, SH_NODE_CAMERA, 0, "CAMERA", CameraData, "Camera Data", "" ) -DefNode( ShaderNode, SH_NODE_LAMP, def_sh_lamp, "LAMP", LampData, "Lamp Data", "" ) DefNode( ShaderNode, SH_NODE_MATH, def_math, "MATH", Math, "Math", "" ) DefNode( ShaderNode, SH_NODE_VECT_MATH, def_vector_math, "VECT_MATH", VectorMath, "Vector Math", "" ) DefNode( ShaderNode, SH_NODE_SQUEEZE, 0, "SQUEEZE", Squeeze, "Squeeze Value", "" ) -DefNode( ShaderNode, SH_NODE_MATERIAL_EXT, def_sh_material, "MATERIAL_EXT", ExtendedMaterial, "Extended Material", "" ) DefNode( ShaderNode, SH_NODE_INVERT, 0, "INVERT", Invert, "Invert", "" ) DefNode( ShaderNode, SH_NODE_SEPRGB, 0, "SEPRGB", SeparateRGB, "Separate RGB", "" ) DefNode( ShaderNode, SH_NODE_COMBRGB, 0, "COMBRGB", CombineRGB, "Combine RGB", "" ) diff --git a/source/blender/nodes/intern/node_exec.c b/source/blender/nodes/intern/node_exec.c index 0cf131adbdc..ac4031f4932 100644 --- a/source/blender/nodes/intern/node_exec.c +++ b/source/blender/nodes/intern/node_exec.c @@ -304,8 +304,6 @@ bool ntreeExecThreadNodes(bNodeTreeExec *exec, bNodeThreadStack *nts, void *call * If the mute func is not set, assume the node should never be muted, * and hence execute it! */ -// if (node->typeinfo->compatibility == NODE_NEW_SHADING) -// return false; if (node->typeinfo->execfunc && !(node->flag & NODE_MUTED)) node->typeinfo->execfunc(callerdata, thread, node, &nodeexec->data, nsin, nsout); } diff --git a/source/blender/nodes/shader/node_shader_tree.c b/source/blender/nodes/shader/node_shader_tree.c index 07fe49889a0..f4e084929cc 100644 --- a/source/blender/nodes/shader/node_shader_tree.c +++ b/source/blender/nodes/shader/node_shader_tree.c @@ -72,7 +72,6 @@ static int shader_tree_poll(const bContext *C, bNodeTreeType *UNUSED(treetype)) /* allow empty engine string too, this is from older versions that didn't have registerable engines yet */ return (engine_id[0] == '\0' || - STREQ(engine_id, RE_engine_id_BLENDER_RENDER) || STREQ(engine_id, RE_engine_id_CYCLES) || !BKE_scene_use_shading_nodes_custom(scene)); } @@ -84,9 +83,7 @@ static void shader_get_from_context(const bContext *C, bNodeTreeType *UNUSED(tre ViewLayer *view_layer = CTX_data_view_layer(C); Object *ob = OBACT(view_layer); - if ((snode->shaderfrom == SNODE_SHADER_OBJECT) || - (BKE_scene_use_new_shading_nodes(scene) == false)) - { + if (snode->shaderfrom == SNODE_SHADER_OBJECT) { if (ob) { *r_from = &ob->id; if (ob->type == OB_LAMP) { @@ -121,16 +118,12 @@ static void shader_get_from_context(const bContext *C, bNodeTreeType *UNUSED(tre } } -static void foreach_nodeclass(Scene *scene, void *calldata, bNodeClassCallback func) +static void foreach_nodeclass(Scene *UNUSED(scene), void *calldata, bNodeClassCallback func) { func(calldata, NODE_CLASS_INPUT, N_("Input")); func(calldata, NODE_CLASS_OUTPUT, N_("Output")); - - if (BKE_scene_use_new_shading_nodes(scene)) { - func(calldata, NODE_CLASS_SHADER, N_("Shader")); - func(calldata, NODE_CLASS_TEXTURE, N_("Texture")); - } - + func(calldata, NODE_CLASS_SHADER, N_("Shader")); + func(calldata, NODE_CLASS_TEXTURE, N_("Texture")); func(calldata, NODE_CLASS_OP_COLOR, N_("Color")); func(calldata, NODE_CLASS_OP_VECTOR, N_("Vector")); func(calldata, NODE_CLASS_CONVERTOR, N_("Convertor")); @@ -625,16 +618,6 @@ void ntreeGPUMaterialNodes(bNodeTree *ntree, GPUMaterial *mat, short compatibili MEM_freeN(localtree); } -/* **************** call to switch lamploop for material node ************ */ - -void (*node_shader_lamp_loop)(struct ShadeInput *, struct ShadeResult *); - -void set_node_shader_lamp_loop(void (*lamp_loop_func)(ShadeInput *, ShadeResult *)) -{ - node_shader_lamp_loop = lamp_loop_func; -} - - bNodeTreeExec *ntreeShaderBeginExecTree_internal(bNodeExecContext *context, bNodeTree *ntree, bNodeInstanceKey parent_key) { bNodeTreeExec *exec; @@ -709,26 +692,14 @@ void ntreeShaderEndExecTree(bNodeTreeExec *exec) } } -/* only for Blender internal */ -bool ntreeShaderExecTree(bNodeTree *ntree, ShadeInput *shi, ShadeResult *shr) +/* TODO: left over from Blender Internal, could reuse for new texture nodes. */ +bool ntreeShaderExecTree(bNodeTree *ntree, int thread) { ShaderCallData scd; - /** - * \note: preserve material from ShadeInput for material id, nodetree execs change it - * fix for bug "[#28012] Mat ID messy with shader nodes" - */ - Material *mat = shi->mat; bNodeThreadStack *nts = NULL; bNodeTreeExec *exec = ntree->execdata; int compat; - /* convert caller data to struct */ - scd.shi = shi; - scd.shr = shr; - - /* each material node has own local shaderesult, with optional copying */ - memset(shr, 0, sizeof(ShadeResult)); - /* ensure execdata is only initialized once */ if (!exec) { BLI_thread_lock(LOCK_NODES); @@ -739,18 +710,10 @@ bool ntreeShaderExecTree(bNodeTree *ntree, ShadeInput *shi, ShadeResult *shr) exec = ntree->execdata; } - nts = ntreeGetThreadStack(exec, shi->thread); - compat = ntreeExecThreadNodes(exec, nts, &scd, shi->thread); + nts = ntreeGetThreadStack(exec, thread); + compat = ntreeExecThreadNodes(exec, nts, &scd, thread); ntreeReleaseThreadStack(nts); - // \note: set material back to preserved material - shi->mat = mat; - - /* better not allow negative for now */ - if (shr->combined[0] < 0.0f) shr->combined[0] = 0.0f; - if (shr->combined[1] < 0.0f) shr->combined[1] = 0.0f; - if (shr->combined[2] < 0.0f) shr->combined[2] = 0.0f; - /* if compat is zero, it has been using non-compatible nodes */ return compat; } diff --git a/source/blender/nodes/shader/node_shader_util.c b/source/blender/nodes/shader/node_shader_util.c index 22171f28790..69a69c156e3 100644 --- a/source/blender/nodes/shader/node_shader_util.c +++ b/source/blender/nodes/shader/node_shader_util.c @@ -91,53 +91,6 @@ void nodestack_get_vec(float *in, short type_in, bNodeStack *ns) } -/* go over all used Geometry and Texture nodes, and return a texco flag */ -/* no group inside needed, this function is called for groups too */ -void ntreeShaderGetTexcoMode(bNodeTree *ntree, int r_mode, short *texco, int *mode) -{ - bNode *node; - bNodeSocket *sock; - int a; - - for (node = ntree->nodes.first; node; node = node->next) { - if (node->type == SH_NODE_TEXTURE) { - if ((r_mode & R_OSA) && node->id) { - Tex *tex = (Tex *)node->id; - if (ELEM(tex->type, TEX_IMAGE, TEX_ENVMAP)) { - *texco |= TEXCO_OSA | NEED_UV; - } - } - /* usability exception... without input we still give the node orcos */ - sock = node->inputs.first; - if (sock == NULL || sock->link == NULL) - *texco |= TEXCO_ORCO | NEED_UV; - } - else if (node->type == SH_NODE_GEOMETRY) { - /* note; sockets always exist for the given type! */ - for (a = 0, sock = node->outputs.first; sock; sock = sock->next, a++) { - if (sock->flag & SOCK_IN_USE) { - switch (a) { - case GEOM_OUT_GLOB: - *texco |= TEXCO_GLOB | NEED_UV; break; - case GEOM_OUT_VIEW: - *texco |= TEXCO_VIEW | NEED_UV; break; - case GEOM_OUT_ORCO: - *texco |= TEXCO_ORCO | NEED_UV; break; - case GEOM_OUT_UV: - *texco |= TEXCO_UV | NEED_UV; break; - case GEOM_OUT_NORMAL: - *texco |= TEXCO_NORM | NEED_UV; break; - case GEOM_OUT_VCOL: - *texco |= NEED_UV; *mode |= MA_VERTEXCOL; break; - case GEOM_OUT_VCOL_ALPHA: - *texco |= NEED_UV; *mode |= MA_VERTEXCOL; break; - } - } - } - } - } -} - void node_gpu_stack_from_data(struct GPUNodeStack *gs, int type, bNodeStack *ns) { memset(gs, 0, sizeof(*gs)); diff --git a/source/blender/nodes/shader/node_shader_util.h b/source/blender/nodes/shader/node_shader_util.h index 2363addb56a..94f89443b1d 100644 --- a/source/blender/nodes/shader/node_shader_util.h +++ b/source/blender/nodes/shader/node_shader_util.h @@ -77,7 +77,6 @@ #include "RE_pipeline.h" #include "RE_shader_ext.h" -#include "GPU_lamp.h" #include "GPU_material.h" #include "GPU_uniformbuffer.h" @@ -89,11 +88,9 @@ void sh_node_type_base(struct bNodeType *ntype, int type, const char *name, shor /* ********* exec data struct, remains internal *********** */ typedef struct ShaderCallData { - ShadeInput *shi; /* from render pipe */ - ShadeResult *shr; /* from render pipe */ + /* Empty for now, may be reused if we convert shader to texture nodes. */ } ShaderCallData; - void nodestack_get_vec(float *in, short type_in, bNodeStack *ns); void node_gpu_stack_from_data(struct GPUNodeStack *gs, int type, struct bNodeStack *ns); diff --git a/source/blender/nodes/shader/nodes/node_shader_camera.c b/source/blender/nodes/shader/nodes/node_shader_camera.c index ac0880d22ba..245360e789f 100644 --- a/source/blender/nodes/shader/nodes/node_shader_camera.c +++ b/source/blender/nodes/shader/nodes/node_shader_camera.c @@ -40,28 +40,12 @@ static bNodeSocketTemplate sh_node_camera_out[] = { { -1, 0, "" } }; - -static void node_shader_exec_camera(void *data, int UNUSED(thread), bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), bNodeStack **UNUSED(in), bNodeStack **out) -{ - if (data) { - ShadeInput *shi = ((ShaderCallData *)data)->shi; /* Data we need for shading. */ - - copy_v3_v3(out[0]->vec, shi->co); /* get view vector */ - out[1]->vec[0] = fabsf(shi->co[2]); /* get view z-depth */ - out[2]->vec[0] = normalize_v3(out[0]->vec); /* get view distance */ - } -} - static int gpu_shader_camera(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out) { GPUNodeLink *viewvec; viewvec = GPU_builtin(GPU_VIEW_POSITION); - - /* Blender has negative Z, Cycles positive Z convention */ - if (GPU_material_use_new_shading_nodes(mat)) - GPU_link(mat, "invert_z", viewvec, &viewvec); - + GPU_link(mat, "invert_z", viewvec, &viewvec); return GPU_stack_link(mat, node, "camera", in, out, viewvec); } @@ -73,7 +57,6 @@ void register_node_type_sh_camera(void) node_type_compatibility(&ntype, NODE_OLD_SHADING | NODE_NEW_SHADING); node_type_socket_templates(&ntype, NULL, sh_node_camera_out); node_type_storage(&ntype, "", NULL, NULL); - node_type_exec(&ntype, NULL, NULL, node_shader_exec_camera); node_type_gpu(&ntype, gpu_shader_camera); nodeRegisterType(&ntype); diff --git a/source/blender/nodes/shader/nodes/node_shader_fresnel.c b/source/blender/nodes/shader/nodes/node_shader_fresnel.c index b285f1a8a3e..30bdf0b0f42 100644 --- a/source/blender/nodes/shader/nodes/node_shader_fresnel.c +++ b/source/blender/nodes/shader/nodes/node_shader_fresnel.c @@ -44,40 +44,15 @@ static int node_shader_gpu_fresnel(GPUMaterial *mat, bNode *node, bNodeExecData if (!in[1].link) { in[1].link = GPU_builtin(GPU_VIEW_NORMAL); } - else if (GPU_material_use_world_space_shading(mat)) { + else { GPU_link(mat, "direction_transform_m4v3", in[1].link, GPU_builtin(GPU_VIEW_MATRIX), &in[1].link); } return GPU_stack_link(mat, node, "node_fresnel", in, out, GPU_builtin(GPU_VIEW_POSITION)); } -static void node_shader_exec_fresnel(void *data, int UNUSED(thread), bNode *node, bNodeExecData *UNUSED(execdata), bNodeStack **in, bNodeStack **out) +static void node_shader_exec_fresnel(void *UNUSED(data), int UNUSED(thread), bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), bNodeStack **UNUSED(in), bNodeStack **UNUSED(out)) { - ShadeInput *shi = ((ShaderCallData *)data)->shi; - - /* Compute IOR. */ - float eta; - nodestack_get_vec(&eta, SOCK_FLOAT, in[0]); - eta = max_ff(eta, 0.00001); - eta = shi->flippednor ? 1 / eta : eta; - - /* Get normal from socket, but only if linked. */ - bNodeSocket *sock_normal = node->inputs.first; - sock_normal = sock_normal->next; - - float n[3]; - if (sock_normal->link) { - nodestack_get_vec(n, SOCK_VECTOR, in[1]); - } - else { - copy_v3_v3(n, shi->vn); - } - - if (shi->use_world_space_shading) { - mul_mat3_m4_v3((float (*)[4])RE_render_current_get_matrix(RE_VIEW_MATRIX), n); - } - - out[0]->vec[0] = RE_fresnel_dielectric(shi->view, n, eta); } /* node type definition */ diff --git a/source/blender/nodes/shader/nodes/node_shader_geom.c b/source/blender/nodes/shader/nodes/node_shader_geom.c deleted file mode 100644 index 57bef4a6784..00000000000 --- a/source/blender/nodes/shader/nodes/node_shader_geom.c +++ /dev/null @@ -1,163 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2005 Blender Foundation. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/nodes/shader/nodes/node_shader_geom.c - * \ingroup shdnodes - */ - - -#include "node_shader_util.h" - -#include "DNA_customdata_types.h" - -/* **************** GEOMETRY ******************** */ - -/* output socket type definition */ -static bNodeSocketTemplate sh_node_geom_out[] = { - { SOCK_VECTOR, 0, N_("Global")}, - { SOCK_VECTOR, 0, N_("Local")}, - { SOCK_VECTOR, 0, N_("View")}, - { SOCK_VECTOR, 0, N_("Orco")}, - { SOCK_VECTOR, 0, N_("UV")}, - { SOCK_VECTOR, 0, N_("Normal")}, - { SOCK_RGBA, 0, N_("Vertex Color")}, - { SOCK_FLOAT, 0, N_("Vertex Alpha")}, - { SOCK_FLOAT, 0, N_("Front/Back")}, - { -1, 0, "" } -}; - -/* node execute callback */ -static void node_shader_exec_geom(void *data, int UNUSED(thread), bNode *node, bNodeExecData *UNUSED(execdata), bNodeStack **UNUSED(in), bNodeStack **out) -{ - if (data) { - ShadeInput *shi = ((ShaderCallData *)data)->shi; - NodeGeometry *ngeo = (NodeGeometry *)node->storage; - ShadeInputUV *suv = &shi->uv[shi->actuv]; - static float defaultvcol[4] = {1.0f, 1.0f, 1.0f, 1.0f}; - int i; - - if (ngeo->uvname[0]) { - /* find uv map by name */ - for (i = 0; i < shi->totuv; i++) { - if (STREQ(shi->uv[i].name, ngeo->uvname)) { - suv = &shi->uv[i]; - break; - } - } - } - - /* out: global, local, view, orco, uv, normal, vertex color */ - copy_v3_v3(out[GEOM_OUT_GLOB]->vec, shi->gl); - copy_v3_v3(out[GEOM_OUT_LOCAL]->vec, shi->co); - copy_v3_v3(out[GEOM_OUT_VIEW]->vec, shi->view); - copy_v3_v3(out[GEOM_OUT_ORCO]->vec, shi->lo); - copy_v3_v3(out[GEOM_OUT_UV]->vec, suv->uv); - copy_v3_v3(out[GEOM_OUT_NORMAL]->vec, shi->vno); - - if (shi->use_world_space_shading) { - negate_v3(out[GEOM_OUT_NORMAL]->vec); - mul_mat3_m4_v3((float (*)[4])RE_render_current_get_matrix(RE_VIEWINV_MATRIX), out[GEOM_OUT_NORMAL]->vec); - } - if (shi->totcol) { - /* find vertex color layer by name */ - ShadeInputCol *scol = &shi->col[0]; - - if (ngeo->colname[0]) { - for (i = 0; i < shi->totcol; i++) { - if (STREQ(shi->col[i].name, ngeo->colname)) { - scol = &shi->col[i]; - break; - } - } - } - - srgb_to_linearrgb_v3_v3(out[GEOM_OUT_VCOL]->vec, scol->col); - out[GEOM_OUT_VCOL]->vec[3] = scol->col[3]; - out[GEOM_OUT_VCOL_ALPHA]->vec[0] = scol->col[3]; - } - else { - memcpy(out[GEOM_OUT_VCOL]->vec, defaultvcol, sizeof(defaultvcol)); - out[GEOM_OUT_VCOL_ALPHA]->vec[0] = 1.0f; - } - - if (shi->osatex) { - out[GEOM_OUT_GLOB]->data = shi->dxgl; - out[GEOM_OUT_GLOB]->datatype = NS_OSA_VECTORS; - out[GEOM_OUT_LOCAL]->data = shi->dxco; - out[GEOM_OUT_LOCAL]->datatype = NS_OSA_VECTORS; - out[GEOM_OUT_VIEW]->data = &shi->dxview; - out[GEOM_OUT_VIEW]->datatype = NS_OSA_VALUES; - out[GEOM_OUT_ORCO]->data = shi->dxlo; - out[GEOM_OUT_ORCO]->datatype = NS_OSA_VECTORS; - out[GEOM_OUT_UV]->data = suv->dxuv; - out[GEOM_OUT_UV]->datatype = NS_OSA_VECTORS; - out[GEOM_OUT_NORMAL]->data = shi->dxno; - out[GEOM_OUT_NORMAL]->datatype = NS_OSA_VECTORS; - } - - /* front/back, normal flipping was stored */ - out[GEOM_OUT_FRONTBACK]->vec[0] = (shi->flippednor) ? 0.0f : 1.0f; - } -} - -static void node_shader_init_geometry(bNodeTree *UNUSED(ntree), bNode *node) -{ - node->storage = MEM_callocN(sizeof(NodeGeometry), "NodeGeometry"); -} - -static int gpu_shader_geom(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out) -{ - NodeGeometry *ngeo = (NodeGeometry *)node->storage; - GPUNodeLink *orco = GPU_attribute(CD_ORCO, ""); - GPUNodeLink *mtface = GPU_attribute(CD_MTFACE, ngeo->uvname); - GPUNodeLink *mcol = GPU_attribute(CD_MCOL, ngeo->colname); - - bool ret = GPU_stack_link(mat, node, "geom", in, out, - GPU_builtin(GPU_VIEW_POSITION), GPU_builtin(GPU_VIEW_NORMAL), - GPU_builtin(GPU_INVERSE_VIEW_MATRIX), orco, mtface, mcol); - if (GPU_material_use_world_space_shading(mat)) { - GPU_link(mat, "vec_math_negate", out[5].link, &out[5].link); - ret &= GPU_link(mat, "direction_transform_m4v3", out[5].link, GPU_builtin(GPU_INVERSE_VIEW_MATRIX), &out[5].link); - } - return ret; -} - -/* node type definition */ -void register_node_type_sh_geom(void) -{ - static bNodeType ntype; - - sh_node_type_base(&ntype, SH_NODE_GEOMETRY, "Geometry", NODE_CLASS_INPUT, 0); - node_type_compatibility(&ntype, NODE_OLD_SHADING); - node_type_socket_templates(&ntype, NULL, sh_node_geom_out); - node_type_init(&ntype, node_shader_init_geometry); - node_type_storage(&ntype, "NodeGeometry", node_free_standard_storage, node_copy_standard_storage); - node_type_exec(&ntype, NULL, NULL, node_shader_exec_geom); - node_type_gpu(&ntype, gpu_shader_geom); - - nodeRegisterType(&ntype); -} diff --git a/source/blender/nodes/shader/nodes/node_shader_lamp.c b/source/blender/nodes/shader/nodes/node_shader_lamp.c deleted file mode 100644 index 3c41227ab8b..00000000000 --- a/source/blender/nodes/shader/nodes/node_shader_lamp.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2013 Blender Foundation. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/nodes/shader/nodes/node_shader_lamp.c - * \ingroup shdnodes - */ - - -#include "node_shader_util.h" - -/* **************** LAMP INFO ******************** */ -static bNodeSocketTemplate sh_node_lamp_out[] = { - { SOCK_RGBA, 0, N_("Color")}, - { SOCK_VECTOR, 0, N_("Light Vector")}, - { SOCK_FLOAT, 0, N_("Distance")}, - { SOCK_RGBA, 0, N_("Shadow")}, - { SOCK_FLOAT, 0, N_("Visibility Factor")}, - { -1, 0, "" } -}; - - -static void node_shader_exec_lamp(void *data, int UNUSED(thread), bNode *node, bNodeExecData *UNUSED(execdata), bNodeStack **UNUSED(in), bNodeStack **out) -{ - if (data) { - Object *ob = (Object *)node->id; - - if (ob) { - ShadeInput *shi = ((ShaderCallData *)data)->shi; - - shi->nodes = 1; /* temp hack to prevent trashadow recursion */ - out[4]->vec[0] = RE_lamp_get_data(shi, ob, out[0]->vec, out[1]->vec, out[2]->vec, out[3]->vec); - shi->nodes = 0; - if (shi->use_world_space_shading) - mul_mat3_m4_v3((float (*)[4])RE_render_current_get_matrix(RE_VIEWINV_MATRIX), out[1]->vec); - } - } -} - -static int gpu_shader_lamp(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out) -{ - if (node->id) { - GPULamp *lamp = GPU_lamp_from_blender(GPU_material_scene(mat), (Object *)node->id, NULL); - GPUNodeLink *col, *lv, *dist, *visifac, *shadow, *energy; - - visifac = GPU_lamp_get_data(mat, lamp, &col, &lv, &dist, &shadow, &energy); - - bool ret = GPU_stack_link(mat, node, "lamp", in, out, col, energy, lv, dist, shadow, visifac); - if (GPU_material_use_world_space_shading(mat)) - ret &= GPU_link(mat, "direction_transform_m4v3", out[1].link, GPU_builtin(GPU_INVERSE_VIEW_MATRIX), &out[1].link); - return ret; - } - - return false; -} - -void register_node_type_sh_lamp(void) -{ - static bNodeType ntype; - - sh_node_type_base(&ntype, SH_NODE_LAMP, "Lamp Data", NODE_CLASS_INPUT, 0); - node_type_compatibility(&ntype, NODE_OLD_SHADING); - node_type_socket_templates(&ntype, NULL, sh_node_lamp_out); - node_type_exec(&ntype, NULL, NULL, node_shader_exec_lamp); - node_type_gpu(&ntype, gpu_shader_lamp); - - nodeRegisterType(&ntype); -} diff --git a/source/blender/nodes/shader/nodes/node_shader_layer_weight.c b/source/blender/nodes/shader/nodes/node_shader_layer_weight.c index 3ab73fdde18..87ed85ffa99 100644 --- a/source/blender/nodes/shader/nodes/node_shader_layer_weight.c +++ b/source/blender/nodes/shader/nodes/node_shader_layer_weight.c @@ -43,50 +43,18 @@ static bNodeSocketTemplate sh_node_layer_weight_out[] = { static int node_shader_gpu_layer_weight(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out) { - if (!in[1].link) + if (!in[1].link) { in[1].link = GPU_builtin(GPU_VIEW_NORMAL); - else if (GPU_material_use_world_space_shading(mat)) { + } + else { GPU_link(mat, "direction_transform_m4v3", in[1].link, GPU_builtin(GPU_VIEW_MATRIX), &in[1].link); } return GPU_stack_link(mat, node, "node_layer_weight", in, out, GPU_builtin(GPU_VIEW_POSITION)); } -static void node_shader_exec_layer_weight(void *data, int UNUSED(thread), bNode *node, bNodeExecData *UNUSED(execdata), bNodeStack **in, bNodeStack **out) +static void node_shader_exec_layer_weight(void *UNUSED(data), int UNUSED(thread), bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), bNodeStack **UNUSED(in), bNodeStack **UNUSED(out)) { - ShadeInput *shi = ((ShaderCallData *)data)->shi; - - /* Compute IOR. */ - float blend; - nodestack_get_vec(&blend, SOCK_FLOAT, in[0]); - float eta = max_ff(1 - blend, 0.00001); - eta = shi->flippednor ? eta : 1 / eta; - - /* Get normal from socket, but only if linked. */ - bNodeSocket *sock_normal = node->inputs.first; - sock_normal = sock_normal->next; - - float n[3]; - if (sock_normal->link) { - nodestack_get_vec(n, SOCK_VECTOR, in[1]); - } - else { - copy_v3_v3(n, shi->vn); - } - - - if (shi->use_world_space_shading) - mul_mat3_m4_v3((float (*)[4])RE_render_current_get_matrix(RE_VIEW_MATRIX), n); - - out[0]->vec[0] = RE_fresnel_dielectric(shi->view, n, eta); - - float facing = fabs(dot_v3v3(shi->view, n)); - if (blend != 0.5) { - CLAMP(blend, 0.0, 0.99999); - blend = (blend < 0.5) ? 2.0 * blend : 0.5 / (1.0 - blend); - facing = pow(facing, blend); - } - out[1]->vec[0] = 1.0 - facing; } /* node type definition */ diff --git a/source/blender/nodes/shader/nodes/node_shader_material.c b/source/blender/nodes/shader/nodes/node_shader_material.c deleted file mode 100644 index 6850cdbf6ea..00000000000 --- a/source/blender/nodes/shader/nodes/node_shader_material.c +++ /dev/null @@ -1,374 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2005 Blender Foundation. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/nodes/shader/nodes/node_shader_material.c - * \ingroup shdnodes - */ - -#include "node_shader_util.h" - -/* **************** MATERIAL ******************** */ - -static bNodeSocketTemplate sh_node_material_in[] = { - { SOCK_RGBA, 1, N_("Color"), 0.0f, 0.0f, 0.0f, 1.0f}, - { SOCK_RGBA, 1, N_("Spec"), 0.0f, 0.0f, 0.0f, 1.0f}, - { SOCK_FLOAT, 1, N_("DiffuseIntensity"), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_NONE}, - { SOCK_VECTOR, 1, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_DIRECTION}, - { -1, 0, "" } -}; - -static bNodeSocketTemplate sh_node_material_out[] = { - { SOCK_RGBA, 0, N_("Color")}, - { SOCK_FLOAT, 0, N_("Alpha")}, - { SOCK_VECTOR, 0, N_("Normal")}, - { -1, 0, "" } -}; - -/* **************** EXTENDED MATERIAL ******************** */ - -static bNodeSocketTemplate sh_node_material_ext_in[] = { - { SOCK_RGBA, 1, N_("Color"), 0.0f, 0.0f, 0.0f, 1.0f}, - { SOCK_RGBA, 1, N_("Spec"), 0.0f, 0.0f, 0.0f, 1.0f}, - { SOCK_FLOAT, 1, N_("DiffuseIntensity"), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_NONE}, - { SOCK_VECTOR, 1, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_DIRECTION}, - { SOCK_RGBA, 1, N_("Mirror"), 0.0f, 0.0f, 0.0f, 1.0f}, - { SOCK_FLOAT, 1, N_("Ambient"), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_NONE}, - { SOCK_FLOAT, 1, N_("Emit"), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_UNSIGNED}, - { SOCK_FLOAT, 1, N_("SpecTra"), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_NONE}, - { SOCK_FLOAT, 1, N_("Reflectivity"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE}, - { SOCK_FLOAT, 1, N_("Alpha"), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_UNSIGNED}, - { SOCK_FLOAT, 1, N_("Translucency"), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_NONE}, - { -1, 0, "" } -}; - -static bNodeSocketTemplate sh_node_material_ext_out[] = { - { SOCK_RGBA, 0, N_("Color")}, - { SOCK_FLOAT, 0, N_("Alpha")}, - { SOCK_VECTOR, 0, N_("Normal")}, - { SOCK_RGBA, 0, N_("Diffuse")}, - { SOCK_RGBA, 0, N_("Spec")}, - { SOCK_RGBA, 0, N_("AO")}, - { -1, 0, "" } -}; - -static void node_shader_exec_material(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out) -{ - if (data && node->id) { - ShadeResult shrnode; - ShadeInput *shi; - ShaderCallData *shcd = data; - float col[4]; - bNodeSocket *sock; - char hasinput[NUM_MAT_IN] = {'\0'}; - int i, mode; - - /* note: cannot use the in[]->hasinput flags directly, as these are not necessarily - * the constant input stack values (e.g. in case material node is inside a group). - * we just want to know if a node input uses external data or the material setting. - * this is an ugly hack, but so is this node as a whole. - */ - for (sock = node->inputs.first, i = 0; sock; sock = sock->next, ++i) - hasinput[i] = (sock->link != NULL); - - shi = shcd->shi; - shi->mat = (Material *)node->id; - - /* copy all relevant material vars, note, keep this synced with render_types.h */ - memcpy(&shi->r, &shi->mat->r, 23 * sizeof(float)); - shi->har = shi->mat->har; - - /* write values */ - if (hasinput[MAT_IN_COLOR]) - nodestack_get_vec(&shi->r, SOCK_VECTOR, in[MAT_IN_COLOR]); - - if (hasinput[MAT_IN_SPEC]) - nodestack_get_vec(&shi->specr, SOCK_VECTOR, in[MAT_IN_SPEC]); - - if (hasinput[MAT_IN_REFL]) - nodestack_get_vec(&shi->refl, SOCK_FLOAT, in[MAT_IN_REFL]); - - /* retrieve normal */ - if (hasinput[MAT_IN_NORMAL]) { - nodestack_get_vec(shi->vn, SOCK_VECTOR, in[MAT_IN_NORMAL]); - if (shi->use_world_space_shading) { - negate_v3(shi->vn); - mul_mat3_m4_v3((float (*)[4])RE_render_current_get_matrix(RE_VIEW_MATRIX), shi->vn); - } - normalize_v3(shi->vn); - } - else - copy_v3_v3(shi->vn, shi->vno); - - /* custom option to flip normal */ - if (node->custom1 & SH_NODE_MAT_NEG) { - negate_v3(shi->vn); - } - - if (node->type == SH_NODE_MATERIAL_EXT) { - if (hasinput[MAT_IN_MIR]) - nodestack_get_vec(&shi->mirr, SOCK_VECTOR, in[MAT_IN_MIR]); - if (hasinput[MAT_IN_AMB]) - nodestack_get_vec(&shi->amb, SOCK_FLOAT, in[MAT_IN_AMB]); - if (hasinput[MAT_IN_EMIT]) - nodestack_get_vec(&shi->emit, SOCK_FLOAT, in[MAT_IN_EMIT]); - if (hasinput[MAT_IN_SPECTRA]) - nodestack_get_vec(&shi->spectra, SOCK_FLOAT, in[MAT_IN_SPECTRA]); - if (hasinput[MAT_IN_RAY_MIRROR]) - nodestack_get_vec(&shi->ray_mirror, SOCK_FLOAT, in[MAT_IN_RAY_MIRROR]); - if (hasinput[MAT_IN_ALPHA]) - nodestack_get_vec(&shi->alpha, SOCK_FLOAT, in[MAT_IN_ALPHA]); - if (hasinput[MAT_IN_TRANSLUCENCY]) - nodestack_get_vec(&shi->translucency, SOCK_FLOAT, in[MAT_IN_TRANSLUCENCY]); - } - - /* make alpha output give results even if transparency is only enabled on - * the material linked in this not and not on the parent material */ - mode = shi->mode; - if (shi->mat->mode & MA_TRANSP) - shi->mode |= MA_TRANSP; - - shi->nodes = 1; /* temp hack to prevent trashadow recursion */ - node_shader_lamp_loop(shi, &shrnode); /* clears shrnode */ - shi->nodes = 0; - - shi->mode = mode; - - /* write to outputs */ - if (node->custom1 & SH_NODE_MAT_DIFF) { - copy_v3_v3(col, shrnode.combined); - if (!(node->custom1 & SH_NODE_MAT_SPEC)) { - sub_v3_v3(col, shrnode.spec); - } - } - else if (node->custom1 & SH_NODE_MAT_SPEC) { - copy_v3_v3(col, shrnode.spec); - } - else - col[0] = col[1] = col[2] = 0.0f; - - col[3] = shrnode.alpha; - - if (shi->do_preview) - BKE_node_preview_set_pixel(execdata->preview, col, shi->xs, shi->ys, shi->do_manage); - - copy_v3_v3(out[MAT_OUT_COLOR]->vec, col); - out[MAT_OUT_ALPHA]->vec[0] = shrnode.alpha; - - if (node->custom1 & SH_NODE_MAT_NEG) { - shi->vn[0] = -shi->vn[0]; - shi->vn[1] = -shi->vn[1]; - shi->vn[2] = -shi->vn[2]; - } - - copy_v3_v3(out[MAT_OUT_NORMAL]->vec, shi->vn); - - if (shi->use_world_space_shading) { - negate_v3(out[MAT_OUT_NORMAL]->vec); - mul_mat3_m4_v3((float (*)[4])RE_render_current_get_matrix(RE_VIEWINV_MATRIX), out[MAT_OUT_NORMAL]->vec); - } - /* Extended material options */ - if (node->type == SH_NODE_MATERIAL_EXT) { - /* Shadow, Reflect, Refract, Radiosity, Speed seem to cause problems inside - * a node tree :( */ - copy_v3_v3(out[MAT_OUT_DIFFUSE]->vec, shrnode.diffshad); - copy_v3_v3(out[MAT_OUT_SPEC]->vec, shrnode.spec); - copy_v3_v3(out[MAT_OUT_AO]->vec, shrnode.ao); - } - - /* copy passes, now just active node */ - if (node->flag & NODE_ACTIVE_ID) { - float combined[4], alpha; - - copy_v4_v4(combined, shcd->shr->combined); - alpha = shcd->shr->alpha; - - *(shcd->shr) = shrnode; - - copy_v4_v4(shcd->shr->combined, combined); - shcd->shr->alpha = alpha; - } - } -} - - -static void node_shader_init_material(bNodeTree *UNUSED(ntree), bNode *node) -{ - node->custom1 = SH_NODE_MAT_DIFF | SH_NODE_MAT_SPEC; -} - -/* XXX this is also done as a local static function in gpu_codegen.c, - * but we need this to hack around the crappy material node. - */ -static GPUNodeLink *gpu_get_input_link(GPUMaterial *mat, GPUNodeStack *in) -{ - if (in->link) { - return in->link; - } - else { - GPUNodeLink *result = NULL; - - /* note GPU_uniform() is only intended to be used as a parameter to - * GPU_link(), returning it directly results in leaks or double frees */ - if (in->type == GPU_FLOAT) - GPU_link(mat, "set_value", GPU_uniform(in->vec), &result); - else if (in->type == GPU_VEC3) - GPU_link(mat, "set_rgb", GPU_uniform(in->vec), &result); - else if (in->type == GPU_VEC4) - GPU_link(mat, "set_rgba", GPU_uniform(in->vec), &result); - else - BLI_assert(0); - - return result; - } -} - -static int gpu_shader_material(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out) -{ - if (node->id) { - GPUShadeInput shi; - GPUShadeResult shr; - bNodeSocket *sock; - char hasinput[NUM_MAT_IN] = {'\0'}; - int i; - - /* note: cannot use the in[]->hasinput flags directly, as these are not necessarily - * the constant input stack values (e.g. in case material node is inside a group). - * we just want to know if a node input uses external data or the material setting. - */ - for (sock = node->inputs.first, i = 0; sock; sock = sock->next, ++i) - hasinput[i] = (sock->link != NULL); - - GPU_shadeinput_set(mat, (Material *)node->id, &shi); - - /* write values */ - if (hasinput[MAT_IN_COLOR]) - shi.rgb = gpu_get_input_link(mat, &in[MAT_IN_COLOR]); - - if (hasinput[MAT_IN_SPEC]) - shi.specrgb = gpu_get_input_link(mat, &in[MAT_IN_SPEC]); - - if (hasinput[MAT_IN_REFL]) - shi.refl = gpu_get_input_link(mat, &in[MAT_IN_REFL]); - - /* retrieve normal */ - if (hasinput[MAT_IN_NORMAL]) { - GPUNodeLink *tmp; - shi.vn = gpu_get_input_link(mat, &in[MAT_IN_NORMAL]); - if (GPU_material_use_world_space_shading(mat)) { - GPU_link(mat, "vec_math_negate", shi.vn, &shi.vn); - GPU_link(mat, "direction_transform_m4v3", shi.vn, GPU_builtin(GPU_VIEW_MATRIX), &shi.vn); - } - GPU_link(mat, "vec_math_normalize", shi.vn, &shi.vn, &tmp); - } - - /* custom option to flip normal */ - if (node->custom1 & SH_NODE_MAT_NEG) - GPU_link(mat, "vec_math_negate", shi.vn, &shi.vn); - - if (node->type == SH_NODE_MATERIAL_EXT) { - if (hasinput[MAT_IN_MIR]) - shi.mir = gpu_get_input_link(mat, &in[MAT_IN_MIR]); - if (hasinput[MAT_IN_AMB]) - shi.amb = gpu_get_input_link(mat, &in[MAT_IN_AMB]); - if (hasinput[MAT_IN_EMIT]) - shi.emit = gpu_get_input_link(mat, &in[MAT_IN_EMIT]); - if (hasinput[MAT_IN_SPECTRA]) - shi.spectra = gpu_get_input_link(mat, &in[MAT_IN_SPECTRA]); - if (hasinput[MAT_IN_ALPHA]) - shi.alpha = gpu_get_input_link(mat, &in[MAT_IN_ALPHA]); - } - - GPU_shaderesult_set(&shi, &shr); /* clears shr */ - - /* write to outputs */ - if (node->custom1 & SH_NODE_MAT_DIFF) { - out[MAT_OUT_COLOR].link = shr.combined; - - if (!(node->custom1 & SH_NODE_MAT_SPEC)) { - GPUNodeLink *link; - GPU_link(mat, "vec_math_sub", shr.combined, shr.spec, &out[MAT_OUT_COLOR].link, &link); - } - } - else if (node->custom1 & SH_NODE_MAT_SPEC) { - out[MAT_OUT_COLOR].link = shr.spec; - } - else - GPU_link(mat, "set_rgb_zero", &out[MAT_OUT_COLOR].link); - - GPU_link(mat, "mtex_alpha_to_col", out[MAT_OUT_COLOR].link, shr.alpha, &out[MAT_OUT_COLOR].link); - - out[MAT_OUT_ALPHA].link = shr.alpha; // - - if (node->custom1 & SH_NODE_MAT_NEG) - GPU_link(mat, "vec_math_negate", shi.vn, &shi.vn); - out[MAT_OUT_NORMAL].link = shi.vn; - if (GPU_material_use_world_space_shading(mat)) { - GPU_link(mat, "vec_math_negate", out[MAT_OUT_NORMAL].link, &out[MAT_OUT_NORMAL].link); - GPU_link(mat, "direction_transform_m4v3", out[MAT_OUT_NORMAL].link, GPU_builtin(GPU_INVERSE_VIEW_MATRIX), &out[MAT_OUT_NORMAL].link); - } - - if (node->type == SH_NODE_MATERIAL_EXT) { - out[MAT_OUT_DIFFUSE].link = shr.diff; - out[MAT_OUT_SPEC].link = shr.spec; - GPU_link(mat, "set_rgb_one", &out[MAT_OUT_AO].link); - } - - return 1; - } - - return 0; -} - -void register_node_type_sh_material(void) -{ - static bNodeType ntype; - - sh_node_type_base(&ntype, SH_NODE_MATERIAL, "Material", NODE_CLASS_INPUT, NODE_PREVIEW); - node_type_compatibility(&ntype, NODE_OLD_SHADING); - node_type_socket_templates(&ntype, sh_node_material_in, sh_node_material_out); - node_type_init(&ntype, node_shader_init_material); - node_type_exec(&ntype, NULL, NULL, node_shader_exec_material); - node_type_gpu(&ntype, gpu_shader_material); - - nodeRegisterType(&ntype); -} - - -void register_node_type_sh_material_ext(void) -{ - static bNodeType ntype; - - sh_node_type_base(&ntype, SH_NODE_MATERIAL_EXT, "Extended Material", NODE_CLASS_INPUT, NODE_PREVIEW); - node_type_compatibility(&ntype, NODE_OLD_SHADING); - node_type_socket_templates(&ntype, sh_node_material_ext_in, sh_node_material_ext_out); - node_type_init(&ntype, node_shader_init_material); - node_type_size_preset(&ntype, NODE_SIZE_MIDDLE); - node_type_exec(&ntype, NULL, NULL, node_shader_exec_material); - node_type_gpu(&ntype, gpu_shader_material); - - nodeRegisterType(&ntype); -} diff --git a/source/blender/nodes/shader/nodes/node_shader_normal.c b/source/blender/nodes/shader/nodes/node_shader_normal.c index 64f3ec94369..7033eeaead0 100644 --- a/source/blender/nodes/shader/nodes/node_shader_normal.c +++ b/source/blender/nodes/shader/nodes/node_shader_normal.c @@ -61,12 +61,7 @@ static void node_shader_exec_normal(void *UNUSED(data), int UNUSED(thread), bNod static int gpu_shader_normal(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out) { GPUNodeLink *vec = GPU_uniform(out[0].vec); - if (GPU_material_use_new_shading_nodes(mat)) { - return GPU_stack_link(mat, node, "normal_new_shading", in, out, vec); - } - else { - return GPU_stack_link(mat, node, "normal", in, out, vec); - } + return GPU_stack_link(mat, node, "normal_new_shading", in, out, vec); } void register_node_type_sh_normal(void) diff --git a/source/blender/nodes/shader/nodes/node_shader_normal_map.c b/source/blender/nodes/shader/nodes/node_shader_normal_map.c index 7584b5eba4d..0d58be76030 100644 --- a/source/blender/nodes/shader/nodes/node_shader_normal_map.c +++ b/source/blender/nodes/shader/nodes/node_shader_normal_map.c @@ -47,80 +47,9 @@ static void node_shader_init_normal_map(bNodeTree *UNUSED(ntree), bNode *node) } static void node_shader_exec_normal_map( - void *data, int UNUSED(thread), bNode *node, bNodeExecData *UNUSED(execdata), - bNodeStack **in, bNodeStack **out) + void *UNUSED(data), int UNUSED(thread), bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), + bNodeStack **UNUSED(in), bNodeStack **UNUSED(out)) { - if (data) { - ShadeInput *shi = ((ShaderCallData *)data)->shi; - - NodeShaderNormalMap *nm = node->storage; - - float strength, vecIn[3]; - nodestack_get_vec(&strength, SOCK_FLOAT, in[0]); - nodestack_get_vec(vecIn, SOCK_VECTOR, in[1]); - - vecIn[0] = -2 * (vecIn[0] - 0.5f); - vecIn[1] = 2 * (vecIn[1] - 0.5f); - vecIn[2] = 2 * (vecIn[2] - 0.5f); - - CLAMP_MIN(strength, 0.0f); - - float *N = shi->nmapnorm; - int uv_index = 0; - switch (nm->space) { - case SHD_SPACE_TANGENT: - if (nm->uv_map[0]) { - /* find uv map by name */ - for (int i = 0; i < shi->totuv; i++) { - if (STREQ(shi->uv[i].name, nm->uv_map)) { - uv_index = i; - break; - } - } - } - else { - uv_index = shi->actuv; - } - - float *T = shi->tangents[uv_index]; - - float B[3]; - cross_v3_v3v3(B, N, T); - mul_v3_fl(B, T[3]); - - for (int j = 0; j < 3; j++) - out[0]->vec[j] = vecIn[0] * T[j] + vecIn[1] * B[j] + vecIn[2] * N[j]; - interp_v3_v3v3(out[0]->vec, N, out[0]->vec, strength); - if (shi->use_world_space_shading) { - mul_mat3_m4_v3((float (*)[4])RE_render_current_get_matrix(RE_VIEWINV_MATRIX), out[0]->vec); - } - break; - - case SHD_SPACE_OBJECT: - case SHD_SPACE_BLENDER_OBJECT: - if (shi->use_world_space_shading) { - mul_mat3_m4_v3((float (*)[4])RE_object_instance_get_matrix(shi->obi, RE_OBJECT_INSTANCE_MATRIX_OB), vecIn); - mul_mat3_m4_v3((float (*)[4])RE_render_current_get_matrix(RE_VIEWINV_MATRIX), N); - } - else - mul_mat3_m4_v3((float (*)[4])RE_object_instance_get_matrix(shi->obi, RE_OBJECT_INSTANCE_MATRIX_LOCALTOVIEW), vecIn); - interp_v3_v3v3(out[0]->vec, N, vecIn, strength); - break; - - case SHD_SPACE_WORLD: - case SHD_SPACE_BLENDER_WORLD: - if (shi->use_world_space_shading) - mul_mat3_m4_v3((float (*)[4])RE_render_current_get_matrix(RE_VIEWINV_MATRIX), N); - else - mul_mat3_m4_v3((float (*)[4])RE_render_current_get_matrix(RE_VIEW_MATRIX), vecIn); - interp_v3_v3v3(out[0]->vec, N, vecIn, strength); - break; - } - if (shi->use_world_space_shading) { - negate_v3(out[0]->vec); - } - normalize_v3(out[0]->vec); - } } static int gpu_shader_normal_map(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out) @@ -145,57 +74,29 @@ static int gpu_shader_normal_map(GPUMaterial *mat, bNode *node, bNodeExecData *U negnorm = GPU_builtin(GPU_VIEW_NORMAL); GPU_link(mat, "math_max", strength, GPU_uniform(d), &strength); - if (GPU_material_use_world_space_shading(mat)) { - - /* ******* CYCLES or BLENDER INTERNAL with world space shading flag ******* */ - - const char *color_to_normal_fnc_name = "color_to_normal_new_shading"; - if (nm->space == SHD_SPACE_BLENDER_OBJECT || nm->space == SHD_SPACE_BLENDER_WORLD || !GPU_material_use_new_shading_nodes(mat)) - color_to_normal_fnc_name = "color_to_blender_normal_new_shading"; - switch (nm->space) { - case SHD_SPACE_TANGENT: - GPU_link(mat, "color_to_normal_new_shading", realnorm, &realnorm); - GPU_link(mat, "node_normal_map", GPU_attribute(CD_TANGENT, nm->uv_map), negnorm, realnorm, &realnorm); - GPU_link(mat, "vec_math_mix", strength, realnorm, GPU_builtin(GPU_VIEW_NORMAL), &out[0].link); - /* for uniform scale this is sufficient to match Cycles */ - GPU_link(mat, "direction_transform_m4v3", out[0].link, GPU_builtin(GPU_INVERSE_VIEW_MATRIX), &out[0].link); - GPU_link(mat, "vect_normalize", out[0].link, &out[0].link); - return true; - case SHD_SPACE_OBJECT: - case SHD_SPACE_BLENDER_OBJECT: - GPU_link(mat, "direction_transform_m4v3", negnorm, GPU_builtin(GPU_INVERSE_VIEW_MATRIX), &negnorm); - GPU_link(mat, color_to_normal_fnc_name, realnorm, &realnorm); - GPU_link(mat, "direction_transform_m4v3", realnorm, GPU_builtin(GPU_OBJECT_MATRIX), &realnorm); - break; - case SHD_SPACE_WORLD: - case SHD_SPACE_BLENDER_WORLD: - GPU_link(mat, "direction_transform_m4v3", negnorm, GPU_builtin(GPU_INVERSE_VIEW_MATRIX), &negnorm); - GPU_link(mat, color_to_normal_fnc_name, realnorm, &realnorm); - break; - } - - } - else { - - /* ************** BLENDER INTERNAL without world space shading flag ******* */ - - GPU_link(mat, "color_to_normal", realnorm, &realnorm); - GPU_link(mat, "mtex_negate_texnormal", realnorm, &realnorm); - GPU_link(mat, "vec_math_negate", negnorm, &negnorm); - - switch (nm->space) { - case SHD_SPACE_TANGENT: - GPU_link(mat, "node_normal_map", GPU_attribute(CD_TANGENT, nm->uv_map), negnorm, realnorm, &realnorm); - break; - case SHD_SPACE_OBJECT: - case SHD_SPACE_BLENDER_OBJECT: - GPU_link(mat, "direction_transform_m4v3", realnorm, GPU_builtin(GPU_LOC_TO_VIEW_MATRIX), &realnorm); - break; - case SHD_SPACE_WORLD: - case SHD_SPACE_BLENDER_WORLD: - GPU_link(mat, "direction_transform_m4v3", realnorm, GPU_builtin(GPU_VIEW_MATRIX), &realnorm); - break; - } + const char *color_to_normal_fnc_name = "color_to_normal_new_shading"; + if (nm->space == SHD_SPACE_BLENDER_OBJECT || nm->space == SHD_SPACE_BLENDER_WORLD) + color_to_normal_fnc_name = "color_to_blender_normal_new_shading"; + switch (nm->space) { + case SHD_SPACE_TANGENT: + GPU_link(mat, "color_to_normal_new_shading", realnorm, &realnorm); + GPU_link(mat, "node_normal_map", GPU_attribute(CD_TANGENT, nm->uv_map), negnorm, realnorm, &realnorm); + GPU_link(mat, "vec_math_mix", strength, realnorm, GPU_builtin(GPU_VIEW_NORMAL), &out[0].link); + /* for uniform scale this is sufficient to match Cycles */ + GPU_link(mat, "direction_transform_m4v3", out[0].link, GPU_builtin(GPU_INVERSE_VIEW_MATRIX), &out[0].link); + GPU_link(mat, "vect_normalize", out[0].link, &out[0].link); + return true; + case SHD_SPACE_OBJECT: + case SHD_SPACE_BLENDER_OBJECT: + GPU_link(mat, "direction_transform_m4v3", negnorm, GPU_builtin(GPU_INVERSE_VIEW_MATRIX), &negnorm); + GPU_link(mat, color_to_normal_fnc_name, realnorm, &realnorm); + GPU_link(mat, "direction_transform_m4v3", realnorm, GPU_builtin(GPU_OBJECT_MATRIX), &realnorm); + break; + case SHD_SPACE_WORLD: + case SHD_SPACE_BLENDER_WORLD: + GPU_link(mat, "direction_transform_m4v3", negnorm, GPU_builtin(GPU_INVERSE_VIEW_MATRIX), &negnorm); + GPU_link(mat, color_to_normal_fnc_name, realnorm, &realnorm); + break; } GPU_link(mat, "vec_math_mix", strength, realnorm, negnorm, &out[0].link); diff --git a/source/blender/nodes/shader/nodes/node_shader_object_info.c b/source/blender/nodes/shader/nodes/node_shader_object_info.c index 471331beae3..25c9bd77250 100644 --- a/source/blender/nodes/shader/nodes/node_shader_object_info.c +++ b/source/blender/nodes/shader/nodes/node_shader_object_info.c @@ -42,13 +42,8 @@ static int node_shader_gpu_object_info(GPUMaterial *mat, bNode *node, bNodeExecD return GPU_stack_link(mat, node, "node_object_info", in, out, GPU_builtin(GPU_OBJECT_MATRIX), GPU_builtin(GPU_OBJECT_INFO)); } -static void node_shader_exec_object_info(void *data, int UNUSED(thread), bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), bNodeStack **UNUSED(in), bNodeStack **out) +static void node_shader_exec_object_info(void *UNUSED(data), int UNUSED(thread), bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), bNodeStack **UNUSED(in), bNodeStack **UNUSED(out)) { - ShaderCallData *scd = (ShaderCallData *)data; - copy_v4_v4(out[0]->vec, RE_object_instance_get_matrix(scd->shi->obi, RE_OBJECT_INSTANCE_MATRIX_OB)[3]); - out[1]->vec[0] = RE_object_instance_get_object_pass_index(scd->shi->obi); - out[2]->vec[0] = scd->shi->mat->index; - out[3]->vec[0] = RE_object_instance_get_random_id(scd->shi->obi) * (1.0f / (float)0xFFFFFFFF); } /* node type definition */ diff --git a/source/blender/nodes/shader/nodes/node_shader_output.c b/source/blender/nodes/shader/nodes/node_shader_output.c deleted file mode 100644 index 52f659d8321..00000000000 --- a/source/blender/nodes/shader/nodes/node_shader_output.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2005 Blender Foundation. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/nodes/shader/nodes/node_shader_output.c - * \ingroup shdnodes - */ - - -#include "node_shader_util.h" - -#include "BKE_scene.h" - -/* **************** OUTPUT ******************** */ -static bNodeSocketTemplate sh_node_output_in[] = { - { SOCK_RGBA, 1, N_("Color"), 0.0f, 0.0f, 0.0f, 1.0f}, - { SOCK_FLOAT, 1, N_("Alpha"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE}, - { -1, 0, "" } -}; - -static void node_shader_exec_output(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **UNUSED(out)) -{ - if (data) { - ShadeInput *shi = ((ShaderCallData *)data)->shi; - float col[4]; - - /* stack order input sockets: col, alpha, normal */ - nodestack_get_vec(col, SOCK_VECTOR, in[0]); - nodestack_get_vec(col + 3, SOCK_FLOAT, in[1]); - - if (shi->do_preview) { - BKE_node_preview_set_pixel(execdata->preview, col, shi->xs, shi->ys, shi->do_manage); - node->lasty = shi->ys; - } - - if (node->flag & NODE_DO_OUTPUT) { - ShadeResult *shr = ((ShaderCallData *)data)->shr; - - copy_v4_v4(shr->combined, col); - shr->alpha = col[3]; - - // copy_v3_v3(shr->nor, in[3]->vec); - } - } -} - -static int gpu_shader_output(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out) -{ - GPUNodeLink *outlink; - -#if 0 - if (in[1].hasinput) - GPU_material_enable_alpha(mat); -#endif - - GPU_stack_link(mat, node, "output_node", in, out, &outlink); - GPU_material_output_link(mat, outlink); - - return 1; -} - -void register_node_type_sh_output(void) -{ - static bNodeType ntype; - - sh_node_type_base(&ntype, SH_NODE_OUTPUT, "Output", NODE_CLASS_OUTPUT, NODE_PREVIEW); - node_type_compatibility(&ntype, NODE_OLD_SHADING); - node_type_socket_templates(&ntype, sh_node_output_in, NULL); - node_type_exec(&ntype, NULL, NULL, node_shader_exec_output); - node_type_gpu(&ntype, gpu_shader_output); - - /* Do not allow muting output node. */ - node_type_internal_links(&ntype, NULL); - - nodeRegisterType(&ntype); -} diff --git a/source/blender/nodes/shader/nodes/node_shader_particle_info.c b/source/blender/nodes/shader/nodes/node_shader_particle_info.c index 69fcbba8f88..46cb513a6d9 100644 --- a/source/blender/nodes/shader/nodes/node_shader_particle_info.c +++ b/source/blender/nodes/shader/nodes/node_shader_particle_info.c @@ -42,11 +42,8 @@ static bNodeSocketTemplate outputs[] = { { SOCK_VECTOR, 0, "Angular Velocity" }, { -1, 0, "" } }; -static void node_shader_exec_particle_info(void *data, int UNUSED(thread), bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), bNodeStack **UNUSED(in), bNodeStack **out) +static void node_shader_exec_particle_info(void *UNUSED(data), int UNUSED(thread), bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), bNodeStack **UNUSED(in), bNodeStack **UNUSED(out)) { - ShadeInput *shi = ((ShaderCallData *)data)->shi; - - RE_instance_get_particle_info(shi->obi, out[0]->vec, out[1]->vec, out[2]->vec, out[3]->vec, out[4]->vec, out[5]->vec, out[6]->vec, out[7]->vec); } static int gpu_shader_particle_info(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out) diff --git a/source/blender/nodes/shader/nodes/node_shader_texture.c b/source/blender/nodes/shader/nodes/node_shader_texture.c deleted file mode 100644 index 755ef106ade..00000000000 --- a/source/blender/nodes/shader/nodes/node_shader_texture.c +++ /dev/null @@ -1,166 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2005 Blender Foundation. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/nodes/shader/nodes/node_shader_texture.c - * \ingroup shdnodes - */ - -#include "DNA_texture_types.h" - -#include "node_shader_util.h" - -#include "GPU_material.h" - -/* **************** TEXTURE ******************** */ -static bNodeSocketTemplate sh_node_texture_in[] = { - { SOCK_VECTOR, 1, "Vector", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE}, /* no limit */ - { -1, 0, "" } -}; -static bNodeSocketTemplate sh_node_texture_out[] = { - { SOCK_FLOAT, 0, N_("Value"), 0, 0, 0, 0, 0, 0, PROP_NONE, SOCK_NO_INTERNAL_LINK}, - { SOCK_RGBA, 0, N_("Color"), 0, 0, 0, 0, 0, 0, PROP_NONE, SOCK_NO_INTERNAL_LINK}, - { SOCK_VECTOR, 0, N_("Normal"), 0, 0, 0, 0, 0, 0, PROP_NONE, SOCK_NO_INTERNAL_LINK}, - { -1, 0, "" } -}; - -static void node_shader_exec_texture(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out) -{ - if (data && node->id) { - ShadeInput *shi = ((ShaderCallData *)data)->shi; - TexResult texres; - bNodeSocket *sock_vector = node->inputs.first; - float vec[3], nor[3] = {0.0f, 0.0f, 0.0f}; - int retval; - short which_output = node->custom1; - - short thread = shi->thread; - - /* out: value, color, normal */ - - /* we should find out if a normal as output is needed, for now we do all */ - texres.nor = nor; - texres.tr = texres.tg = texres.tb = 0.0f; - - /* don't use in[0]->hasinput, see material node for explanation */ - if (sock_vector->link) { - nodestack_get_vec(vec, SOCK_VECTOR, in[0]); - - if (in[0]->datatype == NS_OSA_VECTORS) { - float *fp = in[0]->data; - retval = multitex_nodes((Tex *)node->id, vec, fp, fp + 3, shi->osatex, &texres, thread, which_output, NULL, NULL, NULL); - } - else if (in[0]->datatype == NS_OSA_VALUES) { - const float *fp = in[0]->data; - float dxt[3], dyt[3]; - - dxt[0] = fp[0]; dxt[1] = dxt[2] = 0.0f; - dyt[0] = fp[1]; dyt[1] = dyt[2] = 0.0f; - retval = multitex_nodes((Tex *)node->id, vec, dxt, dyt, shi->osatex, &texres, thread, which_output, NULL, NULL, NULL); - } - else - retval = multitex_nodes((Tex *)node->id, vec, NULL, NULL, 0, &texres, thread, which_output, NULL, NULL, NULL); - } - else { - copy_v3_v3(vec, shi->lo); - retval = multitex_nodes((Tex *)node->id, vec, NULL, NULL, 0, &texres, thread, which_output, NULL, NULL, NULL); - } - - /* stupid exception */ - if ( ((Tex *)node->id)->type == TEX_STUCCI) { - texres.tin = 0.5f + 0.7f * texres.nor[0]; - CLAMP(texres.tin, 0.0f, 1.0f); - } - - /* intensity and color need some handling */ - if (texres.talpha) - out[0]->vec[0] = texres.ta; - else - out[0]->vec[0] = texres.tin; - - if ((retval & TEX_RGB) == 0) { - copy_v3_fl(out[1]->vec, out[0]->vec[0]); - out[1]->vec[3] = 1.0f; - } - else { - copy_v3_v3(out[1]->vec, &texres.tr); - out[1]->vec[3] = 1.0f; - } - - copy_v3_v3(out[2]->vec, nor); - - if (shi->do_preview) { - BKE_node_preview_set_pixel(execdata->preview, out[1]->vec, shi->xs, shi->ys, shi->do_manage); - } - - } -} - -static int gpu_shader_texture(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out) -{ - Tex *tex = (Tex *)node->id; - - if (tex && tex->ima && (tex->type == TEX_IMAGE || tex->type == TEX_ENVMAP)) { - if (tex->type == TEX_IMAGE) { - GPUNodeLink *texlink = GPU_image(tex->ima, &tex->iuser, false); - GPU_stack_link(mat, node, "texture_image", in, out, texlink); - } - else { /* TEX_ENVMAP */ - if (!in[0].link) - in[0].link = GPU_uniform(in[0].vec); - if (!GPU_material_use_world_space_shading(mat)) - GPU_link(mat, "direction_transform_m4v3", in[0].link, GPU_builtin(GPU_INVERSE_VIEW_MATRIX), &in[0].link); - GPU_link(mat, "mtex_cube_map_refl_from_refldir", - GPU_cube_map(tex->ima, &tex->iuser, false), in[0].link, &out[0].link, &out[1].link); - GPU_link(mat, "color_to_normal", out[1].link, &out[2].link); - } - - ImBuf *ibuf = BKE_image_acquire_ibuf(tex->ima, &tex->iuser, NULL); - if (ibuf && (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA) == 0 && - GPU_material_do_color_management(mat)) - { - GPU_link(mat, "srgb_to_linearrgb", out[1].link, &out[1].link); - } - BKE_image_release_ibuf(tex->ima, ibuf, NULL); - - return true; - } - - return false; -} - -void register_node_type_sh_texture(void) -{ - static bNodeType ntype; - - sh_node_type_base(&ntype, SH_NODE_TEXTURE, "Texture", NODE_CLASS_INPUT, NODE_PREVIEW); - node_type_compatibility(&ntype, NODE_OLD_SHADING); - node_type_socket_templates(&ntype, sh_node_texture_in, sh_node_texture_out); - node_type_exec(&ntype, NULL, NULL, node_shader_exec_texture); - node_type_gpu(&ntype, gpu_shader_texture); - - nodeRegisterType(&ntype); -} diff --git a/source/blender/nodes/shader/nodes/node_shader_vectTransform.c b/source/blender/nodes/shader/nodes/node_shader_vectTransform.c index 74e23aed7de..71bb88f892f 100644 --- a/source/blender/nodes/shader/nodes/node_shader_vectTransform.c +++ b/source/blender/nodes/shader/nodes/node_shader_vectTransform.c @@ -52,68 +52,8 @@ static void node_shader_init_vect_transform(bNodeTree *UNUSED(ntree), bNode *nod node->storage = vect; } -static const float (* get_matrix_from_to(ShaderCallData *scd, short from, short to))[4] +static void node_shader_exec_vect_transform(void *UNUSED(data), int UNUSED(thread), bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), bNodeStack **UNUSED(in), bNodeStack **UNUSED(out)) { - switch (from) { - case SHD_VECT_TRANSFORM_SPACE_OBJECT: - switch (to) { - case SHD_VECT_TRANSFORM_SPACE_OBJECT: - return NULL; - case SHD_VECT_TRANSFORM_SPACE_WORLD: - return RE_object_instance_get_matrix(scd->shi->obi, RE_OBJECT_INSTANCE_MATRIX_OB); - case SHD_VECT_TRANSFORM_SPACE_CAMERA: - return RE_object_instance_get_matrix(scd->shi->obi, RE_OBJECT_INSTANCE_MATRIX_LOCALTOVIEW); - } - break; - case SHD_VECT_TRANSFORM_SPACE_WORLD: - switch (to) { - case SHD_VECT_TRANSFORM_SPACE_WORLD: - return NULL; - case SHD_VECT_TRANSFORM_SPACE_CAMERA: - return RE_render_current_get_matrix(RE_VIEW_MATRIX); - case SHD_VECT_TRANSFORM_SPACE_OBJECT: - return RE_object_instance_get_matrix(scd->shi->obi, RE_OBJECT_INSTANCE_MATRIX_OBINV); - } - break; - case SHD_VECT_TRANSFORM_SPACE_CAMERA: - switch (to) { - case SHD_VECT_TRANSFORM_SPACE_CAMERA: - return NULL; - case SHD_VECT_TRANSFORM_SPACE_WORLD: - return RE_render_current_get_matrix(RE_VIEWINV_MATRIX); - case SHD_VECT_TRANSFORM_SPACE_OBJECT: - return RE_object_instance_get_matrix(scd->shi->obi, RE_OBJECT_INSTANCE_MATRIX_LOCALTOVIEWINV); - } - break; - } - return NULL; -} - -static void node_shader_exec_vect_transform(void *data, int UNUSED(thread), bNode *node, bNodeExecData *UNUSED(execdata), bNodeStack **in, bNodeStack **out) -{ - float vec[4]; - const float (*mat)[4]; - - if (data) { - NodeShaderVectTransform *nodeprop = (NodeShaderVectTransform *)node->storage; - - nodestack_get_vec(vec, SOCK_VECTOR, in[0]); - - if (nodeprop->type == SHD_VECT_TRANSFORM_TYPE_POINT) - vec[3] = 1.0f; - else - vec[3] = 0.0f; - - mat = get_matrix_from_to((ShaderCallData *)data, nodeprop->convert_from, nodeprop->convert_to); - if (mat) { - mul_m4_v4((float(*)[4])mat, vec); - } - - if (nodeprop->type == SHD_VECT_TRANSFORM_TYPE_NORMAL) - normalize_v3(vec); - - copy_v4_v4(out[0]->vec, vec); - } } static GPUNodeLink *get_gpulink_matrix_from_to(short from, short to) @@ -161,8 +101,6 @@ static int gpu_shader_vect_transform(GPUMaterial *mat, bNode *node, bNodeExecDat const char *ptransform = "point_transform_m4v3"; const char *func_name = 0; - bool new_shading = GPU_material_use_new_shading_nodes(mat); - NodeShaderVectTransform *nodeprop = (NodeShaderVectTransform *)node->storage; if (in[0].hasinput) @@ -174,19 +112,14 @@ static int gpu_shader_vect_transform(GPUMaterial *mat, bNode *node, bNodeExecDat func_name = (nodeprop->type == SHD_VECT_TRANSFORM_TYPE_POINT) ? ptransform : vtransform; if (fromto) { - if (new_shading) { - /* For cycles we have inverted Z */ - /* TODO: pass here the correct matrices */ - if (nodeprop->convert_from == SHD_VECT_TRANSFORM_SPACE_CAMERA && nodeprop->convert_to != SHD_VECT_TRANSFORM_SPACE_CAMERA) { - GPU_link(mat, "invert_z", inputlink, &inputlink); - } - GPU_link(mat, func_name, inputlink, fromto, &out[0].link); - if (nodeprop->convert_to == SHD_VECT_TRANSFORM_SPACE_CAMERA && nodeprop->convert_from != SHD_VECT_TRANSFORM_SPACE_CAMERA) { - GPU_link(mat, "invert_z", out[0].link, &out[0].link); - } + /* For cycles we have inverted Z */ + /* TODO: pass here the correct matrices */ + if (nodeprop->convert_from == SHD_VECT_TRANSFORM_SPACE_CAMERA && nodeprop->convert_to != SHD_VECT_TRANSFORM_SPACE_CAMERA) { + GPU_link(mat, "invert_z", inputlink, &inputlink); } - else { - GPU_link(mat, func_name, inputlink, fromto, &out[0].link); + GPU_link(mat, func_name, inputlink, fromto, &out[0].link); + if (nodeprop->convert_to == SHD_VECT_TRANSFORM_SPACE_CAMERA && nodeprop->convert_from != SHD_VECT_TRANSFORM_SPACE_CAMERA) { + GPU_link(mat, "invert_z", out[0].link, &out[0].link); } } else diff --git a/source/blender/nodes/texture/node_texture_tree.c b/source/blender/nodes/texture/node_texture_tree.c index d001d80fa8f..5e57338dc57 100644 --- a/source/blender/nodes/texture/node_texture_tree.c +++ b/source/blender/nodes/texture/node_texture_tree.c @@ -68,32 +68,7 @@ static void texture_get_from_context( Object *ob = OBACT(view_layer); Tex *tx = NULL; - if (snode->texfrom == SNODE_TEX_OBJECT) { - if (ob) { - tx = give_current_object_texture(ob); - if (tx) { - if (ob->type == OB_LAMP) - *r_from = (ID *)ob->data; - else - *r_from = (ID *)give_current_material(ob, ob->actcol); - - /* from is not set fully for material nodes, should be ID + Node then */ - *r_id = &tx->id; - *r_ntree = tx->nodetree; - } - } - } - else if (snode->texfrom == SNODE_TEX_WORLD) { - if (scene->world) { - *r_from = (ID *)scene->world; - tx = give_current_world_texture(scene->world); - if (tx) { - *r_id = &tx->id; - *r_ntree = tx->nodetree; - } - } - } - else if (snode->texfrom == SNODE_TEX_BRUSH) { + if (snode->texfrom == SNODE_TEX_BRUSH) { struct Brush *brush = NULL; if (ob && (ob->mode & OB_MODE_SCULPT)) @@ -324,7 +299,6 @@ int ntreeTexExecTree( short which_output, int cfra, int preview, - ShadeInput *shi, MTex *mtex) { TexCallData data; @@ -339,12 +313,11 @@ int ntreeTexExecTree( data.osatex = osatex; data.target = texres; data.do_preview = preview; - data.do_manage = (shi) ? shi->do_manage : true; + data.do_manage = true; data.thread = thread; data.which_output = which_output; data.cfra = cfra; data.mtex = mtex; - data.shi = shi; /* ensure execdata is only initialized once */ if (!exec) { diff --git a/source/blender/nodes/texture/node_texture_util.c b/source/blender/nodes/texture/node_texture_util.c index 32720364f73..8cb61478c41 100644 --- a/source/blender/nodes/texture/node_texture_util.c +++ b/source/blender/nodes/texture/node_texture_util.c @@ -124,7 +124,6 @@ void params_from_cdata(TexParams *out, TexCallData *in) out->previewco = in->co; out->osatex = in->osatex; out->cfra = in->cfra; - out->shi = in->shi; out->mtex = in->mtex; } diff --git a/source/blender/nodes/texture/node_texture_util.h b/source/blender/nodes/texture/node_texture_util.h index f6af5b1b6ca..82ba573425a 100644 --- a/source/blender/nodes/texture/node_texture_util.h +++ b/source/blender/nodes/texture/node_texture_util.h @@ -87,7 +87,6 @@ typedef struct TexCallData { short which_output; int cfra; - ShadeInput *shi; MTex *mtex; } TexCallData; @@ -100,7 +99,6 @@ typedef struct TexParams { /* optional. we don't really want these here, but image * textures need to do mapping & color correction */ - ShadeInput *shi; MTex *mtex; } TexParams; diff --git a/source/blender/nodes/texture/nodes/node_texture_proc.c b/source/blender/nodes/texture/nodes/node_texture_proc.c index 0be5f875a23..c16d723e1e1 100644 --- a/source/blender/nodes/texture/nodes/node_texture_proc.c +++ b/source/blender/nodes/texture/nodes/node_texture_proc.c @@ -69,7 +69,7 @@ static void do_proc(float *result, TexParams *p, const float col1[4], const floa texres.nor = NULL; textype = multitex_nodes(tex, p->co, p->dxt, p->dyt, p->osatex, - &texres, thread, 0, p->shi, p->mtex, NULL); + &texres, thread, 0, p->mtex, NULL); if (is_normal) return; diff --git a/source/blender/nodes/texture/nodes/node_texture_texture.c b/source/blender/nodes/texture/nodes/node_texture_texture.c index 1fd0a55dc63..7e035d522f7 100644 --- a/source/blender/nodes/texture/nodes/node_texture_texture.c +++ b/source/blender/nodes/texture/nodes/node_texture_texture.c @@ -78,7 +78,7 @@ static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor texres.nor = nor; textype = multitex_nodes(nodetex, co, dxt, dyt, p->osatex, - &texres, thread, 0, p->shi, p->mtex, NULL); + &texres, thread, 0, p->mtex, NULL); if (textype & TEX_RGB) { copy_v4_v4(out, &texres.tr); diff --git a/source/blender/physics/BPH_mass_spring.h b/source/blender/physics/BPH_mass_spring.h index c650d83c927..e89aec1456e 100644 --- a/source/blender/physics/BPH_mass_spring.h +++ b/source/blender/physics/BPH_mass_spring.h @@ -58,8 +58,6 @@ void BPH_cloth_solver_free(struct ClothModifierData *clmd); int BPH_cloth_solve(struct Object *ob, float frame, struct ClothModifierData *clmd, struct ListBase *effectors); void BKE_cloth_solver_set_positions(struct ClothModifierData *clmd); -bool BPH_cloth_solver_get_texture_data(struct Object *ob, struct ClothModifierData *clmd, struct VoxelData *vd); - #ifdef __cplusplus } #endif diff --git a/source/blender/physics/intern/BPH_mass_spring.cpp b/source/blender/physics/intern/BPH_mass_spring.cpp index 5b5639495da..e5724c97bbc 100644 --- a/source/blender/physics/intern/BPH_mass_spring.cpp +++ b/source/blender/physics/intern/BPH_mass_spring.cpp @@ -1091,24 +1091,3 @@ int BPH_cloth_solve(Object *ob, float frame, ClothModifierData *clmd, ListBase * return 1; } - -bool BPH_cloth_solver_get_texture_data(Object *UNUSED(ob), ClothModifierData *clmd, VoxelData *vd) -{ - Cloth *cloth = clmd->clothObject; - HairGrid *grid; - float gmin[3], gmax[3]; - - if (!clmd->clothObject || !clmd->clothObject->implicit) - return false; - - hair_get_boundbox(clmd, gmin, gmax); - - grid = BPH_hair_volume_create_vertex_grid(clmd->sim_parms->voxel_cell_size, gmin, gmax); - cloth_continuum_fill_grid(grid, cloth); - - BPH_hair_volume_get_texture_data(grid, vd); - - BPH_hair_volume_free_vertex_grid(grid); - - return true; -} diff --git a/source/blender/physics/intern/hair_volume.cpp b/source/blender/physics/intern/hair_volume.cpp index 5cc1231e6cb..05d30657af8 100644 --- a/source/blender/physics/intern/hair_volume.cpp +++ b/source/blender/physics/intern/hair_volume.cpp @@ -1099,56 +1099,3 @@ static HairGridVert *hair_volume_create_collision_grid(ClothModifierData *clmd, return collgrid; } #endif - -bool BPH_hair_volume_get_texture_data(HairGrid *grid, VoxelData *vd) -{ - int totres, i; - int depth; - - vd->resol[0] = grid->res[0]; - vd->resol[1] = grid->res[1]; - vd->resol[2] = grid->res[2]; - - totres = hair_grid_size(grid->res); - - if (vd->hair_type == TEX_VD_HAIRVELOCITY) { - depth = 4; - vd->data_type = TEX_VD_RGBA_PREMUL; - } - else { - depth = 1; - vd->data_type = TEX_VD_INTENSITY; - } - - if (totres > 0) { - vd->dataset = (float *)MEM_mapallocN(sizeof(float) * depth * (totres), "hair volume texture data"); - - for (i = 0; i < totres; ++i) { - switch (vd->hair_type) { - case TEX_VD_HAIRDENSITY: - vd->dataset[i] = grid->verts[i].density; - break; - - case TEX_VD_HAIRRESTDENSITY: - vd->dataset[i] = 0.0f; // TODO - break; - - case TEX_VD_HAIRVELOCITY: { - vd->dataset[i + 0*totres] = grid->verts[i].velocity[0]; - vd->dataset[i + 1*totres] = grid->verts[i].velocity[1]; - vd->dataset[i + 2*totres] = grid->verts[i].velocity[2]; - vd->dataset[i + 3*totres] = len_v3(grid->verts[i].velocity); - break; - } - case TEX_VD_HAIRENERGY: - vd->dataset[i] = 0.0f; // TODO - break; - } - } - } - else { - vd->dataset = NULL; - } - - return true; -} diff --git a/source/blender/physics/intern/implicit.h b/source/blender/physics/intern/implicit.h index 2f62ab98e12..d6bf5c6b7bf 100644 --- a/source/blender/physics/intern/implicit.h +++ b/source/blender/physics/intern/implicit.h @@ -171,8 +171,6 @@ void BPH_hair_volume_vertex_grid_forces(struct HairGrid *grid, const float x[3], float smoothfac, float pressurefac, float minpressure, float f[3], float dfdx[3][3], float dfdv[3][3]); -bool BPH_hair_volume_get_texture_data(struct HairGrid *grid, struct VoxelData *vd); - #ifdef __cplusplus } #endif diff --git a/source/blender/python/intern/gpu.c b/source/blender/python/intern/gpu.c index a7a0ae78f26..06f3143ec46 100644 --- a/source/blender/python/intern/gpu.c +++ b/source/blender/python/intern/gpu.c @@ -55,7 +55,7 @@ #define PY_MODULE_ADD_CONSTANT(module, name) PyModule_AddIntConstant(module, # name, name) PyDoc_STRVAR(M_gpu_doc, -"This module provides access to the GLSL shader and Offscreen rendering functionalities." +"This module provides access to GPU offscreen rendering, matrix stacks and selection." ); static struct PyModuleDef gpumodule = { PyModuleDef_HEAD_INIT, @@ -74,251 +74,10 @@ static PyObject *PyInit_gpu(void) if (m == NULL) return NULL; - /* Take care to update docs when editing: 'doc/python_api/rst/gpu.rst' */ - - - /* -------------------------------------------------------------------- */ - /* GPUDynamicType */ - - /* device constant groups */ - PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_GROUP_MISC); - PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_GROUP_LAMP); - PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_GROUP_OBJECT); - PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_GROUP_SAMPLER); - PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_GROUP_MIST); - PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_GROUP_WORLD); - PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_GROUP_MAT); - - /* device constants */ - PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_NONE); - /* GPU_DYNAMIC_GROUP_OBJECT */ - PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_OBJECT_VIEWMAT); - PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_OBJECT_MAT); - PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_OBJECT_VIEWIMAT); - PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_OBJECT_IMAT); - PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_OBJECT_LOCTOVIEWMAT); - PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_OBJECT_LOCTOVIEWIMAT); - PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_OBJECT_COLOR); - PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_OBJECT_AUTOBUMPSCALE); - /* GPU_DYNAMIC_GROUP_LAMP */ - PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_LAMP_DYNVEC); - PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_LAMP_DYNCO); - PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_LAMP_DYNIMAT); - PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_LAMP_DYNPERSMAT); - PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_LAMP_DYNENERGY); - PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_LAMP_DYNCOL); - PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_LAMP_ATT1); - PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_LAMP_ATT2); - PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_LAMP_DISTANCE); - PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_LAMP_SPOTSIZE); - PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_LAMP_SPOTBLEND); - PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_LAMP_SPOTSCALE); - /* GPU_DYNAMIC_GROUP_SAMPLER */ - PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_SAMPLER_2DBUFFER); - PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_SAMPLER_2DIMAGE); - PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_SAMPLER_2DSHADOW); - /* GPU_DYNAMIC_GROUP_MIST */ - PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_MIST_ENABLE); - PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_MIST_START); - PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_MIST_DISTANCE); - PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_MIST_INTENSITY); - PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_MIST_TYPE); - PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_MIST_COLOR); - /* GPU_DYNAMIC_GROUP_WORLD */ - PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_HORIZON_COLOR); - PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_AMBIENT_COLOR); - PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_ZENITH_COLOR); - /* GPU_DYNAMIC_GROUP_MAT */ - PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_MAT_DIFFRGB); - PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_MAT_REF); - PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_MAT_SPECRGB); - PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_MAT_SPEC); - PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_MAT_HARD); - PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_MAT_EMIT); - PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_MAT_AMB); - PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_MAT_ALPHA); - PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_MAT_MIR); - - - /* -------------------------------------------------------------------- */ - /* GPUDataType */ - - PY_MODULE_ADD_CONSTANT(m, GPU_DATA_1I); - PY_MODULE_ADD_CONSTANT(m, GPU_DATA_1F); - PY_MODULE_ADD_CONSTANT(m, GPU_DATA_2F); - PY_MODULE_ADD_CONSTANT(m, GPU_DATA_3F); - PY_MODULE_ADD_CONSTANT(m, GPU_DATA_4F); - PY_MODULE_ADD_CONSTANT(m, GPU_DATA_9F); - PY_MODULE_ADD_CONSTANT(m, GPU_DATA_16F); - PY_MODULE_ADD_CONSTANT(m, GPU_DATA_4UB); - - - /* -------------------------------------------------------------------- */ - /* CustomDataType - * - * Intentionally only include the subset used by the GPU API. - */ - PY_MODULE_ADD_CONSTANT(m, CD_MTFACE); - PY_MODULE_ADD_CONSTANT(m, CD_ORCO); - PY_MODULE_ADD_CONSTANT(m, CD_TANGENT); - PY_MODULE_ADD_CONSTANT(m, CD_MCOL); return m; } -#define PY_DICT_ADD_STRING(d, s, f) \ - val = PyUnicode_FromString(s->f); \ - PyDict_SetItemString(d, # f, val); \ - Py_DECREF(val) - -#define PY_DICT_ADD_LONG(d, s, f) \ - val = PyLong_FromLong(s->f); \ - PyDict_SetItemString(d, # f, val); \ - Py_DECREF(val) - -#define PY_DICT_ADD_ID(d, s, f) \ - RNA_id_pointer_create((struct ID *)s->f, &tptr); \ - val = pyrna_struct_CreatePyObject(&tptr); \ - PyDict_SetItemString(d, # f, val); \ - Py_DECREF(val) - -#if 0 /* UNUSED */ -#define PY_OBJ_ADD_ID(d, s, f) \ - val = PyUnicode_FromString(&s->f->id.name[2]); \ - PyObject_SetAttrString(d, # f, val); \ - Py_DECREF(val) - -#define PY_OBJ_ADD_LONG(d, s, f) \ - val = PyLong_FromLong(s->f); \ - PyObject_SetAttrString(d, # f, val); \ - Py_DECREF(val) - -#define PY_OBJ_ADD_STRING(d, s, f) \ - val = PyUnicode_FromString(s->f); \ - PyObject_SetAttrString(d, # f, val); \ - Py_DECREF(val) -#endif - -PyDoc_STRVAR(GPU_export_shader_doc, -"export_shader(scene, material)\n" -"\n" -" Returns the GLSL shader that produces the visual effect of material in scene.\n" -"\n" -" :return: Dictionary defining the shader, uniforms and attributes.\n" -" :rtype: Dict" -); -static PyObject *GPU_export_shader(PyObject *UNUSED(self), PyObject *args, PyObject *kw) -{ - PyObject *pyscene; - PyObject *pymat; - PyObject *result; - PyObject *dict; - PyObject *val; - PyObject *seq; - - int i; - Scene *scene; - PointerRNA tptr; - Material *material; - GPUShaderExport *shader; - GPUInputUniform *uniform; - GPUInputAttribute *attribute; - - static const char *_keywords[] = {"scene", "material", NULL}; - static _PyArg_Parser _parser = {"OO:export_shader", _keywords, 0}; - if (!_PyArg_ParseTupleAndKeywordsFast( - args, kw, &_parser, - &pyscene, &pymat)) - { - return NULL; - } - scene = (Scene *)PyC_RNA_AsPointer(pyscene, "Scene"); - if (scene == NULL) { - return NULL; - } - - material = (Material *)PyC_RNA_AsPointer(pymat, "Material"); - if (material == NULL) { - return NULL; - } - - /* we can call our internal function at last: */ - shader = GPU_shader_export(scene, material); - if (!shader) { - PyErr_SetString(PyExc_RuntimeError, "cannot export shader"); - return NULL; - } - /* build a dictionary */ - result = PyDict_New(); - if (shader->fragment) { - PY_DICT_ADD_STRING(result, shader, fragment); - } - if (shader->vertex) { - PY_DICT_ADD_STRING(result, shader, vertex); - } - seq = PyList_New(BLI_listbase_count(&shader->uniforms)); - for (i = 0, uniform = shader->uniforms.first; uniform; uniform = uniform->next, i++) { - dict = PyDict_New(); - PY_DICT_ADD_STRING(dict, uniform, varname); - PY_DICT_ADD_LONG(dict, uniform, datatype); - PY_DICT_ADD_LONG(dict, uniform, type); - if (uniform->lamp) { - PY_DICT_ADD_ID(dict, uniform, lamp); - } - if (uniform->material) { - PY_DICT_ADD_ID(dict, uniform, material); - } - if (uniform->image) { - PY_DICT_ADD_ID(dict, uniform, image); - } - if (uniform->type == GPU_DYNAMIC_SAMPLER_2DBUFFER || - uniform->type == GPU_DYNAMIC_SAMPLER_2DIMAGE || - uniform->type == GPU_DYNAMIC_SAMPLER_2DSHADOW) - { - PY_DICT_ADD_LONG(dict, uniform, texnumber); - } - if (uniform->texpixels) { - val = PyByteArray_FromStringAndSize((const char *)uniform->texpixels, uniform->texsize * 4); - PyDict_SetItemString(dict, "texpixels", val); - Py_DECREF(val); - PY_DICT_ADD_LONG(dict, uniform, texsize); - } - PyList_SET_ITEM(seq, i, dict); - } - PyDict_SetItemString(result, "uniforms", seq); - Py_DECREF(seq); - - seq = PyList_New(BLI_listbase_count(&shader->attributes)); - for (i = 0, attribute = shader->attributes.first; attribute; attribute = attribute->next, i++) { - dict = PyDict_New(); - PY_DICT_ADD_STRING(dict, attribute, varname); - PY_DICT_ADD_LONG(dict, attribute, datatype); - PY_DICT_ADD_LONG(dict, attribute, type); - PY_DICT_ADD_LONG(dict, attribute, number); - if (attribute->name) { - if (attribute->name[0] != 0) { - PY_DICT_ADD_STRING(dict, attribute, name); - } - else { - val = PyLong_FromLong(0); - PyDict_SetItemString(dict, "name", val); - Py_DECREF(val); - } - } - PyList_SET_ITEM(seq, i, dict); - } - PyDict_SetItemString(result, "attributes", seq); - Py_DECREF(seq); - - GPU_free_shader_export(shader); - - return result; -} - -static PyMethodDef meth_export_shader[] = { - {"export_shader", (PyCFunction)GPU_export_shader, METH_VARARGS | METH_KEYWORDS, GPU_export_shader_doc} -}; - /* -------------------------------------------------------------------- */ /* Initialize Module */ @@ -330,8 +89,6 @@ PyObject *GPU_initPython(void) module = PyInit_gpu(); - PyModule_AddObject(module, "export_shader", (PyObject *)PyCFunction_New(meth_export_shader, NULL)); - /* gpu.offscreen */ PyModule_AddObject(module, "offscreen", (submodule = BPyInit_gpu_offscreen())); PyDict_SetItem(sys_modules, PyModule_GetNameObject(submodule), submodule); diff --git a/source/blender/python/intern/gpu_offscreen.c b/source/blender/python/intern/gpu_offscreen.c index cbfc712b331..a8ec828c13f 100644 --- a/source/blender/python/intern/gpu_offscreen.c +++ b/source/blender/python/intern/gpu_offscreen.c @@ -197,8 +197,6 @@ static PyObject *pygpu_offscreen_draw_view3d(BPy_GPUOffScreen *self, PyObject *a fx_settings = v3d->fx_settings; /* full copy */ - ED_view3d_draw_offscreen_init(scene, view_layer, v3d); - rv3d_mats = ED_view3d_mats_rv3d_backup(ar->regiondata); GPU_offscreen_bind(self->ofs, true); /* bind */ diff --git a/source/blender/render/CMakeLists.txt b/source/blender/render/CMakeLists.txt index c5042bf3f83..0f0060c7578 100644 --- a/source/blender/render/CMakeLists.txt +++ b/source/blender/render/CMakeLists.txt @@ -48,43 +48,15 @@ set(INC_SYS ) set(SRC - intern/raytrace/rayobject.cpp - intern/raytrace/rayobject_empty.cpp - intern/raytrace/rayobject_octree.cpp - intern/raytrace/rayobject_raycounter.cpp - intern/raytrace/rayobject_svbvh.cpp - intern/raytrace/rayobject_instance.cpp - intern/raytrace/rayobject_qbvh.cpp - intern/raytrace/rayobject_rtbuild.cpp - intern/raytrace/rayobject_vbvh.cpp - intern/source/bake.c intern/source/bake_api.c - intern/source/convertblender.c - intern/source/envmap.c intern/source/external_engine.c intern/source/imagetexture.c intern/source/initrender.c intern/source/multires_bake.c - intern/source/occlusion.c intern/source/pipeline.c - intern/source/pixelblending.c - intern/source/pixelshading.c intern/source/pointdensity.c - intern/source/rayshade.c - intern/source/rendercore.c intern/source/render_result.c intern/source/render_texture.c - intern/source/renderdatabase.c - intern/source/shadbuf.c - intern/source/shadeinput.c - intern/source/shadeoutput.c - intern/source/sss.c - intern/source/strand.c - intern/source/sunsky.c - intern/source/texture_ocean.c - intern/source/volume_precache.c - intern/source/volumetric.c - intern/source/voxeldata.c intern/source/zbuf.c extern/include/RE_engine.h @@ -93,38 +65,12 @@ set(SRC extern/include/RE_pipeline.h extern/include/RE_render_ext.h extern/include/RE_shader_ext.h - intern/include/envmap.h intern/include/initrender.h - intern/include/occlusion.h - intern/include/pixelblending.h - intern/include/pixelshading.h - intern/include/pointdensity.h - intern/include/raycounter.h - intern/include/rayobject.h - intern/include/rayintersection.h intern/include/render_types.h intern/include/render_result.h - intern/include/rendercore.h - intern/include/renderdatabase.h intern/include/renderpipeline.h - intern/include/shadbuf.h - intern/include/shading.h - intern/include/sss.h - intern/include/strand.h - intern/include/sunsky.h intern/include/texture.h - intern/include/texture_ocean.h - intern/include/volume_precache.h - intern/include/volumetric.h - intern/include/voxeldata.h intern/include/zbuf.h - intern/raytrace/bvh.h - intern/raytrace/rayobject_hint.h - intern/raytrace/rayobject_internal.h - intern/raytrace/rayobject_rtbuild.h - intern/raytrace/reorganize.h - intern/raytrace/svbvh.h - intern/raytrace/vbvh.h ) if(WITH_PYTHON) diff --git a/source/blender/render/extern/include/RE_bake.h b/source/blender/render/extern/include/RE_bake.h index 090e0e6c28d..d827a3507d9 100644 --- a/source/blender/render/extern/include/RE_bake.h +++ b/source/blender/render/extern/include/RE_bake.h @@ -76,9 +76,6 @@ bool RE_bake_engine( /* bake.c */ int RE_pass_depth(const eScenePassType pass_type); -bool RE_bake_internal( - struct Render *re, struct Object *object, const BakePixel pixel_array[], - const size_t num_pixels, const int depth, const eScenePassType pass_type, float result[]); bool RE_bake_pixels_populate_from_objects( struct Mesh *me_low, BakePixel pixel_array_from[], BakePixel pixel_array_to[], diff --git a/source/blender/render/extern/include/RE_engine.h b/source/blender/render/extern/include/RE_engine.h index 64d87876a2e..e857d508424 100644 --- a/source/blender/render/extern/include/RE_engine.h +++ b/source/blender/render/extern/include/RE_engine.h @@ -69,7 +69,6 @@ struct ViewLayer; #define RE_USE_TEXTURE_PREVIEW 128 #define RE_USE_SHADING_NODES_CUSTOM 256 #define RE_USE_SPHERICAL_STEREO 512 -#define RE_USE_LEGACY_PIPELINE 1024 /* XXX Temporary flag, to be removed once draw manager is finished. */ /* RenderEngine.flag */ #define RE_ENGINE_ANIMATION 1 diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h index e60fc3abad2..022f2a31826 100644 --- a/source/blender/render/extern/include/RE_pipeline.h +++ b/source/blender/render/extern/include/RE_pipeline.h @@ -49,7 +49,6 @@ struct RenderResult; struct ReportList; struct Scene; struct ViewLayer; -struct EnvMap; struct StampData; /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ @@ -251,10 +250,8 @@ void RE_ChangeModeFlag(struct Render *re, int flag, bool clear); struct Object *RE_GetCamera(struct Render *re); /* return camera override if set */ void RE_SetOverrideCamera(struct Render *re, struct Object *camera); void RE_SetCamera(struct Render *re, struct Object *camera); -void RE_SetEnvmapCamera(struct Render *re, struct Object *cam_ob, float viewscale, float clipsta, float clipend); void RE_SetWindow(struct Render *re, const rctf *viewplane, float clipsta, float clipend); void RE_SetOrtho(struct Render *re, const rctf *viewplane, float clipsta, float clipend); -void RE_SetPixelSize(struct Render *re, float pixsize); /* option to set viewmatrix before making dbase */ void RE_SetView(struct Render *re, float mat[4][4]); @@ -264,26 +261,13 @@ void RE_GetView(struct Render *re, float mat[4][4]); void RE_GetViewPlane(struct Render *re, rctf *r_viewplane, rcti *r_disprect); /* make or free the dbase */ -void RE_Database_FromScene( - struct Render *re, struct Main *bmain, struct Scene *scene, - unsigned int lay, int use_camera_view); void RE_Database_CameraOnly( struct Render *re, struct Main *bmain, struct Scene *scene, unsigned int lay, int use_camera_view); -void RE_Database_Preprocess(struct Depsgraph *depsgraph, struct Render *re); -void RE_Database_Free(struct Render *re); - -/* project dbase again, when viewplane/perspective changed */ -void RE_DataBase_ApplyWindow(struct Render *re); -/* rotate scene again, for incremental render */ -void RE_DataBase_IncrementalView(struct Render *re, float viewmat[4][4], int restore); /* set the render threads based on the commandline and autothreads setting */ void RE_init_threadcount(Render *re); -/* the main processor, assumes all was set OK! */ -void RE_TileProcessor(struct Render *re); - bool RE_WriteRenderViewsImage( struct ReportList *reports, struct RenderResult *rr, struct Scene *scene, const bool stamp, char *name); bool RE_WriteRenderViewsMovie( @@ -318,14 +302,6 @@ bool RE_WriteRenderResult( struct RenderResult *RE_MultilayerConvert( void *exrhandle, const char *colorspace, bool predivide, int rectx, int recty); -extern const float default_envmap_layout[]; -bool RE_WriteEnvmapResult( - struct ReportList *reports, struct Scene *scene, struct EnvMap *env, - const char *relpath, const char imtype, float layout[12]); - -/* do a full sample buffer compo */ -void RE_MergeFullSample(struct Render *re, struct Main *bmain, struct Scene *sce, struct bNodeTree *ntree); - /* display and event callbacks */ void RE_display_init_cb (struct Render *re, void *handle, void (*f)(void *handle, RenderResult *rr)); void RE_display_clear_cb(struct Render *re, void *handle, void (*f)(void *handle, RenderResult *rr)); @@ -348,27 +324,10 @@ struct RenderPass *RE_pass_find_by_name(volatile struct RenderLayer *rl, const c struct RenderPass *RE_pass_find_by_type(volatile struct RenderLayer *rl, int passtype, const char *viewname); /* shaded view or baking options */ -#define RE_BAKE_LIGHT 0 /* not listed in rna_scene.c -> can't be enabled! */ -#define RE_BAKE_ALL 1 +#define RE_BAKE_NORMALS 0 +#define RE_BAKE_DISPLACEMENT 1 #define RE_BAKE_AO 2 -#define RE_BAKE_NORMALS 3 -#define RE_BAKE_TEXTURE 4 -#define RE_BAKE_DISPLACEMENT 5 -#define RE_BAKE_SHADOW 6 -#define RE_BAKE_SPEC_COLOR 7 -#define RE_BAKE_SPEC_INTENSITY 8 -#define RE_BAKE_MIRROR_COLOR 9 -#define RE_BAKE_MIRROR_INTENSITY 10 -#define RE_BAKE_ALPHA 11 -#define RE_BAKE_EMIT 12 -#define RE_BAKE_DERIVATIVE 13 -#define RE_BAKE_VERTEX_COLORS 14 - -void RE_Database_Baking( - struct Render *re, struct Main *bmain, struct Scene *scene, struct ViewLayer *view_layer, - unsigned int lay, const int type, struct Object *actob); - -void RE_DataBase_GetView(struct Render *re, float mat[4][4]); + void RE_GetCameraWindow(struct Render *re, struct Object *camera, int frame, float mat[4][4]); void RE_GetCameraModelMatrix(struct Render *re, struct Object *camera, float r_mat[4][4]); struct Scene *RE_GetScene(struct Render *re); @@ -378,13 +337,6 @@ bool RE_is_rendering_allowed(struct Scene *scene, struct Object *camera_override bool RE_allow_render_generic_object(struct Object *ob); -/* RE_updateRenderInstances flag */ -enum { - RE_OBJECT_INSTANCES_UPDATE_VIEW = (1 << 0), - RE_OBJECT_INSTANCES_UPDATE_OBMAT = (1 << 1) -}; -void RE_updateRenderInstances(Render *re, int flag); - /******* defined in render_result.c *********/ bool RE_HasCombinedLayer(RenderResult *res); diff --git a/source/blender/render/extern/include/RE_render_ext.h b/source/blender/render/extern/include/RE_render_ext.h index cf0ff009190..3b4b9262465 100644 --- a/source/blender/render/extern/include/RE_render_ext.h +++ b/source/blender/render/extern/include/RE_render_ext.h @@ -56,12 +56,6 @@ float texture_value_blend(float tex, float out, float fact, float facg, int blen void RE_texture_rng_init(void); void RE_texture_rng_exit(void); -struct Material *RE_sample_material_init(struct Depsgraph *depsgraph, struct Material *orig_mat, struct Scene *scene); -void RE_sample_material_free(struct Material *mat); -void RE_sample_material_color( - struct Material *mat, float color[3], float *alpha, const float volume_co[3], const float surface_co[3], - int tri_index, struct DerivedMesh *orcoDm, struct Object *ob); - /* imagetexture.c */ void ibuf_sample(struct ImBuf *ibuf, float fx, float fy, float dx, float dy, float result[4]); @@ -85,4 +79,6 @@ void RE_point_density_sample( void RE_point_density_free(struct PointDensity *pd); +void RE_point_density_fix_linking(void); + #endif /* __RE_RENDER_EXT_H__ */ diff --git a/source/blender/render/extern/include/RE_shader_ext.h b/source/blender/render/extern/include/RE_shader_ext.h index 281f0082d7f..0d354c27e3a 100644 --- a/source/blender/render/extern/include/RE_shader_ext.h +++ b/source/blender/render/extern/include/RE_shader_ext.h @@ -33,7 +33,7 @@ #define __RE_SHADER_EXT_H__ /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -/* this include is for shading and texture exports */ +/* this include is for texture exports */ /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ /* localized texture result data */ @@ -44,148 +44,6 @@ typedef struct TexResult { float *nor; } TexResult; -/* localized shade result data */ -typedef struct ShadeResult { - float combined[4]; - float col[4]; - float alpha, mist, z; - float emit[3]; - float diff[3]; /* diffuse with no ramps, shadow, etc */ - float diffshad[3]; /* diffuse with shadow */ - float spec[3]; /* specular with shadow */ - float shad[4]; /* shad[3] is shadow intensity */ - float ao[3]; - float env[3]; - float indirect[3]; - float refl[3]; - float refr[3]; - float nor[3]; - float winspeed[4]; - float rayhits[4]; -} ShadeResult; - -/* only here for quick copy */ -struct ShadeInputCopy { - - struct Material *mat; - struct VlakRen *vlr; - struct StrandRen *strand; - struct ObjectInstanceRen *obi; - struct ObjectRen *obr; - int facenr; - float facenor[3]; /* copy from face */ - short flippednor; /* is facenor flipped? */ - struct VertRen *v1, *v2, *v3; /* vertices can be in any order for quads... */ - short i1, i2, i3; /* original vertex indices */ - short puno; - short osatex; - float vn[3], vno[3]; /* actual render normal, and a copy to restore it */ - float n1[3], n2[3], n3[3]; /* vertex normals, corrected */ - int mode, mode2; /* base material mode (OR-ed result of entire node tree) */ -}; - -typedef struct ShadeInputUV { - float dxuv[3], dyuv[3], uv[3]; - const char *name; -} ShadeInputUV; - -typedef struct ShadeInputCol { - float col[4]; - const char *name; -} ShadeInputCol; - -/* localized renderloop data */ -typedef struct ShadeInput { - /* copy from face, also to extract tria from quad */ - /* note it mirrors a struct above for quick copy */ - - struct Material *mat; - struct VlakRen *vlr; - struct StrandRen *strand; - struct ObjectInstanceRen *obi; - struct ObjectRen *obr; - int facenr; - float facenor[3]; /* copy from face */ - short flippednor; /* is facenor flipped? */ - struct VertRen *v1, *v2, *v3; /* vertices can be in any order for quads... */ - short i1, i2, i3; /* original vertex indices */ - short puno; - short osatex; - float vn[3], vno[3]; /* actual render normal, and a copy to restore it */ - float n1[3], n2[3], n3[3]; /* vertex normals, corrected */ - int mode, mode2; /* base material mode (OR-ed result of entire node tree) */ - - /* internal face coordinates */ - float u, v, dx_u, dx_v, dy_u, dy_v; - float co[3], view[3], camera_co[3]; - - /* copy from material, keep synced so we can do memcopy */ - /* current size: 23*4 */ - float r, g, b; - float specr, specg, specb; - float mirr, mirg, mirb; - float ambr, ambb, ambg; - - float amb, emit, ang, spectra, ray_mirror; - float alpha, refl, spec, zoffs, add; - float translucency; - /* end direct copy from material */ - - /* individual copies: */ - int har; /* hardness */ - - /* texture coordinates */ - float lo[3], gl[3], ref[3], orn[3], winco[3], vcol[4]; - float refcol[4], displace[3]; - float strandco, tang[3], nmapnorm[3], nmaptang[4], stress, winspeed[4]; - float duplilo[3], dupliuv[3]; - float tangents[8][4]; /* 8 = MAX_MTFACE */ - - ShadeInputUV uv[8]; /* 8 = MAX_MTFACE */ - ShadeInputCol col[8]; /* 8 = MAX_MCOL */ - int totuv, totcol, actuv, actcol; - - /* dx/dy OSA coordinates */ - float dxco[3], dyco[3]; - float dxlo[3], dylo[3], dxgl[3], dygl[3]; - float dxref[3], dyref[3], dxorn[3], dyorn[3]; - float dxno[3], dyno[3], dxview, dyview; - float dxlv[3], dylv[3]; - float dxwin[3], dywin[3]; - float dxrefract[3], dyrefract[3]; - float dxstrand, dystrand; - - /* AO is a pre-process now */ - float ao[3], indirect[3], env[3]; - - int xs, ys; /* pixel to be rendered */ - int mask; /* subsample mask */ - float scanco[3]; /* original scanline coordinate without jitter */ - - int samplenr; /* sample counter, to detect if we should do shadow again */ - int depth; /* 1 or larger on raytrace shading */ - int volume_depth; /* number of intersections through volumes */ - - /* for strand shading, normal at the surface */ - float surfnor[3], surfdist; - - /* from initialize, part or renderlayer */ - bool do_preview; /* for nodes, in previewrender */ - bool do_manage; /* color management flag */ - bool use_world_space_shading; - short thread, sample; /* sample: ShadeSample array index */ - short nodes; /* indicate node shading, temp hack to prevent recursion */ - - unsigned int lay; - int layflag, passflag, combinedflag; - short object_pass_index; - -#ifdef RE_RAYCOUNTER - RayCounter raycounter; -#endif - -} ShadeInput; - typedef struct BakeImBufuserData { float *displacement_buffer; char *mask_buffer; @@ -212,46 +70,6 @@ int multitex_ext(struct Tex *tex, int multitex_ext_safe(struct Tex *tex, float texvec[3], struct TexResult *texres, struct ImagePool *pool, bool scene_color_manage, const bool skip_load_image); /* only for internal node usage */ int multitex_nodes(struct Tex *tex, float texvec[3], float dxt[3], float dyt[3], int osatex, struct TexResult *texres, - const short thread, short which_output, struct ShadeInput *shi, struct MTex *mtex, - struct ImagePool *pool); -float RE_lamp_get_data(struct ShadeInput *shi, struct Object *lamp_obj, float col[4], float lv[3], float *dist, float shadow[4]); -void RE_instance_get_particle_info(struct ObjectInstanceRen *obi, float *index, float *random, float *age, float *lifetime, float co[3], float *size, float vel[3], float angvel[3]); - -float RE_fresnel_dielectric(float incoming[3], float normal[3], float eta); - -/* shaded view and bake */ -struct Render; -struct Image; - -int RE_bake_shade_all_selected(struct Render *re, int type, struct Object *actob, short *do_update, float *progress); -struct Image *RE_bake_shade_get_image(void); -void RE_bake_ibuf_filter(struct ImBuf *ibuf, char *mask, const int filter); -void RE_bake_ibuf_normalize_displacement(struct ImBuf *ibuf, float *displacement, char *mask, float displacement_min, float displacement_max); -float RE_bake_make_derivative(struct ImBuf *ibuf, float *heights_buffer, const char *mask, - const float height_min, const float height_max, - const float fmult); - -enum { - RE_OBJECT_INSTANCE_MATRIX_OB, - RE_OBJECT_INSTANCE_MATRIX_OBINV, - RE_OBJECT_INSTANCE_MATRIX_LOCALTOVIEW, - RE_OBJECT_INSTANCE_MATRIX_LOCALTOVIEWINV, -}; - -const float (*RE_object_instance_get_matrix(struct ObjectInstanceRen *obi, int matrix_id))[4]; - -float RE_object_instance_get_object_pass_index(struct ObjectInstanceRen *obi); -float RE_object_instance_get_random_id(struct ObjectInstanceRen *obi); - -enum { - RE_VIEW_MATRIX, - RE_VIEWINV_MATRIX, -}; - -const float (*RE_render_current_get_matrix(int matrix_id))[4]; - -#define BAKE_RESULT_OK 0 -#define BAKE_RESULT_NO_OBJECTS 1 -#define BAKE_RESULT_FEEDBACK_LOOP 2 + const short thread, short which_output, struct MTex *mtex, struct ImagePool *pool); #endif /* __RE_SHADER_EXT_H__ */ diff --git a/source/blender/render/intern/include/envmap.h b/source/blender/render/intern/include/envmap.h deleted file mode 100644 index 627e6c0e1e6..00000000000 --- a/source/blender/render/intern/include/envmap.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * envmap_ext.h - * - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/render/intern/include/envmap.h - * \ingroup render - */ - - -#ifndef __ENVMAP_H__ -#define __ENVMAP_H__ - -/** - * Make environment maps for all objects in the scene that have an - * environment map as texture. - * (initrender.c) - */ - -struct Render; -struct TexResult; -struct ImagePool; - -void make_envmaps(struct Render *re); -int envmaptex(struct Tex *tex, const float texvec[3], float dxt[3], float dyt[3], int osatex, struct TexResult *texres, struct ImagePool *pool, const bool skip_image_load); -void env_rotate_scene(struct Render *re, float mat[4][4], int do_rotate); - -#endif /* __ENVMAP_H__ */ - diff --git a/source/blender/render/intern/include/initrender.h b/source/blender/render/intern/include/initrender.h index 87e2d2519d5..e7ff3c7097c 100644 --- a/source/blender/render/intern/include/initrender.h +++ b/source/blender/render/intern/include/initrender.h @@ -33,16 +33,11 @@ #ifndef __INITRENDER_H__ #define __INITRENDER_H__ - /* Functions */ -void free_sample_tables(Render *re); -void make_sample_tables(Render *re); - -void RE_parts_init(Render *re, bool do_crop); +void RE_parts_init(Render *re); void RE_parts_free(Render *re); void RE_parts_clamp(Render *re); - #endif /* __INITRENDER_H__ */ diff --git a/source/blender/render/intern/include/occlusion.h b/source/blender/render/intern/include/occlusion.h deleted file mode 100644 index 4a70d691436..00000000000 --- a/source/blender/render/intern/include/occlusion.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2008 Blender Foundation. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): Brecht Van Lommel. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/render/intern/include/occlusion.h - * \ingroup render - */ - - -#ifndef __OCCLUSION_H__ -#define __OCCLUSION_H__ - -struct Render; -struct ShadeInput; -struct RenderPart; -struct ShadeSample; - -void make_occ_tree(struct Render *re); -void free_occ(struct Render *re); -void sample_occ(struct Render *re, struct ShadeInput *shi); - -void cache_occ_samples(struct Render *re, struct RenderPart *pa, struct ShadeSample *ssamp); -void free_occ_samples(struct Render *re, struct RenderPart *pa); - -#endif - diff --git a/source/blender/render/intern/include/pixelblending.h b/source/blender/render/intern/include/pixelblending.h deleted file mode 100644 index 17a872a0676..00000000000 --- a/source/blender/render/intern/include/pixelblending.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * Contributor(s): 2004-2006 Blender Foundation, full recode - * - * ***** END GPL/BL DUAL LICENSE BLOCK ***** - */ - -/** \file blender/render/intern/include/pixelblending.h - * \ingroup render - */ - - -#ifndef __PIXELBLENDING_H__ -#define __PIXELBLENDING_H__ - - -/** - * add 1 pixel to into filtered three lines - * (float vecs to float vec) - */ -void add_filt_fmask(unsigned int mask, const float col[4], float *rowbuf, int row_w); -void add_filt_fmask_pixsize(unsigned int mask, float *in, float *rowbuf, int row_w, int pixsize); -void add_filt_fmask_coord(float filt[3][3], const float col[4], float *rowbuf, int row_stride, int x, int y, rcti *mask); -void mask_array(unsigned int mask, float filt[3][3]); - -/** - * Alpha-over blending for floats. - */ -void addAlphaOverFloat(float dest[4], const float source[4]); - -/** - * Alpha-under blending for floats. - */ -void addAlphaUnderFloat(float dest[4], const float source[4]); - - -/** - * Same for floats - */ -void addalphaAddfacFloat(float dest[4], const float source[4], char addfac); - -/** - * dest = dest + source - */ -void addalphaAddFloat(float dest[4], const float source[4]); - -#endif /* __PIXELBLENDING_H__ */ diff --git a/source/blender/render/intern/include/pixelshading.h b/source/blender/render/intern/include/pixelshading.h deleted file mode 100644 index 8f23455564f..00000000000 --- a/source/blender/render/intern/include/pixelshading.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * Contributor(s): 2004-2006, Blender Foundation, full recode - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/render/intern/include/pixelshading.h - * \ingroup render - * - * These functions determine what actual color a pixel will have. - */ - -#ifndef __PIXELSHADING_H__ -#define __PIXELSHADING_H__ - - -/** - * Render the pixel at (x,y) for object ap. Apply the jitter mask. - * Output is given in float collector[4]. The type vector: - * t[0] - min. distance - * t[1] - face/halo index - * t[2] - jitter mask - * t[3] - type ZB_POLY or ZB_HALO - * t[4] - max. distance - * mask is pixel coverage in bits - * \return pointer to the object - */ -int shadeHaloFloat(HaloRen *har, - float *col, int zz, - float dist, float xn, - float yn, short flarec); - -/** - * Render the sky at pixel (x, y). - */ -void shadeSkyPixel(float collector[4], float fx, float fy, short thread); -void shadeSkyView(float col_r[3], const float rco[3], const float view[3], const float dxyview[2], short thread); -void shadeAtmPixel(struct SunSky *sunsky, float *collector, float fx, float fy, float distance); -void shadeSunView(float col_r[3], const float view[3]); -/* ------------------------------------------------------------------------- */ - -#endif - diff --git a/source/blender/render/intern/include/pointdensity.h b/source/blender/render/intern/include/pointdensity.h deleted file mode 100644 index 263fa44f9c4..00000000000 --- a/source/blender/render/intern/include/pointdensity.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): Matt Ebb - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/render/intern/include/pointdensity.h - * \ingroup render - */ - - -#ifndef __POINTDENSITY_H__ -#define __POINTDENSITY_H__ - -/** - * Make point density kd-trees for all point density textures in the scene - */ - -struct Depsgraph; -struct PointDensity; -struct Render; -struct TexResult; - -void free_pointdensity(struct PointDensity *pd); -void cache_pointdensity(struct Depsgraph *depsgraph, struct Render *re, struct PointDensity *pd); -void make_pointdensities(struct Depsgraph *depsgraph, struct Render *re); -void free_pointdensities(struct Render *re); -int pointdensitytex(struct Tex *tex, const float texvec[3], struct TexResult *texres); - -#endif /* __POINTDENSITY_H__ */ - diff --git a/source/blender/render/intern/include/raycounter.h b/source/blender/render/intern/include/raycounter.h deleted file mode 100644 index 1694273df0e..00000000000 --- a/source/blender/render/intern/include/raycounter.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2009 Blender Foundation. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): André Pinto. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/render/intern/include/raycounter.h - * \ingroup render - */ - - -#ifndef __RAYCOUNTER_H__ -#define __RAYCOUNTER_H__ - -//#define RE_RAYCOUNTER /* enable counters per ray, useful for measuring raytrace structures performance */ - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef RE_RAYCOUNTER - -/* ray counter functions */ - -typedef struct RayCounter { - struct { - unsigned long long test, hit; - } faces, bb, simd_bb, raycast, raytrace_hint, rayshadow_last_hit; -} RayCounter; - -#define RE_RC_INIT(isec, shi) (isec).raycounter = &((shi).shading.raycounter) -void RE_RC_INFO(RayCounter *rc); -void RE_RC_MERGE(RayCounter *rc, RayCounter *tmp); -#define RE_RC_COUNT(var) (var)++ - -extern RayCounter re_rc_counter[]; - -#else - -/* ray counter stubs */ - -#define RE_RC_INIT(isec,shi) -#define RE_RC_INFO(rc) -#define RE_RC_MERGE(dest,src) -#define RE_RC_COUNT(var) - -#endif - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/source/blender/render/intern/include/rayintersection.h b/source/blender/render/intern/include/rayintersection.h deleted file mode 100644 index 1935e4ef59c..00000000000 --- a/source/blender/render/intern/include/rayintersection.h +++ /dev/null @@ -1,136 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2007 Blender Foundation. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): André Pinto. - * - * ***** END GPL LICENSE BLOCK ***** - * RE_raytrace.h: ray tracing api, can be used independently from the renderer. - */ - -/** \file blender/render/intern/include/rayintersection.h - * \ingroup render - */ - - -#ifndef __RAYINTERSECTION_H__ -#define __RAYINTERSECTION_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "BLI_math_geom.h" - -struct RayObject; - -/* Ray Hints */ - -#define RE_RAY_LCTS_MAX_SIZE 256 -#define RT_USE_LAST_HIT /* last shadow hit is reused before raycasting on whole tree */ -//#define RT_USE_HINT /* last hit object is reused before raycasting on whole tree */ - -typedef struct LCTSHint { - int size; - struct RayObject *stack[RE_RAY_LCTS_MAX_SIZE]; -} LCTSHint; - -typedef struct RayHint { - union { LCTSHint lcts; } data; -} RayHint; - -/* Ray Intersection */ - -typedef struct Isect { - /* ray start, direction (normalized vector), and max distance. on hit, - * the distance is modified to be the distance to the hit point. */ - float start[3]; - float dir[3]; - float dist; - - /* for envmap and incremental view update renders */ - float origstart[3]; - float origdir[3]; - - /* precomputed values to accelerate bounding box intersection */ - int bv_index[6]; - float idot_axis[3]; - - /* intersection options */ - int mode; /* RE_RAY_SHADOW, RE_RAY_MIRROR, RE_RAY_SHADOW_TRA */ - int lay; /* -1 default, set for layer lamps */ - int skip; /* skip flags */ - int check; /* check flags */ - void *userdata; /* used by bake check */ - - /* hit information */ - float u, v; - int isect; /* which half of quad */ - - struct { - void *ob; - void *face; - } hit, orig; - - /* last hit optimization */ - struct RayObject *last_hit; - - /* hints */ -#ifdef RT_USE_HINT - RayTraceHint *hint, *hit_hint; -#endif - RayHint *hint; - - /* ray counter */ -#ifdef RE_RAYCOUNTER - RayCounter *raycounter; -#endif - - /* Precalculated coefficients for watertight intersection check. */ - struct IsectRayPrecalc isect_precalc; -} Isect; - -/* ray types */ -#define RE_RAY_SHADOW 0 -#define RE_RAY_MIRROR 1 -#define RE_RAY_SHADOW_TRA 2 - -/* skip options */ -#define RE_SKIP_CULLFACE (1 << 0) -/* if using this flag then *face should be a pointer to a VlakRen */ -#define RE_SKIP_VLR_NEIGHBOUR (1 << 1) - -/* check options */ -#define RE_CHECK_VLR_NONE 0 -#define RE_CHECK_VLR_RENDER 1 -#define RE_CHECK_VLR_NON_SOLID_MATERIAL 2 -#define RE_CHECK_VLR_BAKE 3 - -/* arbitrary, but can't use e.g. FLT_MAX because of precision issues */ -#define RE_RAYTRACE_MAXDIST 1e15f -#define RE_RAYTRACE_EPSILON 0.0f - -#ifdef __cplusplus -} -#endif - -#endif /* __RAYINTERSECTION_H__ */ - diff --git a/source/blender/render/intern/include/rayobject.h b/source/blender/render/intern/include/rayobject.h deleted file mode 100644 index 63135d01c23..00000000000 --- a/source/blender/render/intern/include/rayobject.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2009 Blender Foundation. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): André Pinto. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/render/intern/include/rayobject.h - * \ingroup render - */ - - -#ifndef __RAYOBJECT_H__ -#define __RAYOBJECT_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -struct Isect; -struct ObjectInstanceRen; -struct RayHint; -struct VlakRen; - -/* RayObject - * Can be a face/triangle, bvh tree, object instance, etc. This is the - * public API used by the renderer, see rayobject_internal.h for the - * internal implementation details. - * */ -typedef struct RayObject RayObject; - -/* Intersection, see rayintersection.h */ - -int RE_rayobject_raycast(RayObject *r, struct Isect *i); - -/* Acceleration Structures */ - -RayObject *RE_rayobject_octree_create(int ocres, int size); -RayObject *RE_rayobject_instance_create(RayObject *target, float transform[4][4], void *ob, void *target_ob); -RayObject *RE_rayobject_empty_create(void); - -RayObject *RE_rayobject_vbvh_create(int size); /* raytrace/rayobject_vbvh.c */ -RayObject *RE_rayobject_svbvh_create(int size); /* raytrace/rayobject_svbvh.c */ -RayObject *RE_rayobject_qbvh_create(int size); /* raytrace/rayobject_qbvh.c */ - -/* Building */ - -void RE_rayobject_add(RayObject *r, RayObject *); -void RE_rayobject_done(RayObject *r); -void RE_rayobject_free(RayObject *r); - -void RE_rayobject_set_control(RayObject *r, void *data, int (*test_break)(void *data)); - -/* RayObject representing faces, all data is locally available instead - * of referring to some external data structure, for possibly faster - * intersection tests. */ - -typedef struct RayFace { - float v1[4], v2[4], v3[4], v4[3]; - int quad; - void *ob; - void *face; -} RayFace; - -#define RE_rayface_isQuad(a) ((a)->quad) - -RayObject *RE_rayface_from_vlak(RayFace *face, struct ObjectInstanceRen *obi, struct VlakRen *vlr); - -RayObject *RE_rayface_from_coords(RayFace *rayface, void *ob, void *face, float *v1, float *v2, float *v3, float *v4); - -/* RayObject representing faces directly from a given VlakRen structure. Thus - * allowing to save memory, but making code triangle intersection dependent on - * render structures. */ - -typedef struct VlakPrimitive { - struct ObjectInstanceRen *ob; - struct VlakRen *face; -} VlakPrimitive; - -RayObject *RE_vlakprimitive_from_vlak(VlakPrimitive *face, struct ObjectInstanceRen *obi, struct VlakRen *vlr); - -/* Bounding Box */ - -/* extend min/max coords so that the rayobject is inside them */ -void RE_rayobject_merge_bb(RayObject *ob, float *min, float *max); - -/* initializes an hint for optimizing raycast where it is know that a ray will pass by the given BB often the origin point */ -void RE_rayobject_hint_bb(RayObject *r, struct RayHint *hint, float min[3], float max[3]); - -/* initializes an hint for optimizing raycast where it is know that a ray will be contained inside the given cone*/ -/* void RE_rayobject_hint_cone(RayObject *r, struct RayHint *hint, float *); */ - -/* Internals */ - -#include "../raytrace/rayobject_internal.h" - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/source/blender/render/intern/include/render_result.h b/source/blender/render/intern/include/render_result.h index 03292579d90..9a1b1b5abe8 100644 --- a/source/blender/render/intern/include/render_result.h +++ b/source/blender/render/intern/include/render_result.h @@ -55,8 +55,6 @@ struct ColorManagedViewSettings; struct RenderResult *render_result_new(struct Render *re, struct rcti *partrct, int crop, int savebuffers, const char *layername, const char *viewname); -struct RenderResult *render_result_new_full_sample(struct Render *re, - struct ListBase *lb, struct rcti *partrct, int crop, int savebuffers, const char *viewname); struct RenderResult *render_result_new_from_exr(void *exrhandle, const char *colorspace, bool predivide, int rectx, int recty); diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h index 97224d3aec0..8308b5e76e4 100644 --- a/source/blender/render/intern/include/render_types.h +++ b/source/blender/render/intern/include/render_types.h @@ -35,58 +35,19 @@ /* exposed internal in render module only! */ /* ------------------------------------------------------------------------- */ -#include "DNA_color_types.h" -#include "DNA_customdata_types.h" #include "DNA_scene_types.h" -#include "DNA_world_types.h" #include "DNA_object_types.h" -#include "DNA_vec_types.h" #include "BLI_threads.h" #include "BKE_main.h" #include "RE_pipeline.h" -#include "RE_shader_ext.h" /* TexResult, ShadeResult, ShadeInput */ -#include "sunsky.h" -#include "BLI_sys_types.h" // for intptr_t support - -struct Depsgraph; struct Object; -struct MemArena; -struct VertTableNode; -struct VlakTableNode; -struct GHash; -struct ObjectInstanceRen; -struct RayObject; -struct RayFace; struct RenderEngine; struct ReportList; struct Main; -struct ImagePool; - -#define TABLEINITSIZE 1024 - -typedef struct SampleTables { - float centLut[16]; - float *fmask1[9], *fmask2[9]; - char cmask[256], *centmask; - -} SampleTables; - -typedef struct QMCSampler { - struct QMCSampler *next, *prev; - int type; - int tot; - int used; - double *samp2d; - double offs[BLENDER_MAX_THREADS][2]; -} QMCSampler; - -// #define SAMP_TYPE_JITTERED 0 // UNUSED -#define SAMP_TYPE_HALTON 1 -#define SAMP_TYPE_HAMMERSLEY 2 /* this is handed over to threaded hiding/passes/shading engine */ typedef struct RenderPart { @@ -95,24 +56,10 @@ typedef struct RenderPart { RenderResult *result; /* result of part rendering */ ListBase fullresult; /* optional full sample buffers */ - int *recto; /* object table for objects */ - int *rectp; /* polygon index table */ - int *rectz; /* zbuffer */ - int *rectmask; /* negative zmask */ - intptr_t *rectdaps; /* delta acum buffer for pixel structs */ - int *rectbacko; /* object table for backside sss */ - int *rectbackp; /* polygon index table for backside sss */ - int *rectbackz; /* zbuffer for backside sss */ - intptr_t *rectall; /* buffer for all faces for sss */ - rcti disprect; /* part coordinates within total picture */ int rectx, recty; /* the size */ int nr; /* nr is partnr */ - short crop, status; /* crop is amount of pixels we crop, for filter */ - short sample; /* sample can be used by zbuffers */ - short thread; /* thread id */ - - char *clipflag; /* clipflags for part zbuffering */ + short status; } RenderPart; enum { @@ -129,10 +76,7 @@ struct Render { int slot; /* state settings */ - short flag, osa, ok, result_ok; - - /* due to performance issues, getting initialized from color management settings once on Render initialization */ - bool scene_color_manage; + short flag, ok, result_ok; /* result of rendering */ RenderResult *result; @@ -150,8 +94,6 @@ struct Render { * without border & crop. convert to long before multiplying together to avoid overflow. */ rcti disprect; /* part within winx winy */ rctf viewplane; /* mapped on winx winy */ - float viewdx, viewdy; /* size of 1 pixel */ - float clipcrop; /* 2 pixel boundary to prevent clip when filter used */ /* final picture width and height (within disprect) */ int rectx, recty; @@ -160,14 +102,7 @@ struct Render { * partx*xparts can be larger than rectx, in that case last part is smaller */ int partx, party; - /* values for viewing */ - float ycor; /* (scene->xasp / scene->yasp), multiplied with 'winy' */ - - float panophi, panosi, panoco, panodxp, panodxv; - - /* Matrices */ - float grvec[3]; /* for world */ - float imat[3][3]; /* copy of viewinv */ + /* Camera transform, only used by Freestyle. */ float viewmat[4][4], viewinv[4][4]; float viewmat_orig[4][4]; /* for incremental render */ float winmat[4][4]; @@ -176,23 +111,12 @@ struct Render { float clipsta; float clipend; - /* samples */ - SampleTables *samples; - float jit[32][2]; - float mblur_jit[32][2]; - ListBase *qmcsamplers; - int num_qmc_samplers; - - /* shadow counter, detect shadow-reuse for shaders */ - int shadowsamplenr[BLENDER_MAX_THREADS]; - /* main, scene, and its full copy of renderdata and world */ struct Main *main; Scene *scene; RenderData r; ListBase view_layers; int active_view_layer; - World wrld; struct Object *camera_override; unsigned int lay, layer_override; @@ -202,56 +126,11 @@ struct Render { /* render engine */ struct RenderEngine *engine; - /* octree tables and variables for raytrace */ - struct RayObject *raytree; - struct RayFace *rayfaces; - struct VlakPrimitive *rayprimitives; - float maxdist; /* needed for keeping an incorrect behavior of SUN and HEMI lights (avoid breaking old scenes) */ - - /* occlusion tree */ - void *occlusiontree; - ListBase strandsurface; - - /* use this instead of R.r.cfra */ - float mblur_offs, field_offs; - - /* render database */ - int totvlak, totvert, tothalo, totstrand, totlamp; - struct HaloRen **sortedhalos; - - ListBase lights; /* GroupObject pointers */ - ListBase lampren; /* storage, for free */ - - ListBase objecttable; - - struct ObjectInstanceRen *objectinstance; - ListBase instancetable; - int totinstance; - - struct Image *bakebuf; - - struct GHash *orco_hash; - - struct GHash *sss_hash; - ListBase *sss_points; - struct Material *sss_mat; - - ListBase customdata_names; - - struct Object *excludeob; - ListBase render_volumes_inside; - ListBase volumes; - #ifdef WITH_FREESTYLE struct Main *freestyle_bmain; ListBase freestyle_renders; #endif - /* arena for allocating data for use during render, for - * example dynamic TFaces to go in the VlakRen structure. - */ - struct MemArena *memArena; - /* callbacks */ void (*display_init)(void *handle, RenderResult *rr); void *dih; @@ -276,414 +155,14 @@ struct Render { struct ReportList *reports; - struct ImagePool *pool; - void **movie_ctx_arr; char viewname[MAX_NAME]; }; -/* ------------------------------------------------------------------------- */ - -struct ISBData; - -typedef struct DeepSample { - int z; - float v; -} DeepSample; - -typedef struct ShadSampleBuf { - struct ShadSampleBuf *next, *prev; - intptr_t *zbuf; - char *cbuf; - DeepSample **deepbuf; - int *totbuf; -} ShadSampleBuf; - -typedef struct ShadBuf { - /* regular shadowbuffer */ - short samp, shadhalostep, totbuf; - float persmat[4][4]; - float viewmat[4][4]; - float winmat[4][4]; - float *jit, *weight; - float d, clipend, pixsize, soft, compressthresh; - int co[3]; - int size, bias; - ListBase buffers; - - /* irregular shadowbufer, result stored per thread */ - struct ISBData *isb_result[BLENDER_MAX_THREADS]; -} ShadBuf; - -/* ------------------------------------------------------------------------- */ - -typedef struct ObjectRen { - struct ObjectRen *next, *prev; - struct Object *ob, *par; - struct Scene *sce; - int index, psysindex, flag, lay; - - float boundbox[2][3]; - - int totvert, totvlak, totstrand, tothalo; - int vertnodeslen, vlaknodeslen, strandnodeslen, blohalen; - struct VertTableNode *vertnodes; - struct VlakTableNode *vlaknodes; - struct StrandTableNode *strandnodes; - struct HaloRen **bloha; - struct StrandBuffer *strandbuf; - - char (*mtface)[MAX_CUSTOMDATA_LAYER_NAME]; - char (*mcol)[MAX_CUSTOMDATA_LAYER_NAME]; - int actmtface, actmcol, bakemtface; - - short tangent_mask; /* which tangent layer should be calculated */ - - float obmat[4][4]; /* only used in convertblender.c, for instancing */ - - /* used on makeraytree */ - struct RayObject *raytree; - struct RayFace *rayfaces; - struct VlakPrimitive *rayprimitives; - struct ObjectInstanceRen *rayobi; - -} ObjectRen; - -typedef struct ObjectInstanceRen { - struct ObjectInstanceRen *next, *prev; - - ObjectRen *obr; - Object *ob, *par; - int index, psysindex, lay; - - float mat[4][4], imat[4][4]; - float nmat[3][3]; /* nmat is inverse mat tranposed */ - - float obmat[4][4], obinvmat[4][4]; - float localtoviewmat[4][4], localtoviewinvmat[4][4]; - - short flag; - - float dupliorco[3], dupliuv[2]; - float (*duplitexmat)[4]; - - struct VolumePrecache *volume_precache; - - float *vectors; /* (RE_WINSPEED_ELEMS * VertRen.index) */ - int totvector; - - /* used on makeraytree */ - struct RayObject *raytree; - int transform_primitives; - - /* Particle info */ - float part_index; - float part_age; - float part_lifetime; - float part_size; - float part_co[3]; - float part_vel[3]; - float part_avel[3]; - - unsigned int random_id; -} ObjectInstanceRen; - -/* ------------------------------------------------------------------------- */ - -typedef struct VertRen { - float co[3]; - float n[3]; - float *orco; - unsigned int flag; /* in use for clipping zbuffer parts, temp setting stuff in convertblender.c - * only an 'int' because of alignment, could be a char too */ - float accum; /* accum for radio weighting, and for strand texco static particles */ - int index; /* index allows extending vertren with any property */ -} VertRen; - -/* ------------------------------------------------------------------------- */ - -struct halosort { - struct HaloRen *har; - int z; -}; - -/* ------------------------------------------------------------------------- */ -struct Material; -struct ImagePool; - -typedef struct RadFace { - float unshot[3], totrad[3]; - float norm[3], cent[3], area; - int flag; -} RadFace; - -typedef struct VlakRen { - struct VertRen *v1, *v2, *v3, *v4; /* keep in order for ** addressing */ - float n[3]; - struct Material *mat; - char puno; - char flag, ec; -#ifdef WITH_FREESTYLE - char freestyle_edge_mark; - char freestyle_face_mark; -#endif - int index; -} VlakRen; - -typedef struct HaloRen { - short miny, maxy; - float alfa, xs, ys, rad, radsq, sin, cos, co[3], no[3]; - float hard, b, g, r; - int zs, zd; - int zBufDist; /* depth in the z-buffer coordinate system */ - char starpoints, type, add, tex; - char linec, ringc, seed; - short flarec; /* used to be a char. why ?*/ - float hasize; - int pixels; - unsigned int lay; - struct Material *mat; - struct ImagePool *pool; - bool skip_load_image, texnode_preview; -} HaloRen; - -/* ------------------------------------------------------------------------- */ - -typedef struct StrandVert { - float co[3]; - float strandco; -} StrandVert; - -typedef struct StrandSurface { - struct StrandSurface *next, *prev; - ObjectRen obr; - int (*face)[4]; - float (*co)[3]; - /* for occlusion caching */ - float (*ao)[3]; - float (*env)[3]; - float (*indirect)[3]; - /* for speedvectors */ - float (*prevco)[3], (*nextco)[3]; - int totvert, totface; -} StrandSurface; - -typedef struct StrandBound { - int start, end; - float boundbox[2][3]; -} StrandBound; - -typedef struct StrandBuffer { - struct StrandBuffer *next, *prev; - struct StrandVert *vert; - struct StrandBound *bound; - int totvert, totbound; - - struct ObjectRen *obr; - struct Material *ma; - struct StrandSurface *surface; - unsigned int lay; - int overrideuv; - int flag, maxdepth; - float adaptcos, minwidth, widthfade; - - float maxwidth; /* for cliptest of strands in blender unit */ - - float winmat[4][4]; - int winx, winy; -} StrandBuffer; - -typedef struct StrandRen { - StrandVert *vert; - StrandBuffer *buffer; - int totvert, flag; - int clip, index; - float orco[3]; -} StrandRen; - -/* ------------------------------------------------------------------------- */ - -typedef struct VolumeOb { - struct VolumeOb *next, *prev; - struct Material *ma; - struct ObjectRen *obr; -} VolumeOb; - -typedef struct MatInside { - struct MatInside *next, *prev; - struct Material *ma; - struct ObjectInstanceRen *obi; -} MatInside; - -typedef struct VolPrecachePart { - struct VolPrecachePart *next, *prev; - struct RayObject *tree; - struct ShadeInput *shi; - struct ObjectInstanceRen *obi; - float viewmat[4][4]; - int num; - int minx, maxx; - int miny, maxy; - int minz, maxz; - int res[3]; - float bbmin[3]; - float voxel[3]; - struct Render *re; -} VolPrecachePart; - -typedef struct VolumePrecache { - int res[3]; - float *bbmin, *bbmax; - float *data_r; - float *data_g; - float *data_b; -} VolumePrecache; - -/* ------------------------------------------------------------------------- */ - -struct LampRen; -struct MTex; - -/** - * For each lamp in a scene, a LampRen is created. It determines the - * properties of a lightsource. - */ - -typedef struct LampShadowSubSample { - int samplenr; - float shadfac[4]; /* rgba shadow */ -} LampShadowSubSample; - -typedef struct LampShadowSample { - LampShadowSubSample s[16]; /* MAX OSA */ -} LampShadowSample; - -typedef struct LampRen { - struct LampRen *next, *prev; - - float xs, ys, dist; - float co[3]; - short type; - int mode; - float r, g, b, k; - float shdwr, shdwg, shdwb; - float energy, haint; - int lay; - float spotsi, spotbl; - float vec[3]; - float xsp, ysp, distkw, inpr; - float halokw, halo; - - short falloff_type; - float ld1, ld2; - float coeff_const, coeff_lin, coeff_quad; - struct CurveMapping *curfalloff; - - /* copied from Lamp, to decouple more rendering stuff */ - /** Size of the shadowbuffer */ - short bufsize; - /** Number of samples for the shadows */ - short samp; - /** Softness factor for shadow */ - float soft; - /** amount of subsample buffers and type of filter for sampling */ - short buffers, filtertype; - /** shadow buffer type (regular, irregular) */ - short buftype; - /** autoclip */ - short bufflag; - /** shadow plus halo: detail level */ - short shadhalostep; - /** Near clip of the lamp */ - float clipsta; - /** Far clip of the lamp */ - float clipend; - /** A small depth offset to prevent self-shadowing. */ - float bias; - /* Compression threshold for deep shadow maps */ - float compressthresh; - - short ray_samp, ray_sampy, ray_sampz, ray_samp_method, ray_samp_type, area_shape, ray_totsamp; - short xold[BLENDER_MAX_THREADS], yold[BLENDER_MAX_THREADS]; /* last jitter table for area lights */ - float area_size, area_sizey, area_sizez; - float adapt_thresh; - - /* sun/sky */ - struct SunSky *sunsky; - - struct ShadBuf *shb; - float *jitter; - - float imat[3][3]; - float spottexfac; - float sh_invcampos[3], sh_zfac; /* sh_= spothalo */ - - float lampmat[4][4]; /* worls space lamp matrix, used for scene rotation */ - - float mat[3][3]; /* 3x3 part from lampmat x viewmat */ - float area[8][3], areasize; - - /* passes & node shader support: all shadow info for a pixel */ - LampShadowSample *shadsamp; - - /* ray optim */ - struct RayObject *last_hit[BLENDER_MAX_THREADS]; - - struct MTex *mtex[MAX_MTEX]; - - /* threading */ - int thread_assigned; - int thread_ready; -} LampRen; - /* **************** defines ********************* */ -/* R.r.mode flag is same as for renderdata */ - /* R.flag */ -#define R_ZTRA 1 -#define R_HALO 2 -#define R_SEC_FIELD 4 -#define R_LAMPHALO 8 -#define R_NEED_TANGENT 16 -#define R_BAKE_TRACE 32 -#define R_BAKING 64 -#define R_ANIMATION 128 -#define R_NEED_VCOL 256 - -/* vlakren->flag (vlak = face in dutch) char!!! */ -#define R_SMOOTH 1 -#define R_HIDDEN 2 -/* strand flag, means special handling */ -#define R_STRAND 4 -#define R_FULL_OSA 8 -#define R_FACE_SPLIT 16 -/* Tells render to divide face other way. */ -#define R_DIVIDE_24 32 -/* vertex normals are tangent or view-corrected vector, for hair strands */ -#define R_TANGENT 64 -#define R_TRACEBLE 128 - -/* vlakren->freestyle_edge_mark */ -#ifdef WITH_FREESTYLE -# define R_EDGE_V1V2 1 -# define R_EDGE_V2V3 2 -# define R_EDGE_V3V4 4 -# define R_EDGE_V3V1 4 -# define R_EDGE_V4V1 8 -#endif - -/* strandbuffer->flag */ -#define R_STRAND_BSPLINE 1 -#define R_STRAND_B_UNITS 2 - -/* objectren->flag */ -#define R_INSTANCEABLE 1 - -/* objectinstance->flag */ -#define R_DUPLI_TRANSFORMED 1 -#define R_ENV_TRANSFORMED 2 -#define R_TRANSFORMED (1|2) +#define R_ANIMATION 1 #endif /* __RENDER_TYPES_H__ */ diff --git a/source/blender/render/intern/include/rendercore.h b/source/blender/render/intern/include/rendercore.h deleted file mode 100644 index c01db7db53e..00000000000 --- a/source/blender/render/intern/include/rendercore.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#ifndef __RENDERCORE_H__ -#define __RENDERCORE_H__ - -/** \file blender/render/intern/include/rendercore.h - * \ingroup render - */ - -#include "render_types.h" - -#include "RE_engine.h" - -#include "DNA_node_types.h" - -#include "NOD_composite.h" - -struct ShadeInput; -struct ShadeResult; -struct World; -struct RenderPart; -struct RenderLayer; -struct RayObject; - -/* ------------------------------------------------------------------------- */ - -typedef struct PixStr { - struct PixStr *next; - int obi, facenr, z, maskz; - unsigned short mask; - short shadfac; -} PixStr; - -typedef struct PixStrMain { - struct PixStrMain *next, *prev; - struct PixStr *ps; - int counter; -} PixStrMain; - -/* ------------------------------------------------------------------------- */ - - -void calc_view_vector(float view[3], float x, float y); -float mistfactor(float zcor, const float co[3]); /* dist and height, return alpha */ - -void renderspothalo(struct ShadeInput *shi, float col[4], float alpha); -void add_halo_flare(Render *re); - -void calc_renderco_zbuf(float co[3], const float view[3], int z); -void calc_renderco_ortho(float co[3], float x, float y, int z); - -int count_mask(unsigned short mask); - -void zbufshade_tile(struct RenderPart *pa); -void zbufshadeDA_tile(struct RenderPart *pa); - -void zbufshade_sss_tile(struct RenderPart *pa); - -int get_sample_layers(struct RenderPart *pa, struct RenderLayer *rl, struct RenderLayer **rlpp); - -void render_internal_update_passes(struct RenderEngine *engine, struct Scene *scene, struct ViewLayer *view_layer); - - -/* -------- ray.c ------- */ - -struct RayObject *RE_rayobject_create(int type, int size, int octree_resolution); - -extern void freeraytree(Render *re); -extern void makeraytree(Render *re); -struct RayObject* makeraytree_object(Render *re, ObjectInstanceRen *obi); - -extern void ray_shadow(ShadeInput *shi, LampRen *lar, float shadfac[4]); -extern void ray_trace(ShadeInput *shi, ShadeResult *); -extern void ray_ao(ShadeInput *shi, float ao[3], float env[3]); -extern void init_jitter_plane(LampRen *lar); -extern void init_ao_sphere(Render *re, struct World *wrld); -extern void init_render_qmcsampler(Render *re); -extern void free_render_qmcsampler(Render *re); - -#endif /* __RENDERCORE_H__ */ diff --git a/source/blender/render/intern/include/renderdatabase.h b/source/blender/render/intern/include/renderdatabase.h deleted file mode 100644 index 6b2deea57d8..00000000000 --- a/source/blender/render/intern/include/renderdatabase.h +++ /dev/null @@ -1,175 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2006 Blender Foundation. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/render/intern/include/renderdatabase.h - * \ingroup render - */ - - -#ifndef __RENDERDATABASE_H__ -#define __RENDERDATABASE_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -struct Object; -struct VlakRen; -struct VertRen; -struct Depsgraph; -struct HaloRen; -struct Main; -struct Material; -struct Render; -struct MCol; -struct MTFace; -struct CustomData; -struct StrandBuffer; -struct StrandRen; -struct ObjectInstanceRen; -struct RadFace; -struct Isect; - -#define RE_QUAD_MASK 0x7FFFFFF -#define RE_QUAD_OFFS 0x8000000 - -/* render allocates totvert/256 of these nodes, for lookup and quick alloc */ -typedef struct VertTableNode { - struct VertRen *vert; - float *rad; - float *strand; - float *tangent; - float *stress; - float *winspeed; - /* Index of vertex in source mesh (before modifiers). */ - int *origindex; -} VertTableNode; - -typedef struct VlakTableNode { - struct VlakRen *vlak; - struct MTFace *mtface; - struct MCol *mcol; - /* Index of mpoly in source mesh (before tessellation). */ - int *origindex; - int totmtface, totmcol; - float *surfnor; - float *tangent_arrays[MAX_MTFACE]; - struct RadFace **radface; -} VlakTableNode; - -typedef struct StrandTableNode { - struct StrandRen *strand; - float *winspeed; - float *surfnor; - float *simplify; - int *face; - struct MCol *mcol; - float *uv; - int totuv, totmcol; -} StrandTableNode; - -/* renderdatabase.c */ -void free_renderdata_tables(struct Render *re); -void free_renderdata_vertnodes(struct VertTableNode *vertnodes); -void free_renderdata_vlaknodes(struct VlakTableNode *vlaknodes); - -void project_renderdata(struct Render *re, void (*projectfunc)(const float *, float mat[4][4], float *), bool do_pano, float xoffs, bool do_buckets); -int clip_render_object(float boundbox[2][3], float bounds[4], float mat[4][4]); - -/* functions are not exported... so wrong names */ - -struct VlakRen *RE_findOrAddVlak(struct ObjectRen *obr, int nr); -struct VertRen *RE_findOrAddVert(struct ObjectRen *obr, int nr); -struct StrandRen *RE_findOrAddStrand(struct ObjectRen *obr, int nr); -struct HaloRen *RE_findOrAddHalo(struct ObjectRen *obr, int nr); -struct HaloRen *RE_inithalo(struct Render *re, struct ObjectRen *obr, struct Material *ma, - const float vec[3], const float vec1[3], - const float *orco, float hasize, float vectsize, int seed); -struct HaloRen *RE_inithalo_particle(struct Render *re, struct ObjectRen *obr, struct DerivedMesh *dm, struct Material *ma, - const float vec[3], const float vec1[3], - const float *orco, const float *uvco, float hasize, float vectsize, int seed, - const float pa_co[3]); -struct StrandBuffer *RE_addStrandBuffer(struct ObjectRen *obr, int totvert); - -struct ObjectRen *RE_addRenderObject(struct Render *re, struct Object *ob, struct Object *par, int index, int psysindex, int lay); -struct ObjectInstanceRen *RE_addRenderInstance( - struct Render *re, struct ObjectRen *obr, struct Object *ob, struct Object *par, - int index, int psysindex, float mat[4][4], int lay, const struct DupliObject *dob); -void RE_makeRenderInstances(struct Render *re); -void RE_updateRenderInstance(Render *re, ObjectInstanceRen *obi, int flag); - -void RE_instance_rotate_ray_start(struct ObjectInstanceRen *obi, struct Isect *is); -void RE_instance_rotate_ray_dir(struct ObjectInstanceRen *obi, struct Isect *is); -void RE_instance_rotate_ray(struct ObjectInstanceRen *obi, struct Isect *is); -void RE_instance_rotate_ray_restore(struct ObjectInstanceRen *obi, struct Isect *is); - -float *RE_vertren_get_stress(struct ObjectRen *obr, struct VertRen *ver, int verify); -float *RE_vertren_get_rad(struct ObjectRen *obr, struct VertRen *ver, int verify); -float *RE_vertren_get_strand(struct ObjectRen *obr, struct VertRen *ver, int verify); -float *RE_vertren_get_tangent(struct ObjectRen *obr, struct VertRen *ver, int verify); -float *RE_vertren_get_winspeed(struct ObjectInstanceRen *obi, struct VertRen *ver, int verify); -int *RE_vertren_get_origindex(struct ObjectRen *obr, VertRen *ver, int verify); - -struct MTFace *RE_vlakren_get_tface(struct ObjectRen *obr, VlakRen *ren, int n, char **name, int verify); -struct MCol *RE_vlakren_get_mcol(struct ObjectRen *obr, VlakRen *ren, int n, char **name, int verify); -int *RE_vlakren_get_origindex(struct ObjectRen *obr, VlakRen *vlak, int verify); -float *RE_vlakren_get_surfnor(struct ObjectRen *obr, VlakRen *ren, int verify); -float *RE_vlakren_get_nmap_tangent(ObjectRen *obr, VlakRen *vlak, int index, bool verify); -RadFace **RE_vlakren_get_radface(struct ObjectRen *obr, VlakRen *ren, int verify); -void RE_vlakren_get_normal(struct Render *re, struct ObjectInstanceRen *obi, struct VlakRen *vlr, float *nor); - -float *RE_strandren_get_surfnor(struct ObjectRen *obr, struct StrandRen *strand, int verify); -float *RE_strandren_get_uv(struct ObjectRen *obr, struct StrandRen *strand, int n, char **name, int verify); -struct MCol *RE_strandren_get_mcol(struct ObjectRen *obr, struct StrandRen *strand, int n, char **name, int verify); -float *RE_strandren_get_simplify(struct ObjectRen *obr, struct StrandRen *strand, int verify); -int *RE_strandren_get_face(struct ObjectRen *obr, struct StrandRen *strand, int verify); -float *RE_strandren_get_winspeed(struct ObjectInstanceRen *obi, struct StrandRen *strand, int verify); - -struct VertRen *RE_vertren_copy(struct ObjectRen *obr, struct VertRen *ver); -struct VlakRen *RE_vlakren_copy(struct ObjectRen *obr, struct VlakRen *vlr); - -void RE_set_customdata_names(struct ObjectRen *obr, struct CustomData *data); - -void area_lamp_vectors(struct LampRen *lar); - - -/* haloren->type: flags */ -#define HA_ONLYSKY 1 -#define HA_VECT 2 -#define HA_XALPHA 4 -#define HA_FLARECIRC 8 - -/* convertblender.c */ -void init_render_world(Render *re); -void RE_Database_FromScene_Vectors(struct Depsgraph *depsgraph, Render *re, struct Main *bmain, struct Scene *sce, unsigned int lay); - -#ifdef __cplusplus -} -#endif - -#endif /* __RENDERDATABASE_H__ */ - diff --git a/source/blender/render/intern/include/renderpipeline.h b/source/blender/render/intern/include/renderpipeline.h index 8c23eb0d4cb..68fbc01b914 100644 --- a/source/blender/render/intern/include/renderpipeline.h +++ b/source/blender/render/intern/include/renderpipeline.h @@ -38,13 +38,10 @@ struct Render; struct RenderData; struct RenderLayer; struct RenderResult; -struct ViewRender; struct RenderLayer *render_get_active_layer(struct Render *re, struct RenderResult *rr); -float panorama_pixel_rot(struct Render *re); void render_update_anim_renderdata(struct Render *re, struct RenderData *rd, struct ListBase *render_layers); void render_copy_renderdata(struct RenderData *to, struct RenderData *from); -void render_copy_viewrender(struct ViewRender *to, struct ViewRender *from); #endif /* __RENDERPIPELINE_H__ */ diff --git a/source/blender/render/intern/include/shadbuf.h b/source/blender/render/intern/include/shadbuf.h deleted file mode 100644 index ddf5de8d974..00000000000 --- a/source/blender/render/intern/include/shadbuf.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#ifndef __SHADBUF_H__ -#define __SHADBUF_H__ - -/** \file blender/render/intern/include/shadbuf.h - * \ingroup render - */ - -#include "render_types.h" - - -/** - * Calculates shadowbuffers for a vector of shadow-giving lamps - * \param lar The vector of lamps - */ -void makeshadowbuf(struct Render *re, LampRen *lar); -void freeshadowbuf(struct LampRen *lar); - -void threaded_makeshadowbufs(struct Render *re); - -/** - * Determines the shadow factor for a face and lamp. There is some - * communication with global variables here. - * \return The shadow factors: 1.0 for no shadow, 0.0 for complete - * shadow. - * \param shb The shadowbuffer to find the shadow factor in. - * \param inp The inproduct between viewvector and ? - * - */ -float testshadowbuf(struct Render *re, struct ShadBuf *shb, const float rco[3], const float dxco[3], const float dyco[3], float inp, float mat_bias); - -/** - * Determines the shadow factor for lamp \a lar, between \a p1 and \a p2. (Which CS?) - */ -float shadow_halo(LampRen *lar, const float p1[3], const float p2[3]); - -/** - * Irregular shadowbuffer - */ - -struct MemArena; -struct APixstr; - -void ISB_create(RenderPart *pa, struct APixstr *apixbuf); -void ISB_free(RenderPart *pa); -float ISB_getshadow(ShadeInput *shi, ShadBuf *shb); - -/* data structures have to be accessible both in camview(x, y) as in lampview(x, y) */ -/* since they're created per tile rendered, speed goes over memory requirements */ - - -/* buffer samples, allocated in camera buffer and pointed to in lampbuffer nodes */ -typedef struct ISBSample { - float zco[3]; /* coordinate in lampview projection */ - short *shadfac; /* initialized zero = full lighted */ - int obi; /* object for face lookup */ - int facenr; /* index in faces list */ -} ISBSample; - -/* transparent version of buffer sample */ -typedef struct ISBSampleA { - float zco[3]; /* coordinate in lampview projection */ - short *shadfac; /* NULL = full lighted */ - int obi; /* object for face lookup */ - int facenr; /* index in faces list */ - struct ISBSampleA *next; /* in end, we want the first items to align with ISBSample */ -} ISBSampleA; - -/* used for transparent storage only */ -typedef struct ISBShadfacA { - struct ISBShadfacA *next; - int obi; - int facenr; - float shadfac; -} ISBShadfacA; - -/* What needs to be stored to evaluate shadow, for each thread in ShadBuf */ -typedef struct ISBData { - short *shadfacs; /* simple storage for solid only */ - ISBShadfacA **shadfaca; - struct MemArena *memarena; - int minx, miny, rectx, recty; /* copy from part disprect */ -} ISBData; - -#endif /* __SHADBUF_H__ */ - diff --git a/source/blender/render/intern/include/shading.h b/source/blender/render/intern/include/shading.h deleted file mode 100644 index 3ef6e9d7476..00000000000 --- a/source/blender/render/intern/include/shading.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2006 Blender Foundation - * All rights reserved. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/render/intern/include/shading.h - * \ingroup render - */ - - -struct ShadeInput; -struct ShadeResult; -struct RenderPart; -struct RenderLayer; -struct PixStr; -struct LampRen; -struct VlakRen; -struct StrandPoint; -struct ObjectInstanceRen; -struct Isect; - -/* shadeinput.c */ - -#define RE_MAX_OSA 16 - -/* needed to calculate shadow and AO for an entire pixel */ -typedef struct ShadeSample { - int tot; /* amount of shi in use, can be 1 for not FULL_OSA */ - - RenderLayer *rlpp[RE_MAX_OSA]; /* fast lookup from sample to renderlayer (fullsample buf) */ - - /* could be malloced once */ - ShadeInput shi[RE_MAX_OSA]; - ShadeResult shr[RE_MAX_OSA]; -} ShadeSample; - - - /* also the node shader callback */ -void shade_material_loop(struct ShadeInput *shi, struct ShadeResult *shr); - -void shade_input_set_triangle_i(struct ShadeInput *shi, struct ObjectInstanceRen *obi, struct VlakRen *vlr, short i1, short i2, short i3); -void shade_input_set_triangle(struct ShadeInput *shi, int obi, int facenr, int normal_flip); -void shade_input_copy_triangle(struct ShadeInput *shi, struct ShadeInput *from); -void shade_input_calc_viewco(struct ShadeInput *shi, float x, float y, float z, float view[3], float dxyview[2], float co[3], float dxco[3], float dyco[3]); -void shade_input_set_viewco(struct ShadeInput *shi, float x, float y, float sx, float sy, float z); -void shade_input_set_uv(struct ShadeInput *shi); -void shade_input_set_normals(struct ShadeInput *shi); -void shade_input_set_vertex_normals(struct ShadeInput *shi); -void shade_input_flip_normals(struct ShadeInput *shi); -void shade_input_set_shade_texco(struct ShadeInput *shi); -void shade_input_set_strand(struct ShadeInput *shi, struct StrandRen *strand, struct StrandPoint *spoint); -void shade_input_set_strand_texco(struct ShadeInput *shi, struct StrandRen *strand, struct StrandVert *svert, struct StrandPoint *spoint); -void shade_input_do_shade(struct ShadeInput *shi, struct ShadeResult *shr); - -void shade_input_init_material(struct ShadeInput *shi); -void shade_input_initialize(struct ShadeInput *shi, struct RenderPart *pa, struct RenderLayer *rl, int sample); - -void shade_sample_initialize(struct ShadeSample *ssamp, struct RenderPart *pa, struct RenderLayer *rl); -void shade_samples_do_AO(struct ShadeSample *ssamp); -void shade_samples_fill_with_ps(struct ShadeSample *ssamp, struct PixStr *ps, int x, int y); -int shade_samples(struct ShadeSample *ssamp, struct PixStr *ps, int x, int y); - -void vlr_set_uv_indices(struct VlakRen *vlr, int *i1, int *i2, int *i3); - -void calc_R_ref(struct ShadeInput *shi); - -void barycentric_differentials_from_position( - const float co[3], const float v1[3], const float v2[3], const float v3[3], - const float dxco[3], const float dyco[3], const float facenor[3], const bool differentials, - float *u, float *v, float *dx_u, float *dx_v, float *dy_u, float *dy_v); - -/* shadeoutput. */ -void shade_lamp_loop(struct ShadeInput *shi, struct ShadeResult *shr); - -void shade_color(struct ShadeInput *shi, ShadeResult *shr); - -void ambient_occlusion(struct ShadeInput *shi); -void environment_lighting_apply(struct ShadeInput *shi, struct ShadeResult *shr); - -ListBase *get_lights(struct ShadeInput *shi); -float lamp_get_visibility(struct LampRen *lar, const float co[3], float lv[3], float *dist); -void lamp_get_shadow(struct LampRen *lar, ShadeInput *shi, float inp, float shadfac[4], int do_real); - -float fresnel_fac(const float view[3], const float vn[3], float fresnel, float fac); - -/* rayshade.c */ -extern void shade_ray(struct Isect *is, struct ShadeInput *shi, struct ShadeResult *shr); diff --git a/source/blender/render/intern/include/sss.h b/source/blender/render/intern/include/sss.h deleted file mode 100644 index 0952c6bff65..00000000000 --- a/source/blender/render/intern/include/sss.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2007 Blender Foundation. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/render/intern/include/sss.h - * \ingroup render - */ - - -#ifndef __SSS_H__ -#define __SSS_H__ - -/* Generic multiple scattering API */ - -struct ScatterSettings; -typedef struct ScatterSettings ScatterSettings; - -struct ScatterTree; -typedef struct ScatterTree ScatterTree; - -ScatterSettings *scatter_settings_new(float refl, float radius, float ior, - float reflfac, float frontweight, float backweight); -void scatter_settings_free(ScatterSettings *ss); - -ScatterTree *scatter_tree_new(ScatterSettings *ss[3], float scale, float error, - float (*co)[3], float (*color)[3], float *area, int totpoint); -void scatter_tree_build(ScatterTree *tree); -void scatter_tree_sample(ScatterTree *tree, const float co[3], float color[3]); -void scatter_tree_free(ScatterTree *tree); - -/* Internal renderer API */ - -struct Render; -struct Material; - -void make_sss_tree(struct Render *re); -void sss_add_points(Render *re, float (*co)[3], float (*color)[3], float *area, int totpoint); -void free_sss(struct Render *re); - -int sample_sss(struct Render *re, struct Material *mat, const float co[3], float color[3]); -int sss_pass_done(struct Render *re, struct Material *mat); - -#endif /*__SSS_H__*/ - diff --git a/source/blender/render/intern/include/strand.h b/source/blender/render/intern/include/strand.h deleted file mode 100644 index 5687ef3c837..00000000000 --- a/source/blender/render/intern/include/strand.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Contributor(s): Brecht Van Lommel. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/render/intern/include/strand.h - * \ingroup render - */ - - -#ifndef __STRAND_H__ -#define __STRAND_H__ - -struct StrandVert; -struct StrandRen; -struct StrandBuffer; -struct ShadeSample; -struct StrandPart; -struct Render; -struct ZSpan; -struct ObjectInstanceRen; -struct StrandSurface; -struct DerivedMesh; -struct ObjectRen; - -typedef struct StrandPoint { - /* position within segment */ - float t; - - /* camera space */ - float co[3]; - float nor[3]; - float tan[3]; - float strandco; - float width; - - /* derivatives */ - float dtco[3], dsco[3]; - float dtstrandco; - - /* outer points */ - float co1[3], co2[3]; - float hoco1[4], hoco2[4]; - float zco1[3], zco2[3]; - int clip1, clip2; - - /* screen space */ - float hoco[4]; - float x, y; - - /* simplification */ - float alpha; -} StrandPoint; - -typedef struct StrandSegment { - struct StrandVert *v[4]; - struct StrandRen *strand; - struct StrandBuffer *buffer; - struct ObjectInstanceRen *obi; - float sqadaptcos; - - StrandPoint point1, point2; - int shaded; -} StrandSegment; - -struct StrandShadeCache; -typedef struct StrandShadeCache StrandShadeCache; - -void strand_eval_point(StrandSegment *sseg, StrandPoint *spoint); -void render_strand_segment(struct Render *re, float winmat[4][4], struct StrandPart *spart, struct ZSpan *zspan, int totzspan, StrandSegment *sseg); -void strand_minmax(struct StrandRen *strand, float min[3], float max[3], const float width); - -struct StrandSurface *cache_strand_surface(struct Render *re, struct ObjectRen *obr, struct DerivedMesh *dm, float mat[4][4], int timeoffset); -void free_strand_surface(struct Render *re); - -struct StrandShadeCache *strand_shade_cache_create(void); -void strand_shade_cache_free(struct StrandShadeCache *cache); -void strand_shade_segment(struct Render *re, struct StrandShadeCache *cache, struct StrandSegment *sseg, struct ShadeSample *ssamp, float t, float s, int addpassflag); -void strand_shade_unref(struct StrandShadeCache *cache, struct ObjectInstanceRen *obi, struct StrandVert *svert); - -#endif - diff --git a/source/blender/render/intern/include/sunsky.h b/source/blender/render/intern/include/sunsky.h deleted file mode 100644 index 60fa8aa51ba..00000000000 --- a/source/blender/render/intern/include/sunsky.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Contributor(s): zaghaghi - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/render/intern/include/sunsky.h - * \ingroup render - */ - -#ifndef __SUNSKY_H__ -#define __SUNSKY_H__ - -// #define SPECTRUM_MAX_COMPONENTS 100 - -typedef struct SunSky { - short effect_type, skyblendtype, sky_colorspace; - float turbidity; - float theta, phi; - - float toSun[3]; - - /*float sunSpectralRaddata[SPECTRUM_MAX_COMPONENTS];*/ - float sunSolidAngle; - - float zenith_Y, zenith_x, zenith_y; - - float perez_Y[5], perez_x[5], perez_y[5]; - - /* suggested by glome in patch [#8063] */ - float horizon_brightness; - float spread; - float sun_brightness; - float sun_size; - float backscattered_light; - float skyblendfac; - float sky_exposure; - - float atm_HGg; - - float atm_SunIntensity; - float atm_InscatteringMultiplier; - float atm_ExtinctionMultiplier; - float atm_BetaRayMultiplier; - float atm_BetaMieMultiplier; - float atm_DistanceMultiplier; - - float atm_BetaRay[3]; - float atm_BetaDashRay[3]; - float atm_BetaMie[3]; - float atm_BetaDashMie[3]; - float atm_BetaRM[3]; -} SunSky; - -void InitSunSky(struct SunSky *sunsky, float turb, const float toSun[3], float horizon_brightness, - float spread, float sun_brightness, float sun_size, float back_scatter, - float skyblendfac, short skyblendtype, float sky_exposure, float sky_colorspace); - -void GetSkyXYZRadiance(struct SunSky *sunsky, float theta, float phi, float color_out[3]); -void GetSkyXYZRadiancef(struct SunSky *sunsky, const float varg[3], float color_out[3]); -void InitAtmosphere(struct SunSky *sunSky, float sun_intens, float mief, float rayf, float inscattf, float extincf, float disf); -void AtmospherePixleShader(struct SunSky *sunSky, float view[3], float s, float rgb[3]); -void ClipColor(float c[3]); - -#endif /*__SUNSKY_H__*/ diff --git a/source/blender/render/intern/include/texture.h b/source/blender/render/intern/include/texture.h index dfb491f46b0..71000e38960 100644 --- a/source/blender/render/intern/include/texture.h +++ b/source/blender/render/intern/include/texture.h @@ -63,29 +63,12 @@ } \ } \ -struct HaloRen; -struct ShadeInput; struct TexResult; struct Tex; struct Image; struct ImBuf; struct ImagePool; -/* texture.h */ - -void do_halo_tex(struct HaloRen *har, float xn, float yn, float col_r[4]); -void do_sky_tex( - const float rco[3], const float view[3], const float lo[3], const float dxyview[2], - float hor[3], float zen[3], float *blend, int skyflag, short thread); -void do_material_tex(struct ShadeInput *shi, struct Render *re); -void do_lamp_tex(LampRen *la, const float lavec[3], struct ShadeInput *shi, float col_r[3], int effect); -void do_volume_tex(struct ShadeInput *shi, const float xyz[3], int mapto_flag, float col_r[3], float *val, struct Render *re); - -void init_render_textures(Render *re); -void end_render_textures(Render *re); - -void render_realtime_texture(struct ShadeInput *shi, struct Image *ima); - /* imagetexture.h */ int imagewraposa(struct Tex *tex, struct Image *ima, struct ImBuf *ibuf, const float texvec[3], const float dxt[2], const float dyt[2], struct TexResult *texres, struct ImagePool *pool, const bool skip_load_image); diff --git a/source/blender/render/intern/include/texture_ocean.h b/source/blender/render/intern/include/texture_ocean.h deleted file mode 100644 index 4a71aff930a..00000000000 --- a/source/blender/render/intern/include/texture_ocean.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * Contributors: Matt Ebb - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#ifndef __TEXTURE_OCEAN_H__ -#define __TEXTURE_OCEAN_H__ - -/** \file blender/render/intern/include/texture_ocean.h - * \ingroup render - */ - -int ocean_texture(struct Tex *tex, const float texvec[2], struct TexResult *texres); - -#endif /* __TEXTURE_OCEAN_H__ */ diff --git a/source/blender/render/intern/include/volume_precache.h b/source/blender/render/intern/include/volume_precache.h deleted file mode 100644 index 9aa280d8276..00000000000 --- a/source/blender/render/intern/include/volume_precache.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): Matt Ebb. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/render/intern/include/volume_precache.h - * \ingroup render - */ - - -void global_bounds_obi(Render *re, ObjectInstanceRen *obi, float bbmin[3], float bbmax[3]); -int point_inside_volume_objectinstance(Render *re, ObjectInstanceRen *obi, const float co[3]); - -void volume_precache(Render *re); -void free_volume_precache(Render *re); - -#define VOL_MS_TIMESTEP 0.1f diff --git a/source/blender/render/intern/include/volumetric.h b/source/blender/render/intern/include/volumetric.h deleted file mode 100644 index 3805478fed0..00000000000 --- a/source/blender/render/intern/include/volumetric.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): Matt Ebb. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/render/intern/include/volumetric.h - * \ingroup render - */ - - -struct Isect; -struct ShadeInput; -struct ShadeResult; - -float vol_get_density(struct ShadeInput *shi, const float co[3]); -void vol_get_scattering(ShadeInput *shi, float scatter_col[3], const float co[3], const float view[3]); - -void shade_volume_outside(ShadeInput *shi, ShadeResult *shr); -void shade_volume_inside(ShadeInput *shi, ShadeResult *shr); -void shade_volume_shadow(struct ShadeInput *shi, struct ShadeResult *shr, struct Isect *last_is); - -#define VOL_IS_BACKFACE 1 -#define VOL_IS_SAMEMATERIAL 2 - -#define VOL_BOUNDS_DEPTH 0 -#define VOL_BOUNDS_SS 1 - -#define VOL_SHADE_OUTSIDE 0 -#define VOL_SHADE_INSIDE 1 diff --git a/source/blender/render/intern/include/voxeldata.h b/source/blender/render/intern/include/voxeldata.h deleted file mode 100644 index dd2262e0357..00000000000 --- a/source/blender/render/intern/include/voxeldata.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): Raul Fernandez Hernandez (Farsthary), Matt Ebb. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/render/intern/include/voxeldata.h - * \ingroup render - */ - -#ifndef __VOXELDATA_H__ -#define __VOXELDATA_H__ - -struct Render; -struct TexResult; - -typedef struct VoxelDataHeader { - int resolX, resolY, resolZ; - int frames; -} VoxelDataHeader; - -void cache_voxeldata(Tex *tex, int scene_frame); -void make_voxeldata(struct Render *re); -int voxeldatatex(struct Tex *tex, const float texvec[3], struct TexResult *texres); - -#endif /* __VOXELDATA_H__ */ diff --git a/source/blender/render/intern/include/zbuf.h b/source/blender/render/intern/include/zbuf.h index 6fc1a4c2656..1a93fc6c3b2 100644 --- a/source/blender/render/intern/include/zbuf.h +++ b/source/blender/render/intern/include/zbuf.h @@ -33,57 +33,6 @@ #ifndef __ZBUF_H__ #define __ZBUF_H__ -struct RenderPart; -struct RenderLayer; -struct LampRen; -struct ListBase; -struct ZSpan; -struct APixstrand; -struct APixstr; -struct StrandShadeCache; - -void fillrect(int *rect, int x, int y, int val); - -/** - * Converts a world coordinate into a homogeneous coordinate in view - * coordinates. - */ -void projectvert(const float v1[3], float winmat[4][4], float adr[4]); -void projectverto(const float v1[3], float winmat[4][4], float adr[4]); -int testclip(const float v[3]); - -void zbuffer_shadow(struct Render *re, float winmat[4][4], struct LampRen *lar, int *rectz, int size, float jitx, float jity); -void zbuffer_abuf_shadow(struct Render *re, struct LampRen *lar, float winmat[4][4], struct APixstr *APixbuf, struct APixstrand *apixbuf, struct ListBase *apsmbase, int size, int samples, float (*jit)[2]); -void zbuffer_solid(struct RenderPart *pa, struct RenderLayer *rl, void (*fillfunc)(struct RenderPart *, struct ZSpan *, int, void *), void *data); - -unsigned short *zbuffer_transp_shade(struct RenderPart *pa, struct RenderLayer *rl, float *pass, struct ListBase *psmlist); -void zbuffer_sss(RenderPart *pa, unsigned int lay, void *handle, void (*func)(void *, int, int, int, int, int)); -int zbuffer_strands_abuf(struct Render *re, struct RenderPart *pa, struct APixstrand *apixbuf, struct ListBase *apsmbase, unsigned int lay, int negzmask, float winmat[4][4], int winx, int winy, int sample, float (*jit)[2], float clipcrop, int shadow, struct StrandShadeCache *cache); - -typedef struct APixstr { - unsigned short mask[4]; /* jitter mask */ - int z[4]; /* distance */ - int p[4]; /* index */ - int obi[4]; /* object instance */ - short shadfac[4]; /* optimize storage for irregular shadow */ - struct APixstr *next; -} APixstr; - -typedef struct APixstrand { - unsigned short mask[4]; /* jitter mask */ - int z[4]; /* distance */ - int p[4]; /* index */ - int obi[4]; /* object instance */ - int seg[4]; /* for strands, segment number */ - float u[4], v[4]; /* for strands, u,v coordinate in segment */ - struct APixstrand *next; -} APixstrand; - -typedef struct APixstrMain { - struct APixstrMain *next, *prev; - void *ps; -} APixstrMain; - /* span fill in method, is also used to localize data for zbuffering */ typedef struct ZSpan { int rectx, recty; /* range for clipping */ @@ -91,61 +40,13 @@ typedef struct ZSpan { int miny1, maxy1, miny2, maxy2; /* actual filled in range */ const float *minp1, *maxp1, *minp2, *maxp2; /* vertex pointers detect min/max range in */ float *span1, *span2; - - float zmulx, zmuly, zofsx, zofsy; /* transform from hoco to zbuf co */ - - int *rectz, *arectz; /* zbuffers, arectz is for transparent */ - int *rectz1; /* secondary z buffer for shadowbuffer (2nd closest z) */ - int *rectp; /* polygon index buffer */ - int *recto; /* object buffer */ - int *rectmask; /* negative zmask buffer */ - APixstr *apixbuf, *curpstr; /* apixbuf for transparent */ - APixstrand *curpstrand; /* same for strands */ - struct ListBase *apsmbase; - - int polygon_offset; /* offset in Z */ - float shad_alpha; /* copy from material, used by irregular shadbuf */ - int mask, apsmcounter; /* in use by apixbuf */ - int apstrandmcounter; - - float clipcrop; /* for shadow, was in R global before */ - - void *sss_handle; /* used by sss */ - void (*sss_func)(void *, int, int, int, int, int); - - void (*zbuffunc)(struct ZSpan *, int, int, const float *, const float *, const float *, const float *); - void (*zbuflinefunc)(struct ZSpan *, int, int, const float *, const float *); - } ZSpan; -/* exported to shadbuf.c */ -void zbufclip4(struct ZSpan *zspan, int obi, int zvlnr, - const float f1[4], const float f2[4], const float f3[4], const float f4[4], - const int c1, const int c2, const int c3, const int c4); +void zbuf_alloc_span(struct ZSpan *zspan, int rectx, int recty); void zbuf_free_span(struct ZSpan *zspan); -void freepsA(struct ListBase *lb); -/* to rendercore.c */ void zspan_scanconvert(struct ZSpan *zpan, void *handle, float *v1, float *v2, float *v3, void (*func)(void *, int, int, float, float) ); -/* exported to edge render... */ -void zbufclip(struct ZSpan *zspan, int obi, int zvlnr, - const float f1[4], const float f2[4], const float f3[4], - const int c1, const int c2, const int c3); -void zbuf_alloc_span(struct ZSpan *zspan, int rectx, int recty, float clipcrop); -void zbufclipwire(struct ZSpan *zspan, int obi, int zvlnr, int ec, - const float ho1[4], const float ho2[4], const float ho3[4], const float ho4[4], - const int c1, const int c2, const int c3, const int c4); - -/* exported to shadeinput.c */ -void zbuf_make_winmat(Render *re, float winmat[4][4]); -void zbuf_render_project(float winmat[4][4], const float co[3], float ho[4]); - -/* should not really be exposed, bad! */ -void hoco_to_zco(ZSpan *zspan, float zco[3], const float hoco[4]); -void zspan_scanconvert_strand(ZSpan *zspan, void *handle, float *v1, float *v2, float *v3, void (*func)(void *, int, int, float, float, float) ); -void zbufsinglewire(ZSpan *zspan, int obi, int zvlnr, const float ho1[4], const float ho2[4]); - #endif diff --git a/source/blender/render/intern/raytrace/bvh.h b/source/blender/render/intern/raytrace/bvh.h deleted file mode 100644 index 25fdb41bb3a..00000000000 --- a/source/blender/render/intern/raytrace/bvh.h +++ /dev/null @@ -1,407 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2009 Blender Foundation. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): André Pinto. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/render/intern/raytrace/bvh.h - * \ingroup render - */ - - -#include "MEM_guardedalloc.h" - -#include "BLI_math.h" - -#include "raycounter.h" -#include "rayintersection.h" -#include "rayobject.h" -#include "rayobject_hint.h" -#include "rayobject_rtbuild.h" - -#include <assert.h> - -#ifdef __SSE__ -#include <xmmintrin.h> -#endif - -#ifndef __BVH_H__ -#define __BVH_H__ - -#ifdef __SSE__ -inline int test_bb_group4(__m128 *bb_group, const Isect *isec) -{ - const __m128 tmin0 = _mm_setzero_ps(); - const __m128 tmax0 = _mm_set_ps1(isec->dist); - - float start[3], idot_axis[3]; - copy_v3_v3(start, isec->start); - copy_v3_v3(idot_axis, isec->idot_axis); - - const __m128 tmin1 = _mm_max_ps(tmin0, _mm_mul_ps(_mm_sub_ps(bb_group[isec->bv_index[0]], _mm_set_ps1(start[0]) ), _mm_set_ps1(idot_axis[0])) ); - const __m128 tmax1 = _mm_min_ps(tmax0, _mm_mul_ps(_mm_sub_ps(bb_group[isec->bv_index[1]], _mm_set_ps1(start[0]) ), _mm_set_ps1(idot_axis[0])) ); - const __m128 tmin2 = _mm_max_ps(tmin1, _mm_mul_ps(_mm_sub_ps(bb_group[isec->bv_index[2]], _mm_set_ps1(start[1]) ), _mm_set_ps1(idot_axis[1])) ); - const __m128 tmax2 = _mm_min_ps(tmax1, _mm_mul_ps(_mm_sub_ps(bb_group[isec->bv_index[3]], _mm_set_ps1(start[1]) ), _mm_set_ps1(idot_axis[1])) ); - const __m128 tmin3 = _mm_max_ps(tmin2, _mm_mul_ps(_mm_sub_ps(bb_group[isec->bv_index[4]], _mm_set_ps1(start[2]) ), _mm_set_ps1(idot_axis[2])) ); - const __m128 tmax3 = _mm_min_ps(tmax2, _mm_mul_ps(_mm_sub_ps(bb_group[isec->bv_index[5]], _mm_set_ps1(start[2]) ), _mm_set_ps1(idot_axis[2])) ); - - return _mm_movemask_ps(_mm_cmpge_ps(tmax3, tmin3)); -} -#endif - -/* - * Determines the distance that the ray must travel to hit the bounding volume of the given node - * Based on Tactical Optimization of Ray/Box Intersection, by Graham Fyffe - * [http://tog.acm.org/resources/RTNews/html/rtnv21n1.html#art9] - */ -static inline int rayobject_bb_intersect_test(const Isect *isec, const float *_bb) -{ - const float *bb = _bb; - - float t1x = (bb[isec->bv_index[0]] - isec->start[0]) * isec->idot_axis[0]; - float t2x = (bb[isec->bv_index[1]] - isec->start[0]) * isec->idot_axis[0]; - float t1y = (bb[isec->bv_index[2]] - isec->start[1]) * isec->idot_axis[1]; - float t2y = (bb[isec->bv_index[3]] - isec->start[1]) * isec->idot_axis[1]; - float t1z = (bb[isec->bv_index[4]] - isec->start[2]) * isec->idot_axis[2]; - float t2z = (bb[isec->bv_index[5]] - isec->start[2]) * isec->idot_axis[2]; - - RE_RC_COUNT(isec->raycounter->bb.test); - - if (t1x > t2y || t2x < t1y || t1x > t2z || t2x < t1z || t1y > t2z || t2y < t1z) return 0; - if (t2x < 0.0f || t2y < 0.0f || t2z < 0.0f) return 0; - if (t1x > isec->dist || t1y > isec->dist || t1z > isec->dist) return 0; - RE_RC_COUNT(isec->raycounter->bb.hit); - - return 1; -} - -/* bvh tree generics */ -template<class Tree> static void bvh_add(Tree *obj, RayObject *ob) -{ - rtbuild_add(obj->builder, ob); -} - -template<class Node> -inline bool is_leaf(Node *node) -{ - return !RE_rayobject_isAligned(node); -} - -template<class Tree> static void bvh_done(Tree *obj); - -template<class Tree> -static void bvh_free(Tree *obj) -{ - if (obj->builder) - rtbuild_free(obj->builder); - - if (obj->node_arena) - BLI_memarena_free(obj->node_arena); - - MEM_freeN(obj); -} - -template<class Tree> -static void bvh_bb(Tree *obj, float *min, float *max) -{ - if (obj->root) - bvh_node_merge_bb(obj->root, min, max); -} - - -template<class Tree> -static float bvh_cost(Tree *obj) -{ - assert(obj->cost >= 0.0f); - return obj->cost; -} - - - -/* bvh tree nodes generics */ -template<class Node> static inline int bvh_node_hit_test(Node *node, Isect *isec) -{ - return rayobject_bb_intersect_test(isec, (const float *)node->bb); -} - - -template<class Node> -static inline void bvh_node_merge_bb(Node *node, float min[3], float max[3]) -{ - if (is_leaf(node)) { - RE_rayobject_merge_bb((RayObject *)node, min, max); - } - else { - DO_MIN(node->bb, min); - DO_MAX(node->bb + 3, max); - } -} - - - -/* - * recursively transverse a BVH looking for a rayhit using a local stack - */ -template<class Node> static inline void bvh_node_push_childs(Node *node, Isect *isec, Node **stack, int &stack_pos); - -template<class Node, int MAX_STACK_SIZE, bool TEST_ROOT, bool SHADOW> -static int bvh_node_stack_raycast(Node *root, Isect *isec) -{ - Node *stack[MAX_STACK_SIZE]; - int hit = 0, stack_pos = 0; - - if (!TEST_ROOT && !is_leaf(root)) - bvh_node_push_childs(root, isec, stack, stack_pos); - else - stack[stack_pos++] = root; - - while (stack_pos) { - Node *node = stack[--stack_pos]; - if (!is_leaf(node)) { - if (bvh_node_hit_test(node, isec)) { - bvh_node_push_childs(node, isec, stack, stack_pos); - assert(stack_pos <= MAX_STACK_SIZE); - } - } - else { - hit |= RE_rayobject_intersect( (RayObject *)node, isec); - if (SHADOW && hit) return hit; - } - } - return hit; -} - - -#ifdef __SSE__ -/* - * Generic SIMD bvh recursion - * this was created to be able to use any simd (with the cost of some memmoves) - * it can take advantage of any SIMD width and doens't needs any special tree care - */ -template<class Node, int MAX_STACK_SIZE, bool TEST_ROOT> -static int bvh_node_stack_raycast_simd(Node *root, Isect *isec) -{ - Node *stack[MAX_STACK_SIZE]; - - int hit = 0, stack_pos = 0; - - if (!TEST_ROOT) { - if (!is_leaf(root)) { - if (!is_leaf(root->child)) - bvh_node_push_childs(root, isec, stack, stack_pos); - else - return RE_rayobject_intersect( (RayObject *)root->child, isec); - } - else - return RE_rayobject_intersect( (RayObject *)root, isec); - } - else { - if (!is_leaf(root)) - stack[stack_pos++] = root; - else - return RE_rayobject_intersect( (RayObject *)root, isec); - } - - while (true) { - //Use SIMD 4 - if (stack_pos >= 4) { - __m128 t_bb[6]; - Node *t_node[4]; - - stack_pos -= 4; - - /* prepare the 4BB for SIMD */ - t_node[0] = stack[stack_pos + 0]->child; - t_node[1] = stack[stack_pos + 1]->child; - t_node[2] = stack[stack_pos + 2]->child; - t_node[3] = stack[stack_pos + 3]->child; - - const float *bb0 = stack[stack_pos + 0]->bb; - const float *bb1 = stack[stack_pos + 1]->bb; - const float *bb2 = stack[stack_pos + 2]->bb; - const float *bb3 = stack[stack_pos + 3]->bb; - - const __m128 x0y0x1y1 = _mm_shuffle_ps(_mm_load_ps(bb0), _mm_load_ps(bb1), _MM_SHUFFLE(1, 0, 1, 0) ); - const __m128 x2y2x3y3 = _mm_shuffle_ps(_mm_load_ps(bb2), _mm_load_ps(bb3), _MM_SHUFFLE(1, 0, 1, 0) ); - t_bb[0] = _mm_shuffle_ps(x0y0x1y1, x2y2x3y3, _MM_SHUFFLE(2, 0, 2, 0) ); - t_bb[1] = _mm_shuffle_ps(x0y0x1y1, x2y2x3y3, _MM_SHUFFLE(3, 1, 3, 1) ); - - const __m128 z0X0z1X1 = _mm_shuffle_ps(_mm_load_ps(bb0), _mm_load_ps(bb1), _MM_SHUFFLE(3, 2, 3, 2) ); - const __m128 z2X2z3X3 = _mm_shuffle_ps(_mm_load_ps(bb2), _mm_load_ps(bb3), _MM_SHUFFLE(3, 2, 3, 2) ); - t_bb[2] = _mm_shuffle_ps(z0X0z1X1, z2X2z3X3, _MM_SHUFFLE(2, 0, 2, 0) ); - t_bb[3] = _mm_shuffle_ps(z0X0z1X1, z2X2z3X3, _MM_SHUFFLE(3, 1, 3, 1) ); - - const __m128 Y0Z0Y1Z1 = _mm_shuffle_ps(_mm_load_ps(bb0 + 4), _mm_load_ps(bb1 + 4), _MM_SHUFFLE(1, 0, 1, 0) ); - const __m128 Y2Z2Y3Z3 = _mm_shuffle_ps(_mm_load_ps(bb2 + 4), _mm_load_ps(bb3 + 4), _MM_SHUFFLE(1, 0, 1, 0) ); - t_bb[4] = _mm_shuffle_ps(Y0Z0Y1Z1, Y2Z2Y3Z3, _MM_SHUFFLE(2, 0, 2, 0) ); - t_bb[5] = _mm_shuffle_ps(Y0Z0Y1Z1, Y2Z2Y3Z3, _MM_SHUFFLE(3, 1, 3, 1) ); -#if 0 - for (int i = 0; i < 4; i++) - { - Node *t = stack[stack_pos + i]; - assert(!is_leaf(t)); - - float *bb = ((float *)t_bb) + i; - bb[4 * 0] = t->bb[0]; - bb[4 * 1] = t->bb[1]; - bb[4 * 2] = t->bb[2]; - bb[4 * 3] = t->bb[3]; - bb[4 * 4] = t->bb[4]; - bb[4 * 5] = t->bb[5]; - t_node[i] = t->child; - } -#endif - RE_RC_COUNT(isec->raycounter->simd_bb.test); - int res = test_bb_group4(t_bb, isec); - - for (int i = 0; i < 4; i++) - if (res & (1 << i)) { - RE_RC_COUNT(isec->raycounter->simd_bb.hit); - if (!is_leaf(t_node[i])) { - for (Node *t = t_node[i]; t; t = t->sibling) { - assert(stack_pos < MAX_STACK_SIZE); - stack[stack_pos++] = t; - } - } - else { - hit |= RE_rayobject_intersect( (RayObject *)t_node[i], isec); - if (hit && isec->mode == RE_RAY_SHADOW) return hit; - } - } - } - else if (stack_pos > 0) { - Node *node = stack[--stack_pos]; - assert(!is_leaf(node)); - - if (bvh_node_hit_test(node, isec)) { - if (!is_leaf(node->child)) { - bvh_node_push_childs(node, isec, stack, stack_pos); - assert(stack_pos <= MAX_STACK_SIZE); - } - else { - hit |= RE_rayobject_intersect( (RayObject *)node->child, isec); - if (hit && isec->mode == RE_RAY_SHADOW) return hit; - } - } - } - else break; - } - return hit; -} -#endif - -/* - * recursively transverse a BVH looking for a rayhit using system stack - */ -#if 0 -template<class Node> -static int bvh_node_raycast(Node *node, Isect *isec) -{ - int hit = 0; - if (bvh_test_node(node, isec)) - { - if (isec->idot_axis[node->split_axis] > 0.0f) - { - int i; - for (i = 0; i < BVH_NCHILDS; i++) - if (!is_leaf(node->child[i])) - { - if (node->child[i] == 0) break; - - hit |= bvh_node_raycast(node->child[i], isec); - if (hit && isec->mode == RE_RAY_SHADOW) return hit; - } - else { - hit |= RE_rayobject_intersect( (RayObject *)node->child[i], isec); - if (hit && isec->mode == RE_RAY_SHADOW) return hit; - } - } - else { - int i; - for (i = BVH_NCHILDS - 1; i >= 0; i--) - if (!is_leaf(node->child[i])) - { - if (node->child[i]) - { - hit |= dfs_raycast(node->child[i], isec); - if (hit && isec->mode == RE_RAY_SHADOW) return hit; - } - } - else { - hit |= RE_rayobject_intersect( (RayObject *)node->child[i], isec); - if (hit && isec->mode == RE_RAY_SHADOW) return hit; - } - } - } - return hit; -} -#endif - -template<class Node, class HintObject> -static void bvh_dfs_make_hint(Node *node, LCTSHint *hint, int reserve_space, HintObject *hintObject) -{ - assert(hint->size + reserve_space + 1 <= RE_RAY_LCTS_MAX_SIZE); - - if (is_leaf(node)) { - hint->stack[hint->size++] = (RayObject *)node; - } - else { - int childs = count_childs(node); - if (hint->size + reserve_space + childs <= RE_RAY_LCTS_MAX_SIZE) { - int result = hint_test_bb(hintObject, node->bb, node->bb + 3); - if (result == HINT_RECURSE) { - /* We are 100% sure the ray will be pass inside this node */ - bvh_dfs_make_hint_push_siblings(node->child, hint, reserve_space, hintObject); - } - else if (result == HINT_ACCEPT) { - hint->stack[hint->size++] = (RayObject *)node; - } - } - else { - hint->stack[hint->size++] = (RayObject *)node; - } - } -} - - -template<class Tree> -static RayObjectAPI *bvh_get_api(int maxstacksize); - - -template<class Tree, int DFS_STACK_SIZE> -static inline RayObject *bvh_create_tree(int size) -{ - Tree *obj = (Tree *)MEM_callocN(sizeof(Tree), "BVHTree"); - assert(RE_rayobject_isAligned(obj)); /* RayObject API assumes real data to be 4-byte aligned */ - - obj->rayobj.api = bvh_get_api<Tree>(DFS_STACK_SIZE); - obj->root = NULL; - - obj->node_arena = NULL; - obj->builder = rtbuild_create(size); - - return RE_rayobject_unalignRayAPI((RayObject *) obj); -} - -#endif diff --git a/source/blender/render/intern/raytrace/rayobject.cpp b/source/blender/render/intern/raytrace/rayobject.cpp deleted file mode 100644 index c16ef5500df..00000000000 --- a/source/blender/render/intern/raytrace/rayobject.cpp +++ /dev/null @@ -1,534 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2009 Blender Foundation. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): André Pinto. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/render/intern/raytrace/rayobject.cpp - * \ingroup render - */ - - -#include <assert.h> - -#include "MEM_guardedalloc.h" - -#include "BLI_math.h" -#include "BLI_utildefines.h" - -#include "DNA_material_types.h" - -#include "rayintersection.h" -#include "rayobject.h" -#include "raycounter.h" -#include "render_types.h" -#include "renderdatabase.h" - -/* RayFace - * - * note we force always inline here, because compiler refuses to otherwise - * because function is too long. Since this is code that is called billions - * of times we really do want to inline. */ - -MALWAYS_INLINE RayObject *rayface_from_coords(RayFace *rayface, void *ob, void *face, - float *v1, float *v2, float *v3, float *v4) -{ - rayface->ob = ob; - rayface->face = face; - - copy_v3_v3(rayface->v1, v1); - copy_v3_v3(rayface->v2, v2); - copy_v3_v3(rayface->v3, v3); - - if (v4) { - copy_v3_v3(rayface->v4, v4); - rayface->quad = 1; - } - else { - rayface->quad = 0; - } - - return RE_rayobject_unalignRayFace(rayface); -} - -MALWAYS_INLINE void rayface_from_vlak(RayFace *rayface, ObjectInstanceRen *obi, VlakRen *vlr) -{ - rayface_from_coords(rayface, obi, vlr, vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->v4 ? vlr->v4->co : NULL); - - if (obi->transform_primitives) { - mul_m4_v3(obi->mat, rayface->v1); - mul_m4_v3(obi->mat, rayface->v2); - mul_m4_v3(obi->mat, rayface->v3); - - if (RE_rayface_isQuad(rayface)) - mul_m4_v3(obi->mat, rayface->v4); - } -} - -RayObject *RE_rayface_from_vlak(RayFace *rayface, ObjectInstanceRen *obi, VlakRen *vlr) -{ - return rayface_from_coords(rayface, obi, vlr, vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->v4 ? vlr->v4->co : NULL); -} - -RayObject *RE_rayface_from_coords(RayFace *rayface, void *ob, void *face, float *v1, float *v2, float *v3, float *v4) -{ - return rayface_from_coords(rayface, ob, face, v1, v2, v3, v4); -} - -/* VlakPrimitive */ - -RayObject *RE_vlakprimitive_from_vlak(VlakPrimitive *face, struct ObjectInstanceRen *obi, struct VlakRen *vlr) -{ - face->ob = obi; - face->face = vlr; - - return RE_rayobject_unalignVlakPrimitive(face); -} - -/* Checks for ignoring faces or materials */ - -MALWAYS_INLINE int vlr_check_intersect(Isect *is, ObjectInstanceRen *obi, VlakRen *vlr) -{ - /* for baking selected to active non-traceable materials might still - * be in the raytree */ - if (!(vlr->flag & R_TRACEBLE)) - return 0; - - /* I know... cpu cycle waste, might do smarter once */ - if (is->mode == RE_RAY_MIRROR) - return !(vlr->mat->mode & MA_ONLYCAST); - else - return (vlr->mat->mode2 & MA_CASTSHADOW) && (is->lay & obi->lay); -} - -MALWAYS_INLINE int vlr_check_intersect_solid(Isect *UNUSED(is), ObjectInstanceRen *UNUSED(obi), VlakRen *vlr) -{ - /* solid material types only */ - if (vlr->mat->material_type == MA_TYPE_SURFACE) - return 1; - else - return 0; -} - -MALWAYS_INLINE int vlr_check_bake(Isect *is, ObjectInstanceRen *obi, VlakRen *UNUSED(vlr)) -{ - return (obi->obr->ob != is->userdata) && (obi->obr->ob->flag & SELECT); -} - -/* Ray Triangle/Quad Intersection */ - -static bool isect_ray_tri_watertight_no_sign_check_v3( - const float ray_origin[3], const struct IsectRayPrecalc *isect_precalc, - const float v0[3], const float v1[3], const float v2[3], - float *r_lambda, float r_uv[2]) -{ - const int kx = isect_precalc->kx; - const int ky = isect_precalc->ky; - const int kz = isect_precalc->kz; - const float sx = isect_precalc->sx; - const float sy = isect_precalc->sy; - const float sz = isect_precalc->sz; - - /* Calculate vertices relative to ray origin. */ - const float a[3] = {v0[0] - ray_origin[0], v0[1] - ray_origin[1], v0[2] - ray_origin[2]}; - const float b[3] = {v1[0] - ray_origin[0], v1[1] - ray_origin[1], v1[2] - ray_origin[2]}; - const float c[3] = {v2[0] - ray_origin[0], v2[1] - ray_origin[1], v2[2] - ray_origin[2]}; - - const float a_kx = a[kx], a_ky = a[ky], a_kz = a[kz]; - const float b_kx = b[kx], b_ky = b[ky], b_kz = b[kz]; - const float c_kx = c[kx], c_ky = c[ky], c_kz = c[kz]; - - /* Perform shear and scale of vertices. */ - const float ax = a_kx - sx * a_kz; - const float ay = a_ky - sy * a_kz; - const float bx = b_kx - sx * b_kz; - const float by = b_ky - sy * b_kz; - const float cx = c_kx - sx * c_kz; - const float cy = c_ky - sy * c_kz; - - /* Calculate scaled barycentric coordinates. */ - const float u = cx * by - cy * bx; - const float v = ax * cy - ay * cx; - const float w = bx * ay - by * ax; - float det; - - if ((u < 0.0f || v < 0.0f || w < 0.0f) && - (u > 0.0f || v > 0.0f || w > 0.0f)) - { - return false; - } - - /* Calculate determinant. */ - det = u + v + w; - if (UNLIKELY(det == 0.0f)) { - return false; - } - else { - /* Calculate scaled z-coordinates of vertices and use them to calculate - * the hit distance. - */ - const float t = (u * a_kz + v * b_kz + w * c_kz) * sz; - /* Normalize u, v and t. */ - const float inv_det = 1.0f / det; - if (r_uv) { - r_uv[0] = u * inv_det; - r_uv[1] = v * inv_det; - } - *r_lambda = t * inv_det; - return true; - } -} - -MALWAYS_INLINE int isec_tri_quad(const float start[3], - const struct IsectRayPrecalc *isect_precalc, - const RayFace *face, - float r_uv[2], float *r_lambda) -{ - float uv[2], l; - - if (isect_ray_tri_watertight_v3(start, isect_precalc, face->v1, face->v2, face->v3, &l, uv)) { - /* check if intersection is within ray length */ - if (l > -RE_RAYTRACE_EPSILON && l < *r_lambda) { - r_uv[0] = -uv[0]; - r_uv[1] = -uv[1]; - *r_lambda = l; - return 1; - } - } - - /* intersect second triangle in quad */ - if (RE_rayface_isQuad(face)) { - if (isect_ray_tri_watertight_v3(start, isect_precalc, face->v1, face->v3, face->v4, &l, uv)) { - /* check if intersection is within ray length */ - if (l > -RE_RAYTRACE_EPSILON && l < *r_lambda) { - r_uv[0] = -uv[0]; - r_uv[1] = -uv[1]; - *r_lambda = l; - return 2; - } - } - } - - return 0; -} - -/* Simpler yes/no Ray Triangle/Quad Intersection */ - -MALWAYS_INLINE int isec_tri_quad_neighbour(const float start[3], - const float dir[3], - const RayFace *face) -{ - float r[3]; - struct IsectRayPrecalc isect_precalc; - float uv[2], l; - - negate_v3_v3(r, dir); /* note, different than above function */ - - isect_ray_tri_watertight_v3_precalc(&isect_precalc, r); - - if (isect_ray_tri_watertight_no_sign_check_v3(start, &isect_precalc, face->v1, face->v2, face->v3, &l, uv)) { - return 1; - } - - /* intersect second triangle in quad */ - if (RE_rayface_isQuad(face)) { - if (isect_ray_tri_watertight_no_sign_check_v3(start, &isect_precalc, face->v1, face->v3, face->v4, &l, uv)) { - return 2; - } - } - - return 0; -} - -/* RayFace intersection with checks and neighbor verifaction included, - * Isect is modified if the face is hit. */ - -MALWAYS_INLINE int intersect_rayface(RayObject *hit_obj, RayFace *face, Isect *is) -{ - float dist, uv[2]; - int ok = 0; - - /* avoid self-intersection */ - if (is->orig.ob == face->ob && is->orig.face == face->face) - return 0; - - /* check if we should intersect this face */ - if (is->check == RE_CHECK_VLR_RENDER) { - if (vlr_check_intersect(is, (ObjectInstanceRen *)face->ob, (VlakRen *)face->face) == 0) - return 0; - } - else if (is->check == RE_CHECK_VLR_NON_SOLID_MATERIAL) { - if (vlr_check_intersect(is, (ObjectInstanceRen *)face->ob, (VlakRen *)face->face) == 0) - return 0; - if (vlr_check_intersect_solid(is, (ObjectInstanceRen *)face->ob, (VlakRen *)face->face) == 0) - return 0; - } - else if (is->check == RE_CHECK_VLR_BAKE) { - if (vlr_check_bake(is, (ObjectInstanceRen *)face->ob, (VlakRen *)face->face) == 0) - return 0; - } - - /* ray counter */ - RE_RC_COUNT(is->raycounter->faces.test); - - dist = is->dist; - ok = isec_tri_quad(is->start, &is->isect_precalc, face, uv, &dist); - - if (ok) { - - /* when a shadow ray leaves a face, it can be little outside the edges - * of it, causing intersection to be detected in its neighbor face */ - if (is->skip & RE_SKIP_VLR_NEIGHBOUR) { - if (dist < 0.1f && is->orig.ob == face->ob) { - VlakRen *a = (VlakRen *)is->orig.face; - VlakRen *b = (VlakRen *)face->face; - ObjectRen *obr = ((ObjectInstanceRen *)face->ob)->obr; - - VertRen **va, **vb; - int *org_idx_a, *org_idx_b; - int i, j; - bool is_neighbor = false; - - /* "same" vertex means either the actual same VertRen, or the same 'final org index', if available - * (autosmooth only, currently). */ - for (i = 0, va = &a->v1; !is_neighbor && i < 4 && *va; ++i, ++va) { - org_idx_a = RE_vertren_get_origindex(obr, *va, false); - for (j = 0, vb = &b->v1; !is_neighbor && j < 4 && *vb; ++j, ++vb) { - if (*va == *vb) { - is_neighbor = true; - } - else if (org_idx_a) { - org_idx_b = RE_vertren_get_origindex(obr, *vb, 0); - if (org_idx_b && *org_idx_a == *org_idx_b) { - is_neighbor = true; - } - } - } - } - - /* So there's a shared edge or vertex, let's intersect ray with self, if that's true - * we can safely return 1, otherwise we assume the intersection is invalid, 0 */ - if (is_neighbor) { - /* create RayFace from original face, transformed if necessary */ - RayFace origface; - ObjectInstanceRen *ob = (ObjectInstanceRen *)is->orig.ob; - rayface_from_vlak(&origface, ob, (VlakRen *)is->orig.face); - - if (!isec_tri_quad_neighbour(is->start, is->dir, &origface)) { - return 0; - } - } - } - } - - RE_RC_COUNT(is->raycounter->faces.hit); - - is->isect = ok; // which half of the quad - is->dist = dist; - is->u = uv[0]; is->v = uv[1]; - - is->hit.ob = face->ob; - is->hit.face = face->face; -#ifdef RT_USE_LAST_HIT - is->last_hit = hit_obj; -#endif - return 1; - } - - return 0; -} - -/* Intersection */ - -int RE_rayobject_raycast(RayObject *r, Isect *isec) -{ - int i; - - /* Pre-calculate orientation for watertight intersection checks. */ - isect_ray_tri_watertight_v3_precalc(&isec->isect_precalc, isec->dir); - - RE_RC_COUNT(isec->raycounter->raycast.test); - - /* setup vars used on raycast */ - for (i = 0; i < 3; i++) { - isec->idot_axis[i] = 1.0f / isec->dir[i]; - - isec->bv_index[2 * i] = isec->idot_axis[i] < 0.0f ? 1 : 0; - isec->bv_index[2 * i + 1] = 1 - isec->bv_index[2 * i]; - - isec->bv_index[2 * i] = i + 3 * isec->bv_index[2 * i]; - isec->bv_index[2 * i + 1] = i + 3 * isec->bv_index[2 * i + 1]; - } - -#ifdef RT_USE_LAST_HIT - /* last hit heuristic */ - if (isec->mode == RE_RAY_SHADOW && isec->last_hit) { - RE_RC_COUNT(isec->raycounter->rayshadow_last_hit.test); - - if (RE_rayobject_intersect(isec->last_hit, isec)) { - RE_RC_COUNT(isec->raycounter->raycast.hit); - RE_RC_COUNT(isec->raycounter->rayshadow_last_hit.hit); - return 1; - } - } -#endif - -#ifdef RT_USE_HINT - isec->hit_hint = 0; -#endif - - if (RE_rayobject_intersect(r, isec)) { - RE_RC_COUNT(isec->raycounter->raycast.hit); - -#ifdef RT_USE_HINT - isec->hint = isec->hit_hint; -#endif - return 1; - } - - return 0; -} - -int RE_rayobject_intersect(RayObject *r, Isect *i) -{ - if (RE_rayobject_isRayFace(r)) { - return intersect_rayface(r, (RayFace *) RE_rayobject_align(r), i); - } - else if (RE_rayobject_isVlakPrimitive(r)) { - //TODO optimize (useless copy to RayFace to avoid duplicate code) - VlakPrimitive *face = (VlakPrimitive *) RE_rayobject_align(r); - RayFace nface; - rayface_from_vlak(&nface, face->ob, face->face); - - return intersect_rayface(r, &nface, i); - } - else if (RE_rayobject_isRayAPI(r)) { - r = RE_rayobject_align(r); - return r->api->raycast(r, i); - } - else { - assert(0); - return 0; - } -} - -/* Building */ - -void RE_rayobject_add(RayObject *r, RayObject *o) -{ - r = RE_rayobject_align(r); - return r->api->add(r, o); -} - -void RE_rayobject_done(RayObject *r) -{ - r = RE_rayobject_align(r); - r->api->done(r); -} - -void RE_rayobject_free(RayObject *r) -{ - r = RE_rayobject_align(r); - r->api->free(r); -} - -float RE_rayobject_cost(RayObject *r) -{ - if (RE_rayobject_isRayFace(r) || RE_rayobject_isVlakPrimitive(r)) { - return 1.0f; - } - else if (RE_rayobject_isRayAPI(r)) { - r = RE_rayobject_align(r); - return r->api->cost(r); - } - else { - assert(0); - return 1.0f; - } -} - -/* Bounding Boxes */ - -void RE_rayobject_merge_bb(RayObject *r, float min[3], float max[3]) -{ - if (RE_rayobject_isRayFace(r)) { - RayFace *face = (RayFace *) RE_rayobject_align(r); - - DO_MINMAX(face->v1, min, max); - DO_MINMAX(face->v2, min, max); - DO_MINMAX(face->v3, min, max); - if (RE_rayface_isQuad(face)) DO_MINMAX(face->v4, min, max); - } - else if (RE_rayobject_isVlakPrimitive(r)) { - VlakPrimitive *face = (VlakPrimitive *) RE_rayobject_align(r); - RayFace nface; - rayface_from_vlak(&nface, face->ob, face->face); - - DO_MINMAX(nface.v1, min, max); - DO_MINMAX(nface.v2, min, max); - DO_MINMAX(nface.v3, min, max); - if (RE_rayface_isQuad(&nface)) DO_MINMAX(nface.v4, min, max); - } - else if (RE_rayobject_isRayAPI(r)) { - r = RE_rayobject_align(r); - r->api->bb(r, min, max); - } - else - assert(0); -} - -/* Hints */ - -void RE_rayobject_hint_bb(RayObject *r, RayHint *hint, float *min, float *max) -{ - if (RE_rayobject_isRayFace(r) || RE_rayobject_isVlakPrimitive(r)) { - return; - } - else if (RE_rayobject_isRayAPI(r)) { - r = RE_rayobject_align(r); - return r->api->hint_bb(r, hint, min, max); - } - else - assert(0); -} - -/* RayObjectControl */ - -int RE_rayobjectcontrol_test_break(RayObjectControl *control) -{ - if (control->test_break) - return control->test_break(control->data); - - return 0; -} - -void RE_rayobject_set_control(RayObject *r, void *data, RE_rayobjectcontrol_test_break_callback test_break) -{ - if (RE_rayobject_isRayAPI(r)) { - r = RE_rayobject_align(r); - r->control.data = data; - r->control.test_break = test_break; - } -} - diff --git a/source/blender/render/intern/raytrace/rayobject_empty.cpp b/source/blender/render/intern/raytrace/rayobject_empty.cpp deleted file mode 100644 index eacec0b7eb9..00000000000 --- a/source/blender/render/intern/raytrace/rayobject_empty.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 1990-1998 NeoGeo BV. - * All rights reserved. - * - * Contributors: 2004/2005 Blender Foundation, full recode - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/render/intern/raytrace/rayobject_empty.cpp - * \ingroup render - */ - - -#include "MEM_guardedalloc.h" - -#include "rayobject.h" - -#include "BLI_utildefines.h" - -/* - * Empty raytree - */ - -static int RE_rayobject_empty_intersect(RayObject *UNUSED(o), Isect *UNUSED(is)) -{ - return 0; -} - -static void RE_rayobject_empty_free(RayObject *UNUSED(o)) -{ -} - -static void RE_rayobject_empty_bb(RayObject *UNUSED(o), float *UNUSED(min), float *UNUSED(max)) -{ - return; -} - -static float RE_rayobject_empty_cost(RayObject *UNUSED(o)) -{ - return 0.0; -} - -static void RE_rayobject_empty_hint_bb(RayObject *UNUSED(o), RayHint *UNUSED(hint), - float *UNUSED(min), float *UNUSED(max)) -{} - -static RayObjectAPI empty_api = -{ - RE_rayobject_empty_intersect, - NULL, //static void RE_rayobject_instance_add(RayObject *o, RayObject *ob); - NULL, //static void RE_rayobject_instance_done(RayObject *o); - RE_rayobject_empty_free, - RE_rayobject_empty_bb, - RE_rayobject_empty_cost, - RE_rayobject_empty_hint_bb -}; - -static RayObject empty_raytree = { &empty_api, {NULL, NULL} }; - -RayObject *RE_rayobject_empty_create() -{ - return RE_rayobject_unalignRayAPI( &empty_raytree ); -} - diff --git a/source/blender/render/intern/raytrace/rayobject_hint.h b/source/blender/render/intern/raytrace/rayobject_hint.h deleted file mode 100644 index 6eb3c035935..00000000000 --- a/source/blender/render/intern/raytrace/rayobject_hint.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2009 Blender Foundation. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): André Pinto. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/render/intern/raytrace/rayobject_hint.h - * \ingroup render - */ - - -#ifndef __RAYOBJECT_HINT_H__ -#define __RAYOBJECT_HINT_H__ - -#define HINT_RECURSE 1 -#define HINT_ACCEPT 0 -#define HINT_DISCARD -1 - -struct HintBB { - float bb[6]; -}; - -inline int hint_test_bb(HintBB *obj, float *Nmin, float *Nmax) -{ - if (bb_fits_inside(Nmin, Nmax, obj->bb, obj->bb + 3) ) - return HINT_RECURSE; - else - return HINT_ACCEPT; -} -#if 0 -struct HintFrustum { - float co[3]; - float no[4][3]; -}; - -inline int hint_test_bb(HintFrustum &obj, float *Nmin, float *Nmax) -{ - //if frustum inside BB - { - return HINT_RECURSE; - } - //if BB outside frustum - { - return HINT_DISCARD; - } - - return HINT_ACCEPT; -} -#endif - -#endif /* __RAYOBJECT_HINT_H__ */ diff --git a/source/blender/render/intern/raytrace/rayobject_instance.cpp b/source/blender/render/intern/raytrace/rayobject_instance.cpp deleted file mode 100644 index 349f0fc6844..00000000000 --- a/source/blender/render/intern/raytrace/rayobject_instance.cpp +++ /dev/null @@ -1,211 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2009 Blender Foundation. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): André Pinto. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/render/intern/raytrace/rayobject_instance.cpp - * \ingroup render - */ - - -#include <assert.h> - -#include "MEM_guardedalloc.h" - -#include "BLI_math.h" -#include "BLI_utildefines.h" - -#include "rayintersection.h" -#include "rayobject.h" - -#define RE_COST_INSTANCE (1.0f) - -static int RE_rayobject_instance_intersect(RayObject *o, Isect *isec); -static void RE_rayobject_instance_free(RayObject *o); -static void RE_rayobject_instance_bb(RayObject *o, float *min, float *max); -static float RE_rayobject_instance_cost(RayObject *o); - -static void RE_rayobject_instance_hint_bb(RayObject *UNUSED(o), RayHint *UNUSED(hint), - float *UNUSED(min), float *UNUSED(max)) -{} - -static RayObjectAPI instance_api = -{ - RE_rayobject_instance_intersect, - NULL, //static void RE_rayobject_instance_add(RayObject *o, RayObject *ob); - NULL, //static void RE_rayobject_instance_done(RayObject *o); - RE_rayobject_instance_free, - RE_rayobject_instance_bb, - RE_rayobject_instance_cost, - RE_rayobject_instance_hint_bb -}; - -typedef struct InstanceRayObject { - RayObject rayobj; - RayObject *target; - - void *ob; //Object represented by this instance - void *target_ob; //Object represented by the inner RayObject, needed to handle self-intersection - - float global2target[4][4]; - float target2global[4][4]; - -} InstanceRayObject; - - -RayObject *RE_rayobject_instance_create(RayObject *target, float transform[4][4], void *ob, void *target_ob) -{ - InstanceRayObject *obj = (InstanceRayObject *)MEM_callocN(sizeof(InstanceRayObject), "InstanceRayObject"); - assert(RE_rayobject_isAligned(obj) ); /* RayObject API assumes real data to be 4-byte aligned */ - - obj->rayobj.api = &instance_api; - obj->target = target; - obj->ob = ob; - obj->target_ob = target_ob; - - copy_m4_m4(obj->target2global, transform); - invert_m4_m4(obj->global2target, obj->target2global); - - return RE_rayobject_unalignRayAPI((RayObject *) obj); -} - -static int RE_rayobject_instance_intersect(RayObject *o, Isect *isec) -{ - InstanceRayObject *obj = (InstanceRayObject *)o; - float start[3], dir[3], idot_axis[3], dist; - int changed = 0, i, res; - - // TODO - this is disabling self intersection on instances - if (isec->orig.ob == obj->ob && obj->ob) { - changed = 1; - isec->orig.ob = obj->target_ob; - } - - // backup old values - copy_v3_v3(start, isec->start); - copy_v3_v3(dir, isec->dir); - copy_v3_v3(idot_axis, isec->idot_axis); - dist = isec->dist; - - // transform to target coordinates system - mul_m4_v3(obj->global2target, isec->start); - mul_mat3_m4_v3(obj->global2target, isec->dir); - isec->dist *= normalize_v3(isec->dir); - - // update idot_axis and bv_index - for (i = 0; i < 3; i++) { - isec->idot_axis[i] = 1.0f / isec->dir[i]; - - isec->bv_index[2 * i] = isec->idot_axis[i] < 0.0f ? 1 : 0; - isec->bv_index[2 * i + 1] = 1 - isec->bv_index[2 * i]; - - isec->bv_index[2 * i] = i + 3 * isec->bv_index[2 * i]; - isec->bv_index[2 * i + 1] = i + 3 * isec->bv_index[2 * i + 1]; - } - - // Pre-calculate orientation for watertight intersection checks. - isect_ray_tri_watertight_v3_precalc(&isec->isect_precalc, isec->dir); - - // raycast - res = RE_rayobject_intersect(obj->target, isec); - - // map dist into original coordinate space - if (res == 0) { - isec->dist = dist; - } - else { - // note we don't just multiply dist, because of possible - // non-uniform scaling in the transform matrix - float vec[3]; - - mul_v3_v3fl(vec, isec->dir, isec->dist); - mul_mat3_m4_v3(obj->target2global, vec); - - isec->dist = len_v3(vec); - isec->hit.ob = obj->ob; - -#ifdef RT_USE_LAST_HIT - // TODO support for last hit optimization in instances that can jump - // directly to the last hit face. - // For now it jumps directly to the last-hit instance root node. - isec->last_hit = RE_rayobject_unalignRayAPI((RayObject *) obj); -#endif - } - - // restore values - copy_v3_v3(isec->start, start); - copy_v3_v3(isec->dir, dir); - copy_v3_v3(isec->idot_axis, idot_axis); - - if (changed) - isec->orig.ob = obj->ob; - - // restore bv_index - for (i = 0; i < 3; i++) { - isec->bv_index[2 * i] = isec->idot_axis[i] < 0.0f ? 1 : 0; - isec->bv_index[2 * i + 1] = 1 - isec->bv_index[2 * i]; - - isec->bv_index[2 * i] = i + 3 * isec->bv_index[2 * i]; - isec->bv_index[2 * i + 1] = i + 3 * isec->bv_index[2 * i + 1]; - } - - // Pre-calculate orientation for watertight intersection checks. - isect_ray_tri_watertight_v3_precalc(&isec->isect_precalc, isec->dir); - - return res; -} - -static void RE_rayobject_instance_free(RayObject *o) -{ - InstanceRayObject *obj = (InstanceRayObject *)o; - MEM_freeN(obj); -} - -static float RE_rayobject_instance_cost(RayObject *o) -{ - InstanceRayObject *obj = (InstanceRayObject *)o; - return RE_rayobject_cost(obj->target) + RE_COST_INSTANCE; -} - -static void RE_rayobject_instance_bb(RayObject *o, float *min, float *max) -{ - //TODO: - // *better bb.. calculated without rotations of bb - // *maybe cache that better-fitted-BB at the InstanceRayObject - InstanceRayObject *obj = (InstanceRayObject *)o; - - float m[3], M[3], t[3]; - int i, j; - INIT_MINMAX(m, M); - RE_rayobject_merge_bb(obj->target, m, M); - - //There must be a faster way than rotating all the 8 vertexs of the BB - for (i = 0; i < 8; i++) { - for (j = 0; j < 3; j++) t[j] = (i & (1 << j)) ? M[j] : m[j]; - mul_m4_v3(obj->target2global, t); - DO_MINMAX(t, min, max); - } -} - diff --git a/source/blender/render/intern/raytrace/rayobject_internal.h b/source/blender/render/intern/raytrace/rayobject_internal.h deleted file mode 100644 index 5b8a43eab03..00000000000 --- a/source/blender/render/intern/raytrace/rayobject_internal.h +++ /dev/null @@ -1,157 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2009 Blender Foundation. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): André Pinto. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#ifndef __RAYOBJECT_INTERNAL_H__ -#define __RAYOBJECT_INTERNAL_H__ - -/** \file blender/render/intern/raytrace/rayobject_internal.h - * \ingroup render - */ - -#ifdef __cplusplus -extern "C" { -#endif - -/* RayObjectControl - * - * This class is intended as a place holder for control, configuration of the - * rayobject like: - * - stop building (TODO maybe when porting build to threads this could be - * implemented with some thread_cancel function) - * - max number of threads and threads callback to use during build - * ... - */ - -typedef int (*RE_rayobjectcontrol_test_break_callback)(void *data); - -typedef struct RayObjectControl { - void *data; - RE_rayobjectcontrol_test_break_callback test_break; -} RayObjectControl; - -/* Returns true if for some reason a heavy processing function should stop - * (eg.: user asked to stop during a tree a build) - */ - -int RE_rayobjectcontrol_test_break(RayObjectControl *c); - -/* RayObject - * - * A ray object is everything where we can cast rays like: - * * a face/triangle - * * an octree - * * a bvh tree - * * an octree of bvh's - * * a bvh of bvh's - * - * - * All types of RayObjects can be created by implementing the - * callbacks of the RayObject. - * - * Due to high computing time evolved with casting on faces - * there is a special type of RayObject (named RayFace) - * which won't use callbacks like other generic nodes. - * - * In order to allow a mixture of RayFace+RayObjects, - * all RayObjects must be 4byte aligned, allowing us to use the - * 2 least significant bits (with the mask 0x03) to define the - * type of RayObject. - * - * This leads to 4 possible types of RayObject: - * - * addr&3 - type of object - * 0 Self (reserved for each structure) - * 1 RayFace (tri/quad primitive) - * 2 RayObject (generic with API callbacks) - * 3 VlakPrimitive - * (vlak primitive - to be used when we have a vlak describing the data - * eg.: on render code) - * - * 0 means it's reserved and has it own meaning inside each ray acceleration structure - * (this way each structure can use the align offset to determine if a node represents a - * RayObject primitive, which can be used to save memory) - */ - -/* used to test the type of ray object */ -#define RE_rayobject_isAligned(o) ((((intptr_t)o)&3) == 0) -#define RE_rayobject_isRayFace(o) ((((intptr_t)o)&3) == 1) -#define RE_rayobject_isRayAPI(o) ((((intptr_t)o)&3) == 2) -#define RE_rayobject_isVlakPrimitive(o) ((((intptr_t)o)&3) == 3) - -/* used to align a given ray object */ -#define RE_rayobject_align(o) ((RayObject *)(((intptr_t)o)&(~3))) - -/* used to unalign a given ray object */ -#define RE_rayobject_unalignRayFace(o) ((RayObject *)(((intptr_t)o)|1)) -#define RE_rayobject_unalignRayAPI(o) ((RayObject *)(((intptr_t)o)|2)) -#define RE_rayobject_unalignVlakPrimitive(o) ((RayObject *)(((intptr_t)o)|3)) - -/* - * This rayobject represents a generic object. With it's own callbacks for raytrace operations. - * It's suitable to implement things like LOD. - */ - -struct RayObject { - struct RayObjectAPI *api; - struct RayObjectControl control; -}; - -typedef int (*RE_rayobject_raycast_callback)(RayObject *, struct Isect *); -typedef void (*RE_rayobject_add_callback)(RayObject *raytree, RayObject *rayobject); -typedef void (*RE_rayobject_done_callback)(RayObject *); -typedef void (*RE_rayobject_free_callback)(RayObject *); -typedef void (*RE_rayobject_merge_bb_callback)(RayObject *, float min[3], float max[3]); -typedef float (*RE_rayobject_cost_callback)(RayObject *); -typedef void (*RE_rayobject_hint_bb_callback)(RayObject *, struct RayHint *, float min[3], float max[3]); - -typedef struct RayObjectAPI { - RE_rayobject_raycast_callback raycast; - RE_rayobject_add_callback add; - RE_rayobject_done_callback done; - RE_rayobject_free_callback free; - RE_rayobject_merge_bb_callback bb; - RE_rayobject_cost_callback cost; - RE_rayobject_hint_bb_callback hint_bb; -} RayObjectAPI; - -/* - * Returns the expected cost of raycast on this node, primitives have a cost of 1 - */ -float RE_rayobject_cost(RayObject *r); - -/* - * This function differs from RE_rayobject_raycast - * RE_rayobject_intersect does NOT perform last-hit optimization - * So this is probably a function to call inside raytrace structures - */ -int RE_rayobject_intersect(RayObject *r, struct Isect *i); - -#ifdef __cplusplus -} -#endif - -#endif /* __RAYOBJECT_INTERNAL_H__ */ diff --git a/source/blender/render/intern/raytrace/rayobject_octree.cpp b/source/blender/render/intern/raytrace/rayobject_octree.cpp deleted file mode 100644 index b21197e728d..00000000000 --- a/source/blender/render/intern/raytrace/rayobject_octree.cpp +++ /dev/null @@ -1,1101 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 1990-1998 NeoGeo BV. - * All rights reserved. - * - * Contributors: 2004/2005 Blender Foundation, full recode - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/render/intern/raytrace/rayobject_octree.cpp - * \ingroup render - */ - - -/* IMPORTANT NOTE: this code must be independent of any other render code - * to use it outside the renderer! */ - -#include <math.h> -#include <string.h> -#include <stdlib.h> -#include <float.h> -#include <assert.h> - -#include "MEM_guardedalloc.h" - -#include "DNA_material_types.h" - -#include "BLI_math.h" -#include "BLI_utildefines.h" - -#include "rayintersection.h" -#include "rayobject.h" - -/* ********** structs *************** */ -#define BRANCH_ARRAY 1024 -#define NODE_ARRAY 4096 - -typedef struct Branch { - struct Branch *b[8]; -} Branch; - -typedef struct OcVal { - short ocx, ocy, ocz; -} OcVal; - -typedef struct Node { - struct RayFace *v[8]; - struct OcVal ov[8]; - struct Node *next; -} Node; - -typedef struct Octree { - RayObject rayobj; - - struct Branch **adrbranch; - struct Node **adrnode; - float ocsize; /* ocsize: mult factor, max size octree */ - float ocfacx, ocfacy, ocfacz; - float min[3], max[3]; - int ocres; - int branchcount, nodecount; - - /* during building only */ - char *ocface; - - RayFace **ro_nodes; - int ro_nodes_size, ro_nodes_used; - -} Octree; - -static int RE_rayobject_octree_intersect(RayObject *o, Isect *isec); -static void RE_rayobject_octree_add(RayObject *o, RayObject *ob); -static void RE_rayobject_octree_done(RayObject *o); -static void RE_rayobject_octree_free(RayObject *o); -static void RE_rayobject_octree_bb(RayObject *o, float *min, float *max); - -/* - * This function is not expected to be called by current code state. - */ -static float RE_rayobject_octree_cost(RayObject *UNUSED(o)) -{ - return 1.0; -} - -static void RE_rayobject_octree_hint_bb(RayObject *UNUSED(o), RayHint *UNUSED(hint), - float *UNUSED(min), float *UNUSED(max)) -{ - return; -} - -static RayObjectAPI octree_api = -{ - RE_rayobject_octree_intersect, - RE_rayobject_octree_add, - RE_rayobject_octree_done, - RE_rayobject_octree_free, - RE_rayobject_octree_bb, - RE_rayobject_octree_cost, - RE_rayobject_octree_hint_bb -}; - -/* **************** ocval method ******************* */ -/* within one octree node, a set of 3x15 bits defines a 'boundbox' to OR with */ - -#define OCVALRES 15 -#define BROW16(min, max) \ - (((max) >= OCVALRES ? 0xFFFF : (1 << ((max) + 1)) - 1) - (((min) > 0) ? ((1 << (min)) - 1) : 0)) - -static void calc_ocval_face(float *v1, float *v2, float *v3, float *v4, short x, short y, short z, OcVal *ov) -{ - float min[3], max[3]; - int ocmin, ocmax; - - copy_v3_v3(min, v1); - copy_v3_v3(max, v1); - DO_MINMAX(v2, min, max); - DO_MINMAX(v3, min, max); - if (v4) { - DO_MINMAX(v4, min, max); - } - - ocmin = OCVALRES * (min[0] - x); - ocmax = OCVALRES * (max[0] - x); - ov->ocx = BROW16(ocmin, ocmax); - - ocmin = OCVALRES * (min[1] - y); - ocmax = OCVALRES * (max[1] - y); - ov->ocy = BROW16(ocmin, ocmax); - - ocmin = OCVALRES * (min[2] - z); - ocmax = OCVALRES * (max[2] - z); - ov->ocz = BROW16(ocmin, ocmax); - -} - -static void calc_ocval_ray(OcVal *ov, float xo, float yo, float zo, float *vec1, float *vec2) -{ - int ocmin, ocmax; - - if (vec1[0] < vec2[0]) { - ocmin = OCVALRES * (vec1[0] - xo); - ocmax = OCVALRES * (vec2[0] - xo); - } - else { - ocmin = OCVALRES * (vec2[0] - xo); - ocmax = OCVALRES * (vec1[0] - xo); - } - ov->ocx = BROW16(ocmin, ocmax); - - if (vec1[1] < vec2[1]) { - ocmin = OCVALRES * (vec1[1] - yo); - ocmax = OCVALRES * (vec2[1] - yo); - } - else { - ocmin = OCVALRES * (vec2[1] - yo); - ocmax = OCVALRES * (vec1[1] - yo); - } - ov->ocy = BROW16(ocmin, ocmax); - - if (vec1[2] < vec2[2]) { - ocmin = OCVALRES * (vec1[2] - zo); - ocmax = OCVALRES * (vec2[2] - zo); - } - else { - ocmin = OCVALRES * (vec2[2] - zo); - ocmax = OCVALRES * (vec1[2] - zo); - } - ov->ocz = BROW16(ocmin, ocmax); -} - -/* ************* octree ************** */ - -static Branch *addbranch(Octree *oc, Branch *br, short ocb) -{ - int index; - - if (br->b[ocb]) return br->b[ocb]; - - oc->branchcount++; - index = oc->branchcount >> 12; - - if (oc->adrbranch[index] == NULL) - oc->adrbranch[index] = (Branch *)MEM_callocN(4096 * sizeof(Branch), "new oc branch"); - - if (oc->branchcount >= BRANCH_ARRAY * 4096) { - printf("error; octree branches full\n"); - oc->branchcount = 0; - } - - return br->b[ocb] = oc->adrbranch[index] + (oc->branchcount & 4095); -} - -static Node *addnode(Octree *oc) -{ - int index; - - oc->nodecount++; - index = oc->nodecount >> 12; - - if (oc->adrnode[index] == NULL) - oc->adrnode[index] = (Node *)MEM_callocN(4096 * sizeof(Node), "addnode"); - - if (oc->nodecount > NODE_ARRAY * NODE_ARRAY) { - printf("error; octree nodes full\n"); - oc->nodecount = 0; - } - - return oc->adrnode[index] + (oc->nodecount & 4095); -} - -static bool face_in_node(RayFace *face, short x, short y, short z, float rtf[4][3]) -{ - static float nor[3], d; - float fx, fy, fz; - - // init static vars - if (face) { - normal_tri_v3(nor, rtf[0], rtf[1], rtf[2]); - d = -nor[0] * rtf[0][0] - nor[1] * rtf[0][1] - nor[2] * rtf[0][2]; - return 0; - } - - fx = x; - fy = y; - fz = z; - - if ((fx) * nor[0] + (fy) * nor[1] + (fz) * nor[2] + d > 0.0f) { - if ((fx + 1) * nor[0] + (fy ) * nor[1] + (fz ) * nor[2] + d < 0.0f) return 1; - if ((fx ) * nor[0] + (fy + 1) * nor[1] + (fz ) * nor[2] + d < 0.0f) return 1; - if ((fx + 1) * nor[0] + (fy + 1) * nor[1] + (fz ) * nor[2] + d < 0.0f) return 1; - - if ((fx ) * nor[0] + (fy ) * nor[1] + (fz + 1) * nor[2] + d < 0.0f) return 1; - if ((fx + 1) * nor[0] + (fy ) * nor[1] + (fz + 1) * nor[2] + d < 0.0f) return 1; - if ((fx ) * nor[0] + (fy + 1) * nor[1] + (fz + 1) * nor[2] + d < 0.0f) return 1; - if ((fx + 1) * nor[0] + (fy + 1) * nor[1] + (fz + 1) * nor[2] + d < 0.0f) return 1; - } - else { - if ((fx + 1) * nor[0] + (fy ) * nor[1] + (fz ) * nor[2] + d > 0.0f) return 1; - if ((fx ) * nor[0] + (fy + 1) * nor[1] + (fz ) * nor[2] + d > 0.0f) return 1; - if ((fx + 1) * nor[0] + (fy + 1) * nor[1] + (fz ) * nor[2] + d > 0.0f) return 1; - - if ((fx ) * nor[0] + (fy ) * nor[1] + (fz + 1) * nor[2] + d > 0.0f) return 1; - if ((fx + 1) * nor[0] + (fy ) * nor[1] + (fz + 1) * nor[2] + d > 0.0f) return 1; - if ((fx ) * nor[0] + (fy + 1) * nor[1] + (fz + 1) * nor[2] + d > 0.0f) return 1; - if ((fx + 1) * nor[0] + (fy + 1) * nor[1] + (fz + 1) * nor[2] + d > 0.0f) return 1; - } - - return 0; -} - -static void ocwrite(Octree *oc, RayFace *face, int quad, short x, short y, short z, float rtf[4][3]) -{ - Branch *br; - Node *no; - short a, oc0, oc1, oc2, oc3, oc4, oc5; - - x <<= 2; - y <<= 1; - - br = oc->adrbranch[0]; - - if (oc->ocres == 512) { - oc0 = ((x & 1024) + (y & 512) + (z & 256)) >> 8; - br = addbranch(oc, br, oc0); - } - if (oc->ocres >= 256) { - oc0 = ((x & 512) + (y & 256) + (z & 128)) >> 7; - br = addbranch(oc, br, oc0); - } - if (oc->ocres >= 128) { - oc0 = ((x & 256) + (y & 128) + (z & 64)) >> 6; - br = addbranch(oc, br, oc0); - } - - oc0 = ((x & 128) + (y & 64) + (z & 32)) >> 5; - oc1 = ((x & 64) + (y & 32) + (z & 16)) >> 4; - oc2 = ((x & 32) + (y & 16) + (z & 8)) >> 3; - oc3 = ((x & 16) + (y & 8) + (z & 4)) >> 2; - oc4 = ((x & 8) + (y & 4) + (z & 2)) >> 1; - oc5 = ((x & 4) + (y & 2) + (z & 1)); - - br = addbranch(oc, br, oc0); - br = addbranch(oc, br, oc1); - br = addbranch(oc, br, oc2); - br = addbranch(oc, br, oc3); - br = addbranch(oc, br, oc4); - no = (Node *)br->b[oc5]; - if (no == NULL) br->b[oc5] = (Branch *)(no = addnode(oc)); - - while (no->next) no = no->next; - - a = 0; - if (no->v[7]) { /* node full */ - no->next = addnode(oc); - no = no->next; - } - else { - while (no->v[a] != NULL) a++; - } - - no->v[a] = (RayFace *) RE_rayobject_align(face); - - if (quad) - calc_ocval_face(rtf[0], rtf[1], rtf[2], rtf[3], x >> 2, y >> 1, z, &no->ov[a]); - else - calc_ocval_face(rtf[0], rtf[1], rtf[2], NULL, x >> 2, y >> 1, z, &no->ov[a]); -} - -static void d2dda(Octree *oc, short b1, short b2, short c1, short c2, char *ocface, short rts[4][3], float rtf[4][3]) -{ - int ocx1, ocx2, ocy1, ocy2; - int x, y, dx = 0, dy = 0; - float ox1, ox2, oy1, oy2; - float lambda, lambda_o, lambda_x, lambda_y, ldx, ldy; - - ocx1 = rts[b1][c1]; - ocy1 = rts[b1][c2]; - ocx2 = rts[b2][c1]; - ocy2 = rts[b2][c2]; - - if (ocx1 == ocx2 && ocy1 == ocy2) { - ocface[oc->ocres * ocx1 + ocy1] = 1; - return; - } - - ox1 = rtf[b1][c1]; - oy1 = rtf[b1][c2]; - ox2 = rtf[b2][c1]; - oy2 = rtf[b2][c2]; - - if (ox1 != ox2) { - if (ox2 - ox1 > 0.0f) { - lambda_x = (ox1 - ocx1 - 1.0f) / (ox1 - ox2); - ldx = -1.0f / (ox1 - ox2); - dx = 1; - } - else { - lambda_x = (ox1 - ocx1) / (ox1 - ox2); - ldx = 1.0f / (ox1 - ox2); - dx = -1; - } - } - else { - lambda_x = 1.0f; - ldx = 0; - } - - if (oy1 != oy2) { - if (oy2 - oy1 > 0.0f) { - lambda_y = (oy1 - ocy1 - 1.0f) / (oy1 - oy2); - ldy = -1.0f / (oy1 - oy2); - dy = 1; - } - else { - lambda_y = (oy1 - ocy1) / (oy1 - oy2); - ldy = 1.0f / (oy1 - oy2); - dy = -1; - } - } - else { - lambda_y = 1.0f; - ldy = 0; - } - - x = ocx1; y = ocy1; - lambda = MIN2(lambda_x, lambda_y); - - while (true) { - - if (x < 0 || y < 0 || x >= oc->ocres || y >= oc->ocres) { - /* pass*/ - } - else { - ocface[oc->ocres * x + y] = 1; - } - - lambda_o = lambda; - if (lambda_x == lambda_y) { - lambda_x += ldx; - x += dx; - lambda_y += ldy; - y += dy; - } - else { - if (lambda_x < lambda_y) { - lambda_x += ldx; - x += dx; - } - else { - lambda_y += ldy; - y += dy; - } - } - lambda = MIN2(lambda_x, lambda_y); - if (lambda == lambda_o) break; - if (lambda >= 1.0f) break; - } - ocface[oc->ocres * ocx2 + ocy2] = 1; -} - -static void filltriangle(Octree *oc, short c1, short c2, char *ocface, short *ocmin, short *ocmax) -{ - int a, x, y, y1, y2; - - for (x = ocmin[c1]; x <= ocmax[c1]; x++) { - a = oc->ocres * x; - for (y = ocmin[c2]; y <= ocmax[c2]; y++) { - if (ocface[a + y]) { - y++; - while (ocface[a + y] && y != ocmax[c2]) y++; - for (y1 = ocmax[c2]; y1 > y; y1--) { - if (ocface[a + y1]) { - for (y2 = y; y2 <= y1; y2++) ocface[a + y2] = 1; - y1 = 0; - } - } - y = ocmax[c2]; - } - } - } -} - -static void RE_rayobject_octree_free(RayObject *tree) -{ - Octree *oc = (Octree *)tree; - -#if 0 - printf("branches %d nodes %d\n", oc->branchcount, oc->nodecount); - printf("raycount %d\n", raycount); - printf("ray coherent %d\n", coherent_ray); - printf("accepted %d rejected %d\n", accepted, rejected); -#endif - if (oc->ocface) - MEM_freeN(oc->ocface); - - if (oc->adrbranch) { - int a = 0; - while (oc->adrbranch[a]) { - MEM_freeN(oc->adrbranch[a]); - oc->adrbranch[a] = NULL; - a++; - } - MEM_freeN(oc->adrbranch); - oc->adrbranch = NULL; - } - oc->branchcount = 0; - - if (oc->adrnode) { - int a = 0; - while (oc->adrnode[a]) { - MEM_freeN(oc->adrnode[a]); - oc->adrnode[a] = NULL; - a++; - } - MEM_freeN(oc->adrnode); - oc->adrnode = NULL; - } - oc->nodecount = 0; - - MEM_freeN(oc); -} - - -RayObject *RE_rayobject_octree_create(int ocres, int size) -{ - Octree *oc = (Octree *)MEM_callocN(sizeof(Octree), "Octree"); - assert(RE_rayobject_isAligned(oc) ); /* RayObject API assumes real data to be 4-byte aligned */ - - oc->rayobj.api = &octree_api; - - oc->ocres = ocres; - - oc->ro_nodes = (RayFace **)MEM_callocN(sizeof(RayFace *) * size, "octree rayobject nodes"); - oc->ro_nodes_size = size; - oc->ro_nodes_used = 0; - - - return RE_rayobject_unalignRayAPI((RayObject *) oc); -} - - -static void RE_rayobject_octree_add(RayObject *tree, RayObject *node) -{ - Octree *oc = (Octree *)tree; - - assert(RE_rayobject_isRayFace(node) ); - assert(oc->ro_nodes_used < oc->ro_nodes_size); - oc->ro_nodes[oc->ro_nodes_used++] = (RayFace *)RE_rayobject_align(node); -} - -static void octree_fill_rayface(Octree *oc, RayFace *face) -{ - float ocfac[3], rtf[4][3]; - float co1[3], co2[3], co3[3], co4[3]; - short rts[4][3]; - short ocmin[3], ocmax[3]; - char *ocface = oc->ocface; // front, top, size view of face, to fill in - int a, b, c, oc1, oc2, oc3, oc4, x, y, z, ocres2; - - ocfac[0] = oc->ocfacx; - ocfac[1] = oc->ocfacy; - ocfac[2] = oc->ocfacz; - - ocres2 = oc->ocres * oc->ocres; - - copy_v3_v3(co1, face->v1); - copy_v3_v3(co2, face->v2); - copy_v3_v3(co3, face->v3); - if (RE_rayface_isQuad(face)) - copy_v3_v3(co4, face->v4); - - for (c = 0; c < 3; c++) { - rtf[0][c] = (co1[c] - oc->min[c]) * ocfac[c]; - rts[0][c] = (short)rtf[0][c]; - rtf[1][c] = (co2[c] - oc->min[c]) * ocfac[c]; - rts[1][c] = (short)rtf[1][c]; - rtf[2][c] = (co3[c] - oc->min[c]) * ocfac[c]; - rts[2][c] = (short)rtf[2][c]; - if (RE_rayface_isQuad(face)) { - rtf[3][c] = (co4[c] - oc->min[c]) * ocfac[c]; - rts[3][c] = (short)rtf[3][c]; - } - } - - for (c = 0; c < 3; c++) { - oc1 = rts[0][c]; - oc2 = rts[1][c]; - oc3 = rts[2][c]; - if (!RE_rayface_isQuad(face)) { - ocmin[c] = min_iii(oc1, oc2, oc3); - ocmax[c] = max_iii(oc1, oc2, oc3); - } - else { - oc4 = rts[3][c]; - ocmin[c] = min_iiii(oc1, oc2, oc3, oc4); - ocmax[c] = max_iiii(oc1, oc2, oc3, oc4); - } - if (ocmax[c] > oc->ocres - 1) ocmax[c] = oc->ocres - 1; - if (ocmin[c] < 0) ocmin[c] = 0; - } - - if (ocmin[0] == ocmax[0] && ocmin[1] == ocmax[1] && ocmin[2] == ocmax[2]) { - ocwrite(oc, face, RE_rayface_isQuad(face), ocmin[0], ocmin[1], ocmin[2], rtf); - } - else { - - d2dda(oc, 0, 1, 0, 1, ocface + ocres2, rts, rtf); - d2dda(oc, 0, 1, 0, 2, ocface, rts, rtf); - d2dda(oc, 0, 1, 1, 2, ocface + 2 * ocres2, rts, rtf); - d2dda(oc, 1, 2, 0, 1, ocface + ocres2, rts, rtf); - d2dda(oc, 1, 2, 0, 2, ocface, rts, rtf); - d2dda(oc, 1, 2, 1, 2, ocface + 2 * ocres2, rts, rtf); - if (!RE_rayface_isQuad(face)) { - d2dda(oc, 2, 0, 0, 1, ocface + ocres2, rts, rtf); - d2dda(oc, 2, 0, 0, 2, ocface, rts, rtf); - d2dda(oc, 2, 0, 1, 2, ocface + 2 * ocres2, rts, rtf); - } - else { - d2dda(oc, 2, 3, 0, 1, ocface + ocres2, rts, rtf); - d2dda(oc, 2, 3, 0, 2, ocface, rts, rtf); - d2dda(oc, 2, 3, 1, 2, ocface + 2 * ocres2, rts, rtf); - d2dda(oc, 3, 0, 0, 1, ocface + ocres2, rts, rtf); - d2dda(oc, 3, 0, 0, 2, ocface, rts, rtf); - d2dda(oc, 3, 0, 1, 2, ocface + 2 * ocres2, rts, rtf); - } - /* nothing todo with triangle..., just fills :) */ - filltriangle(oc, 0, 1, ocface + ocres2, ocmin, ocmax); - filltriangle(oc, 0, 2, ocface, ocmin, ocmax); - filltriangle(oc, 1, 2, ocface + 2 * ocres2, ocmin, ocmax); - - /* init static vars here */ - face_in_node(face, 0, 0, 0, rtf); - - for (x = ocmin[0]; x <= ocmax[0]; x++) { - a = oc->ocres * x; - for (y = ocmin[1]; y <= ocmax[1]; y++) { - if (ocface[a + y + ocres2]) { - b = oc->ocres * y + 2 * ocres2; - for (z = ocmin[2]; z <= ocmax[2]; z++) { - if (ocface[b + z] && ocface[a + z]) { - if (face_in_node(NULL, x, y, z, rtf)) - ocwrite(oc, face, RE_rayface_isQuad(face), x, y, z, rtf); - } - } - } - } - } - - /* same loops to clear octree, doubt it can be done smarter */ - for (x = ocmin[0]; x <= ocmax[0]; x++) { - a = oc->ocres * x; - for (y = ocmin[1]; y <= ocmax[1]; y++) { - /* x-y */ - ocface[a + y + ocres2] = 0; - - b = oc->ocres * y + 2 * ocres2; - for (z = ocmin[2]; z <= ocmax[2]; z++) { - /* y-z */ - ocface[b + z] = 0; - /* x-z */ - ocface[a + z] = 0; - } - } - } - } -} - -static void RE_rayobject_octree_done(RayObject *tree) -{ - Octree *oc = (Octree *)tree; - int c; - float t00, t01, t02; - int ocres2 = oc->ocres * oc->ocres; - - INIT_MINMAX(oc->min, oc->max); - - /* Calculate Bounding Box */ - for (c = 0; c < oc->ro_nodes_used; c++) - RE_rayobject_merge_bb(RE_rayobject_unalignRayFace(oc->ro_nodes[c]), oc->min, oc->max); - - /* Alloc memory */ - oc->adrbranch = (Branch **)MEM_callocN(sizeof(void *) * BRANCH_ARRAY, "octree branches"); - oc->adrnode = (Node **)MEM_callocN(sizeof(void *) * NODE_ARRAY, "octree nodes"); - - oc->adrbranch[0] = (Branch *)MEM_callocN(4096 * sizeof(Branch), "makeoctree"); - - /* the lookup table, per face, for which nodes to fill in */ - oc->ocface = (char *)MEM_callocN(3 * ocres2 + 8, "ocface"); - memset(oc->ocface, 0, 3 * ocres2); - - for (c = 0; c < 3; c++) { /* octree enlarge, still needed? */ - oc->min[c] -= 0.01f; - oc->max[c] += 0.01f; - } - - t00 = oc->max[0] - oc->min[0]; - t01 = oc->max[1] - oc->min[1]; - t02 = oc->max[2] - oc->min[2]; - - /* this minus 0.1 is old safety... seems to be needed? */ - oc->ocfacx = (oc->ocres - 0.1f) / t00; - oc->ocfacy = (oc->ocres - 0.1f) / t01; - oc->ocfacz = (oc->ocres - 0.1f) / t02; - - oc->ocsize = sqrtf(t00 * t00 + t01 * t01 + t02 * t02); /* global, max size octree */ - - for (c = 0; c < oc->ro_nodes_used; c++) { - octree_fill_rayface(oc, oc->ro_nodes[c]); - } - - MEM_freeN(oc->ocface); - oc->ocface = NULL; - MEM_freeN(oc->ro_nodes); - oc->ro_nodes = NULL; - -#if 0 - printf("%f %f - %f\n", oc->min[0], oc->max[0], oc->ocfacx); - printf("%f %f - %f\n", oc->min[1], oc->max[1], oc->ocfacy); - printf("%f %f - %f\n", oc->min[2], oc->max[2], oc->ocfacz); -#endif -} - -static void RE_rayobject_octree_bb(RayObject *tree, float *min, float *max) -{ - Octree *oc = (Octree *)tree; - DO_MINMAX(oc->min, min, max); - DO_MINMAX(oc->max, min, max); -} - -/* check all faces in this node */ -static int testnode(Octree *UNUSED(oc), Isect *is, Node *no, OcVal ocval) -{ - short nr = 0; - - /* return on any first hit */ - if (is->mode == RE_RAY_SHADOW) { - - for (; no; no = no->next) { - for (nr = 0; nr < 8; nr++) { - RayFace *face = no->v[nr]; - OcVal *ov = no->ov + nr; - - if (!face) break; - - if ( (ov->ocx & ocval.ocx) && (ov->ocy & ocval.ocy) && (ov->ocz & ocval.ocz) ) { - if (RE_rayobject_intersect(RE_rayobject_unalignRayFace(face), is) ) - return 1; - } - } - } - } - else { - /* else mirror or glass or shadowtra, return closest face */ - int found = 0; - - for (; no; no = no->next) { - for (nr = 0; nr < 8; nr++) { - RayFace *face = no->v[nr]; - OcVal *ov = no->ov + nr; - - if (!face) break; - - if ( (ov->ocx & ocval.ocx) && (ov->ocy & ocval.ocy) && (ov->ocz & ocval.ocz) ) { - if (RE_rayobject_intersect(RE_rayobject_unalignRayFace(face), is) ) { - found = 1; - } - } - } - } - - return found; - } - - return 0; -} - -/* find the Node for the octree coord x y z */ -static Node *ocread(Octree *oc, int x, int y, int z) -{ - Branch *br; - int oc1; - - x <<= 2; - y <<= 1; - - br = oc->adrbranch[0]; - - if (oc->ocres == 512) { - oc1 = ((x & 1024) + (y & 512) + (z & 256)) >> 8; - br = br->b[oc1]; - if (br == NULL) { - return NULL; - } - } - if (oc->ocres >= 256) { - oc1 = ((x & 512) + (y & 256) + (z & 128)) >> 7; - br = br->b[oc1]; - if (br == NULL) { - return NULL; - } - } - if (oc->ocres >= 128) { - oc1 = ((x & 256) + (y & 128) + (z & 64)) >> 6; - br = br->b[oc1]; - if (br == NULL) { - return NULL; - } - } - - oc1 = ((x & 128) + (y & 64) + (z & 32)) >> 5; - br = br->b[oc1]; - if (br) { - oc1 = ((x & 64) + (y & 32) + (z & 16)) >> 4; - br = br->b[oc1]; - if (br) { - oc1 = ((x & 32) + (y & 16) + (z & 8)) >> 3; - br = br->b[oc1]; - if (br) { - oc1 = ((x & 16) + (y & 8) + (z & 4)) >> 2; - br = br->b[oc1]; - if (br) { - oc1 = ((x & 8) + (y & 4) + (z & 2)) >> 1; - br = br->b[oc1]; - if (br) { - oc1 = ((x & 4) + (y & 2) + (z & 1)); - return (Node *)br->b[oc1]; - } - } - } - } - } - - return NULL; -} - -static int cliptest(float p, float q, float *u1, float *u2) -{ - float r; - - if (p < 0.0f) { - if (q < p) return 0; - else if (q < 0.0f) { - r = q / p; - if (r > *u2) return 0; - else if (r > *u1) *u1 = r; - } - } - else { - if (p > 0.0f) { - if (q < 0.0f) return 0; - else if (q < p) { - r = q / p; - if (r < *u1) return 0; - else if (r < *u2) *u2 = r; - } - } - else if (q < 0.0f) return 0; - } - return 1; -} - -/* extensive coherence checks/storage cancels out the benefit of it, and gives errors... we - * need better methods, sample code commented out below (ton) */ - -#if 0 - -in top : static int coh_nodes[16 * 16 * 16][6]; -in makeoctree : memset(coh_nodes, 0, sizeof(coh_nodes)); - -static void add_coherence_test(int ocx1, int ocx2, int ocy1, int ocy2, int ocz1, int ocz2) -{ - short *sp; - - sp = coh_nodes[(ocx2 & 15) + 16 * (ocy2 & 15) + 256 * (ocz2 & 15)]; - sp[0] = ocx1; sp[1] = ocy1; sp[2] = ocz1; - sp[3] = ocx2; sp[4] = ocy2; sp[5] = ocz2; - -} - -static int do_coherence_test(int ocx1, int ocx2, int ocy1, int ocy2, int ocz1, int ocz2) -{ - short *sp; - - sp = coh_nodes[(ocx2 & 15) + 16 * (ocy2 & 15) + 256 * (ocz2 & 15)]; - if (sp[0] == ocx1 && sp[1] == ocy1 && sp[2] == ocz1 && - sp[3] == ocx2 && sp[4] == ocy2 && sp[5] == ocz2) return 1; - return 0; -} - -#endif - -/* return 1: found valid intersection */ -/* starts with is->orig.face */ -static int RE_rayobject_octree_intersect(RayObject *tree, Isect *is) -{ - Octree *oc = (Octree *)tree; - Node *no; - OcVal ocval; - float vec1[3], vec2[3], start[3], end[3]; - float u1, u2, ox1, ox2, oy1, oy2, oz1, oz2; - float lambda_o, lambda_x, ldx, lambda_y, ldy, lambda_z, ldz, dda_lambda; - float o_lambda = 0; - int dx, dy, dz; - int xo, yo, zo, c1 = 0; - int ocx1, ocx2, ocy1, ocy2, ocz1, ocz2; - - /* clip with octree */ - if (oc->branchcount == 0) return 0; - - /* do this before intersect calls */ -#if 0 - is->facecontr = NULL; /* to check shared edge */ - is->obcontr = 0; - is->faceisect = is->isect = 0; /* shared edge, quad half flag */ - is->userdata = oc->userdata; -#endif - - copy_v3_v3(start, is->start); - madd_v3_v3v3fl(end, is->start, is->dir, is->dist); - ldx = is->dir[0] * is->dist; - o_lambda = is->dist; - u1 = 0.0f; - u2 = 1.0f; - - /* clip with octree cube */ - if (cliptest(-ldx, start[0] - oc->min[0], &u1, &u2)) { - if (cliptest(ldx, oc->max[0] - start[0], &u1, &u2)) { - ldy = is->dir[1] * is->dist; - if (cliptest(-ldy, start[1] - oc->min[1], &u1, &u2)) { - if (cliptest(ldy, oc->max[1] - start[1], &u1, &u2)) { - ldz = is->dir[2] * is->dist; - if (cliptest(-ldz, start[2] - oc->min[2], &u1, &u2)) { - if (cliptest(ldz, oc->max[2] - start[2], &u1, &u2)) { - c1 = 1; - if (u2 < 1.0f) { - end[0] = start[0] + u2 * ldx; - end[1] = start[1] + u2 * ldy; - end[2] = start[2] + u2 * ldz; - } - - if (u1 > 0.0f) { - start[0] += u1 * ldx; - start[1] += u1 * ldy; - start[2] += u1 * ldz; - } - } - } - } - } - } - } - - if (c1 == 0) return 0; - - /* reset static variables in ocread */ - //ocread(oc, oc->ocres, 0, 0); - - /* setup 3dda to traverse octree */ - ox1 = (start[0] - oc->min[0]) * oc->ocfacx; - oy1 = (start[1] - oc->min[1]) * oc->ocfacy; - oz1 = (start[2] - oc->min[2]) * oc->ocfacz; - ox2 = (end[0] - oc->min[0]) * oc->ocfacx; - oy2 = (end[1] - oc->min[1]) * oc->ocfacy; - oz2 = (end[2] - oc->min[2]) * oc->ocfacz; - - ocx1 = (int)ox1; - ocy1 = (int)oy1; - ocz1 = (int)oz1; - ocx2 = (int)ox2; - ocy2 = (int)oy2; - ocz2 = (int)oz2; - - if (ocx1 == ocx2 && ocy1 == ocy2 && ocz1 == ocz2) { - no = ocread(oc, ocx1, ocy1, ocz1); - if (no) { - /* exact intersection with node */ - vec1[0] = ox1; vec1[1] = oy1; vec1[2] = oz1; - vec2[0] = ox2; vec2[1] = oy2; vec2[2] = oz2; - calc_ocval_ray(&ocval, (float)ocx1, (float)ocy1, (float)ocz1, vec1, vec2); - if (testnode(oc, is, no, ocval) ) return 1; - } - } - else { - int found = 0; - //static int coh_ocx1, coh_ocx2, coh_ocy1, coh_ocy2, coh_ocz1, coh_ocz2; - float dox, doy, doz; - int eqval; - - /* calc lambda en ld */ - dox = ox1 - ox2; - doy = oy1 - oy2; - doz = oz1 - oz2; - - if (dox < -FLT_EPSILON) { - ldx = -1.0f / dox; - lambda_x = (ocx1 - ox1 + 1.0f) * ldx; - dx = 1; - } - else if (dox > FLT_EPSILON) { - ldx = 1.0f / dox; - lambda_x = (ox1 - ocx1) * ldx; - dx = -1; - } - else { - lambda_x = 1.0f; - ldx = 0; - dx = 0; - } - - if (doy < -FLT_EPSILON) { - ldy = -1.0f / doy; - lambda_y = (ocy1 - oy1 + 1.0f) * ldy; - dy = 1; - } - else if (doy > FLT_EPSILON) { - ldy = 1.0f / doy; - lambda_y = (oy1 - ocy1) * ldy; - dy = -1; - } - else { - lambda_y = 1.0f; - ldy = 0; - dy = 0; - } - - if (doz < -FLT_EPSILON) { - ldz = -1.0f / doz; - lambda_z = (ocz1 - oz1 + 1.0f) * ldz; - dz = 1; - } - else if (doz > FLT_EPSILON) { - ldz = 1.0f / doz; - lambda_z = (oz1 - ocz1) * ldz; - dz = -1; - } - else { - lambda_z = 1.0f; - ldz = 0; - dz = 0; - } - - xo = ocx1; yo = ocy1; zo = ocz1; - dda_lambda = min_fff(lambda_x, lambda_y, lambda_z); - - vec2[0] = ox1; - vec2[1] = oy1; - vec2[2] = oz1; - - /* this loop has been constructed to make sure the first and last node of ray - * are always included, even when dda_lambda==1.0f or larger */ - - while (true) { - - no = ocread(oc, xo, yo, zo); - if (no) { - - /* calculate ray intersection with octree node */ - copy_v3_v3(vec1, vec2); - // dox, y, z is negative - vec2[0] = ox1 - dda_lambda * dox; - vec2[1] = oy1 - dda_lambda * doy; - vec2[2] = oz1 - dda_lambda * doz; - calc_ocval_ray(&ocval, (float)xo, (float)yo, (float)zo, vec1, vec2); - - //is->dist = (u1 + dda_lambda * (u2 - u1)) * o_lambda; - if (testnode(oc, is, no, ocval) ) - found = 1; - - if (is->dist < (u1 + dda_lambda * (u2 - u1)) * o_lambda) - return found; - } - - - lambda_o = dda_lambda; - - /* traversing octree nodes need careful detection of smallest values, with proper - * exceptions for equal lambdas */ - eqval = (lambda_x == lambda_y); - if (lambda_y == lambda_z) eqval += 2; - if (lambda_x == lambda_z) eqval += 4; - - if (eqval) { // only 4 cases exist! - if (eqval == 7) { // x=y=z - xo += dx; lambda_x += ldx; - yo += dy; lambda_y += ldy; - zo += dz; lambda_z += ldz; - } - else if (eqval == 1) { // x=y - if (lambda_y < lambda_z) { - xo += dx; lambda_x += ldx; - yo += dy; lambda_y += ldy; - } - else { - zo += dz; lambda_z += ldz; - } - } - else if (eqval == 2) { // y=z - if (lambda_x < lambda_y) { - xo += dx; lambda_x += ldx; - } - else { - yo += dy; lambda_y += ldy; - zo += dz; lambda_z += ldz; - } - } - else { // x=z - if (lambda_y < lambda_x) { - yo += dy; lambda_y += ldy; - } - else { - xo += dx; lambda_x += ldx; - zo += dz; lambda_z += ldz; - } - } - } - else { // all three different, just three cases exist - eqval = (lambda_x < lambda_y); - if (lambda_y < lambda_z) eqval += 2; - if (lambda_x < lambda_z) eqval += 4; - - if (eqval == 7 || eqval == 5) { // x smallest - xo += dx; lambda_x += ldx; - } - else if (eqval == 2 || eqval == 6) { // y smallest - yo += dy; lambda_y += ldy; - } - else { // z smallest - zo += dz; lambda_z += ldz; - } - - } - - dda_lambda = min_fff(lambda_x, lambda_y, lambda_z); - if (dda_lambda == lambda_o) break; - /* to make sure the last node is always checked */ - if (lambda_o >= 1.0f) break; - } - } - - /* reached end, no intersections found */ - return 0; -} - - - diff --git a/source/blender/render/intern/raytrace/rayobject_qbvh.cpp b/source/blender/render/intern/raytrace/rayobject_qbvh.cpp deleted file mode 100644 index 5b90ae77732..00000000000 --- a/source/blender/render/intern/raytrace/rayobject_qbvh.cpp +++ /dev/null @@ -1,160 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2009 Blender Foundation. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): André Pinto. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/render/intern/raytrace/rayobject_qbvh.cpp - * \ingroup render - */ - - -#include "MEM_guardedalloc.h" - -#include "BLI_utildefines.h" - -#include "vbvh.h" -#include "svbvh.h" -#include "reorganize.h" - -#ifdef __SSE__ - -#define DFS_STACK_SIZE 256 - -struct QBVHTree { - RayObject rayobj; - - SVBVHNode *root; - MemArena *node_arena; - - float cost; - RTBuilder *builder; -}; - - -template<> -void bvh_done<QBVHTree>(QBVHTree *obj) -{ - rtbuild_done(obj->builder, &obj->rayobj.control); - - //TODO find a away to exactly calculate the needed memory - MemArena *arena1 = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "qbvh arena"); - BLI_memarena_use_malloc(arena1); - - MemArena *arena2 = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "qbvh arena 2"); - BLI_memarena_use_malloc(arena2); - BLI_memarena_use_align(arena2, 16); - - //Build and optimize the tree - //TODO do this in 1 pass (half memory usage during building) - VBVHNode *root = BuildBinaryVBVH<VBVHNode>(arena1, &obj->rayobj.control).transform(obj->builder); - - if (RE_rayobjectcontrol_test_break(&obj->rayobj.control)) { - BLI_memarena_free(arena1); - BLI_memarena_free(arena2); - return; - } - - if (root) { - pushup_simd<VBVHNode, 4>(root); - obj->root = Reorganize_SVBVH<VBVHNode>(arena2).transform(root); - } - else - obj->root = NULL; - - //Free data - BLI_memarena_free(arena1); - - obj->node_arena = arena2; - obj->cost = 1.0; - - rtbuild_free(obj->builder); - obj->builder = NULL; -} - -template<int StackSize> -static int intersect(QBVHTree *obj, Isect *isec) -{ - //TODO renable hint support - if (RE_rayobject_isAligned(obj->root)) { - if (isec->mode == RE_RAY_SHADOW) - return svbvh_node_stack_raycast<StackSize, true>(obj->root, isec); - else - return svbvh_node_stack_raycast<StackSize, false>(obj->root, isec); - } - else - return RE_rayobject_intersect((RayObject *)obj->root, isec); -} - -template<class Tree> -static void bvh_hint_bb(Tree *tree, LCTSHint *hint, float *UNUSED(min), float *UNUSED(max)) -{ - //TODO renable hint support - { - hint->size = 0; - hint->stack[hint->size++] = (RayObject *)tree->root; - } -} -/* the cast to pointer function is needed to workarround gcc bug: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11407 */ -template<class Tree, int STACK_SIZE> -static RayObjectAPI make_api() -{ - static RayObjectAPI api = - { - (RE_rayobject_raycast_callback) ((int (*)(Tree *, Isect *)) & intersect<STACK_SIZE>), - (RE_rayobject_add_callback) ((void (*)(Tree *, RayObject *)) & bvh_add<Tree>), - (RE_rayobject_done_callback) ((void (*)(Tree *)) & bvh_done<Tree>), - (RE_rayobject_free_callback) ((void (*)(Tree *)) & bvh_free<Tree>), - (RE_rayobject_merge_bb_callback)((void (*)(Tree *, float *, float *)) & bvh_bb<Tree>), - (RE_rayobject_cost_callback) ((float (*)(Tree *)) & bvh_cost<Tree>), - (RE_rayobject_hint_bb_callback) ((void (*)(Tree *, LCTSHint *, float *, float *)) & bvh_hint_bb<Tree>) - }; - - return api; -} - -template<class Tree> -RayObjectAPI *bvh_get_api(int maxstacksize) -{ - static RayObjectAPI bvh_api256 = make_api<Tree, 1024>(); - - if (maxstacksize <= 1024) return &bvh_api256; - assert(maxstacksize <= 256); - return NULL; -} - -RayObject *RE_rayobject_qbvh_create(int size) -{ - return bvh_create_tree<QBVHTree, DFS_STACK_SIZE>(size); -} - -#else - -RayObject *RE_rayobject_qbvh_create(int UNUSED(size)) -{ - puts("WARNING: SSE disabled at compile time\n"); - return NULL; -} - -#endif diff --git a/source/blender/render/intern/raytrace/rayobject_raycounter.cpp b/source/blender/render/intern/raytrace/rayobject_raycounter.cpp deleted file mode 100644 index 5335bf50cbc..00000000000 --- a/source/blender/render/intern/raytrace/rayobject_raycounter.cpp +++ /dev/null @@ -1,91 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2009 Blender Foundation. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): André Pinto. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/render/intern/raytrace/rayobject_raycounter.cpp - * \ingroup render - */ - - -#include "rayobject.h" -#include "raycounter.h" - -#ifdef RE_RAYCOUNTER - -void RE_RC_INFO(RayCounter *info) -{ - printf("----------- Raycast counter --------\n"); - printf("Rays total: %llu\n", info->raycast.test ); - printf("Rays hit: %llu\n", info->raycast.hit ); - printf("\n"); - printf("BB tests: %llu\n", info->bb.test ); - printf("BB hits: %llu\n", info->bb.hit ); - printf("\n"); - printf("SIMD BB tests: %llu\n", info->simd_bb.test ); - printf("SIMD BB hits: %llu\n", info->simd_bb.hit ); - printf("\n"); - printf("Primitives tests: %llu\n", info->faces.test ); - printf("Primitives hits: %llu\n", info->faces.hit ); - printf("------------------------------------\n"); - printf("Shadow last-hit tests per ray: %f\n", info->rayshadow_last_hit.test / ((float)info->raycast.test) ); - printf("Shadow last-hit hits per ray: %f\n", info->rayshadow_last_hit.hit / ((float)info->raycast.test) ); - printf("\n"); - printf("Hint tests per ray: %f\n", info->raytrace_hint.test / ((float)info->raycast.test) ); - printf("Hint hits per ray: %f\n", info->raytrace_hint.hit / ((float)info->raycast.test) ); - printf("\n"); - printf("BB tests per ray: %f\n", info->bb.test / ((float)info->raycast.test) ); - printf("BB hits per ray: %f\n", info->bb.hit / ((float)info->raycast.test) ); - printf("\n"); - printf("SIMD tests per ray: %f\n", info->simd_bb.test / ((float)info->raycast.test) ); - printf("SIMD hits per ray: %f\n", info->simd_bb.hit / ((float)info->raycast.test) ); - printf("\n"); - printf("Primitives tests per ray: %f\n", info->faces.test / ((float)info->raycast.test) ); - printf("Primitives hits per ray: %f\n", info->faces.hit / ((float)info->raycast.test) ); - printf("------------------------------------\n"); -} - -void RE_RC_MERGE(RayCounter *dest, RayCounter *tmp) -{ - dest->faces.test += tmp->faces.test; - dest->faces.hit += tmp->faces.hit; - - dest->bb.test += tmp->bb.test; - dest->bb.hit += tmp->bb.hit; - - dest->simd_bb.test += tmp->simd_bb.test; - dest->simd_bb.hit += tmp->simd_bb.hit; - - dest->raycast.test += tmp->raycast.test; - dest->raycast.hit += tmp->raycast.hit; - - dest->rayshadow_last_hit.test += tmp->rayshadow_last_hit.test; - dest->rayshadow_last_hit.hit += tmp->rayshadow_last_hit.hit; - - dest->raytrace_hint.test += tmp->raytrace_hint.test; - dest->raytrace_hint.hit += tmp->raytrace_hint.hit; -} - -#endif diff --git a/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp b/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp deleted file mode 100644 index 103fa3e6034..00000000000 --- a/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp +++ /dev/null @@ -1,531 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2009 Blender Foundation. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): André Pinto. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/render/intern/raytrace/rayobject_rtbuild.cpp - * \ingroup render - */ - - -#include <assert.h> -#include <stdlib.h> -#include <algorithm> - -#if __cplusplus >= 201103L -#include <cmath> -using std::isfinite; -#else -#include <math.h> -#endif - -#include "rayobject_rtbuild.h" - -#include "MEM_guardedalloc.h" - -#include "BLI_math.h" -#include "BLI_utildefines.h" - -static bool selected_node(RTBuilder::Object *node) -{ - return node->selected; -} - -static void rtbuild_init(RTBuilder *b) -{ - b->split_axis = -1; - b->primitives.begin = NULL; - b->primitives.end = NULL; - b->primitives.maxsize = 0; - b->depth = 0; - - for (int i = 0; i < RTBUILD_MAX_CHILDS; i++) - b->child_offset[i] = 0; - - for (int i = 0; i < 3; i++) - b->sorted_begin[i] = b->sorted_end[i] = NULL; - - INIT_MINMAX(b->bb, b->bb + 3); -} - -RTBuilder *rtbuild_create(int size) -{ - RTBuilder *builder = (RTBuilder *) MEM_mallocN(sizeof(RTBuilder), "RTBuilder"); - RTBuilder::Object *memblock = (RTBuilder::Object *)MEM_mallocN(sizeof(RTBuilder::Object) * size, "RTBuilder.objects"); - - - rtbuild_init(builder); - - builder->primitives.begin = builder->primitives.end = memblock; - builder->primitives.maxsize = size; - - for (int i = 0; i < 3; i++) { - builder->sorted_begin[i] = (RTBuilder::Object **)MEM_mallocN(sizeof(RTBuilder::Object *) * size, "RTBuilder.sorted_objects"); - builder->sorted_end[i] = builder->sorted_begin[i]; - } - - - return builder; -} - -void rtbuild_free(RTBuilder *b) -{ - if (b->primitives.begin) MEM_freeN(b->primitives.begin); - - for (int i = 0; i < 3; i++) - if (b->sorted_begin[i]) - MEM_freeN(b->sorted_begin[i]); - - MEM_freeN(b); -} - -void rtbuild_add(RTBuilder *b, RayObject *o) -{ - float bb[6]; - - assert(b->primitives.begin + b->primitives.maxsize != b->primitives.end); - - INIT_MINMAX(bb, bb + 3); - RE_rayobject_merge_bb(o, bb, bb + 3); - - /* skip objects with invalid bounding boxes, nan causes DO_MINMAX - * to do nothing, so we get these invalid values. this shouldn't - * happen usually, but bugs earlier in the pipeline can cause it. */ - if (bb[0] > bb[3] || bb[1] > bb[4] || bb[2] > bb[5]) - return; - /* skip objects with inf bounding boxes */ - if (!isfinite(bb[0]) || !isfinite(bb[1]) || !isfinite(bb[2])) - return; - if (!isfinite(bb[3]) || !isfinite(bb[4]) || !isfinite(bb[5])) - return; - /* skip objects with zero bounding box, they are of no use, and - * will give problems in rtbuild_heuristic_object_split later */ - if (bb[0] == bb[3] && bb[1] == bb[4] && bb[2] == bb[5]) - return; - - copy_v3_v3(b->primitives.end->bb, bb); - copy_v3_v3(b->primitives.end->bb + 3, bb + 3); - b->primitives.end->obj = o; - b->primitives.end->cost = RE_rayobject_cost(o); - - for (int i = 0; i < 3; i++) { - *(b->sorted_end[i]) = b->primitives.end; - b->sorted_end[i]++; - } - b->primitives.end++; -} - -int rtbuild_size(RTBuilder *b) -{ - return b->sorted_end[0] - b->sorted_begin[0]; -} - - -template<class Obj, int Axis> -static bool obj_bb_compare(const Obj &a, const Obj &b) -{ - if (a->bb[Axis] != b->bb[Axis]) - return a->bb[Axis] < b->bb[Axis]; - return a->obj < b->obj; -} - -template<class Item> -static void object_sort(Item *begin, Item *end, int axis) -{ - if (axis == 0) return std::sort(begin, end, obj_bb_compare<Item, 0> ); - if (axis == 1) return std::sort(begin, end, obj_bb_compare<Item, 1> ); - if (axis == 2) return std::sort(begin, end, obj_bb_compare<Item, 2> ); - assert(false); -} - -void rtbuild_done(RTBuilder *b, RayObjectControl *ctrl) -{ - for (int i = 0; i < 3; i++) { - if (b->sorted_begin[i]) { - if (RE_rayobjectcontrol_test_break(ctrl)) break; - object_sort(b->sorted_begin[i], b->sorted_end[i], i); - } - } -} - -RayObject *rtbuild_get_primitive(RTBuilder *b, int index) -{ - return b->sorted_begin[0][index]->obj; -} - -RTBuilder *rtbuild_get_child(RTBuilder *b, int child, RTBuilder *tmp) -{ - rtbuild_init(tmp); - - tmp->depth = b->depth + 1; - - for (int i = 0; i < 3; i++) - if (b->sorted_begin[i]) { - tmp->sorted_begin[i] = b->sorted_begin[i] + b->child_offset[child]; - tmp->sorted_end[i] = b->sorted_begin[i] + b->child_offset[child + 1]; - } - else { - tmp->sorted_begin[i] = NULL; - tmp->sorted_end[i] = NULL; - } - - return tmp; -} - -static void rtbuild_calc_bb(RTBuilder *b) -{ - if (b->bb[0] == 1.0e30f) { - for (RTBuilder::Object **index = b->sorted_begin[0]; index != b->sorted_end[0]; index++) - RE_rayobject_merge_bb( (*index)->obj, b->bb, b->bb + 3); - } -} - -void rtbuild_merge_bb(RTBuilder *b, float min[3], float max[3]) -{ - rtbuild_calc_bb(b); - DO_MIN(b->bb, min); - DO_MAX(b->bb + 3, max); -} - -#if 0 -int rtbuild_get_largest_axis(RTBuilder *b) -{ - rtbuild_calc_bb(b); - return bb_largest_axis(b->bb, b->bb + 3); -} - -//Left balanced tree -int rtbuild_mean_split(RTBuilder *b, int nchilds, int axis) -{ - int i; - int mleafs_per_child, Mleafs_per_child; - int tot_leafs = rtbuild_size(b); - int missing_leafs; - - long long s; - - assert(nchilds <= RTBUILD_MAX_CHILDS); - - //TODO optimize calc of leafs_per_child - for (s = nchilds; s < tot_leafs; s *= nchilds) ; - Mleafs_per_child = s / nchilds; - mleafs_per_child = Mleafs_per_child / nchilds; - - //split min leafs per child - b->child_offset[0] = 0; - for (i = 1; i <= nchilds; i++) - b->child_offset[i] = mleafs_per_child; - - //split remaining leafs - missing_leafs = tot_leafs - mleafs_per_child * nchilds; - for (i = 1; i <= nchilds; i++) - { - if (missing_leafs > Mleafs_per_child - mleafs_per_child) - { - b->child_offset[i] += Mleafs_per_child - mleafs_per_child; - missing_leafs -= Mleafs_per_child - mleafs_per_child; - } - else { - b->child_offset[i] += missing_leafs; - missing_leafs = 0; - break; - } - } - - //adjust for accumulative offsets - for (i = 1; i <= nchilds; i++) - b->child_offset[i] += b->child_offset[i - 1]; - - //Count created childs - for (i = nchilds; b->child_offset[i] == b->child_offset[i - 1]; i--) ; - split_leafs(b, b->child_offset, i, axis); - - assert(b->child_offset[0] == 0 && b->child_offset[i] == tot_leafs); - return i; -} - - -int rtbuild_mean_split_largest_axis(RTBuilder *b, int nchilds) -{ - int axis = rtbuild_get_largest_axis(b); - return rtbuild_mean_split(b, nchilds, axis); -} -#endif - -/* - * "separators" is an array of dim NCHILDS-1 - * and indicates where to cut the childs - */ -#if 0 -int rtbuild_median_split(RTBuilder *b, float *separators, int nchilds, int axis) -{ - int size = rtbuild_size(b); - - assert(nchilds <= RTBUILD_MAX_CHILDS); - if (size <= nchilds) - { - return rtbuild_mean_split(b, nchilds, axis); - } - else { - int i; - - b->split_axis = axis; - - //Calculate child offsets - b->child_offset[0] = 0; - for (i = 0; i < nchilds - 1; i++) - b->child_offset[i + 1] = split_leafs_by_plane(b, b->child_offset[i], size, separators[i]); - b->child_offset[nchilds] = size; - - for (i = 0; i < nchilds; i++) - if (b->child_offset[i + 1] - b->child_offset[i] == size) - return rtbuild_mean_split(b, nchilds, axis); - - return nchilds; - } -} - -int rtbuild_median_split_largest_axis(RTBuilder *b, int nchilds) -{ - int la, i; - float separators[RTBUILD_MAX_CHILDS]; - - rtbuild_calc_bb(b); - - la = bb_largest_axis(b->bb, b->bb + 3); - for (i = 1; i < nchilds; i++) - separators[i - 1] = (b->bb[la + 3] - b->bb[la]) * i / nchilds; - - return rtbuild_median_split(b, separators, nchilds, la); -} -#endif - -//Heuristics Object Splitter - - -struct SweepCost { - float bb[6]; - float cost; -}; - -/* Object Surface Area Heuristic splitter */ -int rtbuild_heuristic_object_split(RTBuilder *b, int nchilds) -{ - int size = rtbuild_size(b); - assert(nchilds == 2); - assert(size > 1); - int baxis = -1, boffset = 0; - - if (size > nchilds) { - if (b->depth > RTBUILD_MAX_SAH_DEPTH) { - // for degenerate cases we avoid running out of stack space - // by simply splitting the children in the middle - b->child_offset[0] = 0; - b->child_offset[1] = (size+1)/2; - b->child_offset[2] = size; - return 2; - } - - float bcost = FLT_MAX; - baxis = -1; - boffset = size / 2; - - SweepCost *sweep = (SweepCost *)MEM_mallocN(sizeof(SweepCost) * size, "RTBuilder.HeuristicSweep"); - - for (int axis = 0; axis < 3; axis++) { - SweepCost sweep_left; - - RTBuilder::Object **obj = b->sorted_begin[axis]; - -// float right_cost = 0; - for (int i = size - 1; i >= 0; i--) { - if (i == size - 1) { - copy_v3_v3(sweep[i].bb, obj[i]->bb); - copy_v3_v3(sweep[i].bb + 3, obj[i]->bb + 3); - sweep[i].cost = obj[i]->cost; - } - else { - sweep[i].bb[0] = min_ff(obj[i]->bb[0], sweep[i + 1].bb[0]); - sweep[i].bb[1] = min_ff(obj[i]->bb[1], sweep[i + 1].bb[1]); - sweep[i].bb[2] = min_ff(obj[i]->bb[2], sweep[i + 1].bb[2]); - sweep[i].bb[3] = max_ff(obj[i]->bb[3], sweep[i + 1].bb[3]); - sweep[i].bb[4] = max_ff(obj[i]->bb[4], sweep[i + 1].bb[4]); - sweep[i].bb[5] = max_ff(obj[i]->bb[5], sweep[i + 1].bb[5]); - sweep[i].cost = obj[i]->cost + sweep[i + 1].cost; - } -// right_cost += obj[i]->cost; - } - - sweep_left.bb[0] = obj[0]->bb[0]; - sweep_left.bb[1] = obj[0]->bb[1]; - sweep_left.bb[2] = obj[0]->bb[2]; - sweep_left.bb[3] = obj[0]->bb[3]; - sweep_left.bb[4] = obj[0]->bb[4]; - sweep_left.bb[5] = obj[0]->bb[5]; - sweep_left.cost = obj[0]->cost; - -// right_cost -= obj[0]->cost; if (right_cost < 0) right_cost = 0; - - for (int i = 1; i < size; i++) { - //Worst case heuristic (cost of each child is linear) - float hcost, left_side, right_side; - - // not using log seems to have no impact on raytracing perf, but - // makes tree construction quicker, left out for now to test (brecht) - // left_side = bb_area(sweep_left.bb, sweep_left.bb + 3) * (sweep_left.cost + logf((float)i)); - // right_side = bb_area(sweep[i].bb, sweep[i].bb + 3) * (sweep[i].cost + logf((float)size - i)); - left_side = bb_area(sweep_left.bb, sweep_left.bb + 3) * (sweep_left.cost); - right_side = bb_area(sweep[i].bb, sweep[i].bb + 3) * (sweep[i].cost); - hcost = left_side + right_side; - - assert(left_side >= 0); - assert(right_side >= 0); - - if (left_side > bcost) break; //No way we can find a better heuristic in this axis - - assert(hcost >= 0); - // this makes sure the tree built is the same whatever is the order of the sorting axis - if (hcost < bcost || (hcost == bcost && axis < baxis)) { - bcost = hcost; - baxis = axis; - boffset = i; - } - DO_MIN(obj[i]->bb, sweep_left.bb); - DO_MAX(obj[i]->bb + 3, sweep_left.bb + 3); - - sweep_left.cost += obj[i]->cost; -// right_cost -= obj[i]->cost; if (right_cost < 0) right_cost = 0; - } - - //assert(baxis >= 0 && baxis < 3); - if (!(baxis >= 0 && baxis < 3)) - baxis = 0; - } - - - MEM_freeN(sweep); - } - else if (size == 2) { - baxis = 0; - boffset = 1; - } - else if (size == 1) { - b->child_offset[0] = 0; - b->child_offset[1] = 1; - return 1; - } - - b->child_offset[0] = 0; - b->child_offset[1] = boffset; - b->child_offset[2] = size; - - - /* Adjust sorted arrays for childs */ - for (int i = 0; i < boffset; i++) b->sorted_begin[baxis][i]->selected = true; - for (int i = boffset; i < size; i++) b->sorted_begin[baxis][i]->selected = false; - for (int i = 0; i < 3; i++) - std::stable_partition(b->sorted_begin[i], b->sorted_end[i], selected_node); - - return nchilds; -} - -/* - * Helper code - * PARTITION code / used on mean-split - * basically this a std::nth_element (like on C++ STL algorithm) - */ -#if 0 -static void split_leafs(RTBuilder *b, int *nth, int partitions, int split_axis) -{ - int i; - b->split_axis = split_axis; - - for (i = 0; i < partitions - 1; i++) - { - assert(nth[i] < nth[i + 1] && nth[i + 1] < nth[partitions]); - - if (split_axis == 0) std::nth_element(b, nth[i], nth[i + 1], nth[partitions], obj_bb_compare<RTBuilder::Object, 0>); - if (split_axis == 1) std::nth_element(b, nth[i], nth[i + 1], nth[partitions], obj_bb_compare<RTBuilder::Object, 1>); - if (split_axis == 2) std::nth_element(b, nth[i], nth[i + 1], nth[partitions], obj_bb_compare<RTBuilder::Object, 2>); - } -} -#endif - -/* - * Bounding Box utils - */ -float bb_volume(const float min[3], const float max[3]) -{ - return (max[0] - min[0]) * (max[1] - min[1]) * (max[2] - min[2]); -} - -float bb_area(const float min[3], const float max[3]) -{ - float sub[3], a; - sub[0] = max[0] - min[0]; - sub[1] = max[1] - min[1]; - sub[2] = max[2] - min[2]; - - a = (sub[0] * sub[1] + sub[0] * sub[2] + sub[1] * sub[2]) * 2.0f; - /* used to have an assert() here on negative results - * however, in this case its likely some overflow or ffast math error. - * so just return 0.0f instead. */ - return a < 0.0f ? 0.0f : a; -} - -int bb_largest_axis(const float min[3], const float max[3]) -{ - float sub[3]; - - sub[0] = max[0] - min[0]; - sub[1] = max[1] - min[1]; - sub[2] = max[2] - min[2]; - if (sub[0] > sub[1]) { - if (sub[0] > sub[2]) - return 0; - else - return 2; - } - else { - if (sub[1] > sub[2]) - return 1; - else - return 2; - } -} - -/* only returns 0 if merging inner and outerbox would create a box larger than outer box */ -int bb_fits_inside(const float outer_min[3], const float outer_max[3], - const float inner_min[3], const float inner_max[3]) -{ - int i; - for (i = 0; i < 3; i++) - if (outer_min[i] > inner_min[i]) return 0; - - for (i = 0; i < 3; i++) - if (outer_max[i] < inner_max[i]) return 0; - - return 1; -} diff --git a/source/blender/render/intern/raytrace/rayobject_rtbuild.h b/source/blender/render/intern/raytrace/rayobject_rtbuild.h deleted file mode 100644 index 061d76e3a3e..00000000000 --- a/source/blender/render/intern/raytrace/rayobject_rtbuild.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2009 Blender Foundation. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): André Pinto. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/render/intern/raytrace/rayobject_rtbuild.h - * \ingroup render - */ - -#ifndef __RAYOBJECT_RTBUILD_H__ -#define __RAYOBJECT_RTBUILD_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "rayobject.h" - - -/* - * Ray Tree Builder - * this structs helps building any type of tree - * it contains several methods to organize/split nodes - * allowing to create a given tree on the fly. - * - * Idea is that other trees BVH, BIH can use this code to - * generate with simple calls, and then convert to the theirs - * specific structure on the fly. - */ -#define RTBUILD_MAX_CHILDS 32 -#define RTBUILD_MAX_SAH_DEPTH 256 - - -typedef struct RTBuilder { - struct Object { - RayObject *obj; - float cost; - float bb[6]; - int selected; - }; - - /* list to all primitives added in this tree */ - struct { - Object *begin, *end; - int maxsize; - } primitives; - - /* sorted list of rayobjects */ - struct Object **sorted_begin[3], **sorted_end[3]; - - /* axis used (if any) on the split method */ - int split_axis; - - /* child partitions calculated during splitting */ - int child_offset[RTBUILD_MAX_CHILDS + 1]; - -// int child_sorted_axis; /* -1 if not sorted */ - - float bb[6]; - - /* current depth */ - int depth; -} RTBuilder; - -/* used during creation */ -RTBuilder *rtbuild_create(int size); -void rtbuild_free(RTBuilder *b); -void rtbuild_add(RTBuilder *b, RayObject *o); -void rtbuild_done(RTBuilder *b, RayObjectControl *c); -void rtbuild_merge_bb(RTBuilder *b, float min[3], float max[3]); -int rtbuild_size(RTBuilder *b); - -RayObject *rtbuild_get_primitive(RTBuilder *b, int offset); - -/* used during tree reorganization */ -RTBuilder *rtbuild_get_child(RTBuilder *b, int child, RTBuilder *tmp); - -/* Calculates child partitions and returns number of efectively needed partitions */ -int rtbuild_get_largest_axis(RTBuilder *b); - -//Object partition -int rtbuild_mean_split(RTBuilder *b, int nchilds, int axis); -int rtbuild_mean_split_largest_axis(RTBuilder *b, int nchilds); - -int rtbuild_heuristic_object_split(RTBuilder *b, int nchilds); - -//Space partition -int rtbuild_median_split(RTBuilder *b, float *separators, int nchilds, int axis); -int rtbuild_median_split_largest_axis(RTBuilder *b, int nchilds); - - -/* bb utils */ -float bb_area(const float min[3], const float max[3]); -float bb_volume(const float min[3], const float max[3]); -int bb_largest_axis(const float min[3], const float max[3]); -int bb_fits_inside(const float outer_min[3], const float outer_max[3], - const float inner_min[3], const float inner_max[3]); - -#ifdef __cplusplus -} -#endif - -#endif /* __RAYOBJECT_RTBUILD_H__ */ diff --git a/source/blender/render/intern/raytrace/rayobject_svbvh.cpp b/source/blender/render/intern/raytrace/rayobject_svbvh.cpp deleted file mode 100644 index eb7dddac06e..00000000000 --- a/source/blender/render/intern/raytrace/rayobject_svbvh.cpp +++ /dev/null @@ -1,192 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2009 Blender Foundation. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): André Pinto. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/render/intern/raytrace/rayobject_svbvh.cpp - * \ingroup render - */ - - -#include "MEM_guardedalloc.h" - -#include "BLI_utildefines.h" - -#include "vbvh.h" -#include "svbvh.h" -#include "reorganize.h" - -#ifdef __SSE__ - -#define DFS_STACK_SIZE 256 - -struct SVBVHTree { - RayObject rayobj; - - SVBVHNode *root; - MemArena *node_arena; - - float cost; - RTBuilder *builder; -}; - -/* - * Cost to test N childs - */ -struct PackCost { - float operator()(int n) - { - return (n / 4) + ((n % 4) > 2 ? 1 : n % 4); - } -}; - - -template<> -void bvh_done<SVBVHTree>(SVBVHTree *obj) -{ - rtbuild_done(obj->builder, &obj->rayobj.control); - - //TODO find a away to exactly calculate the needed memory - MemArena *arena1 = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "svbvh arena"); - BLI_memarena_use_malloc(arena1); - - MemArena *arena2 = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "svbvh arena2"); - BLI_memarena_use_malloc(arena2); - BLI_memarena_use_align(arena2, 16); - - //Build and optimize the tree - if (0) { - VBVHNode *root = BuildBinaryVBVH<VBVHNode>(arena1, &obj->rayobj.control).transform(obj->builder); - - if (RE_rayobjectcontrol_test_break(&obj->rayobj.control)) { - BLI_memarena_free(arena1); - BLI_memarena_free(arena2); - return; - } - - reorganize(root); - remove_useless(root, &root); - bvh_refit(root); - - pushup(root); - pushdown(root); - pushup_simd<VBVHNode, 4>(root); - - obj->root = Reorganize_SVBVH<VBVHNode>(arena2).transform(root); - } - else { - //Finds the optimal packing of this tree using a given cost model - //TODO this uses quite a lot of memory, find ways to reduce memory usage during building - OVBVHNode *root = BuildBinaryVBVH<OVBVHNode>(arena1, &obj->rayobj.control).transform(obj->builder); - - if (RE_rayobjectcontrol_test_break(&obj->rayobj.control)) { - BLI_memarena_free(arena1); - BLI_memarena_free(arena2); - return; - } - - if (root) { - VBVH_optimalPackSIMD<OVBVHNode, PackCost>(PackCost()).transform(root); - obj->root = Reorganize_SVBVH<OVBVHNode>(arena2).transform(root); - } - else - obj->root = NULL; - } - - //Free data - BLI_memarena_free(arena1); - - obj->node_arena = arena2; - obj->cost = 1.0; - - rtbuild_free(obj->builder); - obj->builder = NULL; -} - -template<int StackSize> -static int intersect(SVBVHTree *obj, Isect *isec) -{ - //TODO renable hint support - if (RE_rayobject_isAligned(obj->root)) { - if (isec->mode == RE_RAY_SHADOW) - return svbvh_node_stack_raycast<StackSize, true>(obj->root, isec); - else - return svbvh_node_stack_raycast<StackSize, false>(obj->root, isec); - } - else - return RE_rayobject_intersect( (RayObject *) obj->root, isec); -} - -template<class Tree> -static void bvh_hint_bb(Tree *tree, LCTSHint *hint, float *UNUSED(min), float *UNUSED(max)) -{ - //TODO renable hint support - { - hint->size = 0; - hint->stack[hint->size++] = (RayObject *)tree->root; - } -} -/* the cast to pointer function is needed to workarround gcc bug: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11407 */ -template<class Tree, int STACK_SIZE> -static RayObjectAPI make_api() -{ - static RayObjectAPI api = - { - (RE_rayobject_raycast_callback) ((int (*)(Tree *, Isect *)) & intersect<STACK_SIZE>), - (RE_rayobject_add_callback) ((void (*)(Tree *, RayObject *)) & bvh_add<Tree>), - (RE_rayobject_done_callback) ((void (*)(Tree *)) & bvh_done<Tree>), - (RE_rayobject_free_callback) ((void (*)(Tree *)) & bvh_free<Tree>), - (RE_rayobject_merge_bb_callback)((void (*)(Tree *, float *, float *)) & bvh_bb<Tree>), - (RE_rayobject_cost_callback) ((float (*)(Tree *)) & bvh_cost<Tree>), - (RE_rayobject_hint_bb_callback) ((void (*)(Tree *, LCTSHint *, float *, float *)) & bvh_hint_bb<Tree>) - }; - - return api; -} - -template<class Tree> -static RayObjectAPI *bvh_get_api(int maxstacksize) -{ - static RayObjectAPI bvh_api256 = make_api<Tree, 1024>(); - - if (maxstacksize <= 1024) return &bvh_api256; - assert(maxstacksize <= 256); - return NULL; -} - -RayObject *RE_rayobject_svbvh_create(int size) -{ - return bvh_create_tree<SVBVHTree, DFS_STACK_SIZE>(size); -} - -#else - -RayObject *RE_rayobject_svbvh_create(int UNUSED(size)) -{ - puts("WARNING: SSE disabled at compile time\n"); - return NULL; -} - -#endif diff --git a/source/blender/render/intern/raytrace/rayobject_vbvh.cpp b/source/blender/render/intern/raytrace/rayobject_vbvh.cpp deleted file mode 100644 index dfa5a69b335..00000000000 --- a/source/blender/render/intern/raytrace/rayobject_vbvh.cpp +++ /dev/null @@ -1,206 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2009 Blender Foundation. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): André Pinto. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/render/intern/raytrace/rayobject_vbvh.cpp - * \ingroup render - */ - - -int tot_pushup = 0; -int tot_pushdown = 0; -int tot_hints = 0; - -#include <assert.h> - -#include "MEM_guardedalloc.h" - -#include "BLI_math.h" -#include "BLI_memarena.h" -#include "BLI_utildefines.h" - -#include "BKE_global.h" - -#include "rayintersection.h" -#include "rayobject.h" -#include "rayobject_rtbuild.h" - -#include "reorganize.h" -#include "bvh.h" -#include "vbvh.h" - -#include <queue> -#include <algorithm> - -#define DFS_STACK_SIZE 256 - -struct VBVHTree { - RayObject rayobj; - VBVHNode *root; - MemArena *node_arena; - float cost; - RTBuilder *builder; -}; - -/* - * Cost to test N childs - */ -struct PackCost { - float operator()(int n) - { - return n; - } -}; - -template<> -void bvh_done<VBVHTree>(VBVHTree *obj) -{ - rtbuild_done(obj->builder, &obj->rayobj.control); - - //TODO find a away to exactly calculate the needed memory - MemArena *arena1 = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "vbvh arena"); - BLI_memarena_use_malloc(arena1); - - //Build and optimize the tree - if (1) { - VBVHNode *root = BuildBinaryVBVH<VBVHNode>(arena1, &obj->rayobj.control).transform(obj->builder); - if (RE_rayobjectcontrol_test_break(&obj->rayobj.control)) { - BLI_memarena_free(arena1); - return; - } - - if (root) { - reorganize(root); - remove_useless(root, &root); - bvh_refit(root); - - pushup(root); - pushdown(root); - obj->root = root; - } - else - obj->root = NULL; - } - else { - /* TODO */ -#if 0 - MemArena *arena2 = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "vbvh arena2"); - BLI_memarena_use_malloc(arena2); - - //Finds the optimal packing of this tree using a given cost model - //TODO this uses quite a lot of memory, find ways to reduce memory usage during building - OVBVHNode *root = BuildBinaryVBVH<OVBVHNode>(arena2).transform(obj->builder); - VBVH_optimalPackSIMD<OVBVHNode, PackCost>(PackCost()).transform(root); - obj->root = Reorganize_VBVH<OVBVHNode>(arena1).transform(root); - - BLI_memarena_free(arena2); -#endif - } - - //Cleanup - rtbuild_free(obj->builder); - obj->builder = NULL; - - obj->node_arena = arena1; - obj->cost = 1.0; -} - -template<int StackSize> -static int intersect(VBVHTree *obj, Isect *isec) -{ - //TODO renable hint support - if (RE_rayobject_isAligned(obj->root)) { - if (isec->mode == RE_RAY_SHADOW) - return bvh_node_stack_raycast<VBVHNode, StackSize, false, true>(obj->root, isec); - else - return bvh_node_stack_raycast<VBVHNode, StackSize, false, false>(obj->root, isec); - } - else - return RE_rayobject_intersect( (RayObject *) obj->root, isec); -} - -template<class Tree> -static void bvh_hint_bb(Tree *tree, LCTSHint *hint, float *UNUSED(min), float *UNUSED(max)) -{ - //TODO renable hint support - { - hint->size = 0; - hint->stack[hint->size++] = (RayObject *)tree->root; - } -} - -#if 0 /* UNUSED */ -static void bfree(VBVHTree *tree) -{ - if (tot_pushup + tot_pushdown + tot_hints + tot_moves) { - if (G.debug & G_DEBUG) { - printf("tot pushups: %d\n", tot_pushup); - printf("tot pushdowns: %d\n", tot_pushdown); - printf("tot moves: %d\n", tot_moves); - printf("tot hints created: %d\n", tot_hints); - } - - tot_pushup = 0; - tot_pushdown = 0; - tot_hints = 0; - tot_moves = 0; - } - bvh_free(tree); -} -#endif - -/* the cast to pointer function is needed to workarround gcc bug: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11407 */ -template<class Tree, int STACK_SIZE> -static RayObjectAPI make_api() -{ - static RayObjectAPI api = - { - (RE_rayobject_raycast_callback) ((int (*)(Tree *, Isect *)) & intersect<STACK_SIZE>), - (RE_rayobject_add_callback) ((void (*)(Tree *, RayObject *)) & bvh_add<Tree>), - (RE_rayobject_done_callback) ((void (*)(Tree *)) & bvh_done<Tree>), - (RE_rayobject_free_callback) ((void (*)(Tree *)) & bvh_free<Tree>), - (RE_rayobject_merge_bb_callback)((void (*)(Tree *, float *, float *)) & bvh_bb<Tree>), - (RE_rayobject_cost_callback) ((float (*)(Tree *)) & bvh_cost<Tree>), - (RE_rayobject_hint_bb_callback) ((void (*)(Tree *, LCTSHint *, float *, float *)) & bvh_hint_bb<Tree>) - }; - - return api; -} - -template<class Tree> -RayObjectAPI *bvh_get_api(int maxstacksize) -{ - static RayObjectAPI bvh_api256 = make_api<Tree, 1024>(); - - if (maxstacksize <= 1024) return &bvh_api256; - assert(maxstacksize <= 256); - return 0; -} - -RayObject *RE_rayobject_vbvh_create(int size) -{ - return bvh_create_tree<VBVHTree, DFS_STACK_SIZE>(size); -} diff --git a/source/blender/render/intern/raytrace/reorganize.h b/source/blender/render/intern/raytrace/reorganize.h deleted file mode 100644 index 84d04a8851f..00000000000 --- a/source/blender/render/intern/raytrace/reorganize.h +++ /dev/null @@ -1,513 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2009 Blender Foundation. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): André Pinto. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/render/intern/raytrace/reorganize.h - * \ingroup render - */ - - -#include <float.h> -#include <math.h> -#include <stdio.h> - -#include <algorithm> -#include <queue> -#include <vector> - -#include "BKE_global.h" - -#ifdef _WIN32 -# ifdef INFINITY -# undef INFINITY -# endif -# define INFINITY FLT_MAX // in mingw math.h: (1.0F/0.0F). This generates compile error, though. -#endif - -extern int tot_pushup; -extern int tot_pushdown; - -#if !defined(INFINITY) && defined(HUGE_VAL) -#define INFINITY HUGE_VAL -#endif - -template<class Node> -static bool node_fits_inside(Node *a, Node *b) -{ - return bb_fits_inside(b->bb, b->bb + 3, a->bb, a->bb + 3); -} - -template<class Node> -static void reorganize_find_fittest_parent(Node *tree, Node *node, std::pair<float, Node *> &cost) -{ - std::queue<Node *> q; - q.push(tree); - - while (!q.empty()) { - Node *parent = q.front(); - q.pop(); - - if (parent == node) continue; - if (node_fits_inside(node, parent) && RE_rayobject_isAligned(parent->child) ) { - float pcost = bb_area(parent->bb, parent->bb + 3); - cost = std::min(cost, std::make_pair(pcost, parent) ); - for (Node *child = parent->child; child; child = child->sibling) - q.push(child); - } - } -} - -template<class Node> -static void reorganize(Node *root) -{ - std::queue<Node *> q; - - q.push(root); - while (!q.empty()) { - Node *node = q.front(); - q.pop(); - - if (RE_rayobject_isAligned(node->child)) { - for (Node **prev = &node->child; *prev; ) { - assert(RE_rayobject_isAligned(*prev)); - q.push(*prev); - - std::pair<float, Node *> best(FLT_MAX, root); - reorganize_find_fittest_parent(root, *prev, best); - - if (best.second == node) { - //Already inside the fitnest BB - prev = &(*prev)->sibling; - } - else { - Node *tmp = *prev; - *prev = (*prev)->sibling; - - tmp->sibling = best.second->child; - best.second->child = tmp; - } - - - } - } - if (node != root) { - } - } -} - -/* - * Prunes useless nodes from trees: - * erases nodes with total amount of primitives = 0 - * prunes nodes with only one child (except if that child is a primitive) - */ -template<class Node> -static void remove_useless(Node *node, Node **new_node) -{ - if (RE_rayobject_isAligned(node->child) ) { - - for (Node **prev = &node->child; *prev; ) { - Node *next = (*prev)->sibling; - remove_useless(*prev, prev); - if (*prev == NULL) - *prev = next; - else { - (*prev)->sibling = next; - prev = &((*prev)->sibling); - } - } - } - if (node->child) { - if (RE_rayobject_isAligned(node->child) && node->child->sibling == 0) - *new_node = node->child; - } - else if (node->child == NULL) { - *new_node = NULL; - } -} - -/* - * Minimizes expected number of BBtest by colapsing nodes - * it uses surface area heuristic for determining whether a node should be colapsed - */ -template<class Node> -static void pushup(Node *parent) -{ - if (is_leaf(parent)) return; - - float p_area = bb_area(parent->bb, parent->bb + 3); - Node **prev = &parent->child; - for (Node *child = parent->child; RE_rayobject_isAligned(child) && child; ) { - const float c_area = bb_area(child->bb, child->bb + 3); - const int nchilds = count_childs(child); - float original_cost = ((p_area != 0.0f) ? (c_area / p_area) * nchilds : 1.0f) + 1; - float flatten_cost = nchilds; - if (flatten_cost < original_cost && nchilds >= 2) { - append_sibling(child, child->child); - child = child->sibling; - *prev = child; - -// *prev = child->child; -// append_sibling( *prev, child->sibling ); -// child = *prev; - tot_pushup++; - } - else { - *prev = child; - prev = &(*prev)->sibling; - child = *prev; - } - } - - for (Node *child = parent->child; RE_rayobject_isAligned(child) && child; child = child->sibling) - pushup(child); -} - -/* - * try to optimize number of childs to be a multiple of SSize - */ -template<class Node, int SSize> -static void pushup_simd(Node *parent) -{ - if (is_leaf(parent)) return; - - int n = count_childs(parent); - - Node **prev = &parent->child; - for (Node *child = parent->child; RE_rayobject_isAligned(child) && child; ) { - int cn = count_childs(child); - if (cn - 1 <= (SSize - (n % SSize) ) % SSize && RE_rayobject_isAligned(child->child) ) { - n += (cn - 1); - append_sibling(child, child->child); - child = child->sibling; - *prev = child; - } - else { - *prev = child; - prev = &(*prev)->sibling; - child = *prev; - } - } - - for (Node *child = parent->child; RE_rayobject_isAligned(child) && child; child = child->sibling) - pushup_simd<Node, SSize>(child); -} - - -/* - * Pushdown - * makes sure no child fits inside any of its sibling - */ -template<class Node> -static void pushdown(Node *parent) -{ - Node **s_child = &parent->child; - Node *child = parent->child; - - while (child && RE_rayobject_isAligned(child)) { - Node *next = child->sibling; - Node **next_s_child = &child->sibling; - - //assert(bb_fits_inside(parent->bb, parent->bb+3, child->bb, child->bb+3)); - - for (Node *i = parent->child; RE_rayobject_isAligned(i) && i; i = i->sibling) - if (child != i && bb_fits_inside(i->bb, i->bb + 3, child->bb, child->bb + 3) && RE_rayobject_isAligned(i->child)) { -// todo optimize (should the one with the smallest area?) -// float ia = bb_area(i->bb, i->bb+3) -// if (child->i) - *s_child = child->sibling; - child->sibling = i->child; - i->child = child; - next_s_child = s_child; - - tot_pushdown++; - break; - } - child = next; - s_child = next_s_child; - } - - for (Node *i = parent->child; RE_rayobject_isAligned(i) && i; i = i->sibling) { - pushdown(i); - } -} - - -/* - * BVH refit - * readjust nodes BB (useful if nodes childs where modified) - */ -template<class Node> -static float bvh_refit(Node *node) -{ - if (is_leaf(node)) return 0; - if (is_leaf(node->child)) return 0; - - float total = 0; - - for (Node *child = node->child; child; child = child->sibling) - total += bvh_refit(child); - - float old_area = bb_area(node->bb, node->bb + 3); - INIT_MINMAX(node->bb, node->bb + 3); - for (Node *child = node->child; child; child = child->sibling) { - DO_MIN(child->bb, node->bb); - DO_MAX(child->bb + 3, node->bb + 3); - } - total += old_area - bb_area(node->bb, node->bb + 3); - return total; -} - - -/* - * this finds the best way to packing a tree according to a given test cost function - * with the purpose to reduce the expected cost (eg.: number of BB tests). - */ -#include <vector> -#define MAX_CUT_SIZE 4 /* svbvh assumes max 4 children! */ -#define MAX_OPTIMIZE_CHILDS MAX_CUT_SIZE - -#define CUT_SIZE_IS_VALID(cut_size) ((cut_size) < MAX_CUT_SIZE && (cut_size) >= 0) -#define CUT_SIZE_INVALID -1 - - -struct OVBVHNode { - float bb[6]; - - OVBVHNode *child; - OVBVHNode *sibling; - - /* - * Returns min cost to represent the subtree starting at the given node, - * allowing it to have a given cutsize - */ - float cut_cost[MAX_CUT_SIZE]; - float get_cost(int cutsize) - { - assert(CUT_SIZE_IS_VALID(cutsize - 1)); - return cut_cost[cutsize - 1]; - } - - /* - * This saves the cut size of this child, when parent is reaching - * its minimum cut with the given cut size - */ - int cut_size[MAX_CUT_SIZE]; - int get_cut_size(int parent_cut_size) - { - assert(CUT_SIZE_IS_VALID(parent_cut_size - 1)); - return cut_size[parent_cut_size - 1]; - } - - /* - * Reorganize the node based on calculated cut costs - */ - int best_cutsize; - void set_cut(int cutsize, OVBVHNode ***cut) - { - if (cutsize == 1) { - **cut = this; - *cut = &(**cut)->sibling; - } - else { - if (cutsize > MAX_CUT_SIZE) { - for (OVBVHNode *child = this->child; child && RE_rayobject_isAligned(child); child = child->sibling) { - child->set_cut(1, cut); - cutsize--; - } - assert(cutsize == 0); - } - else { - for (OVBVHNode *child = this->child; child && RE_rayobject_isAligned(child); child = child->sibling) { - child->set_cut(child->get_cut_size(cutsize), cut); - } - } - } - } - - void optimize() - { - if (RE_rayobject_isAligned(this->child)) { - //Calc new childs - if (this->best_cutsize != CUT_SIZE_INVALID) { - OVBVHNode **cut = &(this->child); - set_cut(this->best_cutsize, &cut); - *cut = NULL; - } - - //Optimize new childs - for (OVBVHNode *child = this->child; child && RE_rayobject_isAligned(child); child = child->sibling) - child->optimize(); - } - } -}; - -/* - * Calculates an optimal SIMD packing - * - */ -template<class Node, class TestCost> -struct VBVH_optimalPackSIMD { - TestCost testcost; - - VBVH_optimalPackSIMD(TestCost testcost) - { - this->testcost = testcost; - } - - /* - * calc best cut on a node - */ - struct calc_best { - Node *child[MAX_OPTIMIZE_CHILDS]; - float child_hit_prob[MAX_OPTIMIZE_CHILDS]; - - calc_best(Node *node) - { - int nchilds = 0; - //Fetch childs and needed data - { - float parent_area = bb_area(node->bb, node->bb + 3); - for (Node *child = node->child; child && RE_rayobject_isAligned(child); child = child->sibling) { - this->child[nchilds] = child; - this->child_hit_prob[nchilds] = (parent_area != 0.0f) ? bb_area(child->bb, child->bb + 3) / parent_area : 1.0f; - nchilds++; - } - - assert(nchilds >= 2 && nchilds <= MAX_OPTIMIZE_CHILDS); - } - - - //Build DP table to find minimum cost to represent this node with a given cutsize - int bt[MAX_OPTIMIZE_CHILDS + 1][MAX_CUT_SIZE + 1]; //backtrace table - float cost[MAX_OPTIMIZE_CHILDS + 1][MAX_CUT_SIZE + 1]; //cost table (can be reduced to float[2][MAX_CUT_COST]) - - for (int i = 0; i <= nchilds; i++) { - for (int j = 0; j <= MAX_CUT_SIZE; j++) { - cost[i][j] = INFINITY; - } - } - - cost[0][0] = 0; - - for (int i = 1; i <= nchilds; i++) { - for (int size = i - 1; size /*+(nchilds-i)*/ <= MAX_CUT_SIZE; size++) { - for (int cut = 1; cut + size /*+(nchilds-i)*/ <= MAX_CUT_SIZE; cut++) { - float new_cost = cost[i - 1][size] + child_hit_prob[i - 1] * child[i - 1]->get_cost(cut); - if (new_cost < cost[i][size + cut]) { - cost[i][size + cut] = new_cost; - bt[i][size + cut] = cut; - } - } - } - } - - /* Save the ways to archive the minimum cost with a given cutsize */ - for (int i = nchilds; i <= MAX_CUT_SIZE; i++) { - node->cut_cost[i - 1] = cost[nchilds][i]; - if (cost[nchilds][i] < INFINITY) { - int current_size = i; - for (int j = nchilds; j > 0; j--) { - child[j - 1]->cut_size[i - 1] = bt[j][current_size]; - current_size -= bt[j][current_size]; - } - } - } - } - }; - - void calc_costs(Node *node) - { - - if (RE_rayobject_isAligned(node->child) ) { - int nchilds = 0; - for (Node *child = node->child; child && RE_rayobject_isAligned(child); child = child->sibling) { - calc_costs(child); - nchilds++; - } - - for (int i = 0; i < MAX_CUT_SIZE; i++) - node->cut_cost[i] = INFINITY; - - //We are not allowed to look on nodes with with so many childs - if (nchilds > MAX_CUT_SIZE) { - float cost = 0; - - float parent_area = bb_area(node->bb, node->bb + 3); - for (Node *child = node->child; child && RE_rayobject_isAligned(child); child = child->sibling) { - cost += ((parent_area != 0.0f) ? (bb_area(child->bb, child->bb + 3) / parent_area) : 1.0f) * child->get_cost(1); - } - - cost += testcost(nchilds); - node->cut_cost[0] = cost; - node->best_cutsize = nchilds; - } - else { - calc_best calc(node); - - //calc expected cost if we optimaly pack this node - for (int cutsize = nchilds; cutsize <= MAX_CUT_SIZE; cutsize++) { - float m = node->get_cost(cutsize) + testcost(cutsize); - if (m < node->cut_cost[0]) { - node->cut_cost[0] = m; - node->best_cutsize = cutsize; - } - } - } - - if (node->cut_cost[0] == INFINITY) { - node->best_cutsize = CUT_SIZE_INVALID; - } - } - else { - node->cut_cost[0] = 1.0f; - for (int i = 1; i < MAX_CUT_SIZE; i++) - node->cut_cost[i] = INFINITY; - - /* node->best_cutsize can remain unset here */ - } - } - - Node *transform(Node *node) - { - if (RE_rayobject_isAligned(node->child)) { -#ifdef DEBUG - static int num = 0; - bool first = false; - if (num == 0) { num++; first = true; } -#endif - - calc_costs(node); - -#ifdef DEBUG - if (first && G.debug) { - printf("expected cost = %f (%d)\n", node->cut_cost[0], node->best_cutsize); - } -#endif - node->optimize(); - } - return node; - } -}; diff --git a/source/blender/render/intern/raytrace/svbvh.h b/source/blender/render/intern/raytrace/svbvh.h deleted file mode 100644 index 292b93c445f..00000000000 --- a/source/blender/render/intern/raytrace/svbvh.h +++ /dev/null @@ -1,317 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2009 Blender Foundation. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): André Pinto. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/render/intern/raytrace/svbvh.h - * \ingroup render - */ - -#ifndef __SVBVH_H__ -#define __SVBVH_H__ - -#ifdef __SSE__ - -#include "bvh.h" -#include "BLI_memarena.h" -#include <algorithm> - -struct SVBVHNode { - float child_bb[24]; - SVBVHNode *child[4]; - int nchilds; -}; - -static int svbvh_bb_intersect_test_simd4(const Isect *isec, const __m128 *bb_group) -{ - const __m128 tmin0 = _mm_setzero_ps(); - const __m128 tmax0 = _mm_set_ps1(isec->dist); - - const __m128 start0 = _mm_set_ps1(isec->start[0]); - const __m128 start1 = _mm_set_ps1(isec->start[1]); - const __m128 start2 = _mm_set_ps1(isec->start[2]); - const __m128 sub0 = _mm_sub_ps(bb_group[isec->bv_index[0]], start0); - const __m128 sub1 = _mm_sub_ps(bb_group[isec->bv_index[1]], start0); - const __m128 sub2 = _mm_sub_ps(bb_group[isec->bv_index[2]], start1); - const __m128 sub3 = _mm_sub_ps(bb_group[isec->bv_index[3]], start1); - const __m128 sub4 = _mm_sub_ps(bb_group[isec->bv_index[4]], start2); - const __m128 sub5 = _mm_sub_ps(bb_group[isec->bv_index[5]], start2); - const __m128 idot_axis0 = _mm_set_ps1(isec->idot_axis[0]); - const __m128 idot_axis1 = _mm_set_ps1(isec->idot_axis[1]); - const __m128 idot_axis2 = _mm_set_ps1(isec->idot_axis[2]); - const __m128 mul0 = _mm_mul_ps(sub0, idot_axis0); - const __m128 mul1 = _mm_mul_ps(sub1, idot_axis0); - const __m128 mul2 = _mm_mul_ps(sub2, idot_axis1); - const __m128 mul3 = _mm_mul_ps(sub3, idot_axis1); - const __m128 mul4 = _mm_mul_ps(sub4, idot_axis2); - const __m128 mul5 = _mm_mul_ps(sub5, idot_axis2); - const __m128 tmin1 = _mm_max_ps(tmin0, mul0); - const __m128 tmax1 = _mm_min_ps(tmax0, mul1); - const __m128 tmin2 = _mm_max_ps(tmin1, mul2); - const __m128 tmax2 = _mm_min_ps(tmax1, mul3); - const __m128 tmin3 = _mm_max_ps(tmin2, mul4); - const __m128 tmax3 = _mm_min_ps(tmax2, mul5); - - return _mm_movemask_ps(_mm_cmpge_ps(tmax3, tmin3)); -} - -static int svbvh_bb_intersect_test(const Isect *isec, const float *_bb) -{ - const float *bb = _bb; - - float t1x = (bb[isec->bv_index[0]] - isec->start[0]) * isec->idot_axis[0]; - float t2x = (bb[isec->bv_index[1]] - isec->start[0]) * isec->idot_axis[0]; - float t1y = (bb[isec->bv_index[2]] - isec->start[1]) * isec->idot_axis[1]; - float t2y = (bb[isec->bv_index[3]] - isec->start[1]) * isec->idot_axis[1]; - float t1z = (bb[isec->bv_index[4]] - isec->start[2]) * isec->idot_axis[2]; - float t2z = (bb[isec->bv_index[5]] - isec->start[2]) * isec->idot_axis[2]; - - RE_RC_COUNT(isec->raycounter->bb.test); - - if (t1x > t2y || t2x < t1y || t1x > t2z || t2x < t1z || t1y > t2z || t2y < t1z) return 0; - if (t2x < 0.0f || t2y < 0.0f || t2z < 0.0f) return 0; - if (t1x > isec->dist || t1y > isec->dist || t1z > isec->dist) return 0; - - RE_RC_COUNT(isec->raycounter->bb.hit); - - return 1; -} - -static bool svbvh_node_is_leaf(const SVBVHNode *node) -{ - return !RE_rayobject_isAligned(node); -} - -template<int MAX_STACK_SIZE, bool SHADOW> -static int svbvh_node_stack_raycast(SVBVHNode *root, Isect *isec) -{ - SVBVHNode *stack[MAX_STACK_SIZE], *node; - int hit = 0, stack_pos = 0; - - stack[stack_pos++] = root; - - while (stack_pos) { - node = stack[--stack_pos]; - - if (!svbvh_node_is_leaf(node)) { - int nchilds = node->nchilds; - - if (nchilds == 4) { - float *child_bb = node->child_bb; - int res = svbvh_bb_intersect_test_simd4(isec, ((__m128 *) (child_bb))); - SVBVHNode **child = node->child; - - RE_RC_COUNT(isec->raycounter->simd_bb.test); - - if (res & 1) { stack[stack_pos++] = child[0]; RE_RC_COUNT(isec->raycounter->simd_bb.hit); } - if (res & 2) { stack[stack_pos++] = child[1]; RE_RC_COUNT(isec->raycounter->simd_bb.hit); } - if (res & 4) { stack[stack_pos++] = child[2]; RE_RC_COUNT(isec->raycounter->simd_bb.hit); } - if (res & 8) { stack[stack_pos++] = child[3]; RE_RC_COUNT(isec->raycounter->simd_bb.hit); } - } - else { - float *child_bb = node->child_bb; - SVBVHNode **child = node->child; - int i; - - for (i = 0; i < nchilds; i++) { - if (svbvh_bb_intersect_test(isec, (float *)child_bb + 6 * i)) { - stack[stack_pos++] = child[i]; - } - } - } - } - else { - hit |= RE_rayobject_intersect((RayObject *)node, isec); - if (SHADOW && hit) break; - } - } - - return hit; -} - - -template<> -inline void bvh_node_merge_bb<SVBVHNode>(SVBVHNode *node, float min[3], float max[3]) -{ - if (is_leaf(node)) { - RE_rayobject_merge_bb((RayObject *)node, min, max); - } - else { - int i; - for (i = 0; i + 4 <= node->nchilds; i += 4) { - float *res = node->child_bb + 6 * i; - for (int j = 0; j < 3; j++) { - min[j] = min_ff(min[j], - min_ffff(res[4 * j + 0], - res[4 * j + 1], - res[4 * j + 2], - res[4 * j + 3])); - } - for (int j = 0; j < 3; j++) { - max[j] = max_ff(max[j], - max_ffff(res[4 * (j + 3) + 0], - res[4 * (j + 3) + 1], - res[4 * (j + 3) + 2], - res[4 * (j + 3) + 3])); - } - } - - for (; i < node->nchilds; i++) { - DO_MIN(node->child_bb + 6 * i, min); - DO_MAX(node->child_bb + 3 + 6 * i, max); - } - } -} - - - -/* - * Builds a SVBVH tree form a VBVHTree - */ -template<class OldNode> -struct Reorganize_SVBVH { - MemArena *arena; - - float childs_per_node; - int nodes_with_childs[16]; - int useless_bb; - int nodes; - - Reorganize_SVBVH(MemArena *a) - { - arena = a; - nodes = 0; - childs_per_node = 0; - useless_bb = 0; - - for (int i = 0; i < 16; i++) { - nodes_with_childs[i] = 0; - } - } - - ~Reorganize_SVBVH() - { -#if 0 - { - printf("%f childs per node\n", childs_per_node / nodes); - printf("%d childs BB are useless\n", useless_bb); - for (int i = 0; i < 16; i++) { - printf("%i childs per node: %d/%d = %f\n", i, nodes_with_childs[i], nodes, nodes_with_childs[i] / float(nodes)); - } - } -#endif - } - - SVBVHNode *create_node(int nchilds) - { - SVBVHNode *node = (SVBVHNode *)BLI_memarena_alloc(arena, sizeof(SVBVHNode)); - node->nchilds = nchilds; - - return node; - } - - void copy_bb(float bb[6], const float old_bb[6]) - { - std::copy(old_bb, old_bb + 6, bb); - } - - void prepare_for_simd(SVBVHNode *node) - { - int i = 0; - while (i + 4 <= node->nchilds) { - float vec_tmp[4 * 6]; - float *res = node->child_bb + 6 * i; - std::copy(res, res + 6 * 4, vec_tmp); - - for (int j = 0; j < 6; j++) { - res[4 * j + 0] = vec_tmp[6 * 0 + j]; - res[4 * j + 1] = vec_tmp[6 * 1 + j]; - res[4 * j + 2] = vec_tmp[6 * 2 + j]; - res[4 * j + 3] = vec_tmp[6 * 3 + j]; - } - - i += 4; - } - } - - /* amt must be power of two */ - inline int padup(int num, int amt) - { - return ((num + (amt - 1)) & ~(amt - 1)); - } - - SVBVHNode *transform(OldNode *old) - { - if (is_leaf(old)) - return (SVBVHNode *)old; - if (is_leaf(old->child)) - return (SVBVHNode *)old->child; - - int nchilds = count_childs(old); - int alloc_childs = nchilds; - if (nchilds % 4 > 2) - alloc_childs = padup(nchilds, 4); - - SVBVHNode *node = create_node(alloc_childs); - - childs_per_node += nchilds; - nodes++; - if (nchilds < 16) - nodes_with_childs[nchilds]++; - - useless_bb += alloc_childs - nchilds; - while (alloc_childs > nchilds) { - const static float def_bb[6] = {FLT_MAX, FLT_MAX, FLT_MAX, -FLT_MAX, -FLT_MAX, -FLT_MAX}; - alloc_childs--; - node->child[alloc_childs] = NULL; - copy_bb(node->child_bb + alloc_childs * 6, def_bb); - } - - int i = nchilds; - for (OldNode *o_child = old->child; o_child; o_child = o_child->sibling) { - i--; - node->child[i] = transform(o_child); - if (is_leaf(o_child)) { - float bb[6]; - INIT_MINMAX(bb, bb + 3); - RE_rayobject_merge_bb((RayObject *)o_child, bb, bb + 3); - copy_bb(node->child_bb + i * 6, bb); - break; - } - else { - copy_bb(node->child_bb + i * 6, o_child->bb); - } - } - assert(i == 0); - - prepare_for_simd(node); - - return node; - } -}; - -#endif /* __SSE__ */ - -#endif /* __SVBVH_H__ */ diff --git a/source/blender/render/intern/raytrace/vbvh.h b/source/blender/render/intern/raytrace/vbvh.h deleted file mode 100644 index abccab5fc13..00000000000 --- a/source/blender/render/intern/raytrace/vbvh.h +++ /dev/null @@ -1,238 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2009 Blender Foundation. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): André Pinto. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/render/intern/raytrace/vbvh.h - * \ingroup render - */ - - -#include <assert.h> -#include <algorithm> - -#include "BLI_memarena.h" - -#include "rayobject_rtbuild.h" - -/* - * VBVHNode represents a BVHNode with support for a variable number of childrens - */ -struct VBVHNode { - float bb[6]; - - VBVHNode *child; - VBVHNode *sibling; -}; - - -/* - * Push nodes (used on dfs) - */ -template<class Node> -inline static void bvh_node_push_childs(Node *node, Isect *UNUSED(isec), Node **stack, int &stack_pos) -{ - Node *child = node->child; - - if (is_leaf(child)) { - stack[stack_pos++] = child; - } - else { - while (child) { - /* Skips BB tests on primitives */ -#if 0 - if (is_leaf(child->child)) { - stack[stack_pos++] = child->child; - } - else -#endif - { - stack[stack_pos++] = child; - } - - child = child->sibling; - } - } -} - - -template<class Node> -static int count_childs(Node *parent) -{ - int n = 0; - for (Node *i = parent->child; i; i = i->sibling) { - n++; - if (is_leaf(i)) - break; - } - - return n; -} - - -template<class Node> -static void append_sibling(Node *node, Node *sibling) -{ - while (node->sibling) - node = node->sibling; - - node->sibling = sibling; -} - - -/* - * Builds a binary VBVH from a rtbuild - */ -template<class Node> -struct BuildBinaryVBVH { - MemArena *arena; - RayObjectControl *control; - - void test_break() - { - if (RE_rayobjectcontrol_test_break(control)) - throw "Stop"; - } - - BuildBinaryVBVH(MemArena *a, RayObjectControl *c) - { - arena = a; - control = c; - } - - Node *create_node() - { - Node *node = (Node *)BLI_memarena_alloc(arena, sizeof(Node) ); - assert(RE_rayobject_isAligned(node)); - - node->sibling = NULL; - node->child = NULL; - - return node; - } - - int rtbuild_split(RTBuilder *builder) - { - return ::rtbuild_heuristic_object_split(builder, 2); - } - - Node *transform(RTBuilder *builder) - { - try - { - return _transform(builder); - - } catch (...) - { - } - return NULL; - } - - Node *_transform(RTBuilder *builder) - { - int size = rtbuild_size(builder); - - if (size == 0) { - return NULL; - } - else if (size == 1) { - Node *node = create_node(); - INIT_MINMAX(node->bb, node->bb + 3); - rtbuild_merge_bb(builder, node->bb, node->bb + 3); - node->child = (Node *) rtbuild_get_primitive(builder, 0); - return node; - } - else { - test_break(); - - Node *node = create_node(); - - Node **child = &node->child; - - int nc = rtbuild_split(builder); - INIT_MINMAX(node->bb, node->bb + 3); - - assert(nc == 2); - for (int i = 0; i < nc; i++) { - RTBuilder tmp; - rtbuild_get_child(builder, i, &tmp); - - *child = _transform(&tmp); - DO_MIN((*child)->bb, node->bb); - DO_MAX((*child)->bb + 3, node->bb + 3); - child = &((*child)->sibling); - } - - *child = NULL; - return node; - } - } -}; - -#if 0 -template<class Tree, class OldNode> -struct Reorganize_VBVH { - Tree *tree; - - Reorganize_VBVH(Tree *t) - { - tree = t; - } - - VBVHNode *create_node() - { - VBVHNode *node = (VBVHNode *)BLI_memarena_alloc(tree->node_arena, sizeof(VBVHNode)); - return node; - } - - void copy_bb(VBVHNode *node, OldNode *old) - { - std::copy(old->bb, old->bb + 6, node->bb); - } - - VBVHNode *transform(OldNode *old) - { - if (is_leaf(old)) - return (VBVHNode *)old; - - VBVHNode *node = create_node(); - VBVHNode **child_ptr = &node->child; - node->sibling = 0; - - copy_bb(node, old); - - for (OldNode *o_child = old->child; o_child; o_child = o_child->sibling) - { - VBVHNode *n_child = transform(o_child); - *child_ptr = n_child; - if (is_leaf(n_child)) return node; - child_ptr = &n_child->sibling; - } - *child_ptr = 0; - - return node; - } -}; -#endif diff --git a/source/blender/render/intern/source/bake.c b/source/blender/render/intern/source/bake.c deleted file mode 100644 index 48f5f494e58..00000000000 --- a/source/blender/render/intern/source/bake.c +++ /dev/null @@ -1,1343 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Contributors: 2004/2005/2006 Blender Foundation, full recode - * Contributors: Vertex color baking, Copyright 2011 AutoCRC - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/render/intern/source/bake.c - * \ingroup render - */ - - -/* system includes */ -#include <stdio.h> -#include <string.h> - -/* External modules: */ -#include "MEM_guardedalloc.h" - -#include "BLI_math.h" -#include "BLI_rand.h" -#include "BLI_threads.h" -#include "BLI_utildefines.h" - -#include "DNA_image_types.h" -#include "DNA_material_types.h" -#include "DNA_mesh_types.h" -#include "DNA_meshdata_types.h" - -#include "BKE_customdata.h" -#include "BKE_global.h" -#include "BKE_image.h" -#include "BKE_main.h" -#include "BKE_node.h" -#include "BKE_scene.h" -#include "BKE_library.h" - -#include "IMB_imbuf_types.h" -#include "IMB_imbuf.h" -#include "IMB_colormanagement.h" - -/* local include */ -#include "rayintersection.h" -#include "rayobject.h" -#include "render_types.h" -#include "renderdatabase.h" -#include "shading.h" -#include "zbuf.h" - -#include "PIL_time.h" - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -/* defined in pipeline.c, is hardcopy of active dynamic allocated Render */ -/* only to be used here in this file, it's for speed */ -extern struct Render R; -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - - -/* ************************* bake ************************ */ - - -typedef struct BakeShade { - int thread; - - ShadeSample ssamp; - ObjectInstanceRen *obi; - VlakRen *vlr; - - ZSpan *zspan; - Image *ima; - ImBuf *ibuf; - - int rectx, recty, quad, type, vdone; - bool ready; - - float dir[3]; - Object *actob; - - /* Output: vertex color or image data. If vcol is not NULL, rect and - * rect_float should be NULL. */ - MPoly *mpoly; - MLoop *mloop; - MLoopCol *vcol; - - unsigned int *rect; - float *rect_float; - - /* displacement buffer used for normalization with unknown maximal distance */ - bool use_displacement_buffer; - float *displacement_buffer; - float displacement_min, displacement_max; - - bool use_mask; - char *rect_mask; /* bake pixel mask */ - - float dxco[3], dyco[3]; - - short *do_update; - - struct ColorSpace *rect_colorspace; -} BakeShade; - -static void bake_set_shade_input(ObjectInstanceRen *obi, VlakRen *vlr, ShadeInput *shi, int quad, int UNUSED(isect), int x, int y, float u, float v) -{ - if (quad) - shade_input_set_triangle_i(shi, obi, vlr, 0, 2, 3); - else - shade_input_set_triangle_i(shi, obi, vlr, 0, 1, 2); - - /* cache for shadow */ - shi->samplenr = R.shadowsamplenr[shi->thread]++; - - shi->mask = 0xFFFF; /* all samples */ - - shi->u = -u; - shi->v = -v; - shi->xs = x; - shi->ys = y; - - shade_input_set_uv(shi); - shade_input_set_normals(shi); - - /* no normal flip */ - if (shi->flippednor) - shade_input_flip_normals(shi); - - /* set up view vector to look right at the surface (note that the normal - * is negated in the renderer so it does not need to be done here) */ - shi->view[0] = shi->vn[0]; - shi->view[1] = shi->vn[1]; - shi->view[2] = shi->vn[2]; -} - -static void bake_shade(void *handle, Object *ob, ShadeInput *shi, int UNUSED(quad), int x, int y, float UNUSED(u), float UNUSED(v), float *tvn, float *ttang) -{ - BakeShade *bs = handle; - ShadeSample *ssamp = &bs->ssamp; - ShadeResult shr; - VlakRen *vlr = shi->vlr; - - shade_input_init_material(shi); - - if (bs->type == RE_BAKE_AO) { - ambient_occlusion(shi); - - if (R.r.bake_flag & R_BAKE_NORMALIZE) { - copy_v3_v3(shr.combined, shi->ao); - } - else { - zero_v3(shr.combined); - environment_lighting_apply(shi, &shr); - } - } - else { - if (bs->type == RE_BAKE_SHADOW) /* Why do shadows set the color anyhow?, ignore material color for baking */ - shi->r = shi->g = shi->b = 1.0f; - - shade_input_set_shade_texco(shi); - - /* only do AO for a full bake (and obviously AO bakes) - * AO for light bakes is a leftover and might not be needed */ - if (ELEM(bs->type, RE_BAKE_ALL, RE_BAKE_AO, RE_BAKE_LIGHT)) - shade_samples_do_AO(ssamp); - - if (shi->mat->nodetree && shi->mat->use_nodes) { - ntreeShaderExecTree(shi->mat->nodetree, shi, &shr); - shi->mat = vlr->mat; /* shi->mat is being set in nodetree */ - } - else - shade_material_loop(shi, &shr); - - if (bs->type == RE_BAKE_NORMALS) { - float nor[3]; - - copy_v3_v3(nor, shi->vn); - - if (R.r.bake_normal_space == R_BAKE_SPACE_CAMERA) { - /* pass */ - } - else if (R.r.bake_normal_space == R_BAKE_SPACE_TANGENT) { - float mat[3][3], imat[3][3]; - - /* bitangent */ - if (tvn && ttang) { - copy_v3_v3(mat[0], ttang); - cross_v3_v3v3(mat[1], tvn, ttang); - mul_v3_fl(mat[1], ttang[3]); - copy_v3_v3(mat[2], tvn); - } - else { - copy_v3_v3(mat[0], shi->nmaptang); - cross_v3_v3v3(mat[1], shi->nmapnorm, shi->nmaptang); - mul_v3_fl(mat[1], shi->nmaptang[3]); - copy_v3_v3(mat[2], shi->nmapnorm); - } - - invert_m3_m3(imat, mat); - mul_m3_v3(imat, nor); - } - else if (R.r.bake_normal_space == R_BAKE_SPACE_OBJECT) - mul_mat3_m4_v3(ob->imat_ren, nor); /* ob->imat_ren includes viewinv! */ - else if (R.r.bake_normal_space == R_BAKE_SPACE_WORLD) - mul_mat3_m4_v3(R.viewinv, nor); - - normalize_v3(nor); /* in case object has scaling */ - - /* The invert of the red channel is to make - * the normal map compliant with the outside world. - * It needs to be done because in Blender - * the normal used in the renderer points inward. It is generated - * this way in calc_vertexnormals(). Should this ever change - * this negate must be removed. - * - * there is also a small 1e-5f bias for precision issues. otherwise - * we randomly get 127 or 128 for neutral colors. we choose 128 - * because it is the convention flat color. * */ - shr.combined[0] = (-nor[0]) / 2.0f + 0.5f + 1e-5f; - shr.combined[1] = nor[1] / 2.0f + 0.5f + 1e-5f; - shr.combined[2] = nor[2] / 2.0f + 0.5f + 1e-5f; - } - else if (bs->type == RE_BAKE_TEXTURE) { - copy_v3_v3(shr.combined, &shi->r); - shr.alpha = shi->alpha; - } - else if (bs->type == RE_BAKE_SHADOW) { - copy_v3_v3(shr.combined, shr.shad); - shr.alpha = shi->alpha; - } - else if (bs->type == RE_BAKE_SPEC_COLOR) { - copy_v3_v3(shr.combined, &shi->specr); - shr.alpha = 1.0f; - } - else if (bs->type == RE_BAKE_SPEC_INTENSITY) { - copy_v3_fl(shr.combined, shi->spec); - shr.alpha = 1.0f; - } - else if (bs->type == RE_BAKE_MIRROR_COLOR) { - copy_v3_v3(shr.combined, &shi->mirr); - shr.alpha = 1.0f; - } - else if (bs->type == RE_BAKE_MIRROR_INTENSITY) { - copy_v3_fl(shr.combined, shi->ray_mirror); - shr.alpha = 1.0f; - } - else if (bs->type == RE_BAKE_ALPHA) { - copy_v3_fl(shr.combined, shi->alpha); - shr.alpha = 1.0f; - } - else if (bs->type == RE_BAKE_EMIT) { - copy_v3_fl(shr.combined, shi->emit); - shr.alpha = 1.0f; - } - else if (bs->type == RE_BAKE_VERTEX_COLORS) { - copy_v3_v3(shr.combined, shi->vcol); - shr.alpha = shi->vcol[3]; - } - } - - if (bs->rect_float && !bs->vcol) { - float *col = bs->rect_float + 4 * (bs->rectx * y + x); - copy_v3_v3(col, shr.combined); - if (bs->type == RE_BAKE_ALL || bs->type == RE_BAKE_TEXTURE || bs->type == RE_BAKE_VERTEX_COLORS) { - col[3] = shr.alpha; - } - else { - col[3] = 1.0; - } - } - else { - /* Target is char (LDR). */ - unsigned char col[4]; - - if (ELEM(bs->type, RE_BAKE_ALL, RE_BAKE_TEXTURE)) { - float rgb[3]; - - copy_v3_v3(rgb, shr.combined); - if (R.scene_color_manage) { - /* Vertex colors have no way to specify color space, so they - * default to sRGB. */ - if (!bs->vcol) - IMB_colormanagement_scene_linear_to_colorspace_v3(rgb, bs->rect_colorspace); - else - linearrgb_to_srgb_v3_v3(rgb, rgb); - } - rgb_float_to_uchar(col, rgb); - } - else { - rgb_float_to_uchar(col, shr.combined); - } - - if (ELEM(bs->type, RE_BAKE_ALL, RE_BAKE_TEXTURE, RE_BAKE_VERTEX_COLORS)) { - col[3] = FTOCHAR(shr.alpha); - } - else { - col[3] = 255; - } - - if (bs->vcol) { - /* Vertex color baking. Vcol has no useful alpha channel (it exists - * but is used only for vertex painting). */ - bs->vcol->r = col[0]; - bs->vcol->g = col[1]; - bs->vcol->b = col[2]; - } - else { - unsigned char *imcol = (unsigned char *)(bs->rect + bs->rectx * y + x); - copy_v4_v4_uchar(imcol, col); - } - - } - - if (bs->rect_mask) { - bs->rect_mask[bs->rectx * y + x] = FILTER_MASK_USED; - } - - if (bs->do_update) { - *bs->do_update = true; - } -} - -static void bake_displacement(void *handle, ShadeInput *UNUSED(shi), float dist, int x, int y) -{ - BakeShade *bs = handle; - float disp; - - if (R.r.bake_flag & R_BAKE_NORMALIZE) { - if (R.r.bake_maxdist) - disp = (dist + R.r.bake_maxdist) / (R.r.bake_maxdist * 2); /* alter the range from [-bake_maxdist, bake_maxdist] to [0, 1]*/ - else - disp = dist; - } - else { - disp = 0.5f + dist; /* alter the range from [-0.5,0.5] to [0,1]*/ - } - - if (bs->displacement_buffer) { - float *displacement = bs->displacement_buffer + (bs->rectx * y + x); - *displacement = disp; - bs->displacement_min = min_ff(bs->displacement_min, disp); - bs->displacement_max = max_ff(bs->displacement_max, disp); - } - - if (bs->rect_float && !bs->vcol) { - float *col = bs->rect_float + 4 * (bs->rectx * y + x); - col[0] = col[1] = col[2] = disp; - col[3] = 1.0f; - } - else { - /* Target is char (LDR). */ - unsigned char col[4]; - col[0] = col[1] = col[2] = FTOCHAR(disp); - col[3] = 255; - - if (bs->vcol) { - /* Vertex color baking. Vcol has no useful alpha channel (it exists - * but is used only for vertex painting). */ - bs->vcol->r = col[0]; - bs->vcol->g = col[1]; - bs->vcol->b = col[2]; - } - else { - unsigned char *imcol = (unsigned char *)(bs->rect + bs->rectx * y + x); - copy_v4_v4_uchar(imcol, col); - } - } - if (bs->rect_mask) { - bs->rect_mask[bs->rectx * y + x] = FILTER_MASK_USED; - } -} - -static int bake_intersect_tree(RayObject *raytree, Isect *isect, float *start, float *dir, float sign, float *hitco, float *dist) -{ - float maxdist; - int hit; - - /* might be useful to make a user setting for maxsize*/ - if (R.r.bake_maxdist > 0.0f) - maxdist = R.r.bake_maxdist; - else - maxdist = RE_RAYTRACE_MAXDIST + R.r.bake_biasdist; - - /* 'dir' is always normalized */ - madd_v3_v3v3fl(isect->start, start, dir, -R.r.bake_biasdist); - - mul_v3_v3fl(isect->dir, dir, sign); - - isect->dist = maxdist; - - hit = RE_rayobject_raycast(raytree, isect); - if (hit) { - madd_v3_v3v3fl(hitco, isect->start, isect->dir, isect->dist); - - *dist = isect->dist; - } - - return hit; -} - -static void bake_set_vlr_dxyco(BakeShade *bs, float *uv1, float *uv2, float *uv3) -{ - VlakRen *vlr = bs->vlr; - float A, d1, d2, d3, *v1, *v2, *v3; - - if (bs->quad) { - v1 = vlr->v1->co; - v2 = vlr->v3->co; - v3 = vlr->v4->co; - } - else { - v1 = vlr->v1->co; - v2 = vlr->v2->co; - v3 = vlr->v3->co; - } - - /* formula derived from barycentric coordinates: - * (uvArea1*v1 + uvArea2*v2 + uvArea3*v3)/uvArea - * then taking u and v partial derivatives to get dxco and dyco */ - A = (uv2[0] - uv1[0]) * (uv3[1] - uv1[1]) - (uv3[0] - uv1[0]) * (uv2[1] - uv1[1]); - - if (fabsf(A) > FLT_EPSILON) { - A = 0.5f / A; - - d1 = uv2[1] - uv3[1]; - d2 = uv3[1] - uv1[1]; - d3 = uv1[1] - uv2[1]; - bs->dxco[0] = (v1[0] * d1 + v2[0] * d2 + v3[0] * d3) * A; - bs->dxco[1] = (v1[1] * d1 + v2[1] * d2 + v3[1] * d3) * A; - bs->dxco[2] = (v1[2] * d1 + v2[2] * d2 + v3[2] * d3) * A; - - d1 = uv3[0] - uv2[0]; - d2 = uv1[0] - uv3[0]; - d3 = uv2[0] - uv1[0]; - bs->dyco[0] = (v1[0] * d1 + v2[0] * d2 + v3[0] * d3) * A; - bs->dyco[1] = (v1[1] * d1 + v2[1] * d2 + v3[1] * d3) * A; - bs->dyco[2] = (v1[2] * d1 + v2[2] * d2 + v3[2] * d3) * A; - } - else { - bs->dxco[0] = bs->dxco[1] = bs->dxco[2] = 0.0f; - bs->dyco[0] = bs->dyco[1] = bs->dyco[2] = 0.0f; - } - - if (bs->obi->flag & R_TRANSFORMED) { - mul_m3_v3(bs->obi->nmat, bs->dxco); - mul_m3_v3(bs->obi->nmat, bs->dyco); - } -} - -static void do_bake_shade(void *handle, int x, int y, float u, float v) -{ - BakeShade *bs = handle; - VlakRen *vlr = bs->vlr; - ObjectInstanceRen *obi = bs->obi; - Object *ob = obi->obr->ob; - float l, *v1, *v2, *v3, tvn[3], ttang[4]; - int quad; - ShadeSample *ssamp = &bs->ssamp; - ShadeInput *shi = ssamp->shi; - - /* fast threadsafe break test */ - if (R.test_break(R.tbh)) - return; - - /* setup render coordinates */ - if (bs->quad) { - v1 = vlr->v1->co; - v2 = vlr->v3->co; - v3 = vlr->v4->co; - } - else { - v1 = vlr->v1->co; - v2 = vlr->v2->co; - v3 = vlr->v3->co; - } - - l = 1.0f - u - v; - - /* shrink barycentric coordinates inwards slightly to avoid some issues - * where baking selected to active might just miss the other face at the - * near the edge of a face */ - if (bs->actob) { - const float eps = 1.0f - 1e-4f; - float invsum; - - u = (u - 0.5f) * eps + 0.5f; - v = (v - 0.5f) * eps + 0.5f; - l = (l - 0.5f) * eps + 0.5f; - - invsum = 1.0f / (u + v + l); - - u *= invsum; - v *= invsum; - l *= invsum; - } - - /* renderco */ - shi->co[0] = l * v3[0] + u * v1[0] + v * v2[0]; - shi->co[1] = l * v3[1] + u * v1[1] + v * v2[1]; - shi->co[2] = l * v3[2] + u * v1[2] + v * v2[2]; - - /* avoid self shadow with vertex bake from adjacent faces [#33729] */ - if ((bs->vcol != NULL) && (bs->actob == NULL)) { - madd_v3_v3fl(shi->co, vlr->n, 0.0001f); - } - - if (obi->flag & R_TRANSFORMED) - mul_m4_v3(obi->mat, shi->co); - - copy_v3_v3(shi->dxco, bs->dxco); - copy_v3_v3(shi->dyco, bs->dyco); - - quad = bs->quad; - bake_set_shade_input(obi, vlr, shi, quad, 0, x, y, u, v); - - if (bs->type == RE_BAKE_NORMALS && R.r.bake_normal_space == R_BAKE_SPACE_TANGENT) { - shade_input_set_shade_texco(shi); - copy_v3_v3(tvn, shi->nmapnorm); - copy_v4_v4(ttang, shi->nmaptang); - } - - /* if we are doing selected to active baking, find point on other face */ - if (bs->actob) { - Isect isec, minisec; - float co[3], minco[3], dist, mindist = 0.0f; - int hit, sign, dir = 1; - - /* intersect with ray going forward and backward*/ - hit = 0; - memset(&minisec, 0, sizeof(minisec)); - minco[0] = minco[1] = minco[2] = 0.0f; - - copy_v3_v3(bs->dir, shi->vn); - - for (sign = -1; sign <= 1; sign += 2) { - memset(&isec, 0, sizeof(isec)); - isec.mode = RE_RAY_MIRROR; - - isec.orig.ob = obi; - isec.orig.face = vlr; - isec.userdata = bs->actob; - isec.check = RE_CHECK_VLR_BAKE; - isec.skip = RE_SKIP_VLR_NEIGHBOUR; - - if (bake_intersect_tree(R.raytree, &isec, shi->co, shi->vn, sign, co, &dist)) { - if (!hit || len_squared_v3v3(shi->co, co) < len_squared_v3v3(shi->co, minco)) { - minisec = isec; - mindist = dist; - copy_v3_v3(minco, co); - hit = 1; - dir = sign; - } - } - } - - if (ELEM(bs->type, RE_BAKE_DISPLACEMENT, RE_BAKE_DERIVATIVE)) { - if (hit) - bake_displacement(handle, shi, (dir == -1) ? mindist : -mindist, x, y); - else - bake_displacement(handle, shi, 0.0f, x, y); - return; - } - - /* if hit, we shade from the new point, otherwise from point one starting face */ - if (hit) { - obi = (ObjectInstanceRen *)minisec.hit.ob; - vlr = (VlakRen *)minisec.hit.face; - quad = (minisec.isect == 2); - copy_v3_v3(shi->co, minco); - - u = -minisec.u; - v = -minisec.v; - bake_set_shade_input(obi, vlr, shi, quad, 1, x, y, u, v); - } - } - - if (bs->type == RE_BAKE_NORMALS && R.r.bake_normal_space == R_BAKE_SPACE_TANGENT) - bake_shade(handle, ob, shi, quad, x, y, u, v, tvn, ttang); - else - bake_shade(handle, ob, shi, quad, x, y, u, v, NULL, NULL); -} - -static int get_next_bake_face(BakeShade *bs) -{ - ObjectRen *obr; - VlakRen *vlr; - MTFace *tface; - static int v = 0, vdone = false; - static ObjectInstanceRen *obi = NULL; - - if (bs == NULL) { - vlr = NULL; - v = vdone = false; - obi = R.instancetable.first; - return 0; - } - - BLI_thread_lock(LOCK_CUSTOM1); - - for (; obi; obi = obi->next, v = 0) { - obr = obi->obr; - - /* only allow non instances here */ - if (obr->flag & R_INSTANCEABLE) - continue; - - for (; v < obr->totvlak; v++) { - vlr = RE_findOrAddVlak(obr, v); - - if ((bs->actob && bs->actob == obr->ob) || (!bs->actob && (obr->ob->flag & SELECT))) { - if (R.r.bake_flag & R_BAKE_VCOL) { - /* Gather face data for vertex color bake */ - Mesh *me; - int *origindex, vcollayer; - CustomDataLayer *cdl; - - if (obr->ob->type != OB_MESH) - continue; - me = obr->ob->data; - - origindex = RE_vlakren_get_origindex(obr, vlr, 0); - if (origindex == NULL) - continue; - if (*origindex >= me->totpoly) { - /* Small hack for Array modifier, which gives false - * original indices - z0r */ - continue; - } -#if 0 - /* Only shade selected faces. */ - if ((me->mface[*origindex].flag & ME_FACE_SEL) == 0) - continue; -#endif - - vcollayer = CustomData_get_render_layer_index(&me->ldata, CD_MLOOPCOL); - if (vcollayer == -1) - continue; - - cdl = &me->ldata.layers[vcollayer]; - bs->mpoly = me->mpoly + *origindex; - bs->vcol = ((MLoopCol *)cdl->data) + bs->mpoly->loopstart; - bs->mloop = me->mloop + bs->mpoly->loopstart; - - /* Tag mesh for reevaluation. */ - me->id.tag |= LIB_TAG_DOIT; - } - else { - Image *ima = NULL; - ImBuf *ibuf = NULL; - const float vec_alpha[4] = {0.0f, 0.0f, 0.0f, 0.0f}; - const float vec_solid[4] = {0.0f, 0.0f, 0.0f, 1.0f}; - const float nor_alpha[4] = {0.5f, 0.5f, 1.0f, 0.0f}; - const float nor_solid[4] = {0.5f, 0.5f, 1.0f, 1.0f}; - const float disp_alpha[4] = {0.5f, 0.5f, 0.5f, 0.0f}; - const float disp_solid[4] = {0.5f, 0.5f, 0.5f, 1.0f}; - - tface = RE_vlakren_get_tface(obr, vlr, obr->bakemtface, NULL, 0); - /* should use 'BKE_object_material_edit_image_get' but in this case simpler not to */ - ima = vlr->mat ? vlr->mat->edit_image : NULL; - - if (!tface || !ima) - continue; - - ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL); - - if (ibuf == NULL) - continue; - - if (ibuf->rect == NULL && ibuf->rect_float == NULL) { - BKE_image_release_ibuf(ima, ibuf, NULL); - continue; - } - - if (ibuf->rect_float && !(ibuf->channels == 0 || ibuf->channels == 4)) { - BKE_image_release_ibuf(ima, ibuf, NULL); - continue; - } - - if (ima->flag & IMA_USED_FOR_RENDER) { - ima->id.tag &= ~LIB_TAG_DOIT; - BKE_image_release_ibuf(ima, ibuf, NULL); - continue; - } - - /* find the image for the first time? */ - if (ima->id.tag & LIB_TAG_DOIT) { - ima->id.tag &= ~LIB_TAG_DOIT; - - /* we either fill in float or char, this ensures things go fine */ - if (ibuf->rect_float) - imb_freerectImBuf(ibuf); - /* clear image */ - if (R.r.bake_flag & R_BAKE_CLEAR) { - if (R.r.bake_mode == RE_BAKE_NORMALS && R.r.bake_normal_space == R_BAKE_SPACE_TANGENT) - IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? nor_alpha : nor_solid); - else if (ELEM(R.r.bake_mode, RE_BAKE_DISPLACEMENT, RE_BAKE_DERIVATIVE)) - IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? disp_alpha : disp_solid); - else - IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? vec_alpha : vec_solid); - } - /* might be read by UI to set active image for display */ - R.bakebuf = ima; - } - - /* Tag image for redraw. */ - ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID; - BKE_image_release_ibuf(ima, ibuf, NULL); - } - - bs->obi = obi; - bs->vlr = vlr; - bs->vdone++; /* only for error message if nothing was rendered */ - v++; - BLI_thread_unlock(LOCK_CUSTOM1); - return 1; - } - } - } - - BLI_thread_unlock(LOCK_CUSTOM1); - return 0; -} - -static void bake_single_vertex(BakeShade *bs, VertRen *vert, float u, float v) -{ - int *origindex, i; - MLoopCol *basevcol; - MLoop *mloop; - - /* per vertex fixed seed */ - BLI_thread_srandom(bs->thread, vert->index); - - origindex = RE_vertren_get_origindex(bs->obi->obr, vert, 0); - if (!origindex || *origindex == ORIGINDEX_NONE) - return; - - /* Search for matching vertex index and apply shading. */ - for (i = 0; i < bs->mpoly->totloop; i++) { - mloop = bs->mloop + i; - if (mloop->v != *origindex) - continue; - basevcol = bs->vcol; - bs->vcol = basevcol + i; - do_bake_shade(bs, 0, 0, u, v); - bs->vcol = basevcol; - break; - } -} - -/* Bake all vertices of a face. Actually, this still works on a face-by-face - * basis, and each vertex on each face is shaded. Vertex colors are a property - * of loops, not vertices. */ -static void shade_verts(BakeShade *bs) -{ - VlakRen *vlr = bs->vlr; - - /* Disable baking to image; write to vcol instead. vcol pointer is set in - * bake_single_vertex. */ - bs->ima = NULL; - bs->rect = NULL; - bs->rect_float = NULL; - bs->displacement_buffer = NULL; - bs->displacement_min = FLT_MAX; - bs->displacement_max = -FLT_MAX; - - bs->quad = 0; - - /* No anti-aliasing for vertices. */ - zero_v3(bs->dxco); - zero_v3(bs->dyco); - - /* Shade each vertex of the face. u and v are barycentric coordinates; since - * we're only interested in vertices, these will be 0 or 1. */ - if ((vlr->flag & R_FACE_SPLIT) == 0) { - /* Processing triangle face, whole quad, or first half of split quad. */ - - bake_single_vertex(bs, bs->vlr->v1, 1.0f, 0.0f); - bake_single_vertex(bs, bs->vlr->v2, 0.0f, 1.0f); - bake_single_vertex(bs, bs->vlr->v3, 0.0f, 0.0f); - - if (vlr->v4) { - bs->quad = 1; - bake_single_vertex(bs, bs->vlr->v4, 0.0f, 0.0f); - } - } - else { - /* Processing second half of split quad. Only one vertex to go. */ - if (vlr->flag & R_DIVIDE_24) { - bake_single_vertex(bs, bs->vlr->v2, 0.0f, 1.0f); - } - else { - bake_single_vertex(bs, bs->vlr->v3, 0.0f, 0.0f); - } - } -} - -/* already have tested for tface and ima and zspan */ -static void shade_tface(BakeShade *bs) -{ - VlakRen *vlr = bs->vlr; - ObjectInstanceRen *obi = bs->obi; - ObjectRen *obr = obi->obr; - MTFace *tface = RE_vlakren_get_tface(obr, vlr, obr->bakemtface, NULL, 0); - Image *ima = vlr->mat->edit_image; - float vec[4][2]; - int a, i1, i2, i3; - - /* per face fixed seed */ - BLI_thread_srandom(bs->thread, vlr->index); - - /* check valid zspan */ - if (ima != bs->ima) { - BKE_image_release_ibuf(bs->ima, bs->ibuf, NULL); - - bs->ima = ima; - bs->ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL); - /* note, these calls only free/fill contents of zspan struct, not zspan itself */ - zbuf_free_span(bs->zspan); - zbuf_alloc_span(bs->zspan, bs->ibuf->x, bs->ibuf->y, R.clipcrop); - } - - bs->rectx = bs->ibuf->x; - bs->recty = bs->ibuf->y; - bs->rect = bs->ibuf->rect; - bs->rect_colorspace = bs->ibuf->rect_colorspace; - bs->rect_float = bs->ibuf->rect_float; - bs->vcol = NULL; - bs->quad = 0; - bs->rect_mask = NULL; - bs->displacement_buffer = NULL; - - if (bs->use_mask || bs->use_displacement_buffer) { - BakeImBufuserData *userdata = bs->ibuf->userdata; - if (userdata == NULL) { - BLI_thread_lock(LOCK_CUSTOM1); - userdata = bs->ibuf->userdata; - if (userdata == NULL) /* since the thread was locked, its possible another thread alloced the value */ - userdata = MEM_callocN(sizeof(BakeImBufuserData), "BakeImBufuserData"); - - if (bs->use_mask) { - if (userdata->mask_buffer == NULL) { - userdata->mask_buffer = MEM_callocN(sizeof(char) * bs->rectx * bs->recty, "BakeMask"); - } - } - - if (bs->use_displacement_buffer) { - if (userdata->displacement_buffer == NULL) { - userdata->displacement_buffer = MEM_callocN(sizeof(float) * bs->rectx * bs->recty, "BakeDisp"); - } - } - - bs->ibuf->userdata = userdata; - - BLI_thread_unlock(LOCK_CUSTOM1); - } - - bs->rect_mask = userdata->mask_buffer; - bs->displacement_buffer = userdata->displacement_buffer; - } - - /* get pixel level vertex coordinates */ - for (a = 0; a < 4; a++) { - /* Note, workaround for pixel aligned UVs which are common and can screw up our intersection tests - * where a pixel gets in between 2 faces or the middle of a quad, - * camera aligned quads also have this problem but they are less common. - * Add a small offset to the UVs, fixes bug #18685 - Campbell */ - vec[a][0] = tface->uv[a][0] * (float)bs->rectx - (0.5f + 0.001f); - vec[a][1] = tface->uv[a][1] * (float)bs->recty - (0.5f + 0.002f); - } - - /* UV indices have to be corrected for possible quad->tria splits */ - i1 = 0; i2 = 1; i3 = 2; - vlr_set_uv_indices(vlr, &i1, &i2, &i3); - bake_set_vlr_dxyco(bs, vec[i1], vec[i2], vec[i3]); - zspan_scanconvert(bs->zspan, bs, vec[i1], vec[i2], vec[i3], do_bake_shade); - - if (vlr->v4) { - bs->quad = 1; - bake_set_vlr_dxyco(bs, vec[0], vec[2], vec[3]); - zspan_scanconvert(bs->zspan, bs, vec[0], vec[2], vec[3], do_bake_shade); - } -} - -static void *do_bake_thread(void *bs_v) -{ - BakeShade *bs = bs_v; - - while (get_next_bake_face(bs)) { - if (R.r.bake_flag & R_BAKE_VCOL) { - shade_verts(bs); - } - else { - shade_tface(bs); - } - - /* fast threadsafe break test */ - if (R.test_break(R.tbh)) - break; - - /* access is not threadsafe but since its just true/false probably ok - * only used for interactive baking */ - if (bs->do_update) { - *bs->do_update = true; - } - } - bs->ready = true; - - BKE_image_release_ibuf(bs->ima, bs->ibuf, NULL); - - return NULL; -} - -void RE_bake_ibuf_filter(ImBuf *ibuf, char *mask, const int filter) -{ - /* must check before filtering */ - const bool is_new_alpha = (ibuf->planes != R_IMF_PLANES_RGBA) && BKE_imbuf_alpha_test(ibuf); - - /* Margin */ - if (filter) { - IMB_filter_extend(ibuf, mask, filter); - } - - /* if the bake results in new alpha then change the image setting */ - if (is_new_alpha) { - ibuf->planes = R_IMF_PLANES_RGBA; - } - else { - if (filter && ibuf->planes != R_IMF_PLANES_RGBA) { - /* clear alpha added by filtering */ - IMB_rectfill_alpha(ibuf, 1.0f); - } - } -} - -void RE_bake_ibuf_normalize_displacement(ImBuf *ibuf, float *displacement, char *mask, float displacement_min, float displacement_max) -{ - int i; - const float *current_displacement = displacement; - const char *current_mask = mask; - float max_distance; - - max_distance = max_ff(fabsf(displacement_min), fabsf(displacement_max)); - - for (i = 0; i < ibuf->x * ibuf->y; i++) { - if (*current_mask == FILTER_MASK_USED) { - float normalized_displacement; - - if (max_distance > 1e-5f) - normalized_displacement = (*current_displacement + max_distance) / (max_distance * 2); - else - normalized_displacement = 0.5f; - - if (ibuf->rect_float) { - /* currently baking happens to RGBA only */ - float *fp = ibuf->rect_float + i * 4; - fp[0] = fp[1] = fp[2] = normalized_displacement; - fp[3] = 1.0f; - } - - if (ibuf->rect) { - unsigned char *cp = (unsigned char *) (ibuf->rect + i); - cp[0] = cp[1] = cp[2] = FTOCHAR(normalized_displacement); - cp[3] = 255; - } - } - - current_displacement++; - current_mask++; - } -} - -/* using object selection tags, the faces with UV maps get baked */ -/* render should have been setup */ -/* returns 0 if nothing was handled */ -int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_update, float *progress) -{ - BakeShade *handles; - ListBase threads; - Image *ima; - int a, vdone = false, result = BAKE_RESULT_OK; - bool use_mask = false; - bool use_displacement_buffer = false; - bool do_manage = false; - - if (ELEM(type, RE_BAKE_ALL, RE_BAKE_TEXTURE)) { - do_manage = BKE_scene_check_color_management_enabled(re->scene); - } - - re->scene_color_manage = BKE_scene_check_color_management_enabled(re->scene); - - /* initialize render global */ - R = *re; - R.bakebuf = NULL; - - /* initialize static vars */ - get_next_bake_face(NULL); - - /* do we need a mask? */ - if (re->r.bake_filter) - use_mask = true; - - /* do we need buffer to store displacements */ - if (ELEM(type, RE_BAKE_DISPLACEMENT, RE_BAKE_DERIVATIVE)) { - if (((R.r.bake_flag & R_BAKE_NORMALIZE) && R.r.bake_maxdist == 0.0f) || - (type == RE_BAKE_DERIVATIVE)) - { - use_displacement_buffer = true; - use_mask = true; - } - } - - /* baker uses this flag to detect if image was initialized */ - if ((R.r.bake_flag & R_BAKE_VCOL) == 0) { - for (ima = G.main->image.first; ima; ima = ima->id.next) { - ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL); - ima->id.tag |= LIB_TAG_DOIT; - ima->flag &= ~IMA_USED_FOR_RENDER; - if (ibuf) { - ibuf->userdata = NULL; /* use for masking if needed */ - } - BKE_image_release_ibuf(ima, ibuf, NULL); - } - } - - if (R.r.bake_flag & R_BAKE_VCOL) { - /* untag all meshes */ - BKE_main_id_tag_listbase(&G.main->mesh, LIB_TAG_DOIT, false); - } - - BLI_threadpool_init(&threads, do_bake_thread, re->r.threads); - - handles = MEM_callocN(sizeof(BakeShade) * re->r.threads, "BakeShade"); - - /* get the threads running */ - for (a = 0; a < re->r.threads; a++) { - handles[a].thread = a; - - /* set defaults in handles */ - handles[a].ssamp.shi[0].lay = re->lay; - - if (type == RE_BAKE_SHADOW) { - handles[a].ssamp.shi[0].passflag = SCE_PASS_SHADOW; - } - else { - handles[a].ssamp.shi[0].passflag = SCE_PASS_COMBINED; - } - handles[a].ssamp.shi[0].combinedflag = ~(SCE_PASS_SPEC); - handles[a].ssamp.shi[0].thread = a; - handles[a].ssamp.shi[0].do_manage = do_manage; - handles[a].ssamp.tot = 1; - - handles[a].type = type; - handles[a].actob = actob; - if (R.r.bake_flag & R_BAKE_VCOL) - handles[a].zspan = NULL; - else - handles[a].zspan = MEM_callocN(sizeof(ZSpan), "zspan for bake"); - - handles[a].use_mask = use_mask; - handles[a].use_displacement_buffer = use_displacement_buffer; - - handles[a].do_update = do_update; /* use to tell the view to update */ - - handles[a].displacement_min = FLT_MAX; - handles[a].displacement_max = -FLT_MAX; - - BLI_threadpool_insert(&threads, &handles[a]); - } - - /* wait for everything to be done */ - a = 0; - while (a != re->r.threads) { - PIL_sleep_ms(50); - - /* calculate progress */ - for (vdone = false, a = 0; a < re->r.threads; a++) - vdone += handles[a].vdone; - if (progress) - *progress = (float)(vdone / (float)re->totvlak); - - for (a = 0; a < re->r.threads; a++) { - if (handles[a].ready == false) { - break; - } - } - } - - /* filter and refresh images */ - if ((R.r.bake_flag & R_BAKE_VCOL) == 0) { - float displacement_min = FLT_MAX, displacement_max = -FLT_MAX; - - if (use_displacement_buffer) { - for (a = 0; a < re->r.threads; a++) { - displacement_min = min_ff(displacement_min, handles[a].displacement_min); - displacement_max = max_ff(displacement_max, handles[a].displacement_max); - } - } - - for (ima = G.main->image.first; ima; ima = ima->id.next) { - if ((ima->id.tag & LIB_TAG_DOIT) == 0) { - ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL); - BakeImBufuserData *userdata; - - if (ima->flag & IMA_USED_FOR_RENDER) - result = BAKE_RESULT_FEEDBACK_LOOP; - - if (!ibuf) - continue; - - userdata = (BakeImBufuserData *)ibuf->userdata; - if (userdata) { - if (use_displacement_buffer) { - if (type == RE_BAKE_DERIVATIVE) { - float user_scale = (R.r.bake_flag & R_BAKE_USERSCALE) ? R.r.bake_user_scale : -1.0f; - RE_bake_make_derivative(ibuf, userdata->displacement_buffer, userdata->mask_buffer, - displacement_min, displacement_max, user_scale); - } - else { - RE_bake_ibuf_normalize_displacement(ibuf, userdata->displacement_buffer, userdata->mask_buffer, - displacement_min, displacement_max); - } - } - - RE_bake_ibuf_filter(ibuf, userdata->mask_buffer, re->r.bake_filter); - } - - ibuf->userflags |= IB_BITMAPDIRTY; - BKE_image_release_ibuf(ima, ibuf, NULL); - } - } - - /* calculate return value */ - for (a = 0; a < re->r.threads; a++) { - zbuf_free_span(handles[a].zspan); - MEM_freeN(handles[a].zspan); - } - } - - MEM_freeN(handles); - - BLI_threadpool_end(&threads); - - if (vdone == 0) { - result = BAKE_RESULT_NO_OBJECTS; - } - - return result; -} - -struct Image *RE_bake_shade_get_image(void) -{ - return R.bakebuf; -} - -/* **************** Derivative Maps Baker **************** */ - -static void add_single_heights_margin(const ImBuf *ibuf, const char *mask, float *heights_buffer) -{ - int x, y; - - for (y = 0; y < ibuf->y; y++) { - for (x = 0; x < ibuf->x; x++) { - int index = ibuf->x * y + x; - - /* If unassigned pixel, look for neighbors. */ - if (mask[index] != FILTER_MASK_USED) { - float height_acc = 0; - int denom = 0; - int i, j; - - for (j = -1; j <= 1; j++) - for (i = -1; i <= 1; i++) { - int w = (i == 0 ? 1 : 0) + (j == 0 ? 1 : 0) + 1; - - if (i != 0 || j != 0) { - int index2 = 0; - int x0 = x + i; - int y0 = y + j; - - CLAMP(x0, 0, ibuf->x - 1); - CLAMP(y0, 0, ibuf->y - 1); - - index2 = ibuf->x * y0 + x0; - - if (mask[index2] == FILTER_MASK_USED) { - height_acc += w * heights_buffer[index2]; - denom += w; - } - } - } - - /* Insert final value. */ - if (denom > 0) { - heights_buffer[index] = height_acc / denom; - } - } - } - } -} - -/* returns user-scale */ -float RE_bake_make_derivative(ImBuf *ibuf, float *heights_buffer, const char *mask, - const float height_min, const float height_max, - const float fmult) -{ - const float delta_height = height_max - height_min; - const float denom = delta_height > 0.0f ? (8 * delta_height) : 1.0f; - bool auto_range_fit = fmult <= 0.0f; - float max_num_deriv = -1.0f; - int x, y, index; - - /* Need a single margin to calculate good derivatives. */ - add_single_heights_margin(ibuf, mask, heights_buffer); - - if (auto_range_fit) { - /* If automatic range fitting is enabled. */ - for (y = 0; y < ibuf->y; y++) { - const int Yu = y == (ibuf->y - 1) ? (ibuf->y - 1) : (y + 1); - const int Yc = y; - const int Yd = y == 0 ? 0 : (y - 1); - - for (x = 0; x < ibuf->x; x++) { - const int Xl = x == 0 ? 0 : (x - 1); - const int Xc = x; - const int Xr = x == (ibuf->x - 1) ? (ibuf->x - 1) : (x + 1); - - const float Hcy = heights_buffer[Yc * ibuf->x + Xr] - heights_buffer[Yc * ibuf->x + Xl]; - const float Hu = heights_buffer[Yu * ibuf->x + Xr] - heights_buffer[Yu * ibuf->x + Xl]; - const float Hd = heights_buffer[Yd * ibuf->x + Xr] - heights_buffer[Yd * ibuf->x + Xl]; - - const float Hl = heights_buffer[Yu * ibuf->x + Xl] - heights_buffer[Yd * ibuf->x + Xl]; - const float Hcx = heights_buffer[Yu * ibuf->x + Xc] - heights_buffer[Yd * ibuf->x + Xc]; - const float Hr = heights_buffer[Yu * ibuf->x + Xr] - heights_buffer[Yd * ibuf->x + Xr]; - - /* This corresponds to using the sobel kernel on the heights buffer - * to obtain the derivative multiplied by 8. - */ - const float deriv_x = Hu + 2 * Hcy + Hd; - const float deriv_y = Hr + 2 * Hcx + Hl; - - /* early out */ - index = ibuf->x * y + x; - if (mask[index] != FILTER_MASK_USED) { - continue; - } - - /* Widen bound. */ - if (fabsf(deriv_x) > max_num_deriv) { - max_num_deriv = fabsf(deriv_x); - } - - if (fabsf(deriv_y) > max_num_deriv) { - max_num_deriv = fabsf(deriv_y); - } - } - } - } - - /* Output derivatives. */ - auto_range_fit &= (max_num_deriv > 0); - for (y = 0; y < ibuf->y; y++) { - const int Yu = y == (ibuf->y - 1) ? (ibuf->y - 1) : (y + 1); - const int Yc = y; - const int Yd = y == 0 ? 0 : (y - 1); - - for (x = 0; x < ibuf->x; x++) { - const int Xl = x == 0 ? 0 : (x - 1); - const int Xc = x; - const int Xr = x == (ibuf->x - 1) ? (ibuf->x - 1) : (x + 1); - - const float Hcy = heights_buffer[Yc * ibuf->x + Xr] - heights_buffer[Yc * ibuf->x + Xl]; - const float Hu = heights_buffer[Yu * ibuf->x + Xr] - heights_buffer[Yu * ibuf->x + Xl]; - const float Hd = heights_buffer[Yd * ibuf->x + Xr] - heights_buffer[Yd * ibuf->x + Xl]; - - const float Hl = heights_buffer[Yu * ibuf->x + Xl] - heights_buffer[Yd * ibuf->x + Xl]; - const float Hcx = heights_buffer[Yu * ibuf->x + Xc] - heights_buffer[Yd * ibuf->x + Xc]; - const float Hr = heights_buffer[Yu * ibuf->x + Xr] - heights_buffer[Yd * ibuf->x + Xr]; - - /* This corresponds to using the sobel kernel on the heights buffer - * to obtain the derivative multiplied by 8. - */ - float deriv_x = Hu + 2 * Hcy + Hd; - float deriv_y = Hr + 2 * Hcx + Hl; - - /* Early out. */ - index = ibuf->x * y + x; - if (mask[index] != FILTER_MASK_USED) { - continue; - } - - if (auto_range_fit) { - deriv_x /= max_num_deriv; - deriv_y /= max_num_deriv; - } - else { - deriv_x *= (fmult / denom); - deriv_y *= (fmult / denom); - } - - deriv_x = deriv_x * 0.5f + 0.5f; - deriv_y = deriv_y * 0.5f + 0.5f; - - /* Clamp. */ - CLAMP(deriv_x, 0.0f, 1.0f); - CLAMP(deriv_y, 0.0f, 1.0f); - - /* Write out derivatives. */ - if (ibuf->rect_float) { - float *rrgbf = ibuf->rect_float + index * 4; - - rrgbf[0] = deriv_x; - rrgbf[1] = deriv_y; - rrgbf[2] = 0.0f; - rrgbf[3] = 1.0f; - } - else { - char *rrgb = (char *)ibuf->rect + index * 4; - - rrgb[0] = FTOCHAR(deriv_x); - rrgb[1] = FTOCHAR(deriv_y); - rrgb[2] = 0; - rrgb[3] = 255; - } - } - } - - /* Eeturn user-scale (for rendering). */ - return auto_range_fit ? (max_num_deriv / denom) : (fmult > 0.0f ? (1.0f / fmult) : 0.0f); -} diff --git a/source/blender/render/intern/source/bake_api.c b/source/blender/render/intern/source/bake_api.c index 505af3c2fa8..bd3e01c83a8 100644 --- a/source/blender/render/intern/source/bake_api.c +++ b/source/blender/render/intern/source/bake_api.c @@ -84,19 +84,11 @@ /* local include */ #include "render_types.h" -#include "shading.h" #include "zbuf.h" /* Remove when Cycles moves from MFace to MLoopTri */ #define USE_MFACE_WORKAROUND -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -/* defined in pipeline.c, is hardcopy of active dynamic allocated Render */ -/* only to be used here in this file, it's for speed */ -extern struct Render R; -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - - typedef struct BakeDataZSpan { BakePixel *pixel_array; int primitive_id; @@ -263,6 +255,36 @@ static void calc_point_from_barycentric_extrusion( copy_v3_v3(r_dir, dir); } +static void barycentric_differentials_from_position( + const float co[3], const float v1[3], const float v2[3], const float v3[3], + const float dxco[3], const float dyco[3], const float facenor[3], const bool differentials, + float *u, float *v, float *dx_u, float *dx_v, float *dy_u, float *dy_v) +{ + /* find most stable axis to project */ + int axis1, axis2; + axis_dominant_v3(&axis1, &axis2, facenor); + + /* compute u,v and derivatives */ + float t00 = v3[axis1] - v1[axis1]; + float t01 = v3[axis2] - v1[axis2]; + float t10 = v3[axis1] - v2[axis1]; + float t11 = v3[axis2] - v2[axis2]; + + float detsh = (t00 * t11 - t10 * t01); + detsh = (detsh != 0.0f) ? 1.0f / detsh : 0.0f; + t00 *= detsh; t01 *= detsh; + t10 *= detsh; t11 *= detsh; + + *u = (v3[axis1] - co[axis1]) * t11 - (v3[axis2] - co[axis2]) * t10; + *v = (v3[axis2] - co[axis2]) * t00 - (v3[axis1] - co[axis1]) * t01; + if (differentials) { + *dx_u = dxco[axis1] * t11 - dxco[axis2] * t10; + *dx_v = dxco[axis2] * t00 - dxco[axis1] * t01; + *dy_u = dyco[axis1] * t11 - dyco[axis2] * t10; + *dy_v = dyco[axis2] * t00 - dyco[axis1] * t01; + } +} + /** * This function populates pixel_array and returns TRUE if things are correct */ @@ -665,7 +687,7 @@ void RE_bake_pixels_populate( } for (i = 0; i < bake_images->size; i++) { - zbuf_alloc_span(&bd.zspan[i], bake_images->data[i].width, bake_images->data[i].height, R.clipcrop); + zbuf_alloc_span(&bd.zspan[i], bake_images->data[i].width, bake_images->data[i].height); } looptri = MEM_mallocN(sizeof(*looptri) * tottri, __func__); @@ -958,36 +980,6 @@ void RE_bake_ibuf_clear(Image *image, const bool is_tangent) /* ************************************************************* */ -/** - * not the real UV, but the internal per-face UV instead - * I'm using it to test if everything is correct */ -static bool bake_uv(const BakePixel pixel_array[], const size_t num_pixels, const int depth, float result[]) -{ - size_t i; - - for (i=0; i < num_pixels; i++) { - size_t offset = i * depth; - copy_v2_v2(&result[offset], pixel_array[i].uv); - } - - return true; -} - -bool RE_bake_internal( - Render *UNUSED(re), Object *UNUSED(object), const BakePixel pixel_array[], - const size_t num_pixels, const int depth, const eScenePassType pass_type, float result[]) -{ - switch (pass_type) { - case SCE_PASS_UV: - { - return bake_uv(pixel_array, num_pixels, depth, result); - } - default: - break; - } - return false; -} - int RE_pass_depth(const eScenePassType pass_type) { /* IMB_buffer_byte_from_float assumes 4 channels diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c deleted file mode 100644 index 71e44887a8e..00000000000 --- a/source/blender/render/intern/source/convertblender.c +++ /dev/null @@ -1,5974 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * Contributors: 2004/2005/2006 Blender Foundation, full recode - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/render/intern/source/convertblender.c - * \ingroup render - */ - -#include <math.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <limits.h> - -#include "MEM_guardedalloc.h" - -#include "BLI_math.h" -#include "BLI_blenlib.h" -#include "BLI_utildefines.h" -#include "BLI_rand.h" -#include "BLI_memarena.h" -#ifdef WITH_FREESTYLE -# include "BLI_edgehash.h" -#endif - -#include "BLT_translation.h" - -#include "DNA_material_types.h" -#include "DNA_curve_types.h" -#include "DNA_group_types.h" -#include "DNA_lamp_types.h" -#include "DNA_image_types.h" -#include "DNA_mesh_types.h" -#include "DNA_meshdata_types.h" -#include "DNA_modifier_types.h" -#include "DNA_node_types.h" -#include "DNA_object_types.h" -#include "DNA_object_fluidsim_types.h" -#include "DNA_particle_types.h" -#include "DNA_scene_types.h" -#include "DNA_texture_types.h" - -#include "BKE_anim.h" -#include "BKE_curve.h" -#include "BKE_customdata.h" -#include "BKE_colortools.h" -#include "BKE_displist.h" -#include "BKE_DerivedMesh.h" -#include "BKE_global.h" -#include "BKE_group.h" -#include "BKE_key.h" -#include "BKE_image.h" -#include "BKE_lattice.h" -#include "BKE_layer.h" -#include "BKE_material.h" -#include "BKE_main.h" -#include "BKE_mball.h" -#include "BKE_mesh.h" -#include "BKE_modifier.h" -#include "BKE_node.h" -#include "BKE_object.h" -#include "BKE_particle.h" -#include "BKE_scene.h" - -#include "DEG_depsgraph.h" -#include "DEG_depsgraph_build.h" - -#include "PIL_time.h" - -#include "envmap.h" -#include "occlusion.h" -#include "pointdensity.h" -#include "voxeldata.h" -#include "render_types.h" -#include "rendercore.h" -#include "renderdatabase.h" -#include "renderpipeline.h" -#include "shadbuf.h" -#include "shading.h" -#include "strand.h" -#include "texture.h" -#include "volume_precache.h" -#include "sss.h" -#include "zbuf.h" -#include "sunsky.h" - -/* 10 times larger than normal epsilon, test it on default nurbs sphere with ray_transp (for quad detection) */ -/* or for checking vertex normal flips */ -#define FLT_EPSILON10 1.19209290e-06F - -/* could enable at some point but for now there are far too many conversions */ -#ifdef __GNUC__ -# pragma GCC diagnostic ignored "-Wdouble-promotion" -#endif - -/* ------------------------------------------------------------------------- */ -/* tool functions/defines for ad hoc simplification and possible future - * cleanup */ -/* ------------------------------------------------------------------------- */ - -#define UVTOINDEX(u, v) (startvlak + (u) * sizev + (v)) -/* - * - * NOTE THAT U/V COORDINATES ARE SOMETIMES SWAPPED !! - * - * ^ ()----p4----p3----() - * | | | | | - * u | | F1 | F2 | - * | | | | - * ()----p1----p2----() - * v -> - */ - -/* ------------------------------------------------------------------------- */ - -#define CD_MASK_RENDER_INTERNAL \ - (CD_MASK_BAREMESH | CD_MASK_MFACE | CD_MASK_MTFACE | CD_MASK_MCOL) - -static void split_v_renderfaces(ObjectRen *obr, int startvlak, int UNUSED(startvert), int UNUSED(usize), int vsize, int uIndex, int UNUSED(cyclu), int cyclv) -{ - int vLen = vsize-1+(!!cyclv); - int v; - - for (v=0; v<vLen; v++) { - VlakRen *vlr = RE_findOrAddVlak(obr, startvlak + vLen*uIndex + v); - VlakRen *vlr_other; - VertRen *vert = RE_vertren_copy(obr, vlr->v2); - - if (cyclv) { - vlr->v2 = vert; - - if (v == vLen - 1) { - vlr_other = RE_findOrAddVlak(obr, startvlak + vLen*uIndex + 0); - vlr_other->v1 = vert; - } - else { - vlr_other = RE_findOrAddVlak(obr, startvlak + vLen*uIndex + v+1); - vlr_other->v1 = vert; - } - } - else { - vlr->v2 = vert; - - if (v < vLen - 1) { - vlr_other = RE_findOrAddVlak(obr, startvlak + vLen*uIndex + v+1); - vlr_other->v1 = vert; - } - - if (v == 0) { - vlr->v1 = RE_vertren_copy(obr, vlr->v1); - } - } - } -} - -/* ------------------------------------------------------------------------- */ -/* Stress, tangents and normals */ -/* ------------------------------------------------------------------------- */ - -static void calc_edge_stress_add(float *accum, VertRen *v1, VertRen *v2) -{ - float len= len_v3v3(v1->co, v2->co)/len_v3v3(v1->orco, v2->orco); - float *acc; - - acc= accum + 2*v1->index; - acc[0]+= len; - acc[1]+= 1.0f; - - acc= accum + 2*v2->index; - acc[0]+= len; - acc[1]+= 1.0f; -} - -static void calc_edge_stress(Render *UNUSED(re), ObjectRen *obr, Mesh *me) -{ - float loc[3], size[3], *accum, *acc, *accumoffs, *stress; - int a; - - if (obr->totvert==0) return; - - BKE_mesh_texspace_get(me, loc, NULL, size); - - accum= MEM_callocN(2*sizeof(float)*obr->totvert, "temp accum for stress"); - - /* de-normalize orco */ - for (a=0; a<obr->totvert; a++) { - VertRen *ver= RE_findOrAddVert(obr, a); - if (ver->orco) { - ver->orco[0]= ver->orco[0]*size[0] +loc[0]; - ver->orco[1]= ver->orco[1]*size[1] +loc[1]; - ver->orco[2]= ver->orco[2]*size[2] +loc[2]; - } - } - - /* add stress values */ - accumoffs= accum; /* so we can use vertex index */ - for (a=0; a<obr->totvlak; a++) { - VlakRen *vlr= RE_findOrAddVlak(obr, a); - - if (vlr->v1->orco && vlr->v4) { - calc_edge_stress_add(accumoffs, vlr->v1, vlr->v2); - calc_edge_stress_add(accumoffs, vlr->v2, vlr->v3); - calc_edge_stress_add(accumoffs, vlr->v3, vlr->v1); - if (vlr->v4) { - calc_edge_stress_add(accumoffs, vlr->v3, vlr->v4); - calc_edge_stress_add(accumoffs, vlr->v4, vlr->v1); - calc_edge_stress_add(accumoffs, vlr->v2, vlr->v4); - } - } - } - - for (a=0; a<obr->totvert; a++) { - VertRen *ver= RE_findOrAddVert(obr, a); - if (ver->orco) { - /* find stress value */ - acc= accumoffs + 2*ver->index; - if (acc[1]!=0.0f) - acc[0]/= acc[1]; - stress= RE_vertren_get_stress(obr, ver, 1); - *stress= *acc; - - /* restore orcos */ - ver->orco[0] = (ver->orco[0]-loc[0])/size[0]; - ver->orco[1] = (ver->orco[1]-loc[1])/size[1]; - ver->orco[2] = (ver->orco[2]-loc[2])/size[2]; - } - } - - MEM_freeN(accum); -} - -/* gets tangent from tface or orco */ -static void calc_tangent_vector(ObjectRen *obr, VlakRen *vlr, int do_tangent) -{ - MTFace *tface= RE_vlakren_get_tface(obr, vlr, obr->actmtface, NULL, 0); - VertRen *v1=vlr->v1, *v2=vlr->v2, *v3=vlr->v3, *v4=vlr->v4; - float tang[3], *tav; - float *uv1, *uv2, *uv3, *uv4; - float uv[4][2]; - - if (tface) { - uv1= tface->uv[0]; - uv2= tface->uv[1]; - uv3= tface->uv[2]; - uv4= tface->uv[3]; - } - else if (v1->orco) { - uv1= uv[0]; uv2= uv[1]; uv3= uv[2]; uv4= uv[3]; - map_to_sphere(&uv[0][0], &uv[0][1], v1->orco[0], v1->orco[1], v1->orco[2]); - map_to_sphere(&uv[1][0], &uv[1][1], v2->orco[0], v2->orco[1], v2->orco[2]); - map_to_sphere(&uv[2][0], &uv[2][1], v3->orco[0], v3->orco[1], v3->orco[2]); - if (v4) - map_to_sphere(&uv[3][0], &uv[3][1], v4->orco[0], v4->orco[1], v4->orco[2]); - } - else return; - - tangent_from_uv_v3(uv1, uv2, uv3, v1->co, v2->co, v3->co, vlr->n, tang); - - if (do_tangent) { - tav= RE_vertren_get_tangent(obr, v1, 1); - add_v3_v3(tav, tang); - tav= RE_vertren_get_tangent(obr, v2, 1); - add_v3_v3(tav, tang); - tav= RE_vertren_get_tangent(obr, v3, 1); - add_v3_v3(tav, tang); - } - - if (v4) { - tangent_from_uv_v3(uv1, uv3, uv4, v1->co, v3->co, v4->co, vlr->n, tang); - - if (do_tangent) { - tav= RE_vertren_get_tangent(obr, v1, 1); - add_v3_v3(tav, tang); - tav= RE_vertren_get_tangent(obr, v3, 1); - add_v3_v3(tav, tang); - tav= RE_vertren_get_tangent(obr, v4, 1); - add_v3_v3(tav, tang); - } - } -} - - - -/**************************************************************** - ************ tangent space generation interface **************** - ****************************************************************/ - -typedef struct { - ObjectRen *obr; - int mtface_index; -} SRenderMeshToTangent; - -/* interface */ -#include "mikktspace.h" - -static int GetNumFaces(const SMikkTSpaceContext *pContext) -{ - SRenderMeshToTangent *pMesh = (SRenderMeshToTangent *) pContext->m_pUserData; - return pMesh->obr->totvlak; -} - -static int GetNumVertsOfFace(const SMikkTSpaceContext *pContext, const int face_num) -{ - SRenderMeshToTangent *pMesh = (SRenderMeshToTangent *) pContext->m_pUserData; - VlakRen *vlr= RE_findOrAddVlak(pMesh->obr, face_num); - return vlr->v4!=NULL ? 4 : 3; -} - -static void GetPosition(const SMikkTSpaceContext *pContext, float r_co[3], const int face_num, const int vert_index) -{ - //assert(vert_index>=0 && vert_index<4); - SRenderMeshToTangent *pMesh = (SRenderMeshToTangent *) pContext->m_pUserData; - VlakRen *vlr= RE_findOrAddVlak(pMesh->obr, face_num); - const float *co = (&vlr->v1)[vert_index]->co; - copy_v3_v3(r_co, co); -} - -static void GetTextureCoordinate(const SMikkTSpaceContext *pContext, float r_uv[2], const int face_num, const int vert_index) -{ - //assert(vert_index>=0 && vert_index<4); - SRenderMeshToTangent *pMesh = (SRenderMeshToTangent *) pContext->m_pUserData; - VlakRen *vlr= RE_findOrAddVlak(pMesh->obr, face_num); - MTFace *tface= RE_vlakren_get_tface(pMesh->obr, vlr, pMesh->mtface_index, NULL, 0); - const float *coord; - - if (tface != NULL) { - coord= tface->uv[vert_index]; - copy_v2_v2(r_uv, coord); - } - else if ((coord = (&vlr->v1)[vert_index]->orco)) { - map_to_sphere(&r_uv[0], &r_uv[1], coord[0], coord[1], coord[2]); - } - else { /* else we get un-initialized value, 0.0 ok default? */ - zero_v2(r_uv); - } -} - -static void GetNormal(const SMikkTSpaceContext *pContext, float r_no[3], const int face_num, const int vert_index) -{ - //assert(vert_index>=0 && vert_index<4); - SRenderMeshToTangent *pMesh = (SRenderMeshToTangent *) pContext->m_pUserData; - VlakRen *vlr= RE_findOrAddVlak(pMesh->obr, face_num); - - if (vlr->flag & ME_SMOOTH) { - const float *n = (&vlr->v1)[vert_index]->n; - copy_v3_v3(r_no, n); - } - else { - negate_v3_v3(r_no, vlr->n); - } -} -static void SetTSpace(const SMikkTSpaceContext *pContext, const float fvTangent[3], const float fSign, const int face_num, const int iVert) -{ - //assert(vert_index>=0 && vert_index<4); - SRenderMeshToTangent *pMesh = (SRenderMeshToTangent *) pContext->m_pUserData; - VlakRen *vlr = RE_findOrAddVlak(pMesh->obr, face_num); - float *ftang = RE_vlakren_get_nmap_tangent(pMesh->obr, vlr, pMesh->mtface_index, true); - if (ftang!=NULL) { - copy_v3_v3(&ftang[iVert*4+0], fvTangent); - ftang[iVert*4+3]=fSign; - } -} - -static void calc_vertexnormals(Render *UNUSED(re), ObjectRen *obr, bool do_vertex_normal, bool do_tangent, bool do_nmap_tangent) -{ - int a; - - /* clear all vertex normals */ - if (do_vertex_normal) { - for (a=0; a<obr->totvert; a++) { - VertRen *ver= RE_findOrAddVert(obr, a); - ver->n[0]=ver->n[1]=ver->n[2]= 0.0f; - } - } - - /* calculate cos of angles and point-masses, use as weight factor to - * add face normal to vertex */ - for (a=0; a<obr->totvlak; a++) { - VlakRen *vlr= RE_findOrAddVlak(obr, a); - if (do_vertex_normal && vlr->flag & ME_SMOOTH) { - float *n4= (vlr->v4)? vlr->v4->n: NULL; - const float *c4= (vlr->v4)? vlr->v4->co: NULL; - - accumulate_vertex_normals_v3(vlr->v1->n, vlr->v2->n, vlr->v3->n, n4, - vlr->n, vlr->v1->co, vlr->v2->co, vlr->v3->co, c4); - } - if (do_tangent) { - /* tangents still need to be calculated for flat faces too */ - /* weighting removed, they are not vertexnormals */ - calc_tangent_vector(obr, vlr, do_tangent); - } - } - - /* do solid faces */ - for (a=0; a<obr->totvlak; a++) { - VlakRen *vlr= RE_findOrAddVlak(obr, a); - - if (do_vertex_normal && (vlr->flag & ME_SMOOTH)==0) { - if (is_zero_v3(vlr->v1->n)) copy_v3_v3(vlr->v1->n, vlr->n); - if (is_zero_v3(vlr->v2->n)) copy_v3_v3(vlr->v2->n, vlr->n); - if (is_zero_v3(vlr->v3->n)) copy_v3_v3(vlr->v3->n, vlr->n); - if (vlr->v4 && is_zero_v3(vlr->v4->n)) copy_v3_v3(vlr->v4->n, vlr->n); - } - } - - /* normalize vertex normals */ - for (a=0; a<obr->totvert; a++) { - VertRen *ver= RE_findOrAddVert(obr, a); - normalize_v3(ver->n); - if (do_tangent) { - float *tav= RE_vertren_get_tangent(obr, ver, 0); - if (tav) { - /* orthonorm. */ - const float tdn = dot_v3v3(tav, ver->n); - tav[0] -= ver->n[0]*tdn; - tav[1] -= ver->n[1]*tdn; - tav[2] -= ver->n[2]*tdn; - normalize_v3(tav); - } - } - } - - /* normal mapping tangent with mikktspace */ - if (do_nmap_tangent != false) { - SRenderMeshToTangent mesh2tangent; - SMikkTSpaceContext sContext; - SMikkTSpaceInterface sInterface; - memset(&mesh2tangent, 0, sizeof(SRenderMeshToTangent)); - memset(&sContext, 0, sizeof(SMikkTSpaceContext)); - memset(&sInterface, 0, sizeof(SMikkTSpaceInterface)); - - mesh2tangent.obr = obr; - - sContext.m_pUserData = &mesh2tangent; - sContext.m_pInterface = &sInterface; - sInterface.m_getNumFaces = GetNumFaces; - sInterface.m_getNumVerticesOfFace = GetNumVertsOfFace; - sInterface.m_getPosition = GetPosition; - sInterface.m_getTexCoord = GetTextureCoordinate; - sInterface.m_getNormal = GetNormal; - sInterface.m_setTSpaceBasic = SetTSpace; - - for (a = 0; a < MAX_MTFACE; a++) { - if (obr->tangent_mask & 1 << a) { - mesh2tangent.mtface_index = a; - genTangSpaceDefault(&sContext); - } - } - } -} - -/* ------------------------------------------------------------------------- */ -/* Autosmoothing: */ -/* ------------------------------------------------------------------------- */ - -typedef struct ASvert { - int totface; - ListBase faces; -} ASvert; - -typedef struct ASface { - struct ASface *next, *prev; - VlakRen *vlr[4]; - VertRen *nver[4]; -} ASface; - -static int as_addvert(ASvert *asv, VertRen *v1, VlakRen *vlr) -{ - ASface *asf; - int a = -1; - - if (v1 == NULL) - return a; - - asf = asv->faces.last; - if (asf) { - for (a = 0; a < 4 && asf->vlr[a]; a++) { - } - } - else { - a = 4; - } - - /* new face struct */ - if (a == 4) { - a = 0; - asf = MEM_callocN(sizeof(ASface), "asface"); - BLI_addtail(&asv->faces, asf); - } - - asf->vlr[a] = vlr; - asv->totface++; - - return a; -} - -static VertRen *as_findvertex_lnor(VlakRen *vlr, VertRen *ver, ASvert *asv, const float lnor[3]) -{ - /* return when new vertex already was made, or existing one is OK */ - ASface *asf; - int a; - - /* First face, we can use existing vert and assign it current lnor! */ - if (asv->totface == 1) { - copy_v3_v3(ver->n, lnor); - return ver; - } - - /* In case existing ver has same normal as current lnor, we can simply use it! */ - if (equals_v3v3(lnor, ver->n)) { - return ver; - } - - asf = asv->faces.first; - while (asf) { - for (a = 0; a < 4; a++) { - if (asf->vlr[a] && asf->vlr[a] != vlr) { - /* this face already made a copy for this vertex! */ - if (asf->nver[a]) { - if (equals_v3v3(lnor, asf->nver[a]->n)) { - return asf->nver[a]; - } - } - } - } - asf = asf->next; - } - - return NULL; -} - -static void as_addvert_lnor(ObjectRen *obr, ASvert *asv, VertRen *ver, VlakRen *vlr, const short _lnor[3]) -{ - VertRen *v1; - ASface *asf; - int asf_idx; - float lnor[3]; - - normal_short_to_float_v3(lnor, _lnor); - - asf_idx = as_addvert(asv, ver, vlr); - if (asf_idx < 0) { - return; - } - asf = asv->faces.last; - - /* already made a new vertex within threshold? */ - v1 = as_findvertex_lnor(vlr, ver, asv, lnor); - if (v1 == NULL) { - /* make a new vertex */ - v1 = RE_vertren_copy(obr, ver); - copy_v3_v3(v1->n, lnor); - } - if (v1 != ver) { - asf->nver[asf_idx] = v1; - if (vlr->v1 == ver) vlr->v1 = v1; - if (vlr->v2 == ver) vlr->v2 = v1; - if (vlr->v3 == ver) vlr->v3 = v1; - if (vlr->v4 == ver) vlr->v4 = v1; - } -} - -/* note; autosmooth happens in object space still, after applying autosmooth we rotate */ -/* note2; actually, when original mesh and displist are equal sized, face normals are from original mesh */ -static void autosmooth(Render *UNUSED(re), ObjectRen *obr, float mat[4][4], short (*lnors)[4][3]) -{ - ASvert *asverts; - VertRen *ver; - VlakRen *vlr; - int a, totvert; - - float rot[3][3]; - - /* Note: For normals, we only want rotation, not scaling component. - * Negative scales (aka mirroring) give wrong results, see T44102. */ - if (lnors) { - float mat3[3][3], size[3]; - - copy_m3_m4(mat3, mat); - mat3_to_rot_size(rot, size, mat3); - } - - if (obr->totvert == 0) - return; - - totvert = obr->totvert; - asverts = MEM_callocN(sizeof(ASvert) * totvert, "all smooth verts"); - - if (lnors) { - /* We construct listbase of all vertices and pointers to faces, and add new verts when needed - * (i.e. when existing ones do not share the same (loop)normal). - */ - for (a = 0; a < obr->totvlak; a++, lnors++) { - vlr = RE_findOrAddVlak(obr, a); - /* skip wire faces */ - if (vlr->v2 != vlr->v3) { - as_addvert_lnor(obr, asverts+vlr->v1->index, vlr->v1, vlr, (const short*)lnors[0][0]); - as_addvert_lnor(obr, asverts+vlr->v2->index, vlr->v2, vlr, (const short*)lnors[0][1]); - as_addvert_lnor(obr, asverts+vlr->v3->index, vlr->v3, vlr, (const short*)lnors[0][2]); - if (vlr->v4) - as_addvert_lnor(obr, asverts+vlr->v4->index, vlr->v4, vlr, (const short*)lnors[0][3]); - } - } - } - - /* free */ - for (a = 0; a < totvert; a++) { - BLI_freelistN(&asverts[a].faces); - } - MEM_freeN(asverts); - - /* rotate vertices and calculate normal of faces */ - for (a = 0; a < obr->totvert; a++) { - ver = RE_findOrAddVert(obr, a); - mul_m4_v3(mat, ver->co); - if (lnors) { - mul_m3_v3(rot, ver->n); - negate_v3(ver->n); - } - } - for (a = 0; a < obr->totvlak; a++) { - vlr = RE_findOrAddVlak(obr, a); - - /* skip wire faces */ - if (vlr->v2 != vlr->v3) { - if (vlr->v4) - normal_quad_v3(vlr->n, vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co); - else - normal_tri_v3(vlr->n, vlr->v3->co, vlr->v2->co, vlr->v1->co); - } - } -} - -/* ------------------------------------------------------------------------- */ -/* Orco hash and Materials */ -/* ------------------------------------------------------------------------- */ - -static float *get_object_orco(Render *re, void *ob) -{ - if (!re->orco_hash) { - return NULL; - } - - return BLI_ghash_lookup(re->orco_hash, ob); -} - -static void set_object_orco(Render *re, void *ob, float *orco) -{ - if (!re->orco_hash) - re->orco_hash = BLI_ghash_ptr_new("set_object_orco gh"); - - BLI_ghash_insert(re->orco_hash, ob, orco); -} - -static void free_mesh_orco_hash(Render *re) -{ - if (re->orco_hash) { - BLI_ghash_free(re->orco_hash, NULL, MEM_freeN); - re->orco_hash = NULL; - } -} - -static void check_material_mapto(Material *ma) -{ - int a; - ma->mapto_textured = 0; - - /* cache which inputs are actually textured. - * this can avoid a bit of time spent iterating through all the texture slots, map inputs and map tos - * every time a property which may or may not be textured is accessed */ - - for (a=0; a<MAX_MTEX; a++) { - if (ma->mtex[a] && ma->mtex[a]->tex) { - /* currently used only in volume render, so we'll check for those flags */ - if (ma->mtex[a]->mapto & MAP_DENSITY) ma->mapto_textured |= MAP_DENSITY; - if (ma->mtex[a]->mapto & MAP_EMISSION) ma->mapto_textured |= MAP_EMISSION; - if (ma->mtex[a]->mapto & MAP_EMISSION_COL) ma->mapto_textured |= MAP_EMISSION_COL; - if (ma->mtex[a]->mapto & MAP_SCATTERING) ma->mapto_textured |= MAP_SCATTERING; - if (ma->mtex[a]->mapto & MAP_TRANSMISSION_COL) ma->mapto_textured |= MAP_TRANSMISSION_COL; - if (ma->mtex[a]->mapto & MAP_REFLECTION) ma->mapto_textured |= MAP_REFLECTION; - if (ma->mtex[a]->mapto & MAP_REFLECTION_COL) ma->mapto_textured |= MAP_REFLECTION_COL; - } - } -} -static void flag_render_node_material(Render *re, bNodeTree *ntree) -{ - bNode *node; - - for (node = ntree->nodes.first; node; node = node->next) { - if (node->id) { - if (GS(node->id->name)==ID_MA) { - Material *ma= (Material *)node->id; - - if ((ma->mode & MA_TRANSP) && (ma->mode & MA_ZTRANSP)) - re->flag |= R_ZTRA; - - ma->flag |= MA_IS_USED; - } - else if (node->type==NODE_GROUP) - flag_render_node_material(re, (bNodeTree *)node->id); - } - } -} - -static Material *give_render_material(Render *re, Object *ob, short nr) -{ - extern Material defmaterial; /* material.c */ - Material *ma; - - ma= give_current_material(ob, nr); - if (ma==NULL) - ma= &defmaterial; - - if (re->r.mode & R_SPEED) ma->texco |= NEED_UV; - - if (ma->material_type == MA_TYPE_VOLUME) { - ma->mode |= MA_TRANSP; - ma->mode &= ~MA_SHADBUF; - } - if ((ma->mode & MA_TRANSP) && (ma->mode & MA_ZTRANSP)) - re->flag |= R_ZTRA; - - /* for light groups and SSS */ - ma->flag |= MA_IS_USED; - - if (ma->nodetree && ma->use_nodes) - flag_render_node_material(re, ma->nodetree); - - check_material_mapto(ma); - - return ma; -} - -/* ------------------------------------------------------------------------- */ -/* Particles */ -/* ------------------------------------------------------------------------- */ -typedef struct ParticleStrandData { - struct MCol *mcol; - float *orco, *uvco, *surfnor; - float time, adapt_angle, adapt_pix, size; - int totuv, totcol; - int first, line, adapt, override_uv; -} -ParticleStrandData; -/* future thread problem... */ -static void static_particle_strand(Render *re, ObjectRen *obr, Material *ma, ParticleStrandData *sd, const float vec[3], const float vec1[3]) -{ - static VertRen *v1= NULL, *v2= NULL; - VlakRen *vlr= NULL; - float nor[3], cross[3], crosslen, w, dx, dy, width; - static float anor[3], avec[3]; - int flag, i; - static int second=0; - - sub_v3_v3v3(nor, vec, vec1); - normalize_v3(nor); /* nor needed as tangent */ - cross_v3_v3v3(cross, vec, nor); - - /* turn cross in pixelsize */ - w= vec[2]*re->winmat[2][3] + re->winmat[3][3]; - dx= re->winx*cross[0]*re->winmat[0][0]; - dy= re->winy*cross[1]*re->winmat[1][1]; - w = sqrtf(dx * dx + dy * dy) / w; - - if (w!=0.0f) { - float fac; - if (ma->strand_ease!=0.0f) { - if (ma->strand_ease<0.0f) - fac= pow(sd->time, 1.0f+ma->strand_ease); - else - fac= pow(sd->time, 1.0f/(1.0f-ma->strand_ease)); - } - else fac= sd->time; - - width= ((1.0f-fac)*ma->strand_sta + (fac)*ma->strand_end); - - /* use actual Blender units for strand width and fall back to minimum width */ - if (ma->mode & MA_STR_B_UNITS) { - crosslen= len_v3(cross); - w= 2.0f*crosslen*ma->strand_min/w; - - if (width < w) - width= w; - - /*cross is the radius of the strand so we want it to be half of full width */ - mul_v3_fl(cross, 0.5f/crosslen); - } - else - width/=w; - - mul_v3_fl(cross, width); - } - - if (ma->mode & MA_TANGENT_STR) - flag= R_SMOOTH|R_TANGENT; - else - flag= R_SMOOTH; - - /* only 1 pixel wide strands filled in as quads now, otherwise zbuf errors */ - if (ma->strand_sta==1.0f) - flag |= R_STRAND; - - /* single face line */ - if (sd->line) { - vlr= RE_findOrAddVlak(obr, obr->totvlak++); - vlr->flag= flag; - vlr->v1= RE_findOrAddVert(obr, obr->totvert++); - vlr->v2= RE_findOrAddVert(obr, obr->totvert++); - vlr->v3= RE_findOrAddVert(obr, obr->totvert++); - vlr->v4= RE_findOrAddVert(obr, obr->totvert++); - - copy_v3_v3(vlr->v1->co, vec); - add_v3_v3(vlr->v1->co, cross); - copy_v3_v3(vlr->v1->n, nor); - vlr->v1->orco= sd->orco; - vlr->v1->accum = -1.0f; /* accum abuse for strand texco */ - - copy_v3_v3(vlr->v2->co, vec); - sub_v3_v3v3(vlr->v2->co, vlr->v2->co, cross); - copy_v3_v3(vlr->v2->n, nor); - vlr->v2->orco= sd->orco; - vlr->v2->accum= vlr->v1->accum; - - copy_v3_v3(vlr->v4->co, vec1); - add_v3_v3(vlr->v4->co, cross); - copy_v3_v3(vlr->v4->n, nor); - vlr->v4->orco= sd->orco; - vlr->v4->accum = 1.0f; /* accum abuse for strand texco */ - - copy_v3_v3(vlr->v3->co, vec1); - sub_v3_v3v3(vlr->v3->co, vlr->v3->co, cross); - copy_v3_v3(vlr->v3->n, nor); - vlr->v3->orco= sd->orco; - vlr->v3->accum= vlr->v4->accum; - - normal_quad_v3(vlr->n, vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co); - - vlr->mat= ma; - vlr->ec= ME_V2V3; - - if (sd->surfnor) { - float *snor= RE_vlakren_get_surfnor(obr, vlr, 1); - copy_v3_v3(snor, sd->surfnor); - } - - if (sd->uvco) { - for (i=0; i<sd->totuv; i++) { - MTFace *mtf; - mtf=RE_vlakren_get_tface(obr, vlr, i, NULL, 1); - mtf->uv[0][0]=mtf->uv[1][0]= - mtf->uv[2][0]=mtf->uv[3][0]=(sd->uvco+2*i)[0]; - mtf->uv[0][1]=mtf->uv[1][1]= - mtf->uv[2][1]=mtf->uv[3][1]=(sd->uvco+2*i)[1]; - } - if (sd->override_uv>=0) { - MTFace *mtf; - mtf=RE_vlakren_get_tface(obr, vlr, sd->override_uv, NULL, 0); - - mtf->uv[0][0]=mtf->uv[3][0]=0.0f; - mtf->uv[1][0]=mtf->uv[2][0]=1.0f; - - mtf->uv[0][1]=mtf->uv[1][1]=0.0f; - mtf->uv[2][1]=mtf->uv[3][1]=1.0f; - } - } - if (sd->mcol) { - for (i=0; i<sd->totcol; i++) { - MCol *mc; - mc=RE_vlakren_get_mcol(obr, vlr, i, NULL, 1); - mc[0]=mc[1]=mc[2]=mc[3]=sd->mcol[i]; - mc[0]=mc[1]=mc[2]=mc[3]=sd->mcol[i]; - } - } - } - /* first two vertices of a strand */ - else if (sd->first) { - if (sd->adapt) { - copy_v3_v3(anor, nor); - copy_v3_v3(avec, vec); - second=1; - } - - v1= RE_findOrAddVert(obr, obr->totvert++); - v2= RE_findOrAddVert(obr, obr->totvert++); - - copy_v3_v3(v1->co, vec); - add_v3_v3(v1->co, cross); - copy_v3_v3(v1->n, nor); - v1->orco= sd->orco; - v1->accum = -1.0f; /* accum abuse for strand texco */ - - copy_v3_v3(v2->co, vec); - sub_v3_v3v3(v2->co, v2->co, cross); - copy_v3_v3(v2->n, nor); - v2->orco= sd->orco; - v2->accum= v1->accum; - } - /* more vertices & faces to strand */ - else { - if (sd->adapt==0 || second) { - vlr= RE_findOrAddVlak(obr, obr->totvlak++); - vlr->flag= flag; - vlr->v1= v1; - vlr->v2= v2; - vlr->v3= RE_findOrAddVert(obr, obr->totvert++); - vlr->v4= RE_findOrAddVert(obr, obr->totvert++); - - v1= vlr->v4; /* cycle */ - v2= vlr->v3; /* cycle */ - - - if (sd->adapt) { - second=0; - copy_v3_v3(anor, nor); - copy_v3_v3(avec, vec); - } - - } - else if (sd->adapt) { - float dvec[3], pvec[3]; - sub_v3_v3v3(dvec, avec, vec); - project_v3_v3v3(pvec, dvec, vec); - sub_v3_v3v3(dvec, dvec, pvec); - - w= vec[2]*re->winmat[2][3] + re->winmat[3][3]; - dx= re->winx*dvec[0]*re->winmat[0][0]/w; - dy= re->winy*dvec[1]*re->winmat[1][1]/w; - w = sqrtf(dx * dx + dy * dy); - if (dot_v3v3(anor, nor)<sd->adapt_angle && w>sd->adapt_pix) { - vlr= RE_findOrAddVlak(obr, obr->totvlak++); - vlr->flag= flag; - vlr->v1= v1; - vlr->v2= v2; - vlr->v3= RE_findOrAddVert(obr, obr->totvert++); - vlr->v4= RE_findOrAddVert(obr, obr->totvert++); - - v1= vlr->v4; /* cycle */ - v2= vlr->v3; /* cycle */ - - copy_v3_v3(anor, nor); - copy_v3_v3(avec, vec); - } - else { - vlr= RE_findOrAddVlak(obr, obr->totvlak-1); - } - } - - copy_v3_v3(vlr->v4->co, vec); - add_v3_v3(vlr->v4->co, cross); - copy_v3_v3(vlr->v4->n, nor); - vlr->v4->orco= sd->orco; - vlr->v4->accum= -1.0f + 2.0f * sd->time; /* accum abuse for strand texco */ - - copy_v3_v3(vlr->v3->co, vec); - sub_v3_v3v3(vlr->v3->co, vlr->v3->co, cross); - copy_v3_v3(vlr->v3->n, nor); - vlr->v3->orco= sd->orco; - vlr->v3->accum= vlr->v4->accum; - - normal_quad_v3(vlr->n, vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co); - - vlr->mat= ma; - vlr->ec= ME_V2V3; - - if (sd->surfnor) { - float *snor= RE_vlakren_get_surfnor(obr, vlr, 1); - copy_v3_v3(snor, sd->surfnor); - } - - if (sd->uvco) { - for (i=0; i<sd->totuv; i++) { - MTFace *mtf; - mtf=RE_vlakren_get_tface(obr, vlr, i, NULL, 1); - mtf->uv[0][0]=mtf->uv[1][0]= - mtf->uv[2][0]=mtf->uv[3][0]=(sd->uvco+2*i)[0]; - mtf->uv[0][1]=mtf->uv[1][1]= - mtf->uv[2][1]=mtf->uv[3][1]=(sd->uvco+2*i)[1]; - } - if (sd->override_uv>=0) { - MTFace *mtf; - mtf=RE_vlakren_get_tface(obr, vlr, sd->override_uv, NULL, 0); - - mtf->uv[0][0]=mtf->uv[3][0]=0.0f; - mtf->uv[1][0]=mtf->uv[2][0]=1.0f; - - mtf->uv[0][1]=mtf->uv[1][1]=(vlr->v1->accum+1.0f)/2.0f; - mtf->uv[2][1]=mtf->uv[3][1]=(vlr->v3->accum+1.0f)/2.0f; - } - } - if (sd->mcol) { - for (i=0; i<sd->totcol; i++) { - MCol *mc; - mc=RE_vlakren_get_mcol(obr, vlr, i, NULL, 1); - mc[0]=mc[1]=mc[2]=mc[3]=sd->mcol[i]; - mc[0]=mc[1]=mc[2]=mc[3]=sd->mcol[i]; - } - } - } -} - -static void static_particle_wire(ObjectRen *obr, Material *ma, const float vec[3], const float vec1[3], int first, int line) -{ - VlakRen *vlr; - static VertRen *v1; - - if (line) { - vlr= RE_findOrAddVlak(obr, obr->totvlak++); - vlr->v1= RE_findOrAddVert(obr, obr->totvert++); - vlr->v2= RE_findOrAddVert(obr, obr->totvert++); - vlr->v3= vlr->v2; - vlr->v4= NULL; - - copy_v3_v3(vlr->v1->co, vec); - copy_v3_v3(vlr->v2->co, vec1); - - sub_v3_v3v3(vlr->n, vec, vec1); - normalize_v3(vlr->n); - copy_v3_v3(vlr->v1->n, vlr->n); - copy_v3_v3(vlr->v2->n, vlr->n); - - vlr->mat= ma; - vlr->ec= ME_V1V2; - - } - else if (first) { - v1= RE_findOrAddVert(obr, obr->totvert++); - copy_v3_v3(v1->co, vec); - } - else { - vlr= RE_findOrAddVlak(obr, obr->totvlak++); - vlr->v1= v1; - vlr->v2= RE_findOrAddVert(obr, obr->totvert++); - vlr->v3= vlr->v2; - vlr->v4= NULL; - - v1= vlr->v2; /* cycle */ - copy_v3_v3(v1->co, vec); - - sub_v3_v3v3(vlr->n, vec, vec1); - normalize_v3(vlr->n); - copy_v3_v3(v1->n, vlr->n); - - vlr->mat= ma; - vlr->ec= ME_V1V2; - } - -} - -static void particle_curve(Render *re, ObjectRen *obr, DerivedMesh *dm, Material *ma, ParticleStrandData *sd, - const float loc[3], const float loc1[3], int seed, float *pa_co) -{ - HaloRen *har = NULL; - - if (ma->material_type == MA_TYPE_WIRE) - static_particle_wire(obr, ma, loc, loc1, sd->first, sd->line); - else if (ma->material_type == MA_TYPE_HALO) { - har= RE_inithalo_particle(re, obr, dm, ma, loc, loc1, sd->orco, sd->uvco, sd->size, 1.0, seed, pa_co); - if (har) har->lay= obr->ob->lay; - } - else - static_particle_strand(re, obr, ma, sd, loc, loc1); -} -static void particle_billboard(Render *re, ObjectRen *obr, Material *ma, ParticleBillboardData *bb) -{ - VlakRen *vlr; - MTFace *mtf; - float xvec[3], yvec[3], zvec[3], bb_center[3]; - /* Number of tiles */ - int totsplit = bb->uv_split * bb->uv_split; - int tile, x, y; - /* Tile offsets */ - float uvx = 0.0f, uvy = 0.0f, uvdx = 1.0f, uvdy = 1.0f, time = 0.0f; - - vlr= RE_findOrAddVlak(obr, obr->totvlak++); - vlr->v1= RE_findOrAddVert(obr, obr->totvert++); - vlr->v2= RE_findOrAddVert(obr, obr->totvert++); - vlr->v3= RE_findOrAddVert(obr, obr->totvert++); - vlr->v4= RE_findOrAddVert(obr, obr->totvert++); - - psys_make_billboard(bb, xvec, yvec, zvec, bb_center); - - add_v3_v3v3(vlr->v1->co, bb_center, xvec); - add_v3_v3(vlr->v1->co, yvec); - mul_m4_v3(re->viewmat, vlr->v1->co); - - sub_v3_v3v3(vlr->v2->co, bb_center, xvec); - add_v3_v3(vlr->v2->co, yvec); - mul_m4_v3(re->viewmat, vlr->v2->co); - - sub_v3_v3v3(vlr->v3->co, bb_center, xvec); - sub_v3_v3v3(vlr->v3->co, vlr->v3->co, yvec); - mul_m4_v3(re->viewmat, vlr->v3->co); - - add_v3_v3v3(vlr->v4->co, bb_center, xvec); - sub_v3_v3(vlr->v4->co, yvec); - mul_m4_v3(re->viewmat, vlr->v4->co); - - normal_quad_v3(vlr->n, vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co); - copy_v3_v3(vlr->v1->n, vlr->n); - copy_v3_v3(vlr->v2->n, vlr->n); - copy_v3_v3(vlr->v3->n, vlr->n); - copy_v3_v3(vlr->v4->n, vlr->n); - - vlr->mat= ma; - vlr->ec= ME_V2V3; - - if (bb->uv_split > 1) { - uvdx = uvdy = 1.0f / (float)bb->uv_split; - - if (ELEM(bb->anim, PART_BB_ANIM_AGE, PART_BB_ANIM_FRAME)) { - if (bb->anim == PART_BB_ANIM_FRAME) - time = ((int)(bb->time * bb->lifetime) % totsplit)/(float)totsplit; - else - time = bb->time; - } - else if (bb->anim == PART_BB_ANIM_ANGLE) { - if (bb->align == PART_BB_VIEW) { - time = (float)fmod((bb->tilt + 1.0f) / 2.0f, 1.0); - } - else { - float axis1[3] = {0.0f, 0.0f, 0.0f}; - float axis2[3] = {0.0f, 0.0f, 0.0f}; - - axis1[(bb->align + 1) % 3] = 1.0f; - axis2[(bb->align + 2) % 3] = 1.0f; - - if (bb->lock == 0) { - zvec[bb->align] = 0.0f; - normalize_v3(zvec); - } - - time = saacos(dot_v3v3(zvec, axis1)) / (float)M_PI; - - if (dot_v3v3(zvec, axis2) < 0.0f) - time = 1.0f - time / 2.0f; - else - time /= 2.0f; - } - } - - if (bb->split_offset == PART_BB_OFF_LINEAR) - time = (float)fmod(time + (float)bb->num / (float)totsplit, 1.0f); - else if (bb->split_offset==PART_BB_OFF_RANDOM) - time = (float)fmod(time + bb->random, 1.0f); - - /* Find the coordinates in tile space (integer), then convert to UV - * space (float). Note that Y is flipped. */ - tile = (int)((time + FLT_EPSILON10) * totsplit); - x = tile % bb->uv_split; - y = tile / bb->uv_split; - y = (bb->uv_split - 1) - y; - uvx = uvdx * x; - uvy = uvdy * y; - } - - /* normal UVs */ - if (bb->uv[0] >= 0) { - mtf = RE_vlakren_get_tface(obr, vlr, bb->uv[0], NULL, 1); - mtf->uv[0][0] = 1.0f; - mtf->uv[0][1] = 1.0f; - mtf->uv[1][0] = 0.0f; - mtf->uv[1][1] = 1.0f; - mtf->uv[2][0] = 0.0f; - mtf->uv[2][1] = 0.0f; - mtf->uv[3][0] = 1.0f; - mtf->uv[3][1] = 0.0f; - } - - /* time-index UVs */ - if (bb->uv[1] >= 0) { - mtf = RE_vlakren_get_tface(obr, vlr, bb->uv[1], NULL, 1); - mtf->uv[0][0] = mtf->uv[1][0] = mtf->uv[2][0] = mtf->uv[3][0] = bb->time; - mtf->uv[0][1] = mtf->uv[1][1] = mtf->uv[2][1] = mtf->uv[3][1] = (float)bb->num/(float)bb->totnum; - } - - /* split UVs */ - if (bb->uv_split > 1 && bb->uv[2] >= 0) { - mtf = RE_vlakren_get_tface(obr, vlr, bb->uv[2], NULL, 1); - mtf->uv[0][0] = uvx + uvdx; - mtf->uv[0][1] = uvy + uvdy; - mtf->uv[1][0] = uvx; - mtf->uv[1][1] = uvy + uvdy; - mtf->uv[2][0] = uvx; - mtf->uv[2][1] = uvy; - mtf->uv[3][0] = uvx + uvdx; - mtf->uv[3][1] = uvy; - } -} -static void particle_normal_ren(short ren_as, ParticleSettings *part, Render *re, ObjectRen *obr, DerivedMesh *dm, Material *ma, ParticleStrandData *sd, ParticleBillboardData *bb, ParticleKey *state, int seed, float hasize, float *pa_co) -{ - float loc[3], loc0[3], loc1[3], vel[3]; - - copy_v3_v3(loc, state->co); - - if (ren_as != PART_DRAW_BB) - mul_m4_v3(re->viewmat, loc); - - switch (ren_as) { - case PART_DRAW_LINE: - sd->line = 1; - sd->time = 0.0f; - sd->size = hasize; - - mul_v3_mat3_m4v3(vel, re->viewmat, state->vel); - normalize_v3(vel); - - if (part->draw & PART_DRAW_VEL_LENGTH) - mul_v3_fl(vel, len_v3(state->vel)); - - madd_v3_v3v3fl(loc0, loc, vel, -part->draw_line[0]); - madd_v3_v3v3fl(loc1, loc, vel, part->draw_line[1]); - - particle_curve(re, obr, dm, ma, sd, loc0, loc1, seed, pa_co); - - break; - - case PART_DRAW_BB: - - copy_v3_v3(bb->vec, loc); - copy_v3_v3(bb->vel, state->vel); - - particle_billboard(re, obr, ma, bb); - - break; - - default: - { - HaloRen *har = NULL; - - har = RE_inithalo_particle(re, obr, dm, ma, loc, NULL, sd->orco, sd->uvco, hasize, 0.0, seed, pa_co); - - if (har) har->lay= obr->ob->lay; - - break; - } - } -} -static void get_particle_uvco_mcol(short from, DerivedMesh *dm, float *fuv, int num, ParticleStrandData *sd) -{ - int i; - - /* get uvco */ - if (sd->uvco && ELEM(from, PART_FROM_FACE, PART_FROM_VOLUME)) { - for (i=0; i<sd->totuv; i++) { - if (!ELEM(num, DMCACHE_NOTFOUND, DMCACHE_ISCHILD)) { - MFace *mface = dm->getTessFaceData(dm, num, CD_MFACE); - MTFace *mtface = (MTFace*)CustomData_get_layer_n(&dm->faceData, CD_MTFACE, i); - mtface += num; - - psys_interpolate_uvs(mtface, mface->v4, fuv, sd->uvco + 2 * i); - } - else { - sd->uvco[2*i] = 0.0f; - sd->uvco[2*i + 1] = 0.0f; - } - } - } - - /* get mcol */ - if (sd->mcol && ELEM(from, PART_FROM_FACE, PART_FROM_VOLUME)) { - for (i=0; i<sd->totcol; i++) { - if (!ELEM(num, DMCACHE_NOTFOUND, DMCACHE_ISCHILD)) { - MFace *mface = dm->getTessFaceData(dm, num, CD_MFACE); - MCol *mc = (MCol*)CustomData_get_layer_n(&dm->faceData, CD_MCOL, i); - mc += num * 4; - - psys_interpolate_mcol(mc, mface->v4, fuv, sd->mcol + i); - } - else - memset(&sd->mcol[i], 0, sizeof(MCol)); - } - } -} -static int render_new_particle_system(Depsgraph *depsgraph, Render *re, - ObjectRen *obr, ParticleSystem *psys, int timeoffset) -{ - Object *ob= obr->ob; -// Object *tob=0; - Material *ma = NULL; - ParticleSystemModifierData *psmd; - ParticleSystem *tpsys = NULL; - ParticleSettings *part, *tpart = NULL; - ParticleData *pars, *pa = NULL, *tpa = NULL; - ParticleKey *states = NULL; - ParticleKey state; - ParticleCacheKey *cache = NULL; - ParticleBillboardData bb; - ParticleSimulationData sim = {NULL}; - ParticleStrandData sd; - StrandBuffer *strandbuf = NULL; - StrandVert *svert = NULL; - StrandBound *sbound = NULL; - StrandRen *strand = NULL; - RNG *rng = NULL; - float loc[3], loc1[3], loc0[3], mat[4][4], nmat[3][3], co[3], nor[3], duplimat[4][4]; - float strandlen=0.0f, curlen=0.0f; - float hasize, pa_size, r_tilt, r_length; - float pa_time, pa_birthtime, pa_dietime; - float random, pa_co[3]; - const float cfra= BKE_scene_frame_get(re->scene); - int i, a, k, max_k=0, totpart; - bool do_surfacecache = false, use_duplimat = false; - int totchild=0, step_nbr; - int seed, path_nbr=0, orco1=0, num; - int totface; - - const int *index_mf_to_mpoly = NULL; - const int *index_mp_to_orig = NULL; - -/* 1. check that everything is ok & updated */ - if (psys==NULL) - return 0; - - part=psys->part; - pars=psys->particles; - - if (part==NULL || pars==NULL || !psys_check_enabled(ob, psys, G.is_rendering)) - return 0; - - if (part->ren_as==PART_DRAW_OB || part->ren_as==PART_DRAW_GR || part->ren_as==PART_DRAW_NOT) - return 1; - - if ((re->r.scemode & R_VIEWPORT_PREVIEW) && (ob->mode & OB_MODE_PARTICLE_EDIT)) - return 0; - - if (part->ren_as == PART_DRAW_BB && part->bb_ob == NULL && RE_GetCamera(re) == NULL) - return 0; - -/* 2. start initializing things */ - - /* last possibility to bail out! */ - psmd = psys_get_modifier(ob, psys); - if (!(psmd->modifier.mode & eModifierMode_Render)) - return 0; - - sim.depsgraph = depsgraph; - sim.scene = re->scene; - sim.ob = ob; - sim.psys = psys; - sim.psmd = psmd; - - if (part->phystype==PART_PHYS_KEYED) - psys_count_keyed_targets(&sim); - - totchild=psys->totchild; - - /* can happen for disconnected/global hair */ - if (part->type==PART_HAIR && !psys->childcache) - totchild= 0; - - if (re->r.scemode & R_VIEWPORT_PREVIEW) { /* preview render */ - totchild = (int)((float)totchild * (float)part->disp / 100.0f); - step_nbr = 1 << part->draw_step; - } - else { - step_nbr = 1 << part->ren_step; - } - if (ELEM(part->kink, PART_KINK_SPIRAL)) - step_nbr += part->kink_extra_steps; - - psys->flag |= PSYS_DRAWING; - - rng= BLI_rng_new(psys->seed); - - totpart=psys->totpart; - - memset(&sd, 0, sizeof(ParticleStrandData)); - sd.override_uv = -1; - -/* 2.1 setup material stff */ - ma= give_render_material(re, ob, part->omat); - -#if 0 /* XXX old animation system */ - if (ma->ipo) { - calc_ipo(ma->ipo, cfra); - execute_ipo((ID *)ma, ma->ipo); - } -#endif /* XXX old animation system */ - - hasize = ma->hasize; - seed = ma->seed1; - - re->flag |= R_HALO; - - RE_set_customdata_names(obr, &psmd->dm_final->faceData); - sd.totuv = CustomData_number_of_layers(&psmd->dm_final->faceData, CD_MTFACE); - sd.totcol = CustomData_number_of_layers(&psmd->dm_final->faceData, CD_MCOL); - - if (ma->texco & TEXCO_UV && sd.totuv) { - sd.uvco = MEM_callocN(sd.totuv * 2 * sizeof(float), "particle_uvs"); - - if (ma->strand_uvname[0]) { - sd.override_uv = CustomData_get_named_layer_index(&psmd->dm_final->faceData, CD_MTFACE, ma->strand_uvname); - sd.override_uv -= CustomData_get_layer_index(&psmd->dm_final->faceData, CD_MTFACE); - } - } - else - sd.uvco = NULL; - - if (sd.totcol) - sd.mcol = MEM_callocN(sd.totcol * sizeof(MCol), "particle_mcols"); - -/* 2.2 setup billboards */ - if (part->ren_as == PART_DRAW_BB) { - int first_uv = CustomData_get_layer_index(&psmd->dm_final->faceData, CD_MTFACE); - - bb.uv[0] = CustomData_get_named_layer_index(&psmd->dm_final->faceData, CD_MTFACE, psys->bb_uvname[0]); - if (bb.uv[0] < 0) - bb.uv[0] = CustomData_get_active_layer_index(&psmd->dm_final->faceData, CD_MTFACE); - - bb.uv[1] = CustomData_get_named_layer_index(&psmd->dm_final->faceData, CD_MTFACE, psys->bb_uvname[1]); - - bb.uv[2] = CustomData_get_named_layer_index(&psmd->dm_final->faceData, CD_MTFACE, psys->bb_uvname[2]); - - if (first_uv >= 0) { - bb.uv[0] -= first_uv; - bb.uv[1] -= first_uv; - bb.uv[2] -= first_uv; - } - - bb.align = part->bb_align; - bb.anim = part->bb_anim; - bb.lock = part->draw & PART_DRAW_BB_LOCK; - bb.ob = (part->bb_ob ? part->bb_ob : RE_GetCamera(re)); - bb.split_offset = part->bb_split_offset; - bb.totnum = totpart+totchild; - bb.uv_split = part->bb_uv_split; - } - -/* 2.5 setup matrices */ - mul_m4_m4m4(mat, re->viewmat, ob->obmat); - invert_m4_m4(ob->imat, mat); /* need to be that way, for imat texture */ - transpose_m3_m4(nmat, ob->imat); - - if (psys->flag & PSYS_USE_IMAT) { - /* psys->imat is the original emitter's inverse matrix, ob->obmat is the duplicated object's matrix */ - mul_m4_m4m4(duplimat, ob->obmat, psys->imat); - use_duplimat = true; - } - -/* 2.6 setup strand rendering */ - if (part->ren_as == PART_DRAW_PATH && psys->pathcache) { - path_nbr = step_nbr; - - if (path_nbr) { - if (!ELEM(ma->material_type, MA_TYPE_HALO, MA_TYPE_WIRE)) { - sd.orco = get_object_orco(re, psys); - if (!sd.orco) { - sd.orco = MEM_mallocN(3*sizeof(float)*(totpart+totchild), "particle orcos"); - set_object_orco(re, psys, sd.orco); - } - } - } - - if (part->draw & PART_DRAW_REN_ADAPT) { - sd.adapt = 1; - sd.adapt_pix = (float)part->adapt_pix; - sd.adapt_angle = cosf(DEG2RADF((float)part->adapt_angle)); - } - - if (part->draw & PART_DRAW_REN_STRAND) { - strandbuf= RE_addStrandBuffer(obr, (totpart+totchild)*(path_nbr+1)); - strandbuf->ma= ma; - strandbuf->lay= ob->lay; - copy_m4_m4(strandbuf->winmat, re->winmat); - strandbuf->winx= re->winx; - strandbuf->winy= re->winy; - strandbuf->maxdepth= 2; - strandbuf->adaptcos= cosf(DEG2RADF((float)part->adapt_angle)); - strandbuf->overrideuv= sd.override_uv; - strandbuf->minwidth= ma->strand_min; - - if (ma->strand_widthfade == 0.0f) - strandbuf->widthfade= -1.0f; - else if (ma->strand_widthfade >= 1.0f) - strandbuf->widthfade= 2.0f - ma->strand_widthfade; - else - strandbuf->widthfade= 1.0f/MAX2(ma->strand_widthfade, 1e-5f); - - if (part->flag & PART_HAIR_BSPLINE) - strandbuf->flag |= R_STRAND_BSPLINE; - if (ma->mode & MA_STR_B_UNITS) - strandbuf->flag |= R_STRAND_B_UNITS; - - svert= strandbuf->vert; - - if (re->r.mode & R_SPEED) - do_surfacecache = true; - else if ((re->wrld.mode & (WO_AMB_OCC|WO_ENV_LIGHT|WO_INDIRECT_LIGHT)) && (re->wrld.ao_gather_method == WO_AOGATHER_APPROX)) - if (ma->amb != 0.0f) - do_surfacecache = true; - - totface= psmd->dm_final->getNumTessFaces(psmd->dm_final); - index_mf_to_mpoly = psmd->dm_final->getTessFaceDataArray(psmd->dm_final, CD_ORIGINDEX); - index_mp_to_orig = psmd->dm_final->getPolyDataArray(psmd->dm_final, CD_ORIGINDEX); - if (index_mf_to_mpoly == NULL) { - index_mp_to_orig = NULL; - } - for (a=0; a<totface; a++) - strandbuf->totbound = max_ii(strandbuf->totbound, (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, a): a); - - strandbuf->totbound++; - strandbuf->bound= MEM_callocN(sizeof(StrandBound)*strandbuf->totbound, "StrandBound"); - sbound= strandbuf->bound; - sbound->start= sbound->end= 0; - } - } - - if (sd.orco == NULL) { - sd.orco = MEM_mallocN(3 * sizeof(float), "particle orco"); - orco1 = 1; - } - - if (path_nbr == 0) - psys->lattice_deform_data = psys_create_lattice_deform_data(&sim); - -/* 3. start creating renderable things */ - for (a=0, pa=pars; a<totpart+totchild; a++, pa++, seed++) { - random = BLI_rng_get_float(rng); - /* setup per particle individual stuff */ - if (a<totpart) { - if (pa->flag & PARS_UNEXIST) continue; - - pa_time=(cfra-pa->time)/pa->lifetime; - pa_birthtime = pa->time; - pa_dietime = pa->dietime; - - hasize = ma->hasize; - - /* XXX 'tpsys' is alwyas NULL, this code won't run! */ - /* get orco */ - if (tpsys && part->phystype == PART_PHYS_NO) { - tpa = tpsys->particles + pa->num; - psys_particle_on_emitter( - psmd, - tpart->from, tpa->num, pa->num_dmcache, tpa->fuv, - tpa->foffset, co, nor, NULL, NULL, sd.orco, NULL); - } - else { - psys_particle_on_emitter( - psmd, - part->from, pa->num, pa->num_dmcache, - pa->fuv, pa->foffset, co, nor, NULL, NULL, sd.orco, NULL); - } - - /* get uvco & mcol */ - num= pa->num_dmcache; - - if (num == DMCACHE_NOTFOUND) - if (pa->num < psmd->dm_final->getNumTessFaces(psmd->dm_final)) - num= pa->num; - - get_particle_uvco_mcol(part->from, psmd->dm_final, pa->fuv, num, &sd); - - pa_size = pa->size; - - r_tilt = 2.0f*(psys_frand(psys, a) - 0.5f); - r_length = psys_frand(psys, a+1); - - if (path_nbr) { - cache = psys->pathcache[a]; - max_k = (int)cache->segments; - } - - if (totchild && (part->draw&PART_DRAW_PARENT)==0) continue; - } - else { - ChildParticle *cpa= psys->child+a-totpart; - - if (path_nbr) { - cache = psys->childcache[a-totpart]; - - if (cache->segments < 0) - continue; - - max_k = (int)cache->segments; - } - - pa_time = psys_get_child_time(psys, cpa, cfra, &pa_birthtime, &pa_dietime); - pa_size = psys_get_child_size(psys, cpa, cfra, &pa_time); - - r_tilt = 2.0f*(psys_frand(psys, a + 21) - 0.5f); - r_length = psys_frand(psys, a + 22); - - num = cpa->num; - - /* get orco */ - if (part->childtype == PART_CHILD_FACES) { - psys_particle_on_emitter( - psmd, - PART_FROM_FACE, cpa->num, DMCACHE_ISCHILD, - cpa->fuv, cpa->foffset, co, nor, NULL, NULL, sd.orco, NULL); - } - else { - ParticleData *par = psys->particles + cpa->parent; - psys_particle_on_emitter( - psmd, - part->from, par->num, DMCACHE_ISCHILD, par->fuv, - par->foffset, co, nor, NULL, NULL, sd.orco, NULL); - } - - /* get uvco & mcol */ - if (part->childtype==PART_CHILD_FACES) { - get_particle_uvco_mcol(PART_FROM_FACE, psmd->dm_final, cpa->fuv, cpa->num, &sd); - } - else { - ParticleData *parent = psys->particles + cpa->parent; - num = parent->num_dmcache; - - if (num == DMCACHE_NOTFOUND) - if (parent->num < psmd->dm_final->getNumTessFaces(psmd->dm_final)) - num = parent->num; - - get_particle_uvco_mcol(part->from, psmd->dm_final, parent->fuv, num, &sd); - } - - if (strandbuf) { - int orignum = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, cpa->num) : cpa->num; - - if ((orignum > sbound - strandbuf->bound) && - (orignum < strandbuf->totbound)) - { - sbound = &strandbuf->bound[orignum]; - sbound->start = sbound->end = obr->totstrand; - } - } - } - - /* TEXCO_PARTICLE */ - pa_co[0] = pa_time; - pa_co[1] = 0.f; - pa_co[2] = 0.f; - - /* surface normal shading setup */ - if (ma->mode_l & MA_STR_SURFDIFF) { - mul_m3_v3(nmat, nor); - sd.surfnor= nor; - } - else - sd.surfnor= NULL; - - /* strand render setup */ - if (strandbuf) { - strand= RE_findOrAddStrand(obr, obr->totstrand++); - strand->buffer= strandbuf; - strand->vert= svert; - copy_v3_v3(strand->orco, sd.orco); - - if (sd.surfnor) { - float *snor= RE_strandren_get_surfnor(obr, strand, 1); - copy_v3_v3(snor, sd.surfnor); - } - - if (do_surfacecache && num >= 0) { - int *facenum= RE_strandren_get_face(obr, strand, 1); - *facenum= num; - } - - if (sd.uvco) { - for (i=0; i<sd.totuv; i++) { - if (i != sd.override_uv) { - float *uv= RE_strandren_get_uv(obr, strand, i, NULL, 1); - - uv[0]= sd.uvco[2*i]; - uv[1]= sd.uvco[2*i+1]; - } - } - } - if (sd.mcol) { - for (i=0; i<sd.totcol; i++) { - MCol *mc= RE_strandren_get_mcol(obr, strand, i, NULL, 1); - *mc = sd.mcol[i]; - } - } - - sbound->end++; - } - - /* strandco computation setup */ - if (path_nbr) { - strandlen= 0.0f; - curlen= 0.0f; - for (k=1; k<=path_nbr; k++) - if (k<=max_k) - strandlen += len_v3v3((cache+k-1)->co, (cache+k)->co); - } - - if (path_nbr) { - /* render strands */ - for (k=0; k<=path_nbr; k++) { - float time; - - if (k<=max_k) { - copy_v3_v3(state.co, (cache+k)->co); - copy_v3_v3(state.vel, (cache+k)->vel); - } - else - continue; - - if (k > 0) - curlen += len_v3v3((cache+k-1)->co, (cache+k)->co); - time= curlen/strandlen; - - copy_v3_v3(loc, state.co); - mul_m4_v3(re->viewmat, loc); - - if (strandbuf) { - copy_v3_v3(svert->co, loc); - svert->strandco= -1.0f + 2.0f*time; - svert++; - strand->totvert++; - } - else { - sd.size = hasize; - - if (k==1) { - sd.first = 1; - sd.time = 0.0f; - sub_v3_v3v3(loc0, loc1, loc); - add_v3_v3v3(loc0, loc1, loc0); - - particle_curve(re, obr, psmd->dm_final, ma, &sd, loc1, loc0, seed, pa_co); - } - - sd.first = 0; - sd.time = time; - - if (k) - particle_curve(re, obr, psmd->dm_final, ma, &sd, loc, loc1, seed, pa_co); - - copy_v3_v3(loc1, loc); - } - } - - } - else { - /* render normal particles */ - if (part->trail_count > 1) { - float length = part->path_end * (1.0f - part->randlength * r_length); - int trail_count = part->trail_count * (1.0f - part->randlength * r_length); - float ct = (part->draw & PART_ABS_PATH_TIME) ? cfra : pa_time; - float dt = length / (trail_count ? (float)trail_count : 1.0f); - - /* make sure we have pointcache in memory before getting particle on path */ - psys_make_temp_pointcache(ob, psys); - - for (i=0; i < trail_count; i++, ct -= dt) { - if (part->draw & PART_ABS_PATH_TIME) { - if (ct < pa_birthtime || ct > pa_dietime) - continue; - } - else if (ct < 0.0f || ct > 1.0f) - continue; - - state.time = (part->draw & PART_ABS_PATH_TIME) ? -ct : ct; - psys_get_particle_on_path(&sim, a, &state, 1); - - if (psys->parent) - mul_m4_v3(psys->parent->obmat, state.co); - - if (use_duplimat) - mul_m4_v4(duplimat, state.co); - - if (part->ren_as == PART_DRAW_BB) { - bb.random = random; - bb.offset[0] = part->bb_offset[0]; - bb.offset[1] = part->bb_offset[1]; - bb.size[0] = part->bb_size[0] * pa_size; - if (part->bb_align==PART_BB_VEL) { - float pa_vel = len_v3(state.vel); - float head = part->bb_vel_head*pa_vel; - float tail = part->bb_vel_tail*pa_vel; - bb.size[1] = part->bb_size[1]*pa_size + head + tail; - /* use offset to adjust the particle center. this is relative to size, so need to divide! */ - if (bb.size[1] > 0.0f) - bb.offset[1] += (head-tail) / bb.size[1]; - } - else - bb.size[1] = part->bb_size[1] * pa_size; - bb.tilt = part->bb_tilt * (1.0f - part->bb_rand_tilt * r_tilt); - bb.time = ct; - bb.num = a; - } - - pa_co[0] = (part->draw & PART_ABS_PATH_TIME) ? (ct-pa_birthtime)/(pa_dietime-pa_birthtime) : ct; - pa_co[1] = (float)i/(float)(trail_count-1); - - particle_normal_ren(part->ren_as, part, re, obr, psmd->dm_final, ma, &sd, &bb, &state, seed, hasize, pa_co); - } - } - else { - state.time=cfra; - if (psys_get_particle_state(&sim, a, &state, 0)==0) - continue; - - if (psys->parent) - mul_m4_v3(psys->parent->obmat, state.co); - - if (use_duplimat) - mul_m4_v3(duplimat, state.co); - - if (part->ren_as == PART_DRAW_BB) { - bb.random = random; - bb.offset[0] = part->bb_offset[0]; - bb.offset[1] = part->bb_offset[1]; - bb.size[0] = part->bb_size[0] * pa_size; - if (part->bb_align==PART_BB_VEL) { - float pa_vel = len_v3(state.vel); - float head = part->bb_vel_head*pa_vel; - float tail = part->bb_vel_tail*pa_vel; - bb.size[1] = part->bb_size[1]*pa_size + head + tail; - /* use offset to adjust the particle center. this is relative to size, so need to divide! */ - if (bb.size[1] > 0.0f) - bb.offset[1] += (head-tail) / bb.size[1]; - } - else - bb.size[1] = part->bb_size[1] * pa_size; - bb.tilt = part->bb_tilt * (1.0f - part->bb_rand_tilt * r_tilt); - bb.time = pa_time; - bb.num = a; - bb.lifetime = pa_dietime-pa_birthtime; - } - - particle_normal_ren(part->ren_as, part, re, obr, psmd->dm_final, ma, &sd, &bb, &state, seed, hasize, pa_co); - } - } - - if (orco1==0) - sd.orco+=3; - - if (re->test_break(re->tbh)) - break; - } - - if (do_surfacecache) - strandbuf->surface= cache_strand_surface(re, obr, psmd->dm_final, mat, timeoffset); - -/* 4. clean up */ -#if 0 /* XXX old animation system */ - if (ma) do_mat_ipo(re->scene, ma); -#endif /* XXX old animation system */ - - if (orco1) - MEM_freeN(sd.orco); - - if (sd.uvco) - MEM_freeN(sd.uvco); - - if (sd.mcol) - MEM_freeN(sd.mcol); - - if (states) - MEM_freeN(states); - - BLI_rng_free(rng); - - psys->flag &= ~PSYS_DRAWING; - - if (psys->lattice_deform_data) { - end_latt_deform(psys->lattice_deform_data); - psys->lattice_deform_data = NULL; - } - - if (path_nbr && (ma->mode_l & MA_TANGENT_STR)==0) - calc_vertexnormals(re, obr, 1, 0, 0); - - return 1; -} - -/* ------------------------------------------------------------------------- */ -/* Halo's */ -/* ------------------------------------------------------------------------- */ - -static void make_render_halos(Render *re, ObjectRen *obr, Mesh *UNUSED(me), int totvert, MVert *mvert, Material *ma, float *orco) -{ - Object *ob= obr->ob; - HaloRen *har; - float xn, yn, zn, nor[3], view[3]; - float vec[3], hasize, mat[4][4], imat[3][3]; - int a, ok, seed= ma->seed1; - - mul_m4_m4m4(mat, re->viewmat, ob->obmat); - copy_m3_m4(imat, ob->imat); - - re->flag |= R_HALO; - - for (a=0; a<totvert; a++, mvert++) { - ok= 1; - - if (ok) { - hasize= ma->hasize; - - copy_v3_v3(vec, mvert->co); - mul_m4_v3(mat, vec); - - if (ma->mode & MA_HALOPUNO) { - xn= mvert->no[0]; - yn= mvert->no[1]; - zn= mvert->no[2]; - - /* transpose ! */ - nor[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn; - nor[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn; - nor[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn; - normalize_v3(nor); - - copy_v3_v3(view, vec); - normalize_v3(view); - - zn = dot_v3v3(nor, view); - if (zn>=0.0f) hasize= 0.0f; - else hasize*= zn*zn*zn*zn; - } - - if (orco) har= RE_inithalo(re, obr, ma, vec, NULL, orco, hasize, 0.0, seed); - else har= RE_inithalo(re, obr, ma, vec, NULL, mvert->co, hasize, 0.0, seed); - if (har) har->lay= ob->lay; - } - if (orco) orco+= 3; - seed++; - } -} - -static int verghalo(const void *a1, const void *a2) -{ - const HaloRen *har1= *(const HaloRen**)a1; - const HaloRen *har2= *(const HaloRen**)a2; - - if (har1->zs < har2->zs) return 1; - else if (har1->zs > har2->zs) return -1; - return 0; -} - -static void sort_halos(Render *re, int totsort) -{ - ObjectRen *obr; - HaloRen *har= NULL, **haso; - int a; - - if (re->tothalo==0) return; - - re->sortedhalos= MEM_callocN(sizeof(HaloRen*)*re->tothalo, "sorthalos"); - haso= re->sortedhalos; - - for (obr=re->objecttable.first; obr; obr=obr->next) { - for (a=0; a<obr->tothalo; a++) { - if ((a & 255)==0) har= obr->bloha[a>>8]; - else har++; - - *(haso++)= har; - } - } - - qsort(re->sortedhalos, totsort, sizeof(HaloRen*), verghalo); -} - -/* ------------------------------------------------------------------------- */ -/* Displacement Mapping */ -/* ------------------------------------------------------------------------- */ - -static short test_for_displace(Render *re, Object *ob) -{ - /* return 1 when this object uses displacement textures. */ - Material *ma; - int i; - - for (i=1; i<=ob->totcol; i++) { - ma=give_render_material(re, ob, i); - /* ma->mapto is ORed total of all mapto channels */ - if (ma && (ma->mapto & MAP_DISPLACE)) return 1; - } - return 0; -} - -static void displace_render_vert(Render *re, ObjectRen *obr, ShadeInput *shi, VertRen *vr, int vindex, float *scale) -{ - MTFace *tface; - short texco= shi->mat->texco; - float sample=0, displace[3]; - char *name; - int i; - - /* shi->co is current render coord, just make sure at least some vector is here */ - copy_v3_v3(shi->co, vr->co); - /* vertex normal is used for textures type 'col' and 'var' */ - copy_v3_v3(shi->vn, vr->n); - - if (texco & TEXCO_UV) { - shi->totuv= 0; - shi->actuv= obr->actmtface; - - for (i=0; (tface=RE_vlakren_get_tface(obr, shi->vlr, i, &name, 0)); i++) { - ShadeInputUV *suv= &shi->uv[i]; - - /* shi.uv needs scale correction from tface uv */ - suv->uv[0]= 2*tface->uv[vindex][0]-1.0f; - suv->uv[1]= 2*tface->uv[vindex][1]-1.0f; - suv->uv[2]= 0.0f; - suv->name= name; - shi->totuv++; - } - } - - /* set all rendercoords, 'texco' is an ORed value for all textures needed */ - if ((texco & TEXCO_ORCO) && (vr->orco)) { - copy_v3_v3(shi->lo, vr->orco); - } - if (texco & TEXCO_GLOB) { - copy_v3_v3(shi->gl, shi->co); - mul_m4_v3(re->viewinv, shi->gl); - } - if (texco & TEXCO_NORM) { - copy_v3_v3(shi->orn, shi->vn); - } - if (texco & TEXCO_REFL) { - /* not (yet?) */ - } - if (texco & TEXCO_STRESS) { - const float *s= RE_vertren_get_stress(obr, vr, 0); - - if (s) { - shi->stress= *s; - if (shi->stress<1.0f) shi->stress-= 1.0f; - else shi->stress= (shi->stress-1.0f)/shi->stress; - } - else - shi->stress= 0.0f; - } - - shi->displace[0]= shi->displace[1]= shi->displace[2]= 0.0; - - do_material_tex(shi, re); - - //printf("no=%f, %f, %f\nbefore co=%f, %f, %f\n", vr->n[0], vr->n[1], vr->n[2], - //vr->co[0], vr->co[1], vr->co[2]); - - displace[0]= shi->displace[0] * scale[0]; - displace[1]= shi->displace[1] * scale[1]; - displace[2]= shi->displace[2] * scale[2]; - - /* 0.5 could become button once? */ - vr->co[0] += displace[0]; - vr->co[1] += displace[1]; - vr->co[2] += displace[2]; - - //printf("after co=%f, %f, %f\n", vr->co[0], vr->co[1], vr->co[2]); - - /* we just don't do this vertex again, bad luck for other face using same vertex with - * different material... */ - vr->flag |= 1; - - /* Pass sample back so displace_face can decide which way to split the quad */ - sample = shi->displace[0]*shi->displace[0]; - sample += shi->displace[1]*shi->displace[1]; - sample += shi->displace[2]*shi->displace[2]; - - vr->accum=sample; - /* Should be sqrt(sample), but I'm only looking for "bigger". Save the cycles. */ - return; -} - -static void displace_render_face(Render *re, ObjectRen *obr, VlakRen *vlr, float *scale) -{ - ShadeInput shi; - - /* Warning, This is not that nice, and possibly a bit slow, - * however some variables were not initialized properly in, unless using shade_input_initialize(...), we need to do a memset */ - memset(&shi, 0, sizeof(ShadeInput)); - /* end warning! - Campbell */ - - /* set up shadeinput struct for multitex() */ - - /* memset above means we don't need this */ - /*shi.osatex= 0;*/ /* signal not to use dx[] and dy[] texture AA vectors */ - - shi.obr= obr; - shi.vlr= vlr; /* current render face */ - shi.mat= vlr->mat; /* current input material */ - shi.thread= 0; - - /* TODO, assign these, displacement with new bumpmap is skipped without - campbell */ -#if 0 - /* order is not known ? */ - shi.v1= vlr->v1; - shi.v2= vlr->v2; - shi.v3= vlr->v3; -#endif - - /* Displace the verts, flag is set when done */ - if (!vlr->v1->flag) - displace_render_vert(re, obr, &shi, vlr->v1, 0, scale); - - if (!vlr->v2->flag) - displace_render_vert(re, obr, &shi, vlr->v2, 1, scale); - - if (!vlr->v3->flag) - displace_render_vert(re, obr, &shi, vlr->v3, 2, scale); - - if (vlr->v4) { - if (!vlr->v4->flag) - displace_render_vert(re, obr, &shi, vlr->v4, 3, scale); - - /* closest in displace value. This will help smooth edges. */ - if (fabsf(vlr->v1->accum - vlr->v3->accum) > fabsf(vlr->v2->accum - vlr->v4->accum)) vlr->flag |= R_DIVIDE_24; - else vlr->flag &= ~R_DIVIDE_24; - } - - /* Recalculate the face normal - if flipped before, flip now */ - if (vlr->v4) { - normal_quad_v3(vlr->n, vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co); - } - else { - normal_tri_v3(vlr->n, vlr->v3->co, vlr->v2->co, vlr->v1->co); - } -} - -static void displace(Render *re, ObjectRen *obr) -{ - VertRen *vr; - VlakRen *vlr; -// float min[3]={1e30, 1e30, 1e30}, max[3]={-1e30, -1e30, -1e30}; - float scale[3]={1.0f, 1.0f, 1.0f}, temp[3];//, xn - int i; //, texflag=0; - Object *obt; - - /* Object Size with parenting */ - obt=obr->ob; - while (obt) { - mul_v3_v3v3(temp, obt->size, obt->dscale); - scale[0]*=temp[0]; scale[1]*=temp[1]; scale[2]*=temp[2]; - obt=obt->parent; - } - - /* Clear all flags */ - for (i=0; i<obr->totvert; i++) { - vr= RE_findOrAddVert(obr, i); - vr->flag= 0; - } - - for (i=0; i<obr->totvlak; i++) { - vlr=RE_findOrAddVlak(obr, i); - displace_render_face(re, obr, vlr, scale); - } - - /* Recalc vertex normals */ - calc_vertexnormals(re, obr, 1, 0, 0); -} - -/* ------------------------------------------------------------------------- */ -/* Metaball */ -/* ------------------------------------------------------------------------- */ - -static void init_render_mball(Depsgraph *depsgraph, Render *re, ObjectRen *obr) -{ - Object *ob= obr->ob; - DispList *dl; - VertRen *ver; - VlakRen *vlr, *vlr1; - Material *ma; - float *data, *nors, *orco=NULL, mat[4][4], imat[3][3], xn, yn, zn; - int a, need_orco, vlakindex, *index, negative_scale; - ListBase dispbase= {NULL, NULL}; - - if (ob!=BKE_mball_basis_find(re->scene, ob)) - return; - - mul_m4_m4m4(mat, re->viewmat, ob->obmat); - invert_m4_m4(ob->imat, mat); - copy_m3_m4(imat, ob->imat); - negative_scale = is_negative_m4(mat); - - ma= give_render_material(re, ob, 1); - - need_orco= 0; - if (ma->texco & TEXCO_ORCO) { - need_orco= 1; - } - - BKE_displist_make_mball_forRender(depsgraph, re->scene, ob, &dispbase); - dl= dispbase.first; - if (dl == NULL) return; - - data= dl->verts; - nors= dl->nors; - if (need_orco) { - orco= get_object_orco(re, ob); - - if (!orco) { - /* orco hasn't been found in cache - create new one and add to cache */ - orco= BKE_mball_make_orco(ob, &dispbase); - set_object_orco(re, ob, orco); - } - } - - for (a=0; a<dl->nr; a++, data+=3, nors+=3) { - - ver= RE_findOrAddVert(obr, obr->totvert++); - copy_v3_v3(ver->co, data); - mul_m4_v3(mat, ver->co); - - /* render normals are inverted */ - xn= -nors[0]; - yn= -nors[1]; - zn= -nors[2]; - - /* transpose ! */ - ver->n[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn; - ver->n[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn; - ver->n[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn; - normalize_v3(ver->n); - //if (ob->transflag & OB_NEG_SCALE) negate_v3(ver->n); - - if (need_orco) { - ver->orco= orco; - orco+=3; - } - } - - index= dl->index; - for (a=0; a<dl->parts; a++, index+=4) { - - vlr= RE_findOrAddVlak(obr, obr->totvlak++); - vlr->v1= RE_findOrAddVert(obr, index[0]); - vlr->v2= RE_findOrAddVert(obr, index[1]); - vlr->v3= RE_findOrAddVert(obr, index[2]); - vlr->v4 = NULL; - - if (negative_scale) - normal_tri_v3(vlr->n, vlr->v1->co, vlr->v2->co, vlr->v3->co); - else - normal_tri_v3(vlr->n, vlr->v3->co, vlr->v2->co, vlr->v1->co); - - vlr->mat= ma; - vlr->flag= ME_SMOOTH; - vlr->ec= 0; - - /* mball -too bad- always has triangles, because quads can be non-planar */ - if (index[3] && index[3]!=index[2]) { - vlr1= RE_findOrAddVlak(obr, obr->totvlak++); - vlakindex= vlr1->index; - *vlr1= *vlr; - vlr1->index= vlakindex; - vlr1->v2= vlr1->v3; - vlr1->v3= RE_findOrAddVert(obr, index[3]); - if (negative_scale) - normal_tri_v3(vlr1->n, vlr1->v1->co, vlr1->v2->co, vlr1->v3->co); - else - normal_tri_v3(vlr1->n, vlr1->v3->co, vlr1->v2->co, vlr1->v1->co); - } - } - - /* enforce display lists remade */ - BKE_displist_free(&dispbase); -} - -/* ------------------------------------------------------------------------- */ -/* Surfaces and Curves */ -/* ------------------------------------------------------------------------- */ - -/* returns amount of vertices added for orco */ -static int dl_surf_to_renderdata(ObjectRen *obr, DispList *dl, Material **matar, float *orco, float mat[4][4]) -{ - VertRen *v1, *v2, *v3, *v4, *ver; - VlakRen *vlr, *vlr1, *vlr2, *vlr3; - float *data, n1[3]; - int u, v, orcoret= 0; - int p1, p2, p3, p4, a; - int sizeu, nsizeu, sizev, nsizev; - int startvert, startvlak; - - startvert= obr->totvert; - nsizeu = sizeu = dl->parts; nsizev = sizev = dl->nr; - - data= dl->verts; - for (u = 0; u < sizeu; u++) { - v1 = RE_findOrAddVert(obr, obr->totvert++); /* save this for possible V wrapping */ - copy_v3_v3(v1->co, data); data += 3; - if (orco) { - v1->orco= orco; orco+= 3; orcoret++; - } - mul_m4_v3(mat, v1->co); - - for (v = 1; v < sizev; v++) { - ver= RE_findOrAddVert(obr, obr->totvert++); - copy_v3_v3(ver->co, data); data += 3; - if (orco) { - ver->orco= orco; orco+= 3; orcoret++; - } - mul_m4_v3(mat, ver->co); - } - /* if V-cyclic, add extra vertices at end of the row */ - if (dl->flag & DL_CYCL_U) { - ver= RE_findOrAddVert(obr, obr->totvert++); - copy_v3_v3(ver->co, v1->co); - if (orco) { - ver->orco= orco; orco+=3; orcoret++; //orcobase + 3*(u*sizev + 0); - } - } - } - - /* Done before next loop to get corner vert */ - if (dl->flag & DL_CYCL_U) nsizev++; - if (dl->flag & DL_CYCL_V) nsizeu++; - - /* if U cyclic, add extra row at end of column */ - if (dl->flag & DL_CYCL_V) { - for (v = 0; v < nsizev; v++) { - v1= RE_findOrAddVert(obr, startvert + v); - ver= RE_findOrAddVert(obr, obr->totvert++); - copy_v3_v3(ver->co, v1->co); - if (orco) { - ver->orco= orco; orco+=3; orcoret++; //ver->orco= orcobase + 3*(0*sizev + v); - } - } - } - - sizeu = nsizeu; - sizev = nsizev; - - startvlak= obr->totvlak; - - for (u = 0; u < sizeu - 1; u++) { - p1 = startvert + u * sizev; /* walk through face list */ - p2 = p1 + 1; - p3 = p2 + sizev; - p4 = p3 - 1; - - for (v = 0; v < sizev - 1; v++) { - v1= RE_findOrAddVert(obr, p1); - v2= RE_findOrAddVert(obr, p2); - v3= RE_findOrAddVert(obr, p3); - v4= RE_findOrAddVert(obr, p4); - - vlr= RE_findOrAddVlak(obr, obr->totvlak++); - vlr->v1= v1; vlr->v2= v2; vlr->v3= v3; vlr->v4= v4; - - normal_quad_v3(n1, vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co); - - copy_v3_v3(vlr->n, n1); - - vlr->mat= matar[ dl->col]; - vlr->ec= ME_V1V2+ME_V2V3; - vlr->flag= dl->rt; - - add_v3_v3(v1->n, n1); - add_v3_v3(v2->n, n1); - add_v3_v3(v3->n, n1); - add_v3_v3(v4->n, n1); - - p1++; p2++; p3++; p4++; - } - } - /* fix normals for U resp. V cyclic faces */ - sizeu--; sizev--; /* dec size for face array */ - if (dl->flag & DL_CYCL_V) { - - for (v = 0; v < sizev; v++) { - /* optimize! :*/ - vlr= RE_findOrAddVlak(obr, UVTOINDEX(sizeu - 1, v)); - vlr1= RE_findOrAddVlak(obr, UVTOINDEX(0, v)); - add_v3_v3(vlr1->v1->n, vlr->n); - add_v3_v3(vlr1->v2->n, vlr->n); - add_v3_v3(vlr->v3->n, vlr1->n); - add_v3_v3(vlr->v4->n, vlr1->n); - } - } - if (dl->flag & DL_CYCL_U) { - - for (u = 0; u < sizeu; u++) { - /* optimize! :*/ - vlr= RE_findOrAddVlak(obr, UVTOINDEX(u, 0)); - vlr1= RE_findOrAddVlak(obr, UVTOINDEX(u, sizev-1)); - add_v3_v3(vlr1->v2->n, vlr->n); - add_v3_v3(vlr1->v3->n, vlr->n); - add_v3_v3(vlr->v1->n, vlr1->n); - add_v3_v3(vlr->v4->n, vlr1->n); - } - } - - /* last vertex is an extra case: - * - * ^ ()----()----()----() - * | | | || | - * u | |(0,n)||(0,0)| - * | | || | - * ()====()====[]====() - * | | || | - * | |(m,n)||(m,0)| - * | | || | - * ()----()----()----() - * v -> - * - * vertex [] is no longer shared, therefore distribute - * normals of the surrounding faces to all of the duplicates of [] - */ - - if ((dl->flag & DL_CYCL_V) && (dl->flag & DL_CYCL_U)) { - vlr= RE_findOrAddVlak(obr, UVTOINDEX(sizeu - 1, sizev - 1)); /* (m, n) */ - vlr1= RE_findOrAddVlak(obr, UVTOINDEX(0, 0)); /* (0, 0) */ - add_v3_v3v3(n1, vlr->n, vlr1->n); - vlr2= RE_findOrAddVlak(obr, UVTOINDEX(0, sizev-1)); /* (0, n) */ - add_v3_v3(n1, vlr2->n); - vlr3= RE_findOrAddVlak(obr, UVTOINDEX(sizeu-1, 0)); /* (m, 0) */ - add_v3_v3(n1, vlr3->n); - copy_v3_v3(vlr->v3->n, n1); - copy_v3_v3(vlr1->v1->n, n1); - copy_v3_v3(vlr2->v2->n, n1); - copy_v3_v3(vlr3->v4->n, n1); - } - for (a = startvert; a < obr->totvert; a++) { - ver= RE_findOrAddVert(obr, a); - normalize_v3(ver->n); - } - - - return orcoret; -} - -static void init_render_dm(DerivedMesh *dm, Render *re, ObjectRen *obr, - int timeoffset, float *orco, float mat[4][4]) -{ - Object *ob= obr->ob; - int a, end, totvert, vertofs; - short mat_iter; - VertRen *ver; - VlakRen *vlr; - MVert *mvert = NULL; - MFace *mface; - Material *ma; -#ifdef WITH_FREESTYLE - const int *index_mf_to_mpoly = NULL; - const int *index_mp_to_orig = NULL; - FreestyleFace *ffa = NULL; -#endif - /* Curve *cu= ELEM(ob->type, OB_FONT, OB_CURVE) ? ob->data : NULL; */ - - mvert= dm->getVertArray(dm); - totvert= dm->getNumVerts(dm); - - for (a=0; a<totvert; a++, mvert++) { - ver= RE_findOrAddVert(obr, obr->totvert++); - copy_v3_v3(ver->co, mvert->co); - mul_m4_v3(mat, ver->co); - - if (orco) { - ver->orco= orco; - orco+=3; - } - } - - if (!timeoffset) { - /* store customdata names, because DerivedMesh is freed */ - RE_set_customdata_names(obr, &dm->faceData); - - /* still to do for keys: the correct local texture coordinate */ - - /* faces in order of color blocks */ - vertofs= obr->totvert - totvert; - for (mat_iter= 0; (mat_iter < ob->totcol || (mat_iter==0 && ob->totcol==0)); mat_iter++) { - - ma= give_render_material(re, ob, mat_iter+1); - end= dm->getNumTessFaces(dm); - mface= dm->getTessFaceArray(dm); - -#ifdef WITH_FREESTYLE - if (ob->type == OB_MESH) { - Mesh *me= ob->data; - index_mf_to_mpoly= dm->getTessFaceDataArray(dm, CD_ORIGINDEX); - index_mp_to_orig= dm->getPolyDataArray(dm, CD_ORIGINDEX); - ffa= CustomData_get_layer(&me->pdata, CD_FREESTYLE_FACE); - } -#endif - - for (a=0; a<end; a++, mface++) { - int v1, v2, v3, v4, flag; - - if (mface->mat_nr == mat_iter) { - float len; - - v1= mface->v1; - v2= mface->v2; - v3= mface->v3; - v4= mface->v4; - flag= mface->flag & ME_SMOOTH; - - vlr= RE_findOrAddVlak(obr, obr->totvlak++); - vlr->v1= RE_findOrAddVert(obr, vertofs+v1); - vlr->v2= RE_findOrAddVert(obr, vertofs+v2); - vlr->v3= RE_findOrAddVert(obr, vertofs+v3); - if (v4) vlr->v4= RE_findOrAddVert(obr, vertofs+v4); - else vlr->v4 = NULL; - - /* render normals are inverted in render */ - if (vlr->v4) - len= normal_quad_v3(vlr->n, vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co); - else - len= normal_tri_v3(vlr->n, vlr->v3->co, vlr->v2->co, vlr->v1->co); - - vlr->mat= ma; - vlr->flag= flag; - vlr->ec= 0; /* mesh edges rendered separately */ -#ifdef WITH_FREESTYLE - if (ffa) { - int index = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, a) : a; - vlr->freestyle_face_mark= (ffa[index].flag & FREESTYLE_FACE_MARK) ? 1 : 0; - } - else { - vlr->freestyle_face_mark= 0; - } -#endif - - if (len==0) obr->totvlak--; - else { - CustomDataLayer *layer; - MTFace *mtface, *mtf; - MCol *mcol, *mc; - int index, mtfn= 0, mcn= 0; - char *name; - - for (index=0; index<dm->faceData.totlayer; index++) { - layer= &dm->faceData.layers[index]; - name= layer->name; - - if (layer->type == CD_MTFACE && mtfn < MAX_MTFACE) { - mtf= RE_vlakren_get_tface(obr, vlr, mtfn++, &name, 1); - mtface= (MTFace*)layer->data; - *mtf= mtface[a]; - } - else if (layer->type == CD_MCOL && mcn < MAX_MCOL) { - mc= RE_vlakren_get_mcol(obr, vlr, mcn++, &name, 1); - mcol= (MCol*)layer->data; - memcpy(mc, &mcol[a*4], sizeof(MCol)*4); - } - } - } - } - } - } - - /* Normals */ - calc_vertexnormals(re, obr, 1, 0, 0); - } - -} - -static void init_render_surf(Depsgraph *depsgraph, Render *re, ObjectRen *obr, int timeoffset) -{ - Object *ob= obr->ob; - Nurb *nu = NULL; - Curve *cu; - ListBase displist= {NULL, NULL}; - DispList *dl; - Material **matar; - float *orco=NULL, mat[4][4]; - int a, totmat; - bool need_orco = false; - DerivedMesh *dm= NULL; - - cu= ob->data; - nu= cu->nurb.first; - if (nu == NULL) return; - - mul_m4_m4m4(mat, re->viewmat, ob->obmat); - invert_m4_m4(ob->imat, mat); - - /* material array */ - totmat= ob->totcol+1; - matar= MEM_callocN(sizeof(Material*)*totmat, "init_render_surf matar"); - - for (a=0; a<totmat; a++) { - matar[a]= give_render_material(re, ob, a+1); - - if (matar[a] && matar[a]->texco & TEXCO_ORCO) - need_orco= 1; - } - - if (ob->parent && (ob->parent->type==OB_LATTICE)) need_orco= 1; - - BKE_displist_make_surf(depsgraph, re->scene, ob, &displist, &dm, 1, 0, 1); - - if (dm) { - if (need_orco) { - orco = get_object_orco(re, ob); - if (!orco) { - orco= BKE_displist_make_orco(depsgraph, re->scene, ob, dm, true, true); - if (orco) { - set_object_orco(re, ob, orco); - } - } - } - - init_render_dm(dm, re, obr, timeoffset, orco, mat); - dm->release(dm); - } - else { - if (need_orco) { - orco = get_object_orco(re, ob); - if (!orco) { - orco = BKE_curve_surf_make_orco(ob); - set_object_orco(re, ob, orco); - } - } - - /* walk along displaylist and create rendervertices/-faces */ - for (dl=displist.first; dl; dl=dl->next) { - /* watch out: u ^= y, v ^= x !! */ - if (dl->type==DL_SURF) - orco+= 3*dl_surf_to_renderdata(obr, dl, matar, orco, mat); - } - } - - BKE_displist_free(&displist); - - MEM_freeN(matar); -} - -static void init_render_curve(Depsgraph *depsgraph, Render *re, ObjectRen *obr, int timeoffset) -{ - Object *ob= obr->ob; - Curve *cu; - VertRen *ver; - VlakRen *vlr; - DispList *dl; - DerivedMesh *dm = NULL; - ListBase disp={NULL, NULL}; - Material **matar; - float *data, *fp, *orco=NULL; - float n[3], mat[4][4], nmat[4][4]; - int nr, startvert, a, b, negative_scale; - bool need_orco = false; - int totmat; - - cu= ob->data; - if (ob->type==OB_FONT && cu->str==NULL) return; - else if (ob->type==OB_CURVE && cu->nurb.first==NULL) return; - - BKE_displist_make_curveTypes_forRender(depsgraph, re->scene, ob, &disp, &dm, false, true); - dl= disp.first; - if (dl==NULL) return; - - mul_m4_m4m4(mat, re->viewmat, ob->obmat); - invert_m4_m4(ob->imat, mat); - negative_scale = is_negative_m4(mat); - - /* local object -> world space transform for normals */ - transpose_m4_m4(nmat, mat); - invert_m4(nmat); - - /* material array */ - totmat= ob->totcol+1; - matar= MEM_callocN(sizeof(Material*)*totmat, "init_render_surf matar"); - - for (a=0; a<totmat; a++) { - matar[a]= give_render_material(re, ob, a+1); - - if (matar[a] && matar[a]->texco & TEXCO_ORCO) - need_orco= 1; - } - - if (dm) { - if (need_orco) { - orco = get_object_orco(re, ob); - if (!orco) { - orco = BKE_displist_make_orco(depsgraph, re->scene, ob, dm, true, true); - if (orco) { - set_object_orco(re, ob, orco); - } - } - } - - init_render_dm(dm, re, obr, timeoffset, orco, mat); - dm->release(dm); - } - else { - if (need_orco) { - orco = get_object_orco(re, ob); - if (!orco) { - orco = BKE_curve_make_orco(depsgraph, re->scene, ob, NULL); - set_object_orco(re, ob, orco); - } - } - - while (dl) { - if (dl->col > ob->totcol) { - /* pass */ - } - else if (dl->type==DL_INDEX3) { - const int *index; - - startvert= obr->totvert; - data= dl->verts; - - for (a=0; a<dl->nr; a++, data+=3) { - ver= RE_findOrAddVert(obr, obr->totvert++); - copy_v3_v3(ver->co, data); - - mul_m4_v3(mat, ver->co); - - if (orco) { - ver->orco = orco; - orco += 3; - } - } - - if (timeoffset==0) { - float tmp[3]; - const int startvlak= obr->totvlak; - - zero_v3(n); - index= dl->index; - for (a=0; a<dl->parts; a++, index+=3) { - int v1 = index[0], v2 = index[2], v3 = index[1]; - float *co1 = &dl->verts[v1 * 3], - *co2 = &dl->verts[v2 * 3], - *co3 = &dl->verts[v3 * 3]; - - vlr= RE_findOrAddVlak(obr, obr->totvlak++); - vlr->v1= RE_findOrAddVert(obr, startvert + v1); - vlr->v2= RE_findOrAddVert(obr, startvert + v2); - vlr->v3= RE_findOrAddVert(obr, startvert + v3); - vlr->v4= NULL; - - /* to prevent float accuracy issues, we calculate normal in local object space (not world) */ - if (normal_tri_v3(tmp, co1, co2, co3) > FLT_EPSILON) { - if (negative_scale == false) { - add_v3_v3(n, tmp); - } - else { - sub_v3_v3(n, tmp); - } - } - - vlr->mat= matar[ dl->col ]; - vlr->flag= 0; - vlr->ec= 0; - } - - /* transform normal to world space */ - mul_m4_v3(nmat, n); - normalize_v3(n); - - /* vertex normals */ - for (a= startvlak; a<obr->totvlak; a++) { - vlr= RE_findOrAddVlak(obr, a); - - copy_v3_v3(vlr->n, n); - add_v3_v3(vlr->v1->n, vlr->n); - add_v3_v3(vlr->v3->n, vlr->n); - add_v3_v3(vlr->v2->n, vlr->n); - } - for (a=startvert; a<obr->totvert; a++) { - ver= RE_findOrAddVert(obr, a); - normalize_v3(ver->n); - } - } - } - else if (dl->type==DL_SURF) { - - /* cyclic U means an extruded full circular curve, we skip bevel splitting then */ - if (dl->flag & DL_CYCL_U) { - orco+= 3*dl_surf_to_renderdata(obr, dl, matar, orco, mat); - } - else { - int p1, p2, p3, p4; - - fp= dl->verts; - startvert= obr->totvert; - nr= dl->nr*dl->parts; - - while (nr--) { - ver= RE_findOrAddVert(obr, obr->totvert++); - - copy_v3_v3(ver->co, fp); - mul_m4_v3(mat, ver->co); - fp+= 3; - - if (orco) { - ver->orco = orco; - orco += 3; - } - } - - if (dl->flag & DL_CYCL_V && orco) { - fp = dl->verts; - nr = dl->nr; - while (nr--) { - ver = RE_findOrAddVert(obr, obr->totvert++); - copy_v3_v3(ver->co, fp); - mul_m4_v3(mat, ver->co); - ver->orco = orco; - fp += 3; - orco += 3; - } - } - - if (dl->bevel_split || timeoffset == 0) { - const int startvlak= obr->totvlak; - - for (a=0; a<dl->parts; a++) { - - if (BKE_displist_surfindex_get(dl, a, &b, &p1, &p2, &p3, &p4)==0) - break; - - p1+= startvert; - p2+= startvert; - p3+= startvert; - p4+= startvert; - - if (dl->flag & DL_CYCL_V && orco && a == dl->parts - 1) { - p3 = p1 + dl->nr; - p4 = p2 + dl->nr; - } - - for (; b<dl->nr; b++) { - vlr= RE_findOrAddVlak(obr, obr->totvlak++); - /* important 1 offset in order is kept [#24913] */ - vlr->v1= RE_findOrAddVert(obr, p2); - vlr->v2= RE_findOrAddVert(obr, p1); - vlr->v3= RE_findOrAddVert(obr, p3); - vlr->v4= RE_findOrAddVert(obr, p4); - vlr->ec= ME_V2V3+ME_V3V4; - if (a==0) vlr->ec+= ME_V1V2; - - vlr->flag= dl->rt; - - normal_quad_v3(vlr->n, vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co); - vlr->mat= matar[ dl->col ]; - - p4= p3; - p3++; - p2= p1; - p1++; - } - } - - if (dl->bevel_split) { - for (a = 0; a < dl->parts - 1 + !!(dl->flag & DL_CYCL_V); a++) { - if (BLI_BITMAP_TEST(dl->bevel_split, a)) { - split_v_renderfaces( - obr, startvlak, startvert, dl->parts, dl->nr, a, - /* intentionally swap (v, u) --> (u, v) */ - dl->flag & DL_CYCL_V, dl->flag & DL_CYCL_U); - } - } - } - - /* vertex normals */ - for (a= startvlak; a<obr->totvlak; a++) { - vlr= RE_findOrAddVlak(obr, a); - - add_v3_v3(vlr->v1->n, vlr->n); - add_v3_v3(vlr->v3->n, vlr->n); - add_v3_v3(vlr->v2->n, vlr->n); - add_v3_v3(vlr->v4->n, vlr->n); - } - for (a=startvert; a<obr->totvert; a++) { - ver= RE_findOrAddVert(obr, a); - normalize_v3(ver->n); - } - } - } - } - - dl= dl->next; - } - } - - BKE_displist_free(&disp); - - MEM_freeN(matar); -} - -/* ------------------------------------------------------------------------- */ -/* Mesh */ -/* ------------------------------------------------------------------------- */ - -struct edgesort { - unsigned int v1, v2; - int f; - unsigned int i1, i2; -}; - -/* edges have to be added with lowest index first for sorting */ -static void to_edgesort(struct edgesort *ed, - unsigned int i1, unsigned int i2, - unsigned int v1, unsigned int v2, int f) -{ - if (v1 > v2) { - SWAP(unsigned int, v1, v2); - SWAP(unsigned int, i1, i2); - } - - ed->v1= v1; - ed->v2= v2; - ed->i1= i1; - ed->i2= i2; - ed->f = f; -} - -static int vergedgesort(const void *v1, const void *v2) -{ - const struct edgesort *x1=v1, *x2=v2; - - if ( x1->v1 > x2->v1) return 1; - else if ( x1->v1 < x2->v1) return -1; - else if ( x1->v2 > x2->v2) return 1; - else if ( x1->v2 < x2->v2) return -1; - - return 0; -} - -static struct edgesort *make_mesh_edge_lookup(DerivedMesh *dm, int *totedgesort) -{ - MFace *mf, *mface; - MTFace *tface=NULL; - struct edgesort *edsort, *ed; - unsigned int *mcol=NULL; - int a, totedge=0, totface; - - mface= dm->getTessFaceArray(dm); - totface= dm->getNumTessFaces(dm); - tface= dm->getTessFaceDataArray(dm, CD_MTFACE); - mcol= dm->getTessFaceDataArray(dm, CD_MCOL); - - if (mcol==NULL && tface==NULL) return NULL; - - /* make sorted table with edges and face indices in it */ - for (a= totface, mf= mface; a>0; a--, mf++) { - totedge += mf->v4 ? 4 : 3; - } - - if (totedge==0) - return NULL; - - ed= edsort= MEM_callocN(totedge*sizeof(struct edgesort), "edgesort"); - - for (a=0, mf=mface; a<totface; a++, mf++) { - to_edgesort(ed++, 0, 1, mf->v1, mf->v2, a); - to_edgesort(ed++, 1, 2, mf->v2, mf->v3, a); - if (mf->v4) { - to_edgesort(ed++, 2, 3, mf->v3, mf->v4, a); - to_edgesort(ed++, 3, 0, mf->v4, mf->v1, a); - } - else { - to_edgesort(ed++, 2, 3, mf->v3, mf->v1, a); - } - } - - qsort(edsort, totedge, sizeof(struct edgesort), vergedgesort); - - *totedgesort= totedge; - - return edsort; -} - -static void use_mesh_edge_lookup(ObjectRen *obr, DerivedMesh *dm, MEdge *medge, VlakRen *vlr, struct edgesort *edgetable, int totedge) -{ - struct edgesort ed, *edp; - CustomDataLayer *layer; - MTFace *mtface, *mtf; - MCol *mcol, *mc; - int index, mtfn, mcn; - char *name; - - if (medge->v1 < medge->v2) { - ed.v1= medge->v1; - ed.v2= medge->v2; - } - else { - ed.v1= medge->v2; - ed.v2= medge->v1; - } - - edp= bsearch(&ed, edgetable, totedge, sizeof(struct edgesort), vergedgesort); - - /* since edges have different index ordering, we have to duplicate mcol and tface */ - if (edp) { - mtfn= mcn= 0; - - for (index=0; index<dm->faceData.totlayer; index++) { - layer= &dm->faceData.layers[index]; - name= layer->name; - - if (layer->type == CD_MTFACE && mtfn < MAX_MTFACE) { - mtface= &((MTFace*)layer->data)[edp->f]; - mtf= RE_vlakren_get_tface(obr, vlr, mtfn++, &name, 1); - - *mtf= *mtface; - - memcpy(mtf->uv[0], mtface->uv[edp->i1], sizeof(float)*2); - memcpy(mtf->uv[1], mtface->uv[edp->i2], sizeof(float)*2); - memcpy(mtf->uv[2], mtface->uv[1], sizeof(float)*2); - memcpy(mtf->uv[3], mtface->uv[1], sizeof(float)*2); - } - else if (layer->type == CD_MCOL && mcn < MAX_MCOL) { - mcol= &((MCol*)layer->data)[edp->f*4]; - mc= RE_vlakren_get_mcol(obr, vlr, mcn++, &name, 1); - - mc[0]= mcol[edp->i1]; - mc[1]= mc[2]= mc[3]= mcol[edp->i2]; - } - } - } -} - -static void free_camera_inside_volumes(Render *re) -{ - BLI_freelistN(&re->render_volumes_inside); -} - -static void init_camera_inside_volumes(Render *re) -{ - ObjectInstanceRen *obi; - VolumeOb *vo; - /* coordinates are all in camera space, so camera coordinate is zero. we also - * add an offset for the clip start, however note that with clip start it's - * actually impossible to do a single 'inside' test, since there will not be - * a single point where all camera rays start from, though for small clip start - * they will be close together. */ - float co[3] = {0.f, 0.f, -re->clipsta}; - - for (vo= re->volumes.first; vo; vo= vo->next) { - for (obi= re->instancetable.first; obi; obi= obi->next) { - if (obi->obr == vo->obr) { - if (point_inside_volume_objectinstance(re, obi, co)) { - MatInside *mi; - - mi = MEM_mallocN(sizeof(MatInside), "camera inside material"); - mi->ma = vo->ma; - mi->obi = obi; - - BLI_addtail(&(re->render_volumes_inside), mi); - } - } - } - } - - -#if 0 /* debug */ - { - MatInside *m; - for (m = re->render_volumes_inside.first; m; m = m->next) { - printf("matinside: ma: %s\n", m->ma->id.name + 2); - } - } -#endif -} - -static void add_volume(Render *re, ObjectRen *obr, Material *ma) -{ - struct VolumeOb *vo; - - vo = MEM_mallocN(sizeof(VolumeOb), "volume object"); - - vo->ma = ma; - vo->obr = obr; - - BLI_addtail(&re->volumes, vo); -} - -#ifdef WITH_FREESTYLE -static EdgeHash *make_freestyle_edge_mark_hash(DerivedMesh *dm) -{ - EdgeHash *edge_hash= NULL; - FreestyleEdge *fed; - MEdge *medge; - int totedge, a; - - medge = dm->getEdgeArray(dm); - totedge = dm->getNumEdges(dm); - fed = dm->getEdgeDataArray(dm, CD_FREESTYLE_EDGE); - if (fed) { - edge_hash = BLI_edgehash_new(__func__); - for (a = 0; a < totedge; a++) { - if (fed[a].flag & FREESTYLE_EDGE_MARK) - BLI_edgehash_insert(edge_hash, medge[a].v1, medge[a].v2, medge+a); - } - } - return edge_hash; -} - -static bool has_freestyle_edge_mark(EdgeHash *edge_hash, int v1, int v2) -{ - MEdge *medge= BLI_edgehash_lookup(edge_hash, v1, v2); - return (!medge) ? 0 : 1; -} -#endif - -static void init_render_mesh(Depsgraph *depsgraph, Render *re, ObjectRen *obr, int timeoffset) -{ - Object *ob= obr->ob; - Mesh *me; - MVert *mvert = NULL; - MFace *mface; - VlakRen *vlr; //, *vlr1; - VertRen *ver; - Material *ma; - DerivedMesh *dm; - CustomDataMask mask; - float xn, yn, zn, imat[3][3], mat[4][4]; //nor[3], - float *orco = NULL; - short (*loop_nors)[4][3] = NULL; - bool need_orco = false, need_stress = false, need_tangent = false, need_origindex = false; - bool need_nmap_tangent_concrete = false; - int a, a1, ok, vertofs; - int end, totvert = 0; - bool do_autosmooth = false, do_displace = false; - bool use_original_normals = false; - int recalc_normals = 0; /* false by default */ - int negative_scale; -#ifdef WITH_FREESTYLE - FreestyleFace *ffa; -#endif - - me= ob->data; - - mul_m4_m4m4(mat, re->viewmat, ob->obmat); - invert_m4_m4(ob->imat, mat); - copy_m3_m4(imat, ob->imat); - negative_scale= is_negative_m4(mat); - - need_orco= 0; - for (a=1; a<=ob->totcol; a++) { - ma= give_render_material(re, ob, a); - if (ma) { - if (ma->texco & (TEXCO_ORCO|TEXCO_STRESS)) - need_orco= 1; - if (ma->texco & TEXCO_STRESS) - need_stress= 1; - /* normalmaps, test if tangents needed, separated from shading */ - if (ma->mode_l & MA_TANGENT_V) { - need_tangent= 1; - if (me->mloopuv==NULL) - need_orco= 1; - } - if (ma->mode_l & MA_NORMAP_TANG) { - if (me->mloopuv==NULL) { - need_orco= 1; - } - need_tangent= 1; - } - if (ma->mode2_l & MA_TANGENT_CONCRETE) { - need_nmap_tangent_concrete = true; - } - } - } - - if (re->flag & R_NEED_TANGENT) { - /* exception for tangent space baking */ - if (me->mloopuv==NULL) { - need_orco= 1; - } - need_tangent= 1; - } - - /* check autosmooth and displacement, we then have to skip only-verts optimize - * Note: not sure what we want to give higher priority, currently do_displace - * takes precedence over do_autosmooth. - */ - do_displace = test_for_displace(re, ob); - do_autosmooth = ((me->flag & ME_AUTOSMOOTH) != 0) && !do_displace; - if (do_autosmooth || do_displace) - timeoffset = 0; - - /* origindex currently used when using autosmooth, or baking to vertex colors. */ - need_origindex = (do_autosmooth || ((re->flag & R_BAKING) && (re->r.bake_flag & R_BAKE_VCOL))); - - mask = CD_MASK_RENDER_INTERNAL; - if (!timeoffset) - if (need_orco) - mask |= CD_MASK_ORCO; - -#ifdef WITH_FREESTYLE - mask |= CD_MASK_ORIGINDEX | CD_MASK_FREESTYLE_EDGE | CD_MASK_FREESTYLE_FACE; -#endif - - if (re->r.scemode & R_VIEWPORT_PREVIEW) - dm= mesh_create_derived_view(depsgraph, re->scene, ob, mask); - else - dm= mesh_create_derived_render(depsgraph, re->scene, ob, mask); - if (dm==NULL) return; /* in case duplicated object fails? */ - - mvert= dm->getVertArray(dm); - totvert= dm->getNumVerts(dm); - - if (totvert == 0) { - dm->release(dm); - return; - } - - if (mask & CD_MASK_ORCO) { - orco = get_object_orco(re, ob); - if (!orco) { - orco= dm->getVertDataArray(dm, CD_ORCO); - if (orco) { - orco= MEM_dupallocN(orco); - set_object_orco(re, ob, orco); - } - } - } - - /* attempt to autsmooth on original mesh, only without subsurf */ - if (do_autosmooth && me->totvert==totvert && me->totface==dm->getNumTessFaces(dm)) - use_original_normals= true; - - ma= give_render_material(re, ob, 1); - - - if (ma->material_type == MA_TYPE_HALO) { - make_render_halos(re, obr, me, totvert, mvert, ma, orco); - } - else { - const int *index_vert_orig = NULL; - const int *index_mf_to_mpoly = NULL; - const int *index_mp_to_orig = NULL; - if (need_origindex) { - index_vert_orig = dm->getVertDataArray(dm, CD_ORIGINDEX); - /* double lookup for faces -> polys */ -#ifdef WITH_FREESTYLE - index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX); - index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX); -#endif - } - - for (a=0; a<totvert; a++, mvert++) { - ver= RE_findOrAddVert(obr, obr->totvert++); - copy_v3_v3(ver->co, mvert->co); - if (do_autosmooth == false) { /* autosmooth on original unrotated data to prevent differences between frames */ - normal_short_to_float_v3(ver->n, mvert->no); - mul_m4_v3(mat, ver->co); - mul_transposed_m3_v3(imat, ver->n); - normalize_v3(ver->n); - negate_v3(ver->n); - } - - if (orco) { - ver->orco= orco; - orco+=3; - } - - if (need_origindex) { - int *origindex; - origindex = RE_vertren_get_origindex(obr, ver, 1); - - /* Use orig index array if it's available (e.g. in the presence - * of modifiers). */ - if (index_vert_orig) - *origindex = index_vert_orig[a]; - else - *origindex = a; - } - } - - if (!timeoffset) { - short (*lnp)[4][3] = NULL; -#ifdef WITH_FREESTYLE - EdgeHash *edge_hash; - - /* create a hash table of Freestyle edge marks */ - edge_hash = make_freestyle_edge_mark_hash(dm); -#endif - - /* store customdata names, because DerivedMesh is freed */ - RE_set_customdata_names(obr, &dm->faceData); - - /* add tangent layers if we need */ - if ((ma->nmap_tangent_names_count && need_nmap_tangent_concrete) || need_tangent) { - dm->calcLoopTangents( - dm, need_tangent, - (const char (*)[MAX_NAME])ma->nmap_tangent_names, ma->nmap_tangent_names_count); - obr->tangent_mask = dm->tangent_mask; - DM_generate_tangent_tessface_data(dm, need_nmap_tangent_concrete || need_tangent); - } - - /* still to do for keys: the correct local texture coordinate */ - - /* faces in order of color blocks */ - vertofs= obr->totvert - totvert; - for (a1=0; (a1<ob->totcol || (a1==0 && ob->totcol==0)); a1++) { - - ma= give_render_material(re, ob, a1+1); - - /* test for 100% transparent */ - ok = 1; - if ((ma->alpha == 0.0f) && - (ma->spectra == 0.0f) && - /* No need to test filter here, it's only active with MA_RAYTRANSP and we check against it below. */ - /* (ma->filter == 0.0f) && */ - (ma->mode & MA_TRANSP) && - (ma->mode & (MA_RAYTRANSP | MA_RAYMIRROR)) == 0) - { - ok = 0; - /* texture on transparency? */ - for (a=0; a<MAX_MTEX; a++) { - if (ma->mtex[a] && ma->mtex[a]->tex) { - if (ma->mtex[a]->mapto & MAP_ALPHA) ok= 1; - } - } - } - - /* if wire material, and we got edges, don't do the faces */ - if (ma->material_type == MA_TYPE_WIRE) { - end= dm->getNumEdges(dm); - if (end) ok= 0; - } - - if (ok) { - end= dm->getNumTessFaces(dm); - mface= dm->getTessFaceArray(dm); - if (!loop_nors && do_autosmooth && - (dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL) != NULL)) - { - lnp = loop_nors = MEM_mallocN(sizeof(*loop_nors) * end, __func__); - } -#ifdef WITH_FREESTYLE - index_mf_to_mpoly= dm->getTessFaceDataArray(dm, CD_ORIGINDEX); - index_mp_to_orig= dm->getPolyDataArray(dm, CD_ORIGINDEX); - ffa= CustomData_get_layer(&me->pdata, CD_FREESTYLE_FACE); -#endif - - for (a=0; a<end; a++, mface++) { - int v1, v2, v3, v4, flag; - - if ( mface->mat_nr==a1 ) { - float len; - bool reverse_verts = (negative_scale != 0 && do_autosmooth == false); - int rev_tab[] = {reverse_verts==0 ? 0 : 2, 1, reverse_verts==0 ? 2 : 0, 3}; - v1= reverse_verts==0 ? mface->v1 : mface->v3; - v2= mface->v2; - v3= reverse_verts==0 ? mface->v3 : mface->v1; - v4= mface->v4; - flag = do_autosmooth ? ME_SMOOTH : mface->flag & ME_SMOOTH; - - vlr= RE_findOrAddVlak(obr, obr->totvlak++); - vlr->v1= RE_findOrAddVert(obr, vertofs+v1); - vlr->v2= RE_findOrAddVert(obr, vertofs+v2); - vlr->v3= RE_findOrAddVert(obr, vertofs+v3); - if (v4) vlr->v4 = RE_findOrAddVert(obr, vertofs+v4); - else vlr->v4 = NULL; - -#ifdef WITH_FREESTYLE - /* Freestyle edge/face marks */ - if (edge_hash) { - int edge_mark = 0; - - if (has_freestyle_edge_mark(edge_hash, v1, v2)) edge_mark |= R_EDGE_V1V2; - if (has_freestyle_edge_mark(edge_hash, v2, v3)) edge_mark |= R_EDGE_V2V3; - if (!v4) { - if (has_freestyle_edge_mark(edge_hash, v3, v1)) edge_mark |= R_EDGE_V3V1; - } - else { - if (has_freestyle_edge_mark(edge_hash, v3, v4)) edge_mark |= R_EDGE_V3V4; - if (has_freestyle_edge_mark(edge_hash, v4, v1)) edge_mark |= R_EDGE_V4V1; - } - vlr->freestyle_edge_mark= edge_mark; - } - if (ffa) { - int index = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, a) : a; - vlr->freestyle_face_mark= (ffa[index].flag & FREESTYLE_FACE_MARK) ? 1 : 0; - } - else { - vlr->freestyle_face_mark= 0; - } -#endif - - /* render normals are inverted in render */ - if (use_original_normals) { - MFace *mf= me->mface+a; - MVert *mv= me->mvert; - - if (vlr->v4) - len= normal_quad_v3(vlr->n, mv[mf->v4].co, mv[mf->v3].co, mv[mf->v2].co, mv[mf->v1].co); - else - len= normal_tri_v3(vlr->n, mv[mf->v3].co, mv[mf->v2].co, mv[mf->v1].co); - } - else { - if (vlr->v4) - len= normal_quad_v3(vlr->n, vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co); - else - len= normal_tri_v3(vlr->n, vlr->v3->co, vlr->v2->co, vlr->v1->co); - } - - vlr->mat= ma; - vlr->flag= flag; - vlr->ec= 0; /* mesh edges rendered separately */ - - if (len==0) obr->totvlak--; - else { - CustomDataLayer *layer; - MTFace *mtface, *mtf; - MCol *mcol, *mc; - int index, mtfn= 0, mcn= 0, mln = 0, vindex; - char *name; - int nr_verts = v4!=0 ? 4 : 3; - - for (index=0; index<dm->faceData.totlayer; index++) { - layer= &dm->faceData.layers[index]; - name= layer->name; - - if (layer->type == CD_MTFACE && mtfn < MAX_MTFACE) { - int t; - mtf= RE_vlakren_get_tface(obr, vlr, mtfn++, &name, 1); - mtface= (MTFace*)layer->data; - *mtf = mtface[a]; /* copy face info */ - for (vindex=0; vindex<nr_verts; vindex++) - for (t=0; t<2; t++) - mtf->uv[vindex][t]=mtface[a].uv[rev_tab[vindex]][t]; - } - else if (layer->type == CD_MCOL && mcn < MAX_MCOL) { - mc= RE_vlakren_get_mcol(obr, vlr, mcn++, &name, 1); - mcol= (MCol*)layer->data; - for (vindex=0; vindex<nr_verts; vindex++) - mc[vindex]=mcol[a*4+rev_tab[vindex]]; - } - else if (layer->type == CD_TANGENT) { - if (need_nmap_tangent_concrete || need_tangent) { - int uv_start = CustomData_get_layer_index(&dm->faceData, CD_MTFACE); - int uv_index = CustomData_get_named_layer_index(&dm->faceData, CD_MTFACE, layer->name); - - /* if there are no UVs, orco tangents are in first slot */ - int n = (uv_start >= 0 && uv_index >= 0) ? uv_index - uv_start : 0; - - const float *tangent = (const float *) layer->data; - float *ftang = RE_vlakren_get_nmap_tangent(obr, vlr, n, true); - - for (vindex=0; vindex<nr_verts; vindex++) { - copy_v4_v4(ftang+vindex*4, tangent+a*16+rev_tab[vindex]*4); - mul_mat3_m4_v3(mat, ftang+vindex*4); - normalize_v3(ftang+vindex*4); - } - } - } - else if (layer->type == CD_TESSLOOPNORMAL && mln < 1) { - if (loop_nors) { - const short (*lnors)[4][3] = (const short (*)[4][3])layer->data; - for (vindex = 0; vindex < 4; vindex++) { - //print_v3("lnors[a][rev_tab[vindex]]", lnors[a][rev_tab[vindex]]); - copy_v3_v3_short((short *)lnp[0][vindex], lnors[a][rev_tab[vindex]]); - /* If we copy loop normals, we are doing autosmooth, so we are still - * in object space, no need to multiply with mat! - */ - } - lnp++; - } - mln++; - } - } - - if (need_origindex) { - /* Find original index of mpoly for this tessface. Options: - * - Modified mesh; two-step look up from tessface -> modified mpoly -> original mpoly - * - OR Tesselated mesh; look up from tessface -> mpoly - * - OR Failsafe; tessface == mpoly. Could probably assert(false) in this case? */ - int *origindex; - origindex = RE_vlakren_get_origindex(obr, vlr, 1); - if (index_mf_to_mpoly && index_mp_to_orig) - *origindex = DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, a); - else if (index_mf_to_mpoly) - *origindex = index_mf_to_mpoly[a]; - else - *origindex = a; - } - } - } - } - } - } - -#ifdef WITH_FREESTYLE - /* release the hash table of Freestyle edge marks */ - if (edge_hash) - BLI_edgehash_free(edge_hash, NULL); -#endif - - /* exception... we do edges for wire mode. potential conflict when faces exist... */ - end= dm->getNumEdges(dm); - mvert= dm->getVertArray(dm); - ma= give_render_material(re, ob, 1); - if (end && (ma->material_type == MA_TYPE_WIRE)) { - MEdge *medge; - struct edgesort *edgetable; - int totedge= 0; - recalc_normals= 1; - - medge= dm->getEdgeArray(dm); - - /* we want edges to have UV and vcol too... */ - edgetable= make_mesh_edge_lookup(dm, &totedge); - - for (a1=0; a1<end; a1++, medge++) { - if (medge->flag&ME_EDGERENDER) { - MVert *v0 = &mvert[medge->v1]; - MVert *v1 = &mvert[medge->v2]; - - vlr= RE_findOrAddVlak(obr, obr->totvlak++); - vlr->v1= RE_findOrAddVert(obr, vertofs+medge->v1); - vlr->v2= RE_findOrAddVert(obr, vertofs+medge->v2); - vlr->v3= vlr->v2; - vlr->v4= NULL; - - if (edgetable) - use_mesh_edge_lookup(obr, dm, medge, vlr, edgetable, totedge); - - xn= -(v0->no[0]+v1->no[0]); - yn= -(v0->no[1]+v1->no[1]); - zn= -(v0->no[2]+v1->no[2]); - /* transpose ! */ - vlr->n[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn; - vlr->n[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn; - vlr->n[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn; - normalize_v3(vlr->n); - - vlr->mat= ma; - vlr->flag= 0; - vlr->ec= ME_V1V2; - } - } - if (edgetable) - MEM_freeN(edgetable); - } - } - } - - if (!timeoffset) { - if (need_stress) - calc_edge_stress(re, obr, me); - - if (do_displace) { - calc_vertexnormals(re, obr, 1, 0, 0); - displace(re, obr); - recalc_normals = 0; /* Already computed by displace! */ - } - else if (do_autosmooth) { - recalc_normals = (loop_nors == NULL); /* Should never happen, but better be safe than sorry. */ - autosmooth(re, obr, mat, loop_nors); - } - - if (recalc_normals!=0 || need_tangent!=0) - calc_vertexnormals(re, obr, recalc_normals, need_tangent, need_nmap_tangent_concrete); - } - - MEM_SAFE_FREE(loop_nors); - - dm->release(dm); -} - -/* ------------------------------------------------------------------------- */ -/* Lamps and Shadowbuffers */ -/* ------------------------------------------------------------------------- */ - -static void initshadowbuf(Render *re, LampRen *lar, float mat[4][4]) -{ - struct ShadBuf *shb; - float viewinv[4][4]; - - /* if (la->spsi<16) return; */ - - /* memory alloc */ - shb= (struct ShadBuf *)MEM_callocN(sizeof(struct ShadBuf), "initshadbuf"); - lar->shb= shb; - - if (shb==NULL) return; - - VECCOPY(shb->co, lar->co); /* int copy */ - - /* percentage render: keep track of min and max */ - shb->size= (lar->bufsize*re->r.size)/100; - - if (shb->size<512) shb->size= 512; - else if (shb->size > lar->bufsize) shb->size= lar->bufsize; - - shb->size &= ~15; /* make sure its multiples of 16 */ - - shb->samp= lar->samp; - shb->soft= lar->soft; - shb->shadhalostep= lar->shadhalostep; - - normalize_m4(mat); - invert_m4_m4(shb->winmat, mat); /* winmat is temp */ - - /* matrix: combination of inverse view and lampmat */ - /* calculate again: the ortho-render has no correct viewinv */ - invert_m4_m4(viewinv, re->viewmat); - mul_m4_m4m4(shb->viewmat, shb->winmat, viewinv); - - /* projection */ - shb->d= lar->clipsta; - shb->clipend= lar->clipend; - - /* bias is percentage, made 2x larger because of correction for angle of incidence */ - /* when a ray is closer to parallel of a face, bias value is increased during render */ - shb->bias= (0.02f*lar->bias)*0x7FFFFFFF; - - /* halfway method (average of first and 2nd z) reduces bias issues */ - if (ELEM(lar->buftype, LA_SHADBUF_HALFWAY, LA_SHADBUF_DEEP)) - shb->bias= 0.1f*shb->bias; - - shb->compressthresh= lar->compressthresh; -} - -void area_lamp_vectors(LampRen *lar) -{ - float xsize= 0.5f*lar->area_size, ysize= 0.5f*lar->area_sizey, multifac; - - /* make it smaller, so area light can be multisampled */ - multifac= 1.0f/sqrtf((float)lar->ray_totsamp); - xsize *= multifac; - ysize *= multifac; - - /* corner vectors */ - lar->area[0][0]= lar->co[0] - xsize*lar->mat[0][0] - ysize*lar->mat[1][0]; - lar->area[0][1]= lar->co[1] - xsize*lar->mat[0][1] - ysize*lar->mat[1][1]; - lar->area[0][2]= lar->co[2] - xsize*lar->mat[0][2] - ysize*lar->mat[1][2]; - - /* corner vectors */ - lar->area[1][0]= lar->co[0] - xsize*lar->mat[0][0] + ysize*lar->mat[1][0]; - lar->area[1][1]= lar->co[1] - xsize*lar->mat[0][1] + ysize*lar->mat[1][1]; - lar->area[1][2]= lar->co[2] - xsize*lar->mat[0][2] + ysize*lar->mat[1][2]; - - /* corner vectors */ - lar->area[2][0]= lar->co[0] + xsize*lar->mat[0][0] + ysize*lar->mat[1][0]; - lar->area[2][1]= lar->co[1] + xsize*lar->mat[0][1] + ysize*lar->mat[1][1]; - lar->area[2][2]= lar->co[2] + xsize*lar->mat[0][2] + ysize*lar->mat[1][2]; - - /* corner vectors */ - lar->area[3][0]= lar->co[0] + xsize*lar->mat[0][0] - ysize*lar->mat[1][0]; - lar->area[3][1]= lar->co[1] + xsize*lar->mat[0][1] - ysize*lar->mat[1][1]; - lar->area[3][2]= lar->co[2] + xsize*lar->mat[0][2] - ysize*lar->mat[1][2]; - /* only for correction button size, matrix size works on energy */ - lar->areasize= lar->dist*lar->dist/(4.0f*xsize*ysize); -} - -/* If lar takes more lamp data, the decoupling will be better. */ -static GroupObject *add_render_lamp(Render *re, Object *ob) -{ - Lamp *la= ob->data; - LampRen *lar; - GroupObject *go; - float mat[4][4], angle, xn, yn; - float vec[3]; - int c; - - /* previewrender sets this to zero... prevent accidents */ - if (la==NULL) return NULL; - - /* prevent only shadow from rendering light */ - if (la->mode & LA_ONLYSHADOW) - if ((re->r.mode & R_SHADOW)==0) - return NULL; - - re->totlamp++; - - /* groups is used to unify support for lightgroups, this is the global lightgroup */ - go= MEM_callocN(sizeof(GroupObject), "groupobject"); - BLI_addtail(&re->lights, go); - go->ob= ob; - /* lamprens are in own list, for freeing */ - lar= (LampRen *)MEM_callocN(sizeof(LampRen), "lampren"); - BLI_addtail(&re->lampren, lar); - go->lampren= lar; - - mul_m4_m4m4(mat, re->viewmat, ob->obmat); - invert_m4_m4(ob->imat, mat); - - copy_m4_m4(lar->lampmat, ob->obmat); - copy_m3_m4(lar->mat, mat); - copy_m3_m4(lar->imat, ob->imat); - - lar->bufsize = la->bufsize; - lar->samp = la->samp; - lar->buffers= la->buffers; - if (lar->buffers==0) lar->buffers= 1; - lar->buftype= la->buftype; - lar->filtertype= la->filtertype; - lar->soft = la->soft; - lar->shadhalostep = la->shadhalostep; - lar->clipsta = la->clipsta; - lar->clipend = la->clipend; - - lar->bias = la->bias; - lar->compressthresh = la->compressthresh; - - lar->type= la->type; - lar->mode= la->mode; - - lar->energy= la->energy; - if (la->mode & LA_NEG) lar->energy= -lar->energy; - - lar->vec[0]= -mat[2][0]; - lar->vec[1]= -mat[2][1]; - lar->vec[2]= -mat[2][2]; - normalize_v3(lar->vec); - lar->co[0]= mat[3][0]; - lar->co[1]= mat[3][1]; - lar->co[2]= mat[3][2]; - lar->dist= la->dist; - lar->haint= la->haint; - lar->distkw= lar->dist*lar->dist; - lar->r= lar->energy*la->r; - lar->g= lar->energy*la->g; - lar->b= lar->energy*la->b; - lar->shdwr= la->shdwr; - lar->shdwg= la->shdwg; - lar->shdwb= la->shdwb; - lar->k= la->k; - - /* area */ - lar->ray_samp= la->ray_samp; - lar->ray_sampy= la->ray_sampy; - lar->ray_sampz= la->ray_sampz; - - lar->area_size= la->area_size; - lar->area_sizey= la->area_sizey; - lar->area_sizez= la->area_sizez; - - lar->area_shape= la->area_shape; - - /* Annoying, lamp UI does this, but the UI might not have been used? - add here too. - * make sure this matches buttons_shading.c's logic */ - if (ELEM(la->type, LA_AREA, LA_SPOT, LA_SUN, LA_LOCAL) && (la->mode & LA_SHAD_RAY)) - if (ELEM(la->type, LA_SPOT, LA_SUN, LA_LOCAL)) - if (la->ray_samp_method == LA_SAMP_CONSTANT) la->ray_samp_method = LA_SAMP_HALTON; - - lar->ray_samp_method= la->ray_samp_method; - lar->ray_samp_type= la->ray_samp_type; - - lar->adapt_thresh= la->adapt_thresh; - lar->sunsky = NULL; - - if ( ELEM(lar->type, LA_SPOT, LA_LOCAL)) { - lar->ray_totsamp= lar->ray_samp*lar->ray_samp; - lar->area_shape = LA_AREA_SQUARE; - lar->area_sizey= lar->area_size; - } - else if (lar->type==LA_AREA) { - switch (lar->area_shape) { - case LA_AREA_SQUARE: - lar->ray_totsamp= lar->ray_samp*lar->ray_samp; - lar->ray_sampy= lar->ray_samp; - lar->area_sizey= lar->area_size; - break; - case LA_AREA_RECT: - lar->ray_totsamp= lar->ray_samp*lar->ray_sampy; - break; - case LA_AREA_CUBE: - lar->ray_totsamp= lar->ray_samp*lar->ray_samp*lar->ray_samp; - lar->ray_sampy= lar->ray_samp; - lar->ray_sampz= lar->ray_samp; - lar->area_sizey= lar->area_size; - lar->area_sizez= lar->area_size; - break; - case LA_AREA_BOX: - lar->ray_totsamp= lar->ray_samp*lar->ray_sampy*lar->ray_sampz; - break; - } - - area_lamp_vectors(lar); - init_jitter_plane(lar); /* subsamples */ - } - else if (lar->type==LA_SUN) { - lar->ray_totsamp= lar->ray_samp*lar->ray_samp; - lar->area_shape = LA_AREA_SQUARE; - lar->area_sizey= lar->area_size; - - if ((la->sun_effect_type & LA_SUN_EFFECT_SKY) || - (la->sun_effect_type & LA_SUN_EFFECT_AP)) - { - lar->sunsky = (struct SunSky*)MEM_callocN(sizeof(struct SunSky), "sunskyren"); - lar->sunsky->effect_type = la->sun_effect_type; - - copy_v3_v3(vec, ob->obmat[2]); - normalize_v3(vec); - - InitSunSky( - lar->sunsky, la->atm_turbidity, vec, la->horizon_brightness, - la->spread, la->sun_brightness, la->sun_size, la->backscattered_light, - la->skyblendfac, la->skyblendtype, la->sky_exposure, la->sky_colorspace); - InitAtmosphere( - lar->sunsky, la->sun_intensity, 1.0, 1.0, la->atm_inscattering_factor, la->atm_extinction_factor, - la->atm_distance_factor); - } - } - else lar->ray_totsamp= 0; - - lar->spotsi= la->spotsize; - if (lar->mode & LA_HALO) { - if (lar->spotsi > DEG2RADF(170.0f)) lar->spotsi = DEG2RADF(170.0f); - } - lar->spotsi= cosf(lar->spotsi * 0.5f); - lar->spotbl= (1.0f-lar->spotsi)*la->spotblend; - - memcpy(lar->mtex, la->mtex, MAX_MTEX*sizeof(void *)); - - lar->lay = ob->lay & 0xFFFFFF; /* higher 8 bits are localview layers */ - - lar->falloff_type = la->falloff_type; - lar->ld1= la->att1; - lar->ld2= la->att2; - lar->coeff_const= la->coeff_const; - lar->coeff_lin= la->coeff_lin; - lar->coeff_quad= la->coeff_quad; - lar->curfalloff = curvemapping_copy(la->curfalloff); - - if (lar->curfalloff) { - /* so threads don't conflict on init */ - curvemapping_initialize(lar->curfalloff); - } - - if (lar->type==LA_SPOT) { - - normalize_v3(lar->imat[0]); - normalize_v3(lar->imat[1]); - normalize_v3(lar->imat[2]); - - xn = saacos(lar->spotsi); - xn = sinf(xn) / cosf(xn); - lar->spottexfac= 1.0f/(xn); - - if (lar->mode & LA_ONLYSHADOW) { - if ((lar->mode & (LA_SHAD_BUF|LA_SHAD_RAY))==0) lar->mode -= LA_ONLYSHADOW; - } - - } - - /* set flag for spothalo en initvars */ - if ((la->type == LA_SPOT) && (la->mode & LA_HALO) && - (!(la->mode & LA_SHAD_BUF) || la->buftype != LA_SHADBUF_DEEP)) - { - if (la->haint>0.0f) { - re->flag |= R_LAMPHALO; - - /* camera position (0, 0, 0) rotate around lamp */ - lar->sh_invcampos[0]= -lar->co[0]; - lar->sh_invcampos[1]= -lar->co[1]; - lar->sh_invcampos[2]= -lar->co[2]; - mul_m3_v3(lar->imat, lar->sh_invcampos); - - /* z factor, for a normalized volume */ - angle= saacos(lar->spotsi); - xn= lar->spotsi; - yn = sinf(angle); - lar->sh_zfac= yn/xn; - /* pre-scale */ - lar->sh_invcampos[2]*= lar->sh_zfac; - - /* halfway shadow buffer doesn't work for volumetric effects */ - if (ELEM(lar->buftype, LA_SHADBUF_HALFWAY, LA_SHADBUF_DEEP)) - lar->buftype = LA_SHADBUF_REGULAR; - - } - } - else if (la->type==LA_HEMI) { - lar->mode &= ~(LA_SHAD_RAY|LA_SHAD_BUF); - } - - for (c=0; c<MAX_MTEX; c++) { - if (la->mtex[c] && la->mtex[c]->tex) { - if (la->mtex[c]->mapto & LAMAP_COL) - lar->mode |= LA_TEXTURE; - if (la->mtex[c]->mapto & LAMAP_SHAD) - lar->mode |= LA_SHAD_TEX; - - if (G.is_rendering) { - if (re->osa) { - if (la->mtex[c]->tex->type==TEX_IMAGE) lar->mode |= LA_OSATEX; - } - } - } - } - - /* old code checked for internal render (aka not yafray) */ - { - /* to make sure we can check ray shadow easily in the render code */ - if (lar->mode & LA_SHAD_RAY) { - if ( (re->r.mode & R_RAYTRACE)==0) - lar->mode &= ~LA_SHAD_RAY; - } - - - if (re->r.mode & R_SHADOW) { - - if (la->type==LA_AREA && (lar->mode & LA_SHAD_RAY) && (lar->ray_samp_method == LA_SAMP_CONSTANT)) { - init_jitter_plane(lar); - } - else if (la->type==LA_SPOT && (lar->mode & LA_SHAD_BUF) ) { - /* Per lamp, one shadow buffer is made. */ - lar->bufflag= la->bufflag; - copy_m4_m4(mat, ob->obmat); - initshadowbuf(re, lar, mat); /* mat is altered */ - } - - - /* this is the way used all over to check for shadow */ - if (lar->shb || (lar->mode & LA_SHAD_RAY)) { - LampShadowSample *ls; - LampShadowSubSample *lss; - int a, b; - - memset(re->shadowsamplenr, 0, sizeof(re->shadowsamplenr)); - - lar->shadsamp= MEM_mallocN(re->r.threads*sizeof(LampShadowSample), "lamp shadow sample"); - ls= lar->shadsamp; - - /* shadfacs actually mean light, let's put them to 1 to prevent unitialized accidents */ - for (a=0; a<re->r.threads; a++, ls++) { - lss= ls->s; - for (b=0; b<re->r.osa; b++, lss++) { - lss->samplenr= -1; /* used to detect whether we store or read */ - lss->shadfac[0]= 1.0f; - lss->shadfac[1]= 1.0f; - lss->shadfac[2]= 1.0f; - lss->shadfac[3]= 1.0f; - } - } - } - } - } - - return go; -} - -static bool is_object_restricted(Render *re, Object *ob) -{ - if (re->r.scemode & R_VIEWPORT_PREVIEW) - return (ob->restrictflag & OB_RESTRICT_VIEW) != 0; - else - return (ob->restrictflag & OB_RESTRICT_RENDER) != 0; -} - -static bool is_object_hidden(Render *re, Object *ob) -{ - if (is_object_restricted(re, ob)) - return true; - - if (re->r.scemode & R_VIEWPORT_PREVIEW) { - /* Mesh deform cages and so on mess up the preview. To avoid the problem, - * viewport doesn't show mesh object if its draw type is bounding box or wireframe. - * Unless it's an active smoke domain! - */ - ModifierData *md = NULL; - - if ((md = modifiers_findByType(ob, eModifierType_Smoke)) && - (modifier_isEnabled(re->scene, md, eModifierMode_Realtime))) - { - return false; - } - return ELEM(ob->dt, OB_BOUNDBOX, OB_WIRE); - } - else { - return false; - } -} - -/* layflag: allows material group to ignore layerflag */ -static void add_lightgroup(Render *re, Group *group, int exclusive) -{ - group->id.tag &= ~LIB_TAG_DOIT; - -#if 0 - /* it's a bit too many loops in loops... but will survive */ - /* note that 'exclusive' will remove it from the global list */ - FOREACH_GROUP_BASE_BEGIN(group, base) - { - Object *object = base->object; - - if (is_object_hidden(re, object)) { - continue; - } - - if (base->flag & BASE_VISIBLED) { - if (object && object->type == OB_LAMP) { - for (GroupObject *gol = re->lights.first; gol; gol = gol->next) { - if (gol->ob == object) { - go->lampren = gol->lampren; - break; - } - } - - if (go->lampren == NULL) { - gol= add_render_lamp(re, object); - } - - if (gol && exclusive) { - BLI_remlink(&re->lights, gol); - MEM_freeN(gol); - } - } - } - } - FOREACH_GROUP_BASE_END; -#else - UNUSED_VARS(re, exclusive); -#endif -} - -static void set_material_lightgroups(Render *re) -{ - Group *group; - Material *ma; - - /* not for preview render */ - if (re->scene->r.scemode & (R_BUTS_PREVIEW|R_VIEWPORT_PREVIEW)) - return; - - for (group= re->main->group.first; group; group=group->id.next) - group->id.tag |= LIB_TAG_DOIT; - - /* it's a bit too many loops in loops... but will survive */ - /* hola! materials not in use...? */ - for (ma= re->main->mat.first; ma; ma=ma->id.next) { - if (ma->group && (ma->group->id.tag & LIB_TAG_DOIT)) - add_lightgroup(re, ma->group, ma->mode & MA_GROUP_NOLAY); - } -} - -/* ------------------------------------------------------------------------- */ -/* World */ -/* ------------------------------------------------------------------------- */ - -void init_render_world(Render *re) -{ - void *wrld_prev[2] = { - re->wrld.aotables, - re->wrld.aosphere, - }; - - int a; - - if (re->scene && re->scene->world) { - re->wrld = *(re->scene->world); - - copy_v3_v3(re->grvec, re->viewmat[2]); - normalize_v3(re->grvec); - copy_m3_m4(re->imat, re->viewinv); - - for (a=0; a<MAX_MTEX; a++) - if (re->wrld.mtex[a] && re->wrld.mtex[a]->tex) re->wrld.skytype |= WO_SKYTEX; - - /* AO samples should be OSA minimum */ - if (re->osa) - while (re->wrld.aosamp*re->wrld.aosamp < re->osa) - re->wrld.aosamp++; - if (!(re->r.mode & R_RAYTRACE) && (re->wrld.ao_gather_method == WO_AOGATHER_RAYTRACE)) - re->wrld.mode &= ~(WO_AMB_OCC|WO_ENV_LIGHT|WO_INDIRECT_LIGHT); - } - else { - memset(&re->wrld, 0, sizeof(World)); - re->wrld.exp= 0.0f; - re->wrld.range= 1.0f; - - /* for mist pass */ - re->wrld.miststa= re->clipsta; - re->wrld.mistdist= re->clipend-re->clipsta; - re->wrld.misi= 1.0f; - } - - re->wrld.linfac= 1.0f + powf((2.0f*re->wrld.exp + 0.5f), -10); - re->wrld.logfac= logf((re->wrld.linfac-1.0f)/re->wrld.linfac) / re->wrld.range; - - /* restore runtime vars, needed for viewport rendering [#36005] */ - re->wrld.aotables = wrld_prev[0]; - re->wrld.aosphere = wrld_prev[1]; -} - - - -/* ------------------------------------------------------------------------- */ -/* Object Finalization */ -/* ------------------------------------------------------------------------- */ - -/* prevent phong interpolation for giving ray shadow errors (terminator problem) */ -static void set_phong_threshold(ObjectRen *obr) -{ -// VertRen *ver; - VlakRen *vlr; - float thresh= 0.0, dot; - int tot=0, i; - - /* Added check for 'pointy' situations, only dotproducts of 0.9 and larger - * are taken into account. This threshold is meant to work on smooth geometry, not - * for extreme cases (ton) */ - - for (i=0; i<obr->totvlak; i++) { - vlr= RE_findOrAddVlak(obr, i); - if ((vlr->flag & R_SMOOTH) && (vlr->flag & R_STRAND)==0) { - dot= dot_v3v3(vlr->n, vlr->v1->n); - dot= ABS(dot); - if (dot>0.9f) { - thresh+= dot; tot++; - } - dot= dot_v3v3(vlr->n, vlr->v2->n); - dot= ABS(dot); - if (dot>0.9f) { - thresh+= dot; tot++; - } - - dot= dot_v3v3(vlr->n, vlr->v3->n); - dot= ABS(dot); - if (dot>0.9f) { - thresh+= dot; tot++; - } - - if (vlr->v4) { - dot= dot_v3v3(vlr->n, vlr->v4->n); - dot= ABS(dot); - if (dot>0.9f) { - thresh+= dot; tot++; - } - } - } - } - - if (tot) { - thresh/= (float)tot; - obr->ob->smoothresh= cosf(0.5f*(float)M_PI-saacos(thresh)); - } -} - -/* per face check if all samples should be taken. - * if raytrace or multisample, do always for raytraced material, or when material full_osa set */ -static void set_fullsample_trace_flag(Render *re, ObjectRen *obr) -{ - VlakRen *vlr; - int a, trace, mode, osa; - - osa= re->osa; - trace= re->r.mode & R_RAYTRACE; - - for (a=obr->totvlak-1; a>=0; a--) { - vlr= RE_findOrAddVlak(obr, a); - mode= vlr->mat->mode; - - if (trace && (mode & MA_TRACEBLE)) - vlr->flag |= R_TRACEBLE; - - if (osa) { - if (mode & MA_FULL_OSA) { - vlr->flag |= R_FULL_OSA; - } - else if (trace) { - if (mode & MA_SHLESS) { - /* pass */ - } - else if (vlr->mat->material_type == MA_TYPE_VOLUME) { - /* pass */ - } - else if ((mode & MA_RAYMIRROR) || ((mode & MA_TRANSP) && (mode & MA_RAYTRANSP))) { - /* for blurry reflect/refract, better to take more samples - * inside the raytrace than as OSA samples */ - if ((vlr->mat->gloss_mir == 1.0f) && (vlr->mat->gloss_tra == 1.0f)) - vlr->flag |= R_FULL_OSA; - } - } - } - } -} - -/* split quads for predictable baking - * dir 1 == (0, 1, 2) (0, 2, 3), 2 == (1, 3, 0) (1, 2, 3) - */ -static void split_quads(ObjectRen *obr, int dir) -{ - VlakRen *vlr, *vlr1; - int a; - - for (a=obr->totvlak-1; a>=0; a--) { - vlr= RE_findOrAddVlak(obr, a); - - /* test if rendering as a quad or triangle, skip wire */ - if ((vlr->flag & R_STRAND)==0 && (vlr->mat->material_type != MA_TYPE_WIRE)) { - - if (vlr->v4) { - - vlr1= RE_vlakren_copy(obr, vlr); - vlr1->flag |= R_FACE_SPLIT; - - if ( dir==2 ) vlr->flag |= R_DIVIDE_24; - else vlr->flag &= ~R_DIVIDE_24; - - /* new vertex pointers */ - if (vlr->flag & R_DIVIDE_24) { - vlr1->v1= vlr->v2; - vlr1->v2= vlr->v3; - vlr1->v3= vlr->v4; - - vlr->v3 = vlr->v4; - - vlr1->flag |= R_DIVIDE_24; - } - else { - vlr1->v1= vlr->v1; - vlr1->v2= vlr->v3; - vlr1->v3= vlr->v4; - - vlr1->flag &= ~R_DIVIDE_24; - } - vlr->v4 = vlr1->v4 = NULL; - -#ifdef WITH_FREESTYLE - /* Freestyle edge marks */ - if (vlr->flag & R_DIVIDE_24) { - vlr1->freestyle_edge_mark= - ((vlr->freestyle_edge_mark & R_EDGE_V2V3) ? R_EDGE_V1V2 : 0) | - ((vlr->freestyle_edge_mark & R_EDGE_V3V4) ? R_EDGE_V2V3 : 0); - vlr->freestyle_edge_mark= - ((vlr->freestyle_edge_mark & R_EDGE_V1V2) ? R_EDGE_V1V2 : 0) | - ((vlr->freestyle_edge_mark & R_EDGE_V4V1) ? R_EDGE_V3V1 : 0); - } - else { - vlr1->freestyle_edge_mark= - ((vlr->freestyle_edge_mark & R_EDGE_V3V4) ? R_EDGE_V2V3 : 0) | - ((vlr->freestyle_edge_mark & R_EDGE_V4V1) ? R_EDGE_V3V1 : 0); - vlr->freestyle_edge_mark= - ((vlr->freestyle_edge_mark & R_EDGE_V1V2) ? R_EDGE_V1V2 : 0) | - ((vlr->freestyle_edge_mark & R_EDGE_V2V3) ? R_EDGE_V2V3 : 0); - } -#endif - - /* new normals */ - normal_tri_v3(vlr->n, vlr->v3->co, vlr->v2->co, vlr->v1->co); - normal_tri_v3(vlr1->n, vlr1->v3->co, vlr1->v2->co, vlr1->v1->co); - } - /* clear the flag when not divided */ - else vlr->flag &= ~R_DIVIDE_24; - } - } -} - -static void check_non_flat_quads(ObjectRen *obr) -{ - VlakRen *vlr, *vlr1; - VertRen *v1, *v2, *v3, *v4; - float nor[3], xn, flen; - int a; - - for (a=obr->totvlak-1; a>=0; a--) { - vlr= RE_findOrAddVlak(obr, a); - - /* test if rendering as a quad or triangle, skip wire */ - if (vlr->v4 && (vlr->flag & R_STRAND)==0 && (vlr->mat->material_type != MA_TYPE_WIRE)) { - - /* check if quad is actually triangle */ - v1= vlr->v1; - v2= vlr->v2; - v3= vlr->v3; - v4= vlr->v4; - sub_v3_v3v3(nor, v1->co, v2->co); - if ( ABS(nor[0])<FLT_EPSILON10 && ABS(nor[1])<FLT_EPSILON10 && ABS(nor[2])<FLT_EPSILON10 ) { - vlr->v1= v2; - vlr->v2= v3; - vlr->v3= v4; - vlr->v4= NULL; - vlr->flag |= (R_DIVIDE_24 | R_FACE_SPLIT); - } - else { - sub_v3_v3v3(nor, v2->co, v3->co); - if ( ABS(nor[0])<FLT_EPSILON10 && ABS(nor[1])<FLT_EPSILON10 && ABS(nor[2])<FLT_EPSILON10 ) { - vlr->v2= v3; - vlr->v3= v4; - vlr->v4= NULL; - vlr->flag |= R_FACE_SPLIT; - } - else { - sub_v3_v3v3(nor, v3->co, v4->co); - if ( ABS(nor[0])<FLT_EPSILON10 && ABS(nor[1])<FLT_EPSILON10 && ABS(nor[2])<FLT_EPSILON10 ) { - vlr->v4= NULL; - } - else { - sub_v3_v3v3(nor, v4->co, v1->co); - if ( ABS(nor[0])<FLT_EPSILON10 && ABS(nor[1])<FLT_EPSILON10 && ABS(nor[2])<FLT_EPSILON10 ) { - vlr->v4= NULL; - } - } - } - } - - if (vlr->v4) { - - /* Face is divided along edge with the least gradient */ - /* Flagged with R_DIVIDE_24 if divide is from vert 2 to 4 */ - /* 4---3 4---3 */ - /* |\ 1| or |1 /| */ - /* |0\ | |/ 0| */ - /* 1---2 1---2 0 = orig face, 1 = new face */ - - /* render normals are inverted in render! we calculate normal of single tria here */ - flen= normal_tri_v3(nor, vlr->v4->co, vlr->v3->co, vlr->v1->co); - if (flen==0.0f) normal_tri_v3(nor, vlr->v4->co, vlr->v2->co, vlr->v1->co); - - xn = dot_v3v3(nor, vlr->n); - - if (ABS(xn) < 0.999995f ) { /* checked on noisy fractal grid */ - - float d1, d2; - - vlr1= RE_vlakren_copy(obr, vlr); - vlr1->flag |= R_FACE_SPLIT; - - /* split direction based on vnorms */ - normal_tri_v3(nor, vlr->v1->co, vlr->v2->co, vlr->v3->co); - d1 = dot_v3v3(nor, vlr->v1->n); - - normal_tri_v3(nor, vlr->v2->co, vlr->v3->co, vlr->v4->co); - d2 = dot_v3v3(nor, vlr->v2->n); - - if (fabsf(d1) < fabsf(d2) ) vlr->flag |= R_DIVIDE_24; - else vlr->flag &= ~R_DIVIDE_24; - - /* new vertex pointers */ - if (vlr->flag & R_DIVIDE_24) { - vlr1->v1= vlr->v2; - vlr1->v2= vlr->v3; - vlr1->v3= vlr->v4; - - vlr->v3 = vlr->v4; - - vlr1->flag |= R_DIVIDE_24; - } - else { - vlr1->v1= vlr->v1; - vlr1->v2= vlr->v3; - vlr1->v3= vlr->v4; - - vlr1->flag &= ~R_DIVIDE_24; - } - vlr->v4 = vlr1->v4 = NULL; - - /* new normals */ - normal_tri_v3(vlr->n, vlr->v3->co, vlr->v2->co, vlr->v1->co); - normal_tri_v3(vlr1->n, vlr1->v3->co, vlr1->v2->co, vlr1->v1->co); - -#ifdef WITH_FREESTYLE - /* Freestyle edge marks */ - if (vlr->flag & R_DIVIDE_24) { - vlr1->freestyle_edge_mark= - ((vlr->freestyle_edge_mark & R_EDGE_V2V3) ? R_EDGE_V1V2 : 0) | - ((vlr->freestyle_edge_mark & R_EDGE_V3V4) ? R_EDGE_V2V3 : 0); - vlr->freestyle_edge_mark= - ((vlr->freestyle_edge_mark & R_EDGE_V1V2) ? R_EDGE_V1V2 : 0) | - ((vlr->freestyle_edge_mark & R_EDGE_V4V1) ? R_EDGE_V3V1 : 0); - } - else { - vlr1->freestyle_edge_mark= - ((vlr->freestyle_edge_mark & R_EDGE_V3V4) ? R_EDGE_V2V3 : 0) | - ((vlr->freestyle_edge_mark & R_EDGE_V4V1) ? R_EDGE_V3V1 : 0); - vlr->freestyle_edge_mark= - ((vlr->freestyle_edge_mark & R_EDGE_V1V2) ? R_EDGE_V1V2 : 0) | - ((vlr->freestyle_edge_mark & R_EDGE_V2V3) ? R_EDGE_V2V3 : 0); - } -#endif - } - /* clear the flag when not divided */ - else vlr->flag &= ~R_DIVIDE_24; - } - } - } -} - -static void finalize_render_object(Render *re, ObjectRen *obr, int timeoffset) -{ - Object *ob= obr->ob; - VertRen *ver= NULL; - StrandRen *strand= NULL; - StrandBound *sbound= NULL; - float min[3], max[3], smin[3], smax[3]; - int a, b; - - if (obr->totvert || obr->totvlak || obr->tothalo || obr->totstrand) { - /* the exception below is because displace code now is in init_render_mesh call, - * I will look at means to have autosmooth enabled for all object types - * and have it as general postprocess, like displace */ - if (ob->type!=OB_MESH && test_for_displace(re, ob)) - displace(re, obr); - - if (!timeoffset) { - /* phong normal interpolation can cause error in tracing - * (terminator problem) */ - ob->smoothresh= 0.0; - if ((re->r.mode & R_RAYTRACE) && (re->r.mode & R_SHADOW)) - set_phong_threshold(obr); - - if (re->flag & R_BAKING && re->r.bake_quad_split != 0) { - /* Baking lets us define a quad split order */ - split_quads(obr, re->r.bake_quad_split); - } - else if (BKE_object_is_animated(re->scene, ob)) - split_quads(obr, 1); - else { - if ((re->r.mode & R_SIMPLIFY && re->r.simplify_flag & R_SIMPLE_NO_TRIANGULATE) == 0) - check_non_flat_quads(obr); - } - - set_fullsample_trace_flag(re, obr); - - /* compute bounding boxes for clipping */ - INIT_MINMAX(min, max); - for (a=0; a<obr->totvert; a++) { - if ((a & 255)==0) ver= obr->vertnodes[a>>8].vert; - else ver++; - - minmax_v3v3_v3(min, max, ver->co); - } - - if (obr->strandbuf) { - float width; - - /* compute average bounding box of strandpoint itself (width) */ - if (obr->strandbuf->flag & R_STRAND_B_UNITS) - obr->strandbuf->maxwidth = max_ff(obr->strandbuf->ma->strand_sta, obr->strandbuf->ma->strand_end); - else - obr->strandbuf->maxwidth= 0.0f; - - width= obr->strandbuf->maxwidth; - sbound= obr->strandbuf->bound; - for (b=0; b<obr->strandbuf->totbound; b++, sbound++) { - - INIT_MINMAX(smin, smax); - - for (a=sbound->start; a<sbound->end; a++) { - strand= RE_findOrAddStrand(obr, a); - strand_minmax(strand, smin, smax, width); - } - - copy_v3_v3(sbound->boundbox[0], smin); - copy_v3_v3(sbound->boundbox[1], smax); - - minmax_v3v3_v3(min, max, smin); - minmax_v3v3_v3(min, max, smax); - } - } - - copy_v3_v3(obr->boundbox[0], min); - copy_v3_v3(obr->boundbox[1], max); - } - } -} - -/* ------------------------------------------------------------------------- */ -/* Database */ -/* ------------------------------------------------------------------------- */ - -static int render_object_type(short type) -{ - return OB_TYPE_SUPPORT_MATERIAL(type); -} - -static void find_dupli_instances(Render *re, ObjectRen *obr, DupliObject *dob) -{ - ObjectInstanceRen *obi; - float imat[4][4], obmat[4][4], obimat[4][4], nmat[3][3]; - int first = 1; - - mul_m4_m4m4(obmat, re->viewmat, obr->obmat); - invert_m4_m4(imat, obmat); - - /* for objects instanced by dupliverts/faces/particles, we go over the - * list of instances to find ones that instance obr, and setup their - * matrices and obr pointer */ - for (obi=re->instancetable.last; obi; obi=obi->prev) { - if (!obi->obr && obi->ob == obr->ob && obi->psysindex == obr->psysindex) { - obi->obr= obr; - - /* compute difference between object matrix and - * object matrix with dupli transform, in viewspace */ - copy_m4_m4(obimat, obi->mat); - mul_m4_m4m4(obi->mat, obimat, imat); - - copy_m3_m4(nmat, obi->mat); - invert_m3_m3(obi->nmat, nmat); - transpose_m3(obi->nmat); - - if (dob) { - copy_v3_v3(obi->dupliorco, dob->orco); - obi->dupliuv[0]= dob->uv[0]; - obi->dupliuv[1]= dob->uv[1]; - } - - if (!first) { - re->totvert += obr->totvert; - re->totvlak += obr->totvlak; - re->tothalo += obr->tothalo; - re->totstrand += obr->totstrand; - } - else - first= 0; - } - } -} - -static void assign_dupligroup_dupli(Render *re, ObjectInstanceRen *obi, ObjectRen *obr, DupliObject *dob) -{ - float imat[4][4], obmat[4][4], obimat[4][4], nmat[3][3]; - - mul_m4_m4m4(obmat, re->viewmat, obr->obmat); - invert_m4_m4(imat, obmat); - - obi->obr= obr; - - /* compute difference between object matrix and - * object matrix with dupli transform, in viewspace */ - copy_m4_m4(obimat, obi->mat); - mul_m4_m4m4(obi->mat, obimat, imat); - - copy_m3_m4(nmat, obi->mat); - invert_m3_m3(obi->nmat, nmat); - transpose_m3(obi->nmat); - - if (dob) { - copy_v3_v3(obi->dupliorco, dob->orco); - obi->dupliuv[0]= dob->uv[0]; - obi->dupliuv[1]= dob->uv[1]; - } - - re->totvert += obr->totvert; - re->totvlak += obr->totvlak; - re->tothalo += obr->tothalo; - re->totstrand += obr->totstrand; -} - -static ObjectRen *find_dupligroup_dupli(Render *re, Object *ob, int psysindex) -{ - ObjectRen *obr; - - /* if the object is itself instanced, we don't want to create an instance - * for it */ - if (ob->transflag & OB_RENDER_DUPLI) - return NULL; - - /* try to find an object that was already created so we can reuse it - * and save memory */ - for (obr=re->objecttable.first; obr; obr=obr->next) - if (obr->ob == ob && obr->psysindex == psysindex && (obr->flag & R_INSTANCEABLE)) - return obr; - - return NULL; -} - -static void set_dupli_tex_mat(Render *re, ObjectInstanceRen *obi, DupliObject *dob, float omat[4][4]) -{ - /* For duplis we need to have a matrix that transform the coordinate back - * to it's original position, without the dupli transforms. We also check - * the matrix is actually needed, to save memory on lots of dupliverts for - * example */ - static Object *lastob= NULL; - static int needtexmat= 0; - - /* init */ - if (!re) { - lastob= NULL; - needtexmat= 0; - return; - } - - /* check if we actually need it */ - if (lastob != dob->ob) { - Material ***material; - short a, *totmaterial; - - lastob= dob->ob; - needtexmat= 0; - - totmaterial= give_totcolp(dob->ob); - material= give_matarar(dob->ob); - - if (totmaterial && material) - for (a= 0; a<*totmaterial; a++) - if ((*material)[a] && (*material)[a]->texco & TEXCO_OBJECT) - needtexmat= 1; - } - - if (needtexmat) { - float imat[4][4]; - - obi->duplitexmat= BLI_memarena_alloc(re->memArena, sizeof(float)*4*4); - invert_m4_m4(imat, dob->mat); - mul_m4_series(obi->duplitexmat, re->viewmat, omat, imat, re->viewinv); - } - - copy_v3_v3(obi->dupliorco, dob->orco); - copy_v2_v2(obi->dupliuv, dob->uv); -} - -static void init_render_object_data(Depsgraph *depsgraph, Render *re, ObjectRen *obr, int timeoffset) -{ - Object *ob= obr->ob; - ParticleSystem *psys; - int i; - - if (obr->psysindex) { - if ((!obr->prev || obr->prev->ob != ob || (obr->prev->flag & R_INSTANCEABLE)==0) && ob->type==OB_MESH) { - /* the emitter mesh wasn't rendered so the modifier stack wasn't - * evaluated with render settings */ - DerivedMesh *dm; - const CustomDataMask mask = CD_MASK_RENDER_INTERNAL; - - if (re->r.scemode & R_VIEWPORT_PREVIEW) - dm = mesh_create_derived_view(depsgraph, re->scene, ob, mask); - else - dm = mesh_create_derived_render(depsgraph, re->scene, ob, mask); - dm->release(dm); - } - - for (psys=ob->particlesystem.first, i=0; i<obr->psysindex-1; i++) - psys= psys->next; - - render_new_particle_system(depsgraph, re, obr, psys, timeoffset); - } - else { - if (ELEM(ob->type, OB_FONT, OB_CURVE)) - init_render_curve(depsgraph, re, obr, timeoffset); - else if (ob->type==OB_SURF) - init_render_surf(depsgraph, re, obr, timeoffset); - else if (ob->type==OB_MESH) - init_render_mesh(depsgraph, re, obr, timeoffset); - else if (ob->type==OB_MBALL) - init_render_mball(depsgraph, re, obr); - } - - finalize_render_object(re, obr, timeoffset); - - re->totvert += obr->totvert; - re->totvlak += obr->totvlak; - re->tothalo += obr->tothalo; - re->totstrand += obr->totstrand; -} - -static void add_render_object(Depsgraph *depsgraph, Render *re, Object *ob, Object *par, DupliObject *dob, - float omat[4][4], int timeoffset) -{ - ObjectRen *obr; - ObjectInstanceRen *obi; - ParticleSystem *psys; - int show_emitter, allow_render= 1, index, psysindex, i; - - index= (dob)? dob->persistent_id[0]: 0; - - /* the emitter has to be processed first (render levels of modifiers) */ - /* so here we only check if the emitter should be rendered */ - if (ob->particlesystem.first) { - show_emitter = (ob->duplicator_visibility_flag & OB_DUPLI_FLAG_RENDER) != 0; - - /* if no psys has "show emitter" selected don't render emitter */ - if (show_emitter == 0) - allow_render= 0; - } - - /* one render object for the data itself */ - if (allow_render) { - obr= RE_addRenderObject(re, ob, par, index, 0, ob->lay); - if ((dob && !dob->animated) || (ob->transflag & OB_RENDER_DUPLI)) { - obr->flag |= R_INSTANCEABLE; - copy_m4_m4(obr->obmat, ob->obmat); - } - init_render_object_data(depsgraph, re, obr, timeoffset); - - /* only add instance for objects that have not been used for dupli */ - if (!(ob->transflag & OB_RENDER_DUPLI)) { - obi = RE_addRenderInstance(re, obr, ob, par, index, 0, NULL, ob->lay, dob); - if (dob) set_dupli_tex_mat(re, obi, dob, omat); - } - else - find_dupli_instances(re, obr, dob); - - for (i=1; i<=ob->totcol; i++) { - Material* ma = give_render_material(re, ob, i); - if (ma && ma->material_type == MA_TYPE_VOLUME) - add_volume(re, obr, ma); - } - } - - /* and one render object per particle system */ - if (ob->particlesystem.first) { - psysindex= 1; - for (psys=ob->particlesystem.first; psys; psys=psys->next, psysindex++) { - if (!psys_check_enabled(ob, psys, G.is_rendering)) - continue; - - obr= RE_addRenderObject(re, ob, par, index, psysindex, ob->lay); - if ((dob && !dob->animated) || (ob->transflag & OB_RENDER_DUPLI)) { - obr->flag |= R_INSTANCEABLE; - copy_m4_m4(obr->obmat, ob->obmat); - } - if (dob) - psys->flag |= PSYS_USE_IMAT; - init_render_object_data(depsgraph, re, obr, timeoffset); - psys->flag &= ~PSYS_USE_IMAT; - - /* only add instance for objects that have not been used for dupli */ - if (!(ob->transflag & OB_RENDER_DUPLI)) { - obi = RE_addRenderInstance(re, obr, ob, par, index, psysindex, NULL, ob->lay, dob); - if (dob) set_dupli_tex_mat(re, obi, dob, omat); - } - else - find_dupli_instances(re, obr, dob); - } - } -} - -/* par = pointer to duplicator parent, needed for object lookup table */ -/* index = when duplicater copies same object (particle), the counter */ -static void init_render_object(Depsgraph *depsgraph, Render *re, Object *ob, Object *par, DupliObject *dob, - float omat[4][4], int timeoffset) -{ - static double lasttime= 0.0; - double time; - float mat[4][4]; - - if (ob->type==OB_LAMP) - add_render_lamp(re, ob); - else if (render_object_type(ob->type)) - add_render_object(depsgraph, re, ob, par, dob, omat, timeoffset); - else { - mul_m4_m4m4(mat, re->viewmat, ob->obmat); - invert_m4_m4(ob->imat, mat); - } - - time= PIL_check_seconds_timer(); - if (time - lasttime > 1.0) { - lasttime= time; - /* clumsy copying still */ - re->i.totvert= re->totvert; - re->i.totface= re->totvlak; - re->i.totstrand= re->totstrand; - re->i.tothalo= re->tothalo; - re->i.totlamp= re->totlamp; - re->stats_draw(re->sdh, &re->i); - } - - ob->flag |= OB_DONE; -} - -void RE_Database_Free(Render *re) -{ - LampRen *lar; - - /* will crash if we try to free empty database */ - if (!re->i.convertdone) - return; - - /* statistics for debugging render memory usage */ - if ((G.debug & G_DEBUG) && (G.is_rendering)) { - if ((re->r.scemode & (R_BUTS_PREVIEW|R_VIEWPORT_PREVIEW))==0) { - BKE_image_print_memlist(); - MEM_printmemlist_stats(); - } - } - - /* FREE */ - - for (lar= re->lampren.first; lar; lar= lar->next) { - freeshadowbuf(lar); - if (lar->jitter) MEM_freeN(lar->jitter); - if (lar->shadsamp) MEM_freeN(lar->shadsamp); - if (lar->sunsky) MEM_freeN(lar->sunsky); - curvemapping_free(lar->curfalloff); - } - - free_volume_precache(re); - - BLI_freelistN(&re->lampren); - BLI_freelistN(&re->lights); - - free_renderdata_tables(re); - - /* free orco */ - free_mesh_orco_hash(re); - - if (re->main) { - end_render_materials(re->main); - end_render_textures(re); - free_pointdensities(re); - } - - free_camera_inside_volumes(re); - - if (re->wrld.aosphere) { - MEM_freeN(re->wrld.aosphere); - re->wrld.aosphere= NULL; - if (re->scene && re->scene->world) - re->scene->world->aosphere= NULL; - } - if (re->wrld.aotables) { - MEM_freeN(re->wrld.aotables); - re->wrld.aotables= NULL; - if (re->scene && re->scene->world) - re->scene->world->aotables= NULL; - } - if (re->r.mode & R_RAYTRACE) - free_render_qmcsampler(re); - - if (re->r.mode & R_RAYTRACE) freeraytree(re); - - free_sss(re); - free_occ(re); - free_strand_surface(re); - - re->totvlak=re->totvert=re->totstrand=re->totlamp=re->tothalo= 0; - re->i.convertdone = false; - - re->bakebuf= NULL; - - if (re->scene) - if (re->scene->r.scemode & R_FREE_IMAGE) - if ((re->r.scemode & (R_BUTS_PREVIEW|R_VIEWPORT_PREVIEW))==0) - BKE_image_free_all_textures(); - - if (re->memArena) { - BLI_memarena_free(re->memArena); - re->memArena = NULL; - } -} - -static int allow_render_object(Render *re, Object *ob, int nolamps, int onlyselected, Object *actob) -{ - if (is_object_hidden(re, ob)) - return 0; - - /* Only handle dupli-hiding here if there is no particle systems. Else, let those handle show/noshow. */ - if (!ob->particlesystem.first) { - if ((ob->transflag & OB_DUPLI) && !(ob->transflag & OB_DUPLIFRAMES)) { - return 0; - } - } - - /* don't add non-basic meta objects, ends up having renderobjects with no geometry */ - if (ob->type == OB_MBALL && ob!=BKE_mball_basis_find(re->scene, ob)) - return 0; - - if (nolamps && (ob->type==OB_LAMP)) - return 0; - - if (onlyselected && (ob!=actob && !(ob->flag & SELECT))) - return 0; - - return 1; -} - -static int allow_render_dupli_instance(Render *UNUSED(re), DupliObject *dob, Object *obd) -{ - ParticleSystem *psys; - Material *ma; - short a, *totmaterial; - - /* don't allow objects with halos. we need to have - * all halo's to sort them globally in advance */ - totmaterial= give_totcolp(obd); - - if (totmaterial) { - for (a= 0; a<*totmaterial; a++) { - ma= give_current_material(obd, a + 1); - if (ma && (ma->material_type == MA_TYPE_HALO)) - return 0; - } - } - - for (psys=obd->particlesystem.first; psys; psys=psys->next) - if (!ELEM(psys->part->ren_as, PART_DRAW_BB, PART_DRAW_LINE, PART_DRAW_PATH, PART_DRAW_OB, PART_DRAW_GR)) - return 0; - - /* don't allow lamp, animated duplis, or radio render */ - return (render_object_type(obd->type) && - (!(dob->type == OB_DUPLIGROUP) || !dob->animated)); -} - -static int get_vector_viewlayers(Scene *UNUSED(sce)) -{ - return 0; -} - -static void add_group_render_dupli_obs(Depsgraph *depsgraph, Render *re, Group *group, int nolamps, - int onlyselected, Object *actob, int timeoffset, int level) -{ - /* Simple preventing of too deep nested groups. */ - if (level > MAX_DUPLI_RECUR) return; - - /* Recursively go into dupligroups to find objects with OB_RENDER_DUPLI - * that were not created yet. */ - FOREACH_GROUP_OBJECT_BEGIN(group, ob) - { - if (ob->flag & OB_DONE) { - if (ob->transflag & OB_RENDER_DUPLI) { - if (allow_render_object(re, ob, nolamps, onlyselected, actob)) { - init_render_object(depsgraph, re, ob, NULL, NULL, NULL, timeoffset); - ob->transflag &= ~OB_RENDER_DUPLI; - - if (ob->dup_group) { - add_group_render_dupli_obs(depsgraph, re, ob->dup_group, nolamps, onlyselected, actob, timeoffset, level+1); - } - } - } - } - } - FOREACH_GROUP_OBJECT_END; -} - -static void database_init_objects(Depsgraph *depsgraph, Render *re, unsigned int UNUSED(renderlay), - int nolamps, int onlyselected, Object *actob, int timeoffset) -{ - Base *base; - Object *ob; - Group *group; - ObjectInstanceRen *obi; - Scene *sce_iter; - - /* for duplis we need the Object texture mapping to work as if - * untransformed, set_dupli_tex_mat sets the matrix to allow that - * NULL is just for init */ - set_dupli_tex_mat(NULL, NULL, NULL, NULL); - - /* loop over all objects rather then using SETLOOPER because we may - * reference an mtex-mapped object which isn't rendered or is an - * empty in a dupli group. We could scan all render material/lamp/world - * mtex's for mapto objects but its easier just to set the - * 'imat' / 'imat_ren' on all and unlikely to be a performance hit - * See bug: [#28744] - campbell */ - for (ob= re->main->object.first; ob; ob= ob->id.next) { - float mat[4][4]; - - /* imat objects has to be done here, since displace can have texture using Object map-input */ - mul_m4_m4m4(mat, re->viewmat, ob->obmat); - invert_m4_m4(ob->imat_ren, mat); - copy_m4_m4(ob->imat, ob->imat_ren); - /* each object should only be rendered once */ - ob->flag &= ~OB_DONE; - ob->transflag &= ~OB_RENDER_DUPLI; - } - - for (SETLOOPER(re->scene, sce_iter, base)) { - ob= base->object; - -#if 0 - TODO_LAYER; /* investigate if this is an issue*/ - /* in the prev/next pass for making speed vectors, avoid creating - * objects that are not on a renderlayer with a vector pass, can - * save a lot of time in complex scenes */ - vectorlay= get_vector_viewlayers(re->scene); -#endif - - /* if the object is not visible, ignore it */ - if ((base->flag & BASE_VISIBLED) == 0) { - continue; - } - - /* OB_DONE means the object itself got duplicated, so was already converted */ - if (ob->flag & OB_DONE) { - /* OB_RENDER_DUPLI means instances for it were already created, now - * it still needs to create the ObjectRen containing the data */ - if (ob->transflag & OB_RENDER_DUPLI) { - if (allow_render_object(re, ob, nolamps, onlyselected, actob)) { - init_render_object(depsgraph, re, ob, NULL, NULL, NULL, timeoffset); - ob->transflag &= ~OB_RENDER_DUPLI; - } - } - } - else if (((base->flag & BASE_VISIBLED) != 0) || (ob->type==OB_LAMP)) { - if ((ob->transflag & OB_DUPLI) && (ob->type!=OB_MBALL)) { - DupliObject *dob; - ListBase *duplilist; - DupliApplyData *duplilist_apply_data = NULL; - int i; - - /* create list of duplis generated by this object, particle - * system need to have render settings set for dupli particles */ - duplilist = object_duplilist(depsgraph, re->scene, ob); - duplilist_apply_data = duplilist_apply(depsgraph, ob, NULL, duplilist); - - for (dob= duplilist->first, i = 0; dob; dob= dob->next, ++i) { - DupliExtraData *dob_extra = &duplilist_apply_data->extra[i]; - Object *obd= dob->ob; - - copy_m4_m4(obd->obmat, dob->mat); - - /* group duplis need to set ob matrices correct, for deform. so no_draw is part handled */ - if (!(obd->transflag & OB_RENDER_DUPLI) && dob->no_draw) - continue; - - if (is_object_hidden(re, obd)) - continue; - - if (obd->type==OB_MBALL) - continue; - - if (!allow_render_object(re, obd, nolamps, onlyselected, actob)) - continue; - - if (allow_render_dupli_instance(re, dob, obd)) { - ParticleSystem *psys; - ObjectRen *obr = NULL; - int psysindex; - float mat[4][4]; - - obi=NULL; - - /* instances instead of the actual object are added in two cases, either - * this is a duplivert/face/particle, or it is a non-animated object in - * a dupligroup that has already been created before */ - if (dob->type != OB_DUPLIGROUP || (obr=find_dupligroup_dupli(re, obd, 0))) { - mul_m4_m4m4(mat, re->viewmat, dob->mat); - /* ob = particle system, use that layer */ - obi = RE_addRenderInstance(re, NULL, obd, ob, dob->persistent_id[0], 0, mat, ob->lay, dob); - - /* fill in instance variables for texturing */ - set_dupli_tex_mat(re, obi, dob, dob_extra->obmat); - if (dob->type != OB_DUPLIGROUP) { - copy_v3_v3(obi->dupliorco, dob->orco); - obi->dupliuv[0]= dob->uv[0]; - obi->dupliuv[1]= dob->uv[1]; - } - else { - /* for the second case, setup instance to point to the already - * created object, and possibly setup instances if this object - * itself was duplicated. for the first case find_dupli_instances - * will be called later. */ - assign_dupligroup_dupli(re, obi, obr, dob); - if (obd->transflag & OB_RENDER_DUPLI) - find_dupli_instances(re, obr, dob); - } - } - - /* same logic for particles, each particle system has it's own object, so - * need to go over them separately */ - psysindex= 1; - for (psys=obd->particlesystem.first; psys; psys=psys->next) { - if (dob->type != OB_DUPLIGROUP || (obr=find_dupligroup_dupli(re, obd, psysindex))) { - if (obi == NULL) - mul_m4_m4m4(mat, re->viewmat, dob->mat); - obi = RE_addRenderInstance(re, NULL, obd, ob, dob->persistent_id[0], psysindex++, mat, obd->lay, dob); - - set_dupli_tex_mat(re, obi, dob, dob_extra->obmat); - if (dob->type != OB_DUPLIGROUP) { - copy_v3_v3(obi->dupliorco, dob->orco); - obi->dupliuv[0]= dob->uv[0]; - obi->dupliuv[1]= dob->uv[1]; - } - else { - assign_dupligroup_dupli(re, obi, obr, dob); - if (obd->transflag & OB_RENDER_DUPLI) - find_dupli_instances(re, obr, dob); - } - } - } - - if (obi==NULL) - /* can't instance, just create the object */ - init_render_object(depsgraph, re, obd, ob, dob, dob_extra->obmat, timeoffset); - - if (dob->type != OB_DUPLIGROUP) { - obd->flag |= OB_DONE; - obd->transflag |= OB_RENDER_DUPLI; - } - } - else - init_render_object(depsgraph, re, obd, ob, dob, dob_extra->obmat, timeoffset); - - if (re->test_break(re->tbh)) break; - } - - if (duplilist_apply_data) { - duplilist_restore(duplilist, duplilist_apply_data); - duplilist_free_apply_data(duplilist_apply_data); - } - free_object_duplilist(duplilist); - - if (allow_render_object(re, ob, nolamps, onlyselected, actob)) - init_render_object(depsgraph, re, ob, NULL, NULL, NULL, timeoffset); - } - else if (allow_render_object(re, ob, nolamps, onlyselected, actob)) - init_render_object(depsgraph, re, ob, NULL, NULL, NULL, timeoffset); - } - - if (re->test_break(re->tbh)) break; - } - - /* objects in groups with OB_RENDER_DUPLI set still need to be created, - * since they may not be part of the scene */ - for (group= re->main->group.first; group; group=group->id.next) - add_group_render_dupli_obs(depsgraph, re, group, nolamps, onlyselected, actob, timeoffset, 0); - - if (!re->test_break(re->tbh)) - RE_makeRenderInstances(re); -} - -void RE_Database_CameraOnly(Render *re, Main *bmain, Scene *scene, unsigned int lay, int use_camera_view) -{ - Object *camera; - float mat[4][4]; - - re->main= bmain; - re->scene= scene; - re->lay= lay; - - /* scene needs to be set to get camera */ - camera= RE_GetCamera(re); - - /* if no camera, viewmat should have been set! */ - if (use_camera_view && camera) { - /* called before but need to call again in case of lens animation from the - * above call to BKE_scene_graph_update_for_newframe, fixes bug. [#22702]. - * following calls don't depend on 'RE_SetCamera' */ - RE_SetCamera(re, camera); - RE_GetCameraModelMatrix(re, camera, mat); - invert_m4(mat); - RE_SetView(re, mat); - - /* force correct matrix for scaled cameras */ - DEG_id_tag_update_ex(re->main, &camera->id, OB_RECALC_OB); - } -} - -/* used to be 'rotate scene' */ -void RE_Database_FromScene(Render *re, Main *bmain, Scene *scene, unsigned int lay, int use_camera_view) -{ - Object *camera; - float mat[4][4]; - float amb[3]; - - re->main= bmain; - re->scene= scene; - re->lay= lay; - - if (re->r.scemode & R_VIEWPORT_PREVIEW) - re->scene_color_manage = BKE_scene_check_color_management_enabled(scene); - - /* scene needs to be set to get camera */ - camera= RE_GetCamera(re); - - /* per second, per object, stats print this */ - re->i.infostr= "Preparing Scene data"; - re->i.cfra= scene->r.cfra; - BLI_strncpy(re->i.scene_name, scene->id.name + 2, sizeof(re->i.scene_name)); - - /* XXX add test if dbase was filled already? */ - - re->memArena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "render db arena"); - re->totvlak=re->totvert=re->totstrand=re->totlamp=re->tothalo= 0; - re->lights.first= re->lights.last= NULL; - re->lampren.first= re->lampren.last= NULL; - - re->i.partsdone = false; /* signal now in use for previewrender */ - - /* in localview, lamps are using normal layers, objects only local bits */ - if (re->lay & 0xFF000000) - lay &= 0xFF000000; - - /* applies changes fully */ - if ((re->r.scemode & (R_NO_FRAME_UPDATE|R_BUTS_PREVIEW|R_VIEWPORT_PREVIEW))==0) { - render_update_anim_renderdata(re, &re->scene->r, &re->scene->view_layers); - } - - /* if no camera, viewmat should have been set! */ - if (use_camera_view && camera) { - /* called before but need to call again in case of lens animation from the - * above call to BKE_scene_graph_update_for_newframe, fixes bug. [#22702]. - * following calls don't depend on 'RE_SetCamera' */ - RE_SetCamera(re, camera); - RE_GetCameraModelMatrix(re, camera, mat); - invert_m4(mat); - RE_SetView(re, mat); - - /* force correct matrix for scaled cameras */ - DEG_id_tag_update_ex(re->main, &camera->id, OB_RECALC_OB); - } - - /* store for incremental render, viewmat rotates dbase */ - copy_m4_m4(re->viewmat_orig, re->viewmat); - - init_render_world(re); /* do first, because of ambient. also requires re->osa set correct */ - if (re->r.mode & R_RAYTRACE) { - init_render_qmcsampler(re); - - if (re->wrld.mode & (WO_AMB_OCC|WO_ENV_LIGHT|WO_INDIRECT_LIGHT)) - if (re->wrld.ao_samp_method == WO_AOSAMP_CONSTANT) - init_ao_sphere(re, &re->wrld); - } - - /* still bad... doing all */ - init_render_textures(re); - copy_v3_v3(amb, &re->wrld.ambr); - init_render_materials(re->main, re->r.mode, amb, (re->r.scemode & R_BUTS_PREVIEW) == 0); - set_node_shader_lamp_loop(shade_material_loop); - - /* MAKE RENDER DATA */ - Depsgraph *depsgraph = NULL; - BLI_assert(depsgraph); - /* This will break things, and it should because honestly this function is deprecated and no one uses it. - * maybe freestyle? But even so, this need to change. Even freestyle need to get data from depsgraph - * so we can't create the database only once. */ - database_init_objects(depsgraph, re, lay, 0, 0, NULL, 0); - - if (!re->test_break(re->tbh)) { - set_material_lightgroups(re); - - /* for now some clumsy copying still */ - re->i.totvert= re->totvert; - re->i.totface= re->totvlak; - re->i.totstrand= re->totstrand; - re->i.tothalo= re->tothalo; - re->i.totlamp= re->totlamp; - re->stats_draw(re->sdh, &re->i); - } -} - -void RE_Database_Preprocess(Depsgraph *depsgraph, Render *re) -{ - if (!re->test_break(re->tbh)) { - int tothalo; - - tothalo= re->tothalo; - sort_halos(re, tothalo); - - init_camera_inside_volumes(re); - - re->i.infostr = IFACE_("Creating Shadowbuffers"); - re->stats_draw(re->sdh, &re->i); - - /* SHADOW BUFFER */ - threaded_makeshadowbufs(re); - - /* old code checked for internal render (aka not yafray) */ - { - /* raytree */ - if (!re->test_break(re->tbh)) { - if (re->r.mode & R_RAYTRACE) { - makeraytree(re); - } - } - /* ENVIRONMENT MAPS */ - if (!re->test_break(re->tbh)) - make_envmaps(re); - - /* point density texture */ - if (!re->test_break(re->tbh)) - make_pointdensities(depsgraph, re); - /* voxel data texture */ - if (!re->test_break(re->tbh)) - make_voxeldata(re); - } - - if (!re->test_break(re->tbh)) - project_renderdata(re, projectverto, (re->r.mode & R_PANORAMA) != 0, 0, 1); - - /* Occlusion */ - if ((re->wrld.mode & (WO_AMB_OCC|WO_ENV_LIGHT|WO_INDIRECT_LIGHT)) && !re->test_break(re->tbh)) - if (re->wrld.ao_gather_method == WO_AOGATHER_APPROX) - if (re->r.mode & R_SHADOW) - make_occ_tree(re); - - /* SSS */ - if ((re->r.mode & R_SSS) && !re->test_break(re->tbh)) - make_sss_tree(re); - - if (!re->test_break(re->tbh)) - if (re->r.mode & R_RAYTRACE) - volume_precache(re); - } - - re->i.convertdone = true; - - if (re->test_break(re->tbh)) - RE_Database_Free(re); - - re->i.infostr = NULL; - re->stats_draw(re->sdh, &re->i); -} - -/* exported call to recalculate hoco for vertices, when winmat changed */ -void RE_DataBase_ApplyWindow(Render *re) -{ - project_renderdata(re, projectverto, 0, 0, 0); -} - -/* exported call to rotate render data again, when viewmat changed */ -void RE_DataBase_IncrementalView(Render *re, float viewmat[4][4], int restore) -{ - float oldviewinv[4][4], tmat[4][4]; - - invert_m4_m4(oldviewinv, re->viewmat_orig); - - /* we have to correct for the already rotated vertexcoords */ - mul_m4_m4m4(tmat, viewmat, oldviewinv); - - copy_m4_m4(re->viewmat, viewmat); - invert_m4_m4(re->viewinv, re->viewmat); - - init_camera_inside_volumes(re); - - env_rotate_scene(re, tmat, !restore); - - /* SSS points distribution depends on view */ - if ((re->r.mode & R_SSS) && !re->test_break(re->tbh)) - make_sss_tree(re); -} - - -void RE_DataBase_GetView(Render *re, float mat[4][4]) -{ - copy_m4_m4(mat, re->viewmat); -} - -/* ------------------------------------------------------------------------- */ -/* Speed Vectors */ -/* ------------------------------------------------------------------------- */ - -static void database_fromscene_vectors(Depsgraph *depsgraph, - Render *re, - Scene *scene, - unsigned int lay, - int timeoffset) -{ - Object *camera= RE_GetCamera(re); - float mat[4][4]; - - re->scene= scene; - re->lay= lay; - - /* XXX add test if dbase was filled already? */ - - re->memArena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "vector render db arena"); - re->totvlak=re->totvert=re->totstrand=re->totlamp=re->tothalo= 0; - re->i.totface=re->i.totvert=re->i.totstrand=re->i.totlamp=re->i.tothalo= 0; - re->lights.first= re->lights.last= NULL; - - /* applies changes fully */ - scene->r.cfra += timeoffset; - BKE_scene_graph_update_for_newframe(depsgraph, re->main); - - /* if no camera, viewmat should have been set! */ - if (camera) { - RE_GetCameraModelMatrix(re, camera, mat); - normalize_m4(mat); - invert_m4(mat); - RE_SetView(re, mat); - } - - /* MAKE RENDER DATA */ - database_init_objects(depsgraph, re, lay, 0, 0, NULL, timeoffset); - - if (!re->test_break(re->tbh)) - project_renderdata(re, projectverto, (re->r.mode & R_PANORAMA) != 0, 0, 1); - - /* do this in end, particles for example need cfra */ - scene->r.cfra -= timeoffset; -} - -/* choose to use static, to prevent giving too many args to this call */ -static void speedvector_project(Render *re, float zco[2], const float co[3], const float ho[4]) -{ - static float pixelphix=0.0f, pixelphiy=0.0f, zmulx=0.0f, zmuly=0.0f; - static int pano= 0; - float div; - - /* initialize */ - if (re) { - pano= re->r.mode & R_PANORAMA; - - /* precalculate amount of radians 1 pixel rotates */ - if (pano) { - /* size of 1 pixel mapped to viewplane coords */ - float psize; - - psize = BLI_rctf_size_x(&re->viewplane) / (float)re->winx; - /* x angle of a pixel */ - pixelphix = atan(psize / re->clipsta); - - psize = BLI_rctf_size_y(&re->viewplane) / (float)re->winy; - /* y angle of a pixel */ - pixelphiy = atan(psize / re->clipsta); - } - zmulx= re->winx/2; - zmuly= re->winy/2; - - return; - } - - /* now map hocos to screenspace, uses very primitive clip still */ - if (ho[3]<0.1f) div= 10.0f; - else div= 1.0f/ho[3]; - - /* use cylinder projection */ - if (pano) { - float vec[3], ang; - /* angle between (0, 0, -1) and (co) */ - copy_v3_v3(vec, co); - - ang= saacos(-vec[2]/sqrtf(vec[0]*vec[0] + vec[2]*vec[2])); - if (vec[0]<0.0f) ang= -ang; - zco[0]= ang/pixelphix + zmulx; - - ang= 0.5f*(float)M_PI - saacos(vec[1] / len_v3(vec)); - zco[1]= ang/pixelphiy + zmuly; - - } - else { - zco[0]= zmulx*(1.0f+ho[0]*div); - zco[1]= zmuly*(1.0f+ho[1]*div); - } -} - -static void calculate_speedvector(const float vectors[2], int step, float winsq, float winroot, const float co[3], const float ho[4], float speed[4]) -{ - float zco[2], len; - - speedvector_project(NULL, zco, co, ho); - - zco[0]= vectors[0] - zco[0]; - zco[1]= vectors[1] - zco[1]; - - /* enable nice masks for hardly moving stuff or float inaccuracy */ - if (zco[0]<0.1f && zco[0]>-0.1f && zco[1]<0.1f && zco[1]>-0.1f ) { - zco[0]= 0.0f; - zco[1]= 0.0f; - } - - /* maximize speed for image width, otherwise it never looks good */ - len= zco[0]*zco[0] + zco[1]*zco[1]; - if (len > winsq) { - len= winroot/sqrtf(len); - zco[0]*= len; - zco[1]*= len; - } - - /* note; in main vecblur loop speedvec is negated again */ - if (step) { - speed[2]= -zco[0]; - speed[3]= -zco[1]; - } - else { - speed[0]= zco[0]; - speed[1]= zco[1]; - } -} - -static float *calculate_strandsurface_speedvectors(Render *re, ObjectInstanceRen *obi, StrandSurface *mesh) -{ - if (mesh->co && mesh->prevco && mesh->nextco) { - float winsq= (float)re->winx*(float)re->winy; /* int's can wrap on large images */ - float winroot= sqrtf(winsq); - float (*winspeed)[4]; - float ho[4], prevho[4], nextho[4], winmat[4][4], vec[2]; - int a; - - if (obi->flag & R_TRANSFORMED) - mul_m4_m4m4(winmat, re->winmat, obi->mat); - else - copy_m4_m4(winmat, re->winmat); - - winspeed= MEM_callocN(sizeof(float)*4*mesh->totvert, "StrandSurfWin"); - - for (a=0; a<mesh->totvert; a++) { - projectvert(mesh->co[a], winmat, ho); - - projectvert(mesh->prevco[a], winmat, prevho); - speedvector_project(NULL, vec, mesh->prevco[a], prevho); - calculate_speedvector(vec, 0, winsq, winroot, mesh->co[a], ho, winspeed[a]); - - projectvert(mesh->nextco[a], winmat, nextho); - speedvector_project(NULL, vec, mesh->nextco[a], nextho); - calculate_speedvector(vec, 1, winsq, winroot, mesh->co[a], ho, winspeed[a]); - } - - return (float *)winspeed; - } - - return NULL; -} - -static void calculate_speedvectors(Render *re, ObjectInstanceRen *obi, float *vectors, int step) -{ - ObjectRen *obr= obi->obr; - VertRen *ver= NULL; - StrandRen *strand= NULL; - StrandBuffer *strandbuf; - StrandSurface *mesh= NULL; - float *speed, (*winspeed)[4]=NULL, ho[4], winmat[4][4]; - float *co1, *co2, *co3, *co4, w[4]; - float winsq = (float)re->winx * (float)re->winy, winroot = sqrtf(winsq); /* int's can wrap on large images */ - int a, *face, *index; - - if (obi->flag & R_TRANSFORMED) - mul_m4_m4m4(winmat, re->winmat, obi->mat); - else - copy_m4_m4(winmat, re->winmat); - - if (obr->vertnodes) { - for (a=0; a<obr->totvert; a++, vectors+=2) { - if ((a & 255)==0) ver= obr->vertnodes[a>>8].vert; - else ver++; - - speed= RE_vertren_get_winspeed(obi, ver, 1); - projectvert(ver->co, winmat, ho); - calculate_speedvector(vectors, step, winsq, winroot, ver->co, ho, speed); - } - } - - if (obr->strandnodes) { - strandbuf= obr->strandbuf; - mesh= (strandbuf)? strandbuf->surface: NULL; - - /* compute speed vectors at surface vertices */ - if (mesh) - winspeed= (float(*)[4])calculate_strandsurface_speedvectors(re, obi, mesh); - - if (winspeed) { - for (a=0; a<obr->totstrand; a++, vectors+=2) { - if ((a & 255)==0) strand= obr->strandnodes[a>>8].strand; - else strand++; - - index= RE_strandren_get_face(obr, strand, 0); - if (index && *index < mesh->totface) { - speed= RE_strandren_get_winspeed(obi, strand, 1); - - /* interpolate speed vectors from strand surface */ - face= mesh->face[*index]; - - co1 = mesh->co[face[0]]; - co2 = mesh->co[face[1]]; - co3 = mesh->co[face[2]]; - - if (face[3]) { - co4 = mesh->co[face[3]]; - interp_weights_quad_v3(w, co1, co2, co3, co4, strand->vert->co); - } - else { - interp_weights_tri_v3(w, co1, co2, co3, strand->vert->co); - } - - zero_v4(speed); - madd_v4_v4fl(speed, winspeed[face[0]], w[0]); - madd_v4_v4fl(speed, winspeed[face[1]], w[1]); - madd_v4_v4fl(speed, winspeed[face[2]], w[2]); - if (face[3]) - madd_v4_v4fl(speed, winspeed[face[3]], w[3]); - } - } - - MEM_freeN(winspeed); - } - } -} - -static int load_fluidsimspeedvectors(Render *re, ObjectInstanceRen *obi, float *vectors, int step) -{ - ObjectRen *obr= obi->obr; - Object *fsob= obr->ob; - VertRen *ver= NULL; - float *speed, div, zco[2], avgvel[4] = {0.0, 0.0, 0.0, 0.0}; - float zmulx= re->winx/2, zmuly= re->winy/2, len; - float winsq = (float)re->winx * (float)re->winy, winroot= sqrtf(winsq); /* int's can wrap on large images */ - int a, j; - float hoco[4], ho[4], fsvec[4], camco[4]; - float mat[4][4], winmat[4][4]; - float imat[4][4]; - FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(fsob, eModifierType_Fluidsim); - FluidsimSettings *fss; - FluidVertexVelocity *velarray = NULL; - - /* only one step needed */ - if (step) return 1; - - if (fluidmd) - fss = fluidmd->fss; - else - return 0; - - copy_m4_m4(mat, re->viewmat); - invert_m4_m4(imat, mat); - - /* set first vertex OK */ - if (!fss->meshVelocities) return 0; - - if ( obr->totvert != fss->totvert) { - //fprintf(stderr, "load_fluidsimspeedvectors - modified fluidsim mesh, not using speed vectors (%d,%d)...\n", obr->totvert, fsob->fluidsimSettings->meshSurface->totvert); // DEBUG - return 0; - } - - velarray = fss->meshVelocities; - - if (obi->flag & R_TRANSFORMED) - mul_m4_m4m4(winmat, re->winmat, obi->mat); - else - copy_m4_m4(winmat, re->winmat); - - /* (bad) HACK calculate average velocity */ - /* better solution would be fixing getVelocityAt() in intern/elbeem/intern/solver_util.cpp - * so that also small drops/little water volumes return a velocity != 0. - * But I had no luck in fixing that function - DG */ - for (a=0; a<obr->totvert; a++) { - for (j=0;j<3;j++) avgvel[j] += velarray[a].vel[j]; - - } - for (j=0;j<3;j++) avgvel[j] /= (float)(obr->totvert); - - - for (a=0; a<obr->totvert; a++, vectors+=2) { - if ((a & 255)==0) - ver= obr->vertnodes[a>>8].vert; - else - ver++; - - /* get fluid velocity */ - fsvec[3] = 0.0f; - //fsvec[0] = fsvec[1] = fsvec[2] = fsvec[3] = 0.0; fsvec[2] = 2.0f; // NT fixed test - for (j=0;j<3;j++) fsvec[j] = velarray[a].vel[j]; - - /* (bad) HACK insert average velocity if none is there (see previous comment) */ - if ((fsvec[0] == 0.0f) && (fsvec[1] == 0.0f) && (fsvec[2] == 0.0f)) { - fsvec[0] = avgvel[0]; - fsvec[1] = avgvel[1]; - fsvec[2] = avgvel[2]; - } - - /* transform (=rotate) to cam space */ - camco[0] = dot_v3v3(imat[0], fsvec); - camco[1] = dot_v3v3(imat[1], fsvec); - camco[2] = dot_v3v3(imat[2], fsvec); - - /* get homogeneous coordinates */ - projectvert(camco, winmat, hoco); - projectvert(ver->co, winmat, ho); - - /* now map hocos to screenspace, uses very primitive clip still */ - /* use ho[3] of original vertex, xy component of vel. direction */ - if (ho[3]<0.1f) div= 10.0f; - else div= 1.0f/ho[3]; - zco[0]= zmulx*hoco[0]*div; - zco[1]= zmuly*hoco[1]*div; - - /* maximize speed as usual */ - len= zco[0]*zco[0] + zco[1]*zco[1]; - if (len > winsq) { - len= winroot/sqrtf(len); - zco[0]*= len; zco[1]*= len; - } - - speed= RE_vertren_get_winspeed(obi, ver, 1); - /* set both to the same value */ - speed[0]= speed[2]= zco[0]; - speed[1]= speed[3]= zco[1]; - //if (a < 20) fprintf(stderr,"speed %d %f,%f | camco %f,%f,%f | hoco %f,%f,%f,%f\n", a, speed[0], speed[1], camco[0],camco[1], camco[2], hoco[0],hoco[1], hoco[2],hoco[3]); // NT DEBUG - } - - return 1; -} - -/* makes copy per object of all vectors */ -/* result should be that we can free entire database */ -static void copy_dbase_object_vectors(Render *re, ListBase *lb) -{ - ObjectInstanceRen *obi, *obilb; - ObjectRen *obr; - VertRen *ver= NULL; - float *vec, ho[4], winmat[4][4]; - int a, totvector; - - for (obi= re->instancetable.first; obi; obi= obi->next) { - obr= obi->obr; - - obilb= MEM_mallocN(sizeof(ObjectInstanceRen), "ObInstanceVector"); - memcpy(obilb, obi, sizeof(ObjectInstanceRen)); - BLI_addtail(lb, obilb); - - obilb->totvector= totvector= obr->totvert; - - if (totvector > 0) { - vec= obilb->vectors= MEM_mallocN(2*sizeof(float)*totvector, "vector array"); - - if (obi->flag & R_TRANSFORMED) - mul_m4_m4m4(winmat, re->winmat, obi->mat); - else - copy_m4_m4(winmat, re->winmat); - - for (a=0; a<obr->totvert; a++, vec+=2) { - if ((a & 255)==0) ver= obr->vertnodes[a>>8].vert; - else ver++; - - projectvert(ver->co, winmat, ho); - speedvector_project(NULL, vec, ver->co, ho); - } - } - } -} - -static void free_dbase_object_vectors(ListBase *lb) -{ - ObjectInstanceRen *obi; - - for (obi= lb->first; obi; obi= obi->next) - if (obi->vectors) - MEM_freeN(obi->vectors); - BLI_freelistN(lb); -} - -void RE_Database_FromScene_Vectors(Depsgraph *depsgraph, Render *re, Main *bmain, Scene *sce, unsigned int lay) -{ - ObjectInstanceRen *obi, *oldobi; - StrandSurface *mesh; - ListBase *table; - ListBase oldtable= {NULL, NULL}, newtable= {NULL, NULL}; - ListBase strandsurface; - int step; - - re->i.infostr = IFACE_("Calculating previous frame vectors"); - re->r.mode |= R_SPEED; - - speedvector_project(re, NULL, NULL, NULL); /* initializes projection code */ - - /* creates entire dbase */ - database_fromscene_vectors(depsgraph, re, sce, lay, -1); - - /* copy away vertex info */ - copy_dbase_object_vectors(re, &oldtable); - - /* free dbase and make the future one */ - strandsurface= re->strandsurface; - memset(&re->strandsurface, 0, sizeof(ListBase)); - re->i.convertdone = true; - RE_Database_Free(re); - re->strandsurface= strandsurface; - - if (!re->test_break(re->tbh)) { - /* creates entire dbase */ - re->i.infostr = IFACE_("Calculating next frame vectors"); - - database_fromscene_vectors(depsgraph, re, sce, lay, +1); - } - /* copy away vertex info */ - copy_dbase_object_vectors(re, &newtable); - - /* free dbase and make the real one */ - strandsurface= re->strandsurface; - memset(&re->strandsurface, 0, sizeof(ListBase)); - re->i.convertdone = true; - RE_Database_Free(re); - re->strandsurface= strandsurface; - - if (!re->test_break(re->tbh)) { - RE_Database_FromScene(re, bmain, sce, lay, 1); - RE_Database_Preprocess(depsgraph, re); - } - - if (!re->test_break(re->tbh)) { - int vectorlay= get_vector_viewlayers(re->scene); - - for (step= 0; step<2; step++) { - - if (step) - table= &newtable; - else - table= &oldtable; - - oldobi= table->first; - for (obi= re->instancetable.first; obi && oldobi; obi= obi->next) { - int ok= 1; - FluidsimModifierData *fluidmd; - - if (!(obi->lay & vectorlay)) - continue; - - obi->totvector= obi->obr->totvert; - - /* find matching object in old table */ - if (oldobi->ob!=obi->ob || oldobi->par!=obi->par || oldobi->index!=obi->index || oldobi->psysindex!=obi->psysindex) { - ok= 0; - for (oldobi= table->first; oldobi; oldobi= oldobi->next) - if (oldobi->ob==obi->ob && oldobi->par==obi->par && oldobi->index==obi->index && oldobi->psysindex==obi->psysindex) - break; - if (oldobi==NULL) - oldobi= table->first; - else - ok= 1; - } - if (ok==0) { - printf("speed table: missing object %s\n", obi->ob->id.name + 2); - continue; - } - - /* NT check for fluidsim special treatment */ - fluidmd = (FluidsimModifierData *)modifiers_findByType(obi->ob, eModifierType_Fluidsim); - if (fluidmd && fluidmd->fss && (fluidmd->fss->type & OB_FLUIDSIM_DOMAIN)) { - /* use preloaded per vertex simulation data, only does calculation for step=1 */ - /* NOTE/FIXME - velocities and meshes loaded unnecessarily often during the database_fromscene_vectors calls... */ - load_fluidsimspeedvectors(re, obi, oldobi->vectors, step); - } - else { - /* check if both have same amounts of vertices */ - if (obi->totvector==oldobi->totvector) - calculate_speedvectors(re, obi, oldobi->vectors, step); - else - printf("Warning: object %s has different amount of vertices or strands on other frame\n", obi->ob->id.name + 2); - } /* not fluidsim */ - - oldobi= oldobi->next; - } - } - } - - free_dbase_object_vectors(&oldtable); - free_dbase_object_vectors(&newtable); - - for (mesh=re->strandsurface.first; mesh; mesh=mesh->next) { - if (mesh->prevco) { - MEM_freeN(mesh->prevco); - mesh->prevco= NULL; - } - if (mesh->nextco) { - MEM_freeN(mesh->nextco); - mesh->nextco= NULL; - } - } - - re->i.infostr = NULL; - re->stats_draw(re->sdh, &re->i); -} - - -/* ------------------------------------------------------------------------- */ -/* Baking */ -/* ------------------------------------------------------------------------- */ - -/* setup for shaded view or bake, so only lamps and materials are initialized */ -/* type: - * RE_BAKE_LIGHT: for shaded view, only add lamps - * RE_BAKE_ALL: for baking, all lamps and objects - * RE_BAKE_NORMALS:for baking, no lamps and only selected objects - * RE_BAKE_AO: for baking, no lamps, but all objects - * RE_BAKE_TEXTURE:for baking, no lamps, only selected objects - * RE_BAKE_VERTEX_COLORS:for baking, no lamps, only selected objects - * RE_BAKE_DISPLACEMENT:for baking, no lamps, only selected objects - * RE_BAKE_DERIVATIVE:for baking, no lamps, only selected objects - * RE_BAKE_SHADOW: for baking, only shadows, but all objects - */ -void RE_Database_Baking(Render *re, Main *bmain, Scene *scene, ViewLayer *view_layer, - unsigned int lay, const int type, Object *actob) -{ - Object *camera; - float mat[4][4]; - float amb[3]; - const short onlyselected= !ELEM(type, RE_BAKE_LIGHT, RE_BAKE_ALL, RE_BAKE_SHADOW, RE_BAKE_AO, RE_BAKE_VERTEX_COLORS); - const short nolamps= ELEM(type, RE_BAKE_NORMALS, RE_BAKE_TEXTURE, RE_BAKE_DISPLACEMENT, RE_BAKE_DERIVATIVE, RE_BAKE_VERTEX_COLORS); - - re->main= bmain; - re->scene= scene; - re->lay= lay; - - /* renderdata setup and exceptions */ - render_copy_renderdata(&re->r, &scene->r); - - RE_init_threadcount(re); - - Depsgraph *depsgraph = DEG_graph_new(scene, view_layer, DAG_EVAL_RENDER); - DEG_graph_build_from_view_layer(depsgraph, bmain, scene, view_layer); - BKE_scene_graph_update_tagged(depsgraph, bmain); - - re->flag |= R_BAKING; - re->excludeob= actob; - if (actob) - re->flag |= R_BAKE_TRACE; - - if (type==RE_BAKE_NORMALS && re->r.bake_normal_space==R_BAKE_SPACE_TANGENT) - re->flag |= R_NEED_TANGENT; - - if (type==RE_BAKE_VERTEX_COLORS) - re->flag |= R_NEED_VCOL; - - if (!actob && ELEM(type, RE_BAKE_LIGHT, RE_BAKE_NORMALS, RE_BAKE_TEXTURE, RE_BAKE_DISPLACEMENT, RE_BAKE_DERIVATIVE, RE_BAKE_VERTEX_COLORS)) { - re->r.mode &= ~R_SHADOW; - re->r.mode &= ~R_RAYTRACE; - } - - if (!actob && (type==RE_BAKE_SHADOW)) { - re->r.mode |= R_SHADOW; - } - - /* setup render stuff */ - re->memArena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "bake db arena"); - - re->totvlak=re->totvert=re->totstrand=re->totlamp=re->tothalo= 0; - re->lights.first= re->lights.last= NULL; - re->lampren.first= re->lampren.last= NULL; - - /* in localview, lamps are using normal layers, objects only local bits */ - if (re->lay & 0xFF000000) - lay &= 0xFF000000; - - camera= RE_GetCamera(re); - - /* if no camera, set unit */ - if (camera) { - normalize_m4_m4(mat, camera->obmat); - invert_m4(mat); - RE_SetView(re, mat); - } - else { - unit_m4(mat); - RE_SetView(re, mat); - } - copy_m3_m4(re->imat, re->viewinv); - - /* TODO: deep shadow maps + baking + strands */ - /* strands use the window matrix and view size, there is to correct - * window matrix but at least avoids malloc and crash loop [#27807] */ - unit_m4(re->winmat); - re->winx= re->winy= 256; - /* done setting dummy values */ - - init_render_world(re); /* do first, because of ambient. also requires re->osa set correct */ - if (re->r.mode & R_RAYTRACE) { - init_render_qmcsampler(re); - - if (re->wrld.mode & (WO_AMB_OCC|WO_ENV_LIGHT|WO_INDIRECT_LIGHT)) - if (re->wrld.ao_samp_method == WO_AOSAMP_CONSTANT) - init_ao_sphere(re, &re->wrld); - } - - /* still bad... doing all */ - init_render_textures(re); - - copy_v3_v3(amb, &re->wrld.ambr); - init_render_materials(re->main, re->r.mode, amb, true); - - set_node_shader_lamp_loop(shade_material_loop); - - /* MAKE RENDER DATA */ - database_init_objects(depsgraph, re, lay, nolamps, onlyselected, actob, 0); - - set_material_lightgroups(re); - - /* SHADOW BUFFER */ - if (type!=RE_BAKE_LIGHT) - if (re->r.mode & R_SHADOW) - threaded_makeshadowbufs(re); - - /* raytree */ - if (!re->test_break(re->tbh)) - if (re->r.mode & R_RAYTRACE) - makeraytree(re); - - /* point density texture */ - if (!re->test_break(re->tbh)) - make_pointdensities(depsgraph, re); - - /* voxel data texture */ - if (!re->test_break(re->tbh)) - make_voxeldata(re); - - /* occlusion */ - if ((re->wrld.mode & (WO_AMB_OCC|WO_ENV_LIGHT|WO_INDIRECT_LIGHT)) && !re->test_break(re->tbh)) - if (re->wrld.ao_gather_method == WO_AOGATHER_APPROX) - if (re->r.mode & R_SHADOW) - make_occ_tree(re); - - re->i.convertdone = true; -} diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c deleted file mode 100644 index a5f914b5ca1..00000000000 --- a/source/blender/render/intern/source/envmap.c +++ /dev/null @@ -1,819 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * Contributors: 2004/2005/2006 Blender Foundation, full recode - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/render/intern/source/envmap.c - * \ingroup render - */ - -#include <math.h> -#include <string.h> - -/* external modules: */ - -#include "BLI_math.h" -#include "BLI_blenlib.h" -#include "BLI_threads.h" -#include "BLI_utildefines.h" - -#include "BLT_translation.h" - -#include "IMB_imbuf_types.h" -#include "IMB_imbuf.h" /* for rectcpy */ - -#include "DNA_group_types.h" -#include "DNA_image_types.h" -#include "DNA_lamp_types.h" -#include "DNA_object_types.h" -#include "DNA_scene_types.h" -#include "DNA_texture_types.h" - -#include "BKE_main.h" -#include "BKE_image.h" /* BKE_imbuf_write */ -#include "BKE_layer.h" -#include "BKE_texture.h" -#include "BKE_scene.h" - -/* this module */ -#include "render_types.h" -#include "envmap.h" -#include "renderdatabase.h" -#include "renderpipeline.h" -#include "texture.h" -#include "zbuf.h" -#include "render_result.h" - -/* ------------------------------------------------------------------------- */ - -static void envmap_split_ima(EnvMap *env, ImBuf *ibuf) -{ - int dx, part; - - /* after lock we test cube[1], if set the other thread has done it fine */ - BLI_thread_lock(LOCK_IMAGE); - if (env->cube[1] == NULL) { - - BKE_texture_envmap_free_data(env); - - dx = ibuf->y; - dx /= 2; - if (3 * dx == ibuf->x) { - env->type = ENV_CUBE; - env->ok = ENV_OSA; - } - else if (ibuf->x == ibuf->y) { - env->type = ENV_PLANE; - env->ok = ENV_OSA; - } - else { - printf("Incorrect envmap size\n"); - env->ok = 0; - env->ima->ok = 0; - } - - if (env->ok) { - if (env->type == ENV_CUBE) { - for (part = 0; part < 6; part++) { - env->cube[part] = IMB_allocImBuf(dx, dx, 24, IB_rect | IB_rectfloat); - } - IMB_float_from_rect(ibuf); - - IMB_rectcpy(env->cube[0], ibuf, - 0, 0, 0, 0, dx, dx); - IMB_rectcpy(env->cube[1], ibuf, - 0, 0, dx, 0, dx, dx); - IMB_rectcpy(env->cube[2], ibuf, - 0, 0, 2 * dx, 0, dx, dx); - IMB_rectcpy(env->cube[3], ibuf, - 0, 0, 0, dx, dx, dx); - IMB_rectcpy(env->cube[4], ibuf, - 0, 0, dx, dx, dx, dx); - IMB_rectcpy(env->cube[5], ibuf, - 0, 0, 2 * dx, dx, dx, dx); - - } - else { /* ENV_PLANE */ - env->cube[1] = IMB_dupImBuf(ibuf); - IMB_float_from_rect(env->cube[1]); - } - } - } - BLI_thread_unlock(LOCK_IMAGE); -} - -/* ------------------------------------------------------------------------- */ -/* ****************** RENDER ********************** */ - -/* copy current render */ -static Render *envmap_render_copy(Render *re, EnvMap *env) -{ - Render *envre; - float viewscale; - int cuberes; - - envre = RE_NewRender("Envmap"); - - env->lastsize = re->r.size; - cuberes = (env->cuberes * re->r.size) / 100; - cuberes &= 0xFFFC; - - /* this flag has R_ZTRA in it for example */ - envre->flag = re->flag; - - /* set up renderdata */ - envre->r.mode &= ~(R_BORDER | R_PANORAMA | R_ORTHO | R_MBLUR); - BLI_freelistN(&envre->view_layers); - BLI_freelistN(&envre->r.views); - envre->r.filtertype = 0; - envre->r.tilex = envre->r.xsch / 2; - envre->r.tiley = envre->r.ysch / 2; - envre->r.size = 100; - envre->r.yasp = envre->r.xasp = 1; - - RE_InitState(envre, NULL, &envre->r, &re->view_layers, re->active_view_layer, NULL, cuberes, cuberes, NULL); - envre->main = re->main; - envre->scene = re->scene; /* unsure about this... */ - envre->scene_color_manage = re->scene_color_manage; - envre->lay = re->lay; - - /* view stuff in env render */ - viewscale = (env->type == ENV_PLANE) ? env->viewscale : 1.0f; - RE_SetEnvmapCamera(envre, env->object, viewscale, env->clipsta, env->clipend); - copy_m4_m4(envre->viewmat_orig, re->viewmat_orig); - - /* callbacks */ - envre->display_update = re->display_update; - envre->duh = re->duh; - envre->test_break = re->test_break; - envre->tbh = re->tbh; - envre->current_scene_update = re->current_scene_update; - envre->suh = re->suh; - - /* and for the evil stuff; copy the database... */ - envre->totvlak = re->totvlak; - envre->totvert = re->totvert; - envre->tothalo = re->tothalo; - envre->totstrand = re->totstrand; - envre->totlamp = re->totlamp; - envre->sortedhalos = re->sortedhalos; - envre->lights = re->lights; - envre->objecttable = re->objecttable; - envre->customdata_names = re->customdata_names; - envre->raytree = re->raytree; - envre->totinstance = re->totinstance; - envre->instancetable = re->instancetable; - envre->objectinstance = re->objectinstance; - envre->qmcsamplers = re->qmcsamplers; - - return envre; -} - -static void envmap_free_render_copy(Render *envre) -{ - - envre->totvlak = 0; - envre->totvert = 0; - envre->tothalo = 0; - envre->totstrand = 0; - envre->totlamp = 0; - envre->totinstance = 0; - envre->sortedhalos = NULL; - BLI_listbase_clear(&envre->lights); - BLI_listbase_clear(&envre->objecttable); - BLI_listbase_clear(&envre->customdata_names); - envre->raytree = NULL; - BLI_listbase_clear(&envre->instancetable); - envre->objectinstance = NULL; - envre->qmcsamplers = NULL; - - RE_FreeRender(envre); -} - -/* ------------------------------------------------------------------------- */ - -static void envmap_transmatrix(float mat[4][4], int part) -{ - float tmat[4][4], eul[3], rotmat[4][4]; - - eul[0] = eul[1] = eul[2] = 0.0; - - if (part == 0) { /* neg z */ - /* pass */ - } - else if (part == 1) { /* pos z */ - eul[0] = M_PI; - } - else if (part == 2) { /* pos y */ - eul[0] = M_PI / 2.0; - } - else if (part == 3) { /* neg x */ - eul[0] = M_PI / 2.0; - eul[2] = M_PI / 2.0; - } - else if (part == 4) { /* neg y */ - eul[0] = M_PI / 2.0; - eul[2] = M_PI; - } - else { /* pos x */ - eul[0] = M_PI / 2.0; - eul[2] = -M_PI / 2.0; - } - - copy_m4_m4(tmat, mat); - eul_to_mat4(rotmat, eul); - mul_m4_m4m4(mat, tmat, rotmat); -} -/* ------------------------------------------------------------------------- */ - -static void env_set_imats(Render *re) -{ - float mat[4][4]; - - FOREACH_SCENE_OBJECT_BEGIN(re->scene, ob) - { - mul_m4_m4m4(mat, re->viewmat, ob->obmat); - invert_m4_m4(ob->imat, mat); - } - FOREACH_SCENE_OBJECT_END; -} - -/* ------------------------------------------------------------------------- */ - -void env_rotate_scene(Render *re, float mat[4][4], int do_rotate) -{ - ObjectRen *obr; - ObjectInstanceRen *obi; - LampRen *lar = NULL; - HaloRen *har = NULL; - float imat[3][3], mat_inverse[4][4], smat[4][4], tmat[4][4], cmat[3][3], tmpmat[4][4]; - int a; - - if (do_rotate == 0) { - invert_m4_m4(tmat, mat); - copy_m3_m4(imat, tmat); - - copy_m4_m4(mat_inverse, mat); - } - else { - copy_m4_m4(tmat, mat); - copy_m3_m4(imat, mat); - - invert_m4_m4(mat_inverse, tmat); - } - - for (obi = re->instancetable.first; obi; obi = obi->next) { - /* append or set matrix depending on dupli */ - if (obi->flag & R_DUPLI_TRANSFORMED) { - copy_m4_m4(tmpmat, obi->mat); - mul_m4_m4m4(obi->mat, tmat, tmpmat); - } - else if (do_rotate == 1) - copy_m4_m4(obi->mat, tmat); - else - unit_m4(obi->mat); - - copy_m3_m4(cmat, obi->mat); - invert_m3_m3(obi->nmat, cmat); - transpose_m3(obi->nmat); - - /* indicate the renderer has to use transform matrices */ - if (do_rotate == 0) - obi->flag &= ~R_ENV_TRANSFORMED; - else { - obi->flag |= R_ENV_TRANSFORMED; - copy_m4_m4(obi->imat, mat_inverse); - } - } - - - for (obr = re->objecttable.first; obr; obr = obr->next) { - for (a = 0; a < obr->tothalo; a++) { - if ((a & 255) == 0) har = obr->bloha[a >> 8]; - else har++; - - mul_m4_v3(tmat, har->co); - } - - /* imat_ren is needed for correct texture coordinates */ - mul_m4_m4m4(obr->ob->imat_ren, re->viewmat, obr->ob->obmat); - invert_m4(obr->ob->imat_ren); - } - - for (lar = re->lampren.first; lar; lar = lar->next) { - float lamp_imat[4][4]; - - /* copy from add_render_lamp */ - if (do_rotate == 1) - mul_m4_m4m4(tmpmat, re->viewmat, lar->lampmat); - else - mul_m4_m4m4(tmpmat, re->viewmat_orig, lar->lampmat); - - invert_m4_m4(lamp_imat, tmpmat); - copy_m3_m4(lar->mat, tmpmat); - copy_m3_m4(lar->imat, lamp_imat); - - lar->vec[0]= -tmpmat[2][0]; - lar->vec[1]= -tmpmat[2][1]; - lar->vec[2]= -tmpmat[2][2]; - normalize_v3(lar->vec); - lar->co[0]= tmpmat[3][0]; - lar->co[1]= tmpmat[3][1]; - lar->co[2]= tmpmat[3][2]; - - if (lar->type == LA_AREA) { - area_lamp_vectors(lar); - } - else if (lar->type == LA_SPOT) { - normalize_v3(lar->imat[0]); - normalize_v3(lar->imat[1]); - normalize_v3(lar->imat[2]); - - lar->sh_invcampos[0] = -lar->co[0]; - lar->sh_invcampos[1] = -lar->co[1]; - lar->sh_invcampos[2] = -lar->co[2]; - mul_m3_v3(lar->imat, lar->sh_invcampos); - lar->sh_invcampos[2] *= lar->sh_zfac; - - if (lar->shb) { - if (do_rotate == 1) { - mul_m4_m4m4(smat, lar->shb->viewmat, mat_inverse); - mul_m4_m4m4(lar->shb->persmat, lar->shb->winmat, smat); - } - else mul_m4_m4m4(lar->shb->persmat, lar->shb->winmat, lar->shb->viewmat); - } - } - } - - if (do_rotate) { - init_render_world(re); - env_set_imats(re); - } -} - -/* ------------------------------------------------------------------------- */ - -static void env_layerflags(Render *re, unsigned int notlay) -{ - ObjectRen *obr; - VlakRen *vlr = NULL; - int a; - - /* invert notlay, so if face is in multiple layers it will still be visible, - * unless all 'notlay' bits match the face bits. - * face: 0110 - * not: 0100 - * ~not: 1011 - * now (face & ~not) is true - */ - - notlay = ~notlay; - - for (obr = re->objecttable.first; obr; obr = obr->next) { - if ((obr->lay & notlay) == 0) { - for (a = 0; a < obr->totvlak; a++) { - if ((a & 255) == 0) vlr = obr->vlaknodes[a >> 8].vlak; - else vlr++; - - vlr->flag |= R_HIDDEN; - } - } - } -} - -static void env_hideobject(Render *re, Object *ob) -{ - ObjectRen *obr; - VlakRen *vlr = NULL; - int a; - - for (obr = re->objecttable.first; obr; obr = obr->next) { - for (a = 0; a < obr->totvlak; a++) { - if ((a & 255) == 0) vlr = obr->vlaknodes[a >> 8].vlak; - else vlr++; - - if (obr->ob == ob) - vlr->flag |= R_HIDDEN; - } - } -} - -static void env_showobjects(Render *re) -{ - ObjectRen *obr; - VlakRen *vlr = NULL; - int a; - - for (obr = re->objecttable.first; obr; obr = obr->next) { - for (a = 0; a < obr->totvlak; a++) { - if ((a & 255) == 0) vlr = obr->vlaknodes[a >> 8].vlak; - else vlr++; - - vlr->flag &= ~R_HIDDEN; - } - } -} - -/* ------------------------------------------------------------------------- */ - -static void render_envmap(Render *re, EnvMap *env) -{ - /* only the cubemap and planar map is implemented */ - Render *envre; - ImBuf *ibuf; - float orthmat[4][4]; - float oldviewinv[4][4], mat[4][4], tmat[4][4]; - short part; - - /* need a recalc: ortho-render has no correct viewinv */ - invert_m4_m4(oldviewinv, re->viewmat); - - envre = envmap_render_copy(re, env); - - /* precalc orthmat for object */ - copy_m4_m4(orthmat, env->object->obmat); - normalize_m4(orthmat); - - /* need imat later for texture imat */ - mul_m4_m4m4(mat, re->viewmat, orthmat); - invert_m4_m4(tmat, mat); - copy_m3_m4(env->obimat, tmat); - - for (part = 0; part < 6; part++) { - if (env->type == ENV_PLANE && part != 1) - continue; - - re->display_clear(re->dch, envre->result); - - copy_m4_m4(tmat, orthmat); - envmap_transmatrix(tmat, part); - invert_m4_m4(mat, tmat); - /* mat now is the camera 'viewmat' */ - - copy_m4_m4(envre->viewmat, mat); - copy_m4_m4(envre->viewinv, tmat); - - /* we have to correct for the already rotated vertexcoords */ - mul_m4_m4m4(tmat, envre->viewmat, oldviewinv); - invert_m4_m4(env->imat, tmat); - - env_rotate_scene(envre, tmat, 1); - project_renderdata(envre, projectverto, 0, 0, 1); - env_layerflags(envre, env->notlay); - env_hideobject(envre, env->object); - - if (re->test_break(re->tbh) == 0) { - RE_TileProcessor(envre); - } - - /* rotate back */ - env_showobjects(envre); - env_rotate_scene(envre, tmat, 0); - - if (re->test_break(re->tbh) == 0) { - int y; - float *alpha; - float *rect; - - if (envre->result->do_exr_tile) { - BLI_rw_mutex_lock(&envre->resultmutex, THREAD_LOCK_WRITE); - render_result_exr_file_end(envre); - BLI_rw_mutex_unlock(&envre->resultmutex); - } - - RenderLayer *rl = envre->result->layers.first; - - /* envmap is rendered independently of multiview */ - rect = RE_RenderLayerGetPass(rl, RE_PASSNAME_COMBINED, ""); - ibuf = IMB_allocImBuf(envre->rectx, envre->recty, 24, IB_rect | IB_rectfloat); - memcpy(ibuf->rect_float, rect, ibuf->channels * ibuf->x * ibuf->y * sizeof(float)); - - /* envmap renders without alpha */ - alpha = ibuf->rect_float + 3; - for (y = ibuf->x * ibuf->y - 1; y >= 0; y--, alpha += 4) - *alpha = 1.0; - - env->cube[part] = ibuf; - } - - if (re->test_break(re->tbh)) break; - - } - - if (re->test_break(re->tbh)) BKE_texture_envmap_free_data(env); - else { - if (envre->r.mode & R_OSA) env->ok = ENV_OSA; - else env->ok = ENV_NORMAL; - env->lastframe = re->scene->r.cfra; - } - - /* restore */ - envmap_free_render_copy(envre); - env_set_imats(re); - -} - -/* ------------------------------------------------------------------------- */ - -void make_envmaps(Render *re) -{ - Tex *tex; - bool do_init = false; - int depth = 0, trace; - - if (!(re->r.mode & R_ENVMAP)) return; - - /* we don't raytrace, disabling the flag will cause ray_transp render solid */ - trace = (re->r.mode & R_RAYTRACE); - re->r.mode &= ~R_RAYTRACE; - - re->i.infostr = IFACE_("Creating Environment maps"); - re->stats_draw(re->sdh, &re->i); - - /* 5 = hardcoded max recursion level */ - while (depth < 5) { - tex = re->main->tex.first; - while (tex) { - if (tex->id.us && tex->type == TEX_ENVMAP) { - if (tex->env && tex->env->object) { - EnvMap *env = tex->env; - - if (env->object->lay & re->lay) { - if (env->stype == ENV_LOAD) { - float orthmat[4][4], mat[4][4], tmat[4][4]; - - /* precalc orthmat for object */ - copy_m4_m4(orthmat, env->object->obmat); - normalize_m4(orthmat); - - /* need imat later for texture imat */ - mul_m4_m4m4(mat, re->viewmat, orthmat); - invert_m4_m4(tmat, mat); - copy_m3_m4(env->obimat, tmat); - } - else { - - /* decide if to render an envmap (again) */ - if (env->depth >= depth) { - - /* set 'recalc' to make sure it does an entire loop of recalcs */ - - if (env->ok) { - /* free when OSA, and old one isn't OSA */ - if ((re->r.mode & R_OSA) && env->ok == ENV_NORMAL) - BKE_texture_envmap_free_data(env); - /* free when size larger */ - else if (env->lastsize < re->r.size) - BKE_texture_envmap_free_data(env); - /* free when env is in recalcmode */ - else if (env->recalc) - BKE_texture_envmap_free_data(env); - } - - if (env->ok == 0 && depth == 0) env->recalc = 1; - - if (env->ok == 0) { - do_init = true; - render_envmap(re, env); - - if (depth == env->depth) env->recalc = 0; - } - } - } - } - } - } - tex = tex->id.next; - } - depth++; - } - - if (do_init) { - re->display_init(re->dih, re->result); - re->display_clear(re->dch, re->result); - // re->flag |= R_REDRAW_PRV; - } - /* restore */ - re->r.mode |= trace; - -} - -/* ------------------------------------------------------------------------- */ - -static int envcube_isect(EnvMap *env, const float vec[3], float answ[2]) -{ - float lambda; - int face; - - if (env->type == ENV_PLANE) { - face = 1; - - lambda = 1.0f / vec[2]; - answ[0] = env->viewscale * lambda * vec[0]; - answ[1] = -env->viewscale * lambda * vec[1]; - } - else { - /* which face */ - if (vec[2] <= -fabsf(vec[0]) && vec[2] <= -fabsf(vec[1]) ) { - face = 0; - lambda = -1.0f / vec[2]; - answ[0] = lambda * vec[0]; - answ[1] = lambda * vec[1]; - } - else if (vec[2] >= fabsf(vec[0]) && vec[2] >= fabsf(vec[1])) { - face = 1; - lambda = 1.0f / vec[2]; - answ[0] = lambda * vec[0]; - answ[1] = -lambda * vec[1]; - } - else if (vec[1] >= fabsf(vec[0])) { - face = 2; - lambda = 1.0f / vec[1]; - answ[0] = lambda * vec[0]; - answ[1] = lambda * vec[2]; - } - else if (vec[0] <= -fabsf(vec[1])) { - face = 3; - lambda = -1.0f / vec[0]; - answ[0] = lambda * vec[1]; - answ[1] = lambda * vec[2]; - } - else if (vec[1] <= -fabsf(vec[0])) { - face = 4; - lambda = -1.0f / vec[1]; - answ[0] = -lambda * vec[0]; - answ[1] = lambda * vec[2]; - } - else { - face = 5; - lambda = 1.0f / vec[0]; - answ[0] = -lambda * vec[1]; - answ[1] = lambda * vec[2]; - } - } - - answ[0] = 0.5f + 0.5f * answ[0]; - answ[1] = 0.5f + 0.5f * answ[1]; - return face; -} - -/* ------------------------------------------------------------------------- */ - -static void set_dxtdyt(float r_dxt[3], float r_dyt[3], const float dxt[3], const float dyt[3], int face) -{ - if (face == 2 || face == 4) { - r_dxt[0] = dxt[0]; - r_dyt[0] = dyt[0]; - r_dxt[1] = dxt[2]; - r_dyt[1] = dyt[2]; - } - else if (face == 3 || face == 5) { - r_dxt[0] = dxt[1]; - r_dxt[1] = dxt[2]; - r_dyt[0] = dyt[1]; - r_dyt[1] = dyt[2]; - } - else { - r_dxt[0] = dxt[0]; - r_dyt[0] = dyt[0]; - r_dxt[1] = dxt[1]; - r_dyt[1] = dyt[1]; - } -} - -/* ------------------------------------------------------------------------- */ - -int envmaptex(Tex *tex, const float texvec[3], float dxt[3], float dyt[3], int osatex, TexResult *texres, struct ImagePool *pool, const bool skip_load_image) -{ - extern Render R; /* only in this call */ - /* texvec should be the already reflected normal */ - EnvMap *env; - ImBuf *ibuf; - float fac, vec[3], sco[3], dxts[3], dyts[3]; - int face, face1; - - env = tex->env; - if (env == NULL || (env->stype != ENV_LOAD && env->object == NULL)) { - texres->tin = 0.0; - return 0; - } - - if (env->stype == ENV_LOAD) { - env->ima = tex->ima; - if (env->ima && env->ima->ok) { - if (env->cube[1] == NULL) { - ImBuf *ibuf_ima = BKE_image_pool_acquire_ibuf(env->ima, NULL, pool); - if (ibuf_ima) - envmap_split_ima(env, ibuf_ima); - else - env->ok = 0; - - if (env->type == ENV_PLANE) - tex->extend = TEX_EXTEND; - - BKE_image_pool_release_ibuf(env->ima, ibuf_ima, pool); - } - } - } - - if (env->ok == 0) { - texres->tin = 0.0; - return 0; - } - - /* rotate to envmap space, if object is set */ - copy_v3_v3(vec, texvec); - if (env->object) { - mul_m3_v3(env->obimat, vec); - if (osatex) { - mul_m3_v3(env->obimat, dxt); - mul_m3_v3(env->obimat, dyt); - } - } - else { - if (!BKE_scene_use_world_space_shading(R.scene)) { - // texvec is in view space - mul_mat3_m4_v3(R.viewinv, vec); - if (osatex) { - mul_mat3_m4_v3(R.viewinv, dxt); - mul_mat3_m4_v3(R.viewinv, dyt); - } - } - } - - face = envcube_isect(env, vec, sco); - ibuf = env->cube[face]; - - if (osatex) { - set_dxtdyt(dxts, dyts, dxt, dyt, face); - imagewraposa(tex, NULL, ibuf, sco, dxts, dyts, texres, pool, skip_load_image); - - /* edges? */ - - if (texres->ta < 1.0f) { - TexResult texr1, texr2; - - texr1.nor = texr2.nor = NULL; - texr1.talpha = texr2.talpha = texres->talpha; /* boxclip expects this initialized */ - - add_v3_v3(vec, dxt); - face1 = envcube_isect(env, vec, sco); - sub_v3_v3(vec, dxt); - - if (face != face1) { - ibuf = env->cube[face1]; - set_dxtdyt(dxts, dyts, dxt, dyt, face1); - imagewraposa(tex, NULL, ibuf, sco, dxts, dyts, &texr1, pool, skip_load_image); - } - else texr1.tr = texr1.tg = texr1.tb = texr1.ta = 0.0; - - /* here was the nasty bug! results were not zero-ed. FPE! */ - - add_v3_v3(vec, dyt); - face1 = envcube_isect(env, vec, sco); - sub_v3_v3(vec, dyt); - - if (face != face1) { - ibuf = env->cube[face1]; - set_dxtdyt(dxts, dyts, dxt, dyt, face1); - imagewraposa(tex, NULL, ibuf, sco, dxts, dyts, &texr2, pool, skip_load_image); - } - else texr2.tr = texr2.tg = texr2.tb = texr2.ta = 0.0; - - fac = (texres->ta + texr1.ta + texr2.ta); - if (fac != 0.0f) { - fac = 1.0f / fac; - - texres->tr = fac * (texres->ta * texres->tr + texr1.ta * texr1.tr + texr2.ta * texr2.tr); - texres->tg = fac * (texres->ta * texres->tg + texr1.ta * texr1.tg + texr2.ta * texr2.tg); - texres->tb = fac * (texres->ta * texres->tb + texr1.ta * texr1.tb + texr2.ta * texr2.tb); - } - texres->ta = 1.0; - } - } - else { - imagewrap(tex, NULL, ibuf, sco, texres, pool, skip_load_image); - } - - return 1; -} diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c index 79a414381db..03be96a20bc 100644 --- a/source/blender/render/intern/source/external_engine.c +++ b/source/blender/render/intern/source/external_engine.c @@ -47,6 +47,7 @@ #include "BKE_global.h" #include "BKE_colortools.h" #include "BKE_layer.h" +#include "BKE_node.h" #include "BKE_report.h" #include "BKE_scene.h" @@ -69,22 +70,13 @@ #include "renderpipeline.h" #include "render_types.h" #include "render_result.h" -#include "rendercore.h" /* Render Engine Types */ -static RenderEngineType internal_render_type = { - NULL, NULL, - "BLENDER_RENDER", N_("Blender Render"), RE_INTERNAL | RE_USE_LEGACY_PIPELINE, - NULL, NULL, NULL, NULL, NULL, NULL, render_internal_update_passes, NULL, NULL, NULL, - {NULL, NULL, NULL} -}; - ListBase R_engines = {NULL, NULL}; void RE_engines_init(void) { - RE_engines_register(NULL, &internal_render_type); DRW_engines_register(); } @@ -133,7 +125,7 @@ RenderEngineType *RE_engines_find(const char *idname) type = BLI_findstring(&R_engines, idname, offsetof(RenderEngineType, idname)); if (!type) - type = &internal_render_type; + type = BLI_findstring(&R_engines, "BLENDER_EEVEE", offsetof(RenderEngineType, idname)); return type; } @@ -493,13 +485,6 @@ rcti* RE_engine_get_current_tiles(Render *re, int *r_total_tiles, bool *r_needs_ } tiles[total_tiles] = pa->disprect; - if (pa->crop) { - tiles[total_tiles].xmin += pa->crop; - tiles[total_tiles].ymin += pa->crop; - tiles[total_tiles].xmax -= pa->crop; - tiles[total_tiles].ymax -= pa->crop; - } - total_tiles++; } } @@ -601,7 +586,7 @@ bool RE_bake_engine( engine->resolution_x = re->winx; engine->resolution_y = re->winy; - RE_parts_init(re, false); + RE_parts_init(re); engine->tile_x = re->r.tilex; engine->tile_y = re->r.tiley; @@ -733,7 +718,7 @@ int RE_engine_render(Render *re, int do_all) engine->resolution_x = re->winx; engine->resolution_y = re->winy; - RE_parts_init(re, false); + RE_parts_init(re); engine->tile_x = re->partx; engine->tile_y = re->party; diff --git a/source/blender/render/intern/source/imagetexture.c b/source/blender/render/intern/source/imagetexture.c index 6e5d10fcc84..db28a5db531 100644 --- a/source/blender/render/intern/source/imagetexture.c +++ b/source/blender/render/intern/source/imagetexture.c @@ -53,16 +53,11 @@ #include "BKE_image.h" #include "RE_render_ext.h" +#include "RE_shader_ext.h" #include "render_types.h" #include "texture.h" -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -/* defined in pipeline.c, is hardcopy of active dynamic allocated Render */ -/* only to be used here in this file, it's for speed */ -extern struct Render R; -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - static void boxsample(ImBuf *ibuf, float minx, float miny, float maxx, float maxy, TexResult *texres, const short imaprepeat, const short imapextend); /* *********** IMAGEWRAPPING ****************** */ @@ -211,11 +206,6 @@ int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], TexResul } } - /* warning, no return before setting back! */ - if ( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) ) { - ibuf->rect+= (ibuf->x*ibuf->y); - } - /* keep this before interpolation [#29761] */ if (ima) { if ((tex->imaflag & TEX_USEALPHA) && (ima->flag & IMA_IGNORE_ALPHA) == 0) { @@ -243,10 +233,6 @@ int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], TexResul ibuf_get_color(&texres->tr, ibuf, x, y); } - if ( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) ) { - ibuf->rect-= (ibuf->x*ibuf->y); - } - if (texres->nor) { if (tex->imaflag & TEX_NORMALMAP) { /* qdn: normal from color @@ -979,17 +965,6 @@ static int imagewraposa_aniso(Tex *tex, Image *ima, ImBuf *ibuf, const float tex fy = texvec[1]; } - if (ibuf->flags & IB_fields) { - if (R.r.mode & R_FIELDS) { /* field render */ - if (R.flag & R_SEC_FIELD) { /* correction for 2nd field */ - /* fac1= 0.5/( (float)ibuf->y ); */ - /* fy-= fac1; */ - } - else /* first field */ - fy += 0.5f/( (float)ibuf->y ); - } - } - /* pixel coordinates */ minx = min_fff(dxt[0], dyt[0], dxt[0] + dyt[0]); maxx = max_fff(dxt[0], dyt[0], dxt[0] + dyt[0]); @@ -1129,10 +1104,6 @@ static int imagewraposa_aniso(Tex *tex, Image *ima, ImBuf *ibuf, const float tex intpol = tex->imaflag & TEX_INTERPOL; - /* warning no return! */ - if ((R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields)) - ibuf->rect += ibuf->x*ibuf->y; - /* struct common data */ copy_v2_v2(AFD.dxt, dxt); copy_v2_v2(AFD.dyt, dyt); @@ -1311,9 +1282,6 @@ static int imagewraposa_aniso(Tex *tex, Image *ima, ImBuf *ibuf, const float tex texres->tin = texres->ta; if (tex->flag & TEX_NEGALPHA) texres->ta = 1.f - texres->ta; - if ((R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields)) - ibuf->rect -= ibuf->x*ibuf->y; - if (texres->nor && (tex->imaflag & TEX_NORMALMAP)) { /* normal from color */ /* The invert of the red channel is to make * the normal map compliant with the outside world. @@ -1411,18 +1379,6 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const fy= texvec[1]; } - if (ibuf->flags & IB_fields) { - if (R.r.mode & R_FIELDS) { /* field render */ - if (R.flag & R_SEC_FIELD) { /* correction for 2nd field */ - /* fac1= 0.5/( (float)ibuf->y ); */ - /* fy-= fac1; */ - } - else { /* first field */ - fy+= 0.5f/( (float)ibuf->y ); - } - } - } - /* pixel coordinates */ minx = min_fff(dxt[0], dyt[0], dxt[0] + dyt[0]); @@ -1580,11 +1536,6 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const } } - /* warning no return! */ - if ( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) ) { - ibuf->rect+= (ibuf->x*ibuf->y); - } - /* choice: */ if (tex->imaflag & TEX_MIPMAP) { ImBuf *previbuf, *curibuf; @@ -1731,10 +1682,6 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const if (tex->flag & TEX_NEGALPHA) texres->ta= 1.0f-texres->ta; - if ( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) ) { - ibuf->rect-= (ibuf->x*ibuf->y); - } - if (texres->nor && (tex->imaflag & TEX_NORMALMAP)) { /* qdn: normal from color * The invert of the red channel is to make @@ -1772,16 +1719,10 @@ void image_sample(Image *ima, float fx, float fy, float dx, float dy, float resu return; } - if ( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) ) - ibuf->rect+= (ibuf->x*ibuf->y); - texres.talpha = true; /* boxsample expects to be initialized */ boxsample(ibuf, fx, fy, fx + dx, fy + dy, &texres, 0, 1); copy_v4_v4(result, &texres.tr); - if ( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) ) - ibuf->rect-= (ibuf->x*ibuf->y); - ima->flag|= IMA_USED_FOR_RENDER; BKE_image_pool_release_ibuf(ima, ibuf, pool); diff --git a/source/blender/render/intern/source/initrender.c b/source/blender/render/intern/source/initrender.c index 13c95dac05d..4274d641674 100644 --- a/source/blender/render/intern/source/initrender.c +++ b/source/blender/render/intern/source/initrender.c @@ -38,18 +38,12 @@ #include "BLI_math.h" #include "BLI_blenlib.h" -#include "BLI_jitter_2d.h" #include "BLI_utildefines.h" #include "DNA_camera_types.h" -#include "DNA_image_types.h" -#include "DNA_object_types.h" -#include "DNA_scene_types.h" #include "BKE_camera.h" -#include "DEG_depsgraph.h" - /* this module */ #include "renderpipeline.h" #include "render_types.h" @@ -58,31 +52,6 @@ #include "initrender.h" -/* ********************** */ - -static void init_render_jit(Render *re) -{ - static float jit[32][2]; /* simple caching */ - static float mblur_jit[32][2]; /* simple caching */ - static int lastjit = 0; - static int last_mblur_jit = 0; - - if (lastjit != re->r.osa || last_mblur_jit != re->r.mblur_samples) { - memset(jit, 0, sizeof(jit)); - BLI_jitter_init(jit, re->r.osa); - - memset(mblur_jit, 0, sizeof(mblur_jit)); - BLI_jitter_init(mblur_jit, re->r.mblur_samples); - } - - lastjit = re->r.osa; - memcpy(re->jit, jit, sizeof(jit)); - - last_mblur_jit = re->r.mblur_samples; - memcpy(re->mblur_jit, mblur_jit, sizeof(mblur_jit)); -} - - /* ****************** MASKS and LUTS **************** */ static float filt_quadratic(float x) @@ -173,256 +142,6 @@ float RE_filter_value(int type, float x) return 0.0f; } -static float calc_weight(Render *re, float *weight, int i, int j) -{ - float x, y, dist, totw = 0.0; - int a; - - for (a = 0; a < re->osa; a++) { - x = re->jit[a][0] + i; - y = re->jit[a][1] + j; - dist = sqrtf(x * x + y * y); - - weight[a] = 0.0; - - /* Weighting choices */ - switch (re->r.filtertype) { - case R_FILTER_BOX: - if (i == 0 && j == 0) weight[a] = 1.0; - break; - - case R_FILTER_TENT: - if (dist < re->r.gauss) - weight[a] = re->r.gauss - dist; - break; - - case R_FILTER_GAUSS: - x = dist * re->r.gauss; - weight[a] = (1.0f / expf(x * x) - 1.0f / expf(re->r.gauss * re->r.gauss * 2.25f)); - break; - - case R_FILTER_MITCH: - weight[a] = filt_mitchell(dist * re->r.gauss); - break; - - case R_FILTER_QUAD: - weight[a] = filt_quadratic(dist * re->r.gauss); - break; - - case R_FILTER_CUBIC: - weight[a] = filt_cubic(dist * re->r.gauss); - break; - - case R_FILTER_CATROM: - weight[a] = filt_catrom(dist * re->r.gauss); - break; - - } - - totw += weight[a]; - - } - return totw; -} - -void free_sample_tables(Render *re) -{ - int a; - - if (re->samples) { - for (a = 0; a < 9; a++) { - MEM_freeN(re->samples->fmask1[a]); - MEM_freeN(re->samples->fmask2[a]); - } - - MEM_freeN(re->samples->centmask); - MEM_freeN(re->samples); - re->samples = NULL; - } -} - -/* based on settings in render, it makes the lookup tables */ -void make_sample_tables(Render *re) -{ - static int firsttime = 1; - SampleTables *st; - float flweight[32]; - float weight[32], totw, val, *fpx1, *fpx2, *fpy1, *fpy2, *m3, *m4; - int i, j, a, centmasksize; - - /* optimization tables, only once */ - if (firsttime) { - firsttime = 0; - } - - free_sample_tables(re); - - init_render_jit(re); /* needed for mblur too */ - - if (re->osa == 0) { - /* just prevents cpu cycles for larger render and copying */ - re->r.filtertype = 0; - return; - } - - st = re->samples = MEM_callocN(sizeof(SampleTables), "sample tables"); - - for (a = 0; a < 9; a++) { - st->fmask1[a] = MEM_callocN(256 * sizeof(float), "initfilt"); - st->fmask2[a] = MEM_callocN(256 * sizeof(float), "initfilt"); - } - for (a = 0; a < 256; a++) { - st->cmask[a] = 0; - if (a & 1) st->cmask[a]++; - if (a & 2) st->cmask[a]++; - if (a & 4) st->cmask[a]++; - if (a & 8) st->cmask[a]++; - if (a & 16) st->cmask[a]++; - if (a & 32) st->cmask[a]++; - if (a & 64) st->cmask[a]++; - if (a & 128) st->cmask[a]++; - } - - centmasksize = (1 << re->osa); - st->centmask = MEM_mallocN(centmasksize, "Initfilt3"); - - for (a = 0; a < 16; a++) { - st->centLut[a] = -0.45f + ((float)a) / 16.0f; - } - - /* calculate totw */ - totw = 0.0; - for (j = -1; j < 2; j++) { - for (i = -1; i < 2; i++) { - totw += calc_weight(re, weight, i, j); - } - } - - for (j = -1; j < 2; j++) { - for (i = -1; i < 2; i++) { - /* calculate using jit, with offset the weights */ - - memset(weight, 0, sizeof(weight)); - calc_weight(re, weight, i, j); - - for (a = 0; a < 16; a++) flweight[a] = weight[a] * (1.0f / totw); - - m3 = st->fmask1[3 * (j + 1) + i + 1]; - m4 = st->fmask2[3 * (j + 1) + i + 1]; - - for (a = 0; a < 256; a++) { - if (a & 1) { - m3[a] += flweight[0]; - m4[a] += flweight[8]; - } - if (a & 2) { - m3[a] += flweight[1]; - m4[a] += flweight[9]; - } - if (a & 4) { - m3[a] += flweight[2]; - m4[a] += flweight[10]; - } - if (a & 8) { - m3[a] += flweight[3]; - m4[a] += flweight[11]; - } - if (a & 16) { - m3[a] += flweight[4]; - m4[a] += flweight[12]; - } - if (a & 32) { - m3[a] += flweight[5]; - m4[a] += flweight[13]; - } - if (a & 64) { - m3[a] += flweight[6]; - m4[a] += flweight[14]; - } - if (a & 128) { - m3[a] += flweight[7]; - m4[a] += flweight[15]; - } - } - } - } - - /* centmask: the correct subpixel offset per mask */ - - fpx1 = MEM_mallocN(256 * sizeof(float), "initgauss4"); - fpx2 = MEM_mallocN(256 * sizeof(float), "initgauss4"); - fpy1 = MEM_mallocN(256 * sizeof(float), "initgauss4"); - fpy2 = MEM_mallocN(256 * sizeof(float), "initgauss4"); - for (a = 0; a < 256; a++) { - fpx1[a] = fpx2[a] = 0.0; - fpy1[a] = fpy2[a] = 0.0; - if (a & 1) { - fpx1[a] += re->jit[0][0]; - fpy1[a] += re->jit[0][1]; - fpx2[a] += re->jit[8][0]; - fpy2[a] += re->jit[8][1]; - } - if (a & 2) { - fpx1[a] += re->jit[1][0]; - fpy1[a] += re->jit[1][1]; - fpx2[a] += re->jit[9][0]; - fpy2[a] += re->jit[9][1]; - } - if (a & 4) { - fpx1[a] += re->jit[2][0]; - fpy1[a] += re->jit[2][1]; - fpx2[a] += re->jit[10][0]; - fpy2[a] += re->jit[10][1]; - } - if (a & 8) { - fpx1[a] += re->jit[3][0]; - fpy1[a] += re->jit[3][1]; - fpx2[a] += re->jit[11][0]; - fpy2[a] += re->jit[11][1]; - } - if (a & 16) { - fpx1[a] += re->jit[4][0]; - fpy1[a] += re->jit[4][1]; - fpx2[a] += re->jit[12][0]; - fpy2[a] += re->jit[12][1]; - } - if (a & 32) { - fpx1[a] += re->jit[5][0]; - fpy1[a] += re->jit[5][1]; - fpx2[a] += re->jit[13][0]; - fpy2[a] += re->jit[13][1]; - } - if (a & 64) { - fpx1[a] += re->jit[6][0]; - fpy1[a] += re->jit[6][1]; - fpx2[a] += re->jit[14][0]; - fpy2[a] += re->jit[14][1]; - } - if (a & 128) { - fpx1[a] += re->jit[7][0]; - fpy1[a] += re->jit[7][1]; - fpx2[a] += re->jit[15][0]; - fpy2[a] += re->jit[15][1]; - } - } - - for (a = centmasksize - 1; a > 0; a--) { - val = st->cmask[a & 255] + st->cmask[a >> 8]; - i = 8 + (15.9f * (fpy1[a & 255] + fpy2[a >> 8]) / val); - CLAMP(i, 0, 15); - j = 8 + (15.9f * (fpx1[a & 255] + fpx2[a >> 8]) / val); - CLAMP(j, 0, 15); - i = j + (i << 4); - st->centmask[a] = i; - } - - MEM_freeN(fpx1); - MEM_freeN(fpx2); - MEM_freeN(fpy1); - MEM_freeN(fpy2); -} - - /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ struct Object *RE_GetCamera(Render *re) { @@ -437,37 +156,11 @@ static void re_camera_params_get(Render *re, CameraParams *params, Object *cam_o re->clipsta = params->clipsta; re->clipend = params->clipend; - re->ycor = params->ycor; - re->viewdx = params->viewdx; - re->viewdy = params->viewdy; re->viewplane = params->viewplane; BKE_camera_object_mode(&re->r, cam_ob); } -void RE_SetEnvmapCamera(Render *re, Object *cam_ob, float viewscale, float clipsta, float clipend) -{ - CameraParams params; - - /* setup parameters */ - BKE_camera_params_init(¶ms); - BKE_camera_params_from_object(¶ms, cam_ob); - - params.lens = 16.0f * viewscale; - params.sensor_x = 32.0f; - params.sensor_y = 32.0f; - params.sensor_fit = CAMERA_SENSOR_FIT_AUTO; - params.clipsta = clipsta; - params.clipend = clipend; - - /* compute matrix, viewplane, .. */ - BKE_camera_params_compute_viewplane(¶ms, re->winx, re->winy, 1.0f, 1.0f); - BKE_camera_params_compute_matrix(¶ms); - - /* extract results */ - re_camera_params_get(re, ¶ms, cam_ob); -} - void RE_SetOverrideCamera(Render *re, Object *camera) { re->camera_override = camera; @@ -489,10 +182,6 @@ void RE_SetCamera(Render *re, Object *cam_ob) BKE_camera_params_from_object(¶ms, cam_ob); re_camera_params_stereo3d(re, ¶ms, cam_ob); - params.use_fields = (re->r.mode & R_FIELDS); - params.field_second = (re->flag & R_SEC_FIELD); - params.field_odd = (re->r.mode & R_ODDFIELD); - /* compute matrix, viewplane, .. */ BKE_camera_params_compute_viewplane(¶ms, re->winx, re->winy, re->r.xasp, re->r.yasp); BKE_camera_params_compute_matrix(¶ms); @@ -501,12 +190,6 @@ void RE_SetCamera(Render *re, Object *cam_ob) re_camera_params_get(re, ¶ms, cam_ob); } -void RE_SetPixelSize(Render *re, float pixsize) -{ - re->viewdx = pixsize; - re->viewdy = re->ycor * pixsize; -} - void RE_GetCameraWindow(struct Render *re, struct Object *camera, int frame, float mat[4][4]) { re->r.cfra = frame; @@ -524,13 +207,6 @@ void RE_GetCameraModelMatrix(Render *re, struct Object *camera, float r_mat[4][4 void RE_parts_free(Render *re) { - RenderPart *part = re->parts.first; - - while (part) { - if (part->rectp) MEM_freeN(part->rectp); - if (part->rectz) MEM_freeN(part->rectz); - part = part->next; - } BLI_freelistN(&re->parts); } @@ -541,7 +217,7 @@ void RE_parts_clamp(Render *re) re->party = max_ii(1, min_ii(re->r.tiley, re->recty)); } -void RE_parts_init(Render *re, bool do_crop) +void RE_parts_init(Render *re) { int nr, xd, yd, partx, party, xparts, yparts; int xminb, xmaxb, yminb, ymaxb; @@ -567,10 +243,6 @@ void RE_parts_init(Render *re, bool do_crop) xparts = (re->rectx + partx - 1) / partx; yparts = (re->recty + party - 1) / party; - /* calculate rotation factor of 1 pixel */ - if (re->r.mode & R_PANORAMA) - re->panophi = panorama_pixel_rot(re); - for (nr = 0; nr < xparts * yparts; nr++) { rcti disprect; int rectx, recty; @@ -603,16 +275,6 @@ void RE_parts_init(Render *re, bool do_crop) if (rectx > 0 && recty > 0) { RenderPart *pa = MEM_callocN(sizeof(RenderPart), "new part"); - /* Non-box filters need 2 pixels extra to work */ - if (do_crop && (re->r.filtertype || (re->r.mode & R_EDGE))) { - pa->crop = 2; - disprect.xmin -= pa->crop; - disprect.ymin -= pa->crop; - disprect.xmax += pa->crop; - disprect.ymax += pa->crop; - rectx += 2 * pa->crop; - recty += 2 * pa->crop; - } pa->disprect = disprect; pa->rectx = rectx; pa->recty = recty; diff --git a/source/blender/render/intern/source/multires_bake.c b/source/blender/render/intern/source/multires_bake.c index ddab8b23b59..9fb7e718b18 100644 --- a/source/blender/render/intern/source/multires_bake.c +++ b/source/blender/render/intern/source/multires_bake.c @@ -36,6 +36,7 @@ #include "DNA_object_types.h" #include "DNA_mesh_types.h" +#include "DNA_scene_types.h" #include "BLI_math.h" #include "BLI_listbase.h" @@ -59,10 +60,6 @@ #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" -#include "rayintersection.h" -#include "rayobject.h" -#include "rendercore.h" - typedef void (*MPassKnownData)(DerivedMesh *lores_dm, DerivedMesh *hires_dm, void *thread_data, void *bake_data, ImBuf *ibuf, const int face_index, const int lvl, const float st[2], float tangmat[3][3], const int x, const int y); @@ -115,19 +112,6 @@ typedef struct { const int *orig_index_mp_to_orig; } MNormalBakeData; -typedef struct { - int number_of_rays; - float bias; - - unsigned short *permutation_table_1; - unsigned short *permutation_table_2; - - RayObject *raytree; - RayFace *rayfaces; - - const int *orig_index_mp_to_orig; -} MAOBakeData; - static void multiresbake_get_normal(const MResolvePixelData *data, float norm[],const int tri_num, const int vert_index) { const int poly_index = data->mlooptri[tri_num].poly; @@ -884,6 +868,8 @@ static void apply_tangmat_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm, } } +/* TODO: restore ambient occlusion baking support, using BLI BVH? */ +#if 0 /* **************** Ambient Occlusion Baker **************** */ // must be a power of two @@ -1176,6 +1162,68 @@ static void apply_ao_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm, void rrgb[3] = 255; } } +#endif + +/* ******$***************** Post processing ************************* */ + +static void bake_ibuf_filter(ImBuf *ibuf, char *mask, const int filter) +{ + /* must check before filtering */ + const bool is_new_alpha = (ibuf->planes != R_IMF_PLANES_RGBA) && BKE_imbuf_alpha_test(ibuf); + + /* Margin */ + if (filter) { + IMB_filter_extend(ibuf, mask, filter); + } + + /* if the bake results in new alpha then change the image setting */ + if (is_new_alpha) { + ibuf->planes = R_IMF_PLANES_RGBA; + } + else { + if (filter && ibuf->planes != R_IMF_PLANES_RGBA) { + /* clear alpha added by filtering */ + IMB_rectfill_alpha(ibuf, 1.0f); + } + } +} + +static void bake_ibuf_normalize_displacement(ImBuf *ibuf, float *displacement, char *mask, float displacement_min, float displacement_max) +{ + int i; + const float *current_displacement = displacement; + const char *current_mask = mask; + float max_distance; + + max_distance = max_ff(fabsf(displacement_min), fabsf(displacement_max)); + + for (i = 0; i < ibuf->x * ibuf->y; i++) { + if (*current_mask == FILTER_MASK_USED) { + float normalized_displacement; + + if (max_distance > 1e-5f) + normalized_displacement = (*current_displacement + max_distance) / (max_distance * 2); + else + normalized_displacement = 0.5f; + + if (ibuf->rect_float) { + /* currently baking happens to RGBA only */ + float *fp = ibuf->rect_float + i * 4; + fp[0] = fp[1] = fp[2] = normalized_displacement; + fp[3] = 1.0f; + } + + if (ibuf->rect) { + unsigned char *cp = (unsigned char *) (ibuf->rect + i); + cp[0] = cp[1] = cp[2] = FTOCHAR(normalized_displacement); + cp[3] = 255; + } + } + + current_displacement++; + current_mask++; + } +} /* **************** Common functions public API relates on **************** */ @@ -1229,12 +1277,14 @@ static void bake_images(MultiresBakeRender *bkr, MultiresBakeResult *result) do_multires_bake(bkr, ima, true, apply_tangmat_callback, init_normal_data, free_normal_data, result); break; case RE_BAKE_DISPLACEMENT: - case RE_BAKE_DERIVATIVE: do_multires_bake(bkr, ima, false, apply_heights_callback, init_heights_data, free_heights_data, result); break; +/* TODO: restore ambient occlusion baking support. */ +#if 0 case RE_BAKE_AO: do_multires_bake(bkr, ima, false, apply_ao_callback, init_ao_data, free_ao_data, result); break; +#endif } } @@ -1247,7 +1297,7 @@ static void bake_images(MultiresBakeRender *bkr, MultiresBakeResult *result) static void finish_images(MultiresBakeRender *bkr, MultiresBakeResult *result) { LinkData *link; - bool use_displacement_buffer = ELEM(bkr->mode, RE_BAKE_DISPLACEMENT, RE_BAKE_DERIVATIVE); + bool use_displacement_buffer = bkr->mode == RE_BAKE_DISPLACEMENT; for (link = bkr->image.first; link; link = link->next) { Image *ima = (Image *)link->data; @@ -1258,17 +1308,11 @@ static void finish_images(MultiresBakeRender *bkr, MultiresBakeResult *result) continue; if (use_displacement_buffer) { - if (bkr->mode == RE_BAKE_DERIVATIVE) { - RE_bake_make_derivative(ibuf, userdata->displacement_buffer, userdata->mask_buffer, - result->height_min, result->height_max, bkr->user_scale); - } - else { - RE_bake_ibuf_normalize_displacement(ibuf, userdata->displacement_buffer, userdata->mask_buffer, - result->height_min, result->height_max); - } + bake_ibuf_normalize_displacement(ibuf, userdata->displacement_buffer, userdata->mask_buffer, + result->height_min, result->height_max); } - RE_bake_ibuf_filter(ibuf, userdata->mask_buffer, bkr->bake_filter); + bake_ibuf_filter(ibuf, userdata->mask_buffer, bkr->bake_filter); ibuf->userflags |= IB_BITMAPDIRTY | IB_DISPLAY_BUFFER_INVALID; diff --git a/source/blender/render/intern/source/occlusion.c b/source/blender/render/intern/source/occlusion.c deleted file mode 100644 index 42200a8278c..00000000000 --- a/source/blender/render/intern/source/occlusion.c +++ /dev/null @@ -1,1533 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2008 Blender Foundation. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): Brecht Van Lommel. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/render/intern/source/occlusion.c - * \ingroup render - */ - -#include <math.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "MEM_guardedalloc.h" - -#include "DNA_material_types.h" - -#include "BLI_math.h" -#include "BLI_memarena.h" -#include "BLI_threads.h" -#include "BLI_utildefines.h" - -#include "BLT_translation.h" - -#include "BKE_node.h" -#include "BKE_scene.h" - - -#include "RE_shader_ext.h" - -/* local includes */ -#include "occlusion.h" -#include "render_types.h" -#include "rendercore.h" -#include "renderdatabase.h" -#include "shading.h" - -/* ------------------------- Declarations --------------------------- */ - -#define INVPI ((float)M_1_PI) -#define TOTCHILD 8 -#define CACHE_STEP 3 - -typedef struct OcclusionCacheSample { - float co[3], n[3], ao[3], env[3], indirect[3], intensity, dist2; - int x, y, filled; -} OcclusionCacheSample; - -typedef struct OcclusionCache { - OcclusionCacheSample *sample; - int x, y, w, h, step; -} OcclusionCache; - -typedef struct OccFace { - int obi; - int facenr; -} OccFace; - -typedef struct OccNode { - float co[3], area; - float sh[9], dco; - float occlusion, rad[3]; - int childflag; - union { - //OccFace face; - int face; - struct OccNode *node; - } child[TOTCHILD]; -} OccNode; - -typedef struct OcclusionTree { - MemArena *arena; - - float (*co)[3]; /* temporary during build */ - - OccFace *face; /* instance and face indices */ - float *occlusion; /* occlusion for faces */ - float (*rad)[3]; /* radiance for faces */ - - OccNode *root; - - OccNode **stack[BLENDER_MAX_THREADS]; - int maxdepth; - - int totface; - - float error; - float distfac; - - int dothreadedbuild; - int totbuildthread; - int doindirect; - - OcclusionCache *cache; - - int num_threads; -} OcclusionTree; - -typedef struct OcclusionThread { - Render *re; - StrandSurface *mesh; - float (*faceao)[3]; - float (*faceenv)[3]; - float (*faceindirect)[3]; - int begin, end; - int thread; -} OcclusionThread; - -typedef struct OcclusionBuildThread { - OcclusionTree *tree; - int begin, end, depth; - OccNode *node; -} OcclusionBuildThread; - -/* ------------------------- Shading --------------------------- */ - -extern Render R; /* meh */ - -static void occ_shade(ShadeSample *ssamp, ObjectInstanceRen *obi, VlakRen *vlr, float *rad) -{ - ShadeInput *shi = ssamp->shi; - ShadeResult *shr = ssamp->shr; - float l, u, v, *v1, *v2, *v3; - - /* init */ - if (vlr->v4) { - shi->u = u = 0.5f; - shi->v = v = 0.5f; - } - else { - shi->u = u = 1.0f / 3.0f; - shi->v = v = 1.0f / 3.0f; - } - - /* setup render coordinates */ - v1 = vlr->v1->co; - v2 = vlr->v2->co; - v3 = vlr->v3->co; - - /* renderco */ - l = 1.0f - u - v; - - shi->co[0] = l * v3[0] + u * v1[0] + v * v2[0]; - shi->co[1] = l * v3[1] + u * v1[1] + v * v2[1]; - shi->co[2] = l * v3[2] + u * v1[2] + v * v2[2]; - - shade_input_set_triangle_i(shi, obi, vlr, 0, 1, 2); - - /* set up view vector */ - copy_v3_v3(shi->view, shi->co); - normalize_v3(shi->view); - - /* cache for shadow */ - shi->samplenr++; - - shi->xs = 0; /* TODO */ - shi->ys = 0; - - shade_input_set_normals(shi); - - /* no normal flip */ - if (shi->flippednor) - shade_input_flip_normals(shi); - - madd_v3_v3fl(shi->co, shi->facenor, -0.0001f); /* ugly.. */ - - /* not a pretty solution, but fixes common cases */ - if (shi->obr->ob && shi->obr->ob->transflag & OB_NEG_SCALE) { - negate_v3(shi->vn); - negate_v3(shi->vno); - negate_v3(shi->nmapnorm); - } - - /* init material vars */ - shade_input_init_material(shi); - - /* render */ - shade_input_set_shade_texco(shi); - - if (shi->mat->nodetree && shi->mat->use_nodes) { - ntreeShaderExecTree(shi->mat->nodetree, shi, shr); - shi->mat = vlr->mat; /* shi->mat is being set in nodetree */ - } - else { - shade_material_loop(shi, shr); - } - - copy_v3_v3(rad, shr->combined); -} - -static void occ_build_shade(Render *re, OcclusionTree *tree) -{ - ShadeSample ssamp; - ObjectInstanceRen *obi; - VlakRen *vlr; - int a; - - R = *re; - - /* setup shade sample with correct passes */ - memset(&ssamp, 0, sizeof(ShadeSample)); - ssamp.shi[0].lay = re->lay; - ssamp.shi[0].passflag = SCE_PASS_DIFFUSE | SCE_PASS_RGBA; - ssamp.shi[0].combinedflag = ~(SCE_PASS_SPEC); - ssamp.tot = 1; - - for (a = 0; a < tree->totface; a++) { - obi = &R.objectinstance[tree->face[a].obi]; - vlr = RE_findOrAddVlak(obi->obr, tree->face[a].facenr); - - occ_shade(&ssamp, obi, vlr, tree->rad[a]); - - if (re->test_break(re->tbh)) - break; - } -} - -/* ------------------------- Spherical Harmonics --------------------------- */ - -/* Use 2nd order SH => 9 coefficients, stored in this order: - * 0 = (0,0), - * 1 = (1,-1), 2 = (1,0), 3 = (1,1), - * 4 = (2,-2), 5 = (2,-1), 6 = (2,0), 7 = (2,1), 8 = (2,2) */ - -static void sh_copy(float *shresult, float *sh) -{ - memcpy(shresult, sh, sizeof(float) * 9); -} - -static void sh_mul(float *sh, float f) -{ - int i; - - for (i = 0; i < 9; i++) - sh[i] *= f; -} - -static void sh_add(float *shresult, float *sh1, float *sh2) -{ - int i; - - for (i = 0; i < 9; i++) - shresult[i] = sh1[i] + sh2[i]; -} - -static void sh_from_disc(float *n, float area, float *shresult) -{ - /* See formula (3) in: - * "An Efficient Representation for Irradiance Environment Maps" */ - float sh[9], x, y, z; - - x = n[0]; - y = n[1]; - z = n[2]; - - sh[0] = 0.282095f; - - sh[1] = 0.488603f * y; - sh[2] = 0.488603f * z; - sh[3] = 0.488603f * x; - - sh[4] = 1.092548f * x * y; - sh[5] = 1.092548f * y * z; - sh[6] = 0.315392f * (3.0f * z * z - 1.0f); - sh[7] = 1.092548f * x * z; - sh[8] = 0.546274f * (x * x - y * y); - - sh_mul(sh, area); - sh_copy(shresult, sh); -} - -static float sh_eval(float *sh, float *v) -{ - /* See formula (13) in: - * "An Efficient Representation for Irradiance Environment Maps" */ - static const float c1 = 0.429043f, c2 = 0.511664f, c3 = 0.743125f; - static const float c4 = 0.886227f, c5 = 0.247708f; - float x, y, z, sum; - - x = v[0]; - y = v[1]; - z = v[2]; - - sum = c1 * sh[8] * (x * x - y * y); - sum += c3 * sh[6] * z * z; - sum += c4 * sh[0]; - sum += -c5 * sh[6]; - sum += 2.0f * c1 * (sh[4] * x * y + sh[7] * x * z + sh[5] * y * z); - sum += 2.0f * c2 * (sh[3] * x + sh[1] * y + sh[2] * z); - - return sum; -} - -/* ------------------------------ Building --------------------------------- */ - -static void occ_face(const OccFace *face, float co[3], float normal[3], float *area) -{ - ObjectInstanceRen *obi; - VlakRen *vlr; - float v1[3], v2[3], v3[3], v4[3]; - - obi = &R.objectinstance[face->obi]; - vlr = RE_findOrAddVlak(obi->obr, face->facenr); - - if (co) { - if (vlr->v4) - mid_v3_v3v3(co, vlr->v1->co, vlr->v3->co); - else - mid_v3_v3v3v3(co, vlr->v1->co, vlr->v2->co, vlr->v3->co); - - if (obi->flag & R_TRANSFORMED) - mul_m4_v3(obi->mat, co); - } - - if (normal) { - normal[0] = -vlr->n[0]; - normal[1] = -vlr->n[1]; - normal[2] = -vlr->n[2]; - - if (obi->flag & R_TRANSFORMED) - mul_m3_v3(obi->nmat, normal); - } - - if (area) { - copy_v3_v3(v1, vlr->v1->co); - copy_v3_v3(v2, vlr->v2->co); - copy_v3_v3(v3, vlr->v3->co); - if (vlr->v4) copy_v3_v3(v4, vlr->v4->co); - - if (obi->flag & R_TRANSFORMED) { - mul_m4_v3(obi->mat, v1); - mul_m4_v3(obi->mat, v2); - mul_m4_v3(obi->mat, v3); - if (vlr->v4) mul_m4_v3(obi->mat, v4); - } - - /* todo: correct area for instances */ - if (vlr->v4) - *area = area_quad_v3(v1, v2, v3, v4); - else - *area = area_tri_v3(v1, v2, v3); - } -} - -static void occ_sum_occlusion(OcclusionTree *tree, OccNode *node) -{ - OccNode *child; - float occ, area, totarea, rad[3]; - int a, b, indirect = tree->doindirect; - - occ = 0.0f; - totarea = 0.0f; - if (indirect) zero_v3(rad); - - for (b = 0; b < TOTCHILD; b++) { - if (node->childflag & (1 << b)) { - a = node->child[b].face; - occ_face(&tree->face[a], NULL, NULL, &area); - occ += area * tree->occlusion[a]; - if (indirect) madd_v3_v3fl(rad, tree->rad[a], area); - totarea += area; - } - else if (node->child[b].node) { - child = node->child[b].node; - occ_sum_occlusion(tree, child); - - occ += child->area * child->occlusion; - if (indirect) madd_v3_v3fl(rad, child->rad, child->area); - totarea += child->area; - } - } - - if (totarea != 0.0f) { - occ /= totarea; - if (indirect) mul_v3_fl(rad, 1.0f / totarea); - } - - node->occlusion = occ; - if (indirect) copy_v3_v3(node->rad, rad); -} - -static int occ_find_bbox_axis(OcclusionTree *tree, int begin, int end, float *min, float *max) -{ - float len, maxlen = -1.0f; - int a, axis = 0; - - INIT_MINMAX(min, max); - - for (a = begin; a < end; a++) { - minmax_v3v3_v3(min, max, tree->co[a]); - } - - for (a = 0; a < 3; a++) { - len = max[a] - min[a]; - - if (len > maxlen) { - maxlen = len; - axis = a; - } - } - - return axis; -} - -static void occ_node_from_face(OccFace *face, OccNode *node) -{ - float n[3]; - - occ_face(face, node->co, n, &node->area); - node->dco = 0.0f; - sh_from_disc(n, node->area, node->sh); -} - -static void occ_build_dco(OcclusionTree *tree, OccNode *node, const float co[3], float *dco) -{ - int b; - for (b = 0; b < TOTCHILD; b++) { - float dist, d[3], nco[3]; - - if (node->childflag & (1 << b)) { - occ_face(tree->face + node->child[b].face, nco, NULL, NULL); - } - else if (node->child[b].node) { - OccNode *child = node->child[b].node; - occ_build_dco(tree, child, co, dco); - copy_v3_v3(nco, child->co); - } - else { - continue; - } - - sub_v3_v3v3(d, nco, co); - dist = dot_v3v3(d, d); - if (dist > *dco) - *dco = dist; - } -} - -static void occ_build_split(OcclusionTree *tree, int begin, int end, int *split) -{ - float min[3], max[3], mid; - int axis, a, enda; - - /* split in middle of boundbox. this seems faster than median split - * on complex scenes, possibly since it avoids two distant faces to - * be in the same node better? */ - axis = occ_find_bbox_axis(tree, begin, end, min, max); - mid = 0.5f * (min[axis] + max[axis]); - - a = begin; - enda = end; - while (a < enda) { - if (tree->co[a][axis] > mid) { - enda--; - SWAP(OccFace, tree->face[a], tree->face[enda]); - swap_v3_v3(tree->co[a], tree->co[enda]); - } - else - a++; - } - - *split = enda; -} - -static void occ_build_8_split(OcclusionTree *tree, int begin, int end, int *offset, int *count) -{ - /* split faces into eight groups */ - int b, splitx, splity[2], splitz[4]; - - occ_build_split(tree, begin, end, &splitx); - - /* force split if none found, to deal with degenerate geometry */ - if (splitx == begin || splitx == end) - splitx = (begin + end) / 2; - - occ_build_split(tree, begin, splitx, &splity[0]); - occ_build_split(tree, splitx, end, &splity[1]); - - occ_build_split(tree, begin, splity[0], &splitz[0]); - occ_build_split(tree, splity[0], splitx, &splitz[1]); - occ_build_split(tree, splitx, splity[1], &splitz[2]); - occ_build_split(tree, splity[1], end, &splitz[3]); - - offset[0] = begin; - offset[1] = splitz[0]; - offset[2] = splity[0]; - offset[3] = splitz[1]; - offset[4] = splitx; - offset[5] = splitz[2]; - offset[6] = splity[1]; - offset[7] = splitz[3]; - - for (b = 0; b < 7; b++) - count[b] = offset[b + 1] - offset[b]; - count[7] = end - offset[7]; -} - -static void occ_build_recursive(OcclusionTree *tree, OccNode *node, int begin, int end, int depth); - -static void *exec_occ_build(void *data) -{ - OcclusionBuildThread *othread = (OcclusionBuildThread *)data; - - occ_build_recursive(othread->tree, othread->node, othread->begin, othread->end, othread->depth); - - return NULL; -} - -static void occ_build_recursive(OcclusionTree *tree, OccNode *node, int begin, int end, int depth) -{ - ListBase threads; - OcclusionBuildThread othreads[BLENDER_MAX_THREADS]; - OccNode *child, tmpnode; - /* OccFace *face; */ - int a, b, totthread = 0, offset[TOTCHILD], count[TOTCHILD]; - - /* add a new node */ - node->occlusion = 1.0f; - - /* leaf node with only children */ - if (end - begin <= TOTCHILD) { - for (a = begin, b = 0; a < end; a++, b++) { - /* face= &tree->face[a]; */ - node->child[b].face = a; - node->childflag |= (1 << b); - } - } - else { - /* order faces */ - occ_build_8_split(tree, begin, end, offset, count); - - if (depth == 1 && tree->dothreadedbuild) - BLI_threadpool_init(&threads, exec_occ_build, tree->totbuildthread); - - for (b = 0; b < TOTCHILD; b++) { - if (count[b] == 0) { - node->child[b].node = NULL; - } - else if (count[b] == 1) { - /* face= &tree->face[offset[b]]; */ - node->child[b].face = offset[b]; - node->childflag |= (1 << b); - } - else { - if (tree->dothreadedbuild) - BLI_thread_lock(LOCK_CUSTOM1); - - child = BLI_memarena_alloc(tree->arena, sizeof(OccNode)); - node->child[b].node = child; - - /* keep track of maximum depth for stack */ - if (depth >= tree->maxdepth) - tree->maxdepth = depth + 1; - - if (tree->dothreadedbuild) - BLI_thread_unlock(LOCK_CUSTOM1); - - if (depth == 1 && tree->dothreadedbuild) { - othreads[totthread].tree = tree; - othreads[totthread].node = child; - othreads[totthread].begin = offset[b]; - othreads[totthread].end = offset[b] + count[b]; - othreads[totthread].depth = depth + 1; - BLI_threadpool_insert(&threads, &othreads[totthread]); - totthread++; - } - else - occ_build_recursive(tree, child, offset[b], offset[b] + count[b], depth + 1); - } - } - - if (depth == 1 && tree->dothreadedbuild) - BLI_threadpool_end(&threads); - } - - /* combine area, position and sh */ - for (b = 0; b < TOTCHILD; b++) { - if (node->childflag & (1 << b)) { - child = &tmpnode; - occ_node_from_face(tree->face + node->child[b].face, &tmpnode); - } - else { - child = node->child[b].node; - } - - if (child) { - node->area += child->area; - sh_add(node->sh, node->sh, child->sh); - madd_v3_v3fl(node->co, child->co, child->area); - } - } - - if (node->area != 0.0f) - mul_v3_fl(node->co, 1.0f / node->area); - - /* compute maximum distance from center */ - node->dco = 0.0f; - if (node->area > 0.0f) - occ_build_dco(tree, node, node->co, &node->dco); -} - -static void occ_build_sh_normalize(OccNode *node) -{ - /* normalize spherical harmonics to not include area, so - * we can clamp the dot product and then multiply by area */ - int b; - - if (node->area != 0.0f) - sh_mul(node->sh, 1.0f / node->area); - - for (b = 0; b < TOTCHILD; b++) { - if (node->childflag & (1 << b)) { - /* pass */ - } - else if (node->child[b].node) { - occ_build_sh_normalize(node->child[b].node); - } - } -} - -static OcclusionTree *occ_tree_build(Render *re) -{ - const int num_threads = re->r.threads; - OcclusionTree *tree; - ObjectInstanceRen *obi; - ObjectRen *obr; - Material *ma; - VlakRen *vlr = NULL; - int a, b, c, totface; - - /* count */ - totface = 0; - for (obi = re->instancetable.first; obi; obi = obi->next) { - obr = obi->obr; - for (a = 0; a < obr->totvlak; a++) { - if ((a & 255) == 0) vlr = obr->vlaknodes[a >> 8].vlak; - else vlr++; - - ma = vlr->mat; - - if ((ma->shade_flag & MA_APPROX_OCCLUSION) && (ma->material_type == MA_TYPE_SURFACE)) - totface++; - } - } - - if (totface == 0) - return NULL; - - tree = MEM_callocN(sizeof(OcclusionTree), "OcclusionTree"); - tree->totface = totface; - - /* parameters */ - tree->error = get_render_aosss_error(&re->r, re->wrld.ao_approx_error); - tree->distfac = (re->wrld.aomode & WO_AODIST) ? re->wrld.aodistfac : 0.0f; - tree->doindirect = (re->wrld.ao_indirect_energy > 0.0f && re->wrld.ao_indirect_bounces > 0); - - /* allocation */ - tree->arena = BLI_memarena_new(0x8000 * sizeof(OccNode), "occ tree arena"); - BLI_memarena_use_calloc(tree->arena); - - if (re->wrld.aomode & WO_AOCACHE) - tree->cache = MEM_callocN(sizeof(OcclusionCache) * num_threads, "OcclusionCache"); - - tree->face = MEM_callocN(sizeof(OccFace) * totface, "OcclusionFace"); - tree->co = MEM_callocN(sizeof(float) * 3 * totface, "OcclusionCo"); - tree->occlusion = MEM_callocN(sizeof(float) * totface, "OcclusionOcclusion"); - - if (tree->doindirect) - tree->rad = MEM_callocN(sizeof(float) * 3 * totface, "OcclusionRad"); - - /* make array of face pointers */ - for (b = 0, c = 0, obi = re->instancetable.first; obi; obi = obi->next, c++) { - obr = obi->obr; - for (a = 0; a < obr->totvlak; a++) { - if ((a & 255) == 0) vlr = obr->vlaknodes[a >> 8].vlak; - else vlr++; - - ma = vlr->mat; - - if ((ma->shade_flag & MA_APPROX_OCCLUSION) && (ma->material_type == MA_TYPE_SURFACE)) { - tree->face[b].obi = c; - tree->face[b].facenr = a; - tree->occlusion[b] = 1.0f; - occ_face(&tree->face[b], tree->co[b], NULL, NULL); - b++; - } - } - } - - /* threads */ - tree->totbuildthread = (re->r.threads > 1 && totface > 10000) ? 8 : 1; - tree->dothreadedbuild = (tree->totbuildthread > 1); - - /* recurse */ - tree->root = BLI_memarena_alloc(tree->arena, sizeof(OccNode)); - tree->maxdepth = 1; - occ_build_recursive(tree, tree->root, 0, totface, 1); - - if (tree->doindirect) { - if (!(re->test_break(re->tbh))) - occ_build_shade(re, tree); - - if (!(re->test_break(re->tbh))) - occ_sum_occlusion(tree, tree->root); - } - - MEM_freeN(tree->co); - tree->co = NULL; - - if (!(re->test_break(re->tbh))) - occ_build_sh_normalize(tree->root); - - for (a = 0; a < num_threads; a++) - tree->stack[a] = MEM_callocN(sizeof(OccNode) * TOTCHILD * (tree->maxdepth + 1), "OccStack"); - - tree->num_threads = num_threads; - - return tree; -} - -static void occ_free_tree(OcclusionTree *tree) -{ - int a; - - if (tree) { - if (tree->arena) BLI_memarena_free(tree->arena); - for (a = 0; a < tree->num_threads; a++) - if (tree->stack[a]) - MEM_freeN(tree->stack[a]); - if (tree->occlusion) MEM_freeN(tree->occlusion); - if (tree->cache) MEM_freeN(tree->cache); - if (tree->face) MEM_freeN(tree->face); - if (tree->rad) MEM_freeN(tree->rad); - MEM_freeN(tree); - } -} - -/* ------------------------- Traversal --------------------------- */ - -static float occ_solid_angle(OccNode *node, const float v[3], float d2, float invd2, const float receivenormal[3]) -{ - float dotreceive, dotemit; - float ev[3]; - - ev[0] = -v[0] * invd2; - ev[1] = -v[1] * invd2; - ev[2] = -v[2] * invd2; - dotemit = sh_eval(node->sh, ev); - dotreceive = dot_v3v3(receivenormal, v) * invd2; - - CLAMP(dotemit, 0.0f, 1.0f); - CLAMP(dotreceive, 0.0f, 1.0f); - - return ((node->area * dotemit * dotreceive) / (d2 + node->area * INVPI)) * INVPI; -} - -static float occ_form_factor(OccFace *face, float *p, float *n) -{ - ObjectInstanceRen *obi; - VlakRen *vlr; - float v1[3], v2[3], v3[3], v4[3], q0[3], q1[3], q2[3], q3[3], contrib = 0.0f; - - obi = &R.objectinstance[face->obi]; - vlr = RE_findOrAddVlak(obi->obr, face->facenr); - - copy_v3_v3(v1, vlr->v1->co); - copy_v3_v3(v2, vlr->v2->co); - copy_v3_v3(v3, vlr->v3->co); - - if (obi->flag & R_TRANSFORMED) { - mul_m4_v3(obi->mat, v1); - mul_m4_v3(obi->mat, v2); - mul_m4_v3(obi->mat, v3); - } - - if (form_factor_visible_quad(p, n, v1, v2, v3, q0, q1, q2, q3)) - contrib += form_factor_quad(p, n, q0, q1, q2, q3); - - if (vlr->v4) { - copy_v3_v3(v4, vlr->v4->co); - if (obi->flag & R_TRANSFORMED) - mul_m4_v3(obi->mat, v4); - - if (form_factor_visible_quad(p, n, v1, v3, v4, q0, q1, q2, q3)) - contrib += form_factor_quad(p, n, q0, q1, q2, q3); - } - - return contrib; -} - -static void occ_lookup(OcclusionTree *tree, int thread, OccFace *exclude, - const float pp[3], const float pn[3], float *occ, float rad[3], float bentn[3]) -{ - OccNode *node, **stack; - OccFace *face; - float resultocc, resultrad[3], v[3], p[3], n[3], co[3], invd2; - float distfac, fac, error, d2, weight, emitarea; - int b, f, totstack; - - /* init variables */ - copy_v3_v3(p, pp); - copy_v3_v3(n, pn); - madd_v3_v3fl(p, n, 1e-4f); - - if (bentn) - copy_v3_v3(bentn, n); - - error = tree->error; - distfac = tree->distfac; - - resultocc = 0.0f; - zero_v3(resultrad); - - /* init stack */ - stack = tree->stack[thread]; - stack[0] = tree->root; - totstack = 1; - - while (totstack) { - /* pop point off the stack */ - node = stack[--totstack]; - - sub_v3_v3v3(v, node->co, p); - d2 = dot_v3v3(v, v) + 1e-16f; - emitarea = MAX2(node->area, node->dco); - - if (d2 * error > emitarea) { - if (distfac != 0.0f) { - fac = 1.0f / (1.0f + distfac * d2); - if (fac < 0.01f) - continue; - } - else - fac = 1.0f; - - /* accumulate occlusion from spherical harmonics */ - invd2 = 1.0f / sqrtf(d2); - weight = occ_solid_angle(node, v, d2, invd2, n); - - if (rad) - madd_v3_v3fl(resultrad, node->rad, weight * fac); - - weight *= node->occlusion; - - if (bentn) { - bentn[0] -= weight * invd2 * v[0]; - bentn[1] -= weight * invd2 * v[1]; - bentn[2] -= weight * invd2 * v[2]; - } - - resultocc += weight * fac; - } - else { - /* traverse into children */ - for (b = 0; b < TOTCHILD; b++) { - if (node->childflag & (1 << b)) { - f = node->child[b].face; - face = &tree->face[f]; - - /* accumulate occlusion with face form factor */ - if (!exclude || !(face->obi == exclude->obi && face->facenr == exclude->facenr)) { - if (bentn || distfac != 0.0f) { - occ_face(face, co, NULL, NULL); - sub_v3_v3v3(v, co, p); - d2 = dot_v3v3(v, v) + 1e-16f; - - fac = (distfac == 0.0f) ? 1.0f : 1.0f / (1.0f + distfac * d2); - if (fac < 0.01f) - continue; - } - else - fac = 1.0f; - - weight = occ_form_factor(face, p, n); - - if (rad) - madd_v3_v3fl(resultrad, tree->rad[f], weight * fac); - - weight *= tree->occlusion[f]; - - if (bentn) { - invd2 = 1.0f / sqrtf(d2); - bentn[0] -= weight * invd2 * v[0]; - bentn[1] -= weight * invd2 * v[1]; - bentn[2] -= weight * invd2 * v[2]; - } - - resultocc += weight * fac; - } - } - else if (node->child[b].node) { - /* push child on the stack */ - stack[totstack++] = node->child[b].node; - } - } - } - } - - if (occ) *occ = resultocc; - if (rad) copy_v3_v3(rad, resultrad); -#if 0 - if (rad && exclude) { - int a; - for (a = 0; a < tree->totface; a++) - if ((tree->face[a].obi == exclude->obi && tree->face[a].facenr == exclude->facenr)) - copy_v3_v3(rad, tree->rad[a]); - } -#endif - if (bentn) normalize_v3(bentn); -} - -static void occ_compute_bounces(Render *re, OcclusionTree *tree, int totbounce) -{ - float (*rad)[3], (*sum)[3], (*tmp)[3], co[3], n[3], occ; - int bounce, i; - - rad = MEM_callocN(sizeof(float) * 3 * tree->totface, "OcclusionBounceRad"); - sum = MEM_dupallocN(tree->rad); - - for (bounce = 1; bounce < totbounce; bounce++) { - for (i = 0; i < tree->totface; i++) { - occ_face(&tree->face[i], co, n, NULL); - madd_v3_v3fl(co, n, 1e-8f); - - occ_lookup(tree, 0, &tree->face[i], co, n, &occ, rad[i], NULL); - rad[i][0] = MAX2(rad[i][0], 0.0f); - rad[i][1] = MAX2(rad[i][1], 0.0f); - rad[i][2] = MAX2(rad[i][2], 0.0f); - add_v3_v3(sum[i], rad[i]); - - if (re->test_break(re->tbh)) - break; - } - - if (re->test_break(re->tbh)) - break; - - tmp = tree->rad; - tree->rad = rad; - rad = tmp; - - occ_sum_occlusion(tree, tree->root); - } - - MEM_freeN(rad); - MEM_freeN(tree->rad); - tree->rad = sum; - - if (!re->test_break(re->tbh)) - occ_sum_occlusion(tree, tree->root); -} - -static void occ_compute_passes(Render *re, OcclusionTree *tree, int totpass) -{ - float *occ, co[3], n[3]; - int pass, i; - - occ = MEM_callocN(sizeof(float) * tree->totface, "OcclusionPassOcc"); - - for (pass = 0; pass < totpass; pass++) { - for (i = 0; i < tree->totface; i++) { - occ_face(&tree->face[i], co, n, NULL); - negate_v3(n); - madd_v3_v3fl(co, n, 1e-8f); - - occ_lookup(tree, 0, &tree->face[i], co, n, &occ[i], NULL, NULL); - if (re->test_break(re->tbh)) - break; - } - - if (re->test_break(re->tbh)) - break; - - for (i = 0; i < tree->totface; i++) { - tree->occlusion[i] -= occ[i]; //MAX2(1.0f-occ[i], 0.0f); - if (tree->occlusion[i] < 0.0f) - tree->occlusion[i] = 0.0f; - } - - occ_sum_occlusion(tree, tree->root); - } - - MEM_freeN(occ); -} - -static void sample_occ_tree(Render *re, OcclusionTree *tree, OccFace *exclude, - const float co[3], const float n[3], int thread, int onlyshadow, - float *ao, float *env, float *indirect) -{ - float nn[3], bn[3], fac, occ, occlusion, correction, rad[3]; - int envcolor; - - envcolor = re->wrld.aocolor; - if (onlyshadow) - envcolor = WO_AOPLAIN; - - negate_v3_v3(nn, n); - - occ_lookup(tree, thread, exclude, co, nn, &occ, (tree->doindirect) ? rad : NULL, (env && envcolor) ? bn : NULL); - - correction = re->wrld.ao_approx_correction; - - occlusion = (1.0f - correction) * (1.0f - occ); - CLAMP(occlusion, 0.0f, 1.0f); - if (correction != 0.0f) - occlusion += correction * expf(-occ); - - if (env) { - /* sky shading using bent normal */ - if (ELEM(envcolor, WO_AOSKYCOL, WO_AOSKYTEX)) { - fac = 0.5f * (1.0f + dot_v3v3(bn, re->grvec)); - env[0] = (1.0f - fac) * re->wrld.horr + fac * re->wrld.zenr; - env[1] = (1.0f - fac) * re->wrld.horg + fac * re->wrld.zeng; - env[2] = (1.0f - fac) * re->wrld.horb + fac * re->wrld.zenb; - - mul_v3_fl(env, occlusion); - } - else { - env[0] = occlusion; - env[1] = occlusion; - env[2] = occlusion; - } -#if 0 - else { /* WO_AOSKYTEX */ - float dxyview[3]; - bn[0] = -bn[0]; - bn[1] = -bn[1]; - bn[2] = -bn[2]; - dxyview[0] = 1.0f; - dxyview[1] = 1.0f; - dxyview[2] = 0.0f; - shadeSkyView(ao, co, bn, dxyview); - } -#endif - } - - if (ao) { - ao[0] = occlusion; - ao[1] = occlusion; - ao[2] = occlusion; - } - - if (tree->doindirect) copy_v3_v3(indirect, rad); - else zero_v3(indirect); -} - -/* ---------------------------- Caching ------------------------------- */ - -static OcclusionCacheSample *find_occ_sample(OcclusionCache *cache, int x, int y) -{ - x -= cache->x; - y -= cache->y; - - x /= cache->step; - y /= cache->step; - x *= cache->step; - y *= cache->step; - - if (x < 0 || x >= cache->w || y < 0 || y >= cache->h) - return NULL; - else - return &cache->sample[y * cache->w + x]; -} - -static int sample_occ_cache(OcclusionTree *tree, float *co, float *n, int x, int y, int thread, float *ao, float *env, float *indirect) -{ - OcclusionCache *cache; - OcclusionCacheSample *samples[4], *sample; - float wn[4], wz[4], wb[4], tx, ty, w, totw, mino, maxo; - float d[3], dist2; - int i, x1, y1, x2, y2; - - if (!tree->cache) - return 0; - - /* first try to find a sample in the same pixel */ - cache = &tree->cache[thread]; - - if (cache->sample && cache->step) { - sample = &cache->sample[(y - cache->y) * cache->w + (x - cache->x)]; - if (sample->filled) { - sub_v3_v3v3(d, sample->co, co); - dist2 = dot_v3v3(d, d); - if (dist2 < 0.5f * sample->dist2 && dot_v3v3(sample->n, n) > 0.98f) { - copy_v3_v3(ao, sample->ao); - copy_v3_v3(env, sample->env); - copy_v3_v3(indirect, sample->indirect); - return 1; - } - } - } - else - return 0; - - /* try to interpolate between 4 neighboring pixels */ - samples[0] = find_occ_sample(cache, x, y); - samples[1] = find_occ_sample(cache, x + cache->step, y); - samples[2] = find_occ_sample(cache, x, y + cache->step); - samples[3] = find_occ_sample(cache, x + cache->step, y + cache->step); - - for (i = 0; i < 4; i++) - if (!samples[i] || !samples[i]->filled) - return 0; - - /* require intensities not being too different */ - mino = min_ffff(samples[0]->intensity, samples[1]->intensity, samples[2]->intensity, samples[3]->intensity); - maxo = max_ffff(samples[0]->intensity, samples[1]->intensity, samples[2]->intensity, samples[3]->intensity); - - if (maxo - mino > 0.05f) - return 0; - - /* compute weighted interpolation between samples */ - zero_v3(ao); - zero_v3(env); - zero_v3(indirect); - totw = 0.0f; - - x1 = samples[0]->x; - y1 = samples[0]->y; - x2 = samples[3]->x; - y2 = samples[3]->y; - - tx = (float)(x2 - x) / (float)(x2 - x1); - ty = (float)(y2 - y) / (float)(y2 - y1); - - wb[3] = (1.0f - tx) * (1.0f - ty); - wb[2] = (tx) * (1.0f - ty); - wb[1] = (1.0f - tx) * (ty); - wb[0] = tx * ty; - - for (i = 0; i < 4; i++) { - sub_v3_v3v3(d, samples[i]->co, co); - //dist2 = dot_v3v3(d, d); - - wz[i] = 1.0f; //(samples[i]->dist2/(1e-4f + dist2)); - wn[i] = pow(dot_v3v3(samples[i]->n, n), 32.0f); - - w = wb[i] * wn[i] * wz[i]; - - totw += w; - madd_v3_v3fl(ao, samples[i]->ao, w); - madd_v3_v3fl(env, samples[i]->env, w); - madd_v3_v3fl(indirect, samples[i]->indirect, w); - } - - if (totw >= 0.9f) { - totw = 1.0f / totw; - mul_v3_fl(ao, totw); - mul_v3_fl(env, totw); - mul_v3_fl(indirect, totw); - return 1; - } - - return 0; -} - -static void sample_occ_surface(ShadeInput *shi) -{ - StrandRen *strand = shi->strand; - StrandSurface *mesh = strand->buffer->surface; - const int *face, *index = RE_strandren_get_face(shi->obr, strand, 0); - float w[4], *co1, *co2, *co3, *co4; - - if (mesh && mesh->face && mesh->co && mesh->ao && index) { - face = mesh->face[*index]; - - co1 = mesh->co[face[0]]; - co2 = mesh->co[face[1]]; - co3 = mesh->co[face[2]]; - - if (face[3]) { - co4 = mesh->co[face[3]]; - interp_weights_quad_v3(w, co1, co2, co3, co4, strand->vert->co); - } - else { - interp_weights_tri_v3(w, co1, co2, co3, strand->vert->co); - } - - zero_v3(shi->ao); - zero_v3(shi->env); - zero_v3(shi->indirect); - - madd_v3_v3fl(shi->ao, mesh->ao[face[0]], w[0]); - madd_v3_v3fl(shi->env, mesh->env[face[0]], w[0]); - madd_v3_v3fl(shi->indirect, mesh->indirect[face[0]], w[0]); - madd_v3_v3fl(shi->ao, mesh->ao[face[1]], w[1]); - madd_v3_v3fl(shi->env, mesh->env[face[1]], w[1]); - madd_v3_v3fl(shi->indirect, mesh->indirect[face[1]], w[1]); - madd_v3_v3fl(shi->ao, mesh->ao[face[2]], w[2]); - madd_v3_v3fl(shi->env, mesh->env[face[2]], w[2]); - madd_v3_v3fl(shi->indirect, mesh->indirect[face[2]], w[2]); - if (face[3]) { - madd_v3_v3fl(shi->ao, mesh->ao[face[3]], w[3]); - madd_v3_v3fl(shi->env, mesh->env[face[3]], w[3]); - madd_v3_v3fl(shi->indirect, mesh->indirect[face[3]], w[3]); - } - } - else { - shi->ao[0] = 1.0f; - shi->ao[1] = 1.0f; - shi->ao[2] = 1.0f; - zero_v3(shi->env); - zero_v3(shi->indirect); - } -} - -/* ------------------------- External Functions --------------------------- */ - -static void *exec_strandsurface_sample(void *data) -{ - OcclusionThread *othread = (OcclusionThread *)data; - Render *re = othread->re; - StrandSurface *mesh = othread->mesh; - float ao[3], env[3], indirect[3], co[3], n[3], *co1, *co2, *co3, *co4; - int a, *face; - - for (a = othread->begin; a < othread->end; a++) { - face = mesh->face[a]; - co1 = mesh->co[face[0]]; - co2 = mesh->co[face[1]]; - co3 = mesh->co[face[2]]; - - if (face[3]) { - co4 = mesh->co[face[3]]; - - mid_v3_v3v3(co, co1, co3); - normal_quad_v3(n, co1, co2, co3, co4); - } - else { - mid_v3_v3v3v3(co, co1, co2, co3); - normal_tri_v3(n, co1, co2, co3); - } - negate_v3(n); - - sample_occ_tree(re, re->occlusiontree, NULL, co, n, othread->thread, 0, ao, env, indirect); - copy_v3_v3(othread->faceao[a], ao); - copy_v3_v3(othread->faceenv[a], env); - copy_v3_v3(othread->faceindirect[a], indirect); - } - - return NULL; -} - -void make_occ_tree(Render *re) -{ - OcclusionThread othreads[BLENDER_MAX_THREADS]; - OcclusionTree *tree; - StrandSurface *mesh; - ListBase threads; - float ao[3], env[3], indirect[3], (*faceao)[3], (*faceenv)[3], (*faceindirect)[3]; - int a, totface, totthread, *face, *count; - - /* ugly, needed for occ_face */ - R = *re; - - re->i.infostr = IFACE_("Occlusion preprocessing"); - re->stats_draw(re->sdh, &re->i); - - re->occlusiontree = tree = occ_tree_build(re); - - if (tree && !re->test_break(re->tbh)) { - if (re->wrld.ao_approx_passes > 0) - occ_compute_passes(re, tree, re->wrld.ao_approx_passes); - if (tree->doindirect && (re->wrld.mode & WO_INDIRECT_LIGHT)) - occ_compute_bounces(re, tree, re->wrld.ao_indirect_bounces); - - for (mesh = re->strandsurface.first; mesh; mesh = mesh->next) { - if (!mesh->face || !mesh->co || !mesh->ao) - continue; - - count = MEM_callocN(sizeof(int) * mesh->totvert, "OcclusionCount"); - faceao = MEM_callocN(sizeof(float) * 3 * mesh->totface, "StrandSurfFaceAO"); - faceenv = MEM_callocN(sizeof(float) * 3 * mesh->totface, "StrandSurfFaceEnv"); - faceindirect = MEM_callocN(sizeof(float) * 3 * mesh->totface, "StrandSurfFaceIndirect"); - - totthread = (mesh->totface > 10000) ? re->r.threads : 1; - totface = mesh->totface / totthread; - for (a = 0; a < totthread; a++) { - othreads[a].re = re; - othreads[a].faceao = faceao; - othreads[a].faceenv = faceenv; - othreads[a].faceindirect = faceindirect; - othreads[a].thread = a; - othreads[a].mesh = mesh; - othreads[a].begin = a * totface; - othreads[a].end = (a == totthread - 1) ? mesh->totface : (a + 1) * totface; - } - - if (totthread == 1) { - exec_strandsurface_sample(&othreads[0]); - } - else { - BLI_threadpool_init(&threads, exec_strandsurface_sample, totthread); - - for (a = 0; a < totthread; a++) - BLI_threadpool_insert(&threads, &othreads[a]); - - BLI_threadpool_end(&threads); - } - - for (a = 0; a < mesh->totface; a++) { - face = mesh->face[a]; - - copy_v3_v3(ao, faceao[a]); - copy_v3_v3(env, faceenv[a]); - copy_v3_v3(indirect, faceindirect[a]); - - add_v3_v3(mesh->ao[face[0]], ao); - add_v3_v3(mesh->env[face[0]], env); - add_v3_v3(mesh->indirect[face[0]], indirect); - count[face[0]]++; - add_v3_v3(mesh->ao[face[1]], ao); - add_v3_v3(mesh->env[face[1]], env); - add_v3_v3(mesh->indirect[face[1]], indirect); - count[face[1]]++; - add_v3_v3(mesh->ao[face[2]], ao); - add_v3_v3(mesh->env[face[2]], env); - add_v3_v3(mesh->indirect[face[2]], indirect); - count[face[2]]++; - - if (face[3]) { - add_v3_v3(mesh->ao[face[3]], ao); - add_v3_v3(mesh->env[face[3]], env); - add_v3_v3(mesh->indirect[face[3]], indirect); - count[face[3]]++; - } - } - - for (a = 0; a < mesh->totvert; a++) { - if (count[a]) { - mul_v3_fl(mesh->ao[a], 1.0f / count[a]); - mul_v3_fl(mesh->env[a], 1.0f / count[a]); - mul_v3_fl(mesh->indirect[a], 1.0f / count[a]); - } - } - - MEM_freeN(count); - MEM_freeN(faceao); - MEM_freeN(faceenv); - MEM_freeN(faceindirect); - } - } -} - -void free_occ(Render *re) -{ - if (re->occlusiontree) { - occ_free_tree(re->occlusiontree); - re->occlusiontree = NULL; - } -} - -void sample_occ(Render *re, ShadeInput *shi) -{ - OcclusionTree *tree = re->occlusiontree; - OcclusionCache *cache; - OcclusionCacheSample *sample; - OccFace exclude; - int onlyshadow; - - if (tree) { - if (shi->strand) { - sample_occ_surface(shi); - } - /* try to get result from the cache if possible */ - else if (shi->depth != 0 || !sample_occ_cache(tree, shi->co, shi->vno, shi->xs, shi->ys, shi->thread, shi->ao, shi->env, shi->indirect)) { - /* no luck, let's sample the occlusion */ - exclude.obi = shi->obi - re->objectinstance; - exclude.facenr = shi->vlr->index; - onlyshadow = (shi->mat->mode & MA_ONLYSHADOW); - sample_occ_tree(re, tree, &exclude, shi->co, shi->vno, shi->thread, onlyshadow, shi->ao, shi->env, shi->indirect); - - /* fill result into sample, each time */ - if (tree->cache) { - cache = &tree->cache[shi->thread]; - - if (cache->sample && cache->step) { - sample = &cache->sample[(shi->ys - cache->y) * cache->w + (shi->xs - cache->x)]; - copy_v3_v3(sample->co, shi->co); - copy_v3_v3(sample->n, shi->vno); - copy_v3_v3(sample->ao, shi->ao); - copy_v3_v3(sample->env, shi->env); - copy_v3_v3(sample->indirect, shi->indirect); - sample->intensity = max_fff(sample->ao[0], sample->ao[1], sample->ao[2]); - sample->intensity = max_ff(sample->intensity, max_fff(sample->env[0], sample->env[1], sample->env[2])); - sample->intensity = max_ff(sample->intensity, max_fff(sample->indirect[0], sample->indirect[1], sample->indirect[2])); - sample->dist2 = dot_v3v3(shi->dxco, shi->dxco) + dot_v3v3(shi->dyco, shi->dyco); - sample->filled = 1; - } - } - } - } - else { - shi->ao[0] = 1.0f; - shi->ao[1] = 1.0f; - shi->ao[2] = 1.0f; - - shi->env[0] = 0.0f; - shi->env[1] = 0.0f; - shi->env[2] = 0.0f; - - shi->indirect[0] = 0.0f; - shi->indirect[1] = 0.0f; - shi->indirect[2] = 0.0f; - } -} - -void cache_occ_samples(Render *re, RenderPart *pa, ShadeSample *ssamp) -{ - OcclusionTree *tree = re->occlusiontree; - PixStr ps; - OcclusionCache *cache; - OcclusionCacheSample *sample; - OccFace exclude; - ShadeInput *shi; - intptr_t *rd = NULL; - int *ro = NULL, *rp = NULL, *rz = NULL, onlyshadow; - int x, y, step = CACHE_STEP; - - if (!tree->cache) - return; - - cache = &tree->cache[pa->thread]; - cache->w = pa->rectx; - cache->h = pa->recty; - cache->x = pa->disprect.xmin; - cache->y = pa->disprect.ymin; - cache->step = step; - cache->sample = MEM_callocN(sizeof(OcclusionCacheSample) * cache->w * cache->h, "OcclusionCacheSample"); - sample = cache->sample; - - if (re->osa) { - rd = pa->rectdaps; - } - else { - /* fake pixel struct for non-osa */ - ps.next = NULL; - ps.mask = 0xFFFF; - - ro = pa->recto; - rp = pa->rectp; - rz = pa->rectz; - } - - /* compute a sample at every step pixels */ - for (y = pa->disprect.ymin; y < pa->disprect.ymax; y++) { - for (x = pa->disprect.xmin; x < pa->disprect.xmax; x++, sample++, rd++, ro++, rp++, rz++) { - if (!(((x - pa->disprect.xmin + step) % step) == 0 || x == pa->disprect.xmax - 1)) - continue; - if (!(((y - pa->disprect.ymin + step) % step) == 0 || y == pa->disprect.ymax - 1)) - continue; - - if (re->osa) { - if (!*rd) continue; - - shade_samples_fill_with_ps(ssamp, (PixStr *)(*rd), x, y); - } - else { - if (!*rp) continue; - - ps.obi = *ro; - ps.facenr = *rp; - ps.z = *rz; - shade_samples_fill_with_ps(ssamp, &ps, x, y); - } - - shi = ssamp->shi; - if (shi->vlr) { - onlyshadow = (shi->mat->mode & MA_ONLYSHADOW); - exclude.obi = shi->obi - re->objectinstance; - exclude.facenr = shi->vlr->index; - sample_occ_tree(re, tree, &exclude, shi->co, shi->vno, shi->thread, onlyshadow, shi->ao, shi->env, shi->indirect); - - copy_v3_v3(sample->co, shi->co); - copy_v3_v3(sample->n, shi->vno); - copy_v3_v3(sample->ao, shi->ao); - copy_v3_v3(sample->env, shi->env); - copy_v3_v3(sample->indirect, shi->indirect); - sample->intensity = max_fff(sample->ao[0], sample->ao[1], sample->ao[2]); - sample->intensity = max_ff(sample->intensity, max_fff(sample->env[0], sample->env[1], sample->env[2])); - sample->intensity = max_ff(sample->intensity, max_fff(sample->indirect[0], sample->indirect[1], sample->indirect[2])); - sample->dist2 = dot_v3v3(shi->dxco, shi->dxco) + dot_v3v3(shi->dyco, shi->dyco); - sample->x = shi->xs; - sample->y = shi->ys; - sample->filled = 1; - } - - if (re->test_break(re->tbh)) - break; - } - } -} - -void free_occ_samples(Render *re, RenderPart *pa) -{ - OcclusionTree *tree = re->occlusiontree; - OcclusionCache *cache; - - if (tree->cache) { - cache = &tree->cache[pa->thread]; - - if (cache->sample) - MEM_freeN(cache->sample); - - cache->w = 0; - cache->h = 0; - cache->step = 0; - } -} - diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index ba50467f9ea..dd2042d3220 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -92,6 +92,7 @@ #include "RE_engine.h" #include "RE_pipeline.h" +#include "RE_render_ext.h" #ifdef WITH_FREESTYLE # include "FRS_freestyle.h" @@ -100,14 +101,10 @@ #include "DEG_depsgraph.h" /* internal */ +#include "initrender.h" +#include "renderpipeline.h" #include "render_result.h" #include "render_types.h" -#include "renderpipeline.h" -#include "renderdatabase.h" -#include "rendercore.h" -#include "initrender.h" -#include "pixelblending.h" -#include "zbuf.h" /* render flow * @@ -142,19 +139,10 @@ static struct { ListBase renderlist; } RenderGlobal = {{NULL, NULL}}; -/* hardcopy of current render, used while rendering for speed */ -Render R; - /* ********* alloc and free ******** */ static int do_write_image_or_movie(Render *re, Main *bmain, Scene *scene, bMovieHandle *mh, const int totvideos, const char *name_override); -static volatile int g_break = 0; -static int thread_break(void *UNUSED(arg)) -{ - return g_break; -} - /* default callbacks, set in each new render */ static void result_nothing(void *UNUSED(arg), RenderResult *UNUSED(rr)) {} static void result_rcti_nothing(void *UNUSED(arg), RenderResult *UNUSED(rr), volatile struct rcti *UNUSED(rect)) {} @@ -289,18 +277,6 @@ RenderLayer *render_get_active_layer(Render *re, RenderResult *rr) return rr->layers.first; } -static int UNUSED_FUNCTION(render_scene_needs_vector)(Render *re) -{ - ViewLayer *view_layer; - for (view_layer = re->view_layers.first; view_layer; view_layer = view_layer->next) - if (view_layer->flag & VIEW_LAYER_RENDER) { - if (view_layer->passflag & SCE_PASS_VECTOR) { - return 1; - } - } - return 0; -} - static bool render_scene_has_layers_to_render(Scene *scene) { ViewLayer *view_layer; @@ -525,9 +501,6 @@ Render *RE_NewRender(const char *name) RE_InitRenderCB(re); - /* init some variables */ - re->ycor = 1.0f; - return re; } @@ -598,9 +571,6 @@ void RE_FreeRender(Render *re) re->main = NULL; re->scene = NULL; - RE_Database_Free(re); /* view render can still have full database */ - free_sample_tables(re); - render_result_free(re->result); render_result_free(re->pushedresult); @@ -667,15 +637,10 @@ void RE_FreePersistentData(void) /* clear full sample and tile flags if needed */ static int check_mode_full_sample(RenderData *rd) { - const char *engine_id = rd->engine; int scemode = rd->scemode; - if (!STREQ(engine_id, RE_engine_id_BLENDER_RENDER)) { - scemode &= ~R_FULL_SAMPLE; - } - - if ((rd->mode & R_OSA) == 0) - scemode &= ~R_FULL_SAMPLE; + /* not supported by any current renderer */ + scemode &= ~R_FULL_SAMPLE; #ifdef WITH_OPENEXR if (scemode & R_FULL_SAMPLE) @@ -695,7 +660,7 @@ static void re_init_resolution(Render *re, Render *source, re->winy = winy; if (source && (source->r.mode & R_BORDER)) { /* eeh, doesn't seem original bordered disprect is storing anywhere - * after insertion on black happening in do_render_fields_blur_3d(), + * after insertion on black happening in do_render(), * so for now simply re-calculate disprect using border from source * renderer (sergey) */ @@ -724,9 +689,6 @@ static void re_init_resolution(Render *re, Render *source, re->rectx = winx; re->recty = winy; } - - /* we clip faces with a minimum of 2 pixel boundary outside of image border. see zbuf.c */ - re->clipcrop = 1.0f + 2.0f / (float)(re->winx > re->winy ? re->winy : re->winx); } void render_copy_renderdata(RenderData *to, RenderData *from) @@ -789,23 +751,6 @@ void RE_InitState(Render *re, Render *source, RenderData *rd, re->r.scemode = check_mode_full_sample(&re->r); - /* fullsample wants uniform osa levels */ - if (source && (re->r.scemode & R_FULL_SAMPLE)) { - /* but, if source has no full sample we disable it */ - if ((source->r.scemode & R_FULL_SAMPLE) == 0) - re->r.scemode &= ~R_FULL_SAMPLE; - else - re->r.osa = re->osa = source->osa; - } - else { - /* check state variables, osa? */ - if (re->r.mode & (R_OSA)) { - re->osa = re->r.osa; - if (re->osa > 16) re->osa = 16; - } - else re->osa = 0; - } - if (view_layer) { int index = BLI_findindex(render_layers, view_layer); if (index != -1) { @@ -814,9 +759,6 @@ void RE_InitState(Render *re, Render *source, RenderData *rd, } } - /* always call, checks for gamma, gamma tables and jitter too */ - make_sample_tables(re); - /* if preview render, we try to keep old result */ BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); @@ -867,9 +809,9 @@ void RE_InitState(Render *re, Render *source, RenderData *rd, BLI_rw_mutex_unlock(&re->resultmutex); - re->mblur_offs = re->field_offs = 0.f; - RE_init_threadcount(re); + + RE_point_density_fix_linking(); } /* This function is only called by view3d rendering, which doesn't support @@ -962,7 +904,6 @@ void render_update_anim_renderdata(Render *re, RenderData *rd, ListBase *render_ re->r.gauss = rd->gauss; /* motion blur */ - re->r.mblur_samples = rd->mblur_samples; re->r.blurfac = rd->blurfac; /* freestyle */ @@ -1090,709 +1031,21 @@ void RE_AddObject(Render *UNUSED(re), Object *UNUSED(ob)) /* *************************************** */ -static int render_display_update_enabled(Render *re) -{ - /* don't show preprocess for previewrender sss */ - if (re->sss_points) - return !(re->r.scemode & (R_BUTS_PREVIEW|R_VIEWPORT_PREVIEW)); - else - return 1; -} - -/* the main thread call, renders an entire part */ -static void *do_part_thread(void *pa_v) -{ - RenderPart *pa = pa_v; - - pa->status = PART_STATUS_IN_PROGRESS; - - /* need to return nicely all parts on esc */ - if (R.test_break(R.tbh) == 0) { - - if (!R.sss_points && (R.r.scemode & R_FULL_SAMPLE)) - pa->result = render_result_new_full_sample(&R, &pa->fullresult, &pa->disprect, pa->crop, RR_USE_MEM, R.viewname); - else - pa->result = render_result_new(&R, &pa->disprect, pa->crop, RR_USE_MEM, RR_ALL_LAYERS, R.viewname); - - /* Copy EXR tile settings, so pipeline knows whether this is a result - * for Save Buffers enabled rendering. - * - * TODO(sergey): This actually duplicates logic with external engine, so - * worth looking into more generic solution. - */ - pa->result->do_exr_tile = R.result->do_exr_tile; - - if (R.sss_points) - zbufshade_sss_tile(pa); - else if (R.osa) - zbufshadeDA_tile(pa); - else - zbufshade_tile(pa); - - /* we do actually write pixels, but don't allocate/deallocate anything, - * so it is safe with other threads reading at the same time */ - BLI_rw_mutex_lock(&R.resultmutex, THREAD_LOCK_READ); - - /* merge too on break! */ - if (R.result->do_exr_tile) { - render_result_exr_file_merge(R.result, pa->result, R.viewname); - } - else if (render_display_update_enabled(&R)) { - /* on break, don't merge in result for preview renders, looks nicer */ - if (R.test_break(R.tbh) && (R.r.scemode & (R_BUTS_PREVIEW|R_VIEWPORT_PREVIEW))) { - /* pass */ - } - else { - render_result_merge(R.result, pa->result); - } - } - - BLI_rw_mutex_unlock(&R.resultmutex); - } - - pa->status = PART_STATUS_MERGED; - - return NULL; -} - -/* calculus for how much 1 pixel rendered should rotate the 3d geometry */ -/* is not that simple, needs to be corrected for errors of larger viewplane sizes */ -/* called in initrender.c, RE_parts_init() and convertblender.c, for speedvectors */ -float panorama_pixel_rot(Render *re) -{ - float psize, phi, xfac; - float borderfac = (float)BLI_rcti_size_x(&re->disprect) / (float)re->winx; - int xparts = (re->rectx + re->partx - 1) / re->partx; - - /* size of 1 pixel mapped to viewplane coords */ - psize = BLI_rctf_size_x(&re->viewplane) / (float)re->winx; - /* angle of a pixel */ - phi = atan(psize / re->clipsta); - - /* correction factor for viewplane shifting, first calculate how much the viewplane angle is */ - xfac = borderfac * BLI_rctf_size_x(&re->viewplane) / (float)xparts; - xfac = atan(0.5f * xfac / re->clipsta); - /* and how much the same viewplane angle is wrapped */ - psize = 0.5f * phi * ((float)re->partx); - - /* the ratio applied to final per-pixel angle */ - phi *= xfac / psize; - - return phi; -} - -/* for panorama, we render per Y slice, and update - * camera parameters when we go the next slice */ -static bool find_next_pano_slice(Render *re, int *slice, int *minx, rctf *viewplane) -{ - RenderPart *pa, *best = NULL; - bool found = false; - - *minx = re->winx; - - if (!(re->r.mode & R_PANORAMA)) { - /* for regular render, just one 'slice' */ - found = (*slice == 0); - (*slice)++; - return found; - } - - /* most left part of the non-rendering parts */ - for (pa = re->parts.first; pa; pa = pa->next) { - if (pa->status == PART_STATUS_NONE && pa->nr == 0) { - if (pa->disprect.xmin < *minx) { - found = true; - best = pa; - *minx = pa->disprect.xmin; - } - } - } - - if (best) { - float phi = panorama_pixel_rot(re); - - R.panodxp = (re->winx - (best->disprect.xmin + best->disprect.xmax) ) / 2; - R.panodxv = (BLI_rctf_size_x(viewplane) * R.panodxp) / (float)(re->winx); - - /* shift viewplane */ - R.viewplane.xmin = viewplane->xmin + R.panodxv; - R.viewplane.xmax = viewplane->xmax + R.panodxv; - RE_SetWindow(re, &R.viewplane, R.clipsta, R.clipend); - copy_m4_m4(R.winmat, re->winmat); - - /* rotate database according to part coordinates */ - project_renderdata(re, projectverto, 1, -R.panodxp * phi, 1); - R.panosi = sinf(R.panodxp * phi); - R.panoco = cosf(R.panodxp * phi); - } - - (*slice)++; - - return found; -} - -typedef struct SortRenderPart { - RenderPart *pa; - long long int dist; -} SortRenderPart; - -static int sort_render_part(const void *pa1, const void *pa2) { - const SortRenderPart *rpa1 = pa1; - const SortRenderPart *rpa2 = pa2; - - if (rpa1->dist > rpa2->dist) return 1; - else if (rpa1->dist < rpa2->dist) return -1; - - return 0; -} - -static int sort_and_queue_parts(Render *re, int minx, ThreadQueue *workqueue) -{ - RenderPart *pa; - - /* long long int's needed because of overflow [#24414] */ - long long int centx = re->winx / 2, centy = re->winy / 2, tot = 1; - int totsort = 0; - - /* find center of rendered parts, image center counts for 1 too */ - for (pa = re->parts.first; pa; pa = pa->next) { - if (pa->status >= PART_STATUS_RENDERED) { - centx += BLI_rcti_cent_x(&pa->disprect); - centy += BLI_rcti_cent_y(&pa->disprect); - tot++; - } - else if (pa->status == PART_STATUS_NONE && pa->nr == 0) { - if (!(re->r.mode & R_PANORAMA) || pa->disprect.xmin == minx) { - totsort++; - } - } - } - centx /= tot; - centy /= tot; - - if (totsort > 0) { - SortRenderPart *sortlist = MEM_mallocN(sizeof(*sortlist) * totsort, "renderpartsort"); - long int i = 0; - - /* prepare the list */ - for (pa = re->parts.first; pa; pa = pa->next) { - if (pa->status == PART_STATUS_NONE && pa->nr == 0) { - if (!(re->r.mode & R_PANORAMA) || pa->disprect.xmin == minx) { - long long int distx = centx - BLI_rcti_cent_x(&pa->disprect); - long long int disty = centy - BLI_rcti_cent_y(&pa->disprect); - sortlist[i].dist = (long long int)sqrt(distx * distx + disty * disty); - sortlist[i].pa = pa; - i++; - } - } - } - - /* Now sort it */ - qsort(sortlist, totsort, sizeof(*sortlist), sort_render_part); - - /* Finally flush it to the workqueue */ - for (i = 0; i < totsort; i++) { - pa = sortlist[i].pa; - pa->nr = i + 1; /* for nicest part, and for stats */ - BLI_thread_queue_push(workqueue, pa); - } - - MEM_freeN(sortlist); - - return totsort; - } - - return 0; -} - -static void print_part_stats(Render *re, RenderPart *pa) -{ - char str[64]; - - BLI_snprintf(str, sizeof(str), IFACE_("%s, Part %d-%d"), re->scene->id.name + 2, pa->nr, re->i.totpart); - re->i.infostr = str; - re->stats_draw(re->sdh, &re->i); - re->i.infostr = NULL; -} - -typedef struct RenderThread { - ThreadQueue *workqueue; - ThreadQueue *donequeue; - - int number; - - void (*display_update)(void *handle, RenderResult *rr, volatile rcti *rect); - void *duh; -} RenderThread; - -static void *do_render_thread(void *thread_v) -{ - RenderThread *thread = thread_v; - RenderPart *pa; - - while ((pa = BLI_thread_queue_pop(thread->workqueue))) { - pa->thread = thread->number; - do_part_thread(pa); - - if (thread->display_update) { - thread->display_update(thread->duh, pa->result, NULL); - } - - BLI_thread_queue_push(thread->donequeue, pa); - - if (R.test_break(R.tbh)) - break; - } - - return NULL; -} - -static void UNUSED_FUNCTION(main_render_result_end)(Render *re) -{ - if (re->result->do_exr_tile) { - BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); - render_result_exr_file_end(re); - BLI_rw_mutex_unlock(&re->resultmutex); - } - - if (re->r.scemode & R_EXR_CACHE_FILE) { - BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); - render_result_exr_file_cache_write(re); - BLI_rw_mutex_unlock(&re->resultmutex); - } -} - -static void main_render_result_new(Render *re) -{ - BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); - - /* first step; free the entire render result, make new, and/or prepare exr buffer saving */ - if (re->result == NULL || !(re->r.scemode & (R_BUTS_PREVIEW|R_VIEWPORT_PREVIEW))) { - render_result_free(re->result); - - if (re->sss_points && render_display_update_enabled(re)) - re->result = render_result_new(re, &re->disprect, 0, RR_USE_MEM, RR_ALL_LAYERS, RR_ALL_VIEWS); - else if (re->r.scemode & R_FULL_SAMPLE) - re->result = render_result_new_full_sample(re, &re->fullresult, &re->disprect, 0, RR_USE_EXR, RR_ALL_VIEWS); - else - re->result = render_result_new(re, &re->disprect, 0, - (re->r.scemode & R_EXR_TILE_FILE) ? RR_USE_EXR : RR_USE_MEM, RR_ALL_LAYERS, RR_ALL_VIEWS); - } - - BLI_rw_mutex_unlock(&re->resultmutex); - - if (re->result) { - if (re->result->do_exr_tile) { - render_result_exr_file_begin(re); - } - } -} - -static void threaded_tile_processor(Render *re) -{ - RenderThread thread[BLENDER_MAX_THREADS]; - ThreadQueue *workqueue, *donequeue; - ListBase threads; - RenderPart *pa; - rctf viewplane = re->viewplane; - double lastdraw, elapsed, redrawtime = 1.0f; - int totpart = 0, minx = 0, slice = 0, a, wait; - - if (re->result == NULL) - return; - - /* warning; no return here without closing exr file */ - RE_parts_init(re, true); - - /* assuming no new data gets added to dbase... */ - R = *re; - - /* set threadsafe break */ - R.test_break = thread_break; - - /* create and fill work queue */ - workqueue = BLI_thread_queue_init(); - donequeue = BLI_thread_queue_init(); - - /* for panorama we loop over slices */ - while (find_next_pano_slice(re, &slice, &minx, &viewplane)) { - /* gather parts into queue */ - totpart = sort_and_queue_parts(re, minx, workqueue); - - BLI_thread_queue_nowait(workqueue); - - /* start all threads */ - BLI_threadpool_init(&threads, do_render_thread, re->r.threads); - - for (a = 0; a < re->r.threads; a++) { - thread[a].workqueue = workqueue; - thread[a].donequeue = donequeue; - thread[a].number = a; - - if (render_display_update_enabled(re)) { - thread[a].display_update = re->display_update; - thread[a].duh = re->duh; - } - else { - thread[a].display_update = NULL; - thread[a].duh = NULL; - } - - BLI_threadpool_insert(&threads, &thread[a]); - } - - /* wait for results to come back */ - lastdraw = PIL_check_seconds_timer(); - - while (1) { - elapsed = PIL_check_seconds_timer() - lastdraw; - wait = (redrawtime - elapsed)*1000; - - /* handle finished part */ - if ((pa=BLI_thread_queue_pop_timeout(donequeue, wait))) { - if (pa->result) { - print_part_stats(re, pa); - - render_result_free_list(&pa->fullresult, pa->result); - pa->result = NULL; - re->i.partsdone++; - re->progress(re->prh, re->i.partsdone / (float)re->i.totpart); - } - - totpart--; - } - - /* check for render cancel */ - if ((g_break=re->test_break(re->tbh))) - break; - - /* or done with parts */ - if (totpart == 0) - break; - - /* redraw in progress parts */ - elapsed = PIL_check_seconds_timer() - lastdraw; - if (elapsed > redrawtime) { - if (render_display_update_enabled(re)) - for (pa = re->parts.first; pa; pa = pa->next) - if ((pa->status == PART_STATUS_IN_PROGRESS) && pa->nr && pa->result) - re->display_update(re->duh, pa->result, &pa->result->renrect); - - lastdraw = PIL_check_seconds_timer(); - } - } - - BLI_threadpool_end(&threads); - - if ((g_break=re->test_break(re->tbh))) - break; - } - - if (g_break) { - /* review the done queue and handle all the render parts, - * so no unfreed render result are lurking around - */ - BLI_thread_queue_nowait(donequeue); - while ((pa = BLI_thread_queue_pop(donequeue))) { - if (pa->result) { - render_result_free_list(&pa->fullresult, pa->result); - pa->result = NULL; - } - } - } - - BLI_thread_queue_free(donequeue); - BLI_thread_queue_free(workqueue); - - if (re->result->do_exr_tile) { - BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); - render_result_save_empty_result_tiles(re); - BLI_rw_mutex_unlock(&re->resultmutex); - } - - /* unset threadsafety */ - g_break = 0; - BLI_rw_mutex_lock(&re->partsmutex, THREAD_LOCK_WRITE); - RE_parts_free(re); - BLI_rw_mutex_unlock(&re->partsmutex); - re->viewplane = viewplane; /* restore viewplane, modified by pano render */ -} - #ifdef WITH_FREESTYLE static void init_freestyle(Render *re); static void add_freestyle(Render *re, int render); static void free_all_freestyle_renders(void); #endif -/* currently only called by preview renders and envmap */ -void RE_TileProcessor(Render *re) -{ - main_render_result_new(re); - threaded_tile_processor(re); - - re->i.lastframetime = PIL_check_seconds_timer() - re->i.starttime; - re->stats_draw(re->sdh, &re->i); - -#ifdef WITH_FREESTYLE - /* Freestyle */ - if (re->r.mode & R_EDGE_FRS) { - if (!re->test_break(re->tbh)) { - init_freestyle(re); - add_freestyle(re, 1); - free_all_freestyle_renders(); - - re->i.lastframetime = PIL_check_seconds_timer() - re->i.starttime; - re->stats_draw(re->sdh, &re->i); - } - } -#endif - -} /* ************ This part uses API, for rendering Blender scenes ********** */ static void do_render_3d(Render *re) { re->current_scene_update(re->suh, re->scene); - - /* All the rendering pipeline goes through "external" render engines. */ RE_engine_render(re, 0); } -/* called by blur loop, accumulate RGBA key alpha */ -static void addblur_rect_key(RenderResult *rr, float *rectf, float *rectf1, float blurfac) -{ - float mfac = 1.0f - blurfac; - int a, b, stride = 4 * rr->rectx; - int len = stride * sizeof(float); - - for (a = 0; a < rr->recty; a++) { - if (blurfac == 1.0f) { - memcpy(rectf, rectf1, len); - } - else { - float *rf = rectf, *rf1 = rectf1; - - for (b = rr->rectx; b > 0; b--, rf += 4, rf1 += 4) { - if (rf1[3] < 0.01f) - rf[3] = mfac * rf[3]; - else if (rf[3] < 0.01f) { - rf[0] = rf1[0]; - rf[1] = rf1[1]; - rf[2] = rf1[2]; - rf[3] = blurfac * rf1[3]; - } - else { - rf[0] = mfac * rf[0] + blurfac * rf1[0]; - rf[1] = mfac * rf[1] + blurfac * rf1[1]; - rf[2] = mfac * rf[2] + blurfac * rf1[2]; - rf[3] = mfac * rf[3] + blurfac * rf1[3]; - } - } - } - rectf += stride; - rectf1 += stride; - } -} - -/* called by blur loop, accumulate renderlayers */ -static void addblur_rect(RenderResult *rr, float *rectf, float *rectf1, float blurfac, int channels) -{ - float mfac = 1.0f - blurfac; - int a, b, stride = channels * rr->rectx; - int len = stride * sizeof(float); - - for (a = 0; a < rr->recty; a++) { - if (blurfac == 1.0f) { - memcpy(rectf, rectf1, len); - } - else { - float *rf = rectf, *rf1 = rectf1; - - for (b = rr->rectx * channels; b > 0; b--, rf++, rf1++) { - rf[0] = mfac * rf[0] + blurfac * rf1[0]; - } - } - rectf += stride; - rectf1 += stride; - } -} - - -/* called by blur loop, accumulate renderlayers */ -static void merge_renderresult_blur(RenderResult *rr, RenderResult *brr, float blurfac, bool key_alpha) -{ - RenderLayer *rl, *rl1; - RenderPass *rpass, *rpass1; - - rl1 = brr->layers.first; - for (rl = rr->layers.first; rl && rl1; rl = rl->next, rl1 = rl1->next) { - /* passes are allocated in sync */ - rpass1 = rl1->passes.first; - for (rpass = rl->passes.first; rpass && rpass1; rpass = rpass->next, rpass1 = rpass1->next) { - if (STREQ(rpass->name, RE_PASSNAME_COMBINED) && key_alpha) - addblur_rect_key(rr, rpass->rect, rpass1->rect, blurfac); - else - addblur_rect(rr, rpass->rect, rpass1->rect, blurfac, rpass->channels); - } - } -} - -/* main blur loop, can be called by fields too */ -static void do_render_blur_3d(Render *re) -{ - RenderResult *rres; - float blurfac; - int blur = re->r.mblur_samples; - - /* create accumulation render result */ - rres = render_result_new(re, &re->disprect, 0, RR_USE_MEM, RR_ALL_LAYERS, RR_ALL_VIEWS); - - /* do the blur steps */ - while (blur--) { - re->mblur_offs = re->r.blurfac * ((float)(re->r.mblur_samples - blur)) / (float)re->r.mblur_samples; - - re->i.curblur = re->r.mblur_samples - blur; /* stats */ - - do_render_3d(re); - - blurfac = 1.0f / (float)(re->r.mblur_samples - blur); - - merge_renderresult_blur(rres, re->result, blurfac, false); - if (re->test_break(re->tbh)) break; - } - - /* swap results */ - BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); - render_result_free(re->result); - re->result = rres; - BLI_rw_mutex_unlock(&re->resultmutex); - - re->mblur_offs = 0.0f; - re->i.curblur = 0; /* stats */ - - /* weak... the display callback wants an active renderlayer pointer... */ - re->result->renlay = render_get_active_layer(re, re->result); - re->display_update(re->duh, re->result, NULL); -} - - -/* function assumes rectf1 and rectf2 to be half size of rectf */ -static void interleave_rect(RenderResult *rr, float *rectf, float *rectf1, float *rectf2, int channels) -{ - int a, stride = channels * rr->rectx; - int len = stride * sizeof(float); - - for (a = 0; a < rr->recty; a += 2) { - memcpy(rectf, rectf1, len); - rectf += stride; - rectf1 += stride; - memcpy(rectf, rectf2, len); - rectf += stride; - rectf2 += stride; - } -} - -/* merge render results of 2 fields */ -static void merge_renderresult_fields(RenderResult *rr, RenderResult *rr1, RenderResult *rr2) -{ - RenderLayer *rl, *rl1, *rl2; - RenderPass *rpass, *rpass1, *rpass2; - - rl1 = rr1->layers.first; - rl2 = rr2->layers.first; - for (rl = rr->layers.first; rl && rl1 && rl2; rl = rl->next, rl1 = rl1->next, rl2 = rl2->next) { - - /* passes are allocated in sync */ - rpass1 = rl1->passes.first; - rpass2 = rl2->passes.first; - for (rpass = rl->passes.first; - rpass && rpass1 && rpass2; - rpass = rpass->next, rpass1 = rpass1->next, rpass2 = rpass2->next) - { - interleave_rect(rr, rpass->rect, rpass1->rect, rpass2->rect, rpass->channels); - } - } -} - - -/* interleaves 2 frames */ -static void do_render_fields_3d(Render *re) -{ - Object *camera = RE_GetCamera(re); - RenderResult *rr1, *rr2 = NULL; - - /* no render result was created, we can safely halve render y */ - re->winy /= 2; - re->recty /= 2; - re->disprect.ymin /= 2; - re->disprect.ymax /= 2; - - re->i.curfield = 1; /* stats */ - - /* first field, we have to call camera routine for correct aspect and subpixel offset */ - RE_SetCamera(re, camera); - if (re->r.mode & R_MBLUR && (re->r.scemode & R_FULL_SAMPLE) == 0) - do_render_blur_3d(re); - else - do_render_3d(re); - - BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); - rr1 = re->result; - re->result = NULL; - BLI_rw_mutex_unlock(&re->resultmutex); - - /* second field */ - if (!re->test_break(re->tbh)) { - - re->i.curfield = 2; /* stats */ - - re->flag |= R_SEC_FIELD; - if ((re->r.mode & R_FIELDSTILL) == 0) { - re->field_offs = 0.5f; - } - RE_SetCamera(re, camera); - if (re->r.mode & R_MBLUR && (re->r.scemode & R_FULL_SAMPLE) == 0) - do_render_blur_3d(re); - else - do_render_3d(re); - re->flag &= ~R_SEC_FIELD; - - re->field_offs = 0.0f; - - rr2 = re->result; - } - - /* allocate original height new buffers */ - re->winy *= 2; - re->recty *= 2; - re->disprect.ymin *= 2; - re->disprect.ymax *= 2; - - BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); - re->result = render_result_new(re, &re->disprect, 0, RR_USE_MEM, RR_ALL_LAYERS, RR_ALL_VIEWS); - - if (rr2) { - if (re->r.mode & R_ODDFIELD) - merge_renderresult_fields(re->result, rr2, rr1); - else - merge_renderresult_fields(re->result, rr1, rr2); - - render_result_free(rr2); - } - - render_result_free(rr1); - - re->i.curfield = 0; /* stats */ - - /* weak... the display callback wants an active renderlayer pointer... */ - re->result->renlay = render_get_active_layer(re, re->result); - - BLI_rw_mutex_unlock(&re->resultmutex); - - re->display_update(re->duh, re->result, NULL); -} - /* make sure disprect is not affected by the render border */ static void render_result_disprect_to_full_resolution(Render *re) { @@ -1853,7 +1106,7 @@ static void render_result_uncrop(Render *re) } /* main render routine, no compositing */ -static void do_render_fields_blur_3d(Render *re) +static void do_render(Render *re) { Object *camera = RE_GetCamera(re); /* also check for camera here */ @@ -1866,12 +1119,7 @@ static void do_render_fields_blur_3d(Render *re) /* now use renderdata and camera to set viewplane */ RE_SetCamera(re, camera); - if (re->r.mode & R_FIELDS) - do_render_fields_3d(re); - else if (re->r.mode & R_MBLUR && (re->r.scemode & R_FULL_SAMPLE) == 0) - do_render_blur_3d(re); - else - do_render_3d(re); + do_render_3d(re); /* when border render, check if we have to insert it in black */ render_result_uncrop(re); @@ -1906,7 +1154,6 @@ static void render_scene(Render *re, Scene *sce, int cfra) resc->main = re->main; resc->scene = sce; resc->lay = sce->lay; - resc->scene_color_manage = BKE_scene_check_color_management_enabled(sce); /* ensure scene has depsgraph, base flags etc OK */ BKE_scene_set_background(re->main, sce); @@ -1921,7 +1168,7 @@ static void render_scene(Render *re, Scene *sce, int cfra) resc->current_scene_update = re->current_scene_update; resc->suh = re->suh; - do_render_fields_blur_3d(resc); + do_render(resc); } /* helper call to detect if this scene needs a render, or if there's a any render layer to render */ @@ -2189,12 +1436,14 @@ static void ntree_render_scenes(Render *re) } /* bad call... need to think over proper method still */ -static void render_composit_stats(void *UNUSED(arg), const char *str) +static void render_composit_stats(void *arg, const char *str) { + Render *re = (Render*)arg; + RenderStats i; - memcpy(&i, &R.i, sizeof(i)); + memcpy(&i, &re->i, sizeof(i)); i.infostr = str; - R.stats_draw(R.sdh, &i); + re->stats_draw(re->sdh, &i); } #ifdef WITH_FREESTYLE @@ -2221,63 +1470,24 @@ static void add_freestyle(Render *re, int render) ViewLayer *view_layer, *active_view_layer; LinkData *link; Render *r; - const bool do_link = (re->r.mode & R_MBLUR) == 0 || re->i.curblur == re->r.mblur_samples; active_view_layer = BLI_findlink(&re->view_layers, re->active_view_layer); FRS_begin_stroke_rendering(re); for (view_layer = (ViewLayer *)re->view_layers.first; view_layer; view_layer = view_layer->next) { - if (do_link) { - link = (LinkData *)MEM_callocN(sizeof(LinkData), "LinkData to Freestyle render"); - BLI_addtail(&re->freestyle_renders, link); - } + link = (LinkData *)MEM_callocN(sizeof(LinkData), "LinkData to Freestyle render"); + BLI_addtail(&re->freestyle_renders, link); + if ((re->r.scemode & R_SINGLE_LAYER) && view_layer != active_view_layer) continue; if (FRS_is_freestyle_enabled(view_layer)) { r = FRS_do_stroke_rendering(re, view_layer, render); - if (do_link) - link->data = (void *)r; + link->data = (void *)r; } } FRS_end_stroke_rendering(re); - - /* restore the global R value (invalidated by nested execution of the internal renderer) */ - R = *re; -} - -/* merges the results of Freestyle stroke rendering into a given render result */ -static void composite_freestyle_renders(Render *re, int sample) -{ - Render *freestyle_render; - RenderView *rv; - ViewLayer *view_layer, *active_view_layer; - LinkData *link; - - active_view_layer = BLI_findlink(&re->view_layers, re->active_view_layer); - - link = (LinkData *)re->freestyle_renders.first; - - for (rv = re->result->views.first; rv; rv = rv->next) { - for (view_layer = (ViewLayer *)re->view_layers.first; view_layer; view_layer = view_layer->next) { - if ((re->r.scemode & R_SINGLE_LAYER) && view_layer != active_view_layer) - continue; - - if (FRS_is_freestyle_enabled(view_layer)) { - freestyle_render = (Render *)link->data; - - /* may be NULL in case of empty render layer */ - if (freestyle_render) { - render_result_exr_file_read_sample(freestyle_render, sample); - FRS_composite_result(re, view_layer, freestyle_render); - RE_FreeRenderResult(freestyle_render->result); - freestyle_render->result = NULL; - } - } - link = link->next; - } - } } /* releases temporary scenes and renders for Freestyle stroke rendering */ @@ -2313,238 +1523,8 @@ static void free_all_freestyle_renders(void) } #endif -/* reads all buffers, calls optional composite, merges in first result->views rectf */ -static void do_merge_fullsample(Render *re, bNodeTree *ntree) -{ - ListBase *rectfs; - RenderView *rv; - rcti filter_mask = re->disprect; - float *rectf, filt[3][3]; - int x, y, sample; - int nr, numviews; - - /* interaction callbacks */ - if (ntree) { - ntree->stats_draw = render_composit_stats; - ntree->test_break = re->test_break; - ntree->progress = re->progress; - ntree->sdh = re->sdh; - ntree->tbh = re->tbh; - ntree->prh = re->prh; - } - - /* filtmask needs it */ - R = *re; - - /* temporary storage of the acccumulation buffers */ - rectfs = MEM_callocN(sizeof(ListBase), "fullsample accumulation buffers"); - - numviews = BLI_listbase_count(&re->result->views); - for (nr = 0; nr < numviews; nr++) { - rv = MEM_callocN(sizeof(RenderView), "fullsample renderview"); - - /* we accumulate in here */ - rv->rectf = MEM_mapallocN(re->result->rectx * re->result->recty * sizeof(float) * 4, "fullsample rgba"); - BLI_addtail(rectfs, rv); - } - - for (sample = 0; sample < re->r.osa; sample++) { - Scene *sce; - Render *re1; - RenderResult rres; - int mask; - - /* enable full sample print */ - R.i.curfsa = sample + 1; - - /* set all involved renders on the samplebuffers (first was done by render itself, but needs tagged) */ - /* also function below assumes this */ - - tag_scenes_for_render(re); - for (sce = re->main->scene.first; sce; sce = sce->id.next) { - if (sce->id.tag & LIB_TAG_DOIT) { - re1 = RE_GetSceneRender(sce); - - if (re1 && (re1->r.scemode & R_FULL_SAMPLE)) { - if (sample) { - BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); - render_result_exr_file_read_sample(re1, sample); -#ifdef WITH_FREESTYLE - if (re1->r.mode & R_EDGE_FRS) - composite_freestyle_renders(re1, sample); -#endif - BLI_rw_mutex_unlock(&re->resultmutex); - render_result_uncrop(re1); - } - ntreeCompositTagRender(re1->scene); /* ensure node gets exec to put buffers on stack */ - } - } - } - -#ifdef DEPSGRAPH_WORKAROUND_GROUP_HACK - tag_groups_for_render(re); -#endif - - /* composite */ - if (ntree) { - ntreeCompositTagRender(re->scene); - ntreeCompositTagAnimated(ntree); - - for (rv = re->result->views.first; rv; rv = rv->next) { - ntreeCompositExecTree(re->scene, ntree, &re->r, true, G.background == 0, &re->scene->view_settings, &re->scene->display_settings, rv->name); - } - } - - for (nr = 0, rv = rectfs->first; rv; rv = rv->next, nr++) { - rectf = rv->rectf; - - /* ensure we get either composited result or the active layer */ - RE_AcquireResultImage(re, &rres, nr); - - /* accumulate with filter, and clip */ - mask = (1 << sample); - mask_array(mask, filt); - - for (y = 0; y < re->result->recty; y++) { - float *rf = rectf + 4 * y * re->result->rectx; - float *col = rres.rectf + 4 * y * re->result->rectx; - - for (x = 0; x < re->result->rectx; x++, rf += 4, col += 4) { - /* clamping to 1.0 is needed for correct AA */ - CLAMP(col[0], 0.0f, 1.0f); - CLAMP(col[1], 0.0f, 1.0f); - CLAMP(col[2], 0.0f, 1.0f); - - add_filt_fmask_coord(filt, col, rf, re->result->rectx, x, y, &filter_mask); - } - } - - RE_ReleaseResultImage(re); - - /* show stuff */ - if (sample != re->osa - 1) { - /* weak... the display callback wants an active renderlayer pointer... */ - re->result->renlay = render_get_active_layer(re, re->result); - RE_SetActiveRenderView(re, rv->name); - re->display_update(re->duh, re->result, NULL); - } - } - } - - for (nr = 0; nr < numviews; nr++) { - rectf = ((RenderView *)BLI_findlink(rectfs, nr))->rectf; - - /* clamp alpha and RGB to 0..1 and 0..inf, can go outside due to filter */ - for (y = 0; y < re->result->recty; y++) { - float *rf = rectf + 4 * y * re->result->rectx; - - for (x = 0; x < re->result->rectx; x++, rf += 4) { - rf[0] = MAX2(rf[0], 0.0f); - rf[1] = MAX2(rf[1], 0.0f); - rf[2] = MAX2(rf[2], 0.0f); - CLAMP(rf[3], 0.0f, 1.0f); - } - } - - /* store the final result */ - BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); - rv = RE_RenderViewGetById(re->result, nr); - if (rv->rectf) - MEM_freeN(rv->rectf); - rv->rectf = rectf; - BLI_rw_mutex_unlock(&re->resultmutex); - } - - /* clear interaction callbacks */ - if (ntree) { - ntree->stats_draw = NULL; - ntree->test_break = NULL; - ntree->progress = NULL; - ntree->tbh = ntree->sdh = ntree->prh = NULL; - } - - /* disable full sample print */ - R.i.curfsa = 0; - - /* garbage collection */ - while (rectfs->first) { - rv = rectfs->first; - BLI_remlink(rectfs, rv); - MEM_freeN(rv); - } - MEM_freeN(rectfs); -} - -/* called externally, via compositor */ -void RE_MergeFullSample(Render *re, Main *bmain, Scene *sce, bNodeTree *ntree) -{ - Scene *scene; - bNode *node; - - /* default start situation */ - G.is_break = false; - - re->main = bmain; - re->scene = sce; - re->scene_color_manage = BKE_scene_check_color_management_enabled(sce); - - /* first call RE_ReadRenderResult on every renderlayer scene. this creates Render structs */ - - /* tag scenes unread */ - for (scene = re->main->scene.first; scene; scene = scene->id.next) - scene->id.tag |= LIB_TAG_DOIT; - -#ifdef WITH_FREESTYLE - if (re->freestyle_bmain) { - for (scene = re->freestyle_bmain->scene.first; scene; scene = scene->id.next) - scene->id.tag &= ~LIB_TAG_DOIT; - } -#endif - - for (node = ntree->nodes.first; node; node = node->next) { - if (node->type == CMP_NODE_R_LAYERS && (node->flag & NODE_MUTED) == 0) { - Scene *nodescene = (Scene *)node->id; - - if (nodescene == NULL) nodescene = sce; - if (nodescene->id.tag & LIB_TAG_DOIT) { - nodescene->r.mode |= R_OSA; /* render struct needs tables */ - RE_ReadRenderResult(sce, nodescene); - nodescene->id.tag &= ~LIB_TAG_DOIT; - } - } - } - - /* own render result should be read/allocated */ - if (re->scene->id.tag & LIB_TAG_DOIT) { - RE_ReadRenderResult(re->scene, re->scene); - re->scene->id.tag &= ~LIB_TAG_DOIT; - } - - /* and now we can draw (result is there) */ - re->display_init(re->dih, re->result); - re->display_clear(re->dch, re->result); - -#ifdef WITH_FREESTYLE - if (re->r.mode & R_EDGE_FRS) { - init_freestyle(re); - add_freestyle(re, 0); - } -#endif - - do_merge_fullsample(re, ntree); - -#ifdef WITH_FREESTYLE - free_all_freestyle_renders(); -#endif - -#ifdef DEPSGRAPH_WORKAROUND_GROUP_HACK - /* Restore their visibility based on the viewport visibility flags. */ - tag_groups_for_render(re); -#endif -} - /* returns fully composited render-result on given time step (in RenderData) */ -static void do_render_composite_fields_blur_3d(Render *re) +static void do_render_composite(Render *re) { bNodeTree *ntree = re->scene->nodetree; int update_newframe = 0; @@ -2560,7 +1540,7 @@ static void do_render_composite_fields_blur_3d(Render *re) * it could be optimized to render only the needed view * but what if a scene has a different number of views * than the main scene? */ - do_render_fields_blur_3d(re); + do_render(re); } else { re->i.cfra = re->r.cfra; @@ -2603,27 +1583,17 @@ static void do_render_composite_fields_blur_3d(Render *re) ntree->stats_draw = render_composit_stats; ntree->test_break = re->test_break; ntree->progress = re->progress; - ntree->sdh = re->sdh; + ntree->sdh = re; ntree->tbh = re->tbh; ntree->prh = re->prh; - /* in case it was never initialized */ - R.sdh = re->sdh; - R.stats_draw = re->stats_draw; - R.i.starttime = re->i.starttime; - R.i.cfra = re->i.cfra; - if (update_newframe) { /* If we have consistent depsgraph now would be a time to update them. */ } - if (re->r.scemode & R_FULL_SAMPLE) - do_merge_fullsample(re, ntree); - else { - RenderView *rv; - for (rv = re->result->views.first; rv; rv = rv->next) { - ntreeCompositExecTree(re->scene, ntree, &re->r, true, G.background == 0, &re->scene->view_settings, &re->scene->display_settings, rv->name); - } + RenderView *rv; + for (rv = re->result->views.first; rv; rv = rv->next) { + ntreeCompositExecTree(re->scene, ntree, &re->r, true, G.background == 0, &re->scene->view_settings, &re->scene->display_settings, rv->name); } ntree->stats_draw = NULL; @@ -2632,8 +1602,6 @@ static void do_render_composite_fields_blur_3d(Render *re) ntree->tbh = ntree->sdh = ntree->prh = NULL; } } - else if (re->r.scemode & R_FULL_SAMPLE) - do_merge_fullsample(re, NULL); } #ifdef WITH_FREESTYLE @@ -2804,7 +1772,7 @@ static void do_render_seq(Render *re) /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -/* main loop: doing sequence + fields + blur + 3d render + compositing */ +/* main loop: doing sequence + 3d render + compositing */ static void do_render_all_options(Render *re) { Object *camera; @@ -2834,12 +1802,7 @@ static void do_render_all_options(Render *re) re->display_update(re->duh, re->result, NULL); } else { - re->pool = BKE_image_pool_new(); - - do_render_composite_fields_blur_3d(re); - - BKE_image_pool_free(re->pool); - re->pool = NULL; + do_render_composite(re); } re->i.lastframetime = PIL_check_seconds_timer() - re->i.starttime; @@ -3032,13 +1995,6 @@ bool RE_is_rendering_allowed(Scene *scene, Object *camera_override, ReportList * BKE_report(reports, RPT_ERROR, "Cannot save render buffers, check the temp default path"); return 0; } - - /* no fullsample and edge */ - if ((scemode & R_FULL_SAMPLE) && (scene->r.mode & R_EDGE)) { - BKE_report(reports, RPT_ERROR, "Full sample does not support edge enhance"); - return 0; - } - } if (scemode & R_DOCOMP) { @@ -3085,15 +2041,6 @@ bool RE_is_rendering_allowed(Scene *scene, Object *camera_override, ReportList * #endif } -#ifdef WITH_FREESTYLE - if (scene->r.mode & R_EDGE_FRS) { - if (scene->r.mode & R_FIELDS) { - BKE_report(reports, RPT_ERROR, "Fields not supported in Freestyle"); - return false; - } - } -#endif - if (RE_seq_render_active(scene, &scene->r)) { if (scene->r.mode & R_BORDER) { BKE_report(reports, RPT_ERROR, "Border rendering is not supported by sequencer"); @@ -3112,16 +2059,9 @@ bool RE_is_rendering_allowed(Scene *scene, Object *camera_override, ReportList * static void validate_render_settings(Render *re) { - if (re->r.scemode & (R_EXR_TILE_FILE | R_FULL_SAMPLE)) { - /* no osa + fullsample won't work... */ - if (re->r.osa == 0) - re->r.scemode &= ~R_FULL_SAMPLE; - } - if (RE_engine_is_external(re)) { /* not supported yet */ re->r.scemode &= ~(R_FULL_SAMPLE); - re->r.mode &= ~(R_FIELDS | R_MBLUR); } } @@ -3183,7 +2123,6 @@ static int render_initialize_from_main(Render *re, RenderData *rd, Main *bmain, re->main = bmain; re->scene = scene; - re->scene_color_manage = BKE_scene_check_color_management_enabled(scene); re->camera_override = camera_override; re->lay = lay_override ? lay_override : scene->lay; re->layer_override = lay_override; @@ -3296,7 +2235,7 @@ void RE_RenderFreestyleStrokes(Render *re, Main *bmain, Scene *scene, int render re->result_ok= 0; if (render_initialize_from_main(re, &scene->r, bmain, scene, NULL, NULL, scene->lay, 0, 0)) { if (render) - do_render_fields_blur_3d(re); + do_render_3d(re); } re->result_ok = 1; } @@ -3310,7 +2249,28 @@ void RE_RenderFreestyleExternal(Render *re) for (rv = re->result->views.first; rv; rv = rv->next) { RE_SetActiveRenderView(re, rv->name); - RE_Database_CameraOnly(re, re->main, re->scene, re->lay, 1); + + /* scene needs to be set to get camera */ + Object *camera = RE_GetCamera(re); + + /* if no camera, viewmat should have been set! */ + if (camera) { + /* called before but need to call again in case of lens animation from the + * above call to BKE_scene_graph_update_for_newframe, fixes bug. [#22702]. + * following calls don't depend on 'RE_SetCamera' */ + float mat[4][4]; + + RE_SetCamera(re, camera); + RE_GetCameraModelMatrix(re, camera, mat); + invert_m4(mat); + RE_SetView(re, mat); + + /* force correct matrix for scaled cameras */ + DEG_id_tag_update_ex(re->main, &camera->id, OB_RECALC_OB); + } + + printf("add freestyle\n"); + add_freestyle(re, 1); } } @@ -3838,20 +2798,14 @@ void RE_PreviewRender(Render *re, Main *bmain, Scene *sce) RE_InitState(re, NULL, &sce->r, &sce->view_layers, sce->active_view_layer, NULL, winx, winy, NULL); - re->pool = BKE_image_pool_new(); - re->main = bmain; re->scene = sce; - re->scene_color_manage = BKE_scene_check_color_management_enabled(sce); re->lay = sce->lay; camera = RE_GetCamera(re); RE_SetCamera(re, camera); do_render_3d(re); - - BKE_image_pool_free(re->pool); - re->pool = NULL; } /* note; repeated win/disprect calc... solve that nicer, also in compo */ @@ -3891,7 +2845,6 @@ bool RE_ReadRenderResult(Scene *scene, Scene *scenode) re = RE_NewSceneRender(scene); RE_InitState(re, NULL, &scene->r, &scene->view_layers, scene->active_view_layer, NULL, winx, winy, &disprect); re->scene = scene; - re->scene_color_manage = BKE_scene_check_color_management_enabled(scene); BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); success = render_result_exr_file_cache_read(re); @@ -3968,67 +2921,6 @@ void RE_result_load_from_file(RenderResult *result, ReportList *reports, const c } } -const float default_envmap_layout[] = { 0, 0, 1, 0, 2, 0, 0, 1, 1, 1, 2, 1 }; - -bool RE_WriteEnvmapResult(struct ReportList *reports, Scene *scene, EnvMap *env, const char *relpath, const char imtype, float layout[12]) -{ - ImageFormatData imf; - ImBuf *ibuf = NULL; - int ok; - int dx; - int maxX = 0, maxY = 0, i = 0; - char filepath[FILE_MAX]; - - if (env->cube[1] == NULL) { - BKE_report(reports, RPT_ERROR, "There is no generated environment map available to save"); - return 0; - } - - imf = scene->r.im_format; - imf.imtype = imtype; - - dx = env->cube[1]->x; - - if (env->type == ENV_CUBE) { - for (i = 0; i < 12; i += 2) { - maxX = max_ii(maxX, (int)layout[i] + 1); - maxY = max_ii(maxY, (int)layout[i + 1] + 1); - } - - ibuf = IMB_allocImBuf(maxX * dx, maxY * dx, 24, IB_rectfloat); - - for (i = 0; i < 12; i += 2) - if (layout[i] > -1 && layout[i + 1] > -1) - IMB_rectcpy(ibuf, env->cube[i / 2], layout[i] * dx, layout[i + 1] * dx, 0, 0, dx, dx); - } - else if (env->type == ENV_PLANE) { - ibuf = IMB_allocImBuf(dx, dx, 24, IB_rectfloat); - IMB_rectcpy(ibuf, env->cube[1], 0, 0, 0, 0, dx, dx); - } - else { - BKE_report(reports, RPT_ERROR, "Invalid environment map type"); - return 0; - } - - IMB_colormanagement_imbuf_for_write(ibuf, true, false, &scene->view_settings, &scene->display_settings, &imf); - - /* to save, we first get absolute path */ - BLI_strncpy(filepath, relpath, sizeof(filepath)); - BLI_path_abs(filepath, G.main->name); - - ok = BKE_imbuf_write(ibuf, filepath, &imf); - - IMB_freeImBuf(ibuf); - - if (ok) { - return true; - } - else { - BKE_report(reports, RPT_ERROR, "Error writing environment map"); - return false; - } -} - /* Used in the interface to decide whether to show layers or passes. */ bool RE_layers_have_name(struct RenderResult *rr) { diff --git a/source/blender/render/intern/source/pixelblending.c b/source/blender/render/intern/source/pixelblending.c deleted file mode 100644 index fc79786e5c7..00000000000 --- a/source/blender/render/intern/source/pixelblending.c +++ /dev/null @@ -1,400 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * Contributor(s): Full recode, 2004-2006 Blender Foundation - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/render/intern/source/pixelblending.c - * \ingroup render - * - * Functions to blend pixels with or without alpha, in various formats - * nzc - June 2000 - */ - - -#include <math.h> -#include <string.h> - -/* global includes */ - -/* own includes */ -#include "render_types.h" -#include "pixelblending.h" - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -/* defined in pipeline.c, is hardcopy of active dynamic allocated Render */ -/* only to be used here in this file, it's for speed */ -extern struct Render R; -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - - -/* ------------------------------------------------------------------------- */ -/* Debug/behavior defines */ -/* if defined: alpha blending with floats clips color, as with shorts */ -/* #define RE_FLOAT_COLOR_CLIPPING */ -/* if defined: alpha values are clipped */ -/* For now, we just keep alpha clipping. We run into thresholding and */ -/* blending difficulties otherwise. Be careful here. */ -#define RE_ALPHA_CLIPPING - - - -/* Threshold for a 'full' pixel: pixels with alpha above this level are */ -/* considered opaque This is the decimal value for 0xFFF0 / 0xFFFF */ -#define RE_FULL_COLOR_FLOAT 0.9998f -/* Threshold for an 'empty' pixel: pixels with alpha above this level are */ -/* considered completely transparent. This is the decimal value */ -/* for 0x000F / 0xFFFF */ -#define RE_EMPTY_COLOR_FLOAT 0.0002f - - -/* ------------------------------------------------------------------------- */ - -void addAlphaOverFloat(float dest[4], const float source[4]) -{ - /* d = s + (1-alpha_s)d*/ - float mul; - - mul = 1.0f - source[3]; - - dest[0] = (mul * dest[0]) + source[0]; - dest[1] = (mul * dest[1]) + source[1]; - dest[2] = (mul * dest[2]) + source[2]; - dest[3] = (mul * dest[3]) + source[3]; - -} - - -/* ------------------------------------------------------------------------- */ - -void addAlphaUnderFloat(float dest[4], const float source[4]) -{ - float mul; - - mul = 1.0f - dest[3]; - - dest[0] += (mul * source[0]); - dest[1] += (mul * source[1]); - dest[2] += (mul * source[2]); - dest[3] += (mul * source[3]); -} - - -/* ------------------------------------------------------------------------- */ -void addalphaAddfacFloat(float dest[4], const float source[4], char addfac) -{ - float m; /* weiging factor of destination */ - float c; /* intermediate color */ - - /* Addfac is a number between 0 and 1: rescale */ - /* final target is to diminish the influence of dest when addfac rises */ - m = 1.0f - (source[3] * ((255 - addfac) / 255.0f)); - - /* blend colors*/ - c = (m * dest[0]) + source[0]; -#ifdef RE_FLOAT_COLOR_CLIPPING - if (c >= RE_FULL_COLOR_FLOAT) dest[0] = RE_FULL_COLOR_FLOAT; - else -#endif - dest[0] = c; - - c = (m * dest[1]) + source[1]; -#ifdef RE_FLOAT_COLOR_CLIPPING - if (c >= RE_FULL_COLOR_FLOAT) dest[1] = RE_FULL_COLOR_FLOAT; - else -#endif - dest[1] = c; - - c = (m * dest[2]) + source[2]; -#ifdef RE_FLOAT_COLOR_CLIPPING - if (c >= RE_FULL_COLOR_FLOAT) dest[2] = RE_FULL_COLOR_FLOAT; - else -#endif - dest[2] = c; - - c = (m * dest[3]) + source[3]; -#ifdef RE_ALPHA_CLIPPING - if (c >= RE_FULL_COLOR_FLOAT) dest[3] = RE_FULL_COLOR_FLOAT; - else -#endif - dest[3] = c; - -} - - -/* ------------------------------------------------------------------------- */ - -/* filtered adding to scanlines */ -void add_filt_fmask(unsigned int mask, const float col[4], float *rowbuf, int row_w) -{ - /* calc the value of mask */ - float **fmask1 = R.samples->fmask1, **fmask2 = R.samples->fmask2; - float *rb1, *rb2, *rb3; - float val, r, g, b, al; - unsigned int a, maskand, maskshift; - int j; - - r = col[0]; - g = col[1]; - b = col[2]; - al = col[3]; - - rb2 = rowbuf - 4; - rb3 = rb2 - 4 * row_w; - rb1 = rb2 + 4 * row_w; - - maskand = (mask & 255); - maskshift = (mask >> 8); - - for (j = 2; j >= 0; j--) { - - a = j; - - val = *(fmask1[a] + maskand) + *(fmask2[a] + maskshift); - if (val != 0.0f) { - rb1[0] += val * r; - rb1[1] += val * g; - rb1[2] += val * b; - rb1[3] += val * al; - } - a += 3; - - val = *(fmask1[a] + maskand) + *(fmask2[a] + maskshift); - if (val != 0.0f) { - rb2[0] += val * r; - rb2[1] += val * g; - rb2[2] += val * b; - rb2[3] += val * al; - } - a += 3; - - val = *(fmask1[a] + maskand) + *(fmask2[a] + maskshift); - if (val != 0.0f) { - rb3[0] += val * r; - rb3[1] += val * g; - rb3[2] += val * b; - rb3[3] += val * al; - } - - rb1 += 4; - rb2 += 4; - rb3 += 4; - } -} - - -void mask_array(unsigned int mask, float filt[3][3]) -{ - float **fmask1 = R.samples->fmask1, **fmask2 = R.samples->fmask2; - unsigned int maskand = (mask & 255); - unsigned int maskshift = (mask >> 8); - int a, j; - - for (j = 2; j >= 0; j--) { - - a = j; - - filt[2][2 - j] = *(fmask1[a] + maskand) + *(fmask2[a] + maskshift); - - a += 3; - - filt[1][2 - j] = *(fmask1[a] + maskand) + *(fmask2[a] + maskshift); - - a += 3; - - filt[0][2 - j] = *(fmask1[a] + maskand) + *(fmask2[a] + maskshift); - } -} - - -/** - * Index ordering, scanline based: - * - * <pre> - * --- --- --- - * | 2,0 | 2,1 | 2,2 | - * --- --- --- - * | 1,0 | 1,1 | 1,2 | - * --- --- --- - * | 0,0 | 0,1 | 0,2 | - * --- --- --- - * </pre> - */ - -void add_filt_fmask_coord(float filt[3][3], const float col[4], float *rowbuf, int row_stride, int x, int y, rcti *mask) -{ - float *fpoin[3][3]; - float val, r, g, b, al, lfilt[3][3]; - - r = col[0]; - g = col[1]; - b = col[2]; - al = col[3]; - - memcpy(lfilt, filt, sizeof(lfilt)); - - fpoin[0][1] = rowbuf - 4 * row_stride; - fpoin[1][1] = rowbuf; - fpoin[2][1] = rowbuf + 4 * row_stride; - - fpoin[0][0] = fpoin[0][1] - 4; - fpoin[1][0] = fpoin[1][1] - 4; - fpoin[2][0] = fpoin[2][1] - 4; - - fpoin[0][2] = fpoin[0][1] + 4; - fpoin[1][2] = fpoin[1][1] + 4; - fpoin[2][2] = fpoin[2][1] + 4; - - /* limit filtering to withing a mask for border rendering, so pixels don't - * leak outside of the border */ - if (y <= mask->ymin) { - fpoin[0][0] = fpoin[1][0]; - fpoin[0][1] = fpoin[1][1]; - fpoin[0][2] = fpoin[1][2]; - /* filter needs the opposite value yes! */ - lfilt[0][0] = filt[2][0]; - lfilt[0][1] = filt[2][1]; - lfilt[0][2] = filt[2][2]; - } - else if (y >= mask->ymax - 1) { - fpoin[2][0] = fpoin[1][0]; - fpoin[2][1] = fpoin[1][1]; - fpoin[2][2] = fpoin[1][2]; - - lfilt[2][0] = filt[0][0]; - lfilt[2][1] = filt[0][1]; - lfilt[2][2] = filt[0][2]; - } - - if (x <= mask->xmin) { - fpoin[2][0] = fpoin[2][1]; - fpoin[1][0] = fpoin[1][1]; - fpoin[0][0] = fpoin[0][1]; - - lfilt[2][0] = filt[2][2]; - lfilt[1][0] = filt[1][2]; - lfilt[0][0] = filt[0][2]; - } - else if (x >= mask->xmax - 1) { - fpoin[2][2] = fpoin[2][1]; - fpoin[1][2] = fpoin[1][1]; - fpoin[0][2] = fpoin[0][1]; - - lfilt[2][2] = filt[2][0]; - lfilt[1][2] = filt[1][0]; - lfilt[0][2] = filt[0][0]; - } - - - /* loop unroll */ -#define MASKFILT(i, j) \ - val = lfilt[i][j]; \ - if (val != 0.0f) { \ - float *fp = fpoin[i][j]; \ - fp[0] += val * r; \ - fp[1] += val * g; \ - fp[2] += val * b; \ - fp[3] += val * al; \ - } (void)0 - - MASKFILT(0, 0); - MASKFILT(0, 1); - MASKFILT(0, 2); - MASKFILT(1, 0); - MASKFILT(1, 1); - MASKFILT(1, 2); - MASKFILT(2, 0); - MASKFILT(2, 1); - MASKFILT(2, 2); - -#undef MASKFILT -} - -void add_filt_fmask_pixsize(unsigned int mask, float *in, float *rowbuf, int row_w, int pixsize) -{ - /* calc the value of mask */ - float **fmask1 = R.samples->fmask1, **fmask2 = R.samples->fmask2; - float *rb1, *rb2, *rb3; - float val; - unsigned int a, maskand, maskshift; - int i, j; - - rb2 = rowbuf - pixsize; - rb3 = rb2 - pixsize * row_w; - rb1 = rb2 + pixsize * row_w; - - maskand = (mask & 255); - maskshift = (mask >> 8); - - for (j = 2; j >= 0; j--) { - - a = j; - - val = *(fmask1[a] + maskand) + *(fmask2[a] + maskshift); - if (val != 0.0f) { - for (i = 0; i < pixsize; i++) - rb1[i] += val * in[i]; - } - a += 3; - - val = *(fmask1[a] + maskand) + *(fmask2[a] + maskshift); - if (val != 0.0f) { - for (i = 0; i < pixsize; i++) - rb2[i] += val * in[i]; - } - a += 3; - - val = *(fmask1[a] + maskand) + *(fmask2[a] + maskshift); - if (val != 0.0f) { - for (i = 0; i < pixsize; i++) - rb3[i] += val * in[i]; - } - - rb1 += pixsize; - rb2 += pixsize; - rb3 += pixsize; - } -} - -/* ------------------------------------------------------------------------- */ -void addalphaAddFloat(float dest[4], const float source[4]) -{ - - /* Makes me wonder whether this is required... */ - if (dest[3] < RE_EMPTY_COLOR_FLOAT) { - dest[0] = source[0]; - dest[1] = source[1]; - dest[2] = source[2]; - dest[3] = source[3]; - return; - } - - /* no clipping! */ - dest[0] = dest[0] + source[0]; - dest[1] = dest[1] + source[1]; - dest[2] = dest[2] + source[2]; - dest[3] = dest[3] + source[3]; - -} - - -/* ---------------------------------------------------------------------------- */ diff --git a/source/blender/render/intern/source/pixelshading.c b/source/blender/render/intern/source/pixelshading.c deleted file mode 100644 index ddbdb35bf51..00000000000 --- a/source/blender/render/intern/source/pixelshading.c +++ /dev/null @@ -1,650 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * Contributor(s): 2004-2006, Blender Foundation, full recode - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/render/intern/source/pixelshading.c - * \ingroup render - */ - - -#include <float.h> -#include <math.h> -#include <string.h> - -#include "BLI_math.h" -#include "BLI_utildefines.h" - -/* External modules: */ - -#include "DNA_group_types.h" -#include "DNA_material_types.h" -#include "DNA_object_types.h" -#include "DNA_image_types.h" -#include "DNA_texture_types.h" -#include "DNA_lamp_types.h" - -#include "BKE_material.h" - - -/* own module */ -#include "render_types.h" -#include "renderdatabase.h" -#include "texture.h" -#include "rendercore.h" -#include "shadbuf.h" -#include "pixelshading.h" -#include "sunsky.h" - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -/* defined in pipeline.c, is hardcopy of active dynamic allocated Render */ -/* only to be used here in this file, it's for speed */ -extern struct Render R; -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - - -extern const float hashvectf[]; - -static void render_lighting_halo(HaloRen *har, float col_r[3]) -{ - GroupObject *go; - LampRen *lar; - float i, inp, inpr, rco[3], dco[3], lv[3], lampdist, ld, t, *vn; - float ir, ig, ib, shadfac, soft, lacol[3]; - - ir= ig= ib= 0.0; - - copy_v3_v3(rco, har->co); - dco[0]=dco[1]=dco[2]= 1.0f/har->rad; - - vn= har->no; - - for (go=R.lights.first; go; go= go->next) { - lar= go->lampren; - - /* test for lamplayer */ - if (lar->mode & LA_LAYER) if ((lar->lay & har->lay)==0) continue; - - /* lampdist cacluation */ - if (lar->type==LA_SUN || lar->type==LA_HEMI) { - copy_v3_v3(lv, lar->vec); - lampdist= 1.0; - } - else { - lv[0]= rco[0]-lar->co[0]; - lv[1]= rco[1]-lar->co[1]; - lv[2]= rco[2]-lar->co[2]; - ld = len_v3(lv); - lv[0]/= ld; - lv[1]/= ld; - lv[2]/= ld; - - /* ld is re-used further on (texco's) */ - - if (lar->mode & LA_QUAD) { - t= 1.0; - if (lar->ld1>0.0f) - t= lar->dist/(lar->dist+lar->ld1*ld); - if (lar->ld2>0.0f) - t*= lar->distkw/(lar->distkw+lar->ld2*ld*ld); - - lampdist= t; - } - else { - lampdist= (lar->dist/(lar->dist+ld)); - } - - if (lar->mode & LA_SPHERE) { - t= lar->dist - ld; - if (t<0.0f) continue; - - t/= lar->dist; - lampdist*= (t); - } - - } - - lacol[0]= lar->r; - lacol[1]= lar->g; - lacol[2]= lar->b; - - if (lar->mode & LA_TEXTURE) { - ShadeInput shi; - - /* Warning, This is not that nice, and possibly a bit slow, - * however some variables were not initialized properly in, unless using shade_input_initialize(...), - * we need to do a memset */ - memset(&shi, 0, sizeof(ShadeInput)); - /* end warning! - Campbell */ - - copy_v3_v3(shi.co, rco); - shi.osatex= 0; - do_lamp_tex(lar, lv, &shi, lacol, LA_TEXTURE); - } - - if (lar->type==LA_SPOT) { - - if (lar->mode & LA_SQUARE) { - if (lv[0]*lar->vec[0]+lv[1]*lar->vec[1]+lv[2]*lar->vec[2]>0.0f) { - float x, lvrot[3]; - - /* rotate view to lampspace */ - copy_v3_v3(lvrot, lv); - mul_m3_v3(lar->imat, lvrot); - - x = max_ff(fabsf(lvrot[0]/lvrot[2]), fabsf(lvrot[1]/lvrot[2])); - /* 1.0/(sqrt(1+x*x)) is equivalent to cos(atan(x)) */ - - inpr = 1.0f / (sqrtf(1.0f + x * x)); - } - else inpr= 0.0; - } - else { - inpr= lv[0]*lar->vec[0]+lv[1]*lar->vec[1]+lv[2]*lar->vec[2]; - } - - t= lar->spotsi; - if (inpr<t) continue; - else { - t= inpr-t; - soft= 1.0; - if (t<lar->spotbl && lar->spotbl!=0.0f) { - /* soft area */ - i= t/lar->spotbl; - t= i*i; - soft= (3.0f*t-2.0f*t*i); - inpr*= soft; - } - if (lar->mode & LA_ONLYSHADOW) { - /* if (ma->mode & MA_SHADOW) { */ - /* dot product positive: front side face! */ - inp= vn[0]*lv[0] + vn[1]*lv[1] + vn[2]*lv[2]; - if (inp>0.0f) { - /* testshadowbuf==0.0 : 100% shadow */ - shadfac = testshadowbuf(&R, lar->shb, rco, dco, dco, inp, 0.0f); - if ( shadfac>0.0f ) { - shadfac*= inp*soft*lar->energy; - ir -= shadfac; - ig -= shadfac; - ib -= shadfac; - - continue; - } - } - /* } */ - } - lampdist*=inpr; - } - if (lar->mode & LA_ONLYSHADOW) continue; - - } - - /* dot product and reflectivity*/ - - inp = 1.0f - fabsf(dot_v3v3(vn, lv)); - - /* inp= cos(0.5*M_PI-acos(inp)); */ - - i= inp; - - if (lar->type==LA_HEMI) { - i= 0.5f*i+0.5f; - } - if (i>0.0f) { - i*= lampdist; - } - - /* shadow */ - if (i> -0.41f) { /* heuristic valua! */ - if (lar->shb) { - shadfac = testshadowbuf(&R, lar->shb, rco, dco, dco, inp, 0.0f); - if (shadfac==0.0f) continue; - i*= shadfac; - } - } - - if (i>0.0f) { - ir+= i*lacol[0]; - ig+= i*lacol[1]; - ib+= i*lacol[2]; - } - } - - if (ir<0.0f) ir= 0.0f; - if (ig<0.0f) ig= 0.0f; - if (ib<0.0f) ib= 0.0f; - - col_r[0]*= ir; - col_r[1]*= ig; - col_r[2]*= ib; - -} - - -/** - * Converts a halo z-buffer value to distance from the camera's near plane - * \param z The z-buffer value to convert - * \return a distance from the camera's near plane in blender units - */ -static float haloZtoDist(int z) -{ - float zco = 0; - - if (z >= 0x7FFFFF) - return 10e10; - else { - zco = (float)z/(float)0x7FFFFF; - if (R.r.mode & R_ORTHO) - return (R.winmat[3][2] - zco*R.winmat[3][3])/(R.winmat[2][2]); - else - return (R.winmat[3][2])/(R.winmat[2][2] - R.winmat[2][3]*zco); - } -} - -/** - * \param col (float[4]) Store the rgb color here (with alpha) - * The alpha is used to blend the color to the background - * color_new = (1-alpha)*color_background + color - * \param zz The current zbuffer value at the place of this pixel - * \param dist Distance of the pixel from the center of the halo squared. Given in pixels - * \param xn The x coordinate of the pixel relaticve to the center of the halo. given in pixels - * \param yn The y coordinate of the pixel relaticve to the center of the halo. given in pixels - */ -int shadeHaloFloat(HaloRen *har, float col[4], int zz, - float dist, float xn, float yn, short flarec) -{ - /* fill in col */ - float t, zn, radist, ringf=0.0f, linef=0.0f, alpha, si, co; - int a; - - if (R.wrld.mode & WO_MIST) { - if (har->type & HA_ONLYSKY) { - alpha= har->alfa; - } - else { - /* a bit patchy... */ - alpha= mistfactor(-har->co[2], har->co)*har->alfa; - } - } - else alpha= har->alfa; - - if (alpha==0.0f) - return 0; - - /* soften the halo if it intersects geometry */ - if (har->mat && har->mat->mode & MA_HALO_SOFT) { - float segment_length, halo_depth, distance_from_z /* , visible_depth */ /* UNUSED */, soften; - - /* calculate halo depth */ - segment_length= har->hasize*sasqrt(1.0f - dist/(har->rad*har->rad)); - halo_depth= 2.0f*segment_length; - - if (halo_depth < FLT_EPSILON) - return 0; - - /* calculate how much of this depth is visible */ - distance_from_z = haloZtoDist(zz) - haloZtoDist(har->zs); - /* visible_depth = halo_depth; */ /* UNUSED */ - if (distance_from_z < segment_length) { - soften= (segment_length + distance_from_z)/halo_depth; - - /* apply softening to alpha */ - if (soften < 1.0f) - alpha *= soften; - if (alpha <= 0.0f) - return 0; - } - } - else { - /* not a soft halo. use the old softening code */ - /* halo being intersected? */ - if (har->zs> zz-har->zd) { - t= ((float)(zz-har->zs))/(float)har->zd; - alpha*= sqrtf(sqrtf(t)); - } - } - - radist = sqrtf(dist); - - /* watch it: not used nicely: flarec is set at zero in pixstruct */ - if (flarec) har->pixels+= (int)(har->rad-radist); - - if (har->ringc) { - const float *rc; - float fac; - int ofs; - - /* per ring an antialised circle */ - ofs= har->seed; - - for (a= har->ringc; a>0; a--, ofs+=2) { - - rc= hashvectf + (ofs % 768); - - fac = fabsf(rc[1] * (har->rad * fabsf(rc[0]) - radist)); - - if (fac< 1.0f) { - ringf+= (1.0f-fac); - } - } - } - - if (har->type & HA_VECT) { - dist= fabsf(har->cos * (yn) - har->sin * (xn)) / har->rad; - if (dist>1.0f) dist= 1.0f; - if (har->tex) { - zn= har->sin*xn - har->cos*yn; - yn= har->cos*xn + har->sin*yn; - xn= zn; - } - } - else dist= dist/har->radsq; - - if (har->type & HA_FLARECIRC) { - dist = 0.5f + fabsf(dist - 0.5f); - } - - if (har->hard>=30) { - dist = sqrtf(dist); - if (har->hard>=40) { - dist = sinf(dist*(float)M_PI_2); - if (har->hard>=50) { - dist = sqrtf(dist); - } - } - } - else if (har->hard<20) dist*=dist; - - if (dist < 1.0f) - dist= (1.0f-dist); - else - dist= 0.0f; - - if (har->linec) { - const float *rc; - float fac; - int ofs; - - /* per starpoint an antialiased line */ - ofs= har->seed; - - for (a= har->linec; a>0; a--, ofs+=3) { - - rc= hashvectf + (ofs % 768); - - fac = fabsf((xn) * rc[0] + (yn) * rc[1]); - - if (fac< 1.0f ) - linef+= (1.0f-fac); - } - - linef*= dist; - } - - if (har->starpoints) { - float ster, angle; - /* rotation */ - angle = atan2f(yn, xn); - angle *= (1.0f+0.25f*har->starpoints); - - co= cosf(angle); - si= sinf(angle); - - angle= (co*xn+si*yn)*(co*yn-si*xn); - - ster = fabsf(angle); - if (ster>1.0f) { - ster= (har->rad)/(ster); - - if (ster<1.0f) dist*= sqrtf(ster); - } - } - - /* disputable optimize... (ton) */ - if (dist<=0.00001f) - return 0; - - dist*= alpha; - ringf*= dist; - linef*= alpha; - - /* The color is either the rgb spec-ed by the user, or extracted from */ - /* the texture */ - if (har->tex) { - col[0]= har->r; - col[1]= har->g; - col[2]= har->b; - col[3]= dist; - - do_halo_tex(har, xn, yn, col); - - col[0]*= col[3]; - col[1]*= col[3]; - col[2]*= col[3]; - - } - else { - col[0]= dist*har->r; - col[1]= dist*har->g; - col[2]= dist*har->b; - if (har->type & HA_XALPHA) col[3]= dist*dist; - else col[3]= dist; - } - - if (har->mat) { - if (har->mat->mode & MA_HALO_SHADE) { - /* we test for lights because of preview... */ - if (R.lights.first) render_lighting_halo(har, col); - } - - /* Next, we do the line and ring factor modifications. */ - if (linef!=0.0f) { - Material *ma= har->mat; - - col[0]+= linef * ma->specr; - col[1]+= linef * ma->specg; - col[2]+= linef * ma->specb; - - if (har->type & HA_XALPHA) col[3]+= linef*linef; - else col[3]+= linef; - } - if (ringf!=0.0f) { - Material *ma= har->mat; - - col[0]+= ringf * ma->mirr; - col[1]+= ringf * ma->mirg; - col[2]+= ringf * ma->mirb; - - if (har->type & HA_XALPHA) col[3]+= ringf*ringf; - else col[3]+= ringf; - } - } - - /* alpha requires clip, gives black dots */ - if (col[3] > 1.0f) - col[3]= 1.0f; - - return 1; -} - -/* ------------------------------------------------------------------------- */ - -/* Only view vector is important here. Result goes to col_r[3] */ -void shadeSkyView(float col_r[3], const float rco[3], const float view[3], const float dxyview[2], short thread) -{ - float zen[3], hor[3], blend, blendm; - int skyflag; - - /* flag indicating if we render the top hemisphere */ - skyflag = WO_ZENUP; - - /* Some view vector stuff. */ - if (R.wrld.skytype & WO_SKYREAL) { - - blend = dot_v3v3(view, R.grvec); - - if (blend<0.0f) skyflag= 0; - - blend = fabsf(blend); - } - else if (R.wrld.skytype & WO_SKYPAPER) { - blend= 0.5f + 0.5f * view[1]; - } - else { - /* the fraction of how far we are above the bottom of the screen */ - blend = fabsf(0.5f + view[1]); - } - - copy_v3_v3(hor, &R.wrld.horr); - copy_v3_v3(zen, &R.wrld.zenr); - - /* Careful: SKYTEX and SKYBLEND are NOT mutually exclusive! If */ - /* SKYBLEND is active, the texture and color blend are added. */ - if (R.wrld.skytype & WO_SKYTEX) { - float lo[3]; - copy_v3_v3(lo, view); - if (R.wrld.skytype & WO_SKYREAL) { - - mul_m3_v3(R.imat, lo); - - SWAP(float, lo[1], lo[2]); - - } - do_sky_tex(rco, view, lo, dxyview, hor, zen, &blend, skyflag, thread); - } - - if (blend>1.0f) blend= 1.0f; - blendm= 1.0f-blend; - - /* No clipping, no conversion! */ - if (R.wrld.skytype & WO_SKYBLEND) { - col_r[0] = (blendm*hor[0] + blend*zen[0]); - col_r[1] = (blendm*hor[1] + blend*zen[1]); - col_r[2] = (blendm*hor[2] + blend*zen[2]); - } - else { - /* Done when a texture was grabbed. */ - col_r[0]= hor[0]; - col_r[1]= hor[1]; - col_r[2]= hor[2]; - } -} - -/* shade sky according to sun lamps, all parameters are like shadeSkyView except sunsky*/ -void shadeSunView(float col_r[3], const float view[3]) -{ - GroupObject *go; - LampRen *lar; - float sview[3]; - bool do_init = true; - - for (go=R.lights.first; go; go= go->next) { - lar= go->lampren; - if (lar->type==LA_SUN && lar->sunsky && (lar->sunsky->effect_type & LA_SUN_EFFECT_SKY)) { - float sun_collector[3]; - float colorxyz[3]; - - if (do_init) { - - normalize_v3_v3(sview, view); - mul_m3_v3(R.imat, sview); - if (sview[2] < 0.0f) - sview[2] = 0.0f; - normalize_v3(sview); - do_init = false; - } - - GetSkyXYZRadiancef(lar->sunsky, sview, colorxyz); - xyz_to_rgb(colorxyz[0], colorxyz[1], colorxyz[2], &sun_collector[0], &sun_collector[1], &sun_collector[2], - lar->sunsky->sky_colorspace); - - ramp_blend(lar->sunsky->skyblendtype, col_r, lar->sunsky->skyblendfac, sun_collector); - } - } -} - - -/* - * Stuff the sky color into the collector. - */ -void shadeSkyPixel(float collector[4], float fx, float fy, short thread) -{ - float view[3], dxyview[2]; - - /* - * The rules for sky: - * 1. Draw an image, if a background image was provided. Stop - * 2. get texture and color blend, and combine these. - */ - - float fac; - - if ((R.wrld.skytype & (WO_SKYBLEND+WO_SKYTEX))==0) { - /* 1. solid color */ - copy_v3_v3(collector, &R.wrld.horr); - - collector[3] = 0.0f; - } - else { - /* 2. */ - - /* This one true because of the context of this routine */ - if (R.wrld.skytype & WO_SKYPAPER) { - view[0]= -1.0f + 2.0f*(fx/(float)R.winx); - view[1]= -1.0f + 2.0f*(fy/(float)R.winy); - view[2]= 0.0; - - dxyview[0]= 1.0f/(float)R.winx; - dxyview[1]= 1.0f/(float)R.winy; - } - else { - calc_view_vector(view, fx, fy); - fac= normalize_v3(view); - - if (R.wrld.skytype & WO_SKYTEX) { - dxyview[0]= -R.viewdx/fac; - dxyview[1]= -R.viewdy/fac; - } - } - - /* get sky color in the collector */ - shadeSkyView(collector, NULL, view, dxyview, thread); - collector[3] = 0.0f; - } - - calc_view_vector(view, fx, fy); - shadeSunView(collector, view); -} - -/* aerial perspective */ -void shadeAtmPixel(struct SunSky *sunsky, float collector[3], float fx, float fy, float distance) -{ - float view[3]; - - calc_view_vector(view, fx, fy); - normalize_v3(view); - /*mul_m3_v3(R.imat, view);*/ - AtmospherePixleShader(sunsky, view, distance, collector); -} - -/* eof */ diff --git a/source/blender/render/intern/source/pointdensity.c b/source/blender/render/intern/source/pointdensity.c index 6d0cd52544b..86f31f79c49 100644 --- a/source/blender/render/intern/source/pointdensity.c +++ b/source/blender/render/intern/source/pointdensity.c @@ -63,15 +63,9 @@ #include "render_types.h" #include "texture.h" -#include "pointdensity.h" #include "RE_render_ext.h" - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -/* defined in pipeline.c, is hardcopy of active dynamic allocated Render */ -/* only to be used here in this file, it's for speed */ -extern struct Render R; -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +#include "RE_shader_ext.h" static ThreadMutex sample_mutex = PTHREAD_MUTEX_INITIALIZER; @@ -80,15 +74,13 @@ static int point_data_used(PointDensity *pd) int pd_bitflag = 0; if (pd->source == TEX_PD_PSYS) { - if ((pd->noise_influence == TEX_PD_NOISE_VEL) || - (pd->falloff_type == TEX_PD_FALLOFF_PARTICLE_VEL) || + if ((pd->falloff_type == TEX_PD_FALLOFF_PARTICLE_VEL) || (pd->color_source == TEX_PD_COLOR_PARTVEL) || (pd->color_source == TEX_PD_COLOR_PARTSPEED)) { pd_bitflag |= POINT_DATA_VEL; } - if ((pd->noise_influence == TEX_PD_NOISE_AGE) || - (pd->color_source == TEX_PD_COLOR_PARTAGE) || + if ((pd->color_source == TEX_PD_COLOR_PARTAGE) || (pd->falloff_type == TEX_PD_FALLOFF_PARTICLE_AGE)) { pd_bitflag |= POINT_DATA_LIFE; @@ -466,10 +458,10 @@ static void pointdensity_cache_object(Depsgraph *depsgraph, Scene *scene, } -static void cache_pointdensity_ex(Depsgraph *depsgraph, - Scene *scene, - PointDensity *pd, - const bool use_render_params) +static void cache_pointdensity(Depsgraph *depsgraph, + Scene *scene, + PointDensity *pd, + const bool use_render_params) { if (pd == NULL) { return; @@ -507,15 +499,7 @@ static void cache_pointdensity_ex(Depsgraph *depsgraph, } } -void cache_pointdensity(Depsgraph *depsgraph, Render *re, PointDensity *pd) -{ - cache_pointdensity_ex(depsgraph, - re->scene, - pd, - true); -} - -void free_pointdensity(PointDensity *pd) +static void free_pointdensity(PointDensity *pd) { if (pd == NULL) { return; @@ -533,41 +517,6 @@ void free_pointdensity(PointDensity *pd) pd->totpoints = 0; } -void make_pointdensities(Depsgraph *depsgraph, Render *re) -{ - Tex *tex; - - if (re->scene->r.scemode & R_BUTS_PREVIEW) { - return; - } - - re->i.infostr = IFACE_("Caching Point Densities"); - re->stats_draw(re->sdh, &re->i); - - for (tex = re->main->tex.first; tex != NULL; tex = tex->id.next) { - if (tex->id.us && tex->type == TEX_POINTDENSITY) { - cache_pointdensity(depsgraph, re, tex->pd); - } - } - - re->i.infostr = NULL; - re->stats_draw(re->sdh, &re->i); -} - -void free_pointdensities(Render *re) -{ - Tex *tex; - - if (re->scene->r.scemode & R_BUTS_PREVIEW) - return; - - for (tex = re->main->tex.first; tex != NULL; tex = tex->id.next) { - if (tex->id.us && tex->type == TEX_POINTDENSITY) { - free_pointdensity(tex->pd); - } - } -} - typedef struct PointDensityRangeData { float *density; float squared_radius; @@ -678,7 +627,7 @@ static int pointdensity(PointDensity *pd, { int retval = TEX_INT; PointDensityRangeData pdr; - float density = 0.0f, age = 0.0f, time = 0.0f; + float density = 0.0f, age = 0.0f; float vec[3] = {0.0f, 0.0f, 0.0f}, col[3] = {0.0f, 0.0f, 0.0f}, co[3]; float turb, noise_fac; int num = 0; @@ -712,21 +661,8 @@ static int pointdensity(PointDensity *pd, } if (pd->flag & TEX_PD_TURBULENCE) { - - if (pd->noise_influence == TEX_PD_NOISE_AGE) { - turb = BLI_gTurbulence(pd->noise_size, texvec[0] + age, texvec[1] + age, texvec[2] + age, - pd->noise_depth, 0, pd->noise_basis); - } - else if (pd->noise_influence == TEX_PD_NOISE_TIME) { - time = R.r.cfra / (float)R.r.efra; - turb = BLI_gTurbulence(pd->noise_size, texvec[0] + time, texvec[1] + time, texvec[2] + time, - pd->noise_depth, 0, pd->noise_basis); - //turb = BLI_turbulence(pd->noise_size, texvec[0]+time, texvec[1]+time, texvec[2]+time, pd->noise_depth); - } - else { - turb = BLI_gTurbulence(pd->noise_size, texvec[0] + vec[0], texvec[1] + vec[1], texvec[2] + vec[2], - pd->noise_depth, 0, pd->noise_basis); - } + turb = BLI_gTurbulence(pd->noise_size, texvec[0] + vec[0], texvec[1] + vec[1], texvec[2] + vec[2], + pd->noise_depth, 0, pd->noise_basis); turb -= 0.5f; /* re-center 0.0-1.0 range around 0 to prevent offsetting result */ @@ -838,26 +774,6 @@ static int pointdensity_color(PointDensity *pd, TexResult *texres, float age, co return retval; } -int pointdensitytex(Tex *tex, const float texvec[3], TexResult *texres) -{ - PointDensity *pd = tex->pd; - float age = 0.0f; - float vec[3] = {0.0f, 0.0f, 0.0f}; - float col[3] = {0.0f, 0.0f, 0.0f}; - int retval = pointdensity(pd, texvec, texres, vec, &age, col); - - retval |= pointdensity_color(pd, texres, age, vec, col); - BRICONTRGB; - - return retval; - -#if 0 - if (texres->nor!=NULL) { - texres->nor[0] = texres->nor[1] = texres->nor[2] = 0.0f; - } -#endif -} - static void sample_dummy_point_density(int resolution, float *values) { memset(values, 0, sizeof(float) * 4 * resolution * resolution * resolution); @@ -927,7 +843,7 @@ void RE_point_density_cache( /* Same matricies/resolution as dupli_render_particle_set(). */ BLI_mutex_lock(&sample_mutex); - cache_pointdensity_ex(depsgraph, scene, pd, use_render_params); + cache_pointdensity(depsgraph, scene, pd, use_render_params); BLI_mutex_unlock(&sample_mutex); } @@ -1017,11 +933,15 @@ static void point_density_sample_func( texvec[1] += dim[1] * (float)y / (float)resolution; texvec[2] += dim[2] * (float)z / (float)resolution; - pointdensity(pd, texvec, &texres, vec, &age, col); - pointdensity_color(pd, &texres, age, vec, col); + if (pointdensity(pd, texvec, &texres, vec, &age, col)) { + pointdensity_color(pd, &texres, age, vec, col); - copy_v3_v3(&values[index*4 + 0], &texres.tr); - values[index*4 + 3] = texres.tin; + copy_v3_v3(&values[index*4 + 0], &texres.tr); + values[index*4 + 3] = texres.tin; + } + else { + zero_v4(&values[index*4]); + } } } } @@ -1081,3 +1001,8 @@ void RE_point_density_free(struct PointDensity *pd) { free_pointdensity(pd); } + +void RE_point_density_fix_linking(void) +{ +} + diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c deleted file mode 100644 index 7bac7f29c5a..00000000000 --- a/source/blender/render/intern/source/rayshade.c +++ /dev/null @@ -1,2474 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 1990-1998 NeoGeo BV. - * All rights reserved. - * - * Contributors: 2004/2005 Blender Foundation, full recode - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/render/intern/source/rayshade.c - * \ingroup render - */ - -#include <stdio.h> -#include <math.h> -#include <string.h> -#include <stdlib.h> -#include <float.h> -#include <assert.h> - -#include "MEM_guardedalloc.h" - -#include "DNA_material_types.h" -#include "DNA_lamp_types.h" - -#include "BLI_blenlib.h" -#include "BLI_system.h" -#include "BLI_math.h" -#include "BLI_rand.h" -#include "BLI_utildefines.h" - -#include "BLT_translation.h" - -#include "BKE_node.h" - -#include "render_result.h" -#include "render_types.h" -#include "rendercore.h" -#include "renderdatabase.h" -#include "pixelshading.h" -#include "shading.h" -#include "volumetric.h" - -#include "rayintersection.h" -#include "rayobject.h" -#include "raycounter.h" - -#define RAY_TRA 1 -#define RAY_INSIDE 2 - -#define DEPTH_SHADOW_TRA 10 - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -/* defined in pipeline.c, is hardcopy of active dynamic allocated Render */ -/* only to be used here in this file, it's for speed */ -extern struct Render R; -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -static int test_break(void *data) -{ - Render *re = (Render *)data; - return re->test_break(re->tbh); -} - -static void RE_rayobject_config_control(RayObject *r, Render *re) -{ - if (RE_rayobject_isRayAPI(r)) { - r = RE_rayobject_align(r); - r->control.data = re; - r->control.test_break = test_break; - } -} - -RayObject *RE_rayobject_create(int type, int size, int octree_resolution) -{ - RayObject * res = NULL; - - if (type == R_RAYSTRUCTURE_AUTO) { - /* TODO */ - //if (detect_simd()) -#ifdef __SSE__ - type = BLI_cpu_support_sse2()? R_RAYSTRUCTURE_SIMD_SVBVH: R_RAYSTRUCTURE_VBVH; -#else - type = R_RAYSTRUCTURE_VBVH; -#endif - } - -#ifndef __SSE__ - if (type == R_RAYSTRUCTURE_SIMD_SVBVH || type == R_RAYSTRUCTURE_SIMD_QBVH) { - puts("Warning: Using VBVH (SSE was disabled at compile time)"); - type = R_RAYSTRUCTURE_VBVH; - } -#endif - - - if (type == R_RAYSTRUCTURE_OCTREE) //TODO dynamic ocres - res = RE_rayobject_octree_create(octree_resolution, size); - else if (type == R_RAYSTRUCTURE_VBVH) - res = RE_rayobject_vbvh_create(size); - else if (type == R_RAYSTRUCTURE_SIMD_SVBVH) - res = RE_rayobject_svbvh_create(size); - else if (type == R_RAYSTRUCTURE_SIMD_QBVH) - res = RE_rayobject_qbvh_create(size); - else - res = RE_rayobject_vbvh_create(size); //Fallback - - return res; -} - -static RayObject* rayobject_create(Render *re, int type, int size) -{ - RayObject * res = NULL; - - res = RE_rayobject_create(type, size, re->r.ocres); - - if (res) - RE_rayobject_config_control(res, re); - - return res; -} - -#ifdef RE_RAYCOUNTER -RayCounter re_rc_counter[BLENDER_MAX_THREADS]; -#endif - - -void freeraytree(Render *re) -{ - ObjectInstanceRen *obi; - - if (re->raytree) { - RE_rayobject_free(re->raytree); - re->raytree = NULL; - } - if (re->rayfaces) { - MEM_freeN(re->rayfaces); - re->rayfaces = NULL; - } - if (re->rayprimitives) { - MEM_freeN(re->rayprimitives); - re->rayprimitives = NULL; - } - - for (obi=re->instancetable.first; obi; obi=obi->next) { - ObjectRen *obr = obi->obr; - if (obr->raytree) { - RE_rayobject_free(obr->raytree); - obr->raytree = NULL; - } - if (obr->rayfaces) { - MEM_freeN(obr->rayfaces); - obr->rayfaces = NULL; - } - if (obi->raytree) { - RE_rayobject_free(obi->raytree); - obi->raytree = NULL; - } - } - -#ifdef RE_RAYCOUNTER - { - const int num_threads = re->r.threads; - RayCounter sum; - memset(&sum, 0, sizeof(sum)); - int i; - for (i=0; i<num_threads; i++) - RE_RC_MERGE(&sum, re_rc_counter+i); - RE_RC_INFO(&sum); - } -#endif -} - -static bool is_raytraceable_vlr(Render *re, VlakRen *vlr) -{ - /* note: volumetric must be tracable, wire must not */ - if ((re->flag & R_BAKE_TRACE) || (vlr->flag & R_TRACEBLE) || (vlr->mat->material_type == MA_TYPE_VOLUME)) - if (vlr->mat->material_type != MA_TYPE_WIRE) - return 1; - return 0; -} - -static bool is_raytraceable(Render *re, ObjectInstanceRen *obi) -{ - int v; - ObjectRen *obr = obi->obr; - - if (re->excludeob && obr->ob == re->excludeob) - return 0; - - for (v=0;v<obr->totvlak;v++) { - VlakRen *vlr = obr->vlaknodes[v>>8].vlak + (v&255); - - if (is_raytraceable_vlr(re, vlr)) - return 1; - } - - return 0; -} - - -RayObject* makeraytree_object(Render *re, ObjectInstanceRen *obi) -{ - /*TODO - * out-of-memory safeproof - * break render - * update render stats */ - ObjectRen *obr = obi->obr; - - if (obr->raytree == NULL) { - RayObject *raytree; - RayFace *face = NULL; - VlakPrimitive *vlakprimitive = NULL; - int v; - - //Count faces - int faces = 0; - for (v=0;v<obr->totvlak;v++) { - VlakRen *vlr = obr->vlaknodes[v>>8].vlak + (v&255); - if (is_raytraceable_vlr(re, vlr)) - faces++; - } - - if (faces == 0) - return NULL; - - //Create Ray cast accelaration structure - raytree = rayobject_create( re, re->r.raytrace_structure, faces ); - if ( (re->r.raytrace_options & R_RAYTRACE_USE_LOCAL_COORDS) ) - vlakprimitive = obr->rayprimitives = (VlakPrimitive *)MEM_callocN(faces * sizeof(VlakPrimitive), "ObjectRen primitives"); - else - face = obr->rayfaces = (RayFace *)MEM_callocN(faces * sizeof(RayFace), "ObjectRen faces"); - - obr->rayobi = obi; - - for (v=0;v<obr->totvlak;v++) { - VlakRen *vlr = obr->vlaknodes[v>>8].vlak + (v&255); - if (is_raytraceable_vlr(re, vlr)) { - if ((re->r.raytrace_options & R_RAYTRACE_USE_LOCAL_COORDS)) { - RE_rayobject_add(raytree, RE_vlakprimitive_from_vlak(vlakprimitive, obi, vlr)); - vlakprimitive++; - } - else { - RE_rayface_from_vlak(face, obi, vlr); - RE_rayobject_add(raytree, RE_rayobject_unalignRayFace(face)); - face++; - } - } - } - RE_rayobject_done(raytree); - - /* in case of cancel during build, raytree is not usable */ - if (test_break(re)) - RE_rayobject_free(raytree); - else - obr->raytree= raytree; - } - - if (obr->raytree) { - if ((obi->flag & R_TRANSFORMED) && obi->raytree == NULL) { - obi->transform_primitives = 0; - obi->raytree = RE_rayobject_instance_create( obr->raytree, obi->mat, obi, obi->obr->rayobi ); - } - } - - if (obi->raytree) return obi->raytree; - return obi->obr->raytree; -} - -static bool has_special_rayobject(Render *re, ObjectInstanceRen *obi) -{ - if ( (obi->flag & R_TRANSFORMED) && (re->r.raytrace_options & R_RAYTRACE_USE_INSTANCES) ) { - ObjectRen *obr = obi->obr; - int v, faces = 0; - - for (v=0;v<obr->totvlak;v++) { - VlakRen *vlr = obr->vlaknodes[v>>8].vlak + (v&255); - if (is_raytraceable_vlr(re, vlr)) { - faces++; - if (faces > 4) - return 1; - } - } - } - return 0; -} -/* - * create a single raytrace structure with all faces - */ -static void makeraytree_single(Render *re) -{ - ObjectInstanceRen *obi; - RayObject *raytree; - RayFace *face = NULL; - VlakPrimitive *vlakprimitive = NULL; - int faces = 0, special = 0; - - for (obi = re->instancetable.first; obi; obi = obi->next) { - if (is_raytraceable(re, obi)) { - ObjectRen *obr = obi->obr; - - if (has_special_rayobject(re, obi)) { - special++; - } - else { - int v; - for (v = 0;v < obr->totvlak; v++) { - VlakRen *vlr = obr->vlaknodes[v >> 8].vlak + (v&255); - if (is_raytraceable_vlr(re, vlr)) { - faces++; - } - } - } - } - } - - if (faces + special == 0) { - re->raytree = RE_rayobject_empty_create(); - return; - } - - //Create raytree - raytree = re->raytree = rayobject_create( re, re->r.raytrace_structure, faces+special ); - - if ( (re->r.raytrace_options & R_RAYTRACE_USE_LOCAL_COORDS) ) { - vlakprimitive = re->rayprimitives = (VlakPrimitive *)MEM_callocN(faces * sizeof(VlakPrimitive), "Raytrace vlak-primitives"); - } - else { - face = re->rayfaces = (RayFace *)MEM_callocN(faces * sizeof(RayFace), "Render ray faces"); - } - - for (obi=re->instancetable.first; obi; obi=obi->next) - if (is_raytraceable(re, obi)) { - if (test_break(re)) - break; - - if (has_special_rayobject(re, obi)) { - RayObject *obj = makeraytree_object(re, obi); - - if (test_break(re)) - break; - - if (obj) - RE_rayobject_add(re->raytree, obj); - } - else { - int v; - ObjectRen *obr = obi->obr; - - if (obi->flag & R_TRANSFORMED) { - obi->transform_primitives = 1; - } - - for (v=0;v<obr->totvlak;v++) { - VlakRen *vlr = obr->vlaknodes[v>>8].vlak + (v&255); - if (is_raytraceable_vlr(re, vlr)) { - if ((re->r.raytrace_options & R_RAYTRACE_USE_LOCAL_COORDS)) { - RayObject *obj = RE_vlakprimitive_from_vlak( vlakprimitive, obi, vlr ); - RE_rayobject_add(raytree, obj); - vlakprimitive++; - } - else { - RE_rayface_from_vlak(face, obi, vlr); - if ((obi->flag & R_TRANSFORMED)) { - mul_m4_v3(obi->mat, face->v1); - mul_m4_v3(obi->mat, face->v2); - mul_m4_v3(obi->mat, face->v3); - if (RE_rayface_isQuad(face)) - mul_m4_v3(obi->mat, face->v4); - } - - RE_rayobject_add(raytree, RE_rayobject_unalignRayFace(face)); - face++; - } - } - } - } - } - - if (!test_break(re)) { - re->i.infostr = IFACE_("Raytree.. building"); - re->stats_draw(re->sdh, &re->i); - - RE_rayobject_done(raytree); - } -} - -void makeraytree(Render *re) -{ - float min[3], max[3], sub[3]; - int i; - - re->i.infostr = IFACE_("Raytree.. preparing"); - re->stats_draw(re->sdh, &re->i); - - /* disable options not yet supported by octree, - * they might actually never be supported (unless people really need it) */ - if (re->r.raytrace_structure == R_RAYSTRUCTURE_OCTREE) - re->r.raytrace_options &= ~( R_RAYTRACE_USE_INSTANCES | R_RAYTRACE_USE_LOCAL_COORDS); - - makeraytree_single(re); - - if (test_break(re)) { - freeraytree(re); - - re->i.infostr = IFACE_("Raytree building canceled"); - re->stats_draw(re->sdh, &re->i); - } - else { - /* Calculate raytree max_size - * This is ONLY needed to kept a bogus behavior of SUN and HEMI lights */ - INIT_MINMAX(min, max); - RE_rayobject_merge_bb(re->raytree, min, max); - if (min[0] > max[0]) { /* empty raytree */ - zero_v3(min); - zero_v3(max); - } - for (i=0; i<3; i++) { - /* TODO: explain why add top both min and max??? */ - min[i] += 0.01f; - max[i] += 0.01f; - sub[i] = max[i]-min[i]; - } - - re->maxdist = len_v3(sub); - - re->i.infostr = IFACE_("Raytree finished"); - re->stats_draw(re->sdh, &re->i); - } - -#ifdef RE_RAYCOUNTER - memset(re_rc_counter, 0, sizeof(re_rc_counter)); -#endif -} - -/* if (shi->osatex) */ -static void shade_ray_set_derivative(ShadeInput *shi) -{ - float detsh, t00, t10, t01, t11; - int axis1, axis2; - - /* find most stable axis to project */ - axis_dominant_v3(&axis1, &axis2, shi->facenor); - - /* compute u,v and derivatives */ - if (shi->obi->flag & R_TRANSFORMED) { - float v1[3], v2[3], v3[3]; - - mul_v3_m3v3(v1, shi->obi->nmat, shi->v1->co); - mul_v3_m3v3(v2, shi->obi->nmat, shi->v2->co); - mul_v3_m3v3(v3, shi->obi->nmat, shi->v3->co); - - /* same as below */ - t00= v3[axis1]-v1[axis1]; t01= v3[axis2]-v1[axis2]; - t10= v3[axis1]-v2[axis1]; t11= v3[axis2]-v2[axis2]; - } - else { - const float *v1= shi->v1->co; - const float *v2= shi->v2->co; - const float *v3= shi->v3->co; - - /* same as above */ - t00= v3[axis1]-v1[axis1]; t01= v3[axis2]-v1[axis2]; - t10= v3[axis1]-v2[axis1]; t11= v3[axis2]-v2[axis2]; - } - - detsh= 1.0f/(t00*t11-t10*t01); - t00*= detsh; t01*=detsh; - t10*=detsh; t11*=detsh; - - shi->dx_u= shi->dxco[axis1]*t11- shi->dxco[axis2]*t10; - shi->dx_v= shi->dxco[axis2]*t00- shi->dxco[axis1]*t01; - shi->dy_u= shi->dyco[axis1]*t11- shi->dyco[axis2]*t10; - shi->dy_v= shi->dyco[axis2]*t00- shi->dyco[axis1]*t01; - -} - -/* main ray shader */ -void shade_ray(Isect *is, ShadeInput *shi, ShadeResult *shr) -{ - ObjectInstanceRen *obi = (ObjectInstanceRen *)is->hit.ob; - VlakRen *vlr = (VlakRen *)is->hit.face; - - /* set up view vector */ - copy_v3_v3(shi->view, is->dir); - - /* render co */ - shi->co[0]= is->start[0]+is->dist*(shi->view[0]); - shi->co[1]= is->start[1]+is->dist*(shi->view[1]); - shi->co[2]= is->start[2]+is->dist*(shi->view[2]); - - normalize_v3(shi->view); - - shi->obi= obi; - shi->obr= obi->obr; - shi->vlr= vlr; - shi->mat= vlr->mat; - shade_input_init_material(shi); - - if (is->isect==2) - shade_input_set_triangle_i(shi, obi, vlr, 0, 2, 3); - else - shade_input_set_triangle_i(shi, obi, vlr, 0, 1, 2); - - shi->u= is->u; - shi->v= is->v; - shi->dx_u= shi->dx_v= shi->dy_u= shi->dy_v= 0.0f; - - if (shi->osatex) - shade_ray_set_derivative(shi); - shade_input_set_normals(shi); - - shade_input_set_shade_texco(shi); - if (shi->mat->material_type == MA_TYPE_VOLUME) { - if (ELEM(is->mode, RE_RAY_SHADOW, RE_RAY_SHADOW_TRA)) { - shade_volume_shadow(shi, shr, is); - } - else { - shade_volume_outside(shi, shr); - } - } - else if (is->mode==RE_RAY_SHADOW_TRA) { - /* temp hack to prevent recursion */ - if (shi->nodes==0 && shi->mat->nodetree && shi->mat->use_nodes) { - ntreeShaderExecTree(shi->mat->nodetree, shi, shr); - shi->mat= vlr->mat; /* shi->mat is being set in nodetree */ - } - else - shade_color(shi, shr); - } - else { - if (shi->mat->nodetree && shi->mat->use_nodes) { - ntreeShaderExecTree(shi->mat->nodetree, shi, shr); - shi->mat= vlr->mat; /* shi->mat is being set in nodetree */ - } - else { - shade_material_loop(shi, shr); - } - - /* raytrace likes to separate the spec color */ - sub_v3_v3v3(shr->diff, shr->combined, shr->spec); - copy_v3_v3(shr->diffshad, shr->diff); - } - -} - -static int refraction(float refract[3], const float n[3], const float view[3], float index) -{ - float dot, fac; - - copy_v3_v3(refract, view); - - dot = dot_v3v3(view, n); - - if (dot>0.0f) { - index = 1.0f/index; - fac= 1.0f - (1.0f - dot*dot)*index*index; - if (fac <= 0.0f) return 0; - fac= -dot*index + sqrtf(fac); - } - else { - fac= 1.0f - (1.0f - dot*dot)*index*index; - if (fac <= 0.0f) return 0; - fac= -dot*index - sqrtf(fac); - } - - refract[0]= index*view[0] + fac*n[0]; - refract[1]= index*view[1] + fac*n[1]; - refract[2]= index*view[2] + fac*n[2]; - - return 1; -} - -static void reflection_simple(float ref[3], float n[3], const float view[3]) -{ - const float f1= -2.0f * dot_v3v3(n, view); - madd_v3_v3v3fl(ref, view, n, f1); -} - -/* orn = original face normal */ -static void reflection(float ref[3], float n[3], const float view[3], const float orn[3]) -{ - float f1; - - reflection_simple(ref, n, view); - - /* test phong normals, then we should prevent vector going to the back */ - f1= dot_v3v3(ref, orn); - if (f1>0.0f) { - f1+= 0.01f; - ref[0]-= f1*orn[0]; - ref[1]-= f1*orn[1]; - ref[2]-= f1*orn[2]; - } -} - -#if 0 -static void color_combine(float *result, float fac1, float fac2, float col1[3], float col2[3]) -{ - float col1t[3], col2t[3]; - - col1t[0]= sqrt(col1[0]); - col1t[1]= sqrt(col1[1]); - col1t[2]= sqrt(col1[2]); - col2t[0]= sqrt(col2[0]); - col2t[1]= sqrt(col2[1]); - col2t[2]= sqrt(col2[2]); - - result[0]= (fac1*col1t[0] + fac2*col2t[0]); - result[0]*= result[0]; - result[1]= (fac1*col1t[1] + fac2*col2t[1]); - result[1]*= result[1]; - result[2]= (fac1*col1t[2] + fac2*col2t[2]); - result[2]*= result[2]; -} -#endif - -static float shade_by_transmission(Isect *is, ShadeInput *shi, ShadeResult *shr) -{ - float d; - if (0 == (shi->mat->mode & MA_TRANSP)) - return -1; - - if (shi->mat->tx_limit <= 0.0f) { - d= 1.0f; - } - else { - float p; - - /* shi.co[] calculated by shade_ray() */ - const float dx= shi->co[0] - is->start[0]; - const float dy= shi->co[1] - is->start[1]; - const float dz= shi->co[2] - is->start[2]; - d = sqrtf(dx * dx + dy * dy + dz * dz); - if (d > shi->mat->tx_limit) - d= shi->mat->tx_limit; - - p = shi->mat->tx_falloff; - if (p < 0.0f) p= 0.0f; - else if (p > 10.0f) p= 10.0f; - - shr->alpha *= powf(d, p); - if (shr->alpha > 1.0f) - shr->alpha= 1.0f; - } - - return d; -} - -static void ray_fadeout_endcolor(float col[3], ShadeInput *origshi, ShadeInput *shi, ShadeResult *shr, Isect *isec, const float vec[3]) -{ - /* un-intersected rays get either rendered material color or sky color */ - if (origshi->mat->fadeto_mir == MA_RAYMIR_FADETOMAT) { - copy_v3_v3(col, shr->combined); - } - else if (origshi->mat->fadeto_mir == MA_RAYMIR_FADETOSKY) { - copy_v3_v3(shi->view, vec); - normalize_v3(shi->view); - - shadeSkyView(col, isec->start, shi->view, NULL, shi->thread); - shadeSunView(col, shi->view); - } -} - -static void ray_fadeout(Isect *is, ShadeInput *shi, float col[3], const float blendcol[3], float dist_mir) -{ - /* if fading out, linear blend against fade color */ - float blendfac; - - blendfac = 1.0f - len_v3v3(shi->co, is->start)/dist_mir; - - col[0] = col[0]*blendfac + (1.0f - blendfac)*blendcol[0]; - col[1] = col[1]*blendfac + (1.0f - blendfac)*blendcol[1]; - col[2] = col[2]*blendfac + (1.0f - blendfac)*blendcol[2]; -} - -/* the main recursive tracer itself - * note: 'col' must be initialized */ -static void traceray(ShadeInput *origshi, ShadeResult *origshr, short depth, const float start[3], const float dir[3], float col[4], ObjectInstanceRen *obi, VlakRen *vlr, int traflag) -{ - ShadeInput shi = {NULL}; - Isect isec; - float dist_mir = origshi->mat->dist_mir; - - /* with high depth the number of rays can explode due to the path splitting - * in two each time, giving 2^depth rays. we need to be able to cancel such - * a render to avoid hanging, a better solution would be random picking - * between directions and russian roulette termination */ - if (R.test_break(R.tbh)) { - zero_v4(col); - return; - } - - copy_v3_v3(isec.start, start); - copy_v3_v3(isec.dir, dir); - isec.dist = dist_mir > 0 ? dist_mir : RE_RAYTRACE_MAXDIST; - isec.mode= RE_RAY_MIRROR; - isec.check = RE_CHECK_VLR_RENDER; - isec.skip = RE_SKIP_VLR_NEIGHBOUR; - isec.hint = NULL; - - isec.orig.ob = obi; - isec.orig.face = vlr; - RE_RC_INIT(isec, shi); - - /* database is in original view, obi->imat transforms current position back to original */ - RE_instance_rotate_ray(origshi->obi, &isec); - - if (RE_rayobject_raycast(R.raytree, &isec)) { - ShadeResult shr= {{0}}; - float d= 1.0f; - - RE_instance_rotate_ray_restore(origshi->obi, &isec); - - /* for as long we don't have proper dx/dy transform for rays we copy over original */ - copy_v3_v3(shi.dxco, origshi->dxco); - copy_v3_v3(shi.dyco, origshi->dyco); - - shi.mask= origshi->mask; - shi.osatex= origshi->osatex; - shi.depth= origshi->depth + 1; /* only used to indicate tracing */ - shi.thread= origshi->thread; - //shi.sample= 0; // memset above, so don't need this - shi.xs= origshi->xs; - shi.ys= origshi->ys; - shi.do_manage= origshi->do_manage; - shi.lay= origshi->lay; - shi.passflag= SCE_PASS_COMBINED; /* result of tracing needs no pass info */ - shi.combinedflag= 0xFFFFFF; /* ray trace does all options */ - //shi.do_preview = false; // memset above, so don't need this - - shade_ray(&isec, &shi, &shr); - /* ray has traveled inside the material, so shade by transmission */ - if (traflag & RAY_INSIDE) - d= shade_by_transmission(&isec, &shi, &shr); - - if (depth>0) { - float fr, fg, fb, f1; - - if ((shi.mat->mode_l & MA_TRANSP) && shr.alpha < 1.0f && (shi.mat->mode_l & (MA_ZTRANSP | MA_RAYTRANSP))) { - float nf, f, refract[3], tracol[4]; - - tracol[0]= shi.r; - tracol[1]= shi.g; - tracol[2]= shi.b; - tracol[3]= col[3]; /* we pass on and accumulate alpha */ - - if ((shi.mat->mode & MA_TRANSP) && (shi.mat->mode & MA_RAYTRANSP)) { - /* don't overwrite traflag, it's value is used in mirror reflection */ - int new_traflag = traflag; - - if (new_traflag & RAY_INSIDE) { - /* inside the material, so use inverse normal */ - float norm[3]; - norm[0]= - shi.vn[0]; - norm[1]= - shi.vn[1]; - norm[2]= - shi.vn[2]; - - if (refraction(refract, norm, shi.view, shi.ang)) { - /* ray comes out from the material into air */ - new_traflag &= ~RAY_INSIDE; - } - else { - /* total internal reflection (ray stays inside the material) */ - reflection(refract, norm, shi.view, shi.vn); - } - } - else { - if (refraction(refract, shi.vn, shi.view, shi.ang)) { - /* ray goes in to the material from air */ - new_traflag |= RAY_INSIDE; - } - else { - /* total external reflection (ray doesn't enter the material) */ - reflection(refract, shi.vn, shi.view, shi.vn); - } - } - traceray(origshi, origshr, depth-1, shi.co, refract, tracol, shi.obi, shi.vlr, new_traflag); - } - else - traceray(origshi, origshr, depth-1, shi.co, shi.view, tracol, shi.obi, shi.vlr, 0); - - f= shr.alpha; f1= 1.0f-f; - nf= (shi.mat->mode & MA_RAYTRANSP) ? d * shi.mat->filter : 0.0f; - fr= 1.0f+ nf*(shi.r-1.0f); - fg= 1.0f+ nf*(shi.g-1.0f); - fb= 1.0f+ nf*(shi.b-1.0f); - shr.diff[0]= f*shr.diff[0] + f1*fr*tracol[0]; - shr.diff[1]= f*shr.diff[1] + f1*fg*tracol[1]; - shr.diff[2]= f*shr.diff[2] + f1*fb*tracol[2]; - - shr.spec[0] *=f; - shr.spec[1] *=f; - shr.spec[2] *=f; - - col[3]= f1*tracol[3] + f; - } - else { - col[3]= 1.0f; - } - - float f; - if (shi.mat->mode_l & MA_RAYMIRROR) { - f= shi.ray_mirror; - if (f!=0.0f) f*= fresnel_fac(shi.view, shi.vn, shi.mat->fresnel_mir_i, shi.mat->fresnel_mir); - } - else f= 0.0f; - - if (f!=0.0f) { - float mircol[4]; - float ref[3]; - - reflection_simple(ref, shi.vn, shi.view); - traceray(origshi, origshr, depth-1, shi.co, ref, mircol, shi.obi, shi.vlr, traflag); - - f1= 1.0f-f; - - /* combine */ - //color_combine(col, f*fr*(1.0f-shr.spec[0]), f1, col, shr.diff); - //col[0]+= shr.spec[0]; - //col[1]+= shr.spec[1]; - //col[2]+= shr.spec[2]; - - fr= shi.mirr; - fg= shi.mirg; - fb= shi.mirb; - - col[0]= f*fr*(1.0f-shr.spec[0])*mircol[0] + f1*shr.diff[0] + shr.spec[0]; - col[1]= f*fg*(1.0f-shr.spec[1])*mircol[1] + f1*shr.diff[1] + shr.spec[1]; - col[2]= f*fb*(1.0f-shr.spec[2])*mircol[2] + f1*shr.diff[2] + shr.spec[2]; - } - else { - col[0]= shr.diff[0] + shr.spec[0]; - col[1]= shr.diff[1] + shr.spec[1]; - col[2]= shr.diff[2] + shr.spec[2]; - } - - if (dist_mir > 0.0f) { - float blendcol[3]; - - /* max ray distance set, but found an intersection, so fade this color - * out towards the sky/material color for a smooth transition */ - ray_fadeout_endcolor(blendcol, origshi, &shi, origshr, &isec, dir); - ray_fadeout(&isec, &shi, col, blendcol, dist_mir); - } - } - else { - col[0]= shr.diff[0] + shr.spec[0]; - col[1]= shr.diff[1] + shr.spec[1]; - col[2]= shr.diff[2] + shr.spec[2]; - } - - } - else { - ray_fadeout_endcolor(col, origshi, &shi, origshr, &isec, dir); - } - RE_RC_MERGE(&origshi->raycounter, &shi.raycounter); -} - -/* **************** jitter blocks ********** */ - -/* calc distributed planar energy */ - -static void DP_energy(float *table, float vec[2], int tot, float xsize, float ysize) -{ - int x, y, a; - float *fp, force[3], result[3]; - float dx, dy, dist, min; - - min= MIN2(xsize, ysize); - min*= min; - result[0]= result[1]= 0.0f; - - for (y= -1; y<2; y++) { - dy= ysize*y; - for (x= -1; x<2; x++) { - dx= xsize*x; - fp= table; - for (a=0; a<tot; a++, fp+= 2) { - force[0]= vec[0] - fp[0]-dx; - force[1]= vec[1] - fp[1]-dy; - dist= force[0]*force[0] + force[1]*force[1]; - if (dist < min && dist>0.0f) { - result[0]+= force[0]/dist; - result[1]+= force[1]/dist; - } - } - } - } - vec[0] += 0.1f*min*result[0]/(float)tot; - vec[1] += 0.1f*min*result[1]/(float)tot; - /* cyclic clamping */ - vec[0]= vec[0] - xsize*floorf(vec[0]/xsize + 0.5f); - vec[1]= vec[1] - ysize*floorf(vec[1]/ysize + 0.5f); -} - -/* random offset of 1 in 2 */ -static void jitter_plane_offset(float *jitter1, float *jitter2, int tot, float sizex, float sizey, float ofsx, float ofsy) -{ - float dsizex= sizex*ofsx; - float dsizey= sizey*ofsy; - float hsizex= 0.5f*sizex, hsizey= 0.5f*sizey; - int x; - - for (x=tot; x>0; x--, jitter1+=2, jitter2+=2) { - jitter2[0]= jitter1[0] + dsizex; - jitter2[1]= jitter1[1] + dsizey; - if (jitter2[0] > hsizex) jitter2[0]-= sizex; - if (jitter2[1] > hsizey) jitter2[1]-= sizey; - } -} - -/* called from convertBlenderScene.c */ -/* we do this in advance to get consistent random, not alter the render seed, and be threadsafe */ -void init_jitter_plane(LampRen *lar) -{ - float *fp; - int x, tot= lar->ray_totsamp; - - /* test if already initialized */ - if (lar->jitter) return; - - /* at least 4, or max threads+1 tables */ - if (BLENDER_MAX_THREADS < 4) x= 4; - else x= BLENDER_MAX_THREADS+1; - fp= lar->jitter= MEM_callocN(x*tot*2*sizeof(float), "lamp jitter tab"); - - /* if 1 sample, we leave table to be zero's */ - if (tot>1) { - /* set per-lamp fixed seed */ - RNG *rng = BLI_rng_new_srandom(tot); - int iter=12; - - /* fill table with random locations, area_size large */ - for (x=0; x<tot; x++, fp+=2) { - fp[0]= (BLI_rng_get_float(rng)-0.5f)*lar->area_size; - fp[1]= (BLI_rng_get_float(rng)-0.5f)*lar->area_sizey; - } - - while (iter--) { - fp= lar->jitter; - for (x=tot; x>0; x--, fp+=2) { - DP_energy(lar->jitter, fp, tot, lar->area_size, lar->area_sizey); - } - } - - BLI_rng_free(rng); - } - /* create the dithered tables (could just check lamp type!) */ - jitter_plane_offset(lar->jitter, lar->jitter+2*tot, tot, lar->area_size, lar->area_sizey, 0.5f, 0.0f); - jitter_plane_offset(lar->jitter, lar->jitter+4*tot, tot, lar->area_size, lar->area_sizey, 0.5f, 0.5f); - jitter_plane_offset(lar->jitter, lar->jitter+6*tot, tot, lar->area_size, lar->area_sizey, 0.0f, 0.5f); -} - -/* table around origin, -0.5*size to 0.5*size */ -static float *give_jitter_plane(LampRen *lar, int thread, int xs, int ys) -{ - int tot; - - tot= lar->ray_totsamp; - - if (lar->ray_samp_type & LA_SAMP_JITTER) { - /* made it threadsafe */ - - if (lar->xold[thread]!=xs || lar->yold[thread]!=ys) { - jitter_plane_offset(lar->jitter, lar->jitter+2*(thread+1)*tot, tot, lar->area_size, lar->area_sizey, BLI_thread_frand(thread), BLI_thread_frand(thread)); - lar->xold[thread]= xs; - lar->yold[thread]= ys; - } - return lar->jitter+2*(thread+1)*tot; - } - if (lar->ray_samp_type & LA_SAMP_DITHER) { - return lar->jitter + 2*tot*((xs & 1)+2*(ys & 1)); - } - - return lar->jitter; -} - - -/* **************** QMC sampling *************** */ - -static void UNUSED_FUNCTION(halton_sample)(double *ht_invprimes, double *ht_nums, double *v) -{ - /* incremental halton sequence generator, from: - * "Instant Radiosity", Keller A. */ - unsigned int i; - - for (i = 0; i < 2; i++) { - double r = fabs((1.0 - ht_nums[i]) - 1e-10); - - if (ht_invprimes[i] >= r) { - double lasth; - double h = ht_invprimes[i]; - - do { - lasth = h; - h *= ht_invprimes[i]; - } while (h >= r); - - ht_nums[i] += ((lasth + h) - 1.0); - } - else - ht_nums[i] += ht_invprimes[i]; - - v[i] = (float)ht_nums[i]; - } -} - -static struct QMCSampler *QMC_initSampler(int type, int tot) -{ - QMCSampler *qsa = MEM_callocN(sizeof(QMCSampler), "qmc sampler"); - qsa->samp2d = MEM_callocN(2*sizeof(double)*tot, "qmc sample table"); - - qsa->tot = tot; - qsa->type = type; - - if (qsa->type==SAMP_TYPE_HAMMERSLEY) - BLI_hammersley_2D_sequence(qsa->tot, qsa->samp2d); - - return qsa; -} - -static void QMC_initPixel(QMCSampler *qsa, int thread) -{ - if (qsa->type==SAMP_TYPE_HAMMERSLEY) { - /* hammersley sequence is fixed, already created in QMCSampler init. - * per pixel, gets a random offset. We create separate offsets per thread, for write-safety */ - qsa->offs[thread][0] = 0.5f * BLI_thread_frand(thread); - qsa->offs[thread][1] = 0.5f * BLI_thread_frand(thread); - } - else { /* SAMP_TYPE_HALTON */ - - /* generate a new randomized halton sequence per pixel - * to alleviate qmc artifacts and make it reproducible - * between threads/frames */ - double ht_offset[2]; - unsigned int ht_primes[2] = {2, 3}; - - ht_offset[0] = BLI_thread_frand(thread); - ht_offset[1] = BLI_thread_frand(thread); - - BLI_halton_2D_sequence(ht_primes, ht_offset, qsa->tot, qsa->samp2d); - } -} - -static void QMC_freeSampler(QMCSampler *qsa) -{ - MEM_freeN(qsa->samp2d); - MEM_freeN(qsa); -} - -static void QMC_getSample(double *s, QMCSampler *qsa, int thread, int num) -{ - if (qsa->type == SAMP_TYPE_HAMMERSLEY) { - s[0] = fmod(qsa->samp2d[2*num+0] + qsa->offs[thread][0], 1.0f); - s[1] = fmod(qsa->samp2d[2*num+1] + qsa->offs[thread][1], 1.0f); - } - else { /* SAMP_TYPE_HALTON */ - s[0] = qsa->samp2d[2*num+0]; - s[1] = qsa->samp2d[2*num+1]; - } -} - -/* phong weighted disc using 'blur' for exponent, centred on 0,0 */ -static void QMC_samplePhong(float vec[3], QMCSampler *qsa, int thread, int num, float blur) -{ - double s[2]; - float phi, pz, sqr; - - QMC_getSample(s, qsa, thread, num); - - phi = s[0]*2*M_PI; - pz = pow(s[1], blur); - sqr = sqrtf(1.0f - pz * pz); - - vec[0] = (float)(cosf(phi)*sqr); - vec[1] = (float)(sinf(phi)*sqr); - vec[2] = 0.0f; -} - -/* rect of edge lengths sizex, sizey, centred on 0.0,0.0 i.e. ranging from -sizex/2 to +sizey/2 */ -static void QMC_sampleRect(float vec[3], QMCSampler *qsa, int thread, int num, float sizex, float sizey) -{ - double s[2]; - - QMC_getSample(s, qsa, thread, num); - - vec[0] = (float)(s[0] - 0.5) * sizex; - vec[1] = (float)(s[1] - 0.5) * sizey; - vec[2] = 0.0f; -} - -/* disc of radius 'radius', centred on 0,0 */ -static void QMC_sampleDisc(float vec[3], QMCSampler *qsa, int thread, int num, float radius) -{ - double s[2]; - float phi, sqr; - - QMC_getSample(s, qsa, thread, num); - - phi = s[0]*2*M_PI; - sqr = sqrt(s[1]); - - vec[0] = cosf(phi)*sqr* radius/2.0f; - vec[1] = sinf(phi)*sqr* radius/2.0f; - vec[2] = 0.0f; -} - -/* uniform hemisphere sampling */ -static void QMC_sampleHemi(float vec[3], QMCSampler *qsa, int thread, int num) -{ - double s[2]; - float phi, sqr; - - QMC_getSample(s, qsa, thread, num); - - phi = s[0]*2.0*M_PI; - sqr = sqrt(s[1]); - - vec[0] = cosf(phi)*sqr; - vec[1] = sinf(phi)*sqr; - vec[2] = (float)(1.0 - s[1]*s[1]); -} - -#if 0 /* currently not used */ -/* cosine weighted hemisphere sampling */ -static void QMC_sampleHemiCosine(float vec[3], QMCSampler *qsa, int thread, int num) -{ - double s[2]; - float phi, sqr; - - QMC_getSample(s, qsa, thread, num); - - phi = s[0]*2.f*M_PI; - sqr = s[1]*sqrt(2-s[1]*s[1]); - - vec[0] = cos(phi)*sqr; - vec[1] = sin(phi)*sqr; - vec[2] = 1.f - s[1]*s[1]; - -} -#endif - -/* called from convertBlenderScene.c */ -void init_render_qmcsampler(Render *re) -{ - const int num_threads = re->r.threads; - re->qmcsamplers= MEM_callocN(sizeof(ListBase)*num_threads, "QMCListBase"); - re->num_qmc_samplers = num_threads; -} - -static QMCSampler *get_thread_qmcsampler(Render *re, int thread, int type, int tot) -{ - QMCSampler *qsa; - - /* create qmc samplers as needed, since recursion makes it hard to - * predict how many are needed */ - - for (qsa=re->qmcsamplers[thread].first; qsa; qsa=qsa->next) { - if (qsa->type == type && qsa->tot == tot && !qsa->used) { - qsa->used = true; - return qsa; - } - } - - qsa= QMC_initSampler(type, tot); - qsa->used = true; - BLI_addtail(&re->qmcsamplers[thread], qsa); - - return qsa; -} - -static void release_thread_qmcsampler(Render *UNUSED(re), int UNUSED(thread), QMCSampler *qsa) -{ - qsa->used= 0; -} - -void free_render_qmcsampler(Render *re) -{ - if (re->qmcsamplers) { - QMCSampler *qsa, *next; - int a; - for (a = 0; a < re->num_qmc_samplers; a++) { - for (qsa=re->qmcsamplers[a].first; qsa; qsa=next) { - next= qsa->next; - QMC_freeSampler(qsa); - } - - re->qmcsamplers[a].first= re->qmcsamplers[a].last= NULL; - } - - MEM_freeN(re->qmcsamplers); - re->qmcsamplers= NULL; - } -} - -static int adaptive_sample_variance(int samples, const float col[3], const float colsq[3], float thresh) -{ - float var[3], mean[3]; - - /* scale threshold just to give a bit more precision in input rather than dealing with - * tiny tiny numbers in the UI */ - thresh /= 2; - - mean[0] = col[0] / (float)samples; - mean[1] = col[1] / (float)samples; - mean[2] = col[2] / (float)samples; - - var[0] = (colsq[0] / (float)samples) - (mean[0]*mean[0]); - var[1] = (colsq[1] / (float)samples) - (mean[1]*mean[1]); - var[2] = (colsq[2] / (float)samples) - (mean[2]*mean[2]); - - if ((var[0] * 0.4f < thresh) && (var[1] * 0.3f < thresh) && (var[2] * 0.6f < thresh)) - return 1; - else - return 0; -} - -static int adaptive_sample_contrast_val(int samples, float prev, float val, float thresh) -{ - /* if the last sample's contribution to the total value was below a small threshold - * (i.e. the samples taken are very similar), then taking more samples that are probably - * going to be the same is wasting effort */ - if (fabsf(prev / (float)(samples - 1) - val / (float)samples ) < thresh) { - return 1; - } - else - return 0; -} - -static float get_avg_speed(ShadeInput *shi) -{ - float pre_x, pre_y, post_x, post_y, speedavg; - - pre_x = (shi->winspeed[0] == PASS_VECTOR_MAX)?0.0f:shi->winspeed[0]; - pre_y = (shi->winspeed[1] == PASS_VECTOR_MAX)?0.0f:shi->winspeed[1]; - post_x = (shi->winspeed[2] == PASS_VECTOR_MAX)?0.0f:shi->winspeed[2]; - post_y = (shi->winspeed[3] == PASS_VECTOR_MAX)?0.0f:shi->winspeed[3]; - - speedavg = (sqrtf(pre_x * pre_x + pre_y * pre_y) + sqrtf(post_x * post_x + post_y * post_y)) / 2.0f; - - return speedavg; -} - -/* ***************** main calls ************** */ - - -static void trace_refract(float col[4], ShadeInput *shi, ShadeResult *shr) -{ - QMCSampler *qsa=NULL; - int samp_type; - int traflag=0; - - float samp3d[3], orthx[3], orthy[3]; - float v_refract[3], v_refract_new[3]; - float sampcol[4], colsq[4]; - - float blur = pow3f(1.0f - shi->mat->gloss_tra); - short max_samples = shi->mat->samp_gloss_tra; - float adapt_thresh = shi->mat->adapt_thresh_tra; - - int samples=0; - - colsq[0] = colsq[1] = colsq[2] = 0.0; - col[0] = col[1] = col[2] = 0.0; - col[3]= shr->alpha; - - if (blur > 0.0f) { - if (adapt_thresh != 0.0f) samp_type = SAMP_TYPE_HALTON; - else samp_type = SAMP_TYPE_HAMMERSLEY; - - /* all samples are generated per pixel */ - qsa = get_thread_qmcsampler(&R, shi->thread, samp_type, max_samples); - QMC_initPixel(qsa, shi->thread); - } - else - max_samples = 1; - - - while (samples < max_samples) { - if (refraction(v_refract, shi->vn, shi->view, shi->ang)) { - traflag |= RAY_INSIDE; - } - else { - /* total external reflection can happen for materials with IOR < 1.0 */ - if ((shi->vlr->flag & R_SMOOTH)) - reflection(v_refract, shi->vn, shi->view, shi->facenor); - else - reflection_simple(v_refract, shi->vn, shi->view); - - /* can't blur total external reflection */ - max_samples = 1; - } - - if (max_samples > 1) { - /* get a quasi-random vector from a phong-weighted disc */ - QMC_samplePhong(samp3d, qsa, shi->thread, samples, blur); - - ortho_basis_v3v3_v3(orthx, orthy, v_refract); - mul_v3_fl(orthx, samp3d[0]); - mul_v3_fl(orthy, samp3d[1]); - - /* and perturb the refraction vector in it */ - add_v3_v3v3(v_refract_new, v_refract, orthx); - add_v3_v3(v_refract_new, orthy); - - normalize_v3(v_refract_new); - } - else { - /* no blurriness, use the original normal */ - copy_v3_v3(v_refract_new, v_refract); - } - - sampcol[0]= sampcol[1]= sampcol[2]= sampcol[3]= 0.0f; - - traceray(shi, shr, shi->mat->ray_depth_tra, shi->co, v_refract_new, sampcol, shi->obi, shi->vlr, traflag); - - col[0] += sampcol[0]; - col[1] += sampcol[1]; - col[2] += sampcol[2]; - col[3] += sampcol[3]; - - /* for variance calc */ - colsq[0] += sampcol[0]*sampcol[0]; - colsq[1] += sampcol[1]*sampcol[1]; - colsq[2] += sampcol[2]*sampcol[2]; - - samples++; - - /* adaptive sampling */ - if (adapt_thresh < 1.0f && samples > max_samples/2) { - if (adaptive_sample_variance(samples, col, colsq, adapt_thresh)) - break; - - /* if the pixel so far is very dark, we can get away with less samples */ - if ( (col[0] + col[1] + col[2])/3.0f/(float)samples < 0.01f ) - max_samples--; - } - } - - col[0] /= (float)samples; - col[1] /= (float)samples; - col[2] /= (float)samples; - col[3] /= (float)samples; - - if (qsa) - release_thread_qmcsampler(&R, shi->thread, qsa); -} - -static void trace_reflect(float col[3], ShadeInput *shi, ShadeResult *shr, float fresnelfac) -{ - QMCSampler *qsa=NULL; - int samp_type; - - float samp3d[3], orthx[3], orthy[3]; - float v_nor_new[3], v_reflect[3]; - float sampcol[4], colsq[4]; - - float blur = pow3f(1.0f - shi->mat->gloss_mir); - short max_samples = shi->mat->samp_gloss_mir; - float adapt_thresh = shi->mat->adapt_thresh_mir; - float aniso = 1.0f - shi->mat->aniso_gloss_mir; - - int samples=0; - - col[0] = col[1] = col[2] = 0.0; - colsq[0] = colsq[1] = colsq[2] = 0.0; - - if (blur > 0.0f) { - if (adapt_thresh != 0.0f) samp_type = SAMP_TYPE_HALTON; - else samp_type = SAMP_TYPE_HAMMERSLEY; - - /* all samples are generated per pixel */ - qsa = get_thread_qmcsampler(&R, shi->thread, samp_type, max_samples); - QMC_initPixel(qsa, shi->thread); - } - else - max_samples = 1; - - while (samples < max_samples) { - - if (max_samples > 1) { - /* get a quasi-random vector from a phong-weighted disc */ - QMC_samplePhong(samp3d, qsa, shi->thread, samples, blur); - - /* find the normal's perpendicular plane, blurring along tangents - * if tangent shading enabled */ - if (shi->mat->mode & (MA_TANGENT_V)) { - cross_v3_v3v3(orthx, shi->vn, shi->tang); // bitangent - copy_v3_v3(orthy, shi->tang); - mul_v3_fl(orthx, samp3d[0]); - mul_v3_fl(orthy, samp3d[1]*aniso); - } - else { - ortho_basis_v3v3_v3(orthx, orthy, shi->vn); - mul_v3_fl(orthx, samp3d[0]); - mul_v3_fl(orthy, samp3d[1]); - } - - /* and perturb the normal in it */ - add_v3_v3v3(v_nor_new, shi->vn, orthx); - add_v3_v3(v_nor_new, orthy); - normalize_v3(v_nor_new); - } - else { - /* no blurriness, use the original normal */ - copy_v3_v3(v_nor_new, shi->vn); - } - - if ((shi->vlr->flag & R_SMOOTH)) - reflection(v_reflect, v_nor_new, shi->view, shi->facenor); - else - reflection_simple(v_reflect, v_nor_new, shi->view); - - sampcol[0]= sampcol[1]= sampcol[2]= sampcol[3]= 0.0f; - - traceray(shi, shr, shi->mat->ray_depth, shi->co, v_reflect, sampcol, shi->obi, shi->vlr, 0); - - - col[0] += sampcol[0]; - col[1] += sampcol[1]; - col[2] += sampcol[2]; - - /* for variance calc */ - colsq[0] += sampcol[0]*sampcol[0]; - colsq[1] += sampcol[1]*sampcol[1]; - colsq[2] += sampcol[2]*sampcol[2]; - - samples++; - - /* adaptive sampling */ - if (adapt_thresh > 0.0f && samples > max_samples/3) { - if (adaptive_sample_variance(samples, col, colsq, adapt_thresh)) - break; - - /* if the pixel so far is very dark, we can get away with less samples */ - if ( (col[0] + col[1] + col[2])/3.0f/(float)samples < 0.01f ) - max_samples--; - - /* reduce samples when reflection is dim due to low ray mirror blend value or fresnel factor - * and when reflection is blurry */ - if (fresnelfac < 0.1f * (blur+1)) { - max_samples--; - - /* even more for very dim */ - if (fresnelfac < 0.05f * (blur+1)) - max_samples--; - } - } - } - - col[0] /= (float)samples; - col[1] /= (float)samples; - col[2] /= (float)samples; - - if (qsa) - release_thread_qmcsampler(&R, shi->thread, qsa); -} - -/* extern call from render loop */ -void ray_trace(ShadeInput *shi, ShadeResult *shr) -{ - float f1, fr, fg, fb; - float mircol[4], tracol[4]; - float diff[3]; - int do_tra, do_mir; - - do_tra = ((shi->mode & MA_TRANSP) && (shi->mode & MA_RAYTRANSP) && shr->alpha != 1.0f && (shi->depth <= shi->mat->ray_depth_tra)); - do_mir = ((shi->mat->mode & MA_RAYMIRROR) && shi->ray_mirror != 0.0f && (shi->depth <= shi->mat->ray_depth)); - - /* raytrace mirror and refract like to separate the spec color */ - if (shi->combinedflag & SCE_PASS_SPEC) - sub_v3_v3v3(diff, shr->combined, shr->spec); - else - copy_v3_v3(diff, shr->combined); - - if (do_tra) { - float olddiff[3], f; - - trace_refract(tracol, shi, shr); - - f= shr->alpha; f1= 1.0f-f; - fr= 1.0f+ shi->mat->filter*(shi->r-1.0f); - fg= 1.0f+ shi->mat->filter*(shi->g-1.0f); - fb= 1.0f+ shi->mat->filter*(shi->b-1.0f); - - /* for refract pass */ - copy_v3_v3(olddiff, diff); - - diff[0]= f*diff[0] + f1*fr*tracol[0]; - diff[1]= f*diff[1] + f1*fg*tracol[1]; - diff[2]= f*diff[2] + f1*fb*tracol[2]; - - if (shi->passflag & SCE_PASS_REFRACT) - sub_v3_v3v3(shr->refr, diff, olddiff); - - if (!(shi->combinedflag & SCE_PASS_REFRACT)) - sub_v3_v3v3(diff, diff, shr->refr); - - shr->alpha = min_ff(1.0f, tracol[3]); - } - - if (do_mir) { - const float i= shi->ray_mirror*fresnel_fac(shi->view, shi->vn, shi->mat->fresnel_mir_i, shi->mat->fresnel_mir); - if (i!=0.0f) { - - trace_reflect(mircol, shi, shr, i); - - fr= i*shi->mirr; - fg= i*shi->mirg; - fb= i*shi->mirb; - - if (shi->passflag & SCE_PASS_REFLECT) { - /* mirror pass is not blocked out with spec */ - shr->refl[0]= fr*mircol[0] - fr*diff[0]; - shr->refl[1]= fg*mircol[1] - fg*diff[1]; - shr->refl[2]= fb*mircol[2] - fb*diff[2]; - } - - if (shi->combinedflag & SCE_PASS_REFLECT) { - /* values in shr->spec can be greater than 1.0. - * In this case the mircol uses a zero blending factor, so ignoring it is ok. - * Fixes bug #18837 - when the spec is higher then 1.0, - * diff can become a negative color - Campbell */ - - f1= 1.0f-i; - - diff[0] *= f1; - diff[1] *= f1; - diff[2] *= f1; - - if (shr->spec[0]<1.0f) diff[0] += mircol[0] * (fr*(1.0f-shr->spec[0])); - if (shr->spec[1]<1.0f) diff[1] += mircol[1] * (fg*(1.0f-shr->spec[1])); - if (shr->spec[2]<1.0f) diff[2] += mircol[2] * (fb*(1.0f-shr->spec[2])); - } - } - } - /* put back together */ - if (shi->combinedflag & SCE_PASS_SPEC) - add_v3_v3v3(shr->combined, diff, shr->spec); - else - copy_v3_v3(shr->combined, diff); -} - -/* color 'shadfac' passes through 'col' with alpha and filter */ -/* filter is only applied on alpha defined transparent part */ -static void addAlphaLight(float shadfac[4], const float col[3], float alpha, float filter) -{ - float fr, fg, fb; - - fr= 1.0f+ filter*(col[0]-1.0f); - fg= 1.0f+ filter*(col[1]-1.0f); - fb= 1.0f+ filter*(col[2]-1.0f); - - shadfac[0]= alpha*col[0] + fr*(1.0f-alpha)*shadfac[0]; - shadfac[1]= alpha*col[1] + fg*(1.0f-alpha)*shadfac[1]; - shadfac[2]= alpha*col[2] + fb*(1.0f-alpha)*shadfac[2]; - - shadfac[3]= (1.0f-alpha)*shadfac[3]; -} - -static void ray_trace_shadow_tra(Isect *is, ShadeInput *origshi, int depth, int traflag, float col[4]) -{ - /* ray to lamp, find first face that intersects, check alpha properties, - * if it has col[3]>0.0f continue. so exit when alpha is full */ - const float initial_dist = is->dist; - - if (RE_rayobject_raycast(R.raytree, is)) { - /* Warning regarding initializing to zero's, This is not that nice, - * and possibly a bit slow for every ray, however some variables were - * not initialized properly in, unless using - * shade_input_initialize(...), we need to zero them. */ - ShadeInput shi= {NULL}; - /* end warning! - Campbell */ - - ShadeResult shr; - - /* we got a face */ - - shi.depth= origshi->depth + 1; /* only used to indicate tracing */ - shi.mask= origshi->mask; - shi.thread= origshi->thread; - shi.passflag= SCE_PASS_COMBINED; - shi.combinedflag= 0xFFFFFF; /* ray trace does all options */ - - shi.xs= origshi->xs; - shi.ys= origshi->ys; - shi.do_manage= origshi->do_manage; - shi.lay= origshi->lay; - shi.nodes= origshi->nodes; - - RE_instance_rotate_ray_restore(origshi->obi, is); - - shade_ray(is, &shi, &shr); - if (shi.mat->material_type == MA_TYPE_SURFACE) { - const float d = (shi.mat->mode & MA_RAYTRANSP) ? - ((traflag & RAY_TRA) ? shade_by_transmission(is, &shi, &shr) : 1.0f) : - 0.0f; - /* mix colors based on shadfac (rgb + amount of light factor) */ - addAlphaLight(col, shr.diff, shr.alpha, d*shi.mat->filter); - } - else if (shi.mat->material_type == MA_TYPE_VOLUME) { - const float a = col[3]; - - col[0] = a*col[0] + shr.alpha*shr.combined[0]; - col[1] = a*col[1] + shr.alpha*shr.combined[1]; - col[2] = a*col[2] + shr.alpha*shr.combined[2]; - - col[3] = (1.0f - shr.alpha)*a; - } - - if (depth>0 && col[3]>0.0f) { - - /* adapt isect struct */ - copy_v3_v3(is->start, shi.co); - is->dist = initial_dist-is->dist; - is->orig.ob = shi.obi; - is->orig.face = shi.vlr; - - ray_trace_shadow_tra(is, origshi, depth-1, traflag | RAY_TRA, col); - } - - RE_RC_MERGE(&origshi->raycounter, &shi.raycounter); - } -} - - -/* aolight: function to create random unit sphere vectors for total random sampling */ - -/* calc distributed spherical energy */ -static void DS_energy(float *sphere, int tot, float vec[3]) -{ - float *fp, fac, force[3], res[3]; - int a; - - res[0]= res[1]= res[2]= 0.0f; - - for (a=0, fp=sphere; a<tot; a++, fp+=3) { - sub_v3_v3v3(force, vec, fp); - fac = dot_v3v3(force, force); - if (fac!=0.0f) { - fac= 1.0f/fac; - res[0]+= fac*force[0]; - res[1]+= fac*force[1]; - res[2]+= fac*force[2]; - } - } - - mul_v3_fl(res, 0.5); - add_v3_v3(vec, res); - normalize_v3(vec); - -} - -/* called from convertBlenderScene.c */ -/* creates an equally distributed spherical sample pattern */ -/* and allocates threadsafe memory */ -void init_ao_sphere(Render *re, World *wrld) -{ - /* fixed random */ - const int num_threads = re->r.threads; - RNG *rng; - float *fp; - int a, tot, iter= 16; - - /* we make twice the amount of samples, because only a hemisphere is used */ - tot= 2*wrld->aosamp*wrld->aosamp; - - wrld->aosphere= MEM_mallocN(3*tot*sizeof(float), "AO sphere"); - rng = BLI_rng_new_srandom(tot); - - /* init */ - fp= wrld->aosphere; - for (a=0; a<tot; a++, fp+= 3) { - BLI_rng_get_float_unit_v3(rng, fp); - } - - while (iter--) { - for (a=0, fp= wrld->aosphere; a<tot; a++, fp+= 3) { - DS_energy(wrld->aosphere, tot, fp); - } - } - - /* tables */ - wrld->aotables= MEM_mallocN(num_threads*3*tot*sizeof(float), "AO tables"); - - BLI_rng_free(rng); -} - -/* give per thread a table, we have to compare xs ys because of way OSA works... */ -static float *threadsafe_table_sphere(int test, int thread, int xs, int ys, int tot) -{ - static int xso[BLENDER_MAX_THREADS], yso[BLENDER_MAX_THREADS]; - static int firsttime= 1; - - if (firsttime) { - memset(xso, 255, sizeof(xso)); - memset(yso, 255, sizeof(yso)); - firsttime= 0; - } - - if (xs==xso[thread] && ys==yso[thread]) return R.wrld.aotables+ thread*tot*3; - if (test) return NULL; - xso[thread]= xs; yso[thread]= ys; - return R.wrld.aotables+ thread*tot*3; -} - -static float *sphere_sampler(int type, int resol, int thread, int xs, int ys, int reset) -{ - int tot; - float *vec; - - tot= 2*resol*resol; - - if (type & WO_AORNDSMP) { - /* total random sampling. NOT THREADSAFE! (should be removed, is not useful) */ - RNG *rng = BLI_rng_new(BLI_thread_rand(thread)); - float *sphere; - int a; - - /* always returns table */ - sphere= threadsafe_table_sphere(0, thread, xs, ys, tot); - - vec= sphere; - for (a=0; a<tot; a++, vec+=3) { - BLI_rng_get_float_unit_v3(rng, vec); - } - - BLI_rng_free(rng); - - return sphere; - } - else { - float *sphere; - float *vec1; - - /* returns table if xs and ys were equal to last call, and not resetting */ - sphere= (reset)? NULL: threadsafe_table_sphere(1, thread, xs, ys, tot); - if (sphere==NULL) { - float cosfi, sinfi, cost, sint; - float ang; - int a; - - sphere= threadsafe_table_sphere(0, thread, xs, ys, tot); - - /* random rotation */ - ang = BLI_thread_frand(thread); - sinfi = sinf(ang); cosfi = cosf(ang); - ang = BLI_thread_frand(thread); - sint = sinf(ang); cost = cosf(ang); - - vec= R.wrld.aosphere; - vec1= sphere; - for (a=0; a<tot; a++, vec+=3, vec1+=3) { - vec1[0]= cost*cosfi*vec[0] - sinfi*vec[1] + sint*cosfi*vec[2]; - vec1[1]= cost*sinfi*vec[0] + cosfi*vec[1] + sint*sinfi*vec[2]; - vec1[2]= -sint*vec[0] + cost*vec[2]; - } - } - return sphere; - } -} - -static void ray_ao_qmc(ShadeInput *shi, float ao[3], float env[3]) -{ - Isect isec; - RayHint point_hint; - QMCSampler *qsa=NULL; - float samp3d[3]; - float up[3], side[3], dir[3], nrm[3]; - - float maxdist = R.wrld.aodist; - float fac=0.0f, prev=0.0f; - float adapt_thresh = R.wrld.ao_adapt_thresh; - float adapt_speed_fac = R.wrld.ao_adapt_speed_fac; - - int samples=0; - int max_samples = R.wrld.aosamp*R.wrld.aosamp; - - float dxyview[3], skyadded=0; - int envcolor; - - RE_RC_INIT(isec, *shi); - isec.orig.ob = shi->obi; - isec.orig.face = shi->vlr; - isec.check = RE_CHECK_VLR_NON_SOLID_MATERIAL; - isec.skip = RE_SKIP_VLR_NEIGHBOUR; - isec.hint = NULL; - - isec.hit.ob = NULL; - isec.hit.face = NULL; - - isec.last_hit = NULL; - - isec.mode= (R.wrld.aomode & WO_AODIST)?RE_RAY_SHADOW_TRA:RE_RAY_SHADOW; - isec.lay= -1; - - copy_v3_v3(isec.start, shi->co); - - RE_instance_rotate_ray_start(shi->obi, &isec); - - RE_rayobject_hint_bb(R.raytree, &point_hint, isec.start, isec.start); - isec.hint = &point_hint; - - zero_v3(ao); - zero_v3(env); - - /* prevent sky colors to be added for only shadow (shadow becomes alpha) */ - envcolor= R.wrld.aocolor; - if (shi->mat->mode & MA_ONLYSHADOW) - envcolor= WO_AOPLAIN; - - if (envcolor == WO_AOSKYTEX) { - dxyview[0]= 1.0f/(float)R.wrld.aosamp; - dxyview[1]= 1.0f/(float)R.wrld.aosamp; - dxyview[2]= 0.0f; - } - - if (shi->vlr->flag & R_SMOOTH) { - copy_v3_v3(nrm, shi->vn); - } - else { - copy_v3_v3(nrm, shi->facenor); - } - - ortho_basis_v3v3_v3(up, side, nrm); - - /* sampling init */ - if (R.wrld.ao_samp_method==WO_AOSAMP_HALTON) { - float speedfac; - - speedfac = get_avg_speed(shi) * adapt_speed_fac; - CLAMP(speedfac, 1.0f, 1000.0f); - max_samples /= speedfac; - if (max_samples < 5) max_samples = 5; - - qsa = get_thread_qmcsampler(&R, shi->thread, SAMP_TYPE_HALTON, max_samples); - } - else if (R.wrld.ao_samp_method==WO_AOSAMP_HAMMERSLEY) - qsa = get_thread_qmcsampler(&R, shi->thread, SAMP_TYPE_HAMMERSLEY, max_samples); - - QMC_initPixel(qsa, shi->thread); - - while (samples < max_samples) { - - /* sampling, returns quasi-random vector in unit hemisphere */ - QMC_sampleHemi(samp3d, qsa, shi->thread, samples); - - dir[0] = (samp3d[0]*up[0] + samp3d[1]*side[0] + samp3d[2]*nrm[0]); - dir[1] = (samp3d[0]*up[1] + samp3d[1]*side[1] + samp3d[2]*nrm[1]); - dir[2] = (samp3d[0]*up[2] + samp3d[1]*side[2] + samp3d[2]*nrm[2]); - - normalize_v3(dir); - - isec.dir[0] = -dir[0]; - isec.dir[1] = -dir[1]; - isec.dir[2] = -dir[2]; - isec.dist = maxdist; - - RE_instance_rotate_ray_dir(shi->obi, &isec); - - prev = fac; - - if (RE_rayobject_raycast(R.raytree, &isec)) { - if (R.wrld.aomode & WO_AODIST) fac+= expf(-isec.dist*R.wrld.aodistfac); - else fac+= 1.0f; - } - else if (envcolor!=WO_AOPLAIN) { - float skycol[4]; - float view[3]; - - view[0]= -dir[0]; - view[1]= -dir[1]; - view[2]= -dir[2]; - normalize_v3(view); - - if (envcolor==WO_AOSKYCOL) { - const float skyfac= 0.5f * (1.0f + dot_v3v3(view, R.grvec)); - env[0]+= (1.0f-skyfac)*R.wrld.horr + skyfac*R.wrld.zenr; - env[1]+= (1.0f-skyfac)*R.wrld.horg + skyfac*R.wrld.zeng; - env[2]+= (1.0f-skyfac)*R.wrld.horb + skyfac*R.wrld.zenb; - } - else { /* WO_AOSKYTEX */ - shadeSkyView(skycol, isec.start, view, dxyview, shi->thread); - shadeSunView(skycol, shi->view); - env[0]+= skycol[0]; - env[1]+= skycol[1]; - env[2]+= skycol[2]; - } - skyadded++; - } - - samples++; - - if (qsa && qsa->type == SAMP_TYPE_HALTON) { - /* adaptive sampling - consider samples below threshold as in shadow (or vice versa) and exit early */ - if (adapt_thresh > 0.0f && (samples > max_samples/2) ) { - - if (adaptive_sample_contrast_val(samples, prev, fac, adapt_thresh)) { - break; - } - } - } - } - - /* average color times distances/hits formula */ - ao[0]= ao[1]= ao[2]= 1.0f - fac/(float)samples; - - if (envcolor!=WO_AOPLAIN && skyadded) - mul_v3_fl(env, (1.0f - fac/(float)samples)/((float)skyadded)); - else - copy_v3_v3(env, ao); - - if (qsa) - release_thread_qmcsampler(&R, shi->thread, qsa); -} - -/* extern call from shade_lamp_loop, ambient occlusion calculus */ -static void ray_ao_spheresamp(ShadeInput *shi, float ao[3], float env[3]) -{ - Isect isec; - RayHint point_hint; - float *vec, *nrm, bias, sh=0.0f; - float maxdist = R.wrld.aodist; - float dxyview[3]; - int j= -1, tot, actual=0, skyadded=0, envcolor, resol= R.wrld.aosamp; - - RE_RC_INIT(isec, *shi); - isec.orig.ob = shi->obi; - isec.orig.face = shi->vlr; - isec.check = RE_CHECK_VLR_RENDER; - isec.skip = RE_SKIP_VLR_NEIGHBOUR; - isec.hint = NULL; - - isec.hit.ob = NULL; - isec.hit.face = NULL; - - isec.last_hit = NULL; - - isec.mode= (R.wrld.aomode & WO_AODIST)?RE_RAY_SHADOW_TRA:RE_RAY_SHADOW; - isec.lay= -1; - - copy_v3_v3(isec.start, shi->co); - RE_instance_rotate_ray_start(shi->obi, &isec); - - RE_rayobject_hint_bb(R.raytree, &point_hint, isec.start, isec.start); - isec.hint = &point_hint; - - zero_v3(ao); - zero_v3(env); - - /* bias prevents smoothed faces to appear flat */ - if (shi->vlr->flag & R_SMOOTH) { - bias= R.wrld.aobias; - nrm= shi->vn; - } - else { - bias= 0.0f; - nrm= shi->facenor; - } - - /* prevent sky colors to be added for only shadow (shadow becomes alpha) */ - envcolor= R.wrld.aocolor; - if (shi->mat->mode & MA_ONLYSHADOW) - envcolor= WO_AOPLAIN; - - if (resol>32) resol= 32; - - /* get sphere samples. for faces we get the same samples for sample x/y values, - * for strand render we always require a new sampler because x/y are not set */ - vec= sphere_sampler(R.wrld.aomode, resol, shi->thread, shi->xs, shi->ys, shi->strand != NULL); - - /* warning: since we use full sphere now, and dotproduct is below, we do twice as much */ - tot= 2*resol*resol; - - if (envcolor == WO_AOSKYTEX) { - dxyview[0]= 1.0f/(float)resol; - dxyview[1]= 1.0f/(float)resol; - dxyview[2]= 0.0f; - } - - while (tot--) { - - if (dot_v3v3(vec, nrm) > bias) { - /* only ao samples for mask */ - if (R.r.mode & R_OSA) { - j++; - if (j==R.osa) j= 0; - if (!(shi->mask & (1<<j))) { - vec+=3; - continue; - } - } - - actual++; - - /* always set start/vec/dist */ - isec.dir[0] = -vec[0]; - isec.dir[1] = -vec[1]; - isec.dir[2] = -vec[2]; - isec.dist = maxdist; - - RE_instance_rotate_ray_dir(shi->obi, &isec); - - /* do the trace */ - if (RE_rayobject_raycast(R.raytree, &isec)) { - if (R.wrld.aomode & WO_AODIST) sh+= expf(-isec.dist*R.wrld.aodistfac); - else sh+= 1.0f; - } - else if (envcolor!=WO_AOPLAIN) { - float skycol[4]; - float view[3]; - - view[0]= -vec[0]; - view[1]= -vec[1]; - view[2]= -vec[2]; - normalize_v3(view); - - if (envcolor==WO_AOSKYCOL) { - const float fac = 0.5f * (1.0f + dot_v3v3(view, R.grvec)); - env[0]+= (1.0f-fac)*R.wrld.horr + fac*R.wrld.zenr; - env[1]+= (1.0f-fac)*R.wrld.horg + fac*R.wrld.zeng; - env[2]+= (1.0f-fac)*R.wrld.horb + fac*R.wrld.zenb; - } - else { /* WO_AOSKYTEX */ - shadeSkyView(skycol, isec.start, view, dxyview, shi->thread); - shadeSunView(skycol, shi->view); - env[0]+= skycol[0]; - env[1]+= skycol[1]; - env[2]+= skycol[2]; - } - skyadded++; - } - } - /* samples */ - vec+= 3; - } - - if (actual==0) sh= 1.0f; - else sh = 1.0f - sh/((float)actual); - - /* average color times distances/hits formula */ - ao[0]= ao[1]= ao[2]= sh; - - if (envcolor!=WO_AOPLAIN && skyadded) - mul_v3_fl(env, sh/((float)skyadded)); - else - copy_v3_v3(env, ao); -} - -void ray_ao(ShadeInput *shi, float ao[3], float env[3]) -{ - /* Unfortunately, the unusual way that the sphere sampler calculates roughly twice as many - * samples as are actually traced, and skips them based on bias and OSA settings makes it very difficult - * to reuse code between these two functions. This is the easiest way I can think of to do it - * --broken */ - if (ELEM(R.wrld.ao_samp_method, WO_AOSAMP_HAMMERSLEY, WO_AOSAMP_HALTON)) - ray_ao_qmc(shi, ao, env); - else if (R.wrld.ao_samp_method == WO_AOSAMP_CONSTANT) - ray_ao_spheresamp(shi, ao, env); -} - -static void ray_shadow_jittered_coords(ShadeInput *shi, int max, float jitco[RE_MAX_OSA][3], int *totjitco) -{ - /* magic numbers for reordering sample positions to give better - * results with adaptive sample, when it usually only takes 4 samples */ - int order8[8] = {0, 1, 5, 6, 2, 3, 4, 7}; - int order11[11] = {1, 3, 8, 10, 0, 2, 4, 5, 6, 7, 9}; - int order16[16] = {1, 3, 9, 12, 0, 6, 7, 8, 13, 2, 4, 5, 10, 11, 14, 15}; - int count = count_mask(shi->mask); - - /* for better antialising shadow samples are distributed over the subpixel - * sample coordinates, this only works for raytracing depth 0 though */ - if (!shi->strand && shi->depth == 0 && count > 1 && count <= max) { - float xs, ys, zs, view[3]; - int samp, ordsamp, tot= 0; - - for (samp=0; samp<R.osa; samp++) { - if (R.osa == 8) ordsamp = order8[samp]; - else if (R.osa == 11) ordsamp = order11[samp]; - else if (R.osa == 16) ordsamp = order16[samp]; - else ordsamp = samp; - - if (shi->mask & (1<<ordsamp)) { - /* zbuffer has this inverse corrected, ensures xs,ys are inside pixel */ - xs= (float)shi->scanco[0] + R.jit[ordsamp][0] + 0.5f; - ys= (float)shi->scanco[1] + R.jit[ordsamp][1] + 0.5f; - zs= shi->scanco[2]; - - shade_input_calc_viewco(shi, xs, ys, zs, view, NULL, jitco[tot], NULL, NULL); - tot++; - } - } - - *totjitco= tot; - } - else { - copy_v3_v3(jitco[0], shi->co); - *totjitco= 1; - } -} - -static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, const float lampco[3], float shadfac[4], Isect *isec) -{ - QMCSampler *qsa=NULL; - int samples=0; - float samp3d[3]; - - float fac=0.0f, vec[3], end[3]; - float colsq[4]; - float adapt_thresh = lar->adapt_thresh; - int min_adapt_samples=4, max_samples = lar->ray_totsamp; - float start[3]; - bool do_soft = true, full_osa = false; - int i; - - float min[3], max[3]; - RayHint bb_hint; - - float jitco[RE_MAX_OSA][3]; - int totjitco; - - colsq[0] = colsq[1] = colsq[2] = 0.0; - if (isec->mode==RE_RAY_SHADOW_TRA) { - shadfac[0]= shadfac[1]= shadfac[2]= shadfac[3]= 0.0f; - } - else - shadfac[3]= 1.0f; - - if (lar->ray_totsamp < 2) do_soft = false; - if ((R.r.mode & R_OSA) && (R.osa > 0) && (shi->vlr->flag & R_FULL_OSA)) full_osa = true; - - if (full_osa) { - if (do_soft) max_samples = max_samples/R.osa + 1; - else max_samples = 1; - } - else { - if (do_soft) max_samples = lar->ray_totsamp; - else if (shi->depth == 0) max_samples = (R.osa > 4)?R.osa:5; - else max_samples = 1; - } - - ray_shadow_jittered_coords(shi, max_samples, jitco, &totjitco); - - /* sampling init */ - if (lar->ray_samp_method==LA_SAMP_HALTON) - qsa = get_thread_qmcsampler(&R, shi->thread, SAMP_TYPE_HALTON, max_samples); - else if (lar->ray_samp_method==LA_SAMP_HAMMERSLEY) - qsa = get_thread_qmcsampler(&R, shi->thread, SAMP_TYPE_HAMMERSLEY, max_samples); - - QMC_initPixel(qsa, shi->thread); - - INIT_MINMAX(min, max); - for (i = 0; i < totjitco; i++) { - minmax_v3v3_v3(min, max, jitco[i]); - } - if (shi->obi->flag & R_ENV_TRANSFORMED) { - mul_m4_v3(shi->obi->imat, min); - mul_m4_v3(shi->obi->imat, max); - } - RE_rayobject_hint_bb(R.raytree, &bb_hint, min, max); - - isec->hint = &bb_hint; - isec->check = RE_CHECK_VLR_RENDER; - isec->skip = RE_SKIP_VLR_NEIGHBOUR; - copy_v3_v3(vec, lampco); - - while (samples < max_samples) { - - isec->orig.ob = shi->obi; - isec->orig.face = shi->vlr; - - /* manually jitter the start shading co-ord per sample - * based on the pre-generated OSA texture sampling offsets, - * for anti-aliasing sharp shadow edges. */ - copy_v3_v3(start, jitco[samples % totjitco]); - - if (do_soft) { - /* sphere shadow source */ - if (lar->type == LA_LOCAL) { - float ru[3], rv[3], v[3], s[3]; - - /* calc tangent plane vectors */ - sub_v3_v3v3(v, start, lampco); - normalize_v3(v); - ortho_basis_v3v3_v3(ru, rv, v); - - /* sampling, returns quasi-random vector in area_size disc */ - QMC_sampleDisc(samp3d, qsa, shi->thread, samples, lar->area_size); - - /* distribute disc samples across the tangent plane */ - s[0] = samp3d[0]*ru[0] + samp3d[1]*rv[0]; - s[1] = samp3d[0]*ru[1] + samp3d[1]*rv[1]; - s[2] = samp3d[0]*ru[2] + samp3d[1]*rv[2]; - - copy_v3_v3(samp3d, s); - } - else { - /* sampling, returns quasi-random vector in [sizex,sizey]^2 plane */ - QMC_sampleRect(samp3d, qsa, shi->thread, samples, lar->area_size, lar->area_sizey); - - /* align samples to lamp vector */ - mul_m3_v3(lar->mat, samp3d); - } - end[0] = vec[0]+samp3d[0]; - end[1] = vec[1]+samp3d[1]; - end[2] = vec[2]+samp3d[2]; - } - else { - copy_v3_v3(end, vec); - } - - if (shi->strand) { - /* bias away somewhat to avoid self intersection */ - float jitbias= 0.5f*(len_v3(shi->dxco) + len_v3(shi->dyco)); - float v[3]; - - sub_v3_v3v3(v, start, end); - normalize_v3(v); - - start[0] -= jitbias*v[0]; - start[1] -= jitbias*v[1]; - start[2] -= jitbias*v[2]; - } - - copy_v3_v3(isec->start, start); - sub_v3_v3v3(isec->dir, end, start); - isec->dist = normalize_v3(isec->dir); - - RE_instance_rotate_ray(shi->obi, isec); - - /* trace the ray */ - if (isec->mode==RE_RAY_SHADOW_TRA) { - float col[4] = {1.0f, 1.0f, 1.0f, 1.0f}; - - ray_trace_shadow_tra(isec, shi, DEPTH_SHADOW_TRA, 0, col); - shadfac[0] += col[0]; - shadfac[1] += col[1]; - shadfac[2] += col[2]; - shadfac[3] += col[3]; - - /* for variance calc */ - colsq[0] += col[0]*col[0]; - colsq[1] += col[1]*col[1]; - colsq[2] += col[2]*col[2]; - } - else { - if ( RE_rayobject_raycast(R.raytree, isec) ) fac+= 1.0f; - } - - samples++; - - if (lar->ray_samp_method == LA_SAMP_HALTON) { - - /* adaptive sampling - consider samples below threshold as in shadow (or vice versa) and exit early */ - if ((max_samples > min_adapt_samples) && (adapt_thresh > 0.0f) && (samples > max_samples / 3)) { - if (isec->mode==RE_RAY_SHADOW_TRA) { - if ((shadfac[3] / samples > (1.0f-adapt_thresh)) || (shadfac[3] / samples < adapt_thresh)) - break; - else if (adaptive_sample_variance(samples, shadfac, colsq, adapt_thresh)) - break; - } - else { - if ((fac / samples > (1.0f-adapt_thresh)) || (fac / samples < adapt_thresh)) - break; - } - } - } - } - - if (isec->mode==RE_RAY_SHADOW_TRA) { - shadfac[0] /= samples; - shadfac[1] /= samples; - shadfac[2] /= samples; - shadfac[3] /= samples; - } - else - shadfac[3]= 1.0f-fac/samples; - - if (qsa) - release_thread_qmcsampler(&R, shi->thread, qsa); -} - -static void ray_shadow_jitter(ShadeInput *shi, LampRen *lar, const float lampco[3], float shadfac[4], Isect *isec) -{ - /* area soft shadow */ - const float *jitlamp; - float fac=0.0f, div=0.0f, vec[3]; - int a, j= -1, mask; - RayHint point_hint; - - if (isec->mode==RE_RAY_SHADOW_TRA) { - shadfac[0]= shadfac[1]= shadfac[2]= shadfac[3]= 0.0f; - } - else shadfac[3]= 1.0f; - - fac= 0.0f; - jitlamp= give_jitter_plane(lar, shi->thread, shi->xs, shi->ys); - - a= lar->ray_totsamp; - - /* this correction to make sure we always take at least 1 sample */ - mask= shi->mask; - if (a==4) mask |= (mask>>4)|(mask>>8); - else if (a==9) mask |= (mask>>9); - - copy_v3_v3(isec->start, shi->co); - RE_instance_rotate_ray_start(shi->obi, isec); - - isec->orig.ob = shi->obi; - isec->orig.face = shi->vlr; - RE_rayobject_hint_bb(R.raytree, &point_hint, isec->start, isec->start); - isec->hint = &point_hint; - - while (a--) { - - if (R.r.mode & R_OSA) { - j++; - if (j>=R.osa) j= 0; - if (!(mask & (1<<j))) { - jitlamp+= 2; - continue; - } - } - - vec[0]= jitlamp[0]; - vec[1]= jitlamp[1]; - vec[2]= 0.0f; - mul_m3_v3(lar->mat, vec); - - /* set start and vec */ - isec->dir[0] = vec[0]+lampco[0]-shi->co[0]; - isec->dir[1] = vec[1]+lampco[1]-shi->co[1]; - isec->dir[2] = vec[2]+lampco[2]-shi->co[2]; - - RE_instance_rotate_ray_dir(shi->obi, isec); - - isec->dist = 1.0f; - isec->check = RE_CHECK_VLR_RENDER; - isec->skip = RE_SKIP_VLR_NEIGHBOUR; - - if (isec->mode==RE_RAY_SHADOW_TRA) { - /* isec.col is like shadfac, so defines amount of light (0.0 is full shadow) */ - float col[4] = {1.0f, 1.0f, 1.0f, 1.0f}; - - ray_trace_shadow_tra(isec, shi, DEPTH_SHADOW_TRA, 0, col); - shadfac[0] += col[0]; - shadfac[1] += col[1]; - shadfac[2] += col[2]; - shadfac[3] += col[3]; - } - else if ( RE_rayobject_raycast(R.raytree, isec) ) fac+= 1.0f; - - div+= 1.0f; - jitlamp+= 2; - } - - if (isec->mode==RE_RAY_SHADOW_TRA) { - shadfac[0] /= div; - shadfac[1] /= div; - shadfac[2] /= div; - shadfac[3] /= div; - } - else { - /* sqrt makes nice umbra effect */ - if (lar->ray_samp_type & LA_SAMP_UMBRA) - shadfac[3] = sqrtf(1.0f - fac / div); - else - shadfac[3] = 1.0f - fac / div; - } -} -/* extern call from shade_lamp_loop */ -void ray_shadow(ShadeInput *shi, LampRen *lar, float shadfac[4]) -{ - Isect isec; - float lampco[3]; - - /* setup isec */ - RE_RC_INIT(isec, *shi); - if (shi->mat->mode & MA_SHADOW_TRA) isec.mode= RE_RAY_SHADOW_TRA; - else isec.mode= RE_RAY_SHADOW; - isec.hint = NULL; - - if (lar->mode & (LA_LAYER|LA_LAYER_SHADOW)) - isec.lay= lar->lay; - else - isec.lay= -1; - - /* only when not mir tracing, first hit optimm */ - if (shi->depth==0) { - isec.last_hit = lar->last_hit[shi->thread]; - } - else { - isec.last_hit = NULL; - } - - if (lar->type==LA_SUN || lar->type==LA_HEMI) { - /* jitter and QMC sampling add a displace vector to the lamp position - * that's incorrect because a SUN lamp does not has an exact position - * and the displace should be done at the ray vector instead of the - * lamp position. - * This is easily verified by noticing that shadows of SUN lights change - * with the scene BB. - * - * This was detected during SoC 2009 - Raytrace Optimization, but to keep - * consistency with older render code it wasn't removed. - * - * If the render code goes through some recode/serious bug-fix then this - * is something to consider! - */ - lampco[0]= shi->co[0] - R.maxdist*lar->vec[0]; - lampco[1]= shi->co[1] - R.maxdist*lar->vec[1]; - lampco[2]= shi->co[2] - R.maxdist*lar->vec[2]; - } - else { - copy_v3_v3(lampco, lar->co); - } - - if (ELEM(lar->ray_samp_method, LA_SAMP_HALTON, LA_SAMP_HAMMERSLEY)) { - - ray_shadow_qmc(shi, lar, lampco, shadfac, &isec); - - } - else { - if (lar->ray_totsamp<2) { - - isec.orig.ob = shi->obi; - isec.orig.face = shi->vlr; - - shadfac[3]= 1.0f; /* 1.0=full light */ - - /* set up isec.dir */ - copy_v3_v3(isec.start, shi->co); - sub_v3_v3v3(isec.dir, lampco, isec.start); - isec.dist = normalize_v3(isec.dir); - - RE_instance_rotate_ray(shi->obi, &isec); - - if (isec.mode==RE_RAY_SHADOW_TRA) { - /* isec.col is like shadfac, so defines amount of light (0.0 is full shadow) */ - float col[4] = {1.0f, 1.0f, 1.0f, 1.0f}; - - ray_trace_shadow_tra(&isec, shi, DEPTH_SHADOW_TRA, 0, col); - copy_v4_v4(shadfac, col); - } - else if (RE_rayobject_raycast(R.raytree, &isec)) - shadfac[3]= 0.0f; - } - else { - ray_shadow_jitter(shi, lar, lampco, shadfac, &isec); - } - } - - /* for first hit optim, set last interesected shadow face */ - if (shi->depth==0) { - lar->last_hit[shi->thread] = isec.last_hit; - } - -} - diff --git a/source/blender/render/intern/source/render_result.c b/source/blender/render/intern/source/render_result.c index 5abef431f3d..ba12eac3efa 100644 --- a/source/blender/render/intern/source/render_result.c +++ b/source/blender/render/intern/source/render_result.c @@ -408,7 +408,7 @@ RenderResult *render_result_new(Render *re, rcti *partrct, int crop, int savebuf } FOREACH_VIEW_LAYER_TO_RENDER_END; - /* sss, previewrender and envmap don't do layers, so we make a default one */ + /* previewrender doesn't do layers, so we make a default one */ if (BLI_listbase_is_empty(&rr->layers) && !(layername && layername[0])) { rl = MEM_callocN(sizeof(RenderLayer), "new render layer"); BLI_addtail(&rr->layers, rl); @@ -505,23 +505,6 @@ void render_result_add_pass(RenderResult *rr, const char *name, int channels, co } } -/* allocate osa new results for samples */ -RenderResult *render_result_new_full_sample(Render *re, ListBase *lb, rcti *partrct, int crop, int savebuffers, const char *viewname) -{ - int a; - - if (re->osa == 0) - return render_result_new(re, partrct, crop, savebuffers, RR_ALL_LAYERS, viewname); - - for (a = 0; a < re->osa; a++) { - RenderResult *rr = render_result_new(re, partrct, crop, savebuffers, RR_ALL_LAYERS, viewname); - BLI_addtail(lb, rr); - rr->sample_nr = a; - } - - return lb->first; -} - static int passtype_from_name(const char *name) { const char delim[] = {'.', '\0'}; @@ -1090,8 +1073,8 @@ void render_result_save_empty_result_tiles(Render *re) for (rl = rr->layers.first; rl; rl = rl->next) { for (pa = re->parts.first; pa; pa = pa->next) { if (pa->status != PART_STATUS_MERGED) { - int party = pa->disprect.ymin - re->disprect.ymin + pa->crop; - int partx = pa->disprect.xmin - re->disprect.xmin + pa->crop; + int party = pa->disprect.ymin - re->disprect.ymin; + int partx = pa->disprect.xmin - re->disprect.xmin; IMB_exrtile_write_channels(rl->exrhandle, partx, party, 0, re->viewname, true); } } diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c index 929fc3cc9c3..79d13ecab5b 100644 --- a/source/blender/render/intern/source/render_texture.c +++ b/source/blender/render/intern/source/render_texture.c @@ -65,23 +65,11 @@ #include "MEM_guardedalloc.h" -#include "envmap.h" -#include "pointdensity.h" -#include "voxeldata.h" #include "render_types.h" -#include "shading.h" #include "texture.h" -#include "texture_ocean.h" - -#include "renderdatabase.h" /* needed for UV */ #include "RE_render_ext.h" - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -/* defined in pipeline.c, is hardcopy of active dynamic allocated Render */ -/* only to be used here in this file, it's for speed */ -extern struct Render R; -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +#include "RE_shader_ext.h" static RNG_THREAD_ARRAY *random_tex_array; @@ -97,63 +85,6 @@ void RE_texture_rng_exit(void) } -static void init_render_texture(Render *re, Tex *tex) -{ - /* imap test */ - if (tex->ima && BKE_image_is_animated(tex->ima)) { - BKE_image_user_frame_calc(&tex->iuser, re ? re->r.cfra : 0, re ? re->flag & R_SEC_FIELD:0); - } - - else if (tex->type==TEX_ENVMAP) { - /* just in case */ - tex->imaflag |= TEX_INTERPOL | TEX_MIPMAP; - tex->extend= TEX_CLIP; - - if (tex->env) { - if (tex->env->type==ENV_PLANE) - tex->extend= TEX_EXTEND; - - /* only free envmap when rendermode was set to render envmaps, for previewrender */ - if (G.is_rendering && re) { - if (re->r.mode & R_ENVMAP) - if (tex->env->stype==ENV_ANIM) - BKE_texture_envmap_free_data(tex->env); - } - } - } - - if (tex->nodetree && tex->use_nodes) { - ntreeTexBeginExecTree(tex->nodetree); /* has internal flag to detect it only does it once */ - } -} - -/* ------------------------------------------------------------------------- */ - -void init_render_textures(Render *re) -{ - Tex *tex; - - tex= re->main->tex.first; - while (tex) { - if (tex->id.us) init_render_texture(re, tex); - tex= tex->id.next; - } -} - -static void end_render_texture(Tex *tex) -{ - if (tex && tex->use_nodes && tex->nodetree && tex->nodetree->execdata) - ntreeTexEndExecTree(tex->nodetree->execdata); -} - -void end_render_textures(Render *re) -{ - Tex *tex; - for (tex= re->main->tex.first; tex; tex= tex->id.next) - if (tex->id.us) - end_render_texture(tex); -} - /* ------------------------------------------------------------------------- */ @@ -755,7 +686,6 @@ static int cubemap_glob(const float n[3], float x, float y, float z, float *adr1 else { copy_v3_v3(nor, n); } - mul_mat3_m4_v3(R.viewinv, nor); x1 = fabsf(nor[0]); y1 = fabsf(nor[1]); @@ -781,115 +711,20 @@ static int cubemap_glob(const float n[3], float x, float y, float z, float *adr1 /* ------------------------------------------------------------------------- */ -/* mtex argument only for projection switches */ -static int cubemap( - const MTex *mtex, VlakRen *vlr, const float n[3], float x, float y, float z, float *adr1, float *adr2) -{ - int proj[4]={0, ME_PROJXY, ME_PROJXZ, ME_PROJYZ}, ret= 0; - - if (vlr) { - int index; - - /* Mesh vertices have such flags, for others we calculate it once based on orco */ - if ((vlr->puno & (ME_PROJXY|ME_PROJXZ|ME_PROJYZ))==0) { - /* test for v1, vlr can be faked for baking */ - if (vlr->v1 && vlr->v1->orco) { - float nor[3]; - normal_tri_v3(nor, vlr->v1->orco, vlr->v2->orco, vlr->v3->orco); - - if (fabsf(nor[0]) < fabsf(nor[2]) && fabsf(nor[1]) < fabsf(nor[2])) vlr->puno |= ME_PROJXY; - else if (fabsf(nor[0]) < fabsf(nor[1]) && fabsf(nor[2]) < fabsf(nor[1])) vlr->puno |= ME_PROJXZ; - else vlr->puno |= ME_PROJYZ; - } - else return cubemap_glob(n, x, y, z, adr1, adr2); - } - - if (mtex) { - /* the mtex->proj{xyz} have type char. maybe this should be wider? */ - /* casting to int ensures that the index type is right. */ - index = (int) mtex->projx; - proj[index]= ME_PROJXY; - - index = (int) mtex->projy; - proj[index]= ME_PROJXZ; - - index = (int) mtex->projz; - proj[index]= ME_PROJYZ; - } - - if (vlr->puno & proj[1]) { - *adr1 = (x + 1.0f) / 2.0f; - *adr2 = (y + 1.0f) / 2.0f; - } - else if (vlr->puno & proj[2]) { - *adr1 = (x + 1.0f) / 2.0f; - *adr2 = (z + 1.0f) / 2.0f; - ret= 1; - } - else { - *adr1 = (y + 1.0f) / 2.0f; - *adr2 = (z + 1.0f) / 2.0f; - ret= 2; - } - } - else { - return cubemap_glob(n, x, y, z, adr1, adr2); - } - - return ret; -} - -/* ------------------------------------------------------------------------- */ - -static int cubemap_ob(Object *ob, const float n[3], float x, float y, float z, float *adr1, float *adr2) -{ - float x1, y1, z1, nor[3]; - int ret; - - if (n==NULL) return 0; - - copy_v3_v3(nor, n); - if (ob) mul_mat3_m4_v3(ob->imat, nor); - - x1 = fabsf(nor[0]); - y1 = fabsf(nor[1]); - z1 = fabsf(nor[2]); - - if (z1>=x1 && z1>=y1) { - *adr1 = (x + 1.0f) / 2.0f; - *adr2 = (y + 1.0f) / 2.0f; - ret= 0; - } - else if (y1>=x1 && y1>=z1) { - *adr1 = (x + 1.0f) / 2.0f; - *adr2 = (z + 1.0f) / 2.0f; - ret= 1; - } - else { - *adr1 = (y + 1.0f) / 2.0f; - *adr2 = (z + 1.0f) / 2.0f; - ret= 2; - } - return ret; -} - /* ------------------------------------------------------------------------- */ static void do_2d_mapping( - const MTex *mtex, float texvec[3], VlakRen *vlr, const float n[3], float dxt[3], float dyt[3]) + const MTex *mtex, float texvec[3], const float n[3], float dxt[3], float dyt[3]) { Tex *tex; - Object *ob= NULL; float fx, fy, fac1, area[8]; - int ok, proj, areaflag= 0, wrap, texco; + int ok, proj, areaflag= 0, wrap; /* mtex variables localized, only cubemap doesn't cooperate yet... */ wrap= mtex->mapping; tex= mtex->tex; - ob= mtex->object; - texco= mtex->texco; - if (R.osa==0) { + if (!(dxt && dyt)) { if (wrap==MTEX_FLAT) { fx = (texvec[0] + 1.0f) / 2.0f; @@ -898,9 +733,7 @@ static void do_2d_mapping( else if (wrap == MTEX_TUBE) map_to_tube( &fx, &fy, texvec[0], texvec[1], texvec[2]); else if (wrap == MTEX_SPHERE) map_to_sphere(&fx, &fy, texvec[0], texvec[1], texvec[2]); else { - if (texco == TEXCO_OBJECT) cubemap_ob(ob, n, texvec[0], texvec[1], texvec[2], &fx, &fy); - else if (texco == TEXCO_GLOB) cubemap_glob(n, texvec[0], texvec[1], texvec[2], &fx, &fy); - else cubemap(mtex, vlr, n, texvec[0], texvec[1], texvec[2], &fx, &fy); + cubemap_glob(n, texvec[0], texvec[1], texvec[2], &fx, &fy); } /* repeat */ @@ -996,9 +829,7 @@ static void do_2d_mapping( } else { - if (texco==TEXCO_OBJECT) proj = cubemap_ob(ob, n, texvec[0], texvec[1], texvec[2], &fx, &fy); - else if (texco==TEXCO_GLOB) proj = cubemap_glob(n, texvec[0], texvec[1], texvec[2], &fx, &fy); - else proj = cubemap(mtex, vlr, n, texvec[0], texvec[1], texvec[2], &fx, &fy); + proj = cubemap_glob(n, texvec[0], texvec[1], texvec[2], &fx, &fy); if (proj==1) { SWAP(float, dxt[1], dxt[2]); @@ -1124,8 +955,9 @@ static int multitex(Tex *tex, texres->talpha = false; /* is set when image texture returns alpha (considered premul) */ if (use_nodes && tex->use_nodes && tex->nodetree) { + const float cfra = 1.0f; /* This was only set for Blender Internal render before. */ retval = ntreeTexExecTree(tex->nodetree, texres, texvec, dxt, dyt, osatex, thread, - tex, which_output, R.r.cfra, texnode_preview, NULL, NULL); + tex, which_output, cfra, texnode_preview, NULL); } else { switch (tex->type) { @@ -1160,9 +992,6 @@ static int multitex(Tex *tex, BKE_image_tag_time(tex->ima); } break; - case TEX_ENVMAP: - retval = envmaptex(tex, texvec, dxt, dyt, osatex, texres, pool, skip_load_image); - break; case TEX_MUSGRAVE: /* newnoise: musgrave types */ @@ -1205,15 +1034,6 @@ static int multitex(Tex *tex, retval = mg_distNoiseTex(tex, tmpvec, texres); break; - case TEX_POINTDENSITY: - retval = pointdensitytex(tex, texvec, texres); - break; - case TEX_VOXELDATA: - retval = voxeldatatex(tex, texvec, texres); - break; - case TEX_OCEAN: - retval = ocean_texture(tex, texvec, texres); - break; } } @@ -1238,7 +1058,6 @@ static int multitex_nodes_intern(Tex *tex, TexResult *texres, const short thread, short which_output, - ShadeInput *shi, MTex *mtex, struct ImagePool *pool, const bool scene_color_manage, @@ -1259,7 +1078,7 @@ static int multitex_nodes_intern(Tex *tex, if (mtex) { /* we have mtex, use it for 2d mapping images only */ - do_2d_mapping(mtex, texvec, shi->vlr, shi->facenor, dxt, dyt); + do_2d_mapping(mtex, texvec, NULL, dxt, dyt); rgbnor = multitex(tex, texvec, dxt, dyt, @@ -1272,7 +1091,7 @@ static int multitex_nodes_intern(Tex *tex, texnode_preview, use_nodes); - if (mtex->mapto & (MAP_COL+MAP_COLSPEC+MAP_COLMIR)) { + if (mtex->mapto & (MAP_COL)) { ImBuf *ibuf = BKE_image_pool_acquire_ibuf(tex->ima, &tex->iuser, pool); /* don't linearize float buffers, assumed to be linear */ @@ -1307,7 +1126,7 @@ static int multitex_nodes_intern(Tex *tex, zero_v3(dyt_l); } - do_2d_mapping(&localmtex, texvec_l, NULL, NULL, dxt_l, dyt_l); + do_2d_mapping(&localmtex, texvec_l, NULL, dxt_l, dyt_l); rgbnor = multitex(tex, texvec_l, dxt_l, dyt_l, @@ -1357,41 +1176,15 @@ static int multitex_nodes_intern(Tex *tex, * Use it from render pipeline only! */ int multitex_nodes(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int osatex, TexResult *texres, - const short thread, short which_output, ShadeInput *shi, MTex *mtex, struct ImagePool *pool) + const short thread, short which_output, MTex *mtex, struct ImagePool *pool) { return multitex_nodes_intern(tex, texvec, dxt, dyt, osatex, texres, - thread, which_output, shi, mtex, pool, R.scene_color_manage, - (R.r.scemode & R_NO_IMAGE_LOAD) != 0, - (R.r.scemode & R_TEXNODE_PREVIEW) != 0, + thread, which_output, mtex, pool, true, + false, + false, true); } -/* this is called for surface shading */ -static int multitex_mtex(ShadeInput *shi, MTex *mtex, float texvec[3], float dxt[3], float dyt[3], TexResult *texres, struct ImagePool *pool, const bool skip_load_image) -{ - Tex *tex = mtex->tex; - /* TODO(sergey): Texture preview should become an argument? */ - if (tex->use_nodes && tex->nodetree) { - /* stupid exception here .. but we have to pass shi and mtex to - * textures nodes for 2d mapping and color management for images */ - return ntreeTexExecTree(tex->nodetree, texres, texvec, dxt, dyt, shi->osatex, shi->thread, - tex, mtex->which_output, R.r.cfra, (R.r.scemode & R_TEXNODE_PREVIEW) != 0, shi, mtex); - } - else { - return multitex(mtex->tex, - texvec, - dxt, dyt, - shi->osatex, - texres, - shi->thread, - mtex->which_output, - pool, - skip_load_image, - (R.r.scemode & R_TEXNODE_PREVIEW) != 0, - true); - } -} - /* Warning, if the texres's values are not declared zero, check the return value to be sure * the color values are set before using the r/g/b values, otherwise you may use uninitialized values - Campbell * @@ -1414,7 +1207,7 @@ int multitex_ext(Tex *tex, texres, thread, 0, - NULL, NULL, + NULL, pool, scene_color_manage, skip_load_image, @@ -1435,7 +1228,7 @@ int multitex_ext_safe(Tex *tex, float texvec[3], TexResult *texres, struct Image texres, 0, 0, - NULL, NULL, + NULL, pool, scene_color_manage, skip_load_image, @@ -1652,1949 +1445,6 @@ float texture_value_blend(float tex, float out, float fact, float facg, int blen return in; } -static void texco_mapping(ShadeInput *shi, Tex *tex, MTex *mtex, - const float co[3], const float dx[3], const float dy[3], float texvec[3], float dxt[3], float dyt[3]) -{ - /* new: first swap coords, then map, then trans/scale */ - if (tex->type == TEX_IMAGE) { - /* placement */ - texvec[0] = mtex->projx ? co[mtex->projx - 1] : 0.f; - texvec[1] = mtex->projy ? co[mtex->projy - 1] : 0.f; - texvec[2] = mtex->projz ? co[mtex->projz - 1] : 0.f; - - if (shi->osatex) { - if (mtex->projx) { - dxt[0] = dx[mtex->projx - 1]; - dyt[0] = dy[mtex->projx - 1]; - } - else dxt[0] = dyt[0] = 0.f; - if (mtex->projy) { - dxt[1] = dx[mtex->projy - 1]; - dyt[1] = dy[mtex->projy - 1]; - } - else dxt[1] = dyt[1] = 0.f; - if (mtex->projz) { - dxt[2] = dx[mtex->projz - 1]; - dyt[2] = dy[mtex->projz - 1]; - } - else dxt[2] = dyt[2] = 0.f; - } - do_2d_mapping(mtex, texvec, shi->vlr, shi->facenor, dxt, dyt); - - /* translate and scale */ - texvec[0] = mtex->size[0]*(texvec[0] - 0.5f) + mtex->ofs[0] + 0.5f; - texvec[1] = mtex->size[1]*(texvec[1] - 0.5f) + mtex->ofs[1] + 0.5f; - if (shi->osatex) { - dxt[0] = mtex->size[0] * dxt[0]; - dxt[1] = mtex->size[1] * dxt[1]; - dyt[0] = mtex->size[0] * dyt[0]; - dyt[1] = mtex->size[1] * dyt[1]; - } - - /* problem: repeat-mirror is not a 'repeat' but 'extend' in imagetexture.c */ - /* TXF: bug was here, only modify texvec when repeat mode set, old code affected other modes too. - * New texfilters solve mirroring differently so that it also works correctly when - * textures are scaled (sizeXYZ) as well as repeated. See also modification in do_2d_mapping(). - * (since currently only done in osa mode, results will look incorrect without osa TODO) */ - if (tex->extend == TEX_REPEAT && (tex->flag & TEX_REPEAT_XMIR)) { - if (tex->texfilter == TXF_BOX) - texvec[0] -= floorf(texvec[0]); /* this line equivalent to old code, same below */ - else if (texvec[0] < 0.f || texvec[0] > 1.f) { - const float tx = 0.5f*texvec[0]; - texvec[0] = 2.f*(tx - floorf(tx)); - if (texvec[0] > 1.f) texvec[0] = 2.f - texvec[0]; - } - } - if (tex->extend == TEX_REPEAT && (tex->flag & TEX_REPEAT_YMIR)) { - if (tex->texfilter == TXF_BOX) - texvec[1] -= floorf(texvec[1]); - else if (texvec[1] < 0.f || texvec[1] > 1.f) { - const float ty = 0.5f*texvec[1]; - texvec[1] = 2.f*(ty - floorf(ty)); - if (texvec[1] > 1.f) texvec[1] = 2.f - texvec[1]; - } - } - - } - else { /* procedural */ - /* placement */ - texvec[0] = mtex->size[0]*(mtex->projx ? (co[mtex->projx - 1] + mtex->ofs[0]) : mtex->ofs[0]); - texvec[1] = mtex->size[1]*(mtex->projy ? (co[mtex->projy - 1] + mtex->ofs[1]) : mtex->ofs[1]); - texvec[2] = mtex->size[2]*(mtex->projz ? (co[mtex->projz - 1] + mtex->ofs[2]) : mtex->ofs[2]); - - if (shi->osatex) { - if (mtex->projx) { - dxt[0] = mtex->size[0]*dx[mtex->projx - 1]; - dyt[0] = mtex->size[0]*dy[mtex->projx - 1]; - } - else dxt[0] = dyt[0] = 0.f; - if (mtex->projy) { - dxt[1] = mtex->size[1]*dx[mtex->projy - 1]; - dyt[1] = mtex->size[1]*dy[mtex->projy - 1]; - } - else dxt[1] = dyt[1] = 0.f; - if (mtex->projz) { - dxt[2] = mtex->size[2]*dx[mtex->projz - 1]; - dyt[2] = mtex->size[2]*dy[mtex->projz - 1]; - } - else dxt[2]= dyt[2] = 0.f; - } - - if (mtex->tex->type == TEX_ENVMAP) { - EnvMap *env = tex->env; - if (!env->object) { - // env->object is a view point for envmap rendering - // if it's not set, return the result depending on the world_space_shading flag - if (BKE_scene_use_world_space_shading(R.scene)) { - mul_mat3_m4_v3(R.viewinv, texvec); - if (shi->osatex) { - mul_mat3_m4_v3(R.viewinv, dxt); - mul_mat3_m4_v3(R.viewinv, dyt); - } - } - } - } - } -} - -/* Bump code from 2.5 development cycle, has a number of bugs, but here for compatibility */ - -typedef struct CompatibleBump { - float nu[3], nv[3], nn[3]; - float dudnu, dudnv, dvdnu, dvdnv; - bool nunvdone; -} CompatibleBump; - -static void compatible_bump_init(CompatibleBump *compat_bump) -{ - memset(compat_bump, 0, sizeof(*compat_bump)); - - compat_bump->dudnu = 1.0f; - compat_bump->dvdnv = 1.0f; -} - -static void compatible_bump_uv_derivs(CompatibleBump *compat_bump, ShadeInput *shi, MTex *mtex, int i) -{ - /* uvmapping only, calculation of normal tangent u/v partial derivatives - * (should not be here, dudnu, dudnv, dvdnu & dvdnv should probably be part of ShadeInputUV struct, - * nu/nv in ShadeInput and this calculation should then move to shadeinput.c, - * shade_input_set_shade_texco() func.) */ - - /* NOTE: test for shi->obr->ob here, - * since vlr/obr/obi can be 'fake' when called from fastshade(), another reason to move it.. */ - - /* NOTE: shi->v1 is NULL when called from displace_render_vert, - * assigning verts in this case is not trivial because the shi quad face side is not know. */ - if ((mtex->texflag & MTEX_COMPAT_BUMP) && shi->obr && shi->obr->ob && shi->v1) { - if (mtex->mapto & (MAP_NORM|MAP_WARP) && !((mtex->tex->type==TEX_IMAGE) && (mtex->tex->imaflag & TEX_NORMALMAP))) { - MTFace* tf = RE_vlakren_get_tface(shi->obr, shi->vlr, i, NULL, 0); - int j1 = shi->i1, j2 = shi->i2, j3 = shi->i3; - - vlr_set_uv_indices(shi->vlr, &j1, &j2, &j3); - - /* compute ortho basis around normal */ - if (!compat_bump->nunvdone) { - /* render normal is negated */ - compat_bump->nn[0] = -shi->vn[0]; - compat_bump->nn[1] = -shi->vn[1]; - compat_bump->nn[2] = -shi->vn[2]; - ortho_basis_v3v3_v3(compat_bump->nu, compat_bump->nv, compat_bump->nn); - compat_bump->nunvdone = true; - } - - if (tf) { - const float *uv1 = tf->uv[j1], *uv2 = tf->uv[j2], *uv3 = tf->uv[j3]; - const float an[3] = {fabsf(compat_bump->nn[0]), fabsf(compat_bump->nn[1]), fabsf(compat_bump->nn[2])}; - const int a1 = (an[0] > an[1] && an[0] > an[2]) ? 1 : 0; - const int a2 = (an[2] > an[0] && an[2] > an[1]) ? 1 : 2; - const float dp1_a1 = shi->v1->co[a1] - shi->v3->co[a1]; - const float dp1_a2 = shi->v1->co[a2] - shi->v3->co[a2]; - const float dp2_a1 = shi->v2->co[a1] - shi->v3->co[a1]; - const float dp2_a2 = shi->v2->co[a2] - shi->v3->co[a2]; - const float du1 = uv1[0] - uv3[0], du2 = uv2[0] - uv3[0]; - const float dv1 = uv1[1] - uv3[1], dv2 = uv2[1] - uv3[1]; - const float dpdu_a1 = dv2*dp1_a1 - dv1*dp2_a1; - const float dpdu_a2 = dv2*dp1_a2 - dv1*dp2_a2; - const float dpdv_a1 = du1*dp2_a1 - du2*dp1_a1; - const float dpdv_a2 = du1*dp2_a2 - du2*dp1_a2; - float d = dpdu_a1*dpdv_a2 - dpdv_a1*dpdu_a2; - float uvd = du1*dv2 - dv1*du2; - - if (uvd == 0.f) uvd = 1e-5f; - if (d == 0.f) d = 1e-5f; - d = uvd / d; - - compat_bump->dudnu = (dpdv_a2*compat_bump->nu[a1] - dpdv_a1*compat_bump->nu[a2])*d; - compat_bump->dvdnu = (dpdu_a1*compat_bump->nu[a2] - dpdu_a2*compat_bump->nu[a1])*d; - compat_bump->dudnv = (dpdv_a2*compat_bump->nv[a1] - dpdv_a1*compat_bump->nv[a2])*d; - compat_bump->dvdnv = (dpdu_a1*compat_bump->nv[a2] - dpdu_a2*compat_bump->nv[a1])*d; - } - } - } -} - -static int compatible_bump_compute(CompatibleBump *compat_bump, ShadeInput *shi, MTex *mtex, Tex *tex, TexResult *texres, - float Tnor, const float co[3], const float dx[3], const float dy[3], float texvec[3], float dxt[3], float dyt[3], - struct ImagePool *pool, const bool skip_load_image) -{ - TexResult ttexr = {0, 0, 0, 0, 0, texres->talpha, NULL}; /* temp TexResult */ - float tco[3], texv[3], cd, ud, vd, du, dv, idu, idv; - const int fromrgb = ((tex->type == TEX_IMAGE) || ((tex->flag & TEX_COLORBAND)!=0)); - const float bf = -0.04f*Tnor*mtex->norfac; - int rgbnor; - /* disable internal bump eval */ - float *nvec = texres->nor; - texres->nor = NULL; - /* du & dv estimates, constant value defaults */ - du = dv = 0.01f; - - /* compute ortho basis around normal */ - if (!compat_bump->nunvdone) { - /* render normal is negated */ - negate_v3_v3(compat_bump->nn, shi->vn); - ortho_basis_v3v3_v3(compat_bump->nu, compat_bump->nv, compat_bump->nn); - compat_bump->nunvdone = true; - } - - /* two methods, either constant based on main image resolution, - * (which also works without osa, though of course not always good (or even very bad) results), - * or based on tex derivative max values (osa only). Not sure which is best... */ - - if (!shi->osatex && (tex->type == TEX_IMAGE) && tex->ima) { - /* in case we have no proper derivatives, fall back to - * computing du/dv it based on image size */ - ImBuf *ibuf = BKE_image_pool_acquire_ibuf(tex->ima, &tex->iuser, pool); - if (ibuf) { - du = 1.f/(float)ibuf->x; - dv = 1.f/(float)ibuf->y; - } - BKE_image_pool_release_ibuf(tex->ima, ibuf, pool); - } - else if (shi->osatex) { - /* we have derivatives, can compute proper du/dv */ - if (tex->type == TEX_IMAGE) { /* 2d image, use u & v max. of dx/dy 2d vecs */ - const float adx[2] = {fabsf(dx[0]), fabsf(dx[1])}; - const float ady[2] = {fabsf(dy[0]), fabsf(dy[1])}; - du = MAX2(adx[0], ady[0]); - dv = MAX2(adx[1], ady[1]); - } - else { /* 3d procedural, estimate from all dx/dy elems */ - const float adx[3] = {fabsf(dx[0]), fabsf(dx[1]), fabsf(dx[2])}; - const float ady[3] = {fabsf(dy[0]), fabsf(dy[1]), fabsf(dy[2])}; - du = max_fff(adx[0], adx[1], adx[2]); - dv = max_fff(ady[0], ady[1], ady[2]); - } - } - - /* center, main return value */ - texco_mapping(shi, tex, mtex, co, dx, dy, texvec, dxt, dyt); - rgbnor = multitex_mtex(shi, mtex, texvec, dxt, dyt, texres, pool, skip_load_image); - cd = fromrgb ? (texres->tr + texres->tg + texres->tb) / 3.0f : texres->tin; - - if (mtex->texco == TEXCO_UV) { - /* for the uv case, use the same value for both du/dv, - * since individually scaling the normal derivatives makes them useless... */ - du = min_ff(du, dv); - idu = (du < 1e-5f) ? bf : (bf/du); - - /* +u val */ - tco[0] = co[0] + compat_bump->dudnu*du; - tco[1] = co[1] + compat_bump->dvdnu*du; - tco[2] = 0.f; - texco_mapping(shi, tex, mtex, tco, dx, dy, texv, dxt, dyt); - multitex_mtex(shi, mtex, texv, dxt, dyt, &ttexr, pool, skip_load_image); - ud = idu*(cd - (fromrgb ? (ttexr.tr + ttexr.tg + ttexr.tb) / 3.0f : ttexr.tin)); - - /* +v val */ - tco[0] = co[0] + compat_bump->dudnv*du; - tco[1] = co[1] + compat_bump->dvdnv*du; - tco[2] = 0.f; - texco_mapping(shi, tex, mtex, tco, dx, dy, texv, dxt, dyt); - multitex_mtex(shi, mtex, texv, dxt, dyt, &ttexr, pool, skip_load_image); - vd = idu*(cd - (fromrgb ? (ttexr.tr + ttexr.tg + ttexr.tb) / 3.0f : ttexr.tin)); - } - else { - float tu[3], tv[3]; - - copy_v3_v3(tu, compat_bump->nu); - copy_v3_v3(tv, compat_bump->nv); - - idu = (du < 1e-5f) ? bf : (bf/du); - idv = (dv < 1e-5f) ? bf : (bf/dv); - - if ((mtex->texco == TEXCO_ORCO) && shi->obr && shi->obr->ob) { - mul_mat3_m4_v3(shi->obr->ob->imat_ren, tu); - mul_mat3_m4_v3(shi->obr->ob->imat_ren, tv); - normalize_v3(tu); - normalize_v3(tv); - } - else if (mtex->texco == TEXCO_GLOB) { - mul_mat3_m4_v3(R.viewinv, tu); - mul_mat3_m4_v3(R.viewinv, tv); - } - else if (mtex->texco == TEXCO_OBJECT && mtex->object) { - mul_mat3_m4_v3(mtex->object->imat_ren, tu); - mul_mat3_m4_v3(mtex->object->imat_ren, tv); - normalize_v3(tu); - normalize_v3(tv); - } - - /* +u val */ - tco[0] = co[0] + tu[0]*du; - tco[1] = co[1] + tu[1]*du; - tco[2] = co[2] + tu[2]*du; - texco_mapping(shi, tex, mtex, tco, dx, dy, texv, dxt, dyt); - multitex_mtex(shi, mtex, texv, dxt, dyt, &ttexr, pool, skip_load_image); - ud = idu*(cd - (fromrgb ? (ttexr.tr + ttexr.tg + ttexr.tb) / 3.0f : ttexr.tin)); - - /* +v val */ - tco[0] = co[0] + tv[0]*dv; - tco[1] = co[1] + tv[1]*dv; - tco[2] = co[2] + tv[2]*dv; - texco_mapping(shi, tex, mtex, tco, dx, dy, texv, dxt, dyt); - multitex_mtex(shi, mtex, texv, dxt, dyt, &ttexr, pool, skip_load_image); - vd = idv*(cd - (fromrgb ? (ttexr.tr + ttexr.tg + ttexr.tb) / 3.0f : ttexr.tin)); - } - - /* bumped normal */ - compat_bump->nu[0] += ud*compat_bump->nn[0]; - compat_bump->nu[1] += ud*compat_bump->nn[1]; - compat_bump->nu[2] += ud*compat_bump->nn[2]; - compat_bump->nv[0] += vd*compat_bump->nn[0]; - compat_bump->nv[1] += vd*compat_bump->nn[1]; - compat_bump->nv[2] += vd*compat_bump->nn[2]; - cross_v3_v3v3(nvec, compat_bump->nu, compat_bump->nv); - - nvec[0] = -nvec[0]; - nvec[1] = -nvec[1]; - nvec[2] = -nvec[2]; - texres->nor = nvec; - - rgbnor |= TEX_NOR; - return rgbnor; -} - -/* Improved bump code from later in 2.5 development cycle */ - -typedef struct NTapBump { - int init_done; - int iPrevBumpSpace; /* 0: uninitialized, 1: objectspace, 2: texturespace, 4: viewspace */ - /* bumpmapping */ - float vNorg[3]; /* backup copy of shi->vn */ - float vNacc[3]; /* original surface normal minus the surface gradient of every bump map which is encountered */ - float vR1[3], vR2[3]; /* cross products (sigma_y, original_normal), (original_normal, sigma_x) */ - float sgn_det; /* sign of the determinant of the matrix {sigma_x, sigma_y, original_normal} */ - float fPrevMagnitude; /* copy of previous magnitude, used for multiple bumps in different spaces */ -} NTapBump; - -static void ntap_bump_init(NTapBump *ntap_bump) -{ - memset(ntap_bump, 0, sizeof(*ntap_bump)); -} - -static int ntap_bump_compute(NTapBump *ntap_bump, ShadeInput *shi, MTex *mtex, Tex *tex, TexResult *texres, - float Tnor, const float co[3], const float dx[3], const float dy[3], - float texvec[3], float dxt[3], float dyt[3], struct ImagePool *pool, - const bool skip_load_image) -{ - TexResult ttexr = {0, 0, 0, 0, 0, texres->talpha, NULL}; /* temp TexResult */ - - const int fromrgb = ((tex->type == TEX_IMAGE) || ((tex->flag & TEX_COLORBAND)!=0)); - - /* The negate on Hscale is done because the - * normal in the renderer points inward which corresponds - * to inverting the bump map. The normals are generated - * this way in calc_vertexnormals(). Should this ever change - * this negate must be removed. */ - float Hscale = -Tnor*mtex->norfac; - - int dimx=512, dimy=512; - const int imag_tspace_dimension_x = 1024; /* only used for texture space variant */ - float aspect = 1.0f; - - /* 2 channels for 2D texture and 3 for 3D textures. */ - const int nr_channels = (mtex->texco == TEXCO_UV)? 2 : 3; - int c, rgbnor, iBumpSpace; - float dHdx, dHdy; - int found_deriv_map = (tex->type==TEX_IMAGE) && (tex->imaflag & TEX_DERIVATIVEMAP); - - /* disable internal bump eval in sampler, save pointer */ - float *nvec = texres->nor; - texres->nor = NULL; - - if (found_deriv_map==0) { - if ( mtex->texflag & MTEX_BUMP_TEXTURESPACE ) { - if (tex->ima) - Hscale *= 13.0f; /* appears to be a sensible default value */ - } - else - Hscale *= 0.1f; /* factor 0.1 proved to look like the previous bump code */ - } - - if ( !ntap_bump->init_done ) { - copy_v3_v3(ntap_bump->vNacc, shi->vn); - copy_v3_v3(ntap_bump->vNorg, shi->vn); - ntap_bump->fPrevMagnitude = 1.0f; - ntap_bump->iPrevBumpSpace = 0; - - ntap_bump->init_done = true; - } - - /* resolve image dimensions */ - if (found_deriv_map || (mtex->texflag&MTEX_BUMP_TEXTURESPACE)!=0) { - ImBuf *ibuf = BKE_image_pool_acquire_ibuf(tex->ima, &tex->iuser, pool); - if (ibuf) { - dimx = ibuf->x; - dimy = ibuf->y; - aspect = ((float) dimy) / dimx; - } - BKE_image_pool_release_ibuf(tex->ima, ibuf, pool); - } - - if (found_deriv_map) { - float dBdu, dBdv, auto_bump = 1.0f; - float s = 1; /* negate this if flipped texture coordinate */ - texco_mapping(shi, tex, mtex, co, dx, dy, texvec, dxt, dyt); - rgbnor = multitex_mtex(shi, mtex, texvec, dxt, dyt, texres, pool, skip_load_image); - - if (shi->obr->ob->derivedFinal) { - auto_bump = shi->obr->ob->derivedFinal->auto_bump_scale; - } - - { - float fVirtDim = sqrtf(fabsf((float) (dimx*dimy)*mtex->size[0]*mtex->size[1])); - auto_bump /= MAX2(fVirtDim, FLT_EPSILON); - } - - /* this variant using a derivative map is described here - * http://mmikkelsen3d.blogspot.com/2011/07/derivative-maps.html */ - dBdu = auto_bump*Hscale*dimx*(2*texres->tr-1); - dBdv = auto_bump*Hscale*dimy*(2*texres->tg-1); - - dHdx = dBdu*dxt[0] + s * dBdv*dxt[1]; - dHdy = dBdu*dyt[0] + s * dBdv*dyt[1]; - } - else if (!(mtex->texflag & MTEX_5TAP_BUMP)) { - /* compute height derivatives with respect to output image pixel coordinates x and y */ - float STll[3], STlr[3], STul[3]; - float Hll, Hlr, Hul; - - texco_mapping(shi, tex, mtex, co, dx, dy, texvec, dxt, dyt); - - for (c=0; c<nr_channels; c++) { - /* dx contains the derivatives (du/dx, dv/dx) - * dy contains the derivatives (du/dy, dv/dy) */ - STll[c] = texvec[c]; - STlr[c] = texvec[c]+dxt[c]; - STul[c] = texvec[c]+dyt[c]; - } - - /* clear unused derivatives */ - for (c=nr_channels; c<3; c++) { - STll[c] = 0.0f; - STlr[c] = 0.0f; - STul[c] = 0.0f; - } - - /* use texres for the center sample, set rgbnor */ - rgbnor = multitex_mtex(shi, mtex, STll, dxt, dyt, texres, pool, skip_load_image); - Hll = (fromrgb) ? IMB_colormanagement_get_luminance(&texres->tr) : texres->tin; - - /* use ttexr for the other 2 taps */ - multitex_mtex(shi, mtex, STlr, dxt, dyt, &ttexr, pool, skip_load_image); - Hlr = (fromrgb) ? IMB_colormanagement_get_luminance(&ttexr.tr) : ttexr.tin; - - multitex_mtex(shi, mtex, STul, dxt, dyt, &ttexr, pool, skip_load_image); - Hul = (fromrgb) ? IMB_colormanagement_get_luminance(&ttexr.tr) : ttexr.tin; - - dHdx = Hscale*(Hlr - Hll); - dHdy = Hscale*(Hul - Hll); - } - else { - /* same as above, but doing 5 taps, increasing quality at cost of speed */ - float STc[3], STl[3], STr[3], STd[3], STu[3]; - float /* Hc, */ /* UNUSED */ Hl, Hr, Hd, Hu; - - texco_mapping(shi, tex, mtex, co, dx, dy, texvec, dxt, dyt); - - for (c=0; c<nr_channels; c++) { - STc[c] = texvec[c]; - STl[c] = texvec[c] - 0.5f*dxt[c]; - STr[c] = texvec[c] + 0.5f*dxt[c]; - STd[c] = texvec[c] - 0.5f*dyt[c]; - STu[c] = texvec[c] + 0.5f*dyt[c]; - } - - /* clear unused derivatives */ - for (c=nr_channels; c<3; c++) { - STc[c] = 0.0f; - STl[c] = 0.0f; - STr[c] = 0.0f; - STd[c] = 0.0f; - STu[c] = 0.0f; - } - - /* use texres for the center sample, set rgbnor */ - rgbnor = multitex_mtex(shi, mtex, STc, dxt, dyt, texres, pool, skip_load_image); - /* Hc = (fromrgb) ? IMB_colormanagement_get_luminance(&texres->tr) : texres->tin; */ /* UNUSED */ - - /* use ttexr for the other taps */ - multitex_mtex(shi, mtex, STl, dxt, dyt, &ttexr, pool, skip_load_image); - Hl = (fromrgb) ? IMB_colormanagement_get_luminance(&ttexr.tr) : ttexr.tin; - multitex_mtex(shi, mtex, STr, dxt, dyt, &ttexr, pool, skip_load_image); - Hr = (fromrgb) ? IMB_colormanagement_get_luminance(&ttexr.tr) : ttexr.tin; - multitex_mtex(shi, mtex, STd, dxt, dyt, &ttexr, pool, skip_load_image); - Hd = (fromrgb) ? IMB_colormanagement_get_luminance(&ttexr.tr) : ttexr.tin; - multitex_mtex(shi, mtex, STu, dxt, dyt, &ttexr, pool, skip_load_image); - Hu = (fromrgb) ? IMB_colormanagement_get_luminance(&ttexr.tr) : ttexr.tin; - - dHdx = Hscale*(Hr - Hl); - dHdy = Hscale*(Hu - Hd); - } - - /* restore pointer */ - texres->nor = nvec; - - /* replaced newbump with code based on listing 1 and 2 of - * [Mik10] Mikkelsen M. S.: Bump Mapping Unparameterized Surfaces on the GPU. - * -> http://jbit.net/~sparky/sfgrad_bump/mm_sfgrad_bump.pdf */ - - if ( mtex->texflag & MTEX_BUMP_OBJECTSPACE ) - iBumpSpace = 1; - else if ( mtex->texflag & MTEX_BUMP_TEXTURESPACE ) - iBumpSpace = 2; - else - iBumpSpace = 4; /* ViewSpace */ - - if ( ntap_bump->iPrevBumpSpace != iBumpSpace ) { - - /* initialize normal perturbation vectors */ - int xyz; - float fDet, abs_fDet, fMagnitude; - /* object2view and inverted matrix */ - float obj2view[3][3], view2obj[3][3], tmp[4][4]; - /* local copies of derivatives and normal */ - float dPdx[3], dPdy[3], vN[3]; - copy_v3_v3(dPdx, shi->dxco); - copy_v3_v3(dPdy, shi->dyco); - copy_v3_v3(vN, ntap_bump->vNorg); - - if ( mtex->texflag & MTEX_BUMP_OBJECTSPACE ) { - /* TODO: these calculations happen for every pixel! - * -> move to shi->obi */ - mul_m4_m4m4(tmp, R.viewmat, shi->obr->ob->obmat); - copy_m3_m4(obj2view, tmp); /* use only upper left 3x3 matrix */ - invert_m3_m3(view2obj, obj2view); - - /* generate the surface derivatives in object space */ - mul_m3_v3(view2obj, dPdx); - mul_m3_v3(view2obj, dPdy); - /* generate the unit normal in object space */ - mul_transposed_m3_v3(obj2view, vN); - normalize_v3(vN); - } - - cross_v3_v3v3(ntap_bump->vR1, dPdy, vN); - cross_v3_v3v3(ntap_bump->vR2, vN, dPdx); - fDet = dot_v3v3(dPdx, ntap_bump->vR1); - ntap_bump->sgn_det = (fDet < 0)? -1.0f: 1.0f; - abs_fDet = ntap_bump->sgn_det * fDet; - - if ( mtex->texflag & MTEX_BUMP_TEXTURESPACE ) { - if (tex->ima) { - /* crazy hack solution that gives results similar to normal mapping - part 1 */ - normalize_v3(ntap_bump->vR1); - normalize_v3(ntap_bump->vR2); - abs_fDet = 1.0f; - } - } - - fMagnitude = abs_fDet; - if ( mtex->texflag & MTEX_BUMP_OBJECTSPACE ) { - /* pre do transform of texres->nor by the inverse transposed of obj2view */ - mul_transposed_m3_v3(view2obj, vN); - mul_transposed_m3_v3(view2obj, ntap_bump->vR1); - mul_transposed_m3_v3(view2obj, ntap_bump->vR2); - - fMagnitude *= len_v3(vN); - } - - if (ntap_bump->fPrevMagnitude > 0.0f) - for (xyz=0; xyz<3; xyz++) - ntap_bump->vNacc[xyz] *= fMagnitude / ntap_bump->fPrevMagnitude; - - ntap_bump->fPrevMagnitude = fMagnitude; - ntap_bump->iPrevBumpSpace = iBumpSpace; - } - - if ( mtex->texflag & MTEX_BUMP_TEXTURESPACE ) { - if (tex->ima) { - /* crazy hack solution that gives results similar to normal mapping - part 2 */ - float vec[2]; - const float imag_tspace_dimension_y = aspect*imag_tspace_dimension_x; - - vec[0] = imag_tspace_dimension_x*dxt[0]; - vec[1] = imag_tspace_dimension_y*dxt[1]; - dHdx *= 1.0f/len_v2(vec); - vec[0] = imag_tspace_dimension_x*dyt[0]; - vec[1] = imag_tspace_dimension_y*dyt[1]; - dHdy *= 1.0f/len_v2(vec); - } - } - - /* subtract the surface gradient from vNacc */ - for (c=0; c<3; c++) { - float vSurfGrad_compi = ntap_bump->sgn_det * (dHdx * ntap_bump->vR1[c] + dHdy * ntap_bump->vR2[c]); - ntap_bump->vNacc[c] -= vSurfGrad_compi; - texres->nor[c] = ntap_bump->vNacc[c]; /* copy */ - } - - rgbnor |= TEX_NOR; - return rgbnor; -} - -void do_material_tex(ShadeInput *shi, Render *re) -{ - const bool skip_load_image = (R.r.scemode & R_NO_IMAGE_LOAD) != 0; - CompatibleBump compat_bump; - NTapBump ntap_bump; - MTex *mtex; - Tex *tex; - TexResult texres= {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL}; - float *co = NULL, *dx = NULL, *dy = NULL; - float fact, facm, factt, facmm, stencilTin=1.0; - float texvec[3], dxt[3], dyt[3], tempvec[3], norvec[3], warpvec[3]={0.0f, 0.0f, 0.0f}, Tnor=1.0; - int tex_nr, rgbnor= 0; - bool warp_done = false, use_compat_bump = false, use_ntap_bump = false; - bool found_nmapping = false, found_deriv_map = false; - bool iFirstTimeNMap = true; - - compatible_bump_init(&compat_bump); - ntap_bump_init(&ntap_bump); - - if (re->r.scemode & R_NO_TEX) return; - /* here: test flag if there's a tex (todo) */ - - for (tex_nr=0; tex_nr<MAX_MTEX; tex_nr++) { - - /* separate tex switching */ - if (shi->mat->septex & (1<<tex_nr)) continue; - - if (shi->mat->mtex[tex_nr]) { - mtex= shi->mat->mtex[tex_nr]; - - tex= mtex->tex; - if (tex == NULL) continue; - - found_deriv_map = (tex->type==TEX_IMAGE) && (tex->imaflag & TEX_DERIVATIVEMAP); - use_compat_bump= (mtex->texflag & MTEX_COMPAT_BUMP) != 0; - use_ntap_bump = ((mtex->texflag & (MTEX_3TAP_BUMP|MTEX_5TAP_BUMP|MTEX_BICUBIC_BUMP))!=0 || found_deriv_map!=0) ? true : false; - - /* XXX texture node trees don't work for this yet */ - if (tex->nodetree && tex->use_nodes) { - use_compat_bump = false; - use_ntap_bump = false; - } - - /* case displacement mapping */ - if (shi->osatex == 0 && use_ntap_bump) { - use_ntap_bump = false; - use_compat_bump = true; - } - - /* case ocean */ - if (tex->type == TEX_OCEAN) { - use_ntap_bump = false; - use_compat_bump = false; - } - - /* which coords */ - if (mtex->texco==TEXCO_ORCO) { - if (mtex->texflag & MTEX_DUPLI_MAPTO) { - co= shi->duplilo; dx= dxt; dy= dyt; - dxt[0]= dxt[1]= dxt[2]= 0.0f; - dyt[0]= dyt[1]= dyt[2]= 0.0f; - } - else { - co= shi->lo; dx= shi->dxlo; dy= shi->dylo; - } - } - else if (mtex->texco==TEXCO_OBJECT) { - Object *ob= mtex->object; - if (ob) { - co= tempvec; - dx= dxt; - dy= dyt; - copy_v3_v3(tempvec, shi->co); - if (mtex->texflag & MTEX_OB_DUPLI_ORIG) - if (shi->obi && shi->obi->duplitexmat) - mul_m4_v3(shi->obi->duplitexmat, tempvec); - mul_m4_v3(ob->imat_ren, tempvec); - if (shi->osatex) { - copy_v3_v3(dxt, shi->dxco); - copy_v3_v3(dyt, shi->dyco); - mul_mat3_m4_v3(ob->imat_ren, dxt); - mul_mat3_m4_v3(ob->imat_ren, dyt); - } - } - else { - /* if object doesn't exist, do not use orcos (not initialized) */ - co= shi->co; - dx= shi->dxco; dy= shi->dyco; - } - } - else if (mtex->texco==TEXCO_REFL) { - calc_R_ref(shi); - co= shi->ref; dx= shi->dxref; dy= shi->dyref; - } - else if (mtex->texco==TEXCO_NORM) { - co= shi->orn; dx= shi->dxno; dy= shi->dyno; - } - else if (mtex->texco==TEXCO_TANGENT) { - co= shi->tang; dx= shi->dxno; dy= shi->dyno; - } - else if (mtex->texco==TEXCO_GLOB) { - co= shi->gl; dx= shi->dxgl; dy= shi->dygl; - } - else if (mtex->texco==TEXCO_UV) { - if (mtex->texflag & MTEX_DUPLI_MAPTO) { - co= shi->dupliuv; dx= dxt; dy= dyt; - dxt[0]= dxt[1]= dxt[2]= 0.0f; - dyt[0]= dyt[1]= dyt[2]= 0.0f; - } - else { - ShadeInputUV *suv= &shi->uv[shi->actuv]; - int i = shi->actuv; - - if (mtex->uvname[0] != 0) { - for (i = 0; i < shi->totuv; i++) { - if (STREQ(shi->uv[i].name, mtex->uvname)) { - suv= &shi->uv[i]; - break; - } - } - } - - co= suv->uv; - dx= suv->dxuv; - dy= suv->dyuv; - - compatible_bump_uv_derivs(&compat_bump, shi, mtex, i); - } - } - else if (mtex->texco==TEXCO_WINDOW) { - co= shi->winco; dx= shi->dxwin; dy= shi->dywin; - } - else if (mtex->texco==TEXCO_STRAND) { - co= tempvec; dx= dxt; dy= dyt; - co[0]= shi->strandco; - co[1]= co[2]= 0.0f; - dx[0]= shi->dxstrand; - dx[1]= dx[2]= 0.0f; - dy[0]= shi->dystrand; - dy[1]= dy[2]= 0.0f; - } - else if (mtex->texco==TEXCO_STRESS) { - co= tempvec; dx= dxt; dy= dyt; - co[0]= shi->stress; - co[1]= co[2]= 0.0f; - dx[0]= 0.0f; - dx[1]= dx[2]= 0.0f; - dy[0]= 0.0f; - dy[1]= dy[2]= 0.0f; - } - else { - continue; /* can happen when texco defines disappear and it renders old files */ - } - - /* the pointer defines if bumping happens */ - if (mtex->mapto & (MAP_NORM|MAP_WARP)) { - texres.nor= norvec; - norvec[0]= norvec[1]= norvec[2]= 0.0; - } - else texres.nor= NULL; - - if (warp_done) { - add_v3_v3v3(tempvec, co, warpvec); - co= tempvec; - } - - /* XXX texture node trees don't work for this yet */ - if (texres.nor && !((tex->type==TEX_IMAGE) && (tex->imaflag & TEX_NORMALMAP))) { - if (use_compat_bump) { - rgbnor = compatible_bump_compute(&compat_bump, shi, mtex, tex, - &texres, Tnor*stencilTin, co, dx, dy, texvec, dxt, dyt, - re->pool, skip_load_image); - } - else if (use_ntap_bump) { - rgbnor = ntap_bump_compute(&ntap_bump, shi, mtex, tex, - &texres, Tnor*stencilTin, co, dx, dy, texvec, dxt, dyt, - re->pool, skip_load_image); - } - else { - texco_mapping(shi, tex, mtex, co, dx, dy, texvec, dxt, dyt); - rgbnor = multitex_mtex(shi, mtex, texvec, dxt, dyt, &texres, re->pool, skip_load_image); - } - } - else { - texco_mapping(shi, tex, mtex, co, dx, dy, texvec, dxt, dyt); - rgbnor = multitex_mtex(shi, mtex, texvec, dxt, dyt, &texres, re->pool, skip_load_image); - } - - /* texture output */ - - if ((rgbnor & TEX_RGB) && (mtex->texflag & MTEX_RGBTOINT)) { - texres.tin = IMB_colormanagement_get_luminance(&texres.tr); - rgbnor -= TEX_RGB; - } - if (mtex->texflag & MTEX_NEGATIVE) { - if (rgbnor & TEX_RGB) { - texres.tr= 1.0f-texres.tr; - texres.tg= 1.0f-texres.tg; - texres.tb= 1.0f-texres.tb; - } - texres.tin= 1.0f-texres.tin; - } - if (mtex->texflag & MTEX_STENCIL) { - if (rgbnor & TEX_RGB) { - fact= texres.ta; - texres.ta*= stencilTin; - stencilTin*= fact; - } - else { - fact= texres.tin; - texres.tin*= stencilTin; - stencilTin*= fact; - } - } - else { - Tnor*= stencilTin; - } - - if (texres.nor) { - if ((rgbnor & TEX_NOR)==0) { - /* make our own normal */ - if (rgbnor & TEX_RGB) { - copy_v3_v3(texres.nor, &texres.tr); - } - else { - float co_nor= 0.5f * cosf(texres.tin - 0.5f); - float si = 0.5f * sinf(texres.tin - 0.5f); - float f1, f2; - - f1= shi->vn[0]; - f2= shi->vn[1]; - texres.nor[0]= f1*co_nor+f2*si; - f1= shi->vn[1]; - f2= shi->vn[2]; - texres.nor[1]= f1*co_nor+f2*si; - texres.nor[2]= f2*co_nor-f1*si; - } - } - /* warping, local space */ - if (mtex->mapto & MAP_WARP) { - float *warpnor= texres.nor, warpnor_[3]; - - if (use_ntap_bump) { - copy_v3_v3(warpnor_, texres.nor); - warpnor= warpnor_; - normalize_v3(warpnor_); - } - warpvec[0]= mtex->warpfac*warpnor[0]; - warpvec[1]= mtex->warpfac*warpnor[1]; - warpvec[2]= mtex->warpfac*warpnor[2]; - warp_done = true; - } -#if 0 - if (mtex->texflag & MTEX_VIEWSPACE) { - /* rotate to global coords */ - if (mtex->texco==TEXCO_ORCO || mtex->texco==TEXCO_UV) { - if (shi->vlr && shi->obr && shi->obr->ob) { - float len= normalize_v3(texres.nor); - /* can be optimized... (ton) */ - mul_mat3_m4_v3(shi->obr->ob->obmat, texres.nor); - mul_mat3_m4_v3(re->viewmat, texres.nor); - normalize_v3_length(texres.nor, len); - } - } - } -#endif - } - - /* mapping */ - if (mtex->mapto & (MAP_COL | MAP_COLSPEC | MAP_COLMIR)) { - float tcol[3]; - - /* stencil maps on the texture control slider, not texture intensity value */ - copy_v3_v3(tcol, &texres.tr); - - if ((rgbnor & TEX_RGB) == 0) { - copy_v3_v3(tcol, &mtex->r); - } - else if (mtex->mapto & MAP_ALPHA) { - texres.tin = stencilTin; - } - else { - texres.tin = texres.ta; - } - - /* inverse gamma correction */ - if (tex->type==TEX_IMAGE) { - Image *ima = tex->ima; - ImBuf *ibuf = BKE_image_pool_acquire_ibuf(ima, &tex->iuser, re->pool); - - /* don't linearize float buffers, assumed to be linear */ - if (ibuf != NULL && - ibuf->rect_float == NULL && - (rgbnor & TEX_RGB) && - R.scene_color_manage) - { - IMB_colormanagement_colorspace_to_scene_linear_v3(tcol, ibuf->rect_colorspace); - } - - BKE_image_pool_release_ibuf(ima, ibuf, re->pool); - } - - if (mtex->mapto & MAP_COL) { - float colfac= mtex->colfac*stencilTin; - texture_rgb_blend(&shi->r, tcol, &shi->r, texres.tin, colfac, mtex->blendtype); - } - if (mtex->mapto & MAP_COLSPEC) { - float colspecfac= mtex->colspecfac*stencilTin; - texture_rgb_blend(&shi->specr, tcol, &shi->specr, texres.tin, colspecfac, mtex->blendtype); - } - if (mtex->mapto & MAP_COLMIR) { - float mirrfac= mtex->mirrfac*stencilTin; - - /* exception for envmap only */ - if (tex->type==TEX_ENVMAP && mtex->blendtype==MTEX_BLEND) { - fact= texres.tin*mirrfac; - facm= 1.0f- fact; - shi->refcol[0]= fact + facm*shi->refcol[0]; - shi->refcol[1]= fact*tcol[0] + facm*shi->refcol[1]; - shi->refcol[2]= fact*tcol[1] + facm*shi->refcol[2]; - shi->refcol[3]= fact*tcol[2] + facm*shi->refcol[3]; - } - else { - texture_rgb_blend(&shi->mirr, tcol, &shi->mirr, texres.tin, mirrfac, mtex->blendtype); - } - } - } - if ( (mtex->mapto & MAP_NORM) ) { - if (texres.nor) { - float norfac= mtex->norfac; - - /* we need to code blending modes for normals too once.. now 1 exception hardcoded */ - - if ((tex->type==TEX_IMAGE) && (tex->imaflag & TEX_NORMALMAP)) { - - found_nmapping = 1; - - /* qdn: for normalmaps, to invert the normalmap vector, - * it is better to negate x & y instead of subtracting the vector as was done before */ - if (norfac < 0.0f) { - texres.nor[0] = -texres.nor[0]; - texres.nor[1] = -texres.nor[1]; - } - fact = Tnor*fabsf(norfac); - if (fact>1.f) fact = 1.f; - facm = 1.f-fact; - if (mtex->normapspace == MTEX_NSPACE_TANGENT) { - /* qdn: tangent space */ - float B[3], tv[3]; - const float *no = iFirstTimeNMap ? shi->nmapnorm : shi->vn; - iFirstTimeNMap = false; - cross_v3_v3v3(B, no, shi->nmaptang); /* bitangent */ - mul_v3_fl(B, shi->nmaptang[3]); - /* transform norvec from tangent space to object surface in camera space */ - tv[0] = texres.nor[0]*shi->nmaptang[0] + texres.nor[1]*B[0] + texres.nor[2]*no[0]; - tv[1] = texres.nor[0]*shi->nmaptang[1] + texres.nor[1]*B[1] + texres.nor[2]*no[1]; - tv[2] = texres.nor[0]*shi->nmaptang[2] + texres.nor[1]*B[2] + texres.nor[2]*no[2]; - shi->vn[0]= facm*no[0] + fact*tv[0]; - shi->vn[1]= facm*no[1] + fact*tv[1]; - shi->vn[2]= facm*no[2] + fact*tv[2]; - } - else { - float nor[3]; - - copy_v3_v3(nor, texres.nor); - - if (mtex->normapspace == MTEX_NSPACE_CAMERA) { - /* pass */ - } - else if (mtex->normapspace == MTEX_NSPACE_WORLD) { - mul_mat3_m4_v3(re->viewmat, nor); - } - else if (mtex->normapspace == MTEX_NSPACE_OBJECT) { - if (shi->obr && shi->obr->ob) - mul_mat3_m4_v3(shi->obr->ob->obmat, nor); - mul_mat3_m4_v3(re->viewmat, nor); - } - - normalize_v3(nor); - - /* qdn: worldspace */ - shi->vn[0]= facm*shi->vn[0] + fact*nor[0]; - shi->vn[1]= facm*shi->vn[1] + fact*nor[1]; - shi->vn[2]= facm*shi->vn[2] + fact*nor[2]; - } - } - else { - /* XXX texture node trees don't work for this yet */ - if (use_compat_bump || use_ntap_bump) { - shi->vn[0] = texres.nor[0]; - shi->vn[1] = texres.nor[1]; - shi->vn[2] = texres.nor[2]; - } - else { - float nor[3], dot; - - if (shi->mat->mode & MA_TANGENT_V) { - shi->tang[0]+= Tnor*norfac*texres.nor[0]; - shi->tang[1]+= Tnor*norfac*texres.nor[1]; - shi->tang[2]+= Tnor*norfac*texres.nor[2]; - } - - /* prevent bump to become negative normal */ - nor[0]= Tnor*norfac*texres.nor[0]; - nor[1]= Tnor*norfac*texres.nor[1]; - nor[2]= Tnor*norfac*texres.nor[2]; - - dot= 0.5f + 0.5f * dot_v3v3(nor, shi->vn); - - shi->vn[0]+= dot*nor[0]; - shi->vn[1]+= dot*nor[1]; - shi->vn[2]+= dot*nor[2]; - } - } - normalize_v3(shi->vn); - - /* this makes sure the bump is passed on to the next texture */ - shi->orn[0]= -shi->vn[0]; - shi->orn[1]= -shi->vn[1]; - shi->orn[2]= -shi->vn[2]; - } - } - - if ( mtex->mapto & MAP_DISPLACE ) { - /* Now that most textures offer both Nor and Intensity, allow */ - /* both to work, and let user select with slider. */ - if (texres.nor) { - float norfac= mtex->norfac; - - shi->displace[0]+= 0.2f*Tnor*norfac*texres.nor[0]; - shi->displace[1]+= 0.2f*Tnor*norfac*texres.nor[1]; - shi->displace[2]+= 0.2f*Tnor*norfac*texres.nor[2]; - } - - if (rgbnor & TEX_RGB) { - texres.tin = IMB_colormanagement_get_luminance(&texres.tr); - } - - factt= (0.5f-texres.tin)*mtex->dispfac*stencilTin; facmm= 1.0f-factt; - - if (mtex->blendtype==MTEX_BLEND) { - shi->displace[0]= factt*shi->vn[0] + facmm*shi->displace[0]; - shi->displace[1]= factt*shi->vn[1] + facmm*shi->displace[1]; - shi->displace[2]= factt*shi->vn[2] + facmm*shi->displace[2]; - } - else if (mtex->blendtype==MTEX_MUL) { - shi->displace[0]*= factt*shi->vn[0]; - shi->displace[1]*= factt*shi->vn[1]; - shi->displace[2]*= factt*shi->vn[2]; - } - else { /* add or sub */ - if (mtex->blendtype==MTEX_SUB) factt= -factt; - shi->displace[0]+= factt*shi->vn[0]; - shi->displace[1]+= factt*shi->vn[1]; - shi->displace[2]+= factt*shi->vn[2]; - } - } - - if (mtex->mapto & MAP_VARS) { - /* stencil maps on the texture control slider, not texture intensity value */ - - if (rgbnor & TEX_RGB) { - if (texres.talpha) texres.tin = texres.ta; - else texres.tin = IMB_colormanagement_get_luminance(&texres.tr); - } - - if (mtex->mapto & MAP_REF) { - float difffac= mtex->difffac*stencilTin; - - shi->refl= texture_value_blend(mtex->def_var, shi->refl, texres.tin, difffac, mtex->blendtype); - if (shi->refl<0.0f) shi->refl= 0.0f; - } - if (mtex->mapto & MAP_SPEC) { - float specfac= mtex->specfac*stencilTin; - - shi->spec= texture_value_blend(mtex->def_var, shi->spec, texres.tin, specfac, mtex->blendtype); - if (shi->spec<0.0f) shi->spec= 0.0f; - } - if (mtex->mapto & MAP_EMIT) { - float emitfac= mtex->emitfac*stencilTin; - - shi->emit= texture_value_blend(mtex->def_var, shi->emit, texres.tin, emitfac, mtex->blendtype); - if (shi->emit<0.0f) shi->emit= 0.0f; - } - if (mtex->mapto & MAP_ALPHA) { - float alphafac= mtex->alphafac*stencilTin; - - shi->alpha= texture_value_blend(mtex->def_var, shi->alpha, texres.tin, alphafac, mtex->blendtype); - if (shi->alpha<0.0f) shi->alpha= 0.0f; - else if (shi->alpha>1.0f) shi->alpha= 1.0f; - } - if (mtex->mapto & MAP_HAR) { - float har; /* have to map to 0-1 */ - float hardfac= mtex->hardfac*stencilTin; - - har= ((float)shi->har)/128.0f; - har= 128.0f*texture_value_blend(mtex->def_var, har, texres.tin, hardfac, mtex->blendtype); - - if (har<1.0f) shi->har= 1; - else if (har>511) shi->har= 511; - else shi->har= (int)har; - } - if (mtex->mapto & MAP_RAYMIRR) { - float raymirrfac= mtex->raymirrfac*stencilTin; - - shi->ray_mirror= texture_value_blend(mtex->def_var, shi->ray_mirror, texres.tin, raymirrfac, mtex->blendtype); - if (shi->ray_mirror<0.0f) shi->ray_mirror= 0.0f; - else if (shi->ray_mirror>1.0f) shi->ray_mirror= 1.0f; - } - if (mtex->mapto & MAP_TRANSLU) { - float translfac= mtex->translfac*stencilTin; - - shi->translucency= texture_value_blend(mtex->def_var, shi->translucency, texres.tin, translfac, mtex->blendtype); - if (shi->translucency<0.0f) shi->translucency= 0.0f; - else if (shi->translucency>1.0f) shi->translucency= 1.0f; - } - if (mtex->mapto & MAP_AMB) { - float ambfac= mtex->ambfac*stencilTin; - - shi->amb= texture_value_blend(mtex->def_var, shi->amb, texres.tin, ambfac, mtex->blendtype); - if (shi->amb<0.0f) shi->amb= 0.0f; - else if (shi->amb>1.0f) shi->amb= 1.0f; - - shi->ambr= shi->amb*re->wrld.ambr; - shi->ambg= shi->amb*re->wrld.ambg; - shi->ambb= shi->amb*re->wrld.ambb; - } - } - } - } - if ((use_compat_bump || use_ntap_bump || found_nmapping) && (shi->mat->mode & MA_TANGENT_V) != 0) { - const float fnegdot = -dot_v3v3(shi->vn, shi->tang); - /* apply Gram-Schmidt projection */ - madd_v3_v3fl(shi->tang, shi->vn, fnegdot); - normalize_v3(shi->tang); - } -} - - -void do_volume_tex(ShadeInput *shi, const float *xyz, int mapto_flag, float col_r[3], float *val, Render *re) -{ - const bool skip_load_image = (re->r.scemode & R_NO_IMAGE_LOAD) != 0; - const bool texnode_preview = (re->r.scemode & R_TEXNODE_PREVIEW) != 0; - MTex *mtex; - Tex *tex; - TexResult texres= {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL}; - int tex_nr, rgbnor= 0; - float co[3], texvec[3]; - float fact, stencilTin=1.0; - - if (re->r.scemode & R_NO_TEX) return; - /* here: test flag if there's a tex (todo) */ - - for (tex_nr=0; tex_nr<MAX_MTEX; tex_nr++) { - /* separate tex switching */ - if (shi->mat->septex & (1<<tex_nr)) continue; - - if (shi->mat->mtex[tex_nr]) { - mtex= shi->mat->mtex[tex_nr]; - tex= mtex->tex; - if (tex == NULL) continue; - - /* only process if this texture is mapped - * to one that we're interested in */ - if (!(mtex->mapto & mapto_flag)) continue; - - /* which coords */ - if (mtex->texco==TEXCO_OBJECT) { - Object *ob= mtex->object; - if (ob) { - copy_v3_v3(co, xyz); - if (mtex->texflag & MTEX_OB_DUPLI_ORIG) { - if (shi->obi && shi->obi->duplitexmat) - mul_m4_v3(shi->obi->duplitexmat, co); - } - mul_m4_v3(ob->imat_ren, co); - - if (mtex->texflag & MTEX_MAPTO_BOUNDS && ob->bb) { - /* use bb vec[0] as min and bb vec[6] as max */ - co[0] = (co[0] - ob->bb->vec[0][0]) / (ob->bb->vec[6][0]-ob->bb->vec[0][0]) * 2.0f - 1.0f; - co[1] = (co[1] - ob->bb->vec[0][1]) / (ob->bb->vec[6][1]-ob->bb->vec[0][1]) * 2.0f - 1.0f; - co[2] = (co[2] - ob->bb->vec[0][2]) / (ob->bb->vec[6][2]-ob->bb->vec[0][2]) * 2.0f - 1.0f; - } - } - } - /* not really orco, but 'local' */ - else if (mtex->texco==TEXCO_ORCO) { - - if (mtex->texflag & MTEX_DUPLI_MAPTO) { - copy_v3_v3(co, shi->duplilo); - } - else { - Object *ob= shi->obi->ob; - copy_v3_v3(co, xyz); - mul_m4_v3(ob->imat_ren, co); - - if (mtex->texflag & MTEX_MAPTO_BOUNDS && ob->bb) { - /* use bb vec[0] as min and bb vec[6] as max */ - co[0] = (co[0] - ob->bb->vec[0][0]) / (ob->bb->vec[6][0]-ob->bb->vec[0][0]) * 2.0f - 1.0f; - co[1] = (co[1] - ob->bb->vec[0][1]) / (ob->bb->vec[6][1]-ob->bb->vec[0][1]) * 2.0f - 1.0f; - co[2] = (co[2] - ob->bb->vec[0][2]) / (ob->bb->vec[6][2]-ob->bb->vec[0][2]) * 2.0f - 1.0f; - } - } - } - else if (mtex->texco==TEXCO_GLOB) { - copy_v3_v3(co, xyz); - mul_m4_v3(re->viewinv, co); - } - else { - continue; /* can happen when texco defines disappear and it renders old files */ - } - - texres.nor= NULL; - - if (tex->type == TEX_IMAGE) { - continue; /* not supported yet */ - //do_2d_mapping(mtex, texvec, NULL, NULL, dxt, dyt); - } - else { - /* placement */ - if (mtex->projx) texvec[0]= mtex->size[0]*(co[mtex->projx-1]+mtex->ofs[0]); - else texvec[0]= mtex->size[0]*(mtex->ofs[0]); - - if (mtex->projy) texvec[1]= mtex->size[1]*(co[mtex->projy-1]+mtex->ofs[1]); - else texvec[1]= mtex->size[1]*(mtex->ofs[1]); - - if (mtex->projz) texvec[2]= mtex->size[2]*(co[mtex->projz-1]+mtex->ofs[2]); - else texvec[2]= mtex->size[2]*(mtex->ofs[2]); - } - - rgbnor = multitex(tex, - texvec, - NULL, NULL, - 0, - &texres, - shi->thread, - mtex->which_output, - re->pool, - skip_load_image, - texnode_preview, - true); /* NULL = dxt/dyt, 0 = shi->osatex - not supported */ - - /* texture output */ - - if ((rgbnor & TEX_RGB) && (mtex->texflag & MTEX_RGBTOINT)) { - texres.tin = IMB_colormanagement_get_luminance(&texres.tr); - rgbnor -= TEX_RGB; - } - if (mtex->texflag & MTEX_NEGATIVE) { - if (rgbnor & TEX_RGB) { - texres.tr= 1.0f-texres.tr; - texres.tg= 1.0f-texres.tg; - texres.tb= 1.0f-texres.tb; - } - texres.tin= 1.0f-texres.tin; - } - if (mtex->texflag & MTEX_STENCIL) { - if (rgbnor & TEX_RGB) { - fact= texres.ta; - texres.ta*= stencilTin; - stencilTin*= fact; - } - else { - fact= texres.tin; - texres.tin*= stencilTin; - stencilTin*= fact; - } - } - - - if ((mapto_flag & (MAP_EMISSION_COL+MAP_TRANSMISSION_COL+MAP_REFLECTION_COL)) && (mtex->mapto & (MAP_EMISSION_COL+MAP_TRANSMISSION_COL+MAP_REFLECTION_COL))) { - float tcol[3]; - - /* stencil maps on the texture control slider, not texture intensity value */ - - if ((rgbnor & TEX_RGB) == 0) { - copy_v3_v3(tcol, &mtex->r); - } - else if (mtex->mapto & MAP_DENSITY) { - copy_v3_v3(tcol, &texres.tr); - if (texres.talpha) { - texres.tin = stencilTin; - } - } - else { - copy_v3_v3(tcol, &texres.tr); - if (texres.talpha) { - texres.tin= texres.ta; - } - } - - /* used for emit */ - if ((mapto_flag & MAP_EMISSION_COL) && (mtex->mapto & MAP_EMISSION_COL)) { - float colemitfac= mtex->colemitfac*stencilTin; - texture_rgb_blend(col_r, tcol, col_r, texres.tin, colemitfac, mtex->blendtype); - } - - if ((mapto_flag & MAP_REFLECTION_COL) && (mtex->mapto & MAP_REFLECTION_COL)) { - float colreflfac= mtex->colreflfac*stencilTin; - texture_rgb_blend(col_r, tcol, col_r, texres.tin, colreflfac, mtex->blendtype); - } - - if ((mapto_flag & MAP_TRANSMISSION_COL) && (mtex->mapto & MAP_TRANSMISSION_COL)) { - float coltransfac= mtex->coltransfac*stencilTin; - texture_rgb_blend(col_r, tcol, col_r, texres.tin, coltransfac, mtex->blendtype); - } - } - - if ((mapto_flag & MAP_VARS) && (mtex->mapto & MAP_VARS)) { - /* stencil maps on the texture control slider, not texture intensity value */ - - /* convert RGB to intensity if intensity info isn't provided */ - if (rgbnor & TEX_RGB) { - if (texres.talpha) texres.tin = texres.ta; - else texres.tin = IMB_colormanagement_get_luminance(&texres.tr); - } - - if ((mapto_flag & MAP_EMISSION) && (mtex->mapto & MAP_EMISSION)) { - float emitfac= mtex->emitfac*stencilTin; - - *val = texture_value_blend(mtex->def_var, *val, texres.tin, emitfac, mtex->blendtype); - if (*val<0.0f) *val= 0.0f; - } - if ((mapto_flag & MAP_DENSITY) && (mtex->mapto & MAP_DENSITY)) { - float densfac= mtex->densfac*stencilTin; - - *val = texture_value_blend(mtex->def_var, *val, texres.tin, densfac, mtex->blendtype); - CLAMP(*val, 0.0f, 1.0f); - } - if ((mapto_flag & MAP_SCATTERING) && (mtex->mapto & MAP_SCATTERING)) { - float scatterfac= mtex->scatterfac*stencilTin; - - *val = texture_value_blend(mtex->def_var, *val, texres.tin, scatterfac, mtex->blendtype); - CLAMP(*val, 0.0f, 1.0f); - } - if ((mapto_flag & MAP_REFLECTION) && (mtex->mapto & MAP_REFLECTION)) { - float reflfac= mtex->reflfac*stencilTin; - - *val = texture_value_blend(mtex->def_var, *val, texres.tin, reflfac, mtex->blendtype); - CLAMP(*val, 0.0f, 1.0f); - } - } - } - } -} - - -/* ------------------------------------------------------------------------- */ - -void do_halo_tex(HaloRen *har, float xn, float yn, float col_r[4]) -{ - const bool skip_load_image = har->skip_load_image; - const bool texnode_preview = har->texnode_preview; - MTex *mtex; - TexResult texres= {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL}; - float texvec[3], dxt[3], dyt[3], fact, facm, dx; - int rgb, osatex; - - if (R.r.scemode & R_NO_TEX) return; - - mtex= har->mat->mtex[0]; - if (har->mat->septex & (1<<0)) return; - if (mtex->tex==NULL) return; - - /* no normal mapping */ - texres.nor= NULL; - - texvec[0]= xn/har->rad; - texvec[1]= yn/har->rad; - texvec[2]= 0.0; - - osatex= (har->mat->texco & TEXCO_OSA); - - /* placement */ - if (mtex->projx) texvec[0]= mtex->size[0]*(texvec[mtex->projx-1]+mtex->ofs[0]); - else texvec[0]= mtex->size[0]*(mtex->ofs[0]); - - if (mtex->projy) texvec[1]= mtex->size[1]*(texvec[mtex->projy-1]+mtex->ofs[1]); - else texvec[1]= mtex->size[1]*(mtex->ofs[1]); - - if (mtex->projz) texvec[2]= mtex->size[2]*(texvec[mtex->projz-1]+mtex->ofs[2]); - else texvec[2]= mtex->size[2]*(mtex->ofs[2]); - - if (osatex) { - - dx= 1.0f/har->rad; - - if (mtex->projx) { - dxt[0]= mtex->size[0]*dx; - dyt[0]= mtex->size[0]*dx; - } - else dxt[0]= dyt[0]= 0.0; - - if (mtex->projy) { - dxt[1]= mtex->size[1]*dx; - dyt[1]= mtex->size[1]*dx; - } - else dxt[1]= dyt[1]= 0.0; - - if (mtex->projz) { - dxt[2]= 0.0; - dyt[2]= 0.0; - } - else dxt[2]= dyt[2]= 0.0; - - } - - if (mtex->tex->type==TEX_IMAGE) do_2d_mapping(mtex, texvec, NULL, NULL, dxt, dyt); - - rgb = multitex(mtex->tex, - texvec, - dxt, dyt, - osatex, - &texres, - 0, - mtex->which_output, - har->pool, - skip_load_image, - texnode_preview, - true); - - /* texture output */ - if (rgb && (mtex->texflag & MTEX_RGBTOINT)) { - texres.tin = IMB_colormanagement_get_luminance(&texres.tr); - rgb= 0; - } - if (mtex->texflag & MTEX_NEGATIVE) { - if (rgb) { - texres.tr= 1.0f-texres.tr; - texres.tg= 1.0f-texres.tg; - texres.tb= 1.0f-texres.tb; - } - else texres.tin= 1.0f-texres.tin; - } - - /* mapping */ - if (mtex->mapto & MAP_COL) { - - if (rgb==0) { - texres.tr= mtex->r; - texres.tg= mtex->g; - texres.tb= mtex->b; - } - else if (mtex->mapto & MAP_ALPHA) { - texres.tin= 1.0; - } - else texres.tin= texres.ta; - - /* inverse gamma correction */ - if (mtex->tex->type==TEX_IMAGE) { - Image *ima = mtex->tex->ima; - ImBuf *ibuf = BKE_image_pool_acquire_ibuf(ima, &mtex->tex->iuser, har->pool); - - /* don't linearize float buffers, assumed to be linear */ - if (ibuf && !(ibuf->rect_float) && R.scene_color_manage) - IMB_colormanagement_colorspace_to_scene_linear_v3(&texres.tr, ibuf->rect_colorspace); - - BKE_image_pool_release_ibuf(ima, ibuf, har->pool); - } - - fact= texres.tin*mtex->colfac; - facm= 1.0f-fact; - - if (mtex->blendtype==MTEX_MUL) { - facm= 1.0f-mtex->colfac; - } - - if (mtex->blendtype==MTEX_SUB) fact= -fact; - - if (mtex->blendtype==MTEX_BLEND) { - col_r[0]= (fact*texres.tr + facm*har->r); - col_r[1]= (fact*texres.tg + facm*har->g); - col_r[2]= (fact*texres.tb + facm*har->b); - } - else if (mtex->blendtype==MTEX_MUL) { - col_r[0]= (facm+fact*texres.tr)*har->r; - col_r[1]= (facm+fact*texres.tg)*har->g; - col_r[2]= (facm+fact*texres.tb)*har->b; - } - else { - col_r[0]= (fact*texres.tr + har->r); - col_r[1]= (fact*texres.tg + har->g); - col_r[2]= (fact*texres.tb + har->b); - - CLAMP(col_r[0], 0.0f, 1.0f); - CLAMP(col_r[1], 0.0f, 1.0f); - CLAMP(col_r[2], 0.0f, 1.0f); - } - } - if (mtex->mapto & MAP_ALPHA) { - if (rgb) { - if (texres.talpha) { - texres.tin = texres.ta; - } - else { - texres.tin = IMB_colormanagement_get_luminance(&texres.tr); - } - } - - col_r[3]*= texres.tin; - } -} - -/* ------------------------------------------------------------------------- */ - -/* hor and zen are RGB vectors, blend is 1 float, should all be initialized */ -void do_sky_tex( - const float rco[3], const float view[3], const float lo[3], const float dxyview[2], - float hor[3], float zen[3], float *blend, int skyflag, short thread) -{ - const bool skip_load_image = (R.r.scemode & R_NO_IMAGE_LOAD) != 0; - const bool texnode_preview = (R.r.scemode & R_TEXNODE_PREVIEW) != 0; - MTex *mtex; - Tex *tex; - TexResult texres= {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL}; - float fact, stencilTin=1.0; - float tempvec[3], texvec[3], dxt[3], dyt[3]; - int tex_nr, rgb= 0; - - if (R.r.scemode & R_NO_TEX) return; - /* todo: add flag to test if there's a tex */ - texres.nor= NULL; - - for (tex_nr=0; tex_nr<MAX_MTEX; tex_nr++) { - if (R.wrld.mtex[tex_nr]) { - const float *co; - - mtex= R.wrld.mtex[tex_nr]; - - tex= mtex->tex; - if (tex == NULL) continue; - /* if (mtex->mapto==0) continue; */ - - /* which coords */ - co= lo; - - /* dxt dyt just from 1 value */ - if (dxyview) { - dxt[0]= dxt[1]= dxt[2]= dxyview[0]; - dyt[0]= dyt[1]= dyt[2]= dxyview[1]; - } - else { - dxt[0]= dxt[1]= dxt[2]= 0.0; - dyt[0]= dyt[1]= dyt[2]= 0.0; - } - - /* Grab the mapping settings for this texture */ - switch (mtex->texco) { - case TEXCO_ANGMAP: - /* only works with texture being "real" */ - /* use saacos(), fixes bug [#22398], float precision caused lo[2] to be slightly less than -1.0 */ - if (lo[0] || lo[1]) { /* check for zero case [#24807] */ - fact= (1.0f/(float)M_PI)*saacos(lo[2])/(sqrtf(lo[0]*lo[0] + lo[1]*lo[1])); - tempvec[0]= lo[0]*fact; - tempvec[1]= lo[1]*fact; - tempvec[2]= 0.0; - } - else { - /* this value has no angle, the vector is directly along the view. - * avoid divide by zero and use a dummy value. */ - tempvec[0]= 1.0f; - tempvec[1]= 0.0; - tempvec[2]= 0.0; - } - co= tempvec; - break; - - case TEXCO_H_SPHEREMAP: - case TEXCO_H_TUBEMAP: - if (skyflag & WO_ZENUP) { - if (mtex->texco==TEXCO_H_TUBEMAP) map_to_tube( tempvec, tempvec+1, lo[0], lo[2], lo[1]); - else map_to_sphere(tempvec, tempvec+1, lo[0], lo[2], lo[1]); - /* tube/spheremap maps for outside view, not inside */ - tempvec[0]= 1.0f-tempvec[0]; - /* only top half */ - tempvec[1]= 2.0f*tempvec[1]-1.0f; - tempvec[2]= 0.0; - /* and correction for do_2d_mapping */ - tempvec[0]= 2.0f*tempvec[0]-1.0f; - tempvec[1]= 2.0f*tempvec[1]-1.0f; - co= tempvec; - } - else { - /* potentially dangerous... check with multitex! */ - continue; - } - break; - case TEXCO_EQUIRECTMAP: - tempvec[0]= -atan2f(lo[2], lo[0]) / (float)M_PI; - tempvec[1]= atan2f(lo[1], hypot(lo[0], lo[2])) / (float)M_PI_2; - tempvec[2]= 0.0f; - co= tempvec; - break; - case TEXCO_OBJECT: - if (mtex->object) { - copy_v3_v3(tempvec, lo); - mul_m4_v3(mtex->object->imat_ren, tempvec); - co= tempvec; - } - break; - - case TEXCO_GLOB: - if (rco) { - copy_v3_v3(tempvec, rco); - mul_m4_v3(R.viewinv, tempvec); - co= tempvec; - } - else - co= lo; - -// copy_v3_v3(shi->dxgl, shi->dxco); -// mul_m3_v3(R.imat, shi->dxco); -// copy_v3_v3(shi->dygl, shi->dyco); -// mul_m3_v3(R.imat, shi->dyco); - break; - case TEXCO_VIEW: - co = view; - break; - } - - /* placement */ - if (mtex->projx) texvec[0]= mtex->size[0]*(co[mtex->projx-1]+mtex->ofs[0]); - else texvec[0]= mtex->size[0]*(mtex->ofs[0]); - - if (mtex->projy) texvec[1]= mtex->size[1]*(co[mtex->projy-1]+mtex->ofs[1]); - else texvec[1]= mtex->size[1]*(mtex->ofs[1]); - - if (mtex->projz) texvec[2]= mtex->size[2]*(co[mtex->projz-1]+mtex->ofs[2]); - else texvec[2]= mtex->size[2]*(mtex->ofs[2]); - - /* texture */ - if (tex->type==TEX_IMAGE) do_2d_mapping(mtex, texvec, NULL, NULL, dxt, dyt); - - rgb = multitex(mtex->tex, - texvec, - dxt, dyt, - R.osa, - &texres, - thread, - mtex->which_output, - R.pool, - skip_load_image, - texnode_preview, - true); - - /* texture output */ - if (rgb && (mtex->texflag & MTEX_RGBTOINT)) { - texres.tin = IMB_colormanagement_get_luminance(&texres.tr); - rgb= 0; - } - if (mtex->texflag & MTEX_NEGATIVE) { - if (rgb) { - texres.tr= 1.0f-texres.tr; - texres.tg= 1.0f-texres.tg; - texres.tb= 1.0f-texres.tb; - } - else texres.tin= 1.0f-texres.tin; - } - if (mtex->texflag & MTEX_STENCIL) { - if (rgb) { - fact= texres.ta; - texres.ta*= stencilTin; - stencilTin*= fact; - } - else { - fact= texres.tin; - texres.tin*= stencilTin; - stencilTin*= fact; - } - } - else { - if (rgb) texres.ta *= stencilTin; - else texres.tin*= stencilTin; - } - - /* color mapping */ - if (mtex->mapto & (WOMAP_HORIZ+WOMAP_ZENUP+WOMAP_ZENDOWN)) { - float tcol[3]; - - if (rgb==0) { - texres.tr= mtex->r; - texres.tg= mtex->g; - texres.tb= mtex->b; - } - else texres.tin= texres.ta; - - tcol[0]= texres.tr; tcol[1]= texres.tg; tcol[2]= texres.tb; - - /* inverse gamma correction */ - if (tex->type==TEX_IMAGE) { - Image *ima = tex->ima; - ImBuf *ibuf = BKE_image_pool_acquire_ibuf(ima, &tex->iuser, R.pool); - - /* don't linearize float buffers, assumed to be linear */ - if (ibuf && !(ibuf->rect_float) && R.scene_color_manage) - IMB_colormanagement_colorspace_to_scene_linear_v3(tcol, ibuf->rect_colorspace); - - BKE_image_pool_release_ibuf(ima, ibuf, R.pool); - } - - if (mtex->mapto & WOMAP_HORIZ) { - texture_rgb_blend(hor, tcol, hor, texres.tin, mtex->colfac, mtex->blendtype); - } - if (mtex->mapto & (WOMAP_ZENUP+WOMAP_ZENDOWN)) { - float zenfac = 0.0f; - - if (R.wrld.skytype & WO_SKYREAL) { - if ((skyflag & WO_ZENUP)) { - if (mtex->mapto & WOMAP_ZENUP) zenfac= mtex->zenupfac; - } - else if (mtex->mapto & WOMAP_ZENDOWN) zenfac= mtex->zendownfac; - } - else { - if (mtex->mapto & WOMAP_ZENUP) zenfac= mtex->zenupfac; - else if (mtex->mapto & WOMAP_ZENDOWN) zenfac= mtex->zendownfac; - } - - if (zenfac != 0.0f) - texture_rgb_blend(zen, tcol, zen, texres.tin, zenfac, mtex->blendtype); - } - } - if (mtex->mapto & WOMAP_BLEND) { - if (rgb) texres.tin = IMB_colormanagement_get_luminance(&texres.tr); - - *blend= texture_value_blend(mtex->def_var, *blend, texres.tin, mtex->blendfac, mtex->blendtype); - } - } - } -} - -/* ------------------------------------------------------------------------- */ -/* col_r supposed to be initialized with la->r,g,b */ - -void do_lamp_tex(LampRen *la, const float lavec[3], ShadeInput *shi, float col_r[3], int effect) -{ - const bool skip_load_image = (R.r.scemode & R_NO_IMAGE_LOAD) != 0; - const bool texnode_preview = (R.r.scemode & R_TEXNODE_PREVIEW) != 0; - Object *ob; - MTex *mtex; - Tex *tex; - TexResult texres= {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL}; - float *co = NULL, *dx = NULL, *dy = NULL, fact, stencilTin=1.0; - float texvec[3], dxt[3], dyt[3], tempvec[3]; - int i, tex_nr, rgb= 0; - - if (R.r.scemode & R_NO_TEX) return; - tex_nr= 0; - - for (; tex_nr<MAX_MTEX; tex_nr++) { - - if (la->mtex[tex_nr]) { - mtex= la->mtex[tex_nr]; - - tex= mtex->tex; - if (tex==NULL) continue; - texres.nor= NULL; - - /* which coords */ - if (mtex->texco==TEXCO_OBJECT) { - ob= mtex->object; - if (ob) { - co= tempvec; - dx= dxt; - dy= dyt; - copy_v3_v3(tempvec, shi->co); - mul_m4_v3(ob->imat_ren, tempvec); - if (shi->osatex) { - copy_v3_v3(dxt, shi->dxco); - copy_v3_v3(dyt, shi->dyco); - mul_mat3_m4_v3(ob->imat_ren, dxt); - mul_mat3_m4_v3(ob->imat_ren, dyt); - } - } - else { - co= shi->co; - dx= shi->dxco; dy= shi->dyco; - } - } - else if (mtex->texco==TEXCO_GLOB) { - co= shi->gl; dx= shi->dxco; dy= shi->dyco; - copy_v3_v3(shi->gl, shi->co); - mul_m4_v3(R.viewinv, shi->gl); - } - else if (mtex->texco==TEXCO_VIEW) { - - copy_v3_v3(tempvec, lavec); - mul_m3_v3(la->imat, tempvec); - - if (la->type==LA_SPOT) { - tempvec[0]*= la->spottexfac; - tempvec[1]*= la->spottexfac; - /* project from 3d to 2d */ - tempvec[0] /= -tempvec[2]; - tempvec[1] /= -tempvec[2]; - } - co= tempvec; - - dx= dxt; dy= dyt; - if (shi->osatex) { - copy_v3_v3(dxt, shi->dxlv); - copy_v3_v3(dyt, shi->dylv); - /* need some matrix conversion here? la->imat is a [3][3] matrix!!! **/ - mul_m3_v3(la->imat, dxt); - mul_m3_v3(la->imat, dyt); - - mul_v3_fl(dxt, la->spottexfac); - mul_v3_fl(dyt, la->spottexfac); - } - } - - - /* placement */ - if (mtex->projx && co) texvec[0]= mtex->size[0]*(co[mtex->projx-1]+mtex->ofs[0]); - else texvec[0]= mtex->size[0]*(mtex->ofs[0]); - - if (mtex->projy && co) texvec[1]= mtex->size[1]*(co[mtex->projy-1]+mtex->ofs[1]); - else texvec[1]= mtex->size[1]*(mtex->ofs[1]); - - if (mtex->projz && co) texvec[2]= mtex->size[2]*(co[mtex->projz-1]+mtex->ofs[2]); - else texvec[2]= mtex->size[2]*(mtex->ofs[2]); - - if (shi->osatex) { - if (!dx) { - for (i=0;i<2;i++) { - dxt[i] = dyt[i] = 0.0; - } - } - else { - if (mtex->projx) { - dxt[0]= mtex->size[0]*dx[mtex->projx-1]; - dyt[0]= mtex->size[0]*dy[mtex->projx-1]; - } - else { - dxt[0]= 0.0; - dyt[0]= 0.0; - } - if (mtex->projy) { - dxt[1]= mtex->size[1]*dx[mtex->projy-1]; - dyt[1]= mtex->size[1]*dy[mtex->projy-1]; - } - else { - dxt[1]= 0.0; - dyt[1]= 0.0; - } - if (mtex->projz) { - dxt[2]= mtex->size[2]*dx[mtex->projz-1]; - dyt[2]= mtex->size[2]*dy[mtex->projz-1]; - } - else { - dxt[2]= 0.0; - dyt[2]= 0.0; - } - } - } - - /* texture */ - if (tex->type==TEX_IMAGE) { - do_2d_mapping(mtex, texvec, NULL, NULL, dxt, dyt); - } - - rgb = multitex(tex, - texvec, - dxt, dyt, - shi->osatex, - &texres, - shi->thread, - mtex->which_output, - R.pool, - skip_load_image, - texnode_preview, - true); - - /* texture output */ - if (rgb && (mtex->texflag & MTEX_RGBTOINT)) { - texres.tin = IMB_colormanagement_get_luminance(&texres.tr); - rgb= 0; - } - if (mtex->texflag & MTEX_NEGATIVE) { - if (rgb) { - texres.tr= 1.0f-texres.tr; - texres.tg= 1.0f-texres.tg; - texres.tb= 1.0f-texres.tb; - } - else texres.tin= 1.0f-texres.tin; - } - if (mtex->texflag & MTEX_STENCIL) { - if (rgb) { - fact= texres.ta; - texres.ta*= stencilTin; - stencilTin*= fact; - } - else { - fact= texres.tin; - texres.tin*= stencilTin; - stencilTin*= fact; - } - } - else { - if (rgb) texres.ta*= stencilTin; - else texres.tin*= stencilTin; - } - - /* mapping */ - if (((mtex->mapto & LAMAP_COL) && (effect & LA_TEXTURE))||((mtex->mapto & LAMAP_SHAD) && (effect & LA_SHAD_TEX))) { - float col[3]; - - if (rgb==0) { - texres.tr= mtex->r; - texres.tg= mtex->g; - texres.tb= mtex->b; - } - else if (mtex->mapto & MAP_ALPHA) { - texres.tin= stencilTin; - } - else texres.tin= texres.ta; - - /* inverse gamma correction */ - if (tex->type==TEX_IMAGE) { - Image *ima = tex->ima; - ImBuf *ibuf = BKE_image_pool_acquire_ibuf(ima, &tex->iuser, R.pool); - - /* don't linearize float buffers, assumed to be linear */ - if (ibuf && !(ibuf->rect_float) && R.scene_color_manage) - IMB_colormanagement_colorspace_to_scene_linear_v3(&texres.tr, ibuf->rect_colorspace); - - BKE_image_pool_release_ibuf(ima, ibuf, R.pool); - } - - /* lamp colors were premultiplied with this */ - col[0]= texres.tr*la->energy; - col[1]= texres.tg*la->energy; - col[2]= texres.tb*la->energy; - - if (effect & LA_SHAD_TEX) - texture_rgb_blend(col_r, col, col_r, texres.tin, mtex->shadowfac, mtex->blendtype); - else - texture_rgb_blend(col_r, col, col_r, texres.tin, mtex->colfac, mtex->blendtype); - } - } - } -} - /* ------------------------------------------------------------------------- */ int externtex(const MTex *mtex, @@ -3626,7 +1476,7 @@ int externtex(const MTex *mtex, /* texture */ if (tex->type==TEX_IMAGE) { - do_2d_mapping(mtex, texvec, NULL, NULL, dxt, dyt); + do_2d_mapping(mtex, texvec, NULL, dxt, dyt); } rgb = multitex(tex, @@ -3658,327 +1508,3 @@ int externtex(const MTex *mtex, return (rgb != 0); } - -/* ------------------------------------------------------------------------- */ - -void render_realtime_texture(ShadeInput *shi, Image *ima) -{ - const bool skip_load_image = (R.r.scemode & R_NO_IMAGE_LOAD) != 0; - TexResult texr; - static Tex imatex[BLENDER_MAX_THREADS]; /* threadsafe */ - static int firsttime= 1; - Tex *tex; - float texvec[3], dx[2], dy[2]; - ShadeInputUV *suv= &shi->uv[shi->actuv]; - int a; - - if (R.r.scemode & R_NO_TEX) return; - - if (firsttime) { - BLI_thread_lock(LOCK_IMAGE); - if (firsttime) { - const int num_threads = BLI_system_thread_count(); - for (a = 0; a < num_threads; a++) { - memset(&imatex[a], 0, sizeof(Tex)); - BKE_texture_default(&imatex[a]); - imatex[a].type= TEX_IMAGE; - } - - firsttime= 0; - } - BLI_thread_unlock(LOCK_IMAGE); - } - - tex= &imatex[shi->thread]; - tex->iuser.ok= ima->ok; - tex->ima = ima; - - texvec[0]= 0.5f+0.5f*suv->uv[0]; - texvec[1]= 0.5f+0.5f*suv->uv[1]; - texvec[2] = 0.0f; /* initalize it because imagewrap looks at it. */ - if (shi->osatex) { - dx[0]= 0.5f*suv->dxuv[0]; - dx[1]= 0.5f*suv->dxuv[1]; - dy[0]= 0.5f*suv->dyuv[0]; - dy[1]= 0.5f*suv->dyuv[1]; - } - - texr.nor= NULL; - - if (shi->osatex) imagewraposa(tex, ima, NULL, texvec, dx, dy, &texr, R.pool, skip_load_image); - else imagewrap(tex, ima, NULL, texvec, &texr, R.pool, skip_load_image); - - shi->vcol[0]*= texr.tr; - shi->vcol[1]*= texr.tg; - shi->vcol[2]*= texr.tb; - shi->vcol[3]*= texr.ta; -} - -/* A modified part of shadeinput.c -> shade_input_set_uv() - * Used for sampling UV mapped texture color */ -static void textured_face_generate_uv( - const float normal[3], const float hit[3], - const float v1[3], const float v2[3], const float v3[3], - float r_uv[2]) -{ - - float detsh, t00, t10, t01, t11; - int axis1, axis2; - - /* find most stable axis to project */ - axis_dominant_v3(&axis1, &axis2, normal); - - /* compute u,v and derivatives */ - t00= v3[axis1]-v1[axis1]; t01= v3[axis2]-v1[axis2]; - t10= v3[axis1]-v2[axis1]; t11= v3[axis2]-v2[axis2]; - - detsh= 1.0f/(t00*t11-t10*t01); - t00*= detsh; t01*=detsh; - t10*=detsh; t11*=detsh; - - r_uv[0] = (hit[axis1] - v3[axis1]) * t11 - (hit[axis2] - v3[axis2]) * t10; - r_uv[1] = (hit[axis2] - v3[axis2]) * t00 - (hit[axis1] - v3[axis1]) * t01; - - /* u and v are in range -1 to 0, we allow a little bit extra but not too much, screws up speedvectors */ - CLAMP(r_uv[0], -2.0f, 1.0f); - CLAMP(r_uv[1], -2.0f, 1.0f); -} - -/* Generate an updated copy of material to use for color sampling. */ -Material *RE_sample_material_init(Depsgraph *depsgraph, Material *orig_mat, Scene *scene) -{ - Tex *tex = NULL; - Material *mat; - int tex_nr; - - if (!orig_mat) return NULL; - - /* copy material */ - mat = BKE_material_localize(orig_mat); - - /* update material anims */ - BKE_animsys_evaluate_animdata(scene, &mat->id, mat->adt, BKE_scene_frame_get(scene), ADT_RECALC_ANIM); - - /* strip material copy from unsupported flags */ - for (tex_nr=0; tex_nr<MAX_MTEX; tex_nr++) { - - if (mat->mtex[tex_nr]) { - MTex *mtex = mat->mtex[tex_nr]; - - /* just in case make all non-used mtexes empty*/ - Tex *cur_tex = mtex->tex; - mtex->tex = NULL; - - if (mat->septex & (1<<tex_nr) || !cur_tex) continue; - - /* only keep compatible texflags */ - mtex->texflag = mtex->texflag & (MTEX_RGBTOINT | MTEX_STENCIL | MTEX_NEGATIVE | MTEX_ALPHAMIX); - - /* depending of material type, strip non-compatible mapping modes */ - if (mat->material_type == MA_TYPE_SURFACE) { - if (!ELEM(mtex->texco, TEXCO_ORCO, TEXCO_OBJECT, TEXCO_GLOB, TEXCO_UV)) { - /* ignore this texture */ - mtex->texco = 0; - continue; - } - /* strip all mapto flags except color and alpha */ - mtex->mapto = (mtex->mapto & MAP_COL) | (mtex->mapto & MAP_ALPHA); - } - else if (mat->material_type == MA_TYPE_VOLUME) { - if (!ELEM(mtex->texco, TEXCO_OBJECT, TEXCO_ORCO, TEXCO_GLOB)) { - /* ignore */ - mtex->texco = 0; - continue; - } - /* strip all mapto flags except color and alpha */ - mtex->mapto = mtex->mapto & (MAP_TRANSMISSION_COL | MAP_REFLECTION_COL | MAP_DENSITY); - } - - /* if mapped to an object, calculate inverse matrices */ - if (mtex->texco==TEXCO_OBJECT) { - Object *ob= mtex->object; - if (ob) { - invert_m4_m4(ob->imat, ob->obmat); - copy_m4_m4(ob->imat_ren, ob->imat); - } - } - - /* copy texture */ - tex= mtex->tex = BKE_texture_localize(cur_tex); - - /* update texture anims */ - BKE_animsys_evaluate_animdata(scene, &tex->id, tex->adt, BKE_scene_frame_get(scene), ADT_RECALC_ANIM); - - /* update texture cache if required */ - if (tex->type==TEX_VOXELDATA) { - cache_voxeldata(tex, (int)scene->r.cfra); - } - if (tex->type==TEX_POINTDENSITY) { - /* set dummy values for render and do cache */ - Render dummy_re = {NULL}; - dummy_re.scene = scene; - unit_m4(dummy_re.viewinv); - unit_m4(dummy_re.viewmat); - unit_m4(dummy_re.winmat); - dummy_re.winx = dummy_re.winy = 128; - cache_pointdensity(depsgraph, &dummy_re, tex->pd); - } - - /* update image sequences and movies */ - if (tex->ima && BKE_image_is_animated(tex->ima)) { - BKE_image_user_check_frame_calc(&tex->iuser, (int)scene->r.cfra, 0); - } - } - } - return mat; -} - -/* free all duplicate data allocated by RE_sample_material_init() */ -void RE_sample_material_free(Material *mat) -{ - int tex_nr; - - /* free textures */ - for (tex_nr=0; tex_nr<MAX_MTEX; tex_nr++) { - if (mat->septex & (1<<tex_nr)) continue; - if (mat->mtex[tex_nr]) { - MTex *mtex= mat->mtex[tex_nr]; - - if (mtex->tex) { - /* don't update user counts as we are freeing a duplicate */ - BKE_texture_free(mtex->tex); - MEM_freeN(mtex->tex); - mtex->tex = NULL; - } - } - } - - /* don't update user counts as we are freeing a duplicate */ - BKE_material_free(mat); - MEM_freeN(mat); -} - -/* - * Get material diffuse color and alpha (including linked textures) in given coordinates - * - * color,alpha : input/output color values - * volume_co : sample coordinate in global space. used by volumetric materials - * surface_co : sample surface coordinate in global space. used by "surface" materials - * tri_index : surface tri index - * orcoDm : orco state derived mesh - */ -void RE_sample_material_color( - Material *mat, float color[3], float *alpha, const float volume_co[3], const float surface_co[3], - int tri_index, DerivedMesh *orcoDm, Object *ob) -{ - int v1, v2, v3; - MVert *mvert; - MLoop *mloop; - const MLoopTri *mlooptri; - float normal[3]; - ShadeInput shi = {NULL}; - Render re = {NULL}; - - /* Get face data */ - mvert = orcoDm->getVertArray(orcoDm); - mloop = orcoDm->getLoopArray(orcoDm); - mlooptri = orcoDm->getLoopTriArray(orcoDm); - - if (!mvert || !mlooptri || !mat) { - return; - } - - v1 = mloop[mlooptri[tri_index].tri[0]].v; - v2 = mloop[mlooptri[tri_index].tri[1]].v; - v3 = mloop[mlooptri[tri_index].tri[2]].v; - normal_tri_v3(normal, mvert[v1].co, mvert[v2].co, mvert[v3].co); - - /* generate shadeinput with data required */ - shi.mat = mat; - - /* fill shadeinput data depending on material type */ - if (mat->material_type == MA_TYPE_SURFACE) { - /* global coordinates */ - copy_v3_v3(shi.gl, surface_co); - /* object space coordinates */ - copy_v3_v3(shi.co, surface_co); - mul_m4_v3(ob->imat, shi.co); - /* orco coordinates */ - { - float uv[2]; - float l; - /* Get generated UV */ - textured_face_generate_uv(normal, shi.co, mvert[v1].co, mvert[v2].co, mvert[v3].co, uv); - l= 1.0f+uv[0]+uv[1]; - - /* calculate generated coordinate */ - shi.lo[0]= l*mvert[v3].co[0]-uv[0]*mvert[v1].co[0]-uv[1]*mvert[v2].co[0]; - shi.lo[1]= l*mvert[v3].co[1]-uv[0]*mvert[v1].co[1]-uv[1]*mvert[v2].co[1]; - shi.lo[2]= l*mvert[v3].co[2]-uv[0]*mvert[v1].co[2]-uv[1]*mvert[v2].co[2]; - } - /* uv coordinates */ - { - const int layers = CustomData_number_of_layers(&orcoDm->loopData, CD_MLOOPUV); - const int layer_index = CustomData_get_layer_index(&orcoDm->loopData, CD_MLOOPUV); - int i; - - /* for every uv map set coords and name */ - for (i=0; i<layers; i++) { - if (layer_index >= 0) { - const float *uv1, *uv2, *uv3; - const CustomData *data = &orcoDm->loopData; - const MLoopUV *mloopuv = data->layers[layer_index + i].data; - float uv[2]; - float l; - - /* point layer name from actual layer data */ - shi.uv[i].name = data->layers[i].name; - /* Get generated coordinates to calculate UV from */ - textured_face_generate_uv(normal, shi.co, mvert[v1].co, mvert[v2].co, mvert[v3].co, uv); - /* Get UV mapping coordinate */ - l= 1.0f+uv[0]+uv[1]; - - uv1 = mloopuv[mlooptri[tri_index].tri[0]].uv; - uv2 = mloopuv[mlooptri[tri_index].tri[1]].uv; - uv3 = mloopuv[mlooptri[tri_index].tri[2]].uv; - - shi.uv[i].uv[0]= -1.0f + 2.0f*(l*uv3[0]-uv[0]*uv1[0]-uv[1]*uv2[0]); - shi.uv[i].uv[1]= -1.0f + 2.0f*(l*uv3[1]-uv[0]*uv1[1]-uv[1]*uv2[1]); - shi.uv[i].uv[2]= 0.0f; /* texture.c assumes there are 3 coords */ - } - } - /* active uv map */ - shi.actuv = CustomData_get_active_layer_index(&orcoDm->loopData, CD_MLOOPUV) - layer_index; - shi.totuv = layers; - } - - /* apply initial values from material */ - shi.r = mat->r; - shi.g = mat->g; - shi.b = mat->b; - shi.alpha = mat->alpha; - - /* do texture */ - do_material_tex(&shi, &re); - - /* apply result */ - color[0] = shi.r; - color[1] = shi.g; - color[2] = shi.b; - *alpha = shi.alpha; - } - else if (mat->material_type == MA_TYPE_VOLUME) { - ObjectInstanceRen obi = {NULL}; - obi.ob = ob; - shi.obi = &obi; - unit_m4(re.viewinv); - copy_v3_v3(color, mat->vol.reflection_col); - *alpha = mat->vol.density; - - /* do texture */ - do_volume_tex(&shi, volume_co, (MAP_TRANSMISSION_COL | MAP_REFLECTION_COL | MAP_DENSITY), - color, alpha, &re); - } -} - -/* eof */ diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c deleted file mode 100644 index c9072105dd9..00000000000 --- a/source/blender/render/intern/source/rendercore.c +++ /dev/null @@ -1,2028 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * Contributors: Hos, Robert Wenzlaff. - * Contributors: 2004/2005/2006 Blender Foundation, full recode - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/render/intern/source/rendercore.c - * \ingroup render - */ - - -/* system includes */ -#include <stdio.h> -#include <math.h> -#include <float.h> -#include <string.h> -#include <assert.h> - -/* External modules: */ -#include "MEM_guardedalloc.h" - -#include "BLI_math.h" -#include "BLI_blenlib.h" -#include "BLI_rand.h" -#include "BLI_threads.h" -#include "BLI_utildefines.h" - -#include "DNA_image_types.h" -#include "DNA_lamp_types.h" -#include "DNA_material_types.h" -#include "DNA_group_types.h" - -/* local include */ -#include "renderpipeline.h" -#include "render_result.h" -#include "render_types.h" -#include "renderdatabase.h" -#include "occlusion.h" -#include "pixelblending.h" -#include "pixelshading.h" -#include "shadbuf.h" -#include "shading.h" -#include "sss.h" -#include "zbuf.h" - -/* own include */ -#include "rendercore.h" - - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -/* defined in pipeline.c, is hardcopy of active dynamic allocated Render */ -/* only to be used here in this file, it's for speed */ -extern struct Render R; -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -/* x and y are current pixels in rect to be rendered */ -/* do not normalize! */ -void calc_view_vector(float view[3], float x, float y) -{ - - view[2]= -ABS(R.clipsta); - - if (R.r.mode & R_ORTHO) { - view[0]= view[1]= 0.0f; - } - else { - - if (R.r.mode & R_PANORAMA) { - x-= R.panodxp; - } - - /* move x and y to real viewplane coords */ - x = (x / (float)R.winx); - view[0] = R.viewplane.xmin + x * BLI_rctf_size_x(&R.viewplane); - - y = (y / (float)R.winy); - view[1] = R.viewplane.ymin + y * BLI_rctf_size_y(&R.viewplane); - -// if (R.flag & R_SEC_FIELD) { -// if (R.r.mode & R_ODDFIELD) view[1]= (y+R.ystart)*R.ycor; -// else view[1]= (y+R.ystart+1.0)*R.ycor; -// } -// else view[1]= (y+R.ystart+R.bluroffsy+0.5)*R.ycor; - - if (R.r.mode & R_PANORAMA) { - float u= view[0] + R.panodxv; float v= view[2]; - view[0]= R.panoco*u + R.panosi*v; - view[2]= -R.panosi*u + R.panoco*v; - } - } -} - -void calc_renderco_ortho(float co[3], float x, float y, int z) -{ - /* x and y 3d coordinate can be derived from pixel coord and winmat */ - float fx= 2.0f/(R.winx*R.winmat[0][0]); - float fy= 2.0f/(R.winy*R.winmat[1][1]); - float zco; - - co[0]= (x - 0.5f*R.winx)*fx - R.winmat[3][0]/R.winmat[0][0]; - co[1]= (y - 0.5f*R.winy)*fy - R.winmat[3][1]/R.winmat[1][1]; - - zco= ((float)z)/2147483647.0f; - co[2]= R.winmat[3][2]/( R.winmat[2][3]*zco - R.winmat[2][2] ); -} - -void calc_renderco_zbuf(float co[3], const float view[3], int z) -{ - float fac, zco; - - /* inverse of zbuf calc: zbuf = MAXZ*hoco_z/hoco_w */ - zco= ((float)z)/2147483647.0f; - co[2]= R.winmat[3][2]/( R.winmat[2][3]*zco - R.winmat[2][2] ); - - fac= co[2]/view[2]; - co[0]= fac*view[0]; - co[1]= fac*view[1]; -} - -/* also used in zbuf.c and shadbuf.c */ -int count_mask(unsigned short mask) -{ - if (R.samples) - return (R.samples->cmask[mask & 255]+R.samples->cmask[mask>>8]); - return 0; -} - -static int calchalo_z(HaloRen *har, int zz) -{ - - if (har->type & HA_ONLYSKY) { - if (zz < 0x7FFFFFF0) zz= - 0x7FFFFF; /* edge render messes zvalues */ - } - else { - zz= (zz>>8); - } - return zz; -} - - - -static void halo_pixelstruct(HaloRen *har, RenderLayer **rlpp, int totsample, int od, float dist, float xn, float yn, PixStr *ps) -{ - float col[4], accol[4], fac; - int amount, amountm, zz, flarec, sample, fullsample, mask=0; - - fullsample= (totsample > 1); - amount= 0; - accol[0] = accol[1] = accol[2] = accol[3]= 0.0f; - col[0] = col[1] = col[2] = col[3]= 0.0f; - flarec= har->flarec; - - while (ps) { - amountm= count_mask(ps->mask); - amount+= amountm; - - zz= calchalo_z(har, ps->z); - if ((zz> har->zs) || (har->mat && (har->mat->mode & MA_HALO_SOFT))) { - if (shadeHaloFloat(har, col, zz, dist, xn, yn, flarec)) { - flarec= 0; - - if (fullsample) { - for (sample=0; sample<totsample; sample++) { - if (ps->mask & (1 << sample)) { - float *pass = RE_RenderLayerGetPass(rlpp[sample], RE_PASSNAME_COMBINED, R.viewname); - addalphaAddfacFloat(pass + od*4, col, har->add); - } - } - } - else { - fac= ((float)amountm)/(float)R.osa; - accol[0]+= fac*col[0]; - accol[1]+= fac*col[1]; - accol[2]+= fac*col[2]; - accol[3]+= fac*col[3]; - } - } - } - - mask |= ps->mask; - ps= ps->next; - } - - /* now do the sky sub-pixels */ - amount= R.osa-amount; - if (amount) { - if (shadeHaloFloat(har, col, 0x7FFFFF, dist, xn, yn, flarec)) { - if (!fullsample) { - fac= ((float)amount)/(float)R.osa; - accol[0]+= fac*col[0]; - accol[1]+= fac*col[1]; - accol[2]+= fac*col[2]; - accol[3]+= fac*col[3]; - } - } - } - - if (fullsample) { - for (sample=0; sample<totsample; sample++) { - if (!(mask & (1 << sample))) { - float *pass = RE_RenderLayerGetPass(rlpp[sample], RE_PASSNAME_COMBINED, R.viewname); - addalphaAddfacFloat(pass + od*4, col, har->add); - } - } - } - else { - col[0]= accol[0]; - col[1]= accol[1]; - col[2]= accol[2]; - col[3]= accol[3]; - - for (sample=0; sample<totsample; sample++) { - float *pass = RE_RenderLayerGetPass(rlpp[sample], RE_PASSNAME_COMBINED, R.viewname); - addalphaAddfacFloat(pass + od*4, col, har->add); - } - } -} - -static void halo_tile(RenderPart *pa, RenderLayer *rl) -{ - RenderLayer *rlpp[RE_MAX_OSA]; - HaloRen *har; - rcti disprect= pa->disprect, testrect= pa->disprect; - float dist, xsq, ysq, xn, yn; - float col[4]; - intptr_t *rd= NULL; - int a, *rz, zz, y, sample, totsample, od; - short minx, maxx, miny, maxy, x; - unsigned int lay= (1 << 20) - 1; - - /* we don't render halos in the cropped area, gives errors in flare counter */ - if (pa->crop) { - testrect.xmin+= pa->crop; - testrect.xmax-= pa->crop; - testrect.ymin+= pa->crop; - testrect.ymax-= pa->crop; - } - - totsample= get_sample_layers(pa, rl, rlpp); - - for (a=0; a<R.tothalo; a++) { - har= R.sortedhalos[a]; - - /* layer test, clip halo with y */ - if ((har->lay & lay) == 0) { - /* pass */ - } - else if (testrect.ymin > har->maxy) { - /* pass */ - } - else if (testrect.ymax < har->miny) { - /* pass */ - } - else { - - minx= floor(har->xs-har->rad); - maxx= ceil(har->xs+har->rad); - - if (testrect.xmin > maxx) { - /* pass */ - } - else if (testrect.xmax < minx) { - /* pass */ - } - else { - - minx = max_ii(minx, testrect.xmin); - maxx = min_ii(maxx, testrect.xmax); - - miny = max_ii(har->miny, testrect.ymin); - maxy = min_ii(har->maxy, testrect.ymax); - - for (y=miny; y<maxy; y++) { - int rectofs= (y-disprect.ymin)*pa->rectx + (minx - disprect.xmin); - rz= pa->rectz + rectofs; - od= rectofs; - - if (pa->rectdaps) - rd= pa->rectdaps + rectofs; - - yn= (y-har->ys)*R.ycor; - ysq= yn*yn; - - for (x=minx; x<maxx; x++, rz++, od++) { - xn= x- har->xs; - xsq= xn*xn; - dist= xsq+ysq; - if (dist<har->radsq) { - if (rd && *rd) { - halo_pixelstruct(har, rlpp, totsample, od, dist, xn, yn, (PixStr *)*rd); - } - else { - zz= calchalo_z(har, *rz); - if ((zz> har->zs) || (har->mat && (har->mat->mode & MA_HALO_SOFT))) { - if (shadeHaloFloat(har, col, zz, dist, xn, yn, har->flarec)) { - for (sample=0; sample<totsample; sample++) { - float * rect= RE_RenderLayerGetPass(rlpp[sample], RE_PASSNAME_COMBINED, R.viewname); - addalphaAddfacFloat(rect + od*4, col, har->add); - } - } - } - } - } - if (rd) rd++; - } - } - } - } - if (R.test_break(R.tbh) ) break; - } -} - -static void lamphalo_tile(RenderPart *pa, RenderLayer *rl) -{ - RenderLayer *rlpp[RE_MAX_OSA]; - ShadeInput shi; - float *pass; - float fac, col[4]; - intptr_t *rd= pa->rectdaps; - const int *rz= pa->rectz; - int x, y, sample, totsample, fullsample, od; - - totsample= get_sample_layers(pa, rl, rlpp); - fullsample= (totsample > 1); - - shade_input_initialize(&shi, pa, rl, 0); /* this zero's ShadeInput for us */ - - for (od=0, y=pa->disprect.ymin; y<pa->disprect.ymax; y++) { - for (x=pa->disprect.xmin; x<pa->disprect.xmax; x++, rz++, od++) { - - calc_view_vector(shi.view, x, y); - - if (rd && *rd) { - PixStr *ps= (PixStr *)*rd; - int count, totsamp= 0, mask= 0; - - while (ps) { - if (R.r.mode & R_ORTHO) - calc_renderco_ortho(shi.co, (float)x, (float)y, ps->z); - else - calc_renderco_zbuf(shi.co, shi.view, ps->z); - - totsamp+= count= count_mask(ps->mask); - mask |= ps->mask; - - col[0]= col[1]= col[2]= col[3]= 0.0f; - renderspothalo(&shi, col, 1.0f); - - if (fullsample) { - for (sample=0; sample<totsample; sample++) { - if (ps->mask & (1 << sample)) { - pass = RE_RenderLayerGetPass(rlpp[sample], RE_PASSNAME_COMBINED, R.viewname); - pass += od * 4; - pass[0]+= col[0]; - pass[1]+= col[1]; - pass[2]+= col[2]; - pass[3]+= col[3]; - if (pass[3]>1.0f) pass[3]= 1.0f; - } - } - } - else { - fac= ((float)count)/(float)R.osa; - pass = RE_RenderLayerGetPass(rl, RE_PASSNAME_COMBINED, R.viewname); - pass += od * 4; - pass[0]+= fac*col[0]; - pass[1]+= fac*col[1]; - pass[2]+= fac*col[2]; - pass[3]+= fac*col[3]; - if (pass[3]>1.0f) pass[3]= 1.0f; - } - - ps= ps->next; - } - - if (totsamp<R.osa) { - shi.co[2]= 0.0f; - - col[0]= col[1]= col[2]= col[3]= 0.0f; - renderspothalo(&shi, col, 1.0f); - - if (fullsample) { - for (sample=0; sample<totsample; sample++) { - if (!(mask & (1 << sample))) { - - pass = RE_RenderLayerGetPass(rlpp[sample], RE_PASSNAME_COMBINED, R.viewname); - pass += od * 4; - pass[0]+= col[0]; - pass[1]+= col[1]; - pass[2]+= col[2]; - pass[3]+= col[3]; - if (pass[3]>1.0f) pass[3]= 1.0f; - } - } - } - else { - fac= ((float)R.osa-totsamp)/(float)R.osa; - pass = RE_RenderLayerGetPass(rl, RE_PASSNAME_COMBINED, R.viewname); - pass += od * 4; - pass[0]+= fac*col[0]; - pass[1]+= fac*col[1]; - pass[2]+= fac*col[2]; - pass[3]+= fac*col[3]; - if (pass[3]>1.0f) pass[3]= 1.0f; - } - } - } - else { - if (R.r.mode & R_ORTHO) - calc_renderco_ortho(shi.co, (float)x, (float)y, *rz); - else - calc_renderco_zbuf(shi.co, shi.view, *rz); - - col[0]= col[1]= col[2]= col[3]= 0.0f; - renderspothalo(&shi, col, 1.0f); - - for (sample=0; sample<totsample; sample++) { - pass = RE_RenderLayerGetPass(rlpp[sample], RE_PASSNAME_COMBINED, R.viewname); - pass += od * 4; - pass[0]+= col[0]; - pass[1]+= col[1]; - pass[2]+= col[2]; - pass[3]+= col[3]; - if (pass[3]>1.0f) pass[3]= 1.0f; - } - } - - if (rd) rd++; - } - if (y&1) - if (R.test_break(R.tbh)) break; - } -} - - -/* ********************* MAINLOOPS ******************** */ - -/* osa version */ -static void add_filt_passes(RenderLayer *rl, int curmask, int rectx, int offset, ShadeInput *shi, ShadeResult *shr) -{ - RenderPass *rpass; - - for (rpass= rl->passes.first; rpass; rpass= rpass->next) { - float *fp, *col= NULL; - int pixsize= 3; - - if (STREQ(rpass->name, RE_PASSNAME_COMBINED)) { - add_filt_fmask(curmask, shr->combined, rpass->rect + 4*offset, rectx); - } - else if (STREQ(rpass->name, RE_PASSNAME_Z)) { - fp = rpass->rect + offset; - *fp = shr->z; - } - else if (STREQ(rpass->name, RE_PASSNAME_RGBA)) { - col = shr->col; - pixsize = 4; - } - else if (STREQ(rpass->name, RE_PASSNAME_EMIT)) { - col = shr->emit; - } - else if (STREQ(rpass->name, RE_PASSNAME_DIFFUSE)) { - col = shr->diff; - } - else if (STREQ(rpass->name, RE_PASSNAME_SPEC)) { - col = shr->spec; - } - else if (STREQ(rpass->name, RE_PASSNAME_SHADOW)) { - col = shr->shad; - } - else if (STREQ(rpass->name, RE_PASSNAME_AO)) { - col = shr->ao; - } - else if (STREQ(rpass->name, RE_PASSNAME_ENVIRONMENT)) { - col = shr->env; - } - else if (STREQ(rpass->name, RE_PASSNAME_INDIRECT)) { - col = shr->indirect; - } - else if (STREQ(rpass->name, RE_PASSNAME_REFLECT)) { - col = shr->refl; - } - else if (STREQ(rpass->name, RE_PASSNAME_REFRACT)) { - col = shr->refr; - } - else if (STREQ(rpass->name, RE_PASSNAME_NORMAL)) { - col = shr->nor; - } - else if (STREQ(rpass->name, RE_PASSNAME_UV)) { - /* box filter only, gauss will screwup UV too much */ - if (shi->totuv) { - float mult = (float)count_mask(curmask)/(float)R.osa; - fp = rpass->rect + 3*offset; - fp[0]+= mult*(0.5f + 0.5f*shi->uv[shi->actuv].uv[0]); - fp[1]+= mult*(0.5f + 0.5f*shi->uv[shi->actuv].uv[1]); - fp[2]+= mult; - } - } - else if (STREQ(rpass->name, RE_PASSNAME_INDEXOB)) { - /* no filter */ - if (shi->vlr) { - fp = rpass->rect + offset; - if (*fp==0.0f) - *fp = (float)shi->obr->ob->index; - } - } - else if (STREQ(rpass->name, RE_PASSNAME_INDEXMA)) { - /* no filter */ - if (shi->vlr) { - fp = rpass->rect + offset; - if (*fp==0.0f) - *fp = (float)shi->mat->index; - } - } - else if (STREQ(rpass->name, RE_PASSNAME_MIST)) { - /* */ - col = &shr->mist; - pixsize = 1; - } - else if (STREQ(rpass->name, RE_PASSNAME_VECTOR)) { - /* add minimum speed in pixel, no filter */ - fp = rpass->rect + 4*offset; - if ( (ABS(shr->winspeed[0]) + ABS(shr->winspeed[1]))< (ABS(fp[0]) + ABS(fp[1])) ) { - fp[0] = shr->winspeed[0]; - fp[1] = shr->winspeed[1]; - } - if ( (ABS(shr->winspeed[2]) + ABS(shr->winspeed[3]))< (ABS(fp[2]) + ABS(fp[3])) ) { - fp[2] = shr->winspeed[2]; - fp[3] = shr->winspeed[3]; - } - } - else if (STREQ(rpass->name, RE_PASSNAME_RAYHITS)) { - /* */ - col = shr->rayhits; - pixsize= 4; - } - - if (col) { - fp= rpass->rect + pixsize*offset; - add_filt_fmask_pixsize(curmask, col, fp, rectx, pixsize); - } - } -} - -/* non-osa version */ -static void add_passes(RenderLayer *rl, int offset, ShadeInput *shi, ShadeResult *shr) -{ - RenderPass *rpass; - float *fp; - - for (rpass= rl->passes.first; rpass; rpass= rpass->next) { - float *col= NULL, uvcol[3]; - int a, pixsize= 3; - - if (STREQ(rpass->name, RE_PASSNAME_COMBINED)) { - /* copy combined to use for preview */ - copy_v4_v4(rpass->rect + 4*offset, shr->combined); - } - else if (STREQ(rpass->name, RE_PASSNAME_Z)) { - fp = rpass->rect + offset; - *fp = shr->z; - } - else if (STREQ(rpass->name, RE_PASSNAME_RGBA)) { - col = shr->col; - pixsize = 4; - } - else if (STREQ(rpass->name, RE_PASSNAME_EMIT)) { - col = shr->emit; - } - else if (STREQ(rpass->name, RE_PASSNAME_DIFFUSE)) { - col = shr->diff; - } - else if (STREQ(rpass->name, RE_PASSNAME_SPEC)) { - col = shr->spec; - } - else if (STREQ(rpass->name, RE_PASSNAME_SHADOW)) { - col = shr->shad; - } - else if (STREQ(rpass->name, RE_PASSNAME_AO)) { - col = shr->ao; - } - else if (STREQ(rpass->name, RE_PASSNAME_ENVIRONMENT)) { - col = shr->env; - } - else if (STREQ(rpass->name, RE_PASSNAME_INDIRECT)) { - col = shr->indirect; - } - else if (STREQ(rpass->name, RE_PASSNAME_REFLECT)) { - col = shr->refl; - } - else if (STREQ(rpass->name, RE_PASSNAME_REFRACT)) { - col = shr->refr; - } - else if (STREQ(rpass->name, RE_PASSNAME_NORMAL)) { - col = shr->nor; - } - else if (STREQ(rpass->name, RE_PASSNAME_UV)) { - if (shi->totuv) { - uvcol[0] = 0.5f + 0.5f*shi->uv[shi->actuv].uv[0]; - uvcol[1] = 0.5f + 0.5f*shi->uv[shi->actuv].uv[1]; - uvcol[2] = 1.0f; - col = uvcol; - } - } - else if (STREQ(rpass->name, RE_PASSNAME_VECTOR)) { - col = shr->winspeed; - pixsize = 4; - } - else if (STREQ(rpass->name, RE_PASSNAME_INDEXOB)) { - if (shi->vlr) { - fp = rpass->rect + offset; - *fp = (float)shi->obr->ob->index; - } - } - else if (STREQ(rpass->name, RE_PASSNAME_INDEXMA)) { - if (shi->vlr) { - fp = rpass->rect + offset; - *fp = (float)shi->mat->index; - } - } - else if (STREQ(rpass->name, RE_PASSNAME_MIST)) { - fp = rpass->rect + offset; - *fp = shr->mist; - } - else if (STREQ(rpass->name, RE_PASSNAME_RAYHITS)) { - col = shr->rayhits; - pixsize = 4; - } - - if (col) { - fp = rpass->rect + pixsize*offset; - for (a=0; a<pixsize; a++) - fp[a] = col[a]; - } - } -} - -int get_sample_layers(RenderPart *pa, RenderLayer *rl, RenderLayer **rlpp) -{ - - if (pa->fullresult.first) { - int sample, nr= BLI_findindex(&pa->result->layers, rl); - - for (sample=0; sample<R.osa; sample++) { - RenderResult *rr= BLI_findlink(&pa->fullresult, sample); - - rlpp[sample]= BLI_findlink(&rr->layers, nr); - } - return R.osa; - } - else { - rlpp[0]= rl; - return 1; - } -} - - -/* only do sky, is default in the solid layer (shade_tile) btw */ -static void sky_tile(RenderPart *pa, RenderLayer *rl) -{ - RenderLayer *rlpp[RE_MAX_OSA]; - int x, y, od=0, totsample; - - if (R.r.alphamode!=R_ADDSKY) - return; - - totsample= get_sample_layers(pa, rl, rlpp); - - for (y=pa->disprect.ymin; y<pa->disprect.ymax; y++) { - for (x=pa->disprect.xmin; x<pa->disprect.xmax; x++, od+=4) { - float col[4]; - int sample; - bool done = false; - - for (sample= 0; sample<totsample; sample++) { - float *pass = RE_RenderLayerGetPass(rlpp[sample], RE_PASSNAME_COMBINED, R.viewname); - pass += od; - - if (pass[3]<1.0f) { - - if (done==0) { - shadeSkyPixel(col, x, y, pa->thread); - done = true; - } - - if (pass[3]==0.0f) { - copy_v4_v4(pass, col); - pass[3] = 1.0f; - } - else { - addAlphaUnderFloat(pass, col); - pass[3] = 1.0f; - } - } - } - } - - if (y&1) - if (R.test_break(R.tbh)) break; - } -} - -static void atm_tile(RenderPart *pa, RenderLayer *rl) -{ - RenderPass *zpass; - GroupObject *go; - LampRen *lar; - RenderLayer *rlpp[RE_MAX_OSA]; - int totsample; - int x, y, od= 0; - - totsample= get_sample_layers(pa, rl, rlpp); - - /* check that z pass is enabled */ - if (pa->rectz==NULL) return; - for (zpass= rl->passes.first; zpass; zpass= zpass->next) - if (STREQ(zpass->name, RE_PASSNAME_Z)) - break; - - if (zpass==NULL) return; - - /* check for at least one sun lamp that its atmosphere flag is enabled */ - for (go=R.lights.first; go; go= go->next) { - lar= go->lampren; - if (lar->type==LA_SUN && lar->sunsky && (lar->sunsky->effect_type & LA_SUN_EFFECT_AP)) - break; - } - /* do nothign and return if there is no sun lamp */ - if (go==NULL) - return; - - /* for each x,y and each sample, and each sun lamp*/ - for (y=pa->disprect.ymin; y<pa->disprect.ymax; y++) { - for (x=pa->disprect.xmin; x<pa->disprect.xmax; x++, od++) { - int sample; - - for (sample=0; sample<totsample; sample++) { - const float *zrect = RE_RenderLayerGetPass(rlpp[sample], RE_PASSNAME_Z, R.viewname) + od; - float *rgbrect = RE_RenderLayerGetPass(rlpp[sample], RE_PASSNAME_COMBINED, R.viewname) + 4*od; - float rgb[3] = {0}; - bool done = false; - - for (go=R.lights.first; go; go= go->next) { - - - lar= go->lampren; - if (lar->type==LA_SUN && lar->sunsky) { - - /* if it's sky continue and don't apply atmosphere effect on it */ - if (*zrect >= 9.9e10f || rgbrect[3]==0.0f) { - continue; - } - - if ((lar->sunsky->effect_type & LA_SUN_EFFECT_AP)) { - float tmp_rgb[3]; - - /* skip if worldspace lamp vector is below horizon */ - if (go->ob->obmat[2][2] < 0.f) { - continue; - } - - copy_v3_v3(tmp_rgb, rgbrect); - if (rgbrect[3]!=1.0f) { /* de-premul */ - mul_v3_fl(tmp_rgb, 1.0f/rgbrect[3]); - } - shadeAtmPixel(lar->sunsky, tmp_rgb, x, y, *zrect); - if (rgbrect[3]!=1.0f) { /* premul */ - mul_v3_fl(tmp_rgb, rgbrect[3]); - } - - if (done==0) { - copy_v3_v3(rgb, tmp_rgb); - done = true; - } - else { - rgb[0] = 0.5f*rgb[0] + 0.5f*tmp_rgb[0]; - rgb[1] = 0.5f*rgb[1] + 0.5f*tmp_rgb[1]; - rgb[2] = 0.5f*rgb[2] + 0.5f*tmp_rgb[2]; - } - } - } - } - - /* if at least for one sun lamp aerial perspective was applied*/ - if (done) { - copy_v3_v3(rgbrect, rgb); - } - } - } - } -} - -static void shadeDA_tile(RenderPart *pa, RenderLayer *rl) -{ - RenderResult *rr= pa->result; - ShadeSample ssamp; - intptr_t *rd, *rectdaps= pa->rectdaps; - int samp; - int x, y, seed, crop=0, offs=0, od; - - if (R.test_break(R.tbh)) return; - - /* irregular shadowb buffer creation */ - if (R.r.mode & R_SHADOW) - ISB_create(pa, NULL); - - /* we set per pixel a fixed seed, for random AO and shadow samples */ - seed= pa->rectx*pa->disprect.ymin; - - /* general shader info, passes */ - shade_sample_initialize(&ssamp, pa, rl); - - /* occlusion caching */ - if (R.occlusiontree) - cache_occ_samples(&R, pa, &ssamp); - - /* filtered render, for now we assume only 1 filter size */ - if (pa->crop) { - crop= 1; - rectdaps+= pa->rectx + 1; - offs= pa->rectx + 1; - } - - /* scanline updates have to be 2 lines behind */ - rr->renrect.ymin = 0; - rr->renrect.ymax = -2*crop; - rr->renlay= rl; - - for (y=pa->disprect.ymin+crop; y<pa->disprect.ymax-crop; y++, rr->renrect.ymax++) { - rd= rectdaps; - od= offs; - - for (x=pa->disprect.xmin+crop; x<pa->disprect.xmax-crop; x++, rd++, od++) { - BLI_thread_srandom(pa->thread, seed++); - - if (*rd) { - if (shade_samples(&ssamp, (PixStr *)(*rd), x, y)) { - - /* multisample buffers or filtered mask filling? */ - if (pa->fullresult.first) { - int a; - for (samp=0; samp<ssamp.tot; samp++) { - int smask= ssamp.shi[samp].mask; - for (a=0; a<R.osa; a++) { - int mask= 1<<a; - if (smask & mask) - add_passes(ssamp.rlpp[a], od, &ssamp.shi[samp], &ssamp.shr[samp]); - } - } - } - else { - for (samp=0; samp<ssamp.tot; samp++) - add_filt_passes(rl, ssamp.shi[samp].mask, pa->rectx, od, &ssamp.shi[samp], &ssamp.shr[samp]); - } - } - } - } - - rectdaps+= pa->rectx; - offs+= pa->rectx; - - if (y&1) if (R.test_break(R.tbh)) break; - } - - /* disable scanline updating */ - rr->renlay= NULL; - - if (R.r.mode & R_SHADOW) - ISB_free(pa); - - if (R.occlusiontree) - free_occ_samples(&R, pa); -} - -/* ************* pixel struct ******** */ - - -static PixStrMain *addpsmain(ListBase *lb) -{ - PixStrMain *psm; - - psm= (PixStrMain *)MEM_mallocN(sizeof(PixStrMain), "pixstrMain"); - BLI_addtail(lb, psm); - - psm->ps= (PixStr *)MEM_mallocN(4096*sizeof(PixStr), "pixstr"); - psm->counter= 0; - - return psm; -} - -static void freeps(ListBase *lb) -{ - PixStrMain *psm, *psmnext; - - for (psm= lb->first; psm; psm= psmnext) { - psmnext= psm->next; - if (psm->ps) - MEM_freeN(psm->ps); - MEM_freeN(psm); - } - BLI_listbase_clear(lb); -} - -static void addps(ListBase *lb, intptr_t *rd, int obi, int facenr, int z, int maskz, unsigned short mask) -{ - PixStrMain *psm; - PixStr *ps, *last= NULL; - - if (*rd) { - ps= (PixStr *)(*rd); - - while (ps) { - if ( ps->obi == obi && ps->facenr == facenr ) { - ps->mask |= mask; - return; - } - last= ps; - ps= ps->next; - } - } - - /* make new PS (pixel struct) */ - psm= lb->last; - - if (psm->counter==4095) - psm= addpsmain(lb); - - ps= psm->ps + psm->counter++; - - if (last) last->next= ps; - else *rd= (intptr_t)ps; - - ps->next= NULL; - ps->obi= obi; - ps->facenr= facenr; - ps->z= z; - ps->maskz= maskz; - ps->mask = mask; - ps->shadfac= 0; -} - -static void edge_enhance_add(RenderPart *pa, float *rectf, float *arect) -{ - float addcol[4]; - int pix; - - if (arect==NULL) - return; - - for (pix= pa->rectx*pa->recty; pix>0; pix--, arect++, rectf+=4) { - if (*arect != 0.0f) { - addcol[0]= *arect * R.r.edgeR; - addcol[1]= *arect * R.r.edgeG; - addcol[2]= *arect * R.r.edgeB; - addcol[3]= *arect; - addAlphaOverFloat(rectf, addcol); - } - } -} - -/* clamp alpha and RGB to 0..1 and 0..inf, can go outside due to filter */ -static void clamp_alpha_rgb_range(RenderPart *pa, RenderLayer *rl) -{ - RenderLayer *rlpp[RE_MAX_OSA]; - int y, sample, totsample; - - totsample= get_sample_layers(pa, rl, rlpp); - - /* not for full sample, there we clamp after compositing */ - if (totsample > 1) - return; - - for (sample= 0; sample<totsample; sample++) { - float *rectf = RE_RenderLayerGetPass(rlpp[sample], RE_PASSNAME_COMBINED, R.viewname); - - for (y= pa->rectx*pa->recty; y>0; y--, rectf+=4) { - rectf[0] = MAX2(rectf[0], 0.0f); - rectf[1] = MAX2(rectf[1], 0.0f); - rectf[2] = MAX2(rectf[2], 0.0f); - CLAMP(rectf[3], 0.0f, 1.0f); - } - } -} - -/* adds only alpha values */ -static void edge_enhance_tile(RenderPart *pa, float *rectf, int *rectz) -{ - /* use zbuffer to define edges, add it to the image */ - int y, x, col, *rz, *rz1, *rz2, *rz3; - int zval1, zval2, zval3; - float *rf; - - /* shift values in zbuffer 4 to the right (anti overflows), for filter we need multiplying with 12 max */ - rz= rectz; - if (rz==NULL) return; - - for (y=0; y<pa->recty; y++) - for (x=0; x<pa->rectx; x++, rz++) (*rz)>>= 4; - - rz1= rectz; - rz2= rz1+pa->rectx; - rz3= rz2+pa->rectx; - - rf= rectf+pa->rectx+1; - - for (y=0; y<pa->recty-2; y++) { - for (x=0; x<pa->rectx-2; x++, rz1++, rz2++, rz3++, rf++) { - - /* prevent overflow with sky z values */ - zval1= rz1[0] + 2*rz1[1] + rz1[2]; - zval2= 2*rz2[0] + 2*rz2[2]; - zval3= rz3[0] + 2*rz3[1] + rz3[2]; - - col= ( 4*rz2[1] - (zval1 + zval2 + zval3)/3 ); - if (col<0) col= -col; - - col >>= 5; - if (col > (1<<16)) col= (1<<16); - else col= (R.r.edgeint*col)>>8; - - if (col>0) { - float fcol; - - if (col>255) fcol= 1.0f; - else fcol= (float)col/255.0f; - - if (R.osa) - *rf+= fcol/(float)R.osa; - else - *rf= fcol; - } - } - rz1+= 2; - rz2+= 2; - rz3+= 2; - rf+= 2; - } - - /* shift back zbuf values, we might need it still */ - rz= rectz; - for (y=0; y<pa->recty; y++) - for (x=0; x<pa->rectx; x++, rz++) (*rz)<<= 4; - -} - -static void reset_sky_speed(RenderPart *pa, RenderLayer *rl) -{ - /* for all pixels with max speed, set to zero */ - RenderLayer *rlpp[RE_MAX_OSA]; - float *fp; - int a, sample, totsample; - - totsample= get_sample_layers(pa, rl, rlpp); - - for (sample= 0; sample<totsample; sample++) { - fp= RE_RenderLayerGetPass(rlpp[sample], RE_PASSNAME_VECTOR, R.viewname); - if (fp==NULL) break; - - for (a= 4*pa->rectx*pa->recty - 1; a>=0; a--) - if (fp[a] == PASS_VECTOR_MAX) fp[a]= 0.0f; - } -} - -static unsigned short *make_solid_mask(RenderPart *pa) -{ - intptr_t *rd= pa->rectdaps; - unsigned short *solidmask, *sp; - int x; - - if (rd==NULL) return NULL; - - sp=solidmask= MEM_mallocN(sizeof(short)*pa->rectx*pa->recty, "solidmask"); - - for (x=pa->rectx*pa->recty; x>0; x--, rd++, sp++) { - if (*rd) { - PixStr *ps= (PixStr *)*rd; - - *sp= ps->mask; - for (ps= ps->next; ps; ps= ps->next) - *sp |= ps->mask; - } - else - *sp= 0; - } - - return solidmask; -} - -static void addAlphaOverFloatMask(float *dest, float *source, unsigned short dmask, unsigned short smask) -{ - unsigned short shared= dmask & smask; - float mul= 1.0f - source[3]; - - if (shared) { /* overlapping masks */ - - /* masks differ, we make a mixture of 'add' and 'over' */ - if (shared!=dmask) { - float shared_bits= (float)count_mask(shared); /* alpha over */ - float tot_bits= (float)count_mask(smask|dmask); /* alpha add */ - - float add= (tot_bits - shared_bits)/tot_bits; /* add level */ - mul= add + (1.0f-add)*mul; - } - } - else if (dmask && smask) { - /* works for premul only, of course */ - dest[0]+= source[0]; - dest[1]+= source[1]; - dest[2]+= source[2]; - dest[3]+= source[3]; - - return; - } - - dest[0]= (mul*dest[0]) + source[0]; - dest[1]= (mul*dest[1]) + source[1]; - dest[2]= (mul*dest[2]) + source[2]; - dest[3]= (mul*dest[3]) + source[3]; -} - -typedef struct ZbufSolidData { - RenderLayer *rl; - ListBase *psmlist; - float *edgerect; -} ZbufSolidData; - -static void make_pixelstructs(RenderPart *pa, ZSpan *zspan, int sample, void *data) -{ - ZbufSolidData *sdata = (ZbufSolidData *)data; - ListBase *lb= sdata->psmlist; - intptr_t *rd= pa->rectdaps; - const int *ro= zspan->recto; - const int *rp= zspan->rectp; - const int *rz= zspan->rectz; - const int *rm= zspan->rectmask; - int x, y; - int mask= 1<<sample; - - for (y=0; y<pa->recty; y++) { - for (x=0; x<pa->rectx; x++, rd++, rp++, ro++, rz++, rm++) { - if (*rp) { - addps(lb, rd, *ro, *rp, *rz, (zspan->rectmask)? *rm: 0, mask); - } - } - } - - if (sdata->rl->layflag & SCE_LAY_EDGE) - if (R.r.mode & R_EDGE) - edge_enhance_tile(pa, sdata->edgerect, zspan->rectz); -} - -/* main call for shading Delta Accum, for OSA */ -/* supposed to be fully threadable! */ -void zbufshadeDA_tile(RenderPart *pa) -{ - RenderResult *rr= pa->result; - RenderLayer *rl; - ListBase psmlist= {NULL, NULL}; - float *edgerect= NULL; - - /* allocate the necessary buffers */ - /* zbuffer inits these rects */ - pa->recto= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "recto"); - pa->rectp= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectp"); - pa->rectz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectz"); - for (rl= rr->layers.first; rl; rl= rl->next) { - float *rect = RE_RenderLayerGetPass(rl, RE_PASSNAME_COMBINED, R.viewname); - - if ((rl->layflag & SCE_LAY_ZMASK) && (rl->layflag & SCE_LAY_NEG_ZMASK)) - pa->rectmask= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectmask"); - - /* initialize pixelstructs and edge buffer */ - addpsmain(&psmlist); - pa->rectdaps= MEM_callocN(sizeof(intptr_t)*pa->rectx*pa->recty+4, "zbufDArectd"); - - if (rl->layflag & SCE_LAY_EDGE) - if (R.r.mode & R_EDGE) - edgerect= MEM_callocN(sizeof(float)*pa->rectx*pa->recty, "rectedge"); - - /* always fill visibility */ - for (pa->sample=0; pa->sample<R.osa; pa->sample+=4) { - ZbufSolidData sdata; - - sdata.rl= rl; - sdata.psmlist= &psmlist; - sdata.edgerect= edgerect; - zbuffer_solid(pa, rl, make_pixelstructs, &sdata); - if (R.test_break(R.tbh)) break; - } - - /* shades solid */ - if (rl->layflag & SCE_LAY_SOLID) - shadeDA_tile(pa, rl); - - /* lamphalo after solid, before ztra, looks nicest because ztra does own halo */ - if (R.flag & R_LAMPHALO) - if (rl->layflag & SCE_LAY_HALO) - lamphalo_tile(pa, rl); - - /* halo before ztra, because ztra fills in zbuffer now */ - if (R.flag & R_HALO) - if (rl->layflag & SCE_LAY_HALO) - halo_tile(pa, rl); - - /* transp layer */ - if (R.flag & R_ZTRA || R.totstrand) { - if (rl->layflag & (SCE_LAY_ZTRA|SCE_LAY_STRAND)) { - if (pa->fullresult.first) { - zbuffer_transp_shade(pa, rl, rect, &psmlist); - } - else { - unsigned short *ztramask, *solidmask= NULL; /* 16 bits, MAX_OSA */ - - /* allocate, but not free here, for asynchronous display of this rect in main thread */ - rl->acolrect= MEM_callocN(4*sizeof(float)*pa->rectx*pa->recty, "alpha layer"); - - /* swap for live updates, and it is used in zbuf.c!!! */ - SWAP(float *, rl->acolrect, rect); - ztramask = zbuffer_transp_shade(pa, rl, rect, &psmlist); - SWAP(float *, rl->acolrect, rect); - - /* zbuffer transp only returns ztramask if there's solid rendered */ - if (ztramask) - solidmask= make_solid_mask(pa); - - if (ztramask && solidmask) { - unsigned short *sps= solidmask, *spz= ztramask; - unsigned short fullmask= (1<<R.osa)-1; - float *fcol= rect; - float *acol= rl->acolrect; - int x; - - for (x=pa->rectx*pa->recty; x>0; x--, acol+=4, fcol+=4, sps++, spz++) { - if (*sps == fullmask) - addAlphaOverFloat(fcol, acol); - else - addAlphaOverFloatMask(fcol, acol, *sps, *spz); - } - } - else { - float *fcol= rect; - float *acol= rl->acolrect; - int x; - for (x=pa->rectx*pa->recty; x>0; x--, acol+=4, fcol+=4) { - addAlphaOverFloat(fcol, acol); - } - } - if (solidmask) MEM_freeN(solidmask); - if (ztramask) MEM_freeN(ztramask); - } - } - } - - /* sun/sky */ - if (rl->layflag & SCE_LAY_SKY) - atm_tile(pa, rl); - - /* sky before edge */ - if (rl->layflag & SCE_LAY_SKY) - sky_tile(pa, rl); - - /* extra layers */ - if (rl->layflag & SCE_LAY_EDGE) - if (R.r.mode & R_EDGE) - edge_enhance_add(pa, rect, edgerect); - - if (rl->passflag & SCE_PASS_VECTOR) - reset_sky_speed(pa, rl); - - /* clamp alpha to 0..1 range, can go outside due to filter */ - clamp_alpha_rgb_range(pa, rl); - - /* free stuff within loop! */ - MEM_freeN(pa->rectdaps); pa->rectdaps= NULL; - freeps(&psmlist); - - if (edgerect) MEM_freeN(edgerect); - edgerect= NULL; - - if (pa->rectmask) { - MEM_freeN(pa->rectmask); - pa->rectmask= NULL; - } - } - - /* free all */ - MEM_freeN(pa->recto); pa->recto= NULL; - MEM_freeN(pa->rectp); pa->rectp= NULL; - MEM_freeN(pa->rectz); pa->rectz= NULL; - - /* display active layer */ - rr->renrect.ymin=rr->renrect.ymax = 0; - rr->renlay= render_get_active_layer(&R, rr); -} - - -/* ------------------------------------------------------------------------ */ - -/* non OSA case, full tile render */ -/* supposed to be fully threadable! */ -void zbufshade_tile(RenderPart *pa) -{ - ShadeSample ssamp; - RenderResult *rr= pa->result; - RenderLayer *rl; - PixStr ps; - float *edgerect= NULL; - - /* fake pixel struct, to comply to osa render */ - ps.next= NULL; - ps.mask= 0xFFFF; - - /* zbuffer code clears/inits rects */ - pa->recto= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "recto"); - pa->rectp= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectp"); - pa->rectz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectz"); - - for (rl= rr->layers.first; rl; rl= rl->next) { - float *rect= RE_RenderLayerGetPass(rl, RE_PASSNAME_COMBINED, R.viewname); - if ((rl->layflag & SCE_LAY_ZMASK) && (rl->layflag & SCE_LAY_NEG_ZMASK)) - pa->rectmask= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectmask"); - - /* general shader info, passes */ - shade_sample_initialize(&ssamp, pa, rl); - - zbuffer_solid(pa, rl, NULL, NULL); - - if (!R.test_break(R.tbh)) { /* NOTE: this if () is not consistent */ - - /* edges only for solid part, ztransp doesn't support it yet anti-aliased */ - if (rl->layflag & SCE_LAY_EDGE) { - if (R.r.mode & R_EDGE) { - edgerect= MEM_callocN(sizeof(float)*pa->rectx*pa->recty, "rectedge"); - edge_enhance_tile(pa, edgerect, pa->rectz); - } - } - - /* initialize scanline updates for main thread */ - rr->renrect.ymin = 0; - rr->renlay= rl; - - if (rl->layflag & SCE_LAY_SOLID) { - const float *fcol = rect; - const int *ro= pa->recto, *rp= pa->rectp, *rz= pa->rectz; - int x, y, offs=0, seed; - - /* we set per pixel a fixed seed, for random AO and shadow samples */ - seed= pa->rectx*pa->disprect.ymin; - - /* irregular shadowb buffer creation */ - if (R.r.mode & R_SHADOW) - ISB_create(pa, NULL); - - if (R.occlusiontree) - cache_occ_samples(&R, pa, &ssamp); - - for (y=pa->disprect.ymin; y<pa->disprect.ymax; y++, rr->renrect.ymax++) { - for (x=pa->disprect.xmin; x<pa->disprect.xmax; x++, ro++, rz++, rp++, fcol+=4, offs++) { - /* per pixel fixed seed */ - BLI_thread_srandom(pa->thread, seed++); - - if (*rp) { - ps.obi= *ro; - ps.facenr= *rp; - ps.z= *rz; - if (shade_samples(&ssamp, &ps, x, y)) { - /* combined and passes */ - add_passes(rl, offs, ssamp.shi, ssamp.shr); - } - } - } - if (y&1) - if (R.test_break(R.tbh)) break; - } - - if (R.occlusiontree) - free_occ_samples(&R, pa); - - if (R.r.mode & R_SHADOW) - ISB_free(pa); - } - - /* disable scanline updating */ - rr->renlay= NULL; - } - - /* lamphalo after solid, before ztra, looks nicest because ztra does own halo */ - if (R.flag & R_LAMPHALO) - if (rl->layflag & SCE_LAY_HALO) - lamphalo_tile(pa, rl); - - /* halo before ztra, because ztra fills in zbuffer now */ - if (R.flag & R_HALO) - if (rl->layflag & SCE_LAY_HALO) - halo_tile(pa, rl); - - if (R.flag & R_ZTRA || R.totstrand) { - if (rl->layflag & (SCE_LAY_ZTRA|SCE_LAY_STRAND)) { - float *fcol, *acol; - int x; - - /* allocate, but not free here, for asynchronous display of this rect in main thread */ - rl->acolrect= MEM_callocN(4*sizeof(float)*pa->rectx*pa->recty, "alpha layer"); - - /* swap for live updates */ - SWAP(float *, rl->acolrect, rect); - zbuffer_transp_shade(pa, rl, rect, NULL); - SWAP(float *, rl->acolrect, rect); - - fcol= rect; acol= rl->acolrect; - for (x=pa->rectx*pa->recty; x>0; x--, acol+=4, fcol+=4) { - addAlphaOverFloat(fcol, acol); - } - } - } - - /* sun/sky */ - if (rl->layflag & SCE_LAY_SKY) - atm_tile(pa, rl); - - /* sky before edge */ - if (rl->layflag & SCE_LAY_SKY) - sky_tile(pa, rl); - - if (!R.test_break(R.tbh)) { - if (rl->layflag & SCE_LAY_EDGE) - if (R.r.mode & R_EDGE) - edge_enhance_add(pa, rect, edgerect); - } - - if (rl->passflag & SCE_PASS_VECTOR) - reset_sky_speed(pa, rl); - - if (edgerect) MEM_freeN(edgerect); - edgerect= NULL; - - if (pa->rectmask) { - MEM_freeN(pa->rectmask); - pa->rectmask= NULL; - } - } - - /* display active layer */ - rr->renrect.ymin=rr->renrect.ymax = 0; - rr->renlay= render_get_active_layer(&R, rr); - - MEM_freeN(pa->recto); pa->recto= NULL; - MEM_freeN(pa->rectp); pa->rectp= NULL; - MEM_freeN(pa->rectz); pa->rectz= NULL; -} - -/* SSS preprocess tile render, fully threadable */ -typedef struct ZBufSSSHandle { - RenderPart *pa; - ListBase psmlist; - int totps; -} ZBufSSSHandle; - -static void addps_sss(void *cb_handle, int obi, int facenr, int x, int y, int z) -{ - ZBufSSSHandle *handle = cb_handle; - RenderPart *pa= handle->pa; - - /* extra border for filter gives double samples on part edges, - * don't use those */ - if (x<pa->crop || x>=pa->rectx-pa->crop) - return; - if (y<pa->crop || y>=pa->recty-pa->crop) - return; - - if (pa->rectall) { - intptr_t *rs= pa->rectall + pa->rectx*y + x; - - addps(&handle->psmlist, rs, obi, facenr, z, 0, 0); - handle->totps++; - } - if (pa->rectz) { - int *rz= pa->rectz + pa->rectx*y + x; - int *rp= pa->rectp + pa->rectx*y + x; - int *ro= pa->recto + pa->rectx*y + x; - - if (z < *rz) { - if (*rp == 0) - handle->totps++; - *rz= z; - *rp= facenr; - *ro= obi; - } - } - if (pa->rectbackz) { - int *rz= pa->rectbackz + pa->rectx*y + x; - int *rp= pa->rectbackp + pa->rectx*y + x; - int *ro= pa->rectbacko + pa->rectx*y + x; - - if (z >= *rz) { - if (*rp == 0) - handle->totps++; - *rz= z; - *rp= facenr; - *ro= obi; - } - } -} - -static void shade_sample_sss(ShadeSample *ssamp, Material *mat, ObjectInstanceRen *obi, VlakRen *vlr, int quad, float x, float y, float z, float *co, float color[3], float *area) -{ - ShadeInput *shi= ssamp->shi; - ShadeResult shr; - float /* texfac,*/ /* UNUSED */ orthoarea, nor[3], alpha, sx, sy; - - /* cache for shadow */ - shi->samplenr= R.shadowsamplenr[shi->thread]++; - - if (quad) - shade_input_set_triangle_i(shi, obi, vlr, 0, 2, 3); - else - shade_input_set_triangle_i(shi, obi, vlr, 0, 1, 2); - - /* center pixel */ - sx = x + 0.5f; - sy = y + 0.5f; - - /* we estimate the area here using shi->dxco and shi->dyco. we need to - * enabled shi->osatex these are filled. we compute two areas, one with - * the normal pointed at the camera and one with the original normal, and - * then clamp to avoid a too large contribution from a single pixel */ - shi->osatex= 1; - - copy_v3_v3(nor, shi->facenor); - calc_view_vector(shi->facenor, sx, sy); - normalize_v3(shi->facenor); - shade_input_set_viewco(shi, x, y, sx, sy, z); - orthoarea= len_v3(shi->dxco)*len_v3(shi->dyco); - - copy_v3_v3(shi->facenor, nor); - shade_input_set_viewco(shi, x, y, sx, sy, z); - *area = min_ff(len_v3(shi->dxco) * len_v3(shi->dyco), 2.0f * orthoarea); - - shade_input_set_uv(shi); - shade_input_set_normals(shi); - - /* we don't want flipped normals, they screw up back scattering */ - if (shi->flippednor) - shade_input_flip_normals(shi); - - /* not a pretty solution, but fixes common cases */ - if (shi->obr->ob && shi->obr->ob->transflag & OB_NEG_SCALE) { - negate_v3(shi->vn); - negate_v3(shi->vno); - negate_v3(shi->nmapnorm); - } - - /* if nodetree, use the material that we are currently preprocessing - * instead of the node material */ - if (shi->mat->nodetree && shi->mat->use_nodes) - shi->mat= mat; - - /* init material vars */ - shade_input_init_material(shi); - - /* render */ - shade_input_set_shade_texco(shi); - - shade_samples_do_AO(ssamp); - shade_material_loop(shi, &shr); - - copy_v3_v3(co, shi->co); - copy_v3_v3(color, shr.combined); - - /* texture blending */ - /* texfac= shi->mat->sss_texfac; */ /* UNUSED */ - - alpha= shr.combined[3]; - *area *= alpha; -} - -static void zbufshade_sss_free(RenderPart *pa) -{ -#if 0 - MEM_freeN(pa->rectall); pa->rectall= NULL; - freeps(&handle.psmlist); -#else - MEM_freeN(pa->rectz); pa->rectz= NULL; - MEM_freeN(pa->rectp); pa->rectp= NULL; - MEM_freeN(pa->recto); pa->recto= NULL; - MEM_freeN(pa->rectbackz); pa->rectbackz= NULL; - MEM_freeN(pa->rectbackp); pa->rectbackp= NULL; - MEM_freeN(pa->rectbacko); pa->rectbacko= NULL; -#endif -} - -void zbufshade_sss_tile(RenderPart *pa) -{ - Render *re= &R; - ShadeSample ssamp; - ZBufSSSHandle handle; - RenderResult *rr= pa->result; - RenderLayer *rl; - VlakRen *vlr; - Material *mat= re->sss_mat; - float (*co)[3], (*color)[3], *area, *fcol; - int x, y, seed, quad, totpoint; - const bool display = (re->r.scemode & (R_BUTS_PREVIEW | R_VIEWPORT_PREVIEW)) == 0; - int *ro, *rz, *rp, *rbo, *rbz, *rbp, lay; -#if 0 - PixStr *ps; - intptr_t *rs; - int z; -#endif - - /* setup pixelstr list and buffer for zbuffering */ - handle.pa= pa; - handle.totps= 0; - -#if 0 - handle.psmlist.first= handle.psmlist.last= NULL; - addpsmain(&handle.psmlist); - - pa->rectall= MEM_callocN(sizeof(intptr_t)*pa->rectx*pa->recty+4, "rectall"); -#else - pa->recto= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "recto"); - pa->rectp= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectp"); - pa->rectz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectz"); - pa->rectbacko= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectbacko"); - pa->rectbackp= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectbackp"); - pa->rectbackz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectbackz"); -#endif - - /* setup shade sample with correct passes */ - memset(&ssamp, 0, sizeof(ssamp)); - shade_sample_initialize(&ssamp, pa, rr->layers.first); - ssamp.tot= 1; - - for (rl=rr->layers.first; rl; rl=rl->next) { - ssamp.shi[0].lay |= (1 << 20) - 1; - ssamp.shi[0].layflag |= rl->layflag; - ssamp.shi[0].passflag |= rl->passflag; - ssamp.shi[0].combinedflag |= ~rl->pass_xor; - } - - rl= rr->layers.first; - ssamp.shi[0].passflag |= SCE_PASS_RGBA|SCE_PASS_COMBINED; - ssamp.shi[0].combinedflag &= ~(SCE_PASS_SPEC); - lay= ssamp.shi[0].lay; - - /* create the pixelstrs to be used later */ - zbuffer_sss(pa, lay, &handle, addps_sss); - - if (handle.totps==0) { - zbufshade_sss_free(pa); - return; - } - - fcol= RE_RenderLayerGetPass(rl, RE_PASSNAME_COMBINED, R.viewname); - - co= MEM_mallocN(sizeof(float)*3*handle.totps, "SSSCo"); - color= MEM_mallocN(sizeof(float)*3*handle.totps, "SSSColor"); - area= MEM_mallocN(sizeof(float)*handle.totps, "SSSArea"); - -#if 0 - /* create ISB (does not work currently!) */ - if (re->r.mode & R_SHADOW) - ISB_create(pa, NULL); -#endif - - if (display) { - /* initialize scanline updates for main thread */ - rr->renrect.ymin = 0; - rr->renlay= rl; - } - - seed= pa->rectx*pa->disprect.ymin; -#if 0 - rs= pa->rectall; -#else - rz= pa->rectz; - rp= pa->rectp; - ro= pa->recto; - rbz= pa->rectbackz; - rbp= pa->rectbackp; - rbo= pa->rectbacko; -#endif - totpoint= 0; - - for (y=pa->disprect.ymin; y<pa->disprect.ymax; y++, rr->renrect.ymax++) { - for (x=pa->disprect.xmin; x<pa->disprect.xmax; x++, fcol+=4) { - /* per pixel fixed seed */ - BLI_thread_srandom(pa->thread, seed++); - -#if 0 - if (rs) { - /* for each sample in this pixel, shade it */ - for (ps = (PixStr *)(*rs); ps; ps=ps->next) { - ObjectInstanceRen *obi= &re->objectinstance[ps->obi]; - ObjectRen *obr= obi->obr; - vlr= RE_findOrAddVlak(obr, (ps->facenr-1) & RE_QUAD_MASK); - quad= (ps->facenr & RE_QUAD_OFFS); - z= ps->z; - - shade_sample_sss(&ssamp, mat, obi, vlr, quad, x, y, z, - co[totpoint], color[totpoint], &area[totpoint]); - - totpoint++; - - add_v3_v3(fcol, color); - fcol[3]= 1.0f; - } - - rs++; - } -#else - if (rp) { - if (*rp != 0) { - ObjectInstanceRen *obi= &re->objectinstance[*ro]; - ObjectRen *obr= obi->obr; - - /* shade front */ - vlr= RE_findOrAddVlak(obr, (*rp-1) & RE_QUAD_MASK); - quad= ((*rp) & RE_QUAD_OFFS); - - shade_sample_sss(&ssamp, mat, obi, vlr, quad, x, y, *rz, - co[totpoint], color[totpoint], &area[totpoint]); - - add_v3_v3(fcol, color[totpoint]); - fcol[3]= 1.0f; - totpoint++; - } - - rp++; rz++; ro++; - } - - if (rbp) { - if (*rbp != 0 && !(*rbp == *(rp-1) && *rbo == *(ro-1))) { - ObjectInstanceRen *obi= &re->objectinstance[*rbo]; - ObjectRen *obr= obi->obr; - - /* shade back */ - vlr= RE_findOrAddVlak(obr, (*rbp-1) & RE_QUAD_MASK); - quad= ((*rbp) & RE_QUAD_OFFS); - - shade_sample_sss(&ssamp, mat, obi, vlr, quad, x, y, *rbz, - co[totpoint], color[totpoint], &area[totpoint]); - - /* to indicate this is a back sample */ - area[totpoint]= -area[totpoint]; - - add_v3_v3(fcol, color[totpoint]); - fcol[3]= 1.0f; - totpoint++; - } - - rbz++; rbp++; rbo++; - } -#endif - } - - if (y&1) - if (re->test_break(re->tbh)) break; - } - - /* note: after adding we do not free these arrays, sss keeps them */ - if (totpoint > 0) { - sss_add_points(re, co, color, area, totpoint); - } - else { - MEM_freeN(co); - MEM_freeN(color); - MEM_freeN(area); - } - -#if 0 - if (re->r.mode & R_SHADOW) - ISB_free(pa); -#endif - - if (display) { - /* display active layer */ - rr->renrect.ymin=rr->renrect.ymax = 0; - rr->renlay= render_get_active_layer(&R, rr); - } - - zbufshade_sss_free(pa); -} - -/* ------------------------------------------------------------------------ */ - -static void renderhalo_post(RenderResult *rr, float *rectf, HaloRen *har) /* postprocess version */ -{ - float dist, xsq, ysq, xn, yn, colf[4], *rectft, *rtf; - float haloxs, haloys; - int minx, maxx, miny, maxy, x, y; - - /* calculate the disprect mapped coordinate for halo. note: rectx is disprect corrected */ - haloxs= har->xs - R.disprect.xmin; - haloys= har->ys - R.disprect.ymin; - - har->miny= miny= haloys - har->rad/R.ycor; - har->maxy= maxy= haloys + har->rad/R.ycor; - - if (maxy < 0) { - /* pass */ - } - else if (rr->recty < miny) { - /* pass */ - } - else { - minx = floor(haloxs - har->rad); - maxx = ceil(haloxs + har->rad); - - if (maxx < 0) { - /* pass */ - } - else if (rr->rectx < minx) { - /* pass */ - } - else { - if (minx<0) minx= 0; - if (maxx>=rr->rectx) maxx= rr->rectx-1; - if (miny<0) miny= 0; - if (maxy>rr->recty) maxy= rr->recty; - - rectft= rectf+ 4*rr->rectx*miny; - - for (y=miny; y<maxy; y++) { - - rtf= rectft+4*minx; - - yn= (y - haloys)*R.ycor; - ysq= yn*yn; - - for (x=minx; x<=maxx; x++) { - xn= x - haloxs; - xsq= xn*xn; - dist= xsq+ysq; - if (dist<har->radsq) { - - if (shadeHaloFloat(har, colf, 0x7FFFFF, dist, xn, yn, har->flarec)) - addalphaAddfacFloat(rtf, colf, har->add); - } - rtf+=4; - } - - rectft+= 4*rr->rectx; - - if (R.test_break(R.tbh)) break; - } - } - } -} -/* ------------------------------------------------------------------------ */ - -static void renderflare(RenderResult *rr, float *rectf, HaloRen *har) -{ - extern const float hashvectf[]; - HaloRen fla; - Material *ma; - const float *rc; - float rad, alfa, visifac, vec[3]; - int b, type; - - fla= *har; - fla.linec= fla.ringc= fla.flarec= 0; - - rad= har->rad; - alfa= har->alfa; - - visifac= R.ycor*(har->pixels); - /* all radials added / r^3 == 1.0f! */ - visifac /= (har->rad*har->rad*har->rad); - visifac*= visifac; - - ma= har->mat; - - /* first halo: just do */ - - har->rad= rad*ma->flaresize*visifac; - har->radsq= har->rad*har->rad; - har->zs= fla.zs= 0; - - har->alfa= alfa*visifac; - - renderhalo_post(rr, rectf, har); - - /* next halo's: the flares */ - rc= hashvectf + ma->seed2; - - for (b=1; b<har->flarec; b++) { - - fla.r = fabsf(rc[0]); - fla.g = fabsf(rc[1]); - fla.b = fabsf(rc[2]); - fla.alfa= ma->flareboost*fabsf(alfa*visifac*rc[3]); - fla.hard= 20.0f + fabsf(70.0f*rc[7]); - fla.tex= 0; - - type= (int)(fabsf(3.9f*rc[6])); - - fla.rad = ma->subsize * sqrtf(fabsf(2.0f * har->rad * rc[4])); - - if (type==3) { - fla.rad*= 3.0f; - fla.rad+= R.rectx/10; - } - - fla.radsq= fla.rad*fla.rad; - - vec[0]= 1.4f*rc[5]*(har->xs-R.winx/2); - vec[1]= 1.4f*rc[5]*(har->ys-R.winy/2); - vec[2]= 32.0f*sqrtf(vec[0]*vec[0] + vec[1]*vec[1] + 1.0f); - - fla.xs= R.winx/2 + vec[0] + (1.2f+rc[8])*R.rectx*vec[0]/vec[2]; - fla.ys= R.winy/2 + vec[1] + (1.2f+rc[8])*R.rectx*vec[1]/vec[2]; - - if (R.flag & R_SEC_FIELD) { - if (R.r.mode & R_ODDFIELD) fla.ys += 0.5f; - else fla.ys -= 0.5f; - } - if (type & 1) fla.type= HA_FLARECIRC; - else fla.type= 0; - renderhalo_post(rr, rectf, &fla); - - fla.alfa*= 0.5f; - if (type & 2) fla.type= HA_FLARECIRC; - else fla.type= 0; - renderhalo_post(rr, rectf, &fla); - - rc+= 7; - } -} - -/* needs recode... integrate this better! */ -void add_halo_flare(Render *re) -{ - RenderResult *rr= re->result; - RenderLayer *rl; - HaloRen *har; - int a, mode; - float *rect; - - /* for now, we get the first renderlayer in list with halos set */ - for (rl= rr->layers.first; rl; rl= rl->next) { - bool do_draw = false; - - if ((rl->layflag & SCE_LAY_HALO) == 0) - continue; - - rect = RE_RenderLayerGetPass(rl, RE_PASSNAME_COMBINED, re->viewname); - - if (rect==NULL) - continue; - - mode= R.r.mode; - R.r.mode &= ~R_PANORAMA; - - project_renderdata(&R, projectverto, 0, 0, 0); - - for (a=0; a<R.tothalo; a++) { - har= R.sortedhalos[a]; - - if (har->flarec && (har->lay & ((1 << 20) - 1))) { - do_draw = true; - renderflare(rr, rect, har); - } - } - - if (do_draw) { - /* weak... the display callback wants an active renderlayer pointer... */ - rr->renlay= rl; - re->display_update(re->duh, rr, NULL); - } - - R.r.mode= mode; - } -} - -void render_internal_update_passes(RenderEngine *engine, Scene *scene, ViewLayer *view_layer) -{ - int type; - - RE_engine_register_pass(engine, scene, view_layer, RE_PASSNAME_COMBINED, 4, "RGBA", SOCK_RGBA); - -#define CHECK_PASS(name, channels, chanid) \ - if (view_layer->passflag & (SCE_PASS_ ## name)) { \ - if (channels == 4) type = SOCK_RGBA; \ - else if (channels == 3) type = SOCK_VECTOR; \ - else type = SOCK_FLOAT; \ - RE_engine_register_pass(engine, scene, view_layer, RE_PASSNAME_ ## name, channels, chanid, type); \ - } - - CHECK_PASS(Z, 1, "Z"); - CHECK_PASS(VECTOR, 4, "XYZW"); - CHECK_PASS(NORMAL, 3, "XYZ"); - CHECK_PASS(UV, 3, "UVA"); - CHECK_PASS(RGBA, 4, "RGBA"); - CHECK_PASS(EMIT, 3, "RGB"); - CHECK_PASS(DIFFUSE, 3, "RGB"); - CHECK_PASS(SPEC, 3, "RGB"); - CHECK_PASS(AO, 3, "RGB"); - CHECK_PASS(ENVIRONMENT, 3, "RGB"); - CHECK_PASS(INDIRECT, 3, "RGB"); - CHECK_PASS(SHADOW, 3, "RGB"); - CHECK_PASS(REFLECT, 3, "RGB"); - CHECK_PASS(REFRACT, 3, "RGB"); - CHECK_PASS(INDEXOB, 1, "X"); - CHECK_PASS(INDEXMA, 1, "X"); - CHECK_PASS(MIST, 1, "Z"); - -#undef CHECK_PASS -} diff --git a/source/blender/render/intern/source/renderdatabase.c b/source/blender/render/intern/source/renderdatabase.c deleted file mode 100644 index 2fbfcc64c8f..00000000000 --- a/source/blender/render/intern/source/renderdatabase.c +++ /dev/null @@ -1,1603 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * Contributor(s): 2004-2006, Blender Foundation, full recode - * - * ***** END GPL/BL DUAL LICENSE BLOCK ***** - */ - -/** \file blender/render/intern/source/renderdatabase.c - * \ingroup render - */ - - -/* - * Storage, retrieval and query of render specific data. - * - * All data from a Blender scene is converted by the renderconverter/ - * into a special format that is used by the render module to make - * images out of. These functions interface to the render-specific - * database. - * - * The blo{ha/ve/vl} arrays store pointers to blocks of 256 data - * entries each. - * - * The index of an entry is >>8 (the highest 24 * bits), to find an - * offset in a 256-entry block. - * - * - If the 256-entry block entry has an entry in the - * vertnodes/vlaknodes/bloha array of the current block, the i-th entry in - * that block is allocated to this entry. - * - * - If the entry has no block allocated for it yet, memory is - * allocated. - * - * The pointer to the correct entry is returned. Memory is guaranteed - * to exist (as long as the malloc does not break). Since guarded - * allocation is used, memory _must_ be available. Otherwise, an - * exit(0) would occur. - * - */ - -#include <limits.h> -#include <math.h> -#include <string.h> - -#include "MEM_guardedalloc.h" - - -#include "BLI_math.h" -#include "BLI_blenlib.h" -#include "BLI_utildefines.h" -#include "BLI_hash.h" - -#include "DNA_material_types.h" -#include "DNA_meshdata_types.h" -#include "DNA_texture_types.h" -#include "DNA_listBase.h" -#include "DNA_particle_types.h" - -#include "BKE_customdata.h" -#include "BKE_DerivedMesh.h" - -#include "RE_render_ext.h" /* externtex */ - -#include "rayintersection.h" -#include "rayobject.h" -#include "render_types.h" -#include "renderdatabase.h" -#include "zbuf.h" - -/* ------------------------------------------------------------------------- */ - -/* More dynamic allocation of options for render vertices and faces, so we don't - * have to reserve this space inside vertices. - * Important; vertices and faces, should have been created already (to get tables - * checked) that's a reason why the calls demand VertRen/VlakRen * as arg, not - * the index */ - -/* NOTE! the hardcoded table size 256 is used still in code for going quickly over vertices/faces */ -#define RE_STRESS_ELEMS 1 -#define RE_RAD_ELEMS 4 -#define RE_STRAND_ELEMS 1 -#define RE_TANGENT_ELEMS 3 -#define RE_WINSPEED_ELEMS 4 -#define RE_MTFACE_ELEMS 1 -#define RE_MCOL_ELEMS 4 -#define RE_UV_ELEMS 2 -#define RE_VLAK_ORIGINDEX_ELEMS 1 -#define RE_VERT_ORIGINDEX_ELEMS 1 -#define RE_SURFNOR_ELEMS 3 -#define RE_RADFACE_ELEMS 1 -#define RE_SIMPLIFY_ELEMS 2 -#define RE_FACE_ELEMS 1 -#define RE_NMAP_TANGENT_ELEMS 16 - -float *RE_vertren_get_stress(ObjectRen *obr, VertRen *ver, int verify) -{ - float *stress; - int nr= ver->index>>8; - - stress= obr->vertnodes[nr].stress; - if (stress==NULL) { - if (verify) - stress= obr->vertnodes[nr].stress= MEM_mallocN(256*RE_STRESS_ELEMS*sizeof(float), "stress table"); - else - return NULL; - } - return stress + (ver->index & 255)*RE_STRESS_ELEMS; -} - -/* this one callocs! */ -float *RE_vertren_get_rad(ObjectRen *obr, VertRen *ver, int verify) -{ - float *rad; - int nr= ver->index>>8; - - rad= obr->vertnodes[nr].rad; - if (rad==NULL) { - if (verify) - rad= obr->vertnodes[nr].rad= MEM_callocN(256*RE_RAD_ELEMS*sizeof(float), "rad table"); - else - return NULL; - } - return rad + (ver->index & 255)*RE_RAD_ELEMS; -} - -float *RE_vertren_get_strand(ObjectRen *obr, VertRen *ver, int verify) -{ - float *strand; - int nr= ver->index>>8; - - strand= obr->vertnodes[nr].strand; - if (strand==NULL) { - if (verify) - strand= obr->vertnodes[nr].strand= MEM_mallocN(256*RE_STRAND_ELEMS*sizeof(float), "strand table"); - else - return NULL; - } - return strand + (ver->index & 255)*RE_STRAND_ELEMS; -} - -/* needs calloc */ -float *RE_vertren_get_tangent(ObjectRen *obr, VertRen *ver, int verify) -{ - float *tangent; - int nr= ver->index>>8; - - tangent= obr->vertnodes[nr].tangent; - if (tangent==NULL) { - if (verify) - tangent= obr->vertnodes[nr].tangent= MEM_callocN(256*RE_TANGENT_ELEMS*sizeof(float), "tangent table"); - else - return NULL; - } - return tangent + (ver->index & 255)*RE_TANGENT_ELEMS; -} - -/* needs calloc! not all renderverts have them */ -/* also winspeed is exception, it is stored per instance */ -float *RE_vertren_get_winspeed(ObjectInstanceRen *obi, VertRen *ver, int verify) -{ - float *winspeed; - int totvector; - - winspeed= obi->vectors; - if (winspeed==NULL) { - if (verify) { - totvector= obi->obr->totvert + obi->obr->totstrand; - winspeed= obi->vectors= MEM_callocN(totvector*RE_WINSPEED_ELEMS*sizeof(float), "winspeed table"); - } - else - return NULL; - } - return winspeed + ver->index*RE_WINSPEED_ELEMS; -} - -int *RE_vertren_get_origindex(ObjectRen *obr, VertRen *ver, int verify) -{ - int *origindex; - int nr= ver->index>>8; - - origindex= obr->vertnodes[nr].origindex; - if (origindex==NULL) { - if (verify) - origindex= obr->vertnodes[nr].origindex= MEM_mallocN(256*RE_VERT_ORIGINDEX_ELEMS*sizeof(int), "origindex table"); - else - return NULL; - } - return origindex + (ver->index & 255)*RE_VERT_ORIGINDEX_ELEMS; -} - -VertRen *RE_vertren_copy(ObjectRen *obr, VertRen *ver) -{ - VertRen *v1= RE_findOrAddVert(obr, obr->totvert++); - float *fp1, *fp2; - int *int1, *int2; - int index= v1->index; - - *v1= *ver; - v1->index= index; - - fp1= RE_vertren_get_stress(obr, ver, 0); - if (fp1) { - fp2= RE_vertren_get_stress(obr, v1, 1); - memcpy(fp2, fp1, RE_STRESS_ELEMS*sizeof(float)); - } - fp1= RE_vertren_get_rad(obr, ver, 0); - if (fp1) { - fp2= RE_vertren_get_rad(obr, v1, 1); - memcpy(fp2, fp1, RE_RAD_ELEMS*sizeof(float)); - } - fp1= RE_vertren_get_strand(obr, ver, 0); - if (fp1) { - fp2= RE_vertren_get_strand(obr, v1, 1); - memcpy(fp2, fp1, RE_STRAND_ELEMS*sizeof(float)); - } - fp1= RE_vertren_get_tangent(obr, ver, 0); - if (fp1) { - fp2= RE_vertren_get_tangent(obr, v1, 1); - memcpy(fp2, fp1, RE_TANGENT_ELEMS*sizeof(float)); - } - int1= RE_vertren_get_origindex(obr, ver, 0); - if (int1) { - int2= RE_vertren_get_origindex(obr, v1, 1); - memcpy(int2, int1, RE_VERT_ORIGINDEX_ELEMS*sizeof(int)); - } - return v1; -} - -VertRen *RE_findOrAddVert(ObjectRen *obr, int nr) -{ - VertTableNode *temp; - VertRen *v; - int a; - - if (nr<0) { - printf("error in findOrAddVert: %d\n", nr); - return NULL; - } - a= nr>>8; - - if (a>=obr->vertnodeslen-1) { /* Need to allocate more columns..., and keep last element NULL for free loop */ - temp= obr->vertnodes; - - obr->vertnodes= MEM_mallocN(sizeof(VertTableNode)*(obr->vertnodeslen+TABLEINITSIZE), "vertnodes"); - if (temp) memcpy(obr->vertnodes, temp, obr->vertnodeslen*sizeof(VertTableNode)); - memset(obr->vertnodes+obr->vertnodeslen, 0, TABLEINITSIZE*sizeof(VertTableNode)); - - obr->vertnodeslen+=TABLEINITSIZE; - if (temp) MEM_freeN(temp); - } - - v= obr->vertnodes[a].vert; - if (v==NULL) { - int i; - - v= (VertRen *)MEM_callocN(256*sizeof(VertRen), "findOrAddVert"); - obr->vertnodes[a].vert= v; - - for (i= (nr & 0xFFFFFF00), a=0; a<256; a++, i++) { - v[a].index= i; - } - } - v+= (nr & 255); - return v; -} - -/* ------------------------------------------------------------------------ */ - -MTFace *RE_vlakren_get_tface(ObjectRen *obr, VlakRen *vlr, int n, char **name, int verify) -{ - VlakTableNode *node; - int nr= vlr->index>>8, vlakindex= (vlr->index&255); - int index= (n<<8) + vlakindex; - - node= &obr->vlaknodes[nr]; - - if (verify) { - if (n>=node->totmtface) { - MTFace *mtface= node->mtface; - int size= (n+1)*256; - - node->mtface= MEM_callocN(size*sizeof(MTFace), "Vlak mtface"); - - if (mtface) { - size= node->totmtface*256; - memcpy(node->mtface, mtface, size*sizeof(MTFace)); - MEM_freeN(mtface); - } - - node->totmtface= n+1; - } - } - else { - if (n>=node->totmtface) - return NULL; - - if (name) *name= obr->mtface[n]; - } - - return node->mtface + index; -} - -MCol *RE_vlakren_get_mcol(ObjectRen *obr, VlakRen *vlr, int n, char **name, int verify) -{ - VlakTableNode *node; - int nr= vlr->index>>8, vlakindex= (vlr->index&255); - int index= (n<<8) + vlakindex; - - node= &obr->vlaknodes[nr]; - - if (verify) { - if (n>=node->totmcol) { - MCol *mcol= node->mcol; - int size= (n+1)*256; - - node->mcol= MEM_callocN(size*sizeof(MCol)*RE_MCOL_ELEMS, "Vlak mcol"); - - if (mcol) { - size= node->totmcol*256; - memcpy(node->mcol, mcol, size*sizeof(MCol)*RE_MCOL_ELEMS); - MEM_freeN(mcol); - } - - node->totmcol= n+1; - } - } - else { - if (n>=node->totmcol) - return NULL; - - if (name) *name= obr->mcol[n]; - } - - return node->mcol + index*RE_MCOL_ELEMS; -} - -int *RE_vlakren_get_origindex(ObjectRen *obr, VlakRen *vlak, int verify) -{ - int *origindex; - int nr= vlak->index>>8; - - origindex= obr->vlaknodes[nr].origindex; - if (origindex==NULL) { - if (verify) - origindex= obr->vlaknodes[nr].origindex= MEM_callocN(256*RE_VLAK_ORIGINDEX_ELEMS*sizeof(int), "origindex table"); - else - return NULL; - } - return origindex + (vlak->index & 255)*RE_VLAK_ORIGINDEX_ELEMS; -} - -float *RE_vlakren_get_surfnor(ObjectRen *obr, VlakRen *vlak, int verify) -{ - float *surfnor; - int nr= vlak->index>>8; - - surfnor= obr->vlaknodes[nr].surfnor; - if (surfnor==NULL) { - if (verify) - surfnor= obr->vlaknodes[nr].surfnor= MEM_callocN(256*RE_SURFNOR_ELEMS*sizeof(float), "surfnor table"); - else - return NULL; - } - return surfnor + (vlak->index & 255)*RE_SURFNOR_ELEMS; -} - -float *RE_vlakren_get_nmap_tangent(ObjectRen *obr, VlakRen *vlak, int index, bool verify) -{ - float **tangents; - int nr= vlak->index>>8; - - tangents = obr->vlaknodes[nr].tangent_arrays; - - if (index + 1 > 8) { - return NULL; - } - - index = index < 0 ? 0: index; - - if (tangents[index] == NULL) { - if (verify) { - tangents[index] = MEM_callocN(256*RE_NMAP_TANGENT_ELEMS*sizeof(float), "tangent table"); - } - else - return NULL; - } - - return tangents[index] + (vlak->index & 255)*RE_NMAP_TANGENT_ELEMS; -} - -RadFace **RE_vlakren_get_radface(ObjectRen *obr, VlakRen *vlak, int verify) -{ - RadFace **radface; - int nr= vlak->index>>8; - - radface= obr->vlaknodes[nr].radface; - if (radface==NULL) { - if (verify) - radface = obr->vlaknodes[nr].radface= MEM_callocN(256 * RE_RADFACE_ELEMS * sizeof(void *), "radface table"); - else - return NULL; - } - return radface + (vlak->index & 255)*RE_RADFACE_ELEMS; -} - -VlakRen *RE_vlakren_copy(ObjectRen *obr, VlakRen *vlr) -{ - VlakRen *vlr1 = RE_findOrAddVlak(obr, obr->totvlak++); - MTFace *mtface, *mtface1; - MCol *mcol, *mcol1; - float *surfnor, *surfnor1; - float *tangent, *tangent1; - int *origindex, *origindex1; - RadFace **radface, **radface1; - int i, index = vlr1->index; - char *name; - - *vlr1= *vlr; - vlr1->index= index; - - for (i=0; (mtface=RE_vlakren_get_tface(obr, vlr, i, &name, 0)) != NULL; i++) { - mtface1= RE_vlakren_get_tface(obr, vlr1, i, &name, 1); - memcpy(mtface1, mtface, sizeof(MTFace)*RE_MTFACE_ELEMS); - } - - for (i=0; (mcol=RE_vlakren_get_mcol(obr, vlr, i, &name, 0)) != NULL; i++) { - mcol1= RE_vlakren_get_mcol(obr, vlr1, i, &name, 1); - memcpy(mcol1, mcol, sizeof(MCol)*RE_MCOL_ELEMS); - } - - origindex= RE_vlakren_get_origindex(obr, vlr, 0); - if (origindex) { - origindex1= RE_vlakren_get_origindex(obr, vlr1, 1); - /* Just an int, but memcpy for consistency. */ - memcpy(origindex1, origindex, sizeof(int)*RE_VLAK_ORIGINDEX_ELEMS); - } - - surfnor= RE_vlakren_get_surfnor(obr, vlr, 0); - if (surfnor) { - surfnor1= RE_vlakren_get_surfnor(obr, vlr1, 1); - copy_v3_v3(surfnor1, surfnor); - } - - for (i=0; i < MAX_MTFACE; i++) { - tangent = RE_vlakren_get_nmap_tangent(obr, vlr, i, false); - if (!tangent) - continue; - tangent1 = RE_vlakren_get_nmap_tangent(obr, vlr1, i, true); - memcpy(tangent1, tangent, sizeof(float)*RE_NMAP_TANGENT_ELEMS); - } - - radface= RE_vlakren_get_radface(obr, vlr, 0); - if (radface) { - radface1= RE_vlakren_get_radface(obr, vlr1, 1); - *radface1= *radface; - } - - return vlr1; -} - -void RE_vlakren_get_normal(Render *UNUSED(re), ObjectInstanceRen *obi, VlakRen *vlr, float r_nor[3]) -{ - float (*nmat)[3]= obi->nmat; - - if (obi->flag & R_TRANSFORMED) { - mul_v3_m3v3(r_nor, nmat, vlr->n); - normalize_v3(r_nor); - } - else { - copy_v3_v3(r_nor, vlr->n); - } -} - -void RE_set_customdata_names(ObjectRen *obr, CustomData *data) -{ - /* CustomData layer names are stored per object here, because the - * DerivedMesh which stores the layers is freed */ - - CustomDataLayer *layer; - int numtf = 0, numcol = 0, i, mtfn, mcn; - - if (CustomData_has_layer(data, CD_MTFACE)) { - numtf= CustomData_number_of_layers(data, CD_MTFACE); - obr->mtface= MEM_callocN(sizeof(*obr->mtface)*numtf, "mtfacenames"); - } - - if (CustomData_has_layer(data, CD_MCOL)) { - numcol= CustomData_number_of_layers(data, CD_MCOL); - obr->mcol= MEM_callocN(sizeof(*obr->mcol)*numcol, "mcolnames"); - } - - for (i=0, mtfn=0, mcn=0; i < data->totlayer; i++) { - layer= &data->layers[i]; - - if (layer->type == CD_MTFACE) { - BLI_strncpy(obr->mtface[mtfn++], layer->name, sizeof(layer->name)); - obr->actmtface= CLAMPIS(layer->active_rnd, 0, numtf); - obr->bakemtface= layer->active; - } - else if (layer->type == CD_MCOL) { - BLI_strncpy(obr->mcol[mcn++], layer->name, sizeof(layer->name)); - obr->actmcol= CLAMPIS(layer->active_rnd, 0, numcol); - } - } -} - -VlakRen *RE_findOrAddVlak(ObjectRen *obr, int nr) -{ - VlakTableNode *temp; - VlakRen *v; - int a; - - if (nr<0) { - printf("error in findOrAddVlak: %d\n", nr); - return obr->vlaknodes[0].vlak; - } - a= nr>>8; - - if (a>=obr->vlaknodeslen-1) { /* Need to allocate more columns..., and keep last element NULL for free loop */ - temp= obr->vlaknodes; - - obr->vlaknodes= MEM_mallocN(sizeof(VlakTableNode)*(obr->vlaknodeslen+TABLEINITSIZE), "vlaknodes"); - if (temp) memcpy(obr->vlaknodes, temp, obr->vlaknodeslen*sizeof(VlakTableNode)); - memset(obr->vlaknodes+obr->vlaknodeslen, 0, TABLEINITSIZE*sizeof(VlakTableNode)); - - obr->vlaknodeslen+=TABLEINITSIZE; /*Does this really need to be power of 2?*/ - if (temp) MEM_freeN(temp); - } - - v= obr->vlaknodes[a].vlak; - - if (v==NULL) { - int i; - - v= (VlakRen *)MEM_callocN(256*sizeof(VlakRen), "findOrAddVlak"); - obr->vlaknodes[a].vlak= v; - - for (i= (nr & 0xFFFFFF00), a=0; a<256; a++, i++) - v[a].index= i; - } - v+= (nr & 255); - return v; -} - -/* ------------------------------------------------------------------------ */ - -float *RE_strandren_get_surfnor(ObjectRen *obr, StrandRen *strand, int verify) -{ - float *surfnor; - int nr= strand->index>>8; - - surfnor= obr->strandnodes[nr].surfnor; - if (surfnor==NULL) { - if (verify) - surfnor= obr->strandnodes[nr].surfnor= MEM_callocN(256*RE_SURFNOR_ELEMS*sizeof(float), "surfnor strand table"); - else - return NULL; - } - return surfnor + (strand->index & 255)*RE_SURFNOR_ELEMS; -} - -float *RE_strandren_get_uv(ObjectRen *obr, StrandRen *strand, int n, char **name, int verify) -{ - StrandTableNode *node; - int nr= strand->index>>8, strandindex= (strand->index&255); - int index= (n<<8) + strandindex; - - node= &obr->strandnodes[nr]; - - if (verify) { - if (n>=node->totuv) { - float *uv= node->uv; - int size= (n+1)*256; - - node->uv= MEM_callocN(size*sizeof(float)*RE_UV_ELEMS, "strand uv table"); - - if (uv) { - size= node->totuv*256; - memcpy(node->uv, uv, size*sizeof(float)*RE_UV_ELEMS); - MEM_freeN(uv); - } - - node->totuv= n+1; - } - } - else { - if (n>=node->totuv) - return NULL; - - if (name) *name= obr->mtface[n]; - } - - return node->uv + index*RE_UV_ELEMS; -} - -MCol *RE_strandren_get_mcol(ObjectRen *obr, StrandRen *strand, int n, char **name, int verify) -{ - StrandTableNode *node; - int nr= strand->index>>8, strandindex= (strand->index&255); - int index= (n<<8) + strandindex; - - node= &obr->strandnodes[nr]; - - if (verify) { - if (n>=node->totmcol) { - MCol *mcol= node->mcol; - int size= (n+1)*256; - - node->mcol= MEM_callocN(size*sizeof(MCol)*RE_MCOL_ELEMS, "strand mcol table"); - - if (mcol) { - size= node->totmcol*256; - memcpy(node->mcol, mcol, size*sizeof(MCol)*RE_MCOL_ELEMS); - MEM_freeN(mcol); - } - - node->totmcol= n+1; - } - } - else { - if (n>=node->totmcol) - return NULL; - - if (name) *name= obr->mcol[n]; - } - - return node->mcol + index*RE_MCOL_ELEMS; -} - -float *RE_strandren_get_simplify(struct ObjectRen *obr, struct StrandRen *strand, int verify) -{ - float *simplify; - int nr= strand->index>>8; - - simplify= obr->strandnodes[nr].simplify; - if (simplify==NULL) { - if (verify) - simplify= obr->strandnodes[nr].simplify= MEM_callocN(256*RE_SIMPLIFY_ELEMS*sizeof(float), "simplify strand table"); - else - return NULL; - } - return simplify + (strand->index & 255)*RE_SIMPLIFY_ELEMS; -} - -int *RE_strandren_get_face(ObjectRen *obr, StrandRen *strand, int verify) -{ - int *face; - int nr= strand->index>>8; - - face= obr->strandnodes[nr].face; - if (face==NULL) { - if (verify) - face= obr->strandnodes[nr].face= MEM_callocN(256*RE_FACE_ELEMS*sizeof(int), "face strand table"); - else - return NULL; - } - return face + (strand->index & 255)*RE_FACE_ELEMS; -} - -/* winspeed is exception, it is stored per instance */ -float *RE_strandren_get_winspeed(ObjectInstanceRen *obi, StrandRen *strand, int verify) -{ - float *winspeed; - int totvector; - - winspeed= obi->vectors; - if (winspeed==NULL) { - if (verify) { - totvector= obi->obr->totvert + obi->obr->totstrand; - winspeed= obi->vectors= MEM_callocN(totvector*RE_WINSPEED_ELEMS*sizeof(float), "winspeed strand table"); - } - else - return NULL; - } - return winspeed + (obi->obr->totvert + strand->index)*RE_WINSPEED_ELEMS; -} - -StrandRen *RE_findOrAddStrand(ObjectRen *obr, int nr) -{ - StrandTableNode *temp; - StrandRen *v; - int a; - - if (nr<0) { - printf("error in findOrAddStrand: %d\n", nr); - return obr->strandnodes[0].strand; - } - a= nr>>8; - - if (a>=obr->strandnodeslen-1) { /* Need to allocate more columns..., and keep last element NULL for free loop */ - temp= obr->strandnodes; - - obr->strandnodes= MEM_mallocN(sizeof(StrandTableNode)*(obr->strandnodeslen+TABLEINITSIZE), "strandnodes"); - if (temp) memcpy(obr->strandnodes, temp, obr->strandnodeslen*sizeof(StrandTableNode)); - memset(obr->strandnodes+obr->strandnodeslen, 0, TABLEINITSIZE*sizeof(StrandTableNode)); - - obr->strandnodeslen+=TABLEINITSIZE; /*Does this really need to be power of 2?*/ - if (temp) MEM_freeN(temp); - } - - v= obr->strandnodes[a].strand; - - if (v==NULL) { - int i; - - v= (StrandRen *)MEM_callocN(256*sizeof(StrandRen), "findOrAddStrand"); - obr->strandnodes[a].strand= v; - - for (i= (nr & 0xFFFFFF00), a=0; a<256; a++, i++) - v[a].index= i; - } - v+= (nr & 255); - return v; -} - -StrandBuffer *RE_addStrandBuffer(ObjectRen *obr, int totvert) -{ - StrandBuffer *strandbuf; - - strandbuf= MEM_callocN(sizeof(StrandBuffer), "StrandBuffer"); - strandbuf->vert= MEM_callocN(sizeof(StrandVert)*totvert, "StrandVert"); - strandbuf->totvert= totvert; - strandbuf->obr= obr; - - obr->strandbuf= strandbuf; - - return strandbuf; -} - -/* ------------------------------------------------------------------------ */ - -ObjectRen *RE_addRenderObject(Render *re, Object *ob, Object *par, int index, int psysindex, int lay) -{ - ObjectRen *obr= MEM_callocN(sizeof(ObjectRen), "object render struct"); - - BLI_addtail(&re->objecttable, obr); - obr->ob= ob; - obr->par= par; - obr->index= index; - obr->psysindex= psysindex; - obr->lay= lay; - - return obr; -} - -void free_renderdata_vertnodes(VertTableNode *vertnodes) -{ - int a; - - if (vertnodes==NULL) return; - - for (a=0; vertnodes[a].vert; a++) { - MEM_freeN(vertnodes[a].vert); - - if (vertnodes[a].rad) - MEM_freeN(vertnodes[a].rad); - if (vertnodes[a].strand) - MEM_freeN(vertnodes[a].strand); - if (vertnodes[a].tangent) - MEM_freeN(vertnodes[a].tangent); - if (vertnodes[a].stress) - MEM_freeN(vertnodes[a].stress); - if (vertnodes[a].winspeed) - MEM_freeN(vertnodes[a].winspeed); - if (vertnodes[a].origindex) - MEM_freeN(vertnodes[a].origindex); - } - - MEM_freeN(vertnodes); -} - -void free_renderdata_vlaknodes(VlakTableNode *vlaknodes) -{ - int a; - - if (vlaknodes==NULL) return; - - for (a=0; vlaknodes[a].vlak; a++) { - MEM_freeN(vlaknodes[a].vlak); - - if (vlaknodes[a].mtface) - MEM_freeN(vlaknodes[a].mtface); - if (vlaknodes[a].mcol) - MEM_freeN(vlaknodes[a].mcol); - if (vlaknodes[a].origindex) - MEM_freeN(vlaknodes[a].origindex); - if (vlaknodes[a].surfnor) - MEM_freeN(vlaknodes[a].surfnor); - for (int b = 0; b < MAX_MTFACE; b++) { - if (vlaknodes[a].tangent_arrays[b]) - MEM_freeN(vlaknodes[a].tangent_arrays[b]); - } - if (vlaknodes[a].radface) - MEM_freeN(vlaknodes[a].radface); - } - - MEM_freeN(vlaknodes); -} - -static void free_renderdata_strandnodes(StrandTableNode *strandnodes) -{ - int a; - - if (strandnodes==NULL) return; - - for (a=0; strandnodes[a].strand; a++) { - MEM_freeN(strandnodes[a].strand); - - if (strandnodes[a].uv) - MEM_freeN(strandnodes[a].uv); - if (strandnodes[a].mcol) - MEM_freeN(strandnodes[a].mcol); - if (strandnodes[a].winspeed) - MEM_freeN(strandnodes[a].winspeed); - if (strandnodes[a].surfnor) - MEM_freeN(strandnodes[a].surfnor); - if (strandnodes[a].simplify) - MEM_freeN(strandnodes[a].simplify); - if (strandnodes[a].face) - MEM_freeN(strandnodes[a].face); - } - - MEM_freeN(strandnodes); -} - -void free_renderdata_tables(Render *re) -{ - ObjectInstanceRen *obi; - ObjectRen *obr; - StrandBuffer *strandbuf; - int a=0; - - for (obr=re->objecttable.first; obr; obr=obr->next) { - if (obr->vertnodes) { - free_renderdata_vertnodes(obr->vertnodes); - obr->vertnodes= NULL; - obr->vertnodeslen= 0; - } - - if (obr->vlaknodes) { - free_renderdata_vlaknodes(obr->vlaknodes); - obr->vlaknodes= NULL; - obr->vlaknodeslen= 0; - obr->totvlak= 0; - } - - if (obr->bloha) { - for (a=0; obr->bloha[a]; a++) - MEM_freeN(obr->bloha[a]); - - MEM_freeN(obr->bloha); - obr->bloha= NULL; - obr->blohalen= 0; - } - - if (obr->strandnodes) { - free_renderdata_strandnodes(obr->strandnodes); - obr->strandnodes= NULL; - obr->strandnodeslen= 0; - } - - strandbuf= obr->strandbuf; - if (strandbuf) { - if (strandbuf->vert) MEM_freeN(strandbuf->vert); - if (strandbuf->bound) MEM_freeN(strandbuf->bound); - MEM_freeN(strandbuf); - } - - if (obr->mtface) - MEM_freeN(obr->mtface); - - if (obr->mcol) - MEM_freeN(obr->mcol); - - if (obr->rayfaces) { - MEM_freeN(obr->rayfaces); - obr->rayfaces = NULL; - } - - if (obr->rayprimitives) { - MEM_freeN(obr->rayprimitives); - obr->rayprimitives = NULL; - } - - if (obr->raytree) { - RE_rayobject_free(obr->raytree); - obr->raytree = NULL; - } - } - - if (re->objectinstance) { - for (obi=re->instancetable.first; obi; obi=obi->next) { - if (obi->vectors) - MEM_freeN(obi->vectors); - - if (obi->raytree) - RE_rayobject_free(obi->raytree); - } - - MEM_freeN(re->objectinstance); - re->objectinstance= NULL; - re->totinstance= 0; - re->instancetable.first= re->instancetable.last= NULL; - } - - if (re->sortedhalos) { - MEM_freeN(re->sortedhalos); - re->sortedhalos= NULL; - } - - BLI_freelistN(&re->customdata_names); - BLI_freelistN(&re->objecttable); - BLI_freelistN(&re->instancetable); -} - -/* ------------------------------------------------------------------------ */ - -HaloRen *RE_findOrAddHalo(ObjectRen *obr, int nr) -{ - HaloRen *h, **temp; - int a; - - if (nr<0) { - printf("error in findOrAddHalo: %d\n", nr); - return NULL; - } - a= nr>>8; - - if (a>=obr->blohalen-1) { /* Need to allocate more columns..., and keep last element NULL for free loop */ - //printf("Allocating %i more halo groups. %i total.\n", - // TABLEINITSIZE, obr->blohalen+TABLEINITSIZE ); - temp=obr->bloha; - - obr->bloha = (HaloRen **)MEM_callocN(sizeof(void *) * (obr->blohalen + TABLEINITSIZE), "Bloha"); - if (temp) memcpy(obr->bloha, temp, obr->blohalen*sizeof(void *)); - memset(&(obr->bloha[obr->blohalen]), 0, TABLEINITSIZE * sizeof(void *)); - obr->blohalen+=TABLEINITSIZE; /*Does this really need to be power of 2?*/ - if (temp) MEM_freeN(temp); - } - - h= obr->bloha[a]; - if (h==NULL) { - h= (HaloRen *)MEM_callocN(256*sizeof(HaloRen), "findOrAdHalo"); - obr->bloha[a]= h; - } - h+= (nr & 255); - return h; -} - -/* ------------------------------------------------------------------------- */ - -HaloRen *RE_inithalo(Render *re, ObjectRen *obr, Material *ma, - const float vec[3], const float vec1[3], - const float *orco, float hasize, float vectsize, int seed) -{ - const bool skip_load_image = (re->r.scemode & R_NO_IMAGE_LOAD) != 0; - const bool texnode_preview = (re->r.scemode & R_TEXNODE_PREVIEW) != 0; - HaloRen *har; - MTex *mtex; - float tin, tr, tg, tb, ta; - float xn, yn, zn, texvec[3], hoco[4], hoco1[4]; - - if (hasize==0.0f) return NULL; - - projectverto(vec, re->winmat, hoco); - if (hoco[3]==0.0f) return NULL; - if (vec1) { - projectverto(vec1, re->winmat, hoco1); - if (hoco1[3]==0.0f) return NULL; - } - - har= RE_findOrAddHalo(obr, obr->tothalo++); - copy_v3_v3(har->co, vec); - har->hasize= hasize; - - /* actual projectvert is done in function project_renderdata() because of parts/border/pano */ - /* we do it here for sorting of halos */ - zn= hoco[3]; - har->xs= 0.5f*re->winx*(hoco[0]/zn); - har->ys= 0.5f*re->winy*(hoco[1]/zn); - har->zs= 0x7FFFFF*(hoco[2]/zn); - - har->zBufDist = 0x7FFFFFFF*(hoco[2]/zn); - - /* halovect */ - if (vec1) { - - har->type |= HA_VECT; - - xn= har->xs - 0.5f*re->winx*(hoco1[0]/hoco1[3]); - yn= har->ys - 0.5f*re->winy*(hoco1[1]/hoco1[3]); - if (yn == 0.0f && xn >= 0.0f) zn = 0.0f; - else zn = atan2f(yn, xn); - - har->sin = sinf(zn); - har->cos = cosf(zn); - zn= len_v3v3(vec1, vec); - - har->hasize= vectsize*zn + (1.0f-vectsize)*hasize; - - sub_v3_v3v3(har->no, vec, vec1); - normalize_v3(har->no); - } - - if (ma->mode & MA_HALO_XALPHA) har->type |= HA_XALPHA; - - har->alfa= ma->alpha; - har->r= ma->r; - har->g= ma->g; - har->b= ma->b; - har->add= (255.0f*ma->add); - har->mat= ma; - har->hard= ma->har; - har->seed= seed % 256; - - if (ma->mode & MA_STAR) har->starpoints= ma->starc; - if (ma->mode & MA_HALO_LINES) har->linec= ma->linec; - if (ma->mode & MA_HALO_RINGS) har->ringc= ma->ringc; - if (ma->mode & MA_HALO_FLARE) har->flarec= ma->flarec; - - - if (ma->mtex[0]) { - - if (ma->mode & MA_HALOTEX) { - har->tex = 1; - } - else if (har->mat->septex & (1 << 0)) { - /* only 1 level textures */ - } - else { - mtex= ma->mtex[0]; - copy_v3_v3(texvec, vec); - - if (mtex->texco & TEXCO_NORM) { - ; - } - else if (mtex->texco & TEXCO_OBJECT) { - /* texvec[0]+= imatbase->ivec[0]; */ - /* texvec[1]+= imatbase->ivec[1]; */ - /* texvec[2]+= imatbase->ivec[2]; */ - /* mul_m3_v3(imatbase->imat, texvec); */ - } - else { - if (orco) { - copy_v3_v3(texvec, orco); - } - } - - externtex(mtex, - texvec, - &tin, &tr, &tg, &tb, &ta, - 0, - re->pool, - skip_load_image, - texnode_preview); - - yn= tin*mtex->colfac; - //zn= tin*mtex->alphafac; - - if (mtex->mapto & MAP_COL) { - zn= 1.0f-yn; - har->r= (yn*tr+ zn*ma->r); - har->g= (yn*tg+ zn*ma->g); - har->b= (yn*tb+ zn*ma->b); - } - if (mtex->texco & TEXCO_UV) { - har->alfa= tin; - } - if (mtex->mapto & MAP_ALPHA) - har->alfa= tin; - } - } - - har->pool = re->pool; - har->skip_load_image = skip_load_image; - har->texnode_preview = texnode_preview; - - return har; -} - -HaloRen *RE_inithalo_particle(Render *re, ObjectRen *obr, DerivedMesh *dm, Material *ma, - const float vec[3], const float vec1[3], - const float *orco, const float *uvco, float hasize, float vectsize, int seed, const float pa_co[3]) -{ - const bool skip_load_image = (re->r.scemode & R_NO_IMAGE_LOAD) != 0; - const bool texnode_preview = (re->r.scemode & R_TEXNODE_PREVIEW) != 0; - HaloRen *har; - MTex *mtex; - float tin, tr, tg, tb, ta; - float xn, yn, zn, texvec[3], hoco[4], hoco1[4], in[3], tex[3], out[3]; - int i, hasrgb; - - if (hasize==0.0f) return NULL; - - projectverto(vec, re->winmat, hoco); - if (hoco[3]==0.0f) return NULL; - if (vec1) { - projectverto(vec1, re->winmat, hoco1); - if (hoco1[3]==0.0f) return NULL; - } - - har= RE_findOrAddHalo(obr, obr->tothalo++); - copy_v3_v3(har->co, vec); - har->hasize= hasize; - - /* actual projectvert is done in function project_renderdata() because of parts/border/pano */ - /* we do it here for sorting of halos */ - zn= hoco[3]; - har->xs= 0.5f*re->winx*(hoco[0]/zn); - har->ys= 0.5f*re->winy*(hoco[1]/zn); - har->zs= 0x7FFFFF*(hoco[2]/zn); - - har->zBufDist = 0x7FFFFFFF*(hoco[2]/zn); - - /* halovect */ - if (vec1) { - - har->type |= HA_VECT; - - xn= har->xs - 0.5f*re->winx*(hoco1[0]/hoco1[3]); - yn= har->ys - 0.5f*re->winy*(hoco1[1]/hoco1[3]); - if (yn == 0.0f && xn >= 0.0f) zn = 0.0f; - else zn = atan2f(yn, xn); - - har->sin = sinf(zn); - har->cos = cosf(zn); - zn= len_v3v3(vec1, vec)*0.5f; - - har->hasize= vectsize*zn + (1.0f-vectsize)*hasize; - - sub_v3_v3v3(har->no, vec, vec1); - normalize_v3(har->no); - } - - if (ma->mode & MA_HALO_XALPHA) har->type |= HA_XALPHA; - - har->alfa= ma->alpha; - har->r= ma->r; - har->g= ma->g; - har->b= ma->b; - har->add= (255.0f*ma->add); - har->mat= ma; - har->hard= ma->har; - har->seed= seed % 256; - - if (ma->mode & MA_STAR) har->starpoints= ma->starc; - if (ma->mode & MA_HALO_LINES) har->linec= ma->linec; - if (ma->mode & MA_HALO_RINGS) har->ringc= ma->ringc; - if (ma->mode & MA_HALO_FLARE) har->flarec= ma->flarec; - - if ((ma->mode & MA_HALOTEX) && ma->mtex[0]) - har->tex= 1; - - for (i=0; i<MAX_MTEX; i++) - if (ma->mtex[i] && (ma->septex & (1<<i))==0) { - mtex= ma->mtex[i]; - copy_v3_v3(texvec, vec); - - if (mtex->texco & TEXCO_NORM) { - ; - } - else if (mtex->texco & TEXCO_OBJECT) { - if (mtex->object) - mul_m4_v3(mtex->object->imat_ren, texvec); - } - else if (mtex->texco & TEXCO_GLOB) { - copy_v3_v3(texvec, vec); - } - else if (mtex->texco & TEXCO_UV && uvco) { - int uv_index=CustomData_get_named_layer_index(&dm->faceData, CD_MTFACE, mtex->uvname); - if (uv_index<0) - uv_index=CustomData_get_active_layer_index(&dm->faceData, CD_MTFACE); - - uv_index-=CustomData_get_layer_index(&dm->faceData, CD_MTFACE); - - texvec[0]=2.0f*uvco[2*uv_index]-1.0f; - texvec[1]=2.0f*uvco[2*uv_index+1]-1.0f; - texvec[2]=0.0f; - } - else if (mtex->texco & TEXCO_PARTICLE) { - /* particle coordinates in range [0, 1] */ - texvec[0] = 2.f * pa_co[0] - 1.f; - texvec[1] = 2.f * pa_co[1] - 1.f; - texvec[2] = pa_co[2]; - } - else if (orco) { - copy_v3_v3(texvec, orco); - } - - hasrgb = externtex(mtex, - texvec, - &tin, &tr, &tg, &tb, &ta, - 0, - re->pool, - skip_load_image, - texnode_preview); - - //yn= tin*mtex->colfac; - //zn= tin*mtex->alphafac; - if (mtex->mapto & MAP_COL) { - tex[0]=tr; - tex[1]=tg; - tex[2]=tb; - out[0]=har->r; - out[1]=har->g; - out[2]=har->b; - - texture_rgb_blend(in, tex, out, tin, mtex->colfac, mtex->blendtype); - // zn= 1.0-yn; - //har->r= (yn*tr+ zn*ma->r); - //har->g= (yn*tg+ zn*ma->g); - //har->b= (yn*tb+ zn*ma->b); - har->r= in[0]; - har->g= in[1]; - har->b= in[2]; - } - - /* alpha returned, so let's use it instead of intensity */ - if (hasrgb) - tin = ta; - - if (mtex->mapto & MAP_ALPHA) - har->alfa = texture_value_blend(mtex->def_var, har->alfa, tin, mtex->alphafac, mtex->blendtype); - if (mtex->mapto & MAP_HAR) - har->hard = 1.0f+126.0f*texture_value_blend(mtex->def_var, ((float)har->hard)/127.0f, tin, mtex->hardfac, mtex->blendtype); - if (mtex->mapto & MAP_RAYMIRR) - har->hasize = 100.0f*texture_value_blend(mtex->def_var, har->hasize/100.0f, tin, mtex->raymirrfac, mtex->blendtype); - if (mtex->mapto & MAP_TRANSLU) { - float add = texture_value_blend(mtex->def_var, (float)har->add/255.0f, tin, mtex->translfac, mtex->blendtype); - CLAMP(add, 0.f, 1.f); - har->add = 255.0f*add; - } - /* now what on earth is this good for?? */ - //if (mtex->texco & 16) { - // har->alfa= tin; - //} - } - - har->pool = re->pool; - har->skip_load_image = (re->r.scemode & R_NO_IMAGE_LOAD) != 0; - har->texnode_preview = (re->r.scemode & R_TEXNODE_PREVIEW) != 0; - - return har; -} - -/* -------------------------- operations on entire database ----------------------- */ - -/* ugly function for halos in panorama */ -static int panotestclip(Render *re, bool do_pano, float v[4]) -{ - /* part size (ensure we run RE_parts_clamp first) */ - BLI_assert(re->partx == min_ii(re->r.tilex, re->rectx)); - BLI_assert(re->party == min_ii(re->r.tiley, re->recty)); - - if (do_pano == false) { - return testclip(v); - } - else { - /* to be used for halos en infos */ - float abs4; - short c = 0; - - int xparts = (re->rectx + re->partx - 1) / re->partx; - - abs4= fabsf(v[3]); - - if (v[2]< -abs4) c=16; /* this used to be " if (v[2]<0) ", see clippz() */ - else if (v[2]> abs4) c+= 32; - - if ( v[1]>abs4) c+=4; - else if ( v[1]< -abs4) c+=8; - - abs4*= xparts; - if ( v[0]>abs4) c+=2; - else if ( v[0]< -abs4) c+=1; - - return c; - } -} - -/** - * This adds the hcs coordinates to vertices. It iterates over all - * vertices, halos and faces. After the conversion, we clip in hcs. - * - * Elsewhere, all primites are converted to vertices. - * Called in - * - envmapping (envmap.c) - * - shadow buffering (shadbuf.c) - */ - -void project_renderdata(Render *re, - void (*projectfunc)(const float *, float mat[4][4], float *), - bool do_pano, float xoffs, bool UNUSED(do_buckets)) -{ - ObjectRen *obr; - HaloRen *har = NULL; - float zn, vec[3], hoco[4]; - int a; - - if (do_pano) { - float panophi= xoffs; - - re->panosi = sinf(panophi); - re->panoco = cosf(panophi); - } - - for (obr=re->objecttable.first; obr; obr=obr->next) { - /* calculate view coordinates (and zbuffer value) */ - for (a=0; a<obr->tothalo; a++) { - if ((a & 255)==0) har= obr->bloha[a>>8]; - else har++; - - if (do_pano) { - vec[0]= re->panoco*har->co[0] + re->panosi*har->co[2]; - vec[1]= har->co[1]; - vec[2]= -re->panosi*har->co[0] + re->panoco*har->co[2]; - } - else { - copy_v3_v3(vec, har->co); - } - - projectfunc(vec, re->winmat, hoco); - - /* we clip halos less critical, but not for the Z */ - hoco[0]*= 0.5f; - hoco[1]*= 0.5f; - - if ( panotestclip(re, do_pano, hoco) ) { - har->miny= har->maxy= -10000; /* that way render clips it */ - } - else if (hoco[3]<0.0f) { - har->miny= har->maxy= -10000; /* render clips it */ - } - else { /* do the projection...*/ - /* bring back hocos */ - hoco[0]*= 2.0f; - hoco[1]*= 2.0f; - - zn= hoco[3]; - har->xs= 0.5f*re->winx*(1.0f+hoco[0]/zn); /* the 0.5 negates the previous 2...*/ - har->ys= 0.5f*re->winy*(1.0f+hoco[1]/zn); - - /* this should be the zbuffer coordinate */ - har->zs= 0x7FFFFF*(hoco[2]/zn); - /* taking this from the face clip functions? seems ok... */ - har->zBufDist = 0x7FFFFFFF*(hoco[2]/zn); - - vec[0]+= har->hasize; - projectfunc(vec, re->winmat, hoco); - vec[0]-= har->hasize; - zn= hoco[3]; - har->rad= fabsf(har->xs- 0.5f*re->winx*(1.0f+hoco[0]/zn)); - - /* this clip is not really OK, to prevent stars to become too large */ - if (har->type & HA_ONLYSKY) { - if (har->rad>3.0f) har->rad= 3.0f; - } - - har->radsq= har->rad*har->rad; - - har->miny= har->ys - har->rad/re->ycor; - har->maxy= har->ys + har->rad/re->ycor; - - /* the Zd value is still not really correct for pano */ - - vec[2] -= har->hasize; /* z negative, otherwise it's clipped */ - projectfunc(vec, re->winmat, hoco); - zn = hoco[3]; - zn = fabsf((float)har->zs - 0x7FFFFF * (hoco[2] / zn)); - har->zd = CLAMPIS(zn, 0, INT_MAX); - - } - - } - } -} - -/* ------------------------------------------------------------------------- */ - -void RE_updateRenderInstance(Render *re, ObjectInstanceRen *obi, int flag) -{ - /* flag specifies what things have changed. */ - if (flag & RE_OBJECT_INSTANCES_UPDATE_OBMAT) { - copy_m4_m4(obi->obmat, obi->ob->obmat); - invert_m4_m4(obi->obinvmat, obi->obmat); - } - if (flag & RE_OBJECT_INSTANCES_UPDATE_VIEW) { - mul_m4_m4m4(obi->localtoviewmat, re->viewmat, obi->obmat); - mul_m4_m4m4(obi->localtoviewinvmat, obi->obinvmat, re->viewinv); - } -} - -void RE_updateRenderInstances(Render *re, int flag) -{ - int i = 0; - for (i = 0; i < re->totinstance; i++) - RE_updateRenderInstance(re, &re->objectinstance[i], flag); -} - -ObjectInstanceRen *RE_addRenderInstance( - Render *re, ObjectRen *obr, Object *ob, Object *par, - int index, int psysindex, float mat[4][4], int lay, const DupliObject *dob) -{ - ObjectInstanceRen *obi; - float mat3[3][3]; - - obi= MEM_callocN(sizeof(ObjectInstanceRen), "ObjectInstanceRen"); - obi->obr= obr; - obi->ob= ob; - obi->par= par; - obi->index= index; - obi->psysindex= psysindex; - obi->lay= lay; - - /* Fill particle info */ - if (par && dob) { - const ParticleSystem *psys = dob->particle_system; - if (psys) { - int part_index; - if (obi->index < psys->totpart) { - part_index = obi->index; - } - else if (psys->child) { - part_index = psys->child[obi->index - psys->totpart].parent; - } - else { - part_index = -1; - } - - if (part_index >= 0) { - const ParticleData *p = &psys->particles[part_index]; - obi->part_index = part_index; - obi->part_size = p->size; - obi->part_age = RE_GetStats(re)->cfra - p->time; - obi->part_lifetime = p->lifetime; - - copy_v3_v3(obi->part_co, p->state.co); - copy_v3_v3(obi->part_vel, p->state.vel); - copy_v3_v3(obi->part_avel, p->state.ave); - } - } - } - - /* Fill object info */ - if (dob) { - obi->random_id = dob->random_id; - } - else { - obi->random_id = BLI_hash_int_2d(BLI_hash_string(obi->ob->id.name + 2), 0); - } - - RE_updateRenderInstance(re, obi, RE_OBJECT_INSTANCES_UPDATE_OBMAT | RE_OBJECT_INSTANCES_UPDATE_VIEW); - - if (mat) { - copy_m4_m4(obi->mat, mat); - copy_m3_m4(mat3, mat); - invert_m3_m3(obi->nmat, mat3); - transpose_m3(obi->nmat); - obi->flag |= R_DUPLI_TRANSFORMED; - } - - BLI_addtail(&re->instancetable, obi); - - return obi; -} - -void RE_instance_get_particle_info(struct ObjectInstanceRen *obi, float *index, float *random, float *age, float *lifetime, float co[3], float *size, float vel[3], float angvel[3]) -{ - *index = obi->part_index; - *random = BLI_hash_int_01(obi->part_index); - *age = obi->part_age; - *lifetime = obi->part_lifetime; - copy_v3_v3(co, obi->part_co); - *size = obi->part_size; - copy_v3_v3(vel, obi->part_vel); - copy_v3_v3(angvel, obi->part_avel); -} - - -void RE_makeRenderInstances(Render *re) -{ - ObjectInstanceRen *obi, *oldobi; - ListBase newlist; - int tot; - - /* convert list of object instances to an array for index based lookup */ - tot= BLI_listbase_count(&re->instancetable); - re->objectinstance= MEM_callocN(sizeof(ObjectInstanceRen)*tot, "ObjectInstance"); - re->totinstance= tot; - newlist.first= newlist.last= NULL; - - obi= re->objectinstance; - for (oldobi=re->instancetable.first; oldobi; oldobi=oldobi->next) { - *obi= *oldobi; - - if (obi->obr) { - obi->prev= obi->next= NULL; - BLI_addtail(&newlist, obi); - obi++; - } - else - re->totinstance--; - } - - BLI_freelistN(&re->instancetable); - re->instancetable= newlist; -} - -/* four functions to facilitate envmap rotation for raytrace */ -void RE_instance_rotate_ray_start(ObjectInstanceRen *obi, Isect *is) -{ - if (obi && (obi->flag & R_ENV_TRANSFORMED)) { - copy_v3_v3(is->origstart, is->start); - mul_m4_v3(obi->imat, is->start); - } -} - -void RE_instance_rotate_ray_dir(ObjectInstanceRen *obi, Isect *is) -{ - if (obi && (obi->flag & R_ENV_TRANSFORMED)) { - float end[3]; - - copy_v3_v3(is->origdir, is->dir); - add_v3_v3v3(end, is->origstart, is->dir); - - mul_m4_v3(obi->imat, end); - sub_v3_v3v3(is->dir, end, is->start); - } -} - -void RE_instance_rotate_ray(ObjectInstanceRen *obi, Isect *is) -{ - RE_instance_rotate_ray_start(obi, is); - RE_instance_rotate_ray_dir(obi, is); -} - -void RE_instance_rotate_ray_restore(ObjectInstanceRen *obi, Isect *is) -{ - if (obi && (obi->flag & R_ENV_TRANSFORMED)) { - copy_v3_v3(is->start, is->origstart); - copy_v3_v3(is->dir, is->origdir); - } -} - -int clip_render_object(float boundbox[2][3], float bounds[4], float winmat[4][4]) -{ - float mat[4][4], vec[4]; - int a, fl, flag = -1; - - copy_m4_m4(mat, winmat); - - for (a=0; a < 8; a++) { - vec[0]= (a & 1)? boundbox[0][0]: boundbox[1][0]; - vec[1]= (a & 2)? boundbox[0][1]: boundbox[1][1]; - vec[2]= (a & 4)? boundbox[0][2]: boundbox[1][2]; - vec[3]= 1.0; - mul_m4_v4(mat, vec); - - fl = 0; - if (bounds) { - if (vec[0] < bounds[0] * vec[3]) fl |= 1; - else if (vec[0] > bounds[1] * vec[3]) fl |= 2; - - if (vec[1] > bounds[3] * vec[3]) fl |= 4; - else if (vec[1] < bounds[2] * vec[3]) fl |= 8; - } - else { - if (vec[0] < -vec[3]) fl |= 1; - else if (vec[0] > vec[3]) fl |= 2; - - if (vec[1] > vec[3]) fl |= 4; - else if (vec[1] < -vec[3]) fl |= 8; - } - if (vec[2] < -vec[3]) fl |= 16; - else if (vec[2] > vec[3]) fl |= 32; - - flag &= fl; - if (flag == 0) { - return 0; - } - } - - return flag; -} - diff --git a/source/blender/render/intern/source/shadbuf.c b/source/blender/render/intern/source/shadbuf.c deleted file mode 100644 index fb441662829..00000000000 --- a/source/blender/render/intern/source/shadbuf.c +++ /dev/null @@ -1,2647 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * Contributor(s): 2004-2006, Blender Foundation - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/render/intern/source/shadbuf.c - * \ingroup render - */ - - -#include <math.h> -#include <string.h> - - -#include "MEM_guardedalloc.h" - -#include "DNA_group_types.h" -#include "DNA_lamp_types.h" -#include "DNA_material_types.h" - -#include "BLI_math.h" -#include "BLI_blenlib.h" -#include "BLI_jitter_2d.h" -#include "BLI_memarena.h" -#include "BLI_rand.h" -#include "BLI_utildefines.h" - -#include "BKE_global.h" -#include "BKE_scene.h" - -#include "PIL_time.h" - -#include "render_types.h" -#include "renderdatabase.h" -#include "rendercore.h" -#include "shadbuf.h" -#include "shading.h" -#include "zbuf.h" - -/* XXX, could be better implemented... this is for endian issues */ -#ifdef __BIG_ENDIAN__ -//# define RCOMP 3 -# define GCOMP 2 -# define BCOMP 1 -# define ACOMP 0 -#else -//# define RCOMP 0 -# define GCOMP 1 -# define BCOMP 2 -# define ACOMP 3 -#endif - -#define RCT_SIZE_X(rct) ((rct)->xmax - (rct)->xmin) -#define RCT_SIZE_Y(rct) ((rct)->ymax - (rct)->ymin) - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -/* defined in pipeline.c, is hardcopy of active dynamic allocated Render */ -/* only to be used here in this file, it's for speed */ -extern struct Render R; -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -/* ------------------------------------------------------------------------- */ - -/* initshadowbuf() in convertBlenderScene.c */ - -/* ------------------------------------------------------------------------- */ - -static void copy_to_ztile(int *rectz, int size, int x1, int y1, int tile, char *r1) -{ - int len4, *rz; - int x2, y2; - - x2= x1+tile; - y2= y1+tile; - if (x2>=size) x2= size-1; - if (y2>=size) y2= size-1; - - if (x1>=x2 || y1>=y2) return; - - len4= 4*(x2- x1); - rz= rectz + size*y1 + x1; - for (; y1<y2; y1++) { - memcpy(r1, rz, len4); - rz+= size; - r1+= len4; - } -} - -#if 0 -static int sizeoflampbuf(ShadBuf *shb) -{ - int num, count=0; - char *cp; - - cp= shb->cbuf; - num= (shb->size*shb->size)/256; - - while (num--) count+= *(cp++); - - return 256*count; -} -#endif - -/* not threadsafe... */ -static float *give_jitter_tab(int samp) -{ - /* these are all possible jitter tables, takes up some - * 12k, not really bad! - * For soft shadows, it saves memory and render time - */ - static int tab[17]={1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256}; - static float jit[1496][2]; - static char ctab[17]= {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - int a, offset=0; - - if (samp<2) samp= 2; - else if (samp>16) samp= 16; - - for (a=0; a<samp-1; a++) offset+= tab[a]; - - if (ctab[samp]==0) { - ctab[samp]= 1; - BLI_jitter_init((float (*)[2])jit[offset], samp*samp); - } - - return jit[offset]; - -} - -static void make_jitter_weight_tab(Render *re, ShadBuf *shb, short filtertype) -{ - float *jit, totw= 0.0f; - int samp= get_render_shadow_samples(&re->r, shb->samp); - int a, tot=samp*samp; - - shb->weight= MEM_mallocN(sizeof(float)*tot, "weight tab lamp"); - - for (jit= shb->jit, a=0; a<tot; a++, jit+=2) { - if (filtertype==LA_SHADBUF_TENT) - shb->weight[a] = 0.71f - sqrtf(jit[0] * jit[0] + jit[1] * jit[1]); - else if (filtertype==LA_SHADBUF_GAUSS) - shb->weight[a] = RE_filter_value(R_FILTER_GAUSS, 1.8f * sqrtf(jit[0] * jit[0] + jit[1] * jit[1])); - else - shb->weight[a]= 1.0f; - - totw+= shb->weight[a]; - } - - totw= 1.0f/totw; - for (a=0; a<tot; a++) { - shb->weight[a]*= totw; - } -} - -static int verg_deepsample(const void *poin1, const void *poin2) -{ - const DeepSample *ds1= (const DeepSample*)poin1; - const DeepSample *ds2= (const DeepSample*)poin2; - - if (ds1->z < ds2->z) return -1; - else if (ds1->z == ds2->z) return 0; - else return 1; -} - -static int compress_deepsamples(DeepSample *dsample, int tot, float epsilon) -{ - /* uses doubles to avoid overflows and other numerical issues, - * could be improved */ - DeepSample *ds, *newds; - float v; - double slope, slopemin, slopemax, min, max, div, newmin, newmax; - int a, first, z, newtot= 0; - -#if 0 - if (print) { - for (a=0, ds=dsample; a<tot; a++, ds++) - printf("%lf, %f ", ds->z/(double)0x7FFFFFFF, ds->v); - printf("\n"); - } -#endif - - /* read from and write into same array */ - ds= dsample; - newds= dsample; - a= 0; - - /* as long as we are not at the end of the array */ - for (a++, ds++; a<tot; a++, ds++) { - slopemin= 0.0f; - slopemax= 0.0f; - first= 1; - - for (; a<tot; a++, ds++) { - //dz= ds->z - newds->z; - if (ds->z == newds->z) { - /* still in same z position, simply check - * visibility difference against epsilon */ - if (!(fabsf(newds->v - ds->v) <= epsilon)) { - break; - } - } - else { - /* compute slopes */ - div= (double)0x7FFFFFFF / ((double)ds->z - (double)newds->z); - min= (double)((ds->v - epsilon) - newds->v) * div; - max= (double)((ds->v + epsilon) - newds->v) * div; - - /* adapt existing slopes */ - if (first) { - newmin= min; - newmax= max; - first= 0; - } - else { - newmin= MAX2(slopemin, min); - newmax= MIN2(slopemax, max); - - /* verify if there is still space between the slopes */ - if (newmin > newmax) { - ds--; - a--; - break; - } - } - - slopemin= newmin; - slopemax= newmax; - } - } - - if (a == tot) { - ds--; - a--; - } - - /* always previous z */ - z= ds->z; - - if (first || a==tot-1) { - /* if slopes were not initialized, use last visibility */ - v= ds->v; - } - else { - /* compute visibility at center between slopes at z */ - slope = (slopemin + slopemax) * 0.5; - v = (double)newds->v + slope * ((double)(z - newds->z) / (double)0x7FFFFFFF); - } - - newds++; - newtot++; - - newds->z= z; - newds->v= v; - } - - if (newtot == 0 || (newds->v != (newds-1)->v)) - newtot++; - -#if 0 - if (print) { - for (a=0, ds=dsample; a<newtot; a++, ds++) - printf("%lf, %f ", ds->z/(double)0x7FFFFFFF, ds->v); - printf("\n"); - } -#endif - - return newtot; -} - -static float deep_alpha(Render *re, int obinr, int facenr, bool use_strand) -{ - ObjectInstanceRen *obi= &re->objectinstance[obinr]; - Material *ma; - - if (use_strand) { - StrandRen *strand= RE_findOrAddStrand(obi->obr, facenr-1); - ma= strand->buffer->ma; - } - else { - VlakRen *vlr= RE_findOrAddVlak(obi->obr, (facenr-1) & RE_QUAD_MASK); - ma= vlr->mat; - } - - return ma->shad_alpha; -} - -static void compress_deepshadowbuf(Render *re, ShadBuf *shb, APixstr *apixbuf, APixstrand *apixbufstrand) -{ - ShadSampleBuf *shsample; - DeepSample *ds[RE_MAX_OSA], *sampleds[RE_MAX_OSA], *dsb, *newbuf; - APixstr *ap, *apn; - APixstrand *aps, *apns; - float visibility; - - const int totbuf= shb->totbuf; - const float totbuf_f= (float)shb->totbuf; - const float totbuf_f_inv= 1.0f/totbuf_f; - const int size= shb->size; - - int a, b, c, tot, minz, found, prevtot, newtot; - int sampletot[RE_MAX_OSA], totsample = 0, totsamplec = 0; - - shsample= MEM_callocN(sizeof(ShadSampleBuf), "shad sample buf"); - BLI_addtail(&shb->buffers, shsample); - - shsample->totbuf = MEM_callocN(sizeof(int) * size * size, "deeptotbuf"); - shsample->deepbuf = MEM_callocN(sizeof(DeepSample *) * size * size, "deepbuf"); - - ap= apixbuf; - aps= apixbufstrand; - for (a=0; a<size*size; a++, ap++, aps++) { - /* count number of samples */ - for (c=0; c<totbuf; c++) - sampletot[c]= 0; - - tot= 0; - for (apn=ap; apn; apn=apn->next) - for (b=0; b<4; b++) - if (apn->p[b]) - for (c=0; c<totbuf; c++) - if (apn->mask[b] & (1<<c)) - sampletot[c]++; - - if (apixbufstrand) { - for (apns=aps; apns; apns=apns->next) - for (b=0; b<4; b++) - if (apns->p[b]) - for (c=0; c<totbuf; c++) - if (apns->mask[b] & (1<<c)) - sampletot[c]++; - } - - for (c=0; c<totbuf; c++) - tot += sampletot[c]; - - if (tot == 0) { - shsample->deepbuf[a]= NULL; - shsample->totbuf[a]= 0; - continue; - } - - /* fill samples */ - ds[0]= sampleds[0]= MEM_callocN(sizeof(DeepSample)*tot*2, "deepsample"); - for (c=1; c<totbuf; c++) - ds[c]= sampleds[c]= sampleds[c-1] + sampletot[c-1]*2; - - for (apn=ap; apn; apn=apn->next) { - for (b=0; b<4; b++) { - if (apn->p[b]) { - for (c=0; c<totbuf; c++) { - if (apn->mask[b] & (1<<c)) { - /* two entries to create step profile */ - ds[c]->z= apn->z[b]; - ds[c]->v= 1.0f; /* not used */ - ds[c]++; - ds[c]->z= apn->z[b]; - ds[c]->v= deep_alpha(re, apn->obi[b], apn->p[b], 0); - ds[c]++; - } - } - } - } - } - - if (apixbufstrand) { - for (apns=aps; apns; apns=apns->next) { - for (b=0; b<4; b++) { - if (apns->p[b]) { - for (c=0; c<totbuf; c++) { - if (apns->mask[b] & (1<<c)) { - /* two entries to create step profile */ - ds[c]->z= apns->z[b]; - ds[c]->v= 1.0f; /* not used */ - ds[c]++; - ds[c]->z= apns->z[b]; - ds[c]->v= deep_alpha(re, apns->obi[b], apns->p[b], 1); - ds[c]++; - } - } - } - } - } - } - - for (c=0; c<totbuf; c++) { - /* sort by increasing z */ - qsort(sampleds[c], sampletot[c], sizeof(DeepSample)*2, verg_deepsample); - - /* sum visibility, replacing alpha values */ - visibility= 1.0f; - ds[c]= sampleds[c]; - - for (b=0; b<sampletot[c]; b++) { - /* two entries creating step profile */ - ds[c]->v= visibility; - ds[c]++; - - visibility *= 1.0f-ds[c]->v; - ds[c]->v= visibility; - ds[c]++; - } - - /* halfway trick, probably won't work well for volumes? */ - ds[c]= sampleds[c]; - for (b=0; b<sampletot[c]; b++) { - if (b+1 < sampletot[c]) { - ds[c]->z= (ds[c]->z>>1) + ((ds[c]+2)->z>>1); - ds[c]++; - ds[c]->z= (ds[c]->z>>1) + ((ds[c]+2)->z>>1); - ds[c]++; - } - else { - ds[c]->z= (ds[c]->z>>1) + (0x7FFFFFFF>>1); - ds[c]++; - ds[c]->z= (ds[c]->z>>1) + (0x7FFFFFFF>>1); - ds[c]++; - } - } - - /* init for merge loop */ - ds[c]= sampleds[c]; - sampletot[c] *= 2; - } - - shsample->deepbuf[a]= MEM_callocN(sizeof(DeepSample)*tot*2, "deepsample"); - shsample->totbuf[a]= 0; - - /* merge buffers */ - dsb= shsample->deepbuf[a]; - while (1) { - minz= 0; - found= 0; - - for (c=0; c<totbuf; c++) { - if (sampletot[c] && (!found || ds[c]->z < minz)) { - minz= ds[c]->z; - found= 1; - } - } - - if (!found) - break; - - dsb->z= minz; - dsb->v= 0.0f; - - visibility= 0.0f; - for (c=0; c<totbuf; c++) { - if (sampletot[c] && ds[c]->z == minz) { - ds[c]++; - sampletot[c]--; - } - - if (sampleds[c] == ds[c]) - visibility += totbuf_f_inv; - else - visibility += (ds[c]-1)->v / totbuf_f; - } - - dsb->v= visibility; - dsb++; - shsample->totbuf[a]++; - } - - prevtot= shsample->totbuf[a]; - totsample += prevtot; - - newtot= compress_deepsamples(shsample->deepbuf[a], prevtot, shb->compressthresh); - shsample->totbuf[a]= newtot; - totsamplec += newtot; - - if (newtot < prevtot) { - newbuf= MEM_mallocN(sizeof(DeepSample)*newtot, "cdeepsample"); - memcpy(newbuf, shsample->deepbuf[a], sizeof(DeepSample)*newtot); - MEM_freeN(shsample->deepbuf[a]); - shsample->deepbuf[a]= newbuf; - } - - MEM_freeN(sampleds[0]); - } - - //printf("%d -> %d, ratio %f\n", totsample, totsamplec, (float)totsamplec/(float)totsample); -} - -/* create Z tiles (for compression): this system is 24 bits!!! */ -static void compress_shadowbuf(ShadBuf *shb, int *rectz, int square) -{ - ShadSampleBuf *shsample; - float dist; - uintptr_t *ztile; - int *rz, *rz1, verg, verg1, size= shb->size; - int a, x, y, minx, miny, byt1, byt2; - char *rc, *rcline, *ctile, *zt; - - shsample= MEM_callocN(sizeof(ShadSampleBuf), "shad sample buf"); - BLI_addtail(&shb->buffers, shsample); - - shsample->zbuf= MEM_mallocN(sizeof(uintptr_t)*(size*size)/256, "initshadbuf2"); - shsample->cbuf= MEM_callocN((size*size)/256, "initshadbuf3"); - - ztile= (uintptr_t *)shsample->zbuf; - ctile= shsample->cbuf; - - /* help buffer */ - rcline= MEM_mallocN(256*4+sizeof(int), "makeshadbuf2"); - - for (y=0; y<size; y+=16) { - if (y< size/2) miny= y+15-size/2; - else miny= y-size/2; - - for (x=0; x<size; x+=16) { - - /* is tile within spotbundle? */ - a= size/2; - if (x< a) minx= x+15-a; - else minx= x-a; - - dist = sqrtf((float)(minx * minx + miny * miny)); - - if (square==0 && dist>(float)(a+12)) { /* 12, tested with a onlyshadow lamp */ - a= 256; verg= 0; /* 0x80000000; */ /* 0x7FFFFFFF; */ - rz1= (&verg)+1; - } - else { - copy_to_ztile(rectz, size, x, y, 16, rcline); - rz1= (int *)rcline; - - verg= (*rz1 & 0xFFFFFF00); - - for (a=0;a<256;a++, rz1++) { - if ( (*rz1 & 0xFFFFFF00) !=verg) break; - } - } - if (a==256) { /* complete empty tile */ - *ctile= 0; - *ztile= *(rz1-1); - } - else { - - /* ACOMP etc. are defined to work L/B endian */ - - rc= rcline; - rz1= (int *)rcline; - verg= rc[ACOMP]; - verg1= rc[BCOMP]; - rc+= 4; - byt1= 1; byt2= 1; - for (a=1;a<256;a++, rc+=4) { - byt1 &= (verg==rc[ACOMP]); - byt2 &= (verg1==rc[BCOMP]); - - if (byt1==0) break; - } - if (byt1 && byt2) { /* only store byte */ - *ctile= 1; - *ztile= (uintptr_t)MEM_mallocN(256+4, "tile1"); - rz= (int *)*ztile; - *rz= *rz1; - - zt= (char *)(rz+1); - rc= rcline; - for (a=0; a<256; a++, zt++, rc+=4) *zt= rc[GCOMP]; - } - else if (byt1) { /* only store short */ - *ctile= 2; - *ztile= (uintptr_t)MEM_mallocN(2*256+4, "Tile2"); - rz= (int *)*ztile; - *rz= *rz1; - - zt= (char *)(rz+1); - rc= rcline; - for (a=0; a<256; a++, zt+=2, rc+=4) { - zt[0]= rc[BCOMP]; - zt[1]= rc[GCOMP]; - } - } - else { /* store triple */ - *ctile= 3; - *ztile= (uintptr_t)MEM_mallocN(3*256, "Tile3"); - - zt= (char *)*ztile; - rc= rcline; - for (a=0; a<256; a++, zt+=3, rc+=4) { - zt[0]= rc[ACOMP]; - zt[1]= rc[BCOMP]; - zt[2]= rc[GCOMP]; - } - } - } - ztile++; - ctile++; - } - } - - MEM_freeN(rcline); -} - -/* sets start/end clipping. lar->shb should be initialized */ -static void shadowbuf_autoclip(Render *re, LampRen *lar) -{ - ObjectInstanceRen *obi; - ObjectRen *obr; - VlakRen *vlr= NULL; - VertRen *ver= NULL; - Material *ma= NULL; - float minz, maxz, vec[3], viewmat[4][4], obviewmat[4][4]; - unsigned int lay = -1; - int i, a, maxtotvert, ok= 1; - char *clipflag; - - minz= 1.0e30f; maxz= -1.0e30f; - copy_m4_m4(viewmat, lar->shb->viewmat); - - if (lar->mode & (LA_LAYER|LA_LAYER_SHADOW)) lay= lar->lay; - - maxtotvert= 0; - for (obr=re->objecttable.first; obr; obr=obr->next) - maxtotvert = max_ii(obr->totvert, maxtotvert); - - clipflag= MEM_callocN(sizeof(char)*maxtotvert, "autoclipflag"); - - /* set clip in vertices when face visible */ - for (i=0, obi=re->instancetable.first; obi; i++, obi=obi->next) { - obr= obi->obr; - - if (obi->flag & R_TRANSFORMED) - mul_m4_m4m4(obviewmat, viewmat, obi->mat); - else - copy_m4_m4(obviewmat, viewmat); - - memset(clipflag, 0, sizeof(char)*obr->totvert); - - /* clear clip, is being set if face is visible (clip is calculated for real later) */ - for (a=0; a<obr->totvlak; a++) { - if ((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; - else vlr++; - - /* note; these conditions are copied from zbuffer_shadow() */ - if (vlr->mat!= ma) { - ma= vlr->mat; - ok= 1; - if ((ma->mode2 & MA_CASTSHADOW)==0 || (ma->mode & MA_SHADBUF)==0) ok= 0; - } - - if (ok && (obi->lay & lay)) { - clipflag[vlr->v1->index]= 1; - clipflag[vlr->v2->index]= 1; - clipflag[vlr->v3->index]= 1; - if (vlr->v4) clipflag[vlr->v4->index]= 1; - } - } - - /* calculate min and max */ - for (a=0; a< obr->totvert;a++) { - if ((a & 255)==0) ver= RE_findOrAddVert(obr, a); - else ver++; - - if (clipflag[a]) { - copy_v3_v3(vec, ver->co); - mul_m4_v3(obviewmat, vec); - /* Z on visible side of lamp space */ - if (vec[2] < 0.0f) { - float inpr, z= -vec[2]; - - /* since vec is rotated in lampspace, this is how to get the cosine of angle */ - /* precision is set 20% larger */ - vec[2]*= 1.2f; - normalize_v3(vec); - inpr= - vec[2]; - - if (inpr>=lar->spotsi) { - if (z<minz) minz= z; - if (z>maxz) maxz= z; - } - } - } - } - } - - MEM_freeN(clipflag); - - /* set clipping min and max */ - if (minz < maxz) { - float delta= (maxz - minz); /* threshold to prevent precision issues */ - - //printf("minz %f maxz %f delta %f\n", minz, maxz, delta); - if (lar->bufflag & LA_SHADBUF_AUTO_START) - lar->shb->d= minz - delta*0.02f; /* 0.02 is arbitrary... needs more thinking! */ - if (lar->bufflag & LA_SHADBUF_AUTO_END) - lar->shb->clipend= maxz + delta*0.1f; - - /* bias was calculated as percentage, we scale it to prevent animation issues */ - delta= (lar->clipend-lar->clipsta)/(lar->shb->clipend-lar->shb->d); - //printf("bias delta %f\n", delta); - lar->shb->bias= (int) (delta*(float)lar->shb->bias); - } -} - -static void makeflatshadowbuf(Render *re, LampRen *lar, float *jitbuf) -{ - ShadBuf *shb= lar->shb; - int *rectz, samples; - - /* zbuffering */ - rectz= MEM_mapallocN(sizeof(int)*shb->size*shb->size, "makeshadbuf"); - - for (samples=0; samples<shb->totbuf; samples++) { - zbuffer_shadow(re, shb->persmat, lar, rectz, shb->size, jitbuf[2*samples], jitbuf[2*samples+1]); - /* create Z tiles (for compression): this system is 24 bits!!! */ - compress_shadowbuf(shb, rectz, lar->mode & LA_SQUARE); - - if (re->test_break(re->tbh)) - break; - } - - MEM_freeN(rectz); -} - -static void makedeepshadowbuf(Render *re, LampRen *lar, float *jitbuf) -{ - ShadBuf *shb= lar->shb; - APixstr *apixbuf; - APixstrand *apixbufstrand= NULL; - ListBase apsmbase= {NULL, NULL}; - - /* zbuffering */ - apixbuf= MEM_callocN(sizeof(APixstr)*shb->size*shb->size, "APixbuf"); - if (re->totstrand) - apixbufstrand= MEM_callocN(sizeof(APixstrand)*shb->size*shb->size, "APixbufstrand"); - - zbuffer_abuf_shadow(re, lar, shb->persmat, apixbuf, apixbufstrand, &apsmbase, shb->size, - shb->totbuf, (float(*)[2])jitbuf); - - /* create Z tiles (for compression): this system is 24 bits!!! */ - compress_deepshadowbuf(re, shb, apixbuf, apixbufstrand); - - MEM_freeN(apixbuf); - if (apixbufstrand) - MEM_freeN(apixbufstrand); - freepsA(&apsmbase); -} - -void makeshadowbuf(Render *re, LampRen *lar) -{ - ShadBuf *shb= lar->shb; - float wsize, *jitbuf, twozero[2]= {0.0f, 0.0f}, angle, temp; - - if (lar->bufflag & (LA_SHADBUF_AUTO_START|LA_SHADBUF_AUTO_END)) - shadowbuf_autoclip(re, lar); - - /* just to enforce identical behavior of all irregular buffers */ - if (lar->buftype==LA_SHADBUF_IRREGULAR) - shb->size= 1024; - - /* matrices and window: in winmat the transformation is being put, - * transforming from observer view to lamp view, including lamp window matrix */ - - angle= saacos(lar->spotsi); - temp = 0.5f * shb->size * cosf(angle) / sinf(angle); - shb->pixsize= (shb->d)/temp; - wsize= shb->pixsize*(shb->size/2.0f); - - perspective_m4(shb->winmat, -wsize, wsize, -wsize, wsize, shb->d, shb->clipend); - mul_m4_m4m4(shb->persmat, shb->winmat, shb->viewmat); - - if (ELEM(lar->buftype, LA_SHADBUF_REGULAR, LA_SHADBUF_HALFWAY, LA_SHADBUF_DEEP)) { - shb->totbuf= lar->buffers; - - /* jitter, weights - not threadsafe! */ - BLI_thread_lock(LOCK_CUSTOM1); - shb->jit= give_jitter_tab(get_render_shadow_samples(&re->r, shb->samp)); - make_jitter_weight_tab(re, shb, lar->filtertype); - BLI_thread_unlock(LOCK_CUSTOM1); - - if (shb->totbuf==4) jitbuf= give_jitter_tab(2); - else if (shb->totbuf==9) jitbuf= give_jitter_tab(3); - else jitbuf= twozero; - - /* zbuffering */ - if (lar->buftype == LA_SHADBUF_DEEP) { - makedeepshadowbuf(re, lar, jitbuf); - shb->totbuf= 1; - } - else - makeflatshadowbuf(re, lar, jitbuf); - - /* printf("lampbuf %d\n", sizeoflampbuf(shb)); */ - } -} - -static void *do_shadow_thread(void *re_v) -{ - Render *re = (Render *)re_v; - LampRen *lar; - - do { - BLI_thread_lock(LOCK_CUSTOM1); - for (lar=re->lampren.first; lar; lar=lar->next) { - if (lar->shb && !lar->thread_assigned) { - lar->thread_assigned= 1; - break; - } - } - BLI_thread_unlock(LOCK_CUSTOM1); - - /* if type is irregular, this only sets the perspective matrix and autoclips */ - if (lar) { - makeshadowbuf(re, lar); - BLI_thread_lock(LOCK_CUSTOM1); - lar->thread_ready= 1; - BLI_thread_unlock(LOCK_CUSTOM1); - } - } while (lar && !re->test_break(re->tbh)); - - return NULL; -} - -static volatile int g_break= 0; -static int thread_break(void *UNUSED(arg)) -{ - return g_break; -} - -void threaded_makeshadowbufs(Render *re) -{ - ListBase threads; - LampRen *lar; - int a, totthread= 0; - int (*test_break)(void *); - - /* count number of threads to use */ - if (G.is_rendering) { - for (lar=re->lampren.first; lar; lar= lar->next) - if (lar->shb) - totthread++; - - totthread = min_ii(totthread, re->r.threads); - } - else - totthread = 1; /* preview render */ - - if (totthread <= 1) { - for (lar=re->lampren.first; lar; lar= lar->next) { - if (re->test_break(re->tbh)) break; - if (lar->shb) { - /* if type is irregular, this only sets the perspective matrix and autoclips */ - makeshadowbuf(re, lar); - } - } - } - else { - /* swap test break function */ - test_break= re->test_break; - re->test_break= thread_break; - - for (lar=re->lampren.first; lar; lar= lar->next) { - lar->thread_assigned= 0; - lar->thread_ready= 0; - } - - BLI_threadpool_init(&threads, do_shadow_thread, totthread); - - for (a=0; a<totthread; a++) - BLI_threadpool_insert(&threads, re); - - /* keep rendering as long as there are shadow buffers not ready */ - do { - if ((g_break=test_break(re->tbh))) - break; - - PIL_sleep_ms(50); - - BLI_thread_lock(LOCK_CUSTOM1); - for (lar=re->lampren.first; lar; lar= lar->next) - if (lar->shb && !lar->thread_ready) - break; - BLI_thread_unlock(LOCK_CUSTOM1); - } while (lar); - - BLI_threadpool_end(&threads); - - /* unset threadsafety */ - re->test_break= test_break; - g_break= 0; - } -} - -void freeshadowbuf(LampRen *lar) -{ - if (lar->shb) { - ShadBuf *shb= lar->shb; - ShadSampleBuf *shsample; - int b, v; - - for (shsample= shb->buffers.first; shsample; shsample= shsample->next) { - if (shsample->deepbuf) { - v= shb->size*shb->size; - for (b=0; b<v; b++) - if (shsample->deepbuf[b]) - MEM_freeN(shsample->deepbuf[b]); - - MEM_freeN(shsample->deepbuf); - MEM_freeN(shsample->totbuf); - } - else { - intptr_t *ztile= shsample->zbuf; - const char *ctile= shsample->cbuf; - - v= (shb->size*shb->size)/256; - for (b=0; b<v; b++, ztile++, ctile++) - if (*ctile) MEM_freeN((void *) *ztile); - - MEM_freeN(shsample->zbuf); - MEM_freeN(shsample->cbuf); - } - } - BLI_freelistN(&shb->buffers); - - if (shb->weight) MEM_freeN(shb->weight); - MEM_freeN(lar->shb); - - lar->shb= NULL; - } -} - - -static int firstreadshadbuf(ShadBuf *shb, ShadSampleBuf *shsample, int **rz, int xs, int ys, int nr) -{ - /* return a 1 if fully compressed shadbuf-tile && z==const */ - int ofs; - const char *ct; - - if (shsample->deepbuf) - return 0; - - /* always test borders of shadowbuffer */ - if (xs<0) xs= 0; else if (xs>=shb->size) xs= shb->size-1; - if (ys<0) ys= 0; else if (ys>=shb->size) ys= shb->size-1; - - /* calc z */ - ofs= (ys>>4)*(shb->size>>4) + (xs>>4); - ct= shsample->cbuf+ofs; - if (*ct==0) { - if (nr==0) { - *rz= *( (int **)(shsample->zbuf+ofs) ); - return 1; - } - else if (*rz!= *( (int **)(shsample->zbuf+ofs) )) return 0; - - return 1; - } - - return 0; -} - -static float readdeepvisibility(DeepSample *dsample, int tot, int z, int bias, float *biast) -{ - DeepSample *ds, *prevds; - float t; - int a; - - /* tricky stuff here; we use ints which can overflow easily with bias values */ - - ds= dsample; - for (a=0; a<tot && (z-bias > ds->z); a++, ds++) {} - - if (a == tot) { - if (biast) - *biast= 0.0f; - return (ds-1)->v; /* completely behind all samples */ - } - - /* check if this read needs bias blending */ - if (biast) { - if (z > ds->z) - *biast= (float)(z - ds->z)/(float)bias; - else - *biast= 0.0f; - } - - if (a == 0) - return 1.0f; /* completely in front of all samples */ - - /* converting to float early here because ds->z - prevds->z can overflow */ - prevds= ds-1; - t= ((float)(z-bias) - (float)prevds->z)/((float)ds->z - (float)prevds->z); - return t*ds->v + (1.0f-t)*prevds->v; -} - -static float readdeepshadowbuf(ShadBuf *shb, ShadSampleBuf *shsample, int bias, int xs, int ys, int zs) -{ - float v, biasv, biast; - int ofs, tot; - - if (zs < - 0x7FFFFE00 + bias) - return 1.0; /* extreme close to clipstart */ - - /* calc z */ - ofs= ys*shb->size + xs; - tot= shsample->totbuf[ofs]; - if (tot == 0) - return 1.0f; - - v= readdeepvisibility(shsample->deepbuf[ofs], tot, zs, bias, &biast); - - if (biast != 0.0f) { - /* in soft bias area */ - biasv = readdeepvisibility(shsample->deepbuf[ofs], tot, zs, 0, NULL); - - biast= biast*biast; - return (1.0f-biast)*v + biast*biasv; - } - - return v; -} - -/* return 1.0 : fully in light */ -static float readshadowbuf(ShadBuf *shb, ShadSampleBuf *shsample, int bias, int xs, int ys, int zs) -{ - float temp; - int *rz, ofs; - int zsamp=0; - char *ct, *cz; - - /* simpleclip */ - /* if (xs<0 || ys<0) return 1.0; */ - /* if (xs>=shb->size || ys>=shb->size) return 1.0; */ - - /* always test borders of shadowbuffer */ - if (xs<0) xs= 0; else if (xs>=shb->size) xs= shb->size-1; - if (ys<0) ys= 0; else if (ys>=shb->size) ys= shb->size-1; - - if (shsample->deepbuf) - return readdeepshadowbuf(shb, shsample, bias, xs, ys, zs); - - /* calc z */ - ofs= (ys>>4)*(shb->size>>4) + (xs>>4); - ct= shsample->cbuf+ofs; - rz= *( (int **)(shsample->zbuf+ofs) ); - - if (*ct==3) { - ct= ((char *)rz)+3*16*(ys & 15)+3*(xs & 15); - cz= (char *)&zsamp; - cz[ACOMP]= ct[0]; - cz[BCOMP]= ct[1]; - cz[GCOMP]= ct[2]; - } - else if (*ct==2) { - ct= ((char *)rz); - ct+= 4+2*16*(ys & 15)+2*(xs & 15); - zsamp= *rz; - - cz= (char *)&zsamp; - cz[BCOMP]= ct[0]; - cz[GCOMP]= ct[1]; - } - else if (*ct==1) { - ct= ((char *)rz); - ct+= 4+16*(ys & 15)+(xs & 15); - zsamp= *rz; - - cz= (char *)&zsamp; - cz[GCOMP]= ct[0]; - - } - else { - /* got warning on this for 64 bits.... */ - /* but it's working code! in this case rz is not a pointer but zvalue (ton) */ - zsamp= GET_INT_FROM_POINTER(rz); - } - - /* tricky stuff here; we use ints which can overflow easily with bias values */ - - if (zsamp > zs) return 1.0; /* absolute no shadow */ - else if (zs < - 0x7FFFFE00 + bias) return 1.0; /* extreme close to clipstart */ - else if (zsamp < zs-bias) return 0.0; /* absolute in shadow */ - else { /* soft area */ - - temp= ( (float)(zs- zsamp) )/(float)bias; - return 1.0f - temp*temp; - - } -} - -static void shadowbuf_project_co(float *x, float *y, float *z, ShadBuf *shb, const float co[3]) -{ - float hco[4], size= 0.5f*(float)shb->size; - - copy_v3_v3(hco, co); - hco[3]= 1.0f; - - mul_m4_v4(shb->persmat, hco); - - *x= size*(1.0f+hco[0]/hco[3]); - *y= size*(1.0f+hco[1]/hco[3]); - if (z) *z= (hco[2]/hco[3]); -} - -/* the externally called shadow testing (reading) function */ -/* return 1.0: no shadow at all */ -float testshadowbuf(Render *re, ShadBuf *shb, const float co[3], const float dxco[3], const float dyco[3], float inp, float mat_bias) -{ - ShadSampleBuf *shsample; - float fac, dco[3], dx[3], dy[3], shadfac=0.0f; - float xs1, ys1, zs1, *jit, *weight, xres, yres, biasf; - int xs, ys, zs, bias, *rz; - short a, num; - - /* crash preventer */ - if (shb->buffers.first==NULL) - return 1.0f; - - /* when facing away, assume fully in shadow */ - if (inp <= 0.0f) - return 0.0f; - - /* project coordinate to pixel space */ - shadowbuf_project_co(&xs1, &ys1, &zs1, shb, co); - - /* clip z coordinate, z is projected so that (-1.0, 1.0) matches - * (clipstart, clipend), so we can do this simple test */ - if (zs1>=1.0f) - return 0.0f; - else if (zs1<= -1.0f) - return 1.0f; - - zs= ((float)0x7FFFFFFF)*zs1; - - /* take num*num samples, increase area with fac */ - num= get_render_shadow_samples(&re->r, shb->samp); - num= num*num; - fac= shb->soft; - - /* compute z bias */ - if (mat_bias!=0.0f) biasf= shb->bias*mat_bias; - else biasf= shb->bias; - /* with inp==1.0, bias is half the size. correction value was 1.1, giving errors - * on cube edges, with one side being almost frontal lighted (ton) */ - bias= (1.5f-inp*inp)*biasf; - - /* in case of no filtering we can do things simpler */ - if (num==1) { - for (shsample= shb->buffers.first; shsample; shsample= shsample->next) - shadfac += readshadowbuf(shb, shsample, bias, (int)xs1, (int)ys1, zs); - - return shadfac/(float)shb->totbuf; - } - - /* calculate filter size */ - add_v3_v3v3(dco, co, dxco); - shadowbuf_project_co(&dx[0], &dx[1], NULL, shb, dco); - dx[0]= xs1 - dx[0]; - dx[1]= ys1 - dx[1]; - - add_v3_v3v3(dco, co, dyco); - shadowbuf_project_co(&dy[0], &dy[1], NULL, shb, dco); - dy[0]= xs1 - dy[0]; - dy[1]= ys1 - dy[1]; - - xres = fac * (fabsf(dx[0]) + fabsf(dy[0])); - yres = fac * (fabsf(dx[1]) + fabsf(dy[1])); - if (xres<1.0f) xres= 1.0f; - if (yres<1.0f) yres= 1.0f; - - /* make xs1/xs1 corner of sample area */ - xs1 -= xres*0.5f; - ys1 -= yres*0.5f; - - /* in case we have a constant value in a tile, we can do quicker lookup */ - if (xres<16.0f && yres<16.0f) { - shsample= shb->buffers.first; - if (firstreadshadbuf(shb, shsample, &rz, (int)xs1, (int)ys1, 0)) { - if (firstreadshadbuf(shb, shsample, &rz, (int)(xs1+xres), (int)ys1, 1)) { - if (firstreadshadbuf(shb, shsample, &rz, (int)xs1, (int)(ys1+yres), 1)) { - if (firstreadshadbuf(shb, shsample, &rz, (int)(xs1+xres), (int)(ys1+yres), 1)) { - return readshadowbuf(shb, shsample, bias, (int)xs1, (int)ys1, zs); - } - } - } - } - } - - /* full jittered shadow buffer lookup */ - for (shsample= shb->buffers.first; shsample; shsample= shsample->next) { - jit= shb->jit; - weight= shb->weight; - - for (a=num; a>0; a--, jit+=2, weight++) { - /* instead of jit i tried random: ugly! */ - /* note: the plus 0.5 gives best sampling results, jit goes from -0.5 to 0.5 */ - /* xs1 and ys1 are already corrected to be corner of sample area */ - xs= xs1 + xres*(jit[0] + 0.5f); - ys= ys1 + yres*(jit[1] + 0.5f); - - shadfac+= *weight * readshadowbuf(shb, shsample, bias, xs, ys, zs); - } - } - - /* Renormalizes for the sample number: */ - return shadfac/(float)shb->totbuf; -} - -/* different function... sampling behind clipend can be LIGHT, bias is negative! */ -/* return: light */ -static float readshadowbuf_halo(ShadBuf *shb, ShadSampleBuf *shsample, int xs, int ys, int zs) -{ - float temp; - int *rz, ofs; - int bias, zbias, zsamp; - char *ct, *cz; - - /* negative! The other side is more important */ - bias= -shb->bias; - - /* simpleclip */ - if (xs<0 || ys<0) return 0.0; - if (xs>=shb->size || ys>=shb->size) return 0.0; - - /* calc z */ - ofs= (ys>>4)*(shb->size>>4) + (xs>>4); - ct= shsample->cbuf+ofs; - rz= *( (int **)(shsample->zbuf+ofs) ); - - if (*ct==3) { - ct= ((char *)rz)+3*16*(ys & 15)+3*(xs & 15); - cz= (char *)&zsamp; - zsamp= 0; - cz[ACOMP]= ct[0]; - cz[BCOMP]= ct[1]; - cz[GCOMP]= ct[2]; - } - else if (*ct==2) { - ct= ((char *)rz); - ct+= 4+2*16*(ys & 15)+2*(xs & 15); - zsamp= *rz; - - cz= (char *)&zsamp; - cz[BCOMP]= ct[0]; - cz[GCOMP]= ct[1]; - } - else if (*ct==1) { - ct= ((char *)rz); - ct+= 4+16*(ys & 15)+(xs & 15); - zsamp= *rz; - - cz= (char *)&zsamp; - cz[GCOMP]= ct[0]; - - } - else { - /* same as before */ - /* still working code! (ton) */ - zsamp= GET_INT_FROM_POINTER(rz); - } - - /* NO schadow when sampled at 'eternal' distance */ - - if (zsamp >= 0x7FFFFE00) return 1.0; - - if (zsamp > zs) return 1.0; /* absolute no shadww */ - else { - /* bias is negative, so the (zs-bias) can be beyond 0x7fffffff */ - zbias= 0x7fffffff - zs; - if (zbias > -bias) { - if ( zsamp < zs-bias) return 0.0; /* absolute in shadow */ - } - else return 0.0; /* absolute shadow */ - } - - /* soft area */ - - temp= ( (float)(zs- zsamp) )/(float)bias; - return 1.0f - temp*temp; -} - - -float shadow_halo(LampRen *lar, const float p1[3], const float p2[3]) -{ - /* p1 p2 already are rotated in spot-space */ - ShadBuf *shb= lar->shb; - ShadSampleBuf *shsample; - float co[4], siz; - float lambda, lambda_o, lambda_x, lambda_y, ldx, ldy; - float zf, xf1, yf1, zf1, xf2, yf2, zf2; - float count, lightcount; - int x, y, z, xs1, ys1; - int dx = 0, dy = 0; - - siz= 0.5f*(float)shb->size; - - co[0]= p1[0]; - co[1]= p1[1]; - co[2]= p1[2]/lar->sh_zfac; - co[3]= 1.0; - mul_m4_v4(shb->winmat, co); /* rational hom co */ - xf1= siz*(1.0f+co[0]/co[3]); - yf1= siz*(1.0f+co[1]/co[3]); - zf1= (co[2]/co[3]); - - - co[0]= p2[0]; - co[1]= p2[1]; - co[2]= p2[2]/lar->sh_zfac; - co[3]= 1.0; - mul_m4_v4(shb->winmat, co); /* rational hom co */ - xf2= siz*(1.0f+co[0]/co[3]); - yf2= siz*(1.0f+co[1]/co[3]); - zf2= (co[2]/co[3]); - - /* the 2dda (a pixel line formula) */ - - xs1= (int)xf1; - ys1= (int)yf1; - - if (xf1 != xf2) { - if (xf2-xf1 > 0.0f) { - lambda_x= (xf1-xs1-1.0f)/(xf1-xf2); - ldx= -shb->shadhalostep/(xf1-xf2); - dx= shb->shadhalostep; - } - else { - lambda_x= (xf1-xs1)/(xf1-xf2); - ldx= shb->shadhalostep/(xf1-xf2); - dx= -shb->shadhalostep; - } - } - else { - lambda_x= 1.0; - ldx= 0.0; - } - - if (yf1 != yf2) { - if (yf2-yf1 > 0.0f) { - lambda_y= (yf1-ys1-1.0f)/(yf1-yf2); - ldy= -shb->shadhalostep/(yf1-yf2); - dy= shb->shadhalostep; - } - else { - lambda_y= (yf1-ys1)/(yf1-yf2); - ldy= shb->shadhalostep/(yf1-yf2); - dy= -shb->shadhalostep; - } - } - else { - lambda_y= 1.0; - ldy= 0.0; - } - - x= xs1; - y= ys1; - lambda= count= lightcount= 0.0; - -/* printf("start %x %x \n", (int)(0x7FFFFFFF*zf1), (int)(0x7FFFFFFF*zf2)); */ - - do { - lambda_o= lambda; - - if (lambda_x==lambda_y) { - lambda_x+= ldx; - x+= dx; - lambda_y+= ldy; - y+= dy; - } - else { - if (lambda_x<lambda_y) { - lambda_x+= ldx; - x+= dx; - } - else { - lambda_y+= ldy; - y+= dy; - } - } - - lambda = min_ff(lambda_x, lambda_y); - - /* not making any progress? */ - if (lambda==lambda_o) break; - - /* clip to end of volume */ - lambda = min_ff(lambda, 1.0f); - - zf= zf1 + lambda*(zf2-zf1); - count+= (float)shb->totbuf; - - if (zf<= -1.0f) lightcount += 1.0f; /* close to the spot */ - else { - - /* make sure, behind the clipend we extend halolines. */ - if (zf>=1.0f) z= 0x7FFFF000; - else z= (int)(0x7FFFF000*zf); - - for (shsample= shb->buffers.first; shsample; shsample= shsample->next) - lightcount+= readshadowbuf_halo(shb, shsample, x, y, z); - - } - } - while (lambda < 1.0f); - - if (count!=0.0f) return (lightcount/count); - return 0.0f; - -} - - -/* ********************* Irregular Shadow Buffer (ISB) ************* */ -/* ********** storage of all view samples in a raster of lists ***** */ - -/* based on several articles describing this method, like: - * The Irregular Z-Buffer and its Application to Shadow Mapping - * Gregory S. Johnson - William R. Mark - Christopher A. Burns - * and - * Alias-Free Shadow Maps - * Timo Aila and Samuli Laine - */ - -/* bsp structure (actually kd tree) */ - -#define BSPMAX_SAMPLE 128 -#define BSPMAX_DEPTH 32 - -/* aligned with struct rctf */ -typedef struct Boxf { - float xmin, xmax; - float ymin, ymax; - float zmin, zmax; -} Boxf; - -typedef struct ISBBranch { - struct ISBBranch *left, *right; - float divider[2]; - Boxf box; - short totsamp, index, full, unused; - ISBSample **samples; -} ISBBranch; - -typedef struct BSPFace { - Boxf box; - const float *v1, *v2, *v3, *v4; - int obi; /* object for face lookup */ - int facenr; /* index to retrieve VlakRen */ - int type; /* only for strand now */ - short shad_alpha, is_full; - - /* strand caching data, optimize for point_behind_strand() */ - float radline, radline_end, len; - float vec1[3], vec2[3], rc[3]; -} BSPFace; - -/* boxes are in lamp projection */ -static void init_box(Boxf *box) -{ - box->xmin = 1000000.0f; - box->xmax = 0; - box->ymin = 1000000.0f; - box->ymax = 0; - box->zmin= 0x7FFFFFFF; - box->zmax= - 0x7FFFFFFF; -} - -/* use v1 to calculate boundbox */ -static void bound_boxf(Boxf *box, const float v1[3]) -{ - if (v1[0] < box->xmin) box->xmin = v1[0]; - if (v1[0] > box->xmax) box->xmax = v1[0]; - if (v1[1] < box->ymin) box->ymin = v1[1]; - if (v1[1] > box->ymax) box->ymax = v1[1]; - if (v1[2] < box->zmin) box->zmin= v1[2]; - if (v1[2] > box->zmax) box->zmax= v1[2]; -} - -/* use v1 to calculate boundbox */ -static void bound_rectf(rctf *box, const float v1[2]) -{ - if (v1[0] < box->xmin) box->xmin = v1[0]; - if (v1[0] > box->xmax) box->xmax = v1[0]; - if (v1[1] < box->ymin) box->ymin = v1[1]; - if (v1[1] > box->ymax) box->ymax = v1[1]; -} - - -/* halfway splitting, for initializing a more regular tree */ -static void isb_bsp_split_init(ISBBranch *root, MemArena *mem, int level) -{ - - /* if level > 0 we create new branches and go deeper */ - if (level > 0) { - ISBBranch *left, *right; - int i; - - /* splitpoint */ - root->divider[0]= 0.5f*(root->box.xmin+root->box.xmax); - root->divider[1]= 0.5f*(root->box.ymin+root->box.ymax); - - /* find best splitpoint */ - if (RCT_SIZE_X(&root->box) > RCT_SIZE_Y(&root->box)) - i = root->index = 0; - else - i = root->index = 1; - - left= root->left= BLI_memarena_alloc(mem, sizeof(ISBBranch)); - right= root->right= BLI_memarena_alloc(mem, sizeof(ISBBranch)); - - /* box info */ - left->box= root->box; - right->box= root->box; - if (i==0) { - left->box.xmax = root->divider[0]; - right->box.xmin = root->divider[0]; - } - else { - left->box.ymax = root->divider[1]; - right->box.ymin = root->divider[1]; - } - isb_bsp_split_init(left, mem, level-1); - isb_bsp_split_init(right, mem, level-1); - } - else { - /* we add sample array */ - root->samples= BLI_memarena_alloc(mem, BSPMAX_SAMPLE*sizeof(void *)); - } -} - -/* note; if all samples on same location we just spread them over 2 new branches */ -static void isb_bsp_split(ISBBranch *root, MemArena *mem) -{ - ISBBranch *left, *right; - ISBSample *samples[BSPMAX_SAMPLE]; - int a, i; - - /* splitpoint */ - root->divider[0]= root->divider[1]= 0.0f; - for (a=BSPMAX_SAMPLE-1; a>=0; a--) { - root->divider[0]+= root->samples[a]->zco[0]; - root->divider[1]+= root->samples[a]->zco[1]; - } - root->divider[0]/= BSPMAX_SAMPLE; - root->divider[1]/= BSPMAX_SAMPLE; - - /* find best splitpoint */ - if (RCT_SIZE_X(&root->box) > RCT_SIZE_Y(&root->box)) - i = root->index = 0; - else - i = root->index = 1; - - /* new branches */ - left= root->left= BLI_memarena_alloc(mem, sizeof(ISBBranch)); - right= root->right= BLI_memarena_alloc(mem, sizeof(ISBBranch)); - - /* new sample array */ - left->samples = BLI_memarena_alloc(mem, BSPMAX_SAMPLE*sizeof(void *)); - right->samples = samples; /* tmp */ - - /* split samples */ - for (a=BSPMAX_SAMPLE-1; a>=0; a--) { - int comp= 0; - /* this prevents adding samples all to 1 branch when divider is equal to samples */ - if (root->samples[a]->zco[i] == root->divider[i]) - comp= a & 1; - else if (root->samples[a]->zco[i] < root->divider[i]) - comp= 1; - - if (comp==1) { - left->samples[left->totsamp]= root->samples[a]; - left->totsamp++; - } - else { - right->samples[right->totsamp]= root->samples[a]; - right->totsamp++; - } - } - - /* copy samples from tmp */ - memcpy(root->samples, samples, right->totsamp*(sizeof(void *))); - right->samples= root->samples; - root->samples= NULL; - - /* box info */ - left->box= root->box; - right->box= root->box; - if (i==0) { - left->box.xmax = root->divider[0]; - right->box.xmin = root->divider[0]; - } - else { - left->box.ymax = root->divider[1]; - right->box.ymin = root->divider[1]; - } -} - -/* inserts sample in main tree, also splits on threshold */ -/* returns 1 if error */ -static int isb_bsp_insert(ISBBranch *root, MemArena *memarena, ISBSample *sample) -{ - ISBBranch *bspn= root; - const float *zco= sample->zco; - int i= 0; - - /* debug counter, also used to check if something was filled in ever */ - root->totsamp++; - - /* going over branches until last one found */ - while (bspn->left) { - if (zco[bspn->index] <= bspn->divider[bspn->index]) - bspn= bspn->left; - else - bspn= bspn->right; - i++; - } - /* bspn now is the last branch */ - - if (bspn->totsamp==BSPMAX_SAMPLE) { - printf("error in bsp branch\n"); /* only for debug, cannot happen */ - return 1; - } - - /* insert */ - bspn->samples[bspn->totsamp]= sample; - bspn->totsamp++; - - /* split if allowed and needed */ - if (bspn->totsamp==BSPMAX_SAMPLE) { - if (i==BSPMAX_DEPTH) { - bspn->totsamp--; /* stop filling in... will give errors */ - return 1; - } - isb_bsp_split(bspn, memarena); - } - return 0; -} - -/* initialize vars in face, for optimal point-in-face test */ -static void bspface_init_strand(BSPFace *face) -{ - - face->radline= 0.5f* len_v2v2(face->v1, face->v2); - - mid_v3_v3v3(face->vec1, face->v1, face->v2); - if (face->v4) - mid_v3_v3v3(face->vec2, face->v3, face->v4); - else - copy_v3_v3(face->vec2, face->v3); - - face->rc[0]= face->vec2[0]-face->vec1[0]; - face->rc[1]= face->vec2[1]-face->vec1[1]; - face->rc[2]= face->vec2[2]-face->vec1[2]; - - face->len= face->rc[0]*face->rc[0]+ face->rc[1]*face->rc[1]; - - if (face->len != 0.0f) { - face->radline_end = face->radline / sqrtf(face->len); - face->len = 1.0f / face->len; - } -} - -/* brought back to a simple 2d case */ -static int point_behind_strand(const float p[3], BSPFace *face) -{ - /* v1 - v2 is radius, v1 - v3 length */ - float dist, rc[2], pt[2]; - - /* using code from dist_to_line_segment_v2(), distance vec to line-piece */ - - if (face->len==0.0f) { - rc[0]= p[0]-face->vec1[0]; - rc[1]= p[1]-face->vec1[1]; - dist = len_v2(rc); - - if (dist < face->radline) - return 1; - } - else { - float lambda= ( face->rc[0]*(p[0]-face->vec1[0]) + face->rc[1]*(p[1]-face->vec1[1]) )*face->len; - - if (lambda > -face->radline_end && lambda < 1.0f+face->radline_end) { - /* hesse for dist: */ - //dist= (float)(fabs( (p[0]-vec2[0])*rc[1] + (p[1]-vec2[1])*rc[0])/len); - - pt[0]= lambda*face->rc[0]+face->vec1[0]; - pt[1]= lambda*face->rc[1]+face->vec1[1]; - - rc[0]= pt[0]-p[0]; - rc[1]= pt[1]-p[1]; - dist = len_v2(rc); - - if (dist < face->radline) { - float zval= face->vec1[2] + lambda*face->rc[2]; - if (p[2] > zval) - return 1; - } - } - } - return 0; -} - - -/* return 1 if inside. code derived from src/parametrizer.c */ -static int point_behind_tria2d(const float p[3], const float v1[3], const float v2[3], const float v3[3]) -{ - float a[2], c[2], h[2], div; - float u, v; - - a[0] = v2[0] - v1[0]; - a[1] = v2[1] - v1[1]; - c[0] = v3[0] - v1[0]; - c[1] = v3[1] - v1[1]; - - div = a[0]*c[1] - a[1]*c[0]; - if (div==0.0f) - return 0; - - h[0] = p[0] - v1[0]; - h[1] = p[1] - v1[1]; - - div = 1.0f/div; - - u = (h[0]*c[1] - h[1]*c[0])*div; - if (u >= 0.0f) { - v = (a[0]*h[1] - a[1]*h[0])*div; - if (v >= 0.0f) { - if ( u + v <= 1.0f) { - /* inside, now check if point p is behind */ - float z= (1.0f-u-v)*v1[2] + u*v2[2] + v*v3[2]; - if (z <= p[2]) - return 1; - } - } - } - - return 0; -} - -#if 0 -/* tested these calls, but it gives inaccuracy, 'side' cannot be found reliably using v3 */ - -/* check if line v1-v2 has all rect points on other side of point v3 */ -static int rect_outside_line(rctf *rect, const float v1[3], const float v2[3], const float v3[3]) -{ - float a, b, c; - int side; - - /* line formula for v1-v2 */ - a= v2[1]-v1[1]; - b= v1[0]-v2[0]; - c= -a*v1[0] - b*v1[1]; - side= a*v3[0] + b*v3[1] + c < 0.0f; - - /* the four quad points */ - if ( side==(rect->xmin*a + rect->ymin*b + c >= 0.0f) ) - if ( side==(rect->xmax*a + rect->ymin*b + c >= 0.0f) ) - if ( side==(rect->xmax*a + rect->ymax*b + c >= 0.0f) ) - if ( side==(rect->xmin*a + rect->ymax*b + c >= 0.0f) ) - return 1; - return 0; -} - -/* check if one of the triangle edges separates all rect points on 1 side */ -static int rect_isect_tria(rctf *rect, const float v1[3], const float v2[3], const float v3[3]) -{ - if (rect_outside_line(rect, v1, v2, v3)) - return 0; - if (rect_outside_line(rect, v2, v3, v1)) - return 0; - if (rect_outside_line(rect, v3, v1, v2)) - return 0; - return 1; -} -#endif - -/* if face overlaps a branch, it executes func. recursive */ -static void isb_bsp_face_inside(ISBBranch *bspn, BSPFace *face) -{ - - /* are we descending? */ - if (bspn->left) { - /* hrmf, the box struct cannot be addressed with index */ - if (bspn->index==0) { - if (face->box.xmin <= bspn->divider[0]) - isb_bsp_face_inside(bspn->left, face); - if (face->box.xmax > bspn->divider[0]) - isb_bsp_face_inside(bspn->right, face); - } - else { - if (face->box.ymin <= bspn->divider[1]) - isb_bsp_face_inside(bspn->left, face); - if (face->box.ymax > bspn->divider[1]) - isb_bsp_face_inside(bspn->right, face); - } - } - else { - /* else: end branch reached */ - int a; - - if (bspn->totsamp==0) return; - - /* check for nodes entirely in shadow, can be skipped */ - if (bspn->totsamp==bspn->full) - return; - - /* if bsp node is entirely in front of face, give up */ - if (bspn->box.zmax < face->box.zmin) - return; - - /* if face boundbox is outside of branch rect, give up */ - if (0==BLI_rctf_isect((rctf *)&face->box, (rctf *)&bspn->box, NULL)) - return; - - /* test all points inside branch */ - for (a=bspn->totsamp-1; a>=0; a--) { - ISBSample *samp= bspn->samples[a]; - - if ((samp->facenr!=face->facenr || samp->obi!=face->obi) && samp->shadfac) { - if (face->box.zmin < samp->zco[2]) { - if (BLI_rctf_isect_pt_v((rctf *)&face->box, samp->zco)) { - int inshadow= 0; - - if (face->type) { - if (point_behind_strand(samp->zco, face)) - inshadow= 1; - } - else if ( point_behind_tria2d(samp->zco, face->v1, face->v2, face->v3)) - inshadow= 1; - else if (face->v4 && point_behind_tria2d(samp->zco, face->v1, face->v3, face->v4)) - inshadow= 1; - - if (inshadow) { - *(samp->shadfac) += face->shad_alpha; - /* optimize; is_full means shad_alpha==4096 */ - if (*(samp->shadfac) >= 4096 || face->is_full) { - bspn->full++; - samp->shadfac= NULL; - } - } - } - } - } - } - } -} - -/* based on available samples, recalculate the bounding box for bsp nodes, recursive */ -static void isb_bsp_recalc_box(ISBBranch *root) -{ - if (root->left) { - isb_bsp_recalc_box(root->left); - isb_bsp_recalc_box(root->right); - } - else if (root->totsamp) { - int a; - - init_box(&root->box); - for (a=root->totsamp-1; a>=0; a--) - bound_boxf(&root->box, root->samples[a]->zco); - } -} - -/* callback function for zbuf clip */ -static void isb_bsp_test_strand(ZSpan *zspan, int obi, int zvlnr, - const float *v1, const float *v2, const float *v3, const float *v4) -{ - BSPFace face; - - face.v1= v1; - face.v2= v2; - face.v3= v3; - face.v4= v4; - face.obi= obi; - face.facenr= zvlnr & ~RE_QUAD_OFFS; - face.type= R_STRAND; - if (R.osa) - face.shad_alpha= (short)ceil(4096.0f*zspan->shad_alpha/(float)R.osa); - else - face.shad_alpha= (short)ceil(4096.0f*zspan->shad_alpha); - - face.is_full= (zspan->shad_alpha==1.0f); - - /* setup boundbox */ - init_box(&face.box); - bound_boxf(&face.box, v1); - bound_boxf(&face.box, v2); - bound_boxf(&face.box, v3); - if (v4) - bound_boxf(&face.box, v4); - - /* optimize values */ - bspface_init_strand(&face); - - isb_bsp_face_inside((ISBBranch *)zspan->rectz, &face); - -} - -/* callback function for zbuf clip */ -static void isb_bsp_test_face(ZSpan *zspan, int obi, int zvlnr, - const float *v1, const float *v2, const float *v3, const float *v4) -{ - BSPFace face; - - face.v1= v1; - face.v2= v2; - face.v3= v3; - face.v4= v4; - face.obi= obi; - face.facenr= zvlnr & ~RE_QUAD_OFFS; - face.type= 0; - if (R.osa) - face.shad_alpha= (short)ceil(4096.0f*zspan->shad_alpha/(float)R.osa); - else - face.shad_alpha= (short)ceil(4096.0f*zspan->shad_alpha); - - face.is_full= (zspan->shad_alpha==1.0f); - - /* setup boundbox */ - init_box(&face.box); - bound_boxf(&face.box, v1); - bound_boxf(&face.box, v2); - bound_boxf(&face.box, v3); - if (v4) - bound_boxf(&face.box, v4); - - isb_bsp_face_inside((ISBBranch *)zspan->rectz, &face); -} - -static int testclip_minmax(const float ho[4], const float minmax[4]) -{ - float wco= ho[3]; - int flag= 0; - - if ( ho[0] > minmax[1]*wco) flag = 1; - else if ( ho[0]< minmax[0]*wco) flag = 2; - - if ( ho[1] > minmax[3]*wco) flag |= 4; - else if ( ho[1]< minmax[2]*wco) flag |= 8; - - return flag; -} - -/* main loop going over all faces and check in bsp overlaps, fill in shadfac values */ -static void isb_bsp_fillfaces(Render *re, LampRen *lar, ISBBranch *root) -{ - ObjectInstanceRen *obi; - ObjectRen *obr; - ShadBuf *shb= lar->shb; - ZSpan zspan, zspanstrand; - VlakRen *vlr= NULL; - Material *ma= NULL; - float minmaxf[4], winmat[4][4]; - int size= shb->size; - int i, a, ok=1, lay= -1; - - /* further optimize, also sets minz maxz */ - isb_bsp_recalc_box(root); - - /* extra clipping for minmax */ - minmaxf[0]= (2.0f*root->box.xmin - size-2.0f)/size; - minmaxf[1]= (2.0f*root->box.xmax - size+2.0f)/size; - minmaxf[2]= (2.0f*root->box.ymin - size-2.0f)/size; - minmaxf[3]= (2.0f*root->box.ymax - size+2.0f)/size; - - if (lar->mode & (LA_LAYER|LA_LAYER_SHADOW)) lay= lar->lay; - - /* (ab)use zspan, since we use zbuffer clipping code */ - zbuf_alloc_span(&zspan, size, size, re->clipcrop); - - zspan.zmulx= ((float)size)/2.0f; - zspan.zmuly= ((float)size)/2.0f; - zspan.zofsx= -0.5f; - zspan.zofsy= -0.5f; - - /* pass on bsp root to zspan */ - zspan.rectz= (int *)root; - - /* filling methods */ - zspanstrand= zspan; - // zspan.zbuflinefunc= zbufline_onlyZ; - zspan.zbuffunc= isb_bsp_test_face; - zspanstrand.zbuffunc= isb_bsp_test_strand; - - for (i=0, obi=re->instancetable.first; obi; i++, obi=obi->next) { - obr= obi->obr; - - if (obi->flag & R_TRANSFORMED) - mul_m4_m4m4(winmat, shb->persmat, obi->mat); - else - copy_m4_m4(winmat, shb->persmat); - - for (a=0; a<obr->totvlak; a++) { - - if ((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; - else vlr++; - - /* note, these conditions are copied in shadowbuf_autoclip() */ - if (vlr->mat!= ma) { - ma= vlr->mat; - ok= 1; - if ((ma->mode2 & MA_CASTSHADOW)==0 || (ma->mode & MA_SHADBUF)==0) ok= 0; - if (ma->material_type == MA_TYPE_WIRE) ok= 0; - zspanstrand.shad_alpha= zspan.shad_alpha= ma->shad_alpha; - } - - if (ok && (obi->lay & lay)) { - float hoco[4][4]; - int c1, c2, c3, c4=0; - int d1, d2, d3, d4=0; - int partclip; - - /* create hocos per face, it is while render */ - projectvert(vlr->v1->co, winmat, hoco[0]); d1= testclip_minmax(hoco[0], minmaxf); - projectvert(vlr->v2->co, winmat, hoco[1]); d2= testclip_minmax(hoco[1], minmaxf); - projectvert(vlr->v3->co, winmat, hoco[2]); d3= testclip_minmax(hoco[2], minmaxf); - if (vlr->v4) { - projectvert(vlr->v4->co, winmat, hoco[3]); d4= testclip_minmax(hoco[3], minmaxf); - } - - /* minmax clipping */ - if (vlr->v4) partclip= d1 & d2 & d3 & d4; - else partclip= d1 & d2 & d3; - - if (partclip==0) { - - /* window clipping */ - c1= testclip(hoco[0]); - c2= testclip(hoco[1]); - c3= testclip(hoco[2]); - if (vlr->v4) - c4= testclip(hoco[3]); - - /* ***** NO WIRE YET */ - if (ma->material_type == MA_TYPE_WIRE) { - if (vlr->v4) - zbufclipwire(&zspan, i, a+1, vlr->ec, hoco[0], hoco[1], hoco[2], hoco[3], c1, c2, c3, c4); - else - zbufclipwire(&zspan, i, a+1, vlr->ec, hoco[0], hoco[1], hoco[2], NULL, c1, c2, c3, 0); - } - else if (vlr->v4) { - if (vlr->flag & R_STRAND) - zbufclip4(&zspanstrand, i, a+1, hoco[0], hoco[1], hoco[2], hoco[3], c1, c2, c3, c4); - else - zbufclip4(&zspan, i, a+1, hoco[0], hoco[1], hoco[2], hoco[3], c1, c2, c3, c4); - } - else - zbufclip(&zspan, i, a+1, hoco[0], hoco[1], hoco[2], c1, c2, c3); - - } - } - } - } - - zbuf_free_span(&zspan); -} - -/* returns 1 when the viewpixel is visible in lampbuffer */ -static int viewpixel_to_lampbuf(ShadBuf *shb, ObjectInstanceRen *obi, VlakRen *vlr, float x, float y, float co_r[3]) -{ - float hoco[4], v1[3], nor[3]; - float dface, fac, siz; - - RE_vlakren_get_normal(&R, obi, vlr, nor); - copy_v3_v3(v1, vlr->v1->co); - if (obi->flag & R_TRANSFORMED) - mul_m4_v3(obi->mat, v1); - - /* from shadepixel() */ - dface = dot_v3v3(v1, nor); - hoco[3]= 1.0f; - - /* ortho viewplane cannot intersect using view vector originating in (0, 0, 0) */ - if (R.r.mode & R_ORTHO) { - /* x and y 3d coordinate can be derived from pixel coord and winmat */ - float fx= 2.0f/(R.winx*R.winmat[0][0]); - float fy= 2.0f/(R.winy*R.winmat[1][1]); - - hoco[0]= (x - 0.5f*R.winx)*fx - R.winmat[3][0]/R.winmat[0][0]; - hoco[1]= (y - 0.5f*R.winy)*fy - R.winmat[3][1]/R.winmat[1][1]; - - /* using a*x + b*y + c*z = d equation, (a b c) is normal */ - if (nor[2]!=0.0f) - hoco[2]= (dface - nor[0]*hoco[0] - nor[1]*hoco[1])/nor[2]; - else - hoco[2]= 0.0f; - } - else { - float div, view[3]; - - calc_view_vector(view, x, y); - - div = dot_v3v3(nor, view); - if (div==0.0f) - return 0; - - fac= dface/div; - - hoco[0]= fac*view[0]; - hoco[1]= fac*view[1]; - hoco[2]= fac*view[2]; - } - - /* move 3d vector to lampbuf */ - mul_m4_v4(shb->persmat, hoco); /* rational hom co */ - - /* clip We can test for -1.0/1.0 because of the properties of the - * coordinate transformations. */ - fac = fabsf(hoco[3]); - if (hoco[0]<-fac || hoco[0]>fac) - return 0; - if (hoco[1]<-fac || hoco[1]>fac) - return 0; - if (hoco[2]<-fac || hoco[2]>fac) - return 0; - - siz= 0.5f*(float)shb->size; - co_r[0]= siz*(1.0f+hoco[0]/hoco[3]) -0.5f; - co_r[1]= siz*(1.0f+hoco[1]/hoco[3]) -0.5f; - co_r[2]= ((float)0x7FFFFFFF)*(hoco[2]/hoco[3]); - - /* XXXX bias, much less than normal shadbuf, or do we need a constant? */ - co_r[2] -= 0.05f*shb->bias; - - return 1; -} - -/* storage of shadow results, solid osa and transp case */ -static void isb_add_shadfac(ISBShadfacA **isbsapp, MemArena *mem, int obi, int facenr, short shadfac, short samples) -{ - ISBShadfacA *new; - float shadfacf; - - /* in osa case, the samples were filled in with factor 1.0/R.osa. if fewer samples we have to correct */ - if (R.osa) - shadfacf= ((float)shadfac*R.osa)/(4096.0f*samples); - else - shadfacf= ((float)shadfac)/(4096.0f); - - new= BLI_memarena_alloc(mem, sizeof(ISBShadfacA)); - new->obi= obi; - new->facenr= facenr & ~RE_QUAD_OFFS; - new->shadfac= shadfacf; - if (*isbsapp) - new->next= (*isbsapp); - else - new->next= NULL; - - *isbsapp= new; -} - -/* adding samples, solid case */ -static int isb_add_samples(RenderPart *pa, ISBBranch *root, MemArena *memarena, ISBSample **samplebuf) -{ - int xi, yi, *xcos, *ycos; - int sample, bsp_err= 0; - - /* bsp split doesn't like to handle regular sequences */ - xcos= MEM_mallocN(pa->rectx*sizeof(int), "xcos"); - ycos= MEM_mallocN(pa->recty*sizeof(int), "ycos"); - for (xi=0; xi<pa->rectx; xi++) - xcos[xi]= xi; - for (yi=0; yi<pa->recty; yi++) - ycos[yi]= yi; - BLI_array_randomize(xcos, sizeof(int), pa->rectx, 12345); - BLI_array_randomize(ycos, sizeof(int), pa->recty, 54321); - - for (sample=0; sample<(R.osa?R.osa:1); sample++) { - ISBSample *samp= samplebuf[sample], *samp1; - - for (yi=0; yi<pa->recty; yi++) { - int y= ycos[yi]; - for (xi=0; xi<pa->rectx; xi++) { - int x= xcos[xi]; - samp1= samp + y*pa->rectx + x; - if (samp1->facenr) - bsp_err |= isb_bsp_insert(root, memarena, samp1); - } - if (bsp_err) break; - } - } - - MEM_freeN(xcos); - MEM_freeN(ycos); - - return bsp_err; -} - -/* solid version */ -/* lar->shb, pa->rectz and pa->rectp should exist */ -static void isb_make_buffer(RenderPart *pa, LampRen *lar) -{ - ShadBuf *shb= lar->shb; - ISBData *isbdata; - ISBSample *samp, *samplebuf[16]; /* should be RE_MAX_OSA */ - ISBBranch root; - MemArena *memarena; - intptr_t *rd; - int *recto, *rectp, x, y, sindex, sample, bsp_err=0; - - /* storage for shadow, per thread */ - isbdata= shb->isb_result[pa->thread]; - - /* to map the shi->xs and ys coordinate */ - isbdata->minx= pa->disprect.xmin; - isbdata->miny= pa->disprect.ymin; - isbdata->rectx= pa->rectx; - isbdata->recty= pa->recty; - - /* branches are added using memarena (32k branches) */ - memarena = BLI_memarena_new(0x8000 * sizeof(ISBBranch), "isb arena"); - BLI_memarena_use_calloc(memarena); - - /* samplebuf is in camera view space (pixels) */ - for (sample=0; sample<(R.osa?R.osa:1); sample++) - samplebuf[sample]= MEM_callocN(sizeof(ISBSample)*pa->rectx*pa->recty, "isb samplebuf"); - - /* for end result, ISBSamples point to this in non OSA case, otherwise to pixstruct->shadfac */ - if (R.osa==0) - isbdata->shadfacs= MEM_callocN(pa->rectx*pa->recty*sizeof(short), "isb shadfacs"); - - /* setup bsp root */ - memset(&root, 0, sizeof(ISBBranch)); - root.box.xmin = (float)shb->size; - root.box.ymin = (float)shb->size; - - /* create the sample buffers */ - for (sindex=0, y=0; y<pa->recty; y++) { - for (x=0; x<pa->rectx; x++, sindex++) { - - /* this makes it a long function, but splitting it out would mean 10+ arguments */ - /* first check OSA case */ - if (R.osa) { - rd= pa->rectdaps + sindex; - if (*rd) { - float xs= (float)(x + pa->disprect.xmin); - float ys= (float)(y + pa->disprect.ymin); - - for (sample=0; sample<R.osa; sample++) { - PixStr *ps= (PixStr *)(*rd); - int mask= (1<<sample); - - while (ps) { - if (ps->mask & mask) - break; - ps= ps->next; - } - if (ps && ps->facenr>0) { - ObjectInstanceRen *obi= &R.objectinstance[ps->obi]; - ObjectRen *obr= obi->obr; - VlakRen *vlr= RE_findOrAddVlak(obr, (ps->facenr-1) & RE_QUAD_MASK); - - samp= samplebuf[sample] + sindex; - /* convert image plane pixel location to lamp buffer space */ - if (viewpixel_to_lampbuf(shb, obi, vlr, xs + R.jit[sample][0], ys + R.jit[sample][1], samp->zco)) { - samp->obi= ps->obi; - samp->facenr= ps->facenr & ~RE_QUAD_OFFS; - ps->shadfac= 0; - samp->shadfac= &ps->shadfac; - bound_rectf((rctf *)&root.box, samp->zco); - } - } - } - } - } - else { - rectp= pa->rectp + sindex; - recto= pa->recto + sindex; - if (*rectp>0) { - ObjectInstanceRen *obi= &R.objectinstance[*recto]; - ObjectRen *obr= obi->obr; - VlakRen *vlr= RE_findOrAddVlak(obr, (*rectp-1) & RE_QUAD_MASK); - float xs= (float)(x + pa->disprect.xmin); - float ys= (float)(y + pa->disprect.ymin); - - samp= samplebuf[0] + sindex; - /* convert image plane pixel location to lamp buffer space */ - if (viewpixel_to_lampbuf(shb, obi, vlr, xs, ys, samp->zco)) { - samp->obi= *recto; - samp->facenr= *rectp & ~RE_QUAD_OFFS; - samp->shadfac= isbdata->shadfacs + sindex; - bound_rectf((rctf *)&root.box, samp->zco); - } - } - } - } - } - - /* simple method to see if we have samples */ - if (root.box.xmin != (float)shb->size) { - /* now create a regular split, root.box has the initial bounding box of all pixels */ - /* split bsp 8 levels deep, in regular grid (16 x 16) */ - isb_bsp_split_init(&root, memarena, 8); - - /* insert all samples in BSP now */ - bsp_err= isb_add_samples(pa, &root, memarena, samplebuf); - - if (bsp_err==0) { - /* go over all faces and fill in shadow values */ - - isb_bsp_fillfaces(&R, lar, &root); /* shb->persmat should have been calculated */ - - /* copy shadow samples to persistent buffer, reduce memory overhead */ - if (R.osa) { - ISBShadfacA **isbsa= isbdata->shadfaca= MEM_callocN(pa->rectx*pa->recty*sizeof(void *), "isb shadfacs"); - - isbdata->memarena = BLI_memarena_new(0x8000 * sizeof(ISBSampleA), "isb arena"); - BLI_memarena_use_calloc(isbdata->memarena); - - for (rd= pa->rectdaps, x=pa->rectx*pa->recty; x>0; x--, rd++, isbsa++) { - - if (*rd) { - PixStr *ps= (PixStr *)(*rd); - while (ps) { - if (ps->shadfac) - isb_add_shadfac(isbsa, isbdata->memarena, ps->obi, ps->facenr, ps->shadfac, count_mask(ps->mask)); - ps= ps->next; - } - } - } - } - } - } - else { - if (isbdata->shadfacs) { - MEM_freeN(isbdata->shadfacs); - isbdata->shadfacs= NULL; - } - } - - /* free BSP */ - BLI_memarena_free(memarena); - - /* free samples */ - for (x=0; x<(R.osa?R.osa:1); x++) - MEM_freeN(samplebuf[x]); - - if (bsp_err) printf("error in filling bsp\n"); -} - -/* add sample to buffer, isbsa is the root sample in a buffer */ -static ISBSampleA *isb_alloc_sample_transp(ISBSampleA **isbsa, MemArena *mem) -{ - ISBSampleA *new; - - new= BLI_memarena_alloc(mem, sizeof(ISBSampleA)); - if (*isbsa) - new->next= (*isbsa); - else - new->next= NULL; - - *isbsa= new; - return new; -} - -/* adding samples in BSP, transparent case */ -static int isb_add_samples_transp(RenderPart *pa, ISBBranch *root, MemArena *memarena, ISBSampleA ***samplebuf) -{ - int xi, yi, *xcos, *ycos; - int sample, bsp_err= 0; - - /* bsp split doesn't like to handle regular sequences */ - xcos= MEM_mallocN(pa->rectx*sizeof(int), "xcos"); - ycos= MEM_mallocN(pa->recty*sizeof(int), "ycos"); - for (xi=0; xi<pa->rectx; xi++) - xcos[xi]= xi; - for (yi=0; yi<pa->recty; yi++) - ycos[yi]= yi; - BLI_array_randomize(xcos, sizeof(int), pa->rectx, 12345); - BLI_array_randomize(ycos, sizeof(int), pa->recty, 54321); - - for (sample=0; sample<(R.osa?R.osa:1); sample++) { - ISBSampleA **samp= samplebuf[sample], *samp1; - - for (yi=0; yi<pa->recty; yi++) { - int y= ycos[yi]; - for (xi=0; xi<pa->rectx; xi++) { - int x= xcos[xi]; - - samp1= *(samp + y*pa->rectx + x); - while (samp1) { - bsp_err |= isb_bsp_insert(root, memarena, (ISBSample *)samp1); - samp1= samp1->next; - } - } - if (bsp_err) break; - } - } - - MEM_freeN(xcos); - MEM_freeN(ycos); - - return bsp_err; -} - - -/* Ztransp version */ -/* lar->shb, pa->rectz and pa->rectp should exist */ -static void isb_make_buffer_transp(RenderPart *pa, APixstr *apixbuf, LampRen *lar) -{ - ShadBuf *shb= lar->shb; - ISBData *isbdata; - ISBSampleA *samp, **samplebuf[16]; /* MAX_OSA */ - ISBBranch root; - MemArena *memarena; - APixstr *ap; - int x, y, sindex, sample, bsp_err=0; - - /* storage for shadow, per thread */ - isbdata= shb->isb_result[pa->thread]; - - /* to map the shi->xs and ys coordinate */ - isbdata->minx= pa->disprect.xmin; - isbdata->miny= pa->disprect.ymin; - isbdata->rectx= pa->rectx; - isbdata->recty= pa->recty; - - /* branches are added using memarena (32k branches) */ - memarena = BLI_memarena_new(0x8000 * sizeof(ISBBranch), "isb arena"); - BLI_memarena_use_calloc(memarena); - - /* samplebuf is in camera view space (pixels) */ - for (sample=0; sample<(R.osa?R.osa:1); sample++) - samplebuf[sample]= MEM_callocN(sizeof(void *)*pa->rectx*pa->recty, "isb alpha samplebuf"); - - /* setup bsp root */ - memset(&root, 0, sizeof(ISBBranch)); - root.box.xmin = (float)shb->size; - root.box.ymin = (float)shb->size; - - /* create the sample buffers */ - for (ap= apixbuf, sindex=0, y=0; y<pa->recty; y++) { - for (x=0; x<pa->rectx; x++, sindex++, ap++) { - - if (ap->p[0]) { - APixstr *apn; - float xs= (float)(x + pa->disprect.xmin); - float ys= (float)(y + pa->disprect.ymin); - - for (apn=ap; apn; apn= apn->next) { - int a; - for (a=0; a<4; a++) { - if (apn->p[a]) { - ObjectInstanceRen *obi= &R.objectinstance[apn->obi[a]]; - ObjectRen *obr= obi->obr; - VlakRen *vlr= RE_findOrAddVlak(obr, (apn->p[a]-1) & RE_QUAD_MASK); - float zco[3]; - - /* here we store shadfac, easier to create the end storage buffer. needs zero'ed, multiple shadowbufs use it */ - apn->shadfac[a]= 0; - - if (R.osa) { - for (sample=0; sample<R.osa; sample++) { - int mask= (1<<sample); - - if (apn->mask[a] & mask) { - - /* convert image plane pixel location to lamp buffer space */ - if (viewpixel_to_lampbuf(shb, obi, vlr, xs + R.jit[sample][0], ys + R.jit[sample][1], zco)) { - samp= isb_alloc_sample_transp(samplebuf[sample] + sindex, memarena); - samp->obi= apn->obi[a]; - samp->facenr= apn->p[a] & ~RE_QUAD_OFFS; - samp->shadfac= &apn->shadfac[a]; - - copy_v3_v3(samp->zco, zco); - bound_rectf((rctf *)&root.box, samp->zco); - } - } - } - } - else { - - /* convert image plane pixel location to lamp buffer space */ - if (viewpixel_to_lampbuf(shb, obi, vlr, xs, ys, zco)) { - - samp= isb_alloc_sample_transp(samplebuf[0] + sindex, memarena); - samp->obi= apn->obi[a]; - samp->facenr= apn->p[a] & ~RE_QUAD_OFFS; - samp->shadfac= &apn->shadfac[a]; - - copy_v3_v3(samp->zco, zco); - bound_rectf((rctf *)&root.box, samp->zco); - } - } - } - } - } - } - } - } - - /* simple method to see if we have samples */ - if (root.box.xmin != (float)shb->size) { - /* now create a regular split, root.box has the initial bounding box of all pixels */ - /* split bsp 8 levels deep, in regular grid (16 x 16) */ - isb_bsp_split_init(&root, memarena, 8); - - /* insert all samples in BSP now */ - bsp_err= isb_add_samples_transp(pa, &root, memarena, samplebuf); - - if (bsp_err==0) { - ISBShadfacA **isbsa; - - /* go over all faces and fill in shadow values */ - isb_bsp_fillfaces(&R, lar, &root); /* shb->persmat should have been calculated */ - - /* copy shadow samples to persistent buffer, reduce memory overhead */ - isbsa= isbdata->shadfaca= MEM_callocN(pa->rectx*pa->recty*sizeof(void *), "isb shadfacs"); - - isbdata->memarena = BLI_memarena_new(0x8000 * sizeof(ISBSampleA), "isb arena"); - - for (ap= apixbuf, x=pa->rectx*pa->recty; x>0; x--, ap++, isbsa++) { - - if (ap->p[0]) { - APixstr *apn; - for (apn=ap; apn; apn= apn->next) { - int a; - for (a=0; a<4; a++) { - if (apn->p[a] && apn->shadfac[a]) { - if (R.osa) - isb_add_shadfac(isbsa, isbdata->memarena, apn->obi[a], apn->p[a], apn->shadfac[a], count_mask(apn->mask[a])); - else - isb_add_shadfac(isbsa, isbdata->memarena, apn->obi[a], apn->p[a], apn->shadfac[a], 0); - } - } - } - } - } - } - } - - /* free BSP */ - BLI_memarena_free(memarena); - - /* free samples */ - for (x=0; x<(R.osa?R.osa:1); x++) - MEM_freeN(samplebuf[x]); - - if (bsp_err) printf("error in filling bsp\n"); -} - - - -/* exported */ - -/* returns amount of light (1.0 = no shadow) */ -/* note, shadepixel() rounds the coordinate, not the real sample info */ -float ISB_getshadow(ShadeInput *shi, ShadBuf *shb) -{ - /* if raytracing, we can't accept irregular shadow */ - if (shi->depth==0) { - ISBData *isbdata= shb->isb_result[shi->thread]; - - if (isbdata) { - if (isbdata->shadfacs || isbdata->shadfaca) { - int x= shi->xs - isbdata->minx; - - if (x >= 0 && x < isbdata->rectx) { - int y= shi->ys - isbdata->miny; - - if (y >= 0 && y < isbdata->recty) { - if (isbdata->shadfacs) { - const short *sp= isbdata->shadfacs + y*isbdata->rectx + x; - return *sp>=4096?0.0f:1.0f - ((float)*sp)/4096.0f; - } - else { - int sindex= y*isbdata->rectx + x; - int obi= shi->obi - R.objectinstance; - ISBShadfacA *isbsa= *(isbdata->shadfaca + sindex); - - while (isbsa) { - if (isbsa->facenr==shi->facenr+1 && isbsa->obi==obi) - return isbsa->shadfac>=1.0f?0.0f:1.0f - isbsa->shadfac; - isbsa= isbsa->next; - } - } - } - } - } - } - } - return 1.0f; -} - -/* part is supposed to be solid zbuffered (apixbuf==NULL) or transparent zbuffered */ -void ISB_create(RenderPart *pa, APixstr *apixbuf) -{ - GroupObject *go; - - /* go over all lamps, and make the irregular buffers */ - for (go=R.lights.first; go; go= go->next) { - LampRen *lar= go->lampren; - - if (lar->type==LA_SPOT && lar->shb && lar->buftype==LA_SHADBUF_IRREGULAR) { - - /* create storage for shadow, per thread */ - lar->shb->isb_result[pa->thread]= MEM_callocN(sizeof(ISBData), "isb data"); - - if (apixbuf) - isb_make_buffer_transp(pa, apixbuf, lar); - else - isb_make_buffer(pa, lar); - } - } -} - - -/* end of part rendering, free stored shadow data for this thread from all lamps */ -void ISB_free(RenderPart *pa) -{ - GroupObject *go; - - /* go over all lamps, and free the irregular buffers */ - for (go=R.lights.first; go; go= go->next) { - LampRen *lar= go->lampren; - - if (lar->type==LA_SPOT && lar->shb && lar->buftype==LA_SHADBUF_IRREGULAR) { - ISBData *isbdata= lar->shb->isb_result[pa->thread]; - - if (isbdata) { - if (isbdata->shadfacs) - MEM_freeN(isbdata->shadfacs); - if (isbdata->shadfaca) - MEM_freeN(isbdata->shadfaca); - - if (isbdata->memarena) - BLI_memarena_free(isbdata->memarena); - - MEM_freeN(isbdata); - lar->shb->isb_result[pa->thread]= NULL; - } - } - } -} diff --git a/source/blender/render/intern/source/shadeinput.c b/source/blender/render/intern/source/shadeinput.c deleted file mode 100644 index 6cad37c3e78..00000000000 --- a/source/blender/render/intern/source/shadeinput.c +++ /dev/null @@ -1,1451 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2006 Blender Foundation - * All rights reserved. - * - * Contributors: Hos, Robert Wenzlaff. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/render/intern/source/shadeinput.c - * \ingroup render - */ - - -#include <stdio.h> -#include <math.h> -#include <string.h> - - -#include "BLI_math.h" -#include "BLI_utildefines.h" - -#include "DNA_lamp_types.h" -#include "DNA_meshdata_types.h" -#include "DNA_material_types.h" -#include "DNA_particle_types.h" - -#include "BKE_scene.h" - -#include "BKE_node.h" - -/* local include */ -#include "raycounter.h" -#include "render_types.h" -#include "renderdatabase.h" -#include "rendercore.h" -#include "shading.h" -#include "strand.h" -#include "texture.h" -#include "volumetric.h" -#include "zbuf.h" - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -/* defined in pipeline.c, is hardcopy of active dynamic allocated Render */ -/* only to be used here in this file, it's for speed */ -extern struct Render R; -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -/* Shade Sample order: - * - * - shade_samples_fill_with_ps() - * - for each sample - * - shade_input_set_triangle() <- if prev sample-face is same, use shade_input_copy_triangle() - * - if vlr - * - shade_input_set_viewco() <- not for ray or bake - * - shade_input_set_uv() <- not for ray or bake - * - shade_input_set_normals() - * - shade_samples() - * - if AO - * - shade_samples_do_AO() - * - if shading happens - * - for each sample - * - shade_input_set_shade_texco() - * - shade_samples_do_shade() - * - OSA: distribute sample result with filter masking - * - */ - -/* initialize material variables in shadeinput, - * doing inverse gamma correction where applicable */ -void shade_input_init_material(ShadeInput *shi) -{ - /* note, keep this synced with render_types.h */ - memcpy(&shi->r, &shi->mat->r, 23 * sizeof(float)); - shi->har = shi->mat->har; -} - -/* also used as callback for nodes */ -/* delivers a fully filled in ShadeResult, for all passes */ -void shade_material_loop(ShadeInput *shi, ShadeResult *shr) -{ - - shade_lamp_loop(shi, shr); /* clears shr */ - - if (shi->translucency != 0.0f) { - ShadeResult shr_t; - float fac = shi->translucency; - - shade_input_init_material(shi); - negate_v3_v3(shi->vn, shi->vno); - negate_v3(shi->facenor); - shi->depth++; /* hack to get real shadow now */ - shade_lamp_loop(shi, &shr_t); - shi->depth--; - - /* a couple of passes */ - madd_v3_v3fl(shr->combined, shr_t.combined, fac); - if (shi->passflag & SCE_PASS_SPEC) - madd_v3_v3fl(shr->spec, shr_t.spec, fac); - if (shi->passflag & SCE_PASS_DIFFUSE) { - madd_v3_v3fl(shr->diff, shr_t.diff, fac); - madd_v3_v3fl(shr->diffshad, shr_t.diffshad, fac); - } - if (shi->passflag & SCE_PASS_SHADOW) - madd_v3_v3fl(shr->shad, shr_t.shad, fac); - - negate_v3(shi->vn); - negate_v3(shi->facenor); - } - - /* depth >= 1 when ray-shading */ - if (shi->depth == 0 || shi->volume_depth > 0) { - if (R.r.mode & R_RAYTRACE) { - if (shi->ray_mirror != 0.0f || ((shi->mode & MA_TRANSP) && (shi->mode & MA_RAYTRANSP) && shr->alpha != 1.0f)) { - /* ray trace works on combined, but gives pass info */ - ray_trace(shi, shr); - } - } - /* disable adding of sky for raytransp */ - if ((shi->mode & MA_TRANSP) && (shi->mode & MA_RAYTRANSP)) - if ((shi->layflag & SCE_LAY_SKY) && (R.r.alphamode == R_ADDSKY)) - shr->alpha = 1.0f; - } - - if (R.r.mode & R_RAYTRACE) { - if (R.render_volumes_inside.first) - shade_volume_inside(shi, shr); - } -} - - -/* do a shade, finish up some passes, apply mist */ -void shade_input_do_shade(ShadeInput *shi, ShadeResult *shr) -{ - bool compat = false; - float alpha; - - /* ------ main shading loop -------- */ -#ifdef RE_RAYCOUNTER - memset(&shi->raycounter, 0, sizeof(shi->raycounter)); -#endif - - if (shi->mat->nodetree && shi->mat->use_nodes) { - compat = ntreeShaderExecTree(shi->mat->nodetree, shi, shr); - } - - /* also run this when node shaders fail, due to incompatible shader nodes */ - if (compat == false) { - /* copy all relevant material vars, note, keep this synced with render_types.h */ - shade_input_init_material(shi); - - if (shi->mat->material_type == MA_TYPE_VOLUME) { - if (R.r.mode & R_RAYTRACE) { - shade_volume_outside(shi, shr); - } - } - else { /* MA_TYPE_SURFACE, MA_TYPE_WIRE */ - shade_material_loop(shi, shr); - } - } - - /* copy additional passes */ - if (shi->passflag & (SCE_PASS_VECTOR | SCE_PASS_NORMAL)) { - copy_v4_v4(shr->winspeed, shi->winspeed); - copy_v3_v3(shr->nor, shi->vn); - } - - /* MIST */ - if ((shi->passflag & SCE_PASS_MIST) || ((R.wrld.mode & WO_MIST) && (shi->mat->mode & MA_NOMIST) == 0)) { - if (R.r.mode & R_ORTHO) - shr->mist = mistfactor(-shi->co[2], shi->co); - else - shr->mist = mistfactor(len_v3(shi->co), shi->co); - } - else shr->mist = 0.0f; - - if ((R.wrld.mode & WO_MIST) && (shi->mat->mode & MA_NOMIST) == 0) { - alpha = shr->mist; - } - else alpha = 1.0f; - - /* add mist and premul color */ - if (shr->alpha != 1.0f || alpha != 1.0f) { - float fac = alpha * (shr->alpha); - shr->combined[3] = fac; - - if (shi->mat->material_type != MA_TYPE_VOLUME) - mul_v3_fl(shr->combined, fac); - } - else - shr->combined[3] = 1.0f; - - /* add z */ - shr->z = -shi->co[2]; - - /* RAYHITS */ -#if 0 - if (1 || shi->passflag & SCE_PASS_RAYHITS) { - shr->rayhits[0] = (float)shi->raycounter.faces.test; - shr->rayhits[1] = (float)shi->raycounter.bb.hit; - shr->rayhits[2] = 0.0; - shr->rayhits[3] = 1.0; - } -#endif - - RE_RC_MERGE(&re_rc_counter[shi->thread], &shi->raycounter); -} - -/* **************************************************************************** */ -/* ShadeInput */ -/* **************************************************************************** */ - - -void vlr_set_uv_indices(VlakRen *vlr, int *i1, int *i2, int *i3) -{ - /* to prevent storing new tfaces or vcols, we check a split runtime */ - /* 4---3 4---3 */ - /* |\ 1| or |1 /| */ - /* |0\ | |/ 0| */ - /* 1---2 1---2 0 = orig face, 1 = new face */ - - /* Update vert nums to point to correct verts of original face */ - if (vlr->flag & R_DIVIDE_24) { - if (vlr->flag & R_FACE_SPLIT) { - (*i1)++; (*i2)++; (*i3)++; - } - else { - (*i3)++; - } - } - else if (vlr->flag & R_FACE_SPLIT) { - (*i2)++; (*i3)++; - } -} - -/* copy data from face to ShadeInput, general case */ -/* indices 0 1 2 3 only */ -void shade_input_set_triangle_i(ShadeInput *shi, ObjectInstanceRen *obi, VlakRen *vlr, short i1, short i2, short i3) -{ - VertRen **vpp = &vlr->v1; - - shi->vlr = vlr; - shi->obi = obi; - shi->obr = obi->obr; - - shi->v1 = vpp[i1]; - shi->v2 = vpp[i2]; - shi->v3 = vpp[i3]; - - shi->i1 = i1; - shi->i2 = i2; - shi->i3 = i3; - - /* note, shi->mat is set in node shaders */ - shi->mat = vlr->mat; - - shi->osatex = (shi->mat->texco & TEXCO_OSA); - shi->mode = shi->mat->mode_l; /* or-ed result for all nodes */ - shi->mode2 = shi->mat->mode2_l; - - /* facenormal copy, can get flipped */ - shi->flippednor = 0; - RE_vlakren_get_normal(&R, obi, vlr, shi->facenor); - - /* calculate vertexnormals */ - if (vlr->flag & R_SMOOTH) { - copy_v3_v3(shi->n1, shi->v1->n); - copy_v3_v3(shi->n2, shi->v2->n); - copy_v3_v3(shi->n3, shi->v3->n); - - if (obi->flag & R_TRANSFORMED) { - mul_m3_v3(obi->nmat, shi->n1); normalize_v3(shi->n1); - mul_m3_v3(obi->nmat, shi->n2); normalize_v3(shi->n2); - mul_m3_v3(obi->nmat, shi->n3); normalize_v3(shi->n3); - } - } -} - -/* copy data from face to ShadeInput, scanline case */ -void shade_input_set_triangle(ShadeInput *shi, int obi, int facenr, int UNUSED(normal_flip)) -{ - if (facenr > 0) { - shi->obi = &R.objectinstance[obi]; - shi->obr = shi->obi->obr; - shi->facenr = (facenr - 1) & RE_QUAD_MASK; - if (shi->facenr < shi->obr->totvlak) { - VlakRen *vlr = RE_findOrAddVlak(shi->obr, shi->facenr); - - if (facenr & RE_QUAD_OFFS) - shade_input_set_triangle_i(shi, shi->obi, vlr, 0, 2, 3); - else - shade_input_set_triangle_i(shi, shi->obi, vlr, 0, 1, 2); - } - else - shi->vlr = NULL; /* general signal we got sky */ - } - else - shi->vlr = NULL; /* general signal we got sky */ -} - -/* full osa case: copy static info */ -void shade_input_copy_triangle(ShadeInput *shi, ShadeInput *from) -{ - /* not so nice, but works... warning is in RE_shader_ext.h */ - memcpy(shi, from, sizeof(struct ShadeInputCopy)); -} - -/* copy data from strand to shadeinput */ -void shade_input_set_strand(ShadeInput *shi, StrandRen *strand, StrandPoint *spoint) -{ - /* note, shi->mat is set in node shaders */ - shi->mat = strand->buffer->ma; - - shi->osatex = (shi->mat->texco & TEXCO_OSA); - shi->mode = shi->mat->mode_l; /* or-ed result for all nodes */ - - /* shade_input_set_viewco equivalent */ - copy_v3_v3(shi->co, spoint->co); - copy_v3_v3(shi->view, shi->co); - normalize_v3(shi->view); - - shi->xs = (int)spoint->x; - shi->ys = (int)spoint->y; - - if (shi->osatex || (R.r.mode & R_SHADOW)) { - copy_v3_v3(shi->dxco, spoint->dtco); - copy_v3_v3(shi->dyco, spoint->dsco); - } - - /* dxview, dyview, not supported */ - - /* facenormal, simply viewco flipped */ - copy_v3_v3(shi->facenor, spoint->nor); - - /* shade_input_set_normals equivalent */ - if (shi->mat->mode & MA_TANGENT_STR) { - copy_v3_v3(shi->vn, spoint->tan); - } - else { - float cross[3]; - - cross_v3_v3v3(cross, spoint->co, spoint->tan); - cross_v3_v3v3(shi->vn, cross, spoint->tan); - normalize_v3(shi->vn); - - if (dot_v3v3(shi->vn, shi->view) < 0.0f) - negate_v3(shi->vn); - } - - copy_v3_v3(shi->vno, shi->vn); -} - -void shade_input_set_strand_texco(ShadeInput *shi, StrandRen *strand, StrandVert *svert, StrandPoint *spoint) -{ - StrandBuffer *strandbuf = strand->buffer; - ObjectRen *obr = strandbuf->obr; - StrandVert *sv; - int mode = shi->mode; /* or-ed result for all nodes */ - short texco = shi->mat->texco; - - if ((shi->mat->texco & TEXCO_REFL)) { - /* shi->dxview, shi->dyview, not supported */ - } - - if (shi->osatex && (texco & (TEXCO_NORM | TEXCO_REFL))) { - /* not supported */ - } - - if (mode & (MA_TANGENT_V | MA_NORMAP_TANG)) { - copy_v3_v3(shi->tang, spoint->tan); - copy_v3_v3(shi->nmaptang, spoint->tan); - } - - if (mode & MA_STR_SURFDIFF) { - const float *surfnor = RE_strandren_get_surfnor(obr, strand, 0); - - if (surfnor) - copy_v3_v3(shi->surfnor, surfnor); - else - copy_v3_v3(shi->surfnor, shi->vn); - - if (shi->mat->strand_surfnor > 0.0f) { - shi->surfdist = 0.0f; - for (sv = strand->vert; sv != svert; sv++) - shi->surfdist += len_v3v3(sv->co, (sv + 1)->co); - shi->surfdist += spoint->t * len_v3v3(sv->co, (sv + 1)->co); - } - } - - if (R.r.mode & R_SPEED) { - const float *speed; - - speed = RE_strandren_get_winspeed(shi->obi, strand, 0); - if (speed) - copy_v4_v4(shi->winspeed, speed); - else - shi->winspeed[0] = shi->winspeed[1] = shi->winspeed[2] = shi->winspeed[3] = 0.0f; - } - - /* shade_input_set_shade_texco equivalent */ - if (texco & NEED_UV) { - if (texco & TEXCO_ORCO) { - copy_v3_v3(shi->lo, strand->orco); - /* no shi->osatex, orco derivatives are zero */ - } - - if (texco & TEXCO_GLOB) { - mul_v3_m4v3(shi->gl, R.viewinv, shi->co); - - if (shi->osatex) { - mul_v3_mat3_m4v3(shi->dxgl, R.viewinv, shi->dxco); - mul_v3_mat3_m4v3(shi->dygl, R.viewinv, shi->dyco); - } - } - - if (texco & TEXCO_STRAND) { - shi->strandco = spoint->strandco; - - if (shi->osatex) { - shi->dxstrand = spoint->dtstrandco; - shi->dystrand = 0.0f; - } - } - - if ((texco & TEXCO_UV) || (mode & (MA_VERTEXCOL | MA_VERTEXCOLP))) { - MCol *mcol; - const float *uv; - char *name; - int i; - - shi->totuv = 0; - shi->totcol = 0; - shi->actuv = obr->actmtface; - shi->actcol = obr->actmcol; - - if (mode & (MA_VERTEXCOL | MA_VERTEXCOLP)) { - for (i = 0; (mcol = RE_strandren_get_mcol(obr, strand, i, &name, 0)); i++) { - ShadeInputCol *scol = &shi->col[i]; - const char *cp = (char *)mcol; - - shi->totcol++; - scol->name = name; - - scol->col[0] = cp[3] / 255.0f; - scol->col[1] = cp[2] / 255.0f; - scol->col[2] = cp[1] / 255.0f; - scol->col[3] = cp[0] / 255.0f; - } - - if (shi->totcol) { - shi->vcol[0] = shi->col[shi->actcol].col[0]; - shi->vcol[1] = shi->col[shi->actcol].col[1]; - shi->vcol[2] = shi->col[shi->actcol].col[2]; - shi->vcol[3] = shi->col[shi->actcol].col[3]; - } - else { - shi->vcol[0] = 0.0f; - shi->vcol[1] = 0.0f; - shi->vcol[2] = 0.0f; - shi->vcol[3] = 0.0f; - } - } - - for (i = 0; (uv = RE_strandren_get_uv(obr, strand, i, &name, 0)); i++) { - ShadeInputUV *suv = &shi->uv[i]; - - shi->totuv++; - suv->name = name; - - if (strandbuf->overrideuv == i) { - suv->uv[0] = -1.0f; - suv->uv[1] = spoint->strandco; - suv->uv[2] = 0.0f; - } - else { - suv->uv[0] = -1.0f + 2.0f * uv[0]; - suv->uv[1] = -1.0f + 2.0f * uv[1]; - suv->uv[2] = 0.0f; /* texture.c assumes there are 3 coords */ - } - - if (shi->osatex) { - suv->dxuv[0] = 0.0f; - suv->dxuv[1] = 0.0f; - suv->dyuv[0] = 0.0f; - suv->dyuv[1] = 0.0f; - } - } - - if (shi->totuv == 0) { - ShadeInputUV *suv = &shi->uv[0]; - - suv->uv[0] = 0.0f; - suv->uv[1] = spoint->strandco; - suv->uv[2] = 0.0f; /* texture.c assumes there are 3 coords */ - } - - } - - if (texco & TEXCO_NORM) { - shi->orn[0] = -shi->vn[0]; - shi->orn[1] = -shi->vn[1]; - shi->orn[2] = -shi->vn[2]; - } - - if (texco & TEXCO_STRESS) { - /* not supported */ - } - - if (texco & TEXCO_TANGENT) { - if ((mode & MA_TANGENT_V) == 0) { - /* just prevent surprises */ - shi->tang[0] = shi->tang[1] = shi->tang[2] = 0.0f; - shi->nmaptang[0] = shi->nmaptang[1] = shi->nmaptang[2] = 0.0f; - } - } - } - - /* this only avalailable for scanline renders */ - if (shi->depth == 0) { - if (texco & TEXCO_WINDOW) { - shi->winco[0] = -1.0f + 2.0f * spoint->x / (float)R.winx; - shi->winco[1] = -1.0f + 2.0f * spoint->y / (float)R.winy; - shi->winco[2] = 0.0f; - - /* not supported */ - if (shi->osatex) { - shi->dxwin[0] = 0.0f; - shi->dywin[1] = 0.0f; - shi->dxwin[0] = 0.0f; - shi->dywin[1] = 0.0f; - } - } - } - - if (shi->do_manage) { - if (mode & (MA_VERTEXCOL | MA_VERTEXCOLP)) { - srgb_to_linearrgb_v3_v3(shi->vcol, shi->vcol); - } - } - -} - -/* from scanline pixel coordinates to 3d coordinates, requires set_triangle */ -void shade_input_calc_viewco(ShadeInput *shi, float x, float y, float z, float view[3], float dxyview[2], float co[3], float dxco[3], float dyco[3]) -{ - /* returns not normalized, so is in viewplane coords */ - calc_view_vector(view, x, y); - - if (shi->mat->material_type == MA_TYPE_WIRE) { - /* wire cannot use normal for calculating shi->co, so - * we reconstruct the coordinate less accurate */ - if (R.r.mode & R_ORTHO) - calc_renderco_ortho(co, x, y, z); - else - calc_renderco_zbuf(co, view, z); - } - else { - /* for non-wire, intersect with the triangle to get the exact coord */ - float fac, dface, v1[3]; - - copy_v3_v3(v1, shi->v1->co); - if (shi->obi->flag & R_TRANSFORMED) - mul_m4_v3(shi->obi->mat, v1); - - dface = dot_v3v3(v1, shi->facenor); - - /* ortho viewplane cannot intersect using view vector originating in (0,0,0) */ - if (R.r.mode & R_ORTHO) { - /* x and y 3d coordinate can be derived from pixel coord and winmat */ - float fx = 2.0f / (R.winx * R.winmat[0][0]); - float fy = 2.0f / (R.winy * R.winmat[1][1]); - - co[0] = (x - 0.5f * R.winx) * fx - R.winmat[3][0] / R.winmat[0][0]; - co[1] = (y - 0.5f * R.winy) * fy - R.winmat[3][1] / R.winmat[1][1]; - - /* using a*x + b*y + c*z = d equation, (a b c) is normal */ - if (shi->facenor[2] != 0.0f) - co[2] = (dface - shi->facenor[0] * co[0] - shi->facenor[1] * co[1]) / shi->facenor[2]; - else - co[2] = 0.0f; - - if (dxco && dyco) { - dxco[0] = fx; - dxco[1] = 0.0f; - if (shi->facenor[2] != 0.0f) - dxco[2] = -(shi->facenor[0] * fx) / shi->facenor[2]; - else - dxco[2] = 0.0f; - - dyco[0] = 0.0f; - dyco[1] = fy; - if (shi->facenor[2] != 0.0f) - dyco[2] = -(shi->facenor[1] * fy) / shi->facenor[2]; - else - dyco[2] = 0.0f; - - if (dxyview) { - fac = (co[2] != 0.0f) ? (1.0f / co[2]) : 0.0f; - dxyview[0] = -R.viewdx * fac; - dxyview[1] = -R.viewdy * fac; - } - } - } - else { - float div; - - div = dot_v3v3(shi->facenor, view); - if (div != 0.0f) fac = dface / div; - else fac = 0.0f; - - co[0] = fac * view[0]; - co[1] = fac * view[1]; - co[2] = fac * view[2]; - - /* pixel dx/dy for render coord */ - if (dxco && dyco) { - float u = dface / (div - R.viewdx * shi->facenor[0]); - float v = dface / (div - R.viewdy * shi->facenor[1]); - - dxco[0] = co[0] - (view[0] - R.viewdx) * u; - dxco[1] = co[1] - (view[1]) * u; - dxco[2] = co[2] - (view[2]) * u; - - dyco[0] = co[0] - (view[0]) * v; - dyco[1] = co[1] - (view[1] - R.viewdy) * v; - dyco[2] = co[2] - (view[2]) * v; - - if (dxyview) { - if (fac != 0.0f) fac = 1.0f / fac; - dxyview[0] = -R.viewdx * fac; - dxyview[1] = -R.viewdy * fac; - } - } - } - } - - /* set camera coords - for scanline, it's always 0.0,0.0,0.0 (render is in camera space) - * however for raytrace it can be different - the position of the last intersection */ - shi->camera_co[0] = shi->camera_co[1] = shi->camera_co[2] = 0.0f; - - /* cannot normalize earlier, code above needs it at viewplane level */ - normalize_v3(view); -} - -/* from scanline pixel coordinates to 3d coordinates, requires set_triangle */ -void shade_input_set_viewco(ShadeInput *shi, float x, float y, float xs, float ys, float z) -{ - float *dxyview = NULL, *dxco = NULL, *dyco = NULL; - - /* currently in use for dithering (soft shadow), node preview, irregular shad */ - shi->xs = (int)xs; - shi->ys = (int)ys; - - /* original scanline coordinate without jitter */ - shi->scanco[0] = x; - shi->scanco[1] = y; - shi->scanco[2] = z; - - /* check if we need derivatives */ - if (shi->osatex || (R.r.mode & R_SHADOW)) { - dxco = shi->dxco; - dyco = shi->dyco; - - if ((shi->mat->texco & TEXCO_REFL)) - dxyview = &shi->dxview; - } - - shade_input_calc_viewco(shi, xs, ys, z, shi->view, dxyview, shi->co, dxco, dyco); -} - -void barycentric_differentials_from_position( - const float co[3], const float v1[3], const float v2[3], const float v3[3], - const float dxco[3], const float dyco[3], const float facenor[3], const bool differentials, - float *u, float *v, float *dx_u, float *dx_v, float *dy_u, float *dy_v) -{ - /* find most stable axis to project */ - int axis1, axis2; - axis_dominant_v3(&axis1, &axis2, facenor); - - /* compute u,v and derivatives */ - float t00 = v3[axis1] - v1[axis1]; - float t01 = v3[axis2] - v1[axis2]; - float t10 = v3[axis1] - v2[axis1]; - float t11 = v3[axis2] - v2[axis2]; - - float detsh = (t00 * t11 - t10 * t01); - detsh = (detsh != 0.0f) ? 1.0f / detsh : 0.0f; - t00 *= detsh; t01 *= detsh; - t10 *= detsh; t11 *= detsh; - - *u = (v3[axis1] - co[axis1]) * t11 - (v3[axis2] - co[axis2]) * t10; - *v = (v3[axis2] - co[axis2]) * t00 - (v3[axis1] - co[axis1]) * t01; - if (differentials) { - *dx_u = dxco[axis1] * t11 - dxco[axis2] * t10; - *dx_v = dxco[axis2] * t00 - dxco[axis1] * t01; - *dy_u = dyco[axis1] * t11 - dyco[axis2] * t10; - *dy_v = dyco[axis2] * t00 - dyco[axis1] * t01; - } -} -/* calculate U and V, for scanline (silly render face u and v are in range -1 to 0) */ -void shade_input_set_uv(ShadeInput *shi) -{ - VlakRen *vlr = shi->vlr; - - if ((vlr->flag & R_SMOOTH) || (shi->mat->texco & NEED_UV) || (shi->passflag & SCE_PASS_UV)) { - float v1[3], v2[3], v3[3]; - - copy_v3_v3(v1, shi->v1->co); - copy_v3_v3(v2, shi->v2->co); - copy_v3_v3(v3, shi->v3->co); - - if (shi->obi->flag & R_TRANSFORMED) { - mul_m4_v3(shi->obi->mat, v1); - mul_m4_v3(shi->obi->mat, v2); - mul_m4_v3(shi->obi->mat, v3); - } - - /* exception case for wire render of edge */ - if (vlr->v2 == vlr->v3) { - float lend, lenc; - - lend = len_v3v3(v2, v1); - lenc = len_v3v3(shi->co, v1); - - if (lend == 0.0f) { - shi->u = shi->v = 0.0f; - } - else { - shi->u = -(1.0f - lenc / lend); - shi->v = 0.0f; - } - - if (shi->osatex) { - shi->dx_u = 0.0f; - shi->dx_v = 0.0f; - shi->dy_u = 0.0f; - shi->dy_v = 0.0f; - } - } - else { - barycentric_differentials_from_position( - shi->co, v1, v2, v3, shi->dxco, shi->dyco, shi->facenor, shi->osatex, - &shi->u, &shi->v, &shi->dx_u, &shi->dx_v, &shi->dy_u, &shi->dy_v); - - shi->u = -shi->u; - shi->v = -shi->v; - - /* u and v are in range -1 to 0, we allow a little bit extra but not too much, screws up speedvectors */ - CLAMP(shi->u, -2.0f, 1.0f); - CLAMP(shi->v, -2.0f, 1.0f); - } - } -} - -void shade_input_set_normals(ShadeInput *shi) -{ - float u = shi->u, v = shi->v; - float l = 1.0f + u + v; - - shi->flippednor = 0; - - /* test flip normals to viewing direction */ - if (!(shi->vlr->flag & R_TANGENT)) { - if (dot_v3v3(shi->facenor, shi->view) < 0.0f) { - negate_v3(shi->facenor); - shi->flippednor = 1; - } - } - - /* calculate vertexnormals */ - if (shi->vlr->flag & R_SMOOTH) { - float *n1 = shi->n1, *n2 = shi->n2, *n3 = shi->n3; - - if (shi->flippednor) { - negate_v3(n1); - negate_v3(n2); - negate_v3(n3); - } - - shi->vn[0] = l * n3[0] - u * n1[0] - v * n2[0]; - shi->vn[1] = l * n3[1] - u * n1[1] - v * n2[1]; - shi->vn[2] = l * n3[2] - u * n1[2] - v * n2[2]; - - /* use unnormalized normal (closer to games) */ - copy_v3_v3(shi->nmapnorm, shi->vn); - - normalize_v3(shi->vn); - } - else { - copy_v3_v3(shi->vn, shi->facenor); - copy_v3_v3(shi->nmapnorm, shi->vn); - } - - /* used in nodes */ - copy_v3_v3(shi->vno, shi->vn); - - /* flip normals to viewing direction */ - if (!(shi->vlr->flag & R_TANGENT)) - if (dot_v3v3(shi->facenor, shi->view) < 0.0f) - shade_input_flip_normals(shi); -} - -/* XXX shi->flippednor messes up otherwise */ -void shade_input_set_vertex_normals(ShadeInput *shi) -{ - float u = shi->u, v = shi->v; - float l = 1.0f + u + v; - - /* calculate vertexnormals */ - if (shi->vlr->flag & R_SMOOTH) { - const float *n1 = shi->n1, *n2 = shi->n2, *n3 = shi->n3; - - shi->vn[0] = l * n3[0] - u * n1[0] - v * n2[0]; - shi->vn[1] = l * n3[1] - u * n1[1] - v * n2[1]; - shi->vn[2] = l * n3[2] - u * n1[2] - v * n2[2]; - - /* use unnormalized normal (closer to games) */ - copy_v3_v3(shi->nmapnorm, shi->vn); - - normalize_v3(shi->vn); - } - else { - copy_v3_v3(shi->vn, shi->facenor); - copy_v3_v3(shi->nmapnorm, shi->vn); - } - - /* used in nodes */ - copy_v3_v3(shi->vno, shi->vn); -} - - -/* use by raytrace, sss, bake to flip into the right direction */ -void shade_input_flip_normals(ShadeInput *shi) -{ - negate_v3(shi->facenor); - negate_v3(shi->vn); - negate_v3(shi->vno); - negate_v3(shi->nmapnorm); - shi->flippednor = !shi->flippednor; -} - -void shade_input_set_shade_texco(ShadeInput *shi) -{ - ObjectInstanceRen *obi = shi->obi; - ObjectRen *obr = shi->obr; - VertRen *v1 = shi->v1, *v2 = shi->v2, *v3 = shi->v3; - float u = shi->u, v = shi->v; - float l = 1.0f + u + v, dl; - int mode = shi->mode; /* or-ed result for all nodes */ - int mode2 = shi->mode2; - short texco = shi->mat->texco; - const bool need_mikk_tangent = (mode & MA_NORMAP_TANG || R.flag & R_NEED_TANGENT); - const bool need_mikk_tangent_concrete = (mode2 & MA_TANGENT_CONCRETE) != 0; - - /* calculate dxno */ - if (shi->vlr->flag & R_SMOOTH) { - - if (shi->osatex && (texco & (TEXCO_NORM | TEXCO_REFL)) ) { - const float *n1 = shi->n1, *n2 = shi->n2, *n3 = shi->n3; - - dl = shi->dx_u + shi->dx_v; - shi->dxno[0] = dl * n3[0] - shi->dx_u * n1[0] - shi->dx_v * n2[0]; - shi->dxno[1] = dl * n3[1] - shi->dx_u * n1[1] - shi->dx_v * n2[1]; - shi->dxno[2] = dl * n3[2] - shi->dx_u * n1[2] - shi->dx_v * n2[2]; - dl = shi->dy_u + shi->dy_v; - shi->dyno[0] = dl * n3[0] - shi->dy_u * n1[0] - shi->dy_v * n2[0]; - shi->dyno[1] = dl * n3[1] - shi->dy_u * n1[1] - shi->dy_v * n2[1]; - shi->dyno[2] = dl * n3[2] - shi->dy_u * n1[2] - shi->dy_v * n2[2]; - - } - } - - /* calc tangents */ - if (mode & (MA_TANGENT_V | MA_NORMAP_TANG) || mode2 & MA_TANGENT_CONCRETE || R.flag & R_NEED_TANGENT) { - const float *s1, *s2, *s3; - float tl, tu, tv; - - if (shi->vlr->flag & R_SMOOTH) { - tl = l; - tu = u; - tv = v; - } - else { - /* qdn: flat faces have tangents too, - * could pick either one, using average here */ - tl = 1.0f / 3.0f; - tu = -1.0f / 3.0f; - tv = -1.0f / 3.0f; - } - - shi->tang[0] = shi->tang[1] = shi->tang[2] = 0.0f; - shi->nmaptang[0] = shi->nmaptang[1] = shi->nmaptang[2] = 0.0f; - - if (mode & MA_TANGENT_V) { - s1 = RE_vertren_get_tangent(obr, v1, 0); - s2 = RE_vertren_get_tangent(obr, v2, 0); - s3 = RE_vertren_get_tangent(obr, v3, 0); - - if (s1 && s2 && s3) { - shi->tang[0] = (tl * s3[0] - tu * s1[0] - tv * s2[0]); - shi->tang[1] = (tl * s3[1] - tu * s1[1] - tv * s2[1]); - shi->tang[2] = (tl * s3[2] - tu * s1[2] - tv * s2[2]); - - if (obi->flag & R_TRANSFORMED) - mul_m3_v3(obi->nmat, shi->tang); - - normalize_v3(shi->tang); - copy_v3_v3(shi->nmaptang, shi->tang); - } - } - - if (need_mikk_tangent || need_mikk_tangent_concrete) { - int j1 = shi->i1, j2 = shi->i2, j3 = shi->i3; - float c0[3], c1[3], c2[3]; - int acttang = obr->actmtface; - - vlr_set_uv_indices(shi->vlr, &j1, &j2, &j3); - - /* cycle through all tangent in vlakren */ - for (int i = 0; i < MAX_MTFACE; i++) { - const float *tangent = RE_vlakren_get_nmap_tangent(obr, shi->vlr, i, false); - if (!tangent) - continue; - - copy_v3_v3(c0, &tangent[j1 * 4]); - copy_v3_v3(c1, &tangent[j2 * 4]); - copy_v3_v3(c2, &tangent[j3 * 4]); - - /* keeping tangents normalized at vertex level - * corresponds better to how it's done in game engines */ - if (obi->flag & R_TRANSFORMED) { - mul_mat3_m4_v3(obi->mat, c0); normalize_v3(c0); - mul_mat3_m4_v3(obi->mat, c1); normalize_v3(c1); - mul_mat3_m4_v3(obi->mat, c2); normalize_v3(c2); - } - - /* we don't normalize the interpolated TBN tangent - * corresponds better to how it's done in game engines */ - shi->tangents[i][0] = (tl * c2[0] - tu * c0[0] - tv * c1[0]); - shi->tangents[i][1] = (tl * c2[1] - tu * c0[1] - tv * c1[1]); - shi->tangents[i][2] = (tl * c2[2] - tu * c0[2] - tv * c1[2]); - - /* the sign is the same for all 3 vertices of any - * non degenerate triangle. */ - shi->tangents[i][3] = tangent[j1 * 4 + 3]; - - if (acttang == i && need_mikk_tangent) { - for (int m = 0; m < 4; m++) { - shi->nmaptang[m] = shi->tangents[i][m]; - } - } - } - } - } - - if (mode & MA_STR_SURFDIFF) { - const float *surfnor = RE_vlakren_get_surfnor(obr, shi->vlr, 0); - - if (surfnor) { - copy_v3_v3(shi->surfnor, surfnor); - if (obi->flag & R_TRANSFORMED) - mul_m3_v3(obi->nmat, shi->surfnor); - } - else - copy_v3_v3(shi->surfnor, shi->vn); - - shi->surfdist = 0.0f; - } - - if (R.r.mode & R_SPEED) { - const float *s1, *s2, *s3; - - s1 = RE_vertren_get_winspeed(obi, v1, 0); - s2 = RE_vertren_get_winspeed(obi, v2, 0); - s3 = RE_vertren_get_winspeed(obi, v3, 0); - if (s1 && s2 && s3) { - shi->winspeed[0] = (l * s3[0] - u * s1[0] - v * s2[0]); - shi->winspeed[1] = (l * s3[1] - u * s1[1] - v * s2[1]); - shi->winspeed[2] = (l * s3[2] - u * s1[2] - v * s2[2]); - shi->winspeed[3] = (l * s3[3] - u * s1[3] - v * s2[3]); - } - else { - shi->winspeed[0] = shi->winspeed[1] = shi->winspeed[2] = shi->winspeed[3] = 0.0f; - } - } - - /* pass option forces UV calc */ - if ((shi->passflag & SCE_PASS_UV) || (R.flag & R_NEED_VCOL)) - texco |= (NEED_UV | TEXCO_UV); - - /* texture coordinates. shi->dxuv shi->dyuv have been set */ - if (texco & NEED_UV) { - - if (texco & TEXCO_ORCO) { - if (v1->orco) { - const float *o1, *o2, *o3; - - o1 = v1->orco; - o2 = v2->orco; - o3 = v3->orco; - - shi->lo[0] = l * o3[0] - u * o1[0] - v * o2[0]; - shi->lo[1] = l * o3[1] - u * o1[1] - v * o2[1]; - shi->lo[2] = l * o3[2] - u * o1[2] - v * o2[2]; - - if (shi->osatex) { - dl = shi->dx_u + shi->dx_v; - shi->dxlo[0] = dl * o3[0] - shi->dx_u * o1[0] - shi->dx_v * o2[0]; - shi->dxlo[1] = dl * o3[1] - shi->dx_u * o1[1] - shi->dx_v * o2[1]; - shi->dxlo[2] = dl * o3[2] - shi->dx_u * o1[2] - shi->dx_v * o2[2]; - dl = shi->dy_u + shi->dy_v; - shi->dylo[0] = dl * o3[0] - shi->dy_u * o1[0] - shi->dy_v * o2[0]; - shi->dylo[1] = dl * o3[1] - shi->dy_u * o1[1] - shi->dy_v * o2[1]; - shi->dylo[2] = dl * o3[2] - shi->dy_u * o1[2] - shi->dy_v * o2[2]; - } - } - - copy_v3_v3(shi->duplilo, obi->dupliorco); - } - - if (texco & TEXCO_GLOB) { - copy_v3_v3(shi->gl, shi->co); - mul_m4_v3(R.viewinv, shi->gl); - if (shi->osatex) { - copy_v3_v3(shi->dxgl, shi->dxco); - mul_mat3_m4_v3(R.viewinv, shi->dxgl); - copy_v3_v3(shi->dygl, shi->dyco); - mul_mat3_m4_v3(R.viewinv, shi->dygl); - } - } - - if (texco & TEXCO_STRAND) { - shi->strandco = (l * v3->accum - u * v1->accum - v * v2->accum); - if (shi->osatex) { - dl = shi->dx_u + shi->dx_v; - shi->dxstrand = dl * v3->accum - shi->dx_u * v1->accum - shi->dx_v * v2->accum; - dl = shi->dy_u + shi->dy_v; - shi->dystrand = dl * v3->accum - shi->dy_u * v1->accum - shi->dy_v * v2->accum; - } - } - - if ((texco & TEXCO_UV) || (mode & (MA_VERTEXCOL | MA_VERTEXCOLP)) || (R.flag & R_NEED_VCOL)) { - VlakRen *vlr = shi->vlr; - MTFace *tface; - MCol *mcol; - char *name; - int i, j1 = shi->i1, j2 = shi->i2, j3 = shi->i3; - - /* uv and vcols are not copied on split, so set them according vlr divide flag */ - vlr_set_uv_indices(vlr, &j1, &j2, &j3); - - shi->totuv = 0; - shi->totcol = 0; - shi->actuv = obr->actmtface; - shi->actcol = obr->actmcol; - - if ((mode & (MA_VERTEXCOL | MA_VERTEXCOLP)) || (R.flag & R_NEED_VCOL)) { - for (i = 0; (mcol = RE_vlakren_get_mcol(obr, vlr, i, &name, 0)); i++) { - ShadeInputCol *scol = &shi->col[i]; - const char *cp1, *cp2, *cp3; - float a[3]; - - shi->totcol++; - scol->name = name; - - cp1 = (char *)(mcol + j1); - cp2 = (char *)(mcol + j2); - cp3 = (char *)(mcol + j3); - - /* alpha values */ - a[0] = ((float)cp1[0]) / 255.f; - a[1] = ((float)cp2[0]) / 255.f; - a[2] = ((float)cp3[0]) / 255.f; - scol->col[3] = l * a[2] - u * a[0] - v * a[1]; - - /* sample premultiplied color value */ - scol->col[0] = (l * ((float)cp3[3]) * a[2] - u * ((float)cp1[3]) * a[0] - v * ((float)cp2[3]) * a[1]) / 255.f; - scol->col[1] = (l * ((float)cp3[2]) * a[2] - u * ((float)cp1[2]) * a[0] - v * ((float)cp2[2]) * a[1]) / 255.f; - scol->col[2] = (l * ((float)cp3[1]) * a[2] - u * ((float)cp1[1]) * a[0] - v * ((float)cp2[1]) * a[1]) / 255.f; - - /* if not zero alpha, restore non-multiplied color */ - if (scol->col[3]) { - mul_v3_fl(scol->col, 1.0f / scol->col[3]); - } - } - - if (shi->totcol) { - shi->vcol[0] = shi->col[shi->actcol].col[0]; - shi->vcol[1] = shi->col[shi->actcol].col[1]; - shi->vcol[2] = shi->col[shi->actcol].col[2]; - shi->vcol[3] = shi->col[shi->actcol].col[3]; - } - else { - shi->vcol[0] = 0.0f; - shi->vcol[1] = 0.0f; - shi->vcol[2] = 0.0f; - shi->vcol[3] = 1.0f; - } - } - - for (i = 0; (tface = RE_vlakren_get_tface(obr, vlr, i, &name, 0)); i++) { - ShadeInputUV *suv = &shi->uv[i]; - const float *uv1 = tface->uv[j1]; - const float *uv2 = tface->uv[j2]; - const float *uv3 = tface->uv[j3]; - - shi->totuv++; - suv->name = name; - - if ((shi->mat->mapflag & MA_MAPFLAG_UVPROJECT) && (shi->depth == 0)) { - float x = shi->xs; - float y = shi->ys; - - float s1[2] = {-1.0f + 2.0f * uv1[0], -1.0f + 2.0f * uv1[1]}; - float s2[2] = {-1.0f + 2.0f * uv2[0], -1.0f + 2.0f * uv2[1]}; - float s3[2] = {-1.0f + 2.0f * uv3[0], -1.0f + 2.0f * uv3[1]}; - - - float obwinmat[4][4], winmat[4][4], ho1[4], ho2[4], ho3[4]; - float Zmulx, Zmuly; - float hox, hoy, l_proj, dl_proj, u_proj, v_proj; - float s00, s01, s10, s11, detsh; - - /* old globals, localized now */ - Zmulx = ((float)R.winx) / 2.0f; - Zmuly = ((float)R.winy) / 2.0f; - - zbuf_make_winmat(&R, winmat); - if (shi->obi->flag & R_TRANSFORMED) - mul_m4_m4m4(obwinmat, winmat, obi->mat); - else - copy_m4_m4(obwinmat, winmat); - - zbuf_render_project(obwinmat, v1->co, ho1); - zbuf_render_project(obwinmat, v2->co, ho2); - zbuf_render_project(obwinmat, v3->co, ho3); - - s00 = ho3[0] / ho3[3] - ho1[0] / ho1[3]; - s01 = ho3[1] / ho3[3] - ho1[1] / ho1[3]; - s10 = ho3[0] / ho3[3] - ho2[0] / ho2[3]; - s11 = ho3[1] / ho3[3] - ho2[1] / ho2[3]; - - detsh = s00 * s11 - s10 * s01; - detsh = (detsh != 0.0f) ? 1.0f / detsh : 0.0f; - s00 *= detsh; s01 *= detsh; - s10 *= detsh; s11 *= detsh; - - /* recalc u and v again */ - hox = x / Zmulx - 1.0f; - hoy = y / Zmuly - 1.0f; - u_proj = (hox - ho3[0] / ho3[3]) * s11 - (hoy - ho3[1] / ho3[3]) * s10; - v_proj = (hoy - ho3[1] / ho3[3]) * s00 - (hox - ho3[0] / ho3[3]) * s01; - l_proj = 1.0f + u_proj + v_proj; - - suv->uv[0] = l_proj * s3[0] - u_proj * s1[0] - v_proj * s2[0]; - suv->uv[1] = l_proj * s3[1] - u_proj * s1[1] - v_proj * s2[1]; - suv->uv[2] = 0.0f; - - if (shi->osatex) { - float dxuv[2], dyuv[2]; - dxuv[0] = s11 / Zmulx; - dxuv[1] = -s01 / Zmulx; - dyuv[0] = -s10 / Zmuly; - dyuv[1] = s00 / Zmuly; - - dl_proj = dxuv[0] + dxuv[1]; - suv->dxuv[0] = dl_proj * s3[0] - dxuv[0] * s1[0] - dxuv[1] * s2[0]; - suv->dxuv[1] = dl_proj * s3[1] - dxuv[0] * s1[1] - dxuv[1] * s2[1]; - dl_proj = dyuv[0] + dyuv[1]; - suv->dyuv[0] = dl_proj * s3[0] - dyuv[0] * s1[0] - dyuv[1] * s2[0]; - suv->dyuv[1] = dl_proj * s3[1] - dyuv[0] * s1[1] - dyuv[1] * s2[1]; - } - } - else { - - suv->uv[0] = -1.0f + 2.0f * (l * uv3[0] - u * uv1[0] - v * uv2[0]); - suv->uv[1] = -1.0f + 2.0f * (l * uv3[1] - u * uv1[1] - v * uv2[1]); - suv->uv[2] = 0.0f; /* texture.c assumes there are 3 coords */ - - if (shi->osatex) { - float duv[2]; - - dl = shi->dx_u + shi->dx_v; - duv[0] = shi->dx_u; - duv[1] = shi->dx_v; - - suv->dxuv[0] = 2.0f * (dl * uv3[0] - duv[0] * uv1[0] - duv[1] * uv2[0]); - suv->dxuv[1] = 2.0f * (dl * uv3[1] - duv[0] * uv1[1] - duv[1] * uv2[1]); - - dl = shi->dy_u + shi->dy_v; - duv[0] = shi->dy_u; - duv[1] = shi->dy_v; - - suv->dyuv[0] = 2.0f * (dl * uv3[0] - duv[0] * uv1[0] - duv[1] * uv2[0]); - suv->dyuv[1] = 2.0f * (dl * uv3[1] - duv[0] * uv1[1] - duv[1] * uv2[1]); - } - } - } - - shi->dupliuv[0] = -1.0f + 2.0f * obi->dupliuv[0]; - shi->dupliuv[1] = -1.0f + 2.0f * obi->dupliuv[1]; - shi->dupliuv[2] = 0.0f; - - if (shi->totuv == 0) { - ShadeInputUV *suv = &shi->uv[0]; - - suv->uv[0] = 2.0f * (u + .5f); - suv->uv[1] = 2.0f * (v + .5f); - suv->uv[2] = 0.0f; /* texture.c assumes there are 3 coords */ - } - } - - if (texco & TEXCO_NORM) { - shi->orn[0] = -shi->vn[0]; - shi->orn[1] = -shi->vn[1]; - shi->orn[2] = -shi->vn[2]; - } - - if (texco & TEXCO_STRESS) { - const float *s1, *s2, *s3; - - s1 = RE_vertren_get_stress(obr, v1, 0); - s2 = RE_vertren_get_stress(obr, v2, 0); - s3 = RE_vertren_get_stress(obr, v3, 0); - if (s1 && s2 && s3) { - shi->stress = l * s3[0] - u * s1[0] - v * s2[0]; - if (shi->stress < 1.0f) shi->stress -= 1.0f; - else shi->stress = (shi->stress - 1.0f) / shi->stress; - } - else shi->stress = 0.0f; - } - - if (texco & TEXCO_TANGENT) { - if ((mode & MA_TANGENT_V) == 0) { - /* just prevent surprises */ - shi->tang[0] = shi->tang[1] = shi->tang[2] = 0.0f; - shi->nmaptang[0] = shi->nmaptang[1] = shi->nmaptang[2] = 0.0f; - } - } - } - - /* this only avalailable for scanline renders */ - if (shi->depth == 0) { - float x = shi->xs; - float y = shi->ys; - - if (texco & TEXCO_WINDOW) { - shi->winco[0] = -1.0f + 2.0f * x / (float)R.winx; - shi->winco[1] = -1.0f + 2.0f * y / (float)R.winy; - shi->winco[2] = 0.0f; - if (shi->osatex) { - shi->dxwin[0] = 2.0f / (float)R.winx; - shi->dywin[1] = 2.0f / (float)R.winy; - shi->dxwin[1] = shi->dxwin[2] = 0.0f; - shi->dywin[0] = shi->dywin[2] = 0.0f; - } - } - } - /* else { - * Note! For raytracing winco is not set, - * important because thus means all shader input's need to have their variables set to zero - * else un-initialized values are used - */ - if (shi->do_manage) { - if ((mode & (MA_VERTEXCOL | MA_VERTEXCOLP)) || (R.flag & R_NEED_VCOL)) { - srgb_to_linearrgb_v3_v3(shi->vcol, shi->vcol); - } - } - -} - -/* ****************** ShadeSample ************************************** */ - -/* initialize per part, not per pixel! */ -void shade_input_initialize(ShadeInput *shi, RenderPart *pa, RenderLayer *rl, int sample) -{ - - memset(shi, 0, sizeof(ShadeInput)); - - shi->sample = sample; - shi->thread = pa->thread; - shi->do_preview = (R.r.scemode & R_MATNODE_PREVIEW) != 0; - - shi->do_manage = BKE_scene_check_color_management_enabled(R.scene); - shi->use_world_space_shading = BKE_scene_use_world_space_shading(R.scene); - - shi->lay = (1 << 20) - 1; - shi->layflag = rl->layflag; - shi->passflag = rl->passflag; - shi->combinedflag = ~rl->pass_xor; -// shi->rl= rl; - /* note shi.depth==0 means first hit, not raytracing */ - -} - -/* initialize per part, not per pixel! */ -void shade_sample_initialize(ShadeSample *ssamp, RenderPart *pa, RenderLayer *rl) -{ - int a, tot; - - tot = R.osa == 0 ? 1 : R.osa; - - for (a = 0; a < tot; a++) { - shade_input_initialize(&ssamp->shi[a], pa, rl, a); - memset(&ssamp->shr[a], 0, sizeof(ShadeResult)); - } - - get_sample_layers(pa, rl, ssamp->rlpp); -} - -/* Do AO or (future) GI */ -void shade_samples_do_AO(ShadeSample *ssamp) -{ - if (!(R.r.mode & R_SHADOW)) - return; - if (!(R.r.mode & R_RAYTRACE) && !(R.wrld.ao_gather_method == WO_AOGATHER_APPROX)) - return; - - if (R.wrld.mode & (WO_AMB_OCC | WO_ENV_LIGHT | WO_INDIRECT_LIGHT)) { - ShadeInput *shi = &ssamp->shi[0]; - int sample; - - if (((shi->passflag & SCE_PASS_COMBINED) && (shi->combinedflag & (SCE_PASS_AO | SCE_PASS_ENVIRONMENT | SCE_PASS_INDIRECT))) || - (shi->passflag & (SCE_PASS_AO | SCE_PASS_ENVIRONMENT | SCE_PASS_INDIRECT))) - { - for (sample = 0; sample < ssamp->tot; shi++, sample++) - if (!(shi->mode & MA_SHLESS)) - ambient_occlusion(shi); /* stores in shi->ao[] */ - } - } -} - - -void shade_samples_fill_with_ps(ShadeSample *ssamp, PixStr *ps, int x, int y) -{ - ShadeInput *shi; - float xs, ys; - - ssamp->tot = 0; - - for (shi = ssamp->shi; ps; ps = ps->next) { - shade_input_set_triangle(shi, ps->obi, ps->facenr, 1); - - if (shi->vlr) { /* NULL happens for env material or for 'all z' */ - unsigned short curmask = ps->mask; - - /* full osa is only set for OSA renders */ - if (shi->vlr->flag & R_FULL_OSA) { - short shi_cp = 0, samp; - - for (samp = 0; samp < R.osa; samp++) { - if (curmask & (1 << samp)) { - /* zbuffer has this inverse corrected, ensures xs,ys are inside pixel */ - xs = (float)x + R.jit[samp][0] + 0.5f; - ys = (float)y + R.jit[samp][1] + 0.5f; - - if (shi_cp) - shade_input_copy_triangle(shi, shi - 1); - - shi->mask = (1 << samp); -// shi->rl= ssamp->rlpp[samp]; - shi->samplenr = R.shadowsamplenr[shi->thread]++; /* this counter is not being reset per pixel */ - shade_input_set_viewco(shi, x, y, xs, ys, (float)ps->z); - shade_input_set_uv(shi); - if (shi_cp == 0) - shade_input_set_normals(shi); - else /* XXX shi->flippednor messes up otherwise */ - shade_input_set_vertex_normals(shi); - - shi_cp = 1; - shi++; - } - } - } - else { - if (R.osa) { - short b = R.samples->centmask[curmask]; - xs = (float)x + R.samples->centLut[b & 15] + 0.5f; - ys = (float)y + R.samples->centLut[b >> 4] + 0.5f; - } - else if (R.i.curblur) { - xs= (float)x + R.mblur_jit[R.i.curblur-1][0] + 0.5f; - ys= (float)y + R.mblur_jit[R.i.curblur-1][1] + 0.5f; - } - else { - xs = (float)x + 0.5f; - ys = (float)y + 0.5f; - } - - shi->mask = curmask; - shi->samplenr = R.shadowsamplenr[shi->thread]++; - shade_input_set_viewco(shi, x, y, xs, ys, (float)ps->z); - shade_input_set_uv(shi); - shade_input_set_normals(shi); - shi++; - } - - /* total sample amount, shi->sample is static set in initialize */ - if (shi != ssamp->shi) - ssamp->tot = (shi - 1)->sample + 1; - } - } -} - -/* shades samples, returns true if anything happened */ -int shade_samples(ShadeSample *ssamp, PixStr *ps, int x, int y) -{ - shade_samples_fill_with_ps(ssamp, ps, x, y); - - if (ssamp->tot) { - ShadeInput *shi = ssamp->shi; - ShadeResult *shr = ssamp->shr; - int samp; - - /* if shadow or AO? */ - shade_samples_do_AO(ssamp); - - /* if shade (all shadepinputs have same passflag) */ - if (ssamp->shi[0].passflag & ~(SCE_PASS_Z | SCE_PASS_INDEXOB | SCE_PASS_INDEXMA)) { - - for (samp = 0; samp < ssamp->tot; samp++, shi++, shr++) { - shade_input_set_shade_texco(shi); - shade_input_do_shade(shi, shr); - } - } - else if (shi->passflag & SCE_PASS_Z) { - for (samp = 0; samp < ssamp->tot; samp++, shi++, shr++) - shr->z = -shi->co[2]; - } - - return 1; - } - return 0; -} - diff --git a/source/blender/render/intern/source/shadeoutput.c b/source/blender/render/intern/source/shadeoutput.c deleted file mode 100644 index f3e391672a9..00000000000 --- a/source/blender/render/intern/source/shadeoutput.c +++ /dev/null @@ -1,2162 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2006 Blender Foundation - * All rights reserved. - * - * Contributors: Hos, Robert Wenzlaff. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/render/intern/source/shadeoutput.c - * \ingroup render - */ - -#include <stdio.h> -#include <float.h> -#include <math.h> -#include <string.h> - -#include "BLI_math.h" -#include "BLI_utildefines.h" - -#include "BKE_colorband.h" -#include "BKE_colortools.h" -#include "BKE_material.h" - -#include "DNA_group_types.h" -#include "DNA_lamp_types.h" -#include "DNA_material_types.h" - -/* local include */ -#include "occlusion.h" -#include "render_types.h" -#include "rendercore.h" -#include "shadbuf.h" -#include "sss.h" -#include "texture.h" - -#include "shading.h" /* own include */ - -#include "IMB_colormanagement.h" - -/* could enable at some point but for now there are far too many conversions */ -#ifdef __GNUC__ -# pragma GCC diagnostic ignored "-Wdouble-promotion" -#endif - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -/* defined in pipeline.c, is hardcopy of active dynamic allocated Render */ -/* only to be used here in this file, it's for speed */ -extern struct Render R; -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -ListBase *get_lights(ShadeInput *shi) -{ - - if (R.r.scemode & R_BUTS_PREVIEW) - return &R.lights; - if (shi->mat && shi->mat->group) - return &shi->mat->group->gobject; - - return &R.lights; -} - -#if 0 -static void fogcolor(const float colf[3], float *rco, float *view) -{ - float alpha, stepsize, startdist, dist, hor[4], zen[3], vec[3], dview[3]; - float div=0.0f, distfac; - - hor[0]= R.wrld.horr; hor[1]= R.wrld.horg; hor[2]= R.wrld.horb; - zen[0]= R.wrld.zenr; zen[1]= R.wrld.zeng; zen[2]= R.wrld.zenb; - - copy_v3_v3(vec, rco); - - /* we loop from cur coord to mist start in steps */ - stepsize= 1.0f; - - div= ABS(view[2]); - dview[0]= view[0]/(stepsize*div); - dview[1]= view[1]/(stepsize*div); - dview[2]= -stepsize; - - startdist= -rco[2] + BLI_frand(); - for (dist= startdist; dist>R.wrld.miststa; dist-= stepsize) { - - hor[0]= R.wrld.horr; hor[1]= R.wrld.horg; hor[2]= R.wrld.horb; - alpha= 1.0f; - do_sky_tex(vec, vec, NULL, hor, zen, &alpha); - - distfac= (dist-R.wrld.miststa)/R.wrld.mistdist; - - hor[3]= hor[0]*distfac*distfac; - - /* premul! */ - alpha= hor[3]; - hor[0]= hor[0]*alpha; - hor[1]= hor[1]*alpha; - hor[2]= hor[2]*alpha; - addAlphaOverFloat(colf, hor); - - sub_v3_v3(vec, dview); - } -} -#endif - -/* zcor is distance, co the 3d coordinate in eye space, return alpha */ -float mistfactor(float zcor, float const co[3]) -{ - float fac, hi; - - fac = zcor - R.wrld.miststa; /* zcor is calculated per pixel */ - - /* fac= -co[2]-R.wrld.miststa; */ - - if (fac > 0.0f) { - if (fac < R.wrld.mistdist) { - - fac = (fac / R.wrld.mistdist); - - if (R.wrld.mistype == 0) { - fac *= fac; - } - else if (R.wrld.mistype == 1) { - /* pass */ - } - else { - fac = sqrtf(fac); - } - } - else { - fac = 1.0f; - } - } - else { - fac = 0.0f; - } - - /* height switched off mist */ - if (R.wrld.misthi!=0.0f && fac!=0.0f) { - /* at height misthi the mist is completely gone */ - - hi = R.viewinv[0][2] * co[0] + - R.viewinv[1][2] * co[1] + - R.viewinv[2][2] * co[2] + - R.viewinv[3][2]; - - if (hi > R.wrld.misthi) { - fac = 0.0f; - } - else if (hi>0.0f) { - hi= (R.wrld.misthi-hi)/R.wrld.misthi; - fac*= hi*hi; - } - } - - return (1.0f-fac)* (1.0f-R.wrld.misi); -} - -static void spothalo(struct LampRen *lar, ShadeInput *shi, float *intens) -{ - double a, b, c, disc, nray[3], npos[3]; - double t0, t1 = 0.0f, t2= 0.0f, t3; - float p1[3], p2[3], ladist, maxz = 0.0f, maxy = 0.0f, haint; - int cuts; - bool do_clip = true, use_yco = false; - - *intens= 0.0f; - haint= lar->haint; - - if (R.r.mode & R_ORTHO) { - /* camera pos (view vector) cannot be used... */ - /* camera position (cox,coy,0) rotate around lamp */ - p1[0]= shi->co[0]-lar->co[0]; - p1[1]= shi->co[1]-lar->co[1]; - p1[2]= -lar->co[2]; - mul_m3_v3(lar->imat, p1); - copy_v3db_v3fl(npos, p1); /* npos is double! */ - - /* pre-scale */ - npos[2] *= (double)lar->sh_zfac; - } - else { - copy_v3db_v3fl(npos, lar->sh_invcampos); /* in initlamp calculated */ - } - - /* rotate view */ - copy_v3db_v3fl(nray, shi->view); - mul_m3_v3_double(lar->imat, nray); - - if (R.wrld.mode & WO_MIST) { - /* patchy... */ - haint *= mistfactor(-lar->co[2], lar->co); - if (haint==0.0f) { - return; - } - } - - - /* rotate maxz */ - if (shi->co[2]==0.0f) { - do_clip = false; /* for when halo at sky */ - } - else { - p1[0]= shi->co[0]-lar->co[0]; - p1[1]= shi->co[1]-lar->co[1]; - p1[2]= shi->co[2]-lar->co[2]; - - maxz= lar->imat[0][2]*p1[0]+lar->imat[1][2]*p1[1]+lar->imat[2][2]*p1[2]; - maxz*= lar->sh_zfac; - maxy= lar->imat[0][1]*p1[0]+lar->imat[1][1]*p1[1]+lar->imat[2][1]*p1[2]; - - if (fabs(nray[2]) < FLT_EPSILON) { - use_yco = true; - } - } - - /* scale z to make sure volume is normalized */ - nray[2] *= (double)lar->sh_zfac; - /* nray does not need normalization */ - - ladist= lar->sh_zfac*lar->dist; - - /* solve */ - a = nray[0] * nray[0] + nray[1] * nray[1] - nray[2]*nray[2]; - b = nray[0] * npos[0] + nray[1] * npos[1] - nray[2]*npos[2]; - c = npos[0] * npos[0] + npos[1] * npos[1] - npos[2]*npos[2]; - - cuts= 0; - if (fabs(a) < DBL_EPSILON) { - /* - * Only one intersection point... - */ - return; - } - else { - disc = b*b - a*c; - - if (disc==0.0) { - t1=t2= (-b)/ a; - cuts= 2; - } - else if (disc > 0.0) { - disc = sqrt(disc); - t1 = (-b + disc) / a; - t2 = (-b - disc) / a; - cuts= 2; - } - } - if (cuts==2) { - int ok1=0, ok2=0; - - /* sort */ - if (t1>t2) { - a= t1; t1= t2; t2= a; - } - - /* z of intersection points with diabolo */ - p1[2]= npos[2] + t1*nray[2]; - p2[2]= npos[2] + t2*nray[2]; - - /* evaluate both points */ - if (p1[2]<=0.0f) ok1= 1; - if (p2[2]<=0.0f && t1!=t2) ok2= 1; - - /* at least 1 point with negative z */ - if (ok1==0 && ok2==0) return; - - /* intersction point with -ladist, the bottom of the cone */ - if (use_yco == false) { - t3= ((double)(-ladist)-npos[2])/nray[2]; - - /* de we have to replace one of the intersection points? */ - if (ok1) { - if (p1[2]<-ladist) t1= t3; - } - else { - t1= t3; - } - if (ok2) { - if (p2[2]<-ladist) t2= t3; - } - else { - t2= t3; - } - } - else if (ok1==0 || ok2==0) return; - - /* at least 1 visible interesction point */ - if (t1<0.0 && t2<0.0) return; - - if (t1<0.0) t1= 0.0; - if (t2<0.0) t2= 0.0; - - if (t1==t2) return; - - /* sort again to be sure */ - if (t1>t2) { - a= t1; t1= t2; t2= a; - } - - /* calculate t0: is the maximum visible z (when halo is intersected by face) */ - if (do_clip) { - if (use_yco == false) t0 = ((double)maxz - npos[2]) / nray[2]; - else t0 = ((double)maxy - npos[1]) / nray[1]; - - if (t0 < t1) return; - if (t0 < t2) t2= t0; - } - - /* calc points */ - p1[0]= npos[0] + t1*nray[0]; - p1[1]= npos[1] + t1*nray[1]; - p1[2]= npos[2] + t1*nray[2]; - p2[0]= npos[0] + t2*nray[0]; - p2[1]= npos[1] + t2*nray[1]; - p2[2]= npos[2] + t2*nray[2]; - - - /* now we have 2 points, make three lengths with it */ - - a = len_v3(p1); - b = len_v3(p2); - c = len_v3v3(p1, p2); - - a/= ladist; - a= sqrt(a); - b/= ladist; - b= sqrt(b); - c/= ladist; - - *intens= c*( (1.0-a)+(1.0-b) ); - - /* WATCH IT: do not clip a,b en c at 1.0, this gives nasty little overflows - * at the edges (especially with narrow halos) */ - if (*intens<=0.0f) return; - - /* soft area */ - /* not needed because t0 has been used for p1/p2 as well */ - /* if (doclip && t0<t2) { */ - /* *intens *= (t0-t1)/(t2-t1); */ - /* } */ - - *intens *= haint; - - if (lar->shb && lar->shb->shadhalostep) { - *intens *= shadow_halo(lar, p1, p2); - } - - } -} - -void renderspothalo(ShadeInput *shi, float col[4], float alpha) -{ - ListBase *lights; - GroupObject *go; - LampRen *lar; - float i; - - if (alpha==0.0f) return; - - lights= get_lights(shi); - for (go=lights->first; go; go= go->next) { - lar= go->lampren; - if (lar==NULL) continue; - - if (lar->type==LA_SPOT && (lar->mode & LA_HALO) && (lar->buftype != LA_SHADBUF_DEEP) && lar->haint>0) { - - if (lar->mode & LA_LAYER) - if (shi->vlr && (lar->lay & shi->obi->lay)==0) - continue; - if ((lar->lay & shi->lay)==0) - continue; - - spothalo(lar, shi, &i); - if (i > 0.0f) { - const float i_alpha = i * alpha; - col[0] += i_alpha * lar->r; - col[1] += i_alpha * lar->g; - col[2] += i_alpha * lar->b; - col[3] += i_alpha; /* all premul */ - } - } - } - /* clip alpha, is needed for unified 'alpha threshold' (vanillaRenderPipe.c) */ - if (col[3]>1.0f) col[3]= 1.0f; -} - - - -/* ---------------- shaders ----------------------- */ - -static double Normalize_d(double *n) -{ - double d; - - d= n[0]*n[0]+n[1]*n[1]+n[2]*n[2]; - - if (d>0.00000000000000001) { - d= sqrt(d); - - n[0]/=d; - n[1]/=d; - n[2]/=d; - } - else { - n[0]=n[1]=n[2]= 0.0; - d= 0.0; - } - return d; -} - -/* mix of 'real' fresnel and allowing control. grad defines blending gradient */ -float fresnel_fac(const float view[3], const float vn[3], float grad, float fac) -{ - float t1, t2; - - if (fac==0.0f) return 1.0f; - - t1 = dot_v3v3(view, vn); - if (t1>0.0f) t2= 1.0f+t1; - else t2= 1.0f-t1; - - t2= grad + (1.0f-grad)*powf(t2, fac); - - if (t2<0.0f) return 0.0f; - else if (t2>1.0f) return 1.0f; - return t2; -} - -static double saacos_d(double fac) -{ - if (fac<= -1.0) return M_PI; - else if (fac>=1.0) return 0.0; - else return acos(fac); -} - -/* Stoke's form factor. Need doubles here for extreme small area sizes */ -static float area_lamp_energy(float (*area)[3], const float co[3], const float vn[3]) -{ - double fac; - double vec[4][3]; /* vectors of rendered co to vertices lamp */ - double cross[4][3]; /* cross products of this */ - double rad[4]; /* angles between vecs */ - - VECSUB(vec[0], co, area[0]); - VECSUB(vec[1], co, area[1]); - VECSUB(vec[2], co, area[2]); - VECSUB(vec[3], co, area[3]); - - Normalize_d(vec[0]); - Normalize_d(vec[1]); - Normalize_d(vec[2]); - Normalize_d(vec[3]); - - /* cross product */ -#define CROSS(dest, a, b) \ - { \ - dest[0]= a[1] * b[2] - a[2] * b[1]; \ - dest[1]= a[2] * b[0] - a[0] * b[2]; \ - dest[2]= a[0] * b[1] - a[1] * b[0]; \ - } (void)0 - - CROSS(cross[0], vec[0], vec[1]); - CROSS(cross[1], vec[1], vec[2]); - CROSS(cross[2], vec[2], vec[3]); - CROSS(cross[3], vec[3], vec[0]); - -#undef CROSS - - Normalize_d(cross[0]); - Normalize_d(cross[1]); - Normalize_d(cross[2]); - Normalize_d(cross[3]); - - /* angles */ - rad[0]= vec[0][0]*vec[1][0]+ vec[0][1]*vec[1][1]+ vec[0][2]*vec[1][2]; - rad[1]= vec[1][0]*vec[2][0]+ vec[1][1]*vec[2][1]+ vec[1][2]*vec[2][2]; - rad[2]= vec[2][0]*vec[3][0]+ vec[2][1]*vec[3][1]+ vec[2][2]*vec[3][2]; - rad[3]= vec[3][0]*vec[0][0]+ vec[3][1]*vec[0][1]+ vec[3][2]*vec[0][2]; - - rad[0]= saacos_d(rad[0]); - rad[1]= saacos_d(rad[1]); - rad[2]= saacos_d(rad[2]); - rad[3]= saacos_d(rad[3]); - - /* Stoke formula */ - fac= rad[0]*(vn[0]*cross[0][0]+ vn[1]*cross[0][1]+ vn[2]*cross[0][2]); - fac+= rad[1]*(vn[0]*cross[1][0]+ vn[1]*cross[1][1]+ vn[2]*cross[1][2]); - fac+= rad[2]*(vn[0]*cross[2][0]+ vn[1]*cross[2][1]+ vn[2]*cross[2][2]); - fac+= rad[3]*(vn[0]*cross[3][0]+ vn[1]*cross[3][1]+ vn[2]*cross[3][2]); - - if (fac<=0.0) return 0.0; - return fac; -} - -static float area_lamp_energy_multisample(LampRen *lar, const float co[3], float *vn) -{ - /* corner vectors are moved around according lamp jitter */ - float *jitlamp= lar->jitter, vec[3]; - float area[4][3], intens= 0.0f; - int a= lar->ray_totsamp; - - /* test if co is behind lamp */ - sub_v3_v3v3(vec, co, lar->co); - if (dot_v3v3(vec, lar->vec) < 0.0f) - return 0.0f; - - while (a--) { - vec[0]= jitlamp[0]; - vec[1]= jitlamp[1]; - vec[2]= 0.0f; - mul_m3_v3(lar->mat, vec); - - add_v3_v3v3(area[0], lar->area[0], vec); - add_v3_v3v3(area[1], lar->area[1], vec); - add_v3_v3v3(area[2], lar->area[2], vec); - add_v3_v3v3(area[3], lar->area[3], vec); - - intens+= area_lamp_energy(area, co, vn); - - jitlamp+= 2; - } - intens /= (float)lar->ray_totsamp; - - return pow(intens * lar->areasize, lar->k); /* corrected for buttons size and lar->dist^2 */ -} - -static float spec(float inp, int hard) -{ - float b1; - - if (inp>=1.0f) return 1.0f; - else if (inp<=0.0f) return 0.0f; - - b1= inp*inp; - /* avoid FPE */ - if (b1<0.01f) b1= 0.01f; - - if ((hard & 1)==0) inp= 1.0f; - if (hard & 2) inp*= b1; - b1*= b1; - if (hard & 4) inp*= b1; - b1*= b1; - if (hard & 8) inp*= b1; - b1*= b1; - if (hard & 16) inp*= b1; - b1*= b1; - - /* avoid FPE */ - if (b1<0.001f) b1= 0.0f; - - if (hard & 32) inp*= b1; - b1*= b1; - if (hard & 64) inp*=b1; - b1*= b1; - if (hard & 128) inp*=b1; - - if (b1<0.001f) b1= 0.0f; - - if (hard & 256) { - b1*= b1; - inp*=b1; - } - - return inp; -} - -static float Phong_Spec(const float n[3], const float l[3], const float v[3], int hard, int tangent ) -{ - float h[3]; - float rslt; - - h[0] = l[0] + v[0]; - h[1] = l[1] + v[1]; - h[2] = l[2] + v[2]; - normalize_v3(h); - - rslt = h[0]*n[0] + h[1]*n[1] + h[2]*n[2]; - if (tangent) rslt= sasqrt(1.0f - rslt*rslt); - - if ( rslt > 0.0f ) rslt= spec(rslt, hard); - else rslt = 0.0f; - - return rslt; -} - - -/* reduced cook torrance spec (for off-specular peak) */ -static float CookTorr_Spec(const float n[3], const float l[3], const float v[3], int hard, int tangent) -{ - float i, nh, nv, h[3]; - - h[0]= v[0]+l[0]; - h[1]= v[1]+l[1]; - h[2]= v[2]+l[2]; - normalize_v3(h); - - nh= n[0]*h[0]+n[1]*h[1]+n[2]*h[2]; - if (tangent) nh= sasqrt(1.0f - nh*nh); - else if (nh<0.0f) return 0.0f; - - nv= n[0]*v[0]+n[1]*v[1]+n[2]*v[2]; - if (tangent) nv= sasqrt(1.0f - nv*nv); - else if (nv<0.0f) nv= 0.0f; - - i= spec(nh, hard); - - i= i/(0.1f+nv); - return i; -} - -/* Blinn spec */ -static float Blinn_Spec(const float n[3], const float l[3], const float v[3], float refrac, float spec_power, int tangent) -{ - float i, nh, nv, nl, vh, h[3]; - float a, b, c, g=0.0f, p, f, ang; - - if (refrac < 1.0f) return 0.0f; - if (spec_power == 0.0f) return 0.0f; - - /* conversion from 'hardness' (1-255) to 'spec_power' (50 maps at 0.1) */ - if (spec_power<100.0f) - spec_power = sqrtf(1.0f / spec_power); - else spec_power= 10.0f/spec_power; - - h[0]= v[0]+l[0]; - h[1]= v[1]+l[1]; - h[2]= v[2]+l[2]; - normalize_v3(h); - - nh= n[0]*h[0]+n[1]*h[1]+n[2]*h[2]; /* Dot product between surface normal and half-way vector */ - if (tangent) nh= sasqrt(1.0f - nh*nh); - else if (nh<0.0f) return 0.0f; - - nv= n[0]*v[0]+n[1]*v[1]+n[2]*v[2]; /* Dot product between surface normal and view vector */ - if (tangent) nv= sasqrt(1.0f - nv*nv); - if (nv<=0.01f) nv= 0.01f; /* hrms... */ - - nl= n[0]*l[0]+n[1]*l[1]+n[2]*l[2]; /* Dot product between surface normal and light vector */ - if (tangent) nl= sasqrt(1.0f - nl*nl); - if (nl<=0.01f) { - return 0.0f; - } - - vh= v[0]*h[0]+v[1]*h[1]+v[2]*h[2]; /* Dot product between view vector and half-way vector */ - if (vh<=0.0f) vh= 0.01f; - - a = 1.0f; - b = (2.0f*nh*nv)/vh; - c = (2.0f*nh*nl)/vh; - - if ( a < b && a < c ) g = a; - else if ( b < a && b < c ) g = b; - else if ( c < a && c < b ) g = c; - - p = sqrt((double)((refrac * refrac)+(vh * vh) - 1.0f)); - f = (((p-vh)*(p-vh))/((p+vh)*(p+vh)))*(1+((((vh*(p+vh))-1.0f)*((vh*(p+vh))-1.0f))/(((vh*(p-vh))+1.0f)*((vh*(p-vh))+1.0f)))); - ang = saacos(nh); - - i= f * g * exp((double)(-(ang*ang) / (2.0f*spec_power*spec_power))); - if (i<0.0f) i= 0.0f; - - return i; -} - -/* cartoon render spec */ -static float Toon_Spec(const float n[3], const float l[3], const float v[3], float size, float smooth, int tangent) -{ - float h[3]; - float ang; - float rslt; - - h[0] = l[0] + v[0]; - h[1] = l[1] + v[1]; - h[2] = l[2] + v[2]; - normalize_v3(h); - - rslt = h[0]*n[0] + h[1]*n[1] + h[2]*n[2]; - if (tangent) rslt = sasqrt(1.0f - rslt*rslt); - - ang = saacos( rslt ); - - if ( ang < size ) rslt = 1.0f; - else if ( ang >= (size + smooth) || smooth == 0.0f ) rslt = 0.0f; - else rslt = 1.0f - ((ang - size) / smooth); - - return rslt; -} - -/* Ward isotropic gaussian spec */ -static float WardIso_Spec(const float n[3], const float l[3], const float v[3], float rms, int tangent) -{ - float i, nh, nv, nl, h[3], angle, alpha; - - - /* half-way vector */ - h[0] = l[0] + v[0]; - h[1] = l[1] + v[1]; - h[2] = l[2] + v[2]; - normalize_v3(h); - - nh = n[0]*h[0]+n[1]*h[1]+n[2]*h[2]; /* Dot product between surface normal and half-way vector */ - if (tangent) nh = sasqrt(1.0f - nh*nh); - if (nh<=0.0f) nh = 0.001f; - - nv = n[0]*v[0]+n[1]*v[1]+n[2]*v[2]; /* Dot product between surface normal and view vector */ - if (tangent) nv = sasqrt(1.0f - nv*nv); - if (nv<=0.0f) nv = 0.001f; - - nl = n[0]*l[0]+n[1]*l[1]+n[2]*l[2]; /* Dot product between surface normal and light vector */ - if (tangent) nl = sasqrt(1.0f - nl*nl); - if (nl<=0.0f) nl = 0.001f; - - angle = tanf(saacos(nh)); - alpha = MAX2(rms, 0.001f); - - i= nl * (1.0f/(4.0f*(float)M_PI*alpha*alpha)) * (expf( -(angle*angle)/(alpha*alpha))/(sqrtf(nv*nl))); - - return i; -} - -/* cartoon render diffuse */ -static float Toon_Diff(const float n[3], const float l[3], const float UNUSED(v[3]), float size, float smooth) -{ - float rslt, ang; - - rslt = n[0]*l[0] + n[1]*l[1] + n[2]*l[2]; - - ang = saacos(rslt); - - if ( ang < size ) rslt = 1.0f; - else if ( ang >= (size + smooth) || smooth == 0.0f ) rslt = 0.0f; - else rslt = 1.0f - ((ang - size) / smooth); - - return rslt; -} - -/* Oren Nayar diffuse */ - -/* 'nl' is either dot product, or return value of area light */ -/* in latter case, only last multiplication uses 'nl' */ -static float OrenNayar_Diff(float nl, const float n[3], const float l[3], const float v[3], float rough ) -{ - float i/*, nh*/, nv /*, vh */, realnl, h[3]; - float a, b, t, A, B; - float Lit_A, View_A, Lit_B[3], View_B[3]; - - h[0]= v[0]+l[0]; - h[1]= v[1]+l[1]; - h[2]= v[2]+l[2]; - normalize_v3(h); - - /* nh= n[0]*h[0]+n[1]*h[1]+n[2]*h[2]; */ /* Dot product between surface normal and half-way vector */ - /* if (nh<0.0f) nh = 0.0f; */ - - nv= n[0]*v[0]+n[1]*v[1]+n[2]*v[2]; /* Dot product between surface normal and view vector */ - if (nv<=0.0f) nv= 0.0f; - - realnl= n[0]*l[0]+n[1]*l[1]+n[2]*l[2]; /* Dot product between surface normal and light vector */ - if (realnl<=0.0f) return 0.0f; - if (nl<0.0f) return 0.0f; /* value from area light */ - - /* vh= v[0]*h[0]+v[1]*h[1]+v[2]*h[2]; */ /* Dot product between view vector and halfway vector */ - /* if (vh<=0.0f) vh= 0.0f; */ - - Lit_A = saacos(realnl); - View_A = saacos( nv ); - - Lit_B[0] = l[0] - (realnl * n[0]); - Lit_B[1] = l[1] - (realnl * n[1]); - Lit_B[2] = l[2] - (realnl * n[2]); - normalize_v3(Lit_B); - - View_B[0] = v[0] - (nv * n[0]); - View_B[1] = v[1] - (nv * n[1]); - View_B[2] = v[2] - (nv * n[2]); - normalize_v3(View_B); - - t = Lit_B[0]*View_B[0] + Lit_B[1]*View_B[1] + Lit_B[2]*View_B[2]; - if ( t < 0 ) t = 0; - - if ( Lit_A > View_A ) { - a = Lit_A; - b = View_A; - } - else { - a = View_A; - b = Lit_A; - } - - A = 1.0f - (0.5f * ((rough * rough) / ((rough * rough) + 0.33f))); - B = 0.45f * ((rough * rough) / ((rough * rough) + 0.09f)); - - b*= 0.95f; /* prevent tangens from shooting to inf, 'nl' can be not a dot product here. */ - /* overflow only happens with extreme size area light, and higher roughness */ - i = nl * ( A + ( B * t * sinf(a) * tanf(b) ) ); - - return i; -} - -/* Minnaert diffuse */ -static float Minnaert_Diff(float nl, const float n[3], const float v[3], float darkness) -{ - float i, nv; - - /* nl = dot product between surface normal and light vector */ - if (nl <= 0.0f) - return 0.0f; - - /* nv = dot product between surface normal and view vector */ - nv = dot_v3v3(n, v); - if (nv < 0.0f) - nv = 0.0f; - - if (darkness <= 1.0f) - i = nl * pow(max_ff(nv * nl, 0.1f), (darkness - 1.0f) ); /*The Real model*/ - else - i = nl * pow( (1.001f - nv), (darkness - 1.0f) ); /*Nvidia model*/ - - return i; -} - -static float Fresnel_Diff(float *vn, float *lv, float *UNUSED(view), float fac_i, float fac) -{ - return fresnel_fac(lv, vn, fac_i, fac); -} - -/* --------------------------------------------- */ -/* also called from texture.c */ -void calc_R_ref(ShadeInput *shi) -{ - float i; - - /* shi->vn dot shi->view */ - i= -2*(shi->vn[0]*shi->view[0]+shi->vn[1]*shi->view[1]+shi->vn[2]*shi->view[2]); - - shi->ref[0]= (shi->view[0]+i*shi->vn[0]); - shi->ref[1]= (shi->view[1]+i*shi->vn[1]); - shi->ref[2]= (shi->view[2]+i*shi->vn[2]); - if (shi->osatex) { - if (shi->vlr->flag & R_SMOOTH) { - i= -2*( (shi->vn[0]+shi->dxno[0])*(shi->view[0]+shi->dxview) + - (shi->vn[1]+shi->dxno[1])*shi->view[1]+ (shi->vn[2]+shi->dxno[2])*shi->view[2] ); - - shi->dxref[0]= shi->ref[0]- ( shi->view[0]+shi->dxview+i*(shi->vn[0]+shi->dxno[0])); - shi->dxref[1]= shi->ref[1]- (shi->view[1]+ i*(shi->vn[1]+shi->dxno[1])); - shi->dxref[2]= shi->ref[2]- (shi->view[2]+ i*(shi->vn[2]+shi->dxno[2])); - - i= -2*( (shi->vn[0]+shi->dyno[0])*shi->view[0]+ - (shi->vn[1]+shi->dyno[1])*(shi->view[1]+shi->dyview)+ (shi->vn[2]+shi->dyno[2])*shi->view[2] ); - - shi->dyref[0]= shi->ref[0]- (shi->view[0]+ i*(shi->vn[0]+shi->dyno[0])); - shi->dyref[1]= shi->ref[1]- (shi->view[1]+shi->dyview+i*(shi->vn[1]+shi->dyno[1])); - shi->dyref[2]= shi->ref[2]- (shi->view[2]+ i*(shi->vn[2]+shi->dyno[2])); - - } - else { - - i= -2*( shi->vn[0]*(shi->view[0]+shi->dxview) + - shi->vn[1]*shi->view[1]+ shi->vn[2]*shi->view[2] ); - - shi->dxref[0]= shi->ref[0]- (shi->view[0]+shi->dxview+i*shi->vn[0]); - shi->dxref[1]= shi->ref[1]- (shi->view[1]+ i*shi->vn[1]); - shi->dxref[2]= shi->ref[2]- (shi->view[2]+ i*shi->vn[2]); - - i= -2*( shi->vn[0]*shi->view[0]+ - shi->vn[1]*(shi->view[1]+shi->dyview)+ shi->vn[2]*shi->view[2] ); - - shi->dyref[0]= shi->ref[0]- (shi->view[0]+ i*shi->vn[0]); - shi->dyref[1]= shi->ref[1]- (shi->view[1]+shi->dyview+i*shi->vn[1]); - shi->dyref[2]= shi->ref[2]- (shi->view[2]+ i*shi->vn[2]); - } - } - -} - -/* called from rayshade.c */ -void shade_color(ShadeInput *shi, ShadeResult *shr) -{ - Material *ma= shi->mat; - - if (ma->mode & (MA_VERTEXCOLP)) { - float neg_alpha = 1.0f - shi->vcol[3]; - shi->r= shi->r*neg_alpha + shi->vcol[0]*shi->vcol[3]; - shi->g= shi->g*neg_alpha + shi->vcol[1]*shi->vcol[3]; - shi->b= shi->b*neg_alpha + shi->vcol[2]*shi->vcol[3]; - } - - if (ma->texco) - do_material_tex(shi, &R); - - if (ma->fresnel_tra!=0.0f) - shi->alpha*= fresnel_fac(shi->view, shi->vn, ma->fresnel_tra_i, ma->fresnel_tra); - - if (!(shi->mode & MA_TRANSP)) shi->alpha= 1.0f; - - shr->diff[0]= shi->r; - shr->diff[1]= shi->g; - shr->diff[2]= shi->b; - shr->alpha= shi->alpha; - - /* modulate by the object color */ - if ((ma->shade_flag & MA_OBCOLOR) && shi->obr->ob) { - float obcol[4]; - - copy_v4_v4(obcol, shi->obr->ob->col); - CLAMP(obcol[3], 0.0f, 1.0f); - - shr->diff[0] *= obcol[0]; - shr->diff[1] *= obcol[1]; - shr->diff[2] *= obcol[2]; - if (shi->mode & MA_TRANSP) shr->alpha *= obcol[3]; - } - - copy_v3_v3(shr->diffshad, shr->diff); -} - -/* ramp for at end of shade */ -static void ramp_diffuse_result(float *diff, ShadeInput *shi) -{ - Material *ma= shi->mat; - float col[4]; - - if (ma->ramp_col) { - if (ma->rampin_col==MA_RAMP_IN_RESULT) { - float fac = IMB_colormanagement_get_luminance(diff); - BKE_colorband_evaluate(ma->ramp_col, fac, col); - - /* blending method */ - fac= col[3]*ma->rampfac_col; - - ramp_blend(ma->rampblend_col, diff, fac, col); - } - } -} - -/* r,g,b denote energy, ramp is used with different values to make new material color */ -static void add_to_diffuse(float diff[3], const ShadeInput *shi, const float is, const float rgb[3]) -{ - Material *ma= shi->mat; - - if (ma->ramp_col && (ma->mode & MA_RAMP_COL)) { - - /* MA_RAMP_IN_RESULT is exceptional */ - if (ma->rampin_col==MA_RAMP_IN_RESULT) { - /* normal add */ - diff[0] += rgb[0] * shi->r; - diff[1] += rgb[1] * shi->g; - diff[2] += rgb[2] * shi->b; - } - else { - float colt[3], col[4]; - float fac; - - /* input */ - switch (ma->rampin_col) { - case MA_RAMP_IN_ENERGY: - fac = IMB_colormanagement_get_luminance(rgb); - break; - case MA_RAMP_IN_SHADER: - fac = is; - break; - case MA_RAMP_IN_NOR: - fac = dot_v3v3(shi->view, shi->vn); - break; - default: - fac = 0.0f; - break; - } - - BKE_colorband_evaluate(ma->ramp_col, fac, col); - - /* blending method */ - fac = col[3] * ma->rampfac_col; - copy_v3_v3(colt, &shi->r); - - ramp_blend(ma->rampblend_col, colt, fac, col); - - /* output to */ - diff[0] += rgb[0] * colt[0]; - diff[1] += rgb[1] * colt[1]; - diff[2] += rgb[2] * colt[2]; - } - } - else { - diff[0] += rgb[0] * shi->r; - diff[1] += rgb[1] * shi->g; - diff[2] += rgb[2] * shi->b; - } -} - -static void ramp_spec_result(float spec_col[3], ShadeInput *shi) -{ - Material *ma= shi->mat; - - if (ma->ramp_spec && (ma->rampin_spec==MA_RAMP_IN_RESULT)) { - float col[4]; - float fac = IMB_colormanagement_get_luminance(spec_col); - - BKE_colorband_evaluate(ma->ramp_spec, fac, col); - - /* blending method */ - fac= col[3]*ma->rampfac_spec; - - ramp_blend(ma->rampblend_spec, spec_col, fac, col); - - } -} - -/* is = dot product shade, t = spec energy */ -static void do_specular_ramp(ShadeInput *shi, float is, float t, float spec[3]) -{ - Material *ma= shi->mat; - - spec[0]= shi->specr; - spec[1]= shi->specg; - spec[2]= shi->specb; - - /* MA_RAMP_IN_RESULT is exception */ - if (ma->ramp_spec && (ma->rampin_spec!=MA_RAMP_IN_RESULT)) { - float fac; - float col[4]; - - /* input */ - switch (ma->rampin_spec) { - case MA_RAMP_IN_ENERGY: - fac= t; - break; - case MA_RAMP_IN_SHADER: - fac= is; - break; - case MA_RAMP_IN_NOR: - fac= shi->view[0]*shi->vn[0] + shi->view[1]*shi->vn[1] + shi->view[2]*shi->vn[2]; - break; - default: - fac= 0.0f; - break; - } - - BKE_colorband_evaluate(ma->ramp_spec, fac, col); - - /* blending method */ - fac= col[3]*ma->rampfac_spec; - - ramp_blend(ma->rampblend_spec, spec, fac, col); - } -} - -/* pure AO, check for raytrace and world should have been done */ -/* preprocess, textures were not done, don't use shi->amb for that reason */ -void ambient_occlusion(ShadeInput *shi) -{ - if ((R.wrld.ao_gather_method == WO_AOGATHER_APPROX) && shi->mat->amb!=0.0f) { - sample_occ(&R, shi); - } - else if ((R.r.mode & R_RAYTRACE) && shi->mat->amb!=0.0f) { - ray_ao(shi, shi->ao, shi->env); - } - else { - shi->ao[0]= shi->ao[1]= shi->ao[2]= 1.0f; - zero_v3(shi->env); - zero_v3(shi->indirect); - } -} - - -/* wrld mode was checked for */ -static void ambient_occlusion_apply(ShadeInput *shi, ShadeResult *shr) -{ - float f= R.wrld.aoenergy; - float tmp[3], tmpspec[3]; - - if (!((R.r.mode & R_RAYTRACE) || R.wrld.ao_gather_method == WO_AOGATHER_APPROX)) - return; - if (f == 0.0f) - return; - - if (R.wrld.aomix==WO_AOADD) { - shr->combined[0] += shi->ao[0]*shi->r*shi->refl*f; - shr->combined[1] += shi->ao[1]*shi->g*shi->refl*f; - shr->combined[2] += shi->ao[2]*shi->b*shi->refl*f; - } - else if (R.wrld.aomix==WO_AOMUL) { - mul_v3_v3v3(tmp, shr->combined, shi->ao); - mul_v3_v3v3(tmpspec, shr->spec, shi->ao); - - if (f == 1.0f) { - copy_v3_v3(shr->combined, tmp); - copy_v3_v3(shr->spec, tmpspec); - } - else { - interp_v3_v3v3(shr->combined, shr->combined, tmp, f); - interp_v3_v3v3(shr->spec, shr->spec, tmpspec, f); - } - } -} - -void environment_lighting_apply(ShadeInput *shi, ShadeResult *shr) -{ - float f= R.wrld.ao_env_energy*shi->amb; - - if (!((R.r.mode & R_RAYTRACE) || R.wrld.ao_gather_method == WO_AOGATHER_APPROX)) - return; - if (f == 0.0f) - return; - - shr->combined[0] += shi->env[0]*shi->r*shi->refl*f; - shr->combined[1] += shi->env[1]*shi->g*shi->refl*f; - shr->combined[2] += shi->env[2]*shi->b*shi->refl*f; -} - -static void indirect_lighting_apply(ShadeInput *shi, ShadeResult *shr) -{ - float f= R.wrld.ao_indirect_energy; - - if (!((R.r.mode & R_RAYTRACE) || R.wrld.ao_gather_method == WO_AOGATHER_APPROX)) - return; - if (f == 0.0f) - return; - - shr->combined[0] += shi->indirect[0]*shi->r*shi->refl*f; - shr->combined[1] += shi->indirect[1]*shi->g*shi->refl*f; - shr->combined[2] += shi->indirect[2]*shi->b*shi->refl*f; -} - -/* result written in shadfac */ -void lamp_get_shadow(LampRen *lar, ShadeInput *shi, float inp, float shadfac[4], int do_real) -{ - LampShadowSubSample *lss= &(lar->shadsamp[shi->thread].s[shi->sample]); - - if (do_real || lss->samplenr!=shi->samplenr) { - - shadfac[0]= shadfac[1]= shadfac[2]= shadfac[3]= 1.0f; - - if (lar->shb) { - if (lar->buftype==LA_SHADBUF_IRREGULAR) - shadfac[3]= ISB_getshadow(shi, lar->shb); - else - shadfac[3] = testshadowbuf(&R, lar->shb, shi->co, shi->dxco, shi->dyco, inp, shi->mat->lbias); - } - else if (lar->mode & LA_SHAD_RAY) { - ray_shadow(shi, lar, shadfac); - } - - if (shi->depth==0) { - copy_v4_v4(lss->shadfac, shadfac); - lss->samplenr= shi->samplenr; - } - } - else { - copy_v4_v4(shadfac, lss->shadfac); - } -} - -/* lampdistance and spot angle, writes in lv and dist */ -float lamp_get_visibility(LampRen *lar, const float co[3], float lv[3], float *dist) -{ - if (lar->type==LA_SUN || lar->type==LA_HEMI) { - *dist= 1.0f; - copy_v3_v3(lv, lar->vec); - return 1.0f; - } - else { - float visifac= 1.0f, visifac_r; - - sub_v3_v3v3(lv, co, lar->co); - mul_v3_fl(lv, 1.0f / (*dist = len_v3(lv))); - - /* area type has no quad or sphere option */ - if (lar->type==LA_AREA) { - /* area is single sided */ - //if (dot_v3v3(lv, lar->vec) > 0.0f) - // visifac= 1.0f; - //else - // visifac= 0.0f; - } - else { - switch (lar->falloff_type) { - case LA_FALLOFF_CONSTANT: - visifac = 1.0f; - break; - case LA_FALLOFF_INVLINEAR: - visifac = lar->dist/(lar->dist + dist[0]); - break; - case LA_FALLOFF_INVSQUARE: - /* NOTE: This seems to be a hack since commit r12045 says this - * option is similar to old Quad, but with slight changes. - * Correct inv square would be (which would be old Quad): - * visifac = lar->distkw / (lar->distkw + dist[0]*dist[0]); - */ - visifac = lar->dist / (lar->dist + dist[0]*dist[0]); - break; - case LA_FALLOFF_SLIDERS: - if (lar->ld1>0.0f) - visifac= lar->dist/(lar->dist+lar->ld1*dist[0]); - if (lar->ld2>0.0f) - visifac*= lar->distkw/(lar->distkw+lar->ld2*dist[0]*dist[0]); - break; - case LA_FALLOFF_INVCOEFFICIENTS: - visifac_r = lar->coeff_const + - lar->coeff_lin * dist[0] + - lar->coeff_quad * dist[0] * dist[0]; - if (visifac_r > 0.0) - visifac = 1.0 / visifac_r; - else - visifac = 0.0; - break; - case LA_FALLOFF_CURVE: - /* curvemapping_initialize is called from #add_render_lamp */ - visifac = curvemapping_evaluateF(lar->curfalloff, 0, dist[0]/lar->dist); - break; - } - - if (lar->mode & LA_SPHERE) { - float t= lar->dist - dist[0]; - if (t<=0.0f) - visifac= 0.0f; - else - visifac*= t/lar->dist; - } - - if (visifac > 0.0f) { - if (lar->type==LA_SPOT) { - float inpr, t; - - if (lar->mode & LA_SQUARE) { - if (dot_v3v3(lv, lar->vec) > 0.0f) { - float lvrot[3], x; - - /* rotate view to lampspace */ - copy_v3_v3(lvrot, lv); - mul_m3_v3(lar->imat, lvrot); - - x = max_ff(fabsf(lvrot[0]/lvrot[2]), fabsf(lvrot[1]/lvrot[2])); - /* 1.0f/(sqrt(1+x*x)) is equivalent to cos(atan(x)) */ - - inpr = 1.0f / (sqrtf(1.0f + x * x)); - } - else inpr= 0.0f; - } - else { - inpr= lv[0]*lar->vec[0]+lv[1]*lar->vec[1]+lv[2]*lar->vec[2]; - } - - t= lar->spotsi; - if (inpr<=t) - visifac= 0.0f; - else { - t= inpr-t; - if (t<lar->spotbl && lar->spotbl!=0.0f) { - /* soft area */ - float i= t/lar->spotbl; - t= i*i; - inpr*= (3.0f*t-2.0f*t*i); - } - visifac*= inpr; - } - } - } - } - if (visifac <= 0.001f) visifac = 0.0f; - return visifac; - } -} - -/* function returns raw diff, spec and full shadowed diff in the 'shad' pass */ -static void shade_one_light(LampRen *lar, ShadeInput *shi, ShadeResult *shr, int passflag) -{ - Material *ma= shi->mat; - VlakRen *vlr= shi->vlr; - float lv[3], lampdist, lacol[3], shadfac[4], lashdw[3]; - float i, is, i_noshad, inp, *vn, *view, vnor[3], phongcorr=1.0f; - float visifac; - - vn= shi->vn; - view= shi->view; - - - if (lar->energy == 0.0f) return; - /* only shadow lamps shouldn't affect shadow-less materials at all */ - if ((lar->mode & LA_ONLYSHADOW) && (!(ma->mode & MA_SHADOW) || !(R.r.mode & R_SHADOW))) - return; - /* optimization, don't render fully black lamps */ - if (!(lar->mode & LA_TEXTURE) && (lar->r + lar->g + lar->b == 0.0f)) - return; - - /* lampdist, spot angle, area side, ... */ - visifac= lamp_get_visibility(lar, shi->co, lv, &lampdist); - if (visifac==0.0f) - return; - - if (lar->type==LA_SPOT) { - if (lar->mode & LA_OSATEX) { - shi->osatex= 1; /* signal for multitex() */ - - shi->dxlv[0]= lv[0] - (shi->co[0]-lar->co[0]+shi->dxco[0])/lampdist; - shi->dxlv[1]= lv[1] - (shi->co[1]-lar->co[1]+shi->dxco[1])/lampdist; - shi->dxlv[2]= lv[2] - (shi->co[2]-lar->co[2]+shi->dxco[2])/lampdist; - - shi->dylv[0]= lv[0] - (shi->co[0]-lar->co[0]+shi->dyco[0])/lampdist; - shi->dylv[1]= lv[1] - (shi->co[1]-lar->co[1]+shi->dyco[1])/lampdist; - shi->dylv[2]= lv[2] - (shi->co[2]-lar->co[2]+shi->dyco[2])/lampdist; - } - } - - /* lamp color texture */ - lacol[0]= lar->r; - lacol[1]= lar->g; - lacol[2]= lar->b; - - lashdw[0]= lar->shdwr; - lashdw[1]= lar->shdwg; - lashdw[2]= lar->shdwb; - - if (lar->mode & LA_TEXTURE) do_lamp_tex(lar, lv, shi, lacol, LA_TEXTURE); - if (lar->mode & LA_SHAD_TEX) do_lamp_tex(lar, lv, shi, lashdw, LA_SHAD_TEX); - - /* tangent case; calculate fake face normal, aligned with lampvector */ - /* note, vnor==vn is used as tangent trigger for buffer shadow */ - if (vlr->flag & R_TANGENT) { - float cross[3], nstrand[3], blend; - - if (ma->mode & MA_STR_SURFDIFF) { - cross_v3_v3v3(cross, shi->surfnor, vn); - cross_v3_v3v3(nstrand, vn, cross); - - blend= dot_v3v3(nstrand, shi->surfnor); - blend= 1.0f - blend; - CLAMP(blend, 0.0f, 1.0f); - - interp_v3_v3v3(vnor, nstrand, shi->surfnor, blend); - normalize_v3(vnor); - } - else { - cross_v3_v3v3(cross, lv, vn); - cross_v3_v3v3(vnor, cross, vn); - normalize_v3(vnor); - } - - if (ma->strand_surfnor > 0.0f) { - if (ma->strand_surfnor > shi->surfdist) { - blend= (ma->strand_surfnor - shi->surfdist)/ma->strand_surfnor; - interp_v3_v3v3(vnor, vnor, shi->surfnor, blend); - normalize_v3(vnor); - } - } - - vnor[0]= -vnor[0];vnor[1]= -vnor[1];vnor[2]= -vnor[2]; - vn= vnor; - } - else if (ma->mode & MA_TANGENT_V) { - float cross[3]; - cross_v3_v3v3(cross, lv, shi->tang); - cross_v3_v3v3(vnor, cross, shi->tang); - normalize_v3(vnor); - vnor[0]= -vnor[0];vnor[1]= -vnor[1];vnor[2]= -vnor[2]; - vn= vnor; - } - - /* dot product and reflectivity */ - /* inp = dotproduct, is = shader result, i = lamp energy (with shadow), i_noshad = i without shadow */ - inp= dot_v3v3(vn, lv); - - /* phong threshold to prevent backfacing faces having artifacts on ray shadow (terminator problem) */ - /* this complex construction screams for a nicer implementation! (ton) */ - if (R.r.mode & R_SHADOW) { - if (ma->mode & MA_SHADOW) { - if (lar->type == LA_HEMI || lar->type == LA_AREA) { - /* pass */ - } - else if ((ma->mode & MA_RAYBIAS) && (lar->mode & LA_SHAD_RAY) && (vlr->flag & R_SMOOTH)) { - float thresh= shi->obr->ob->smoothresh; - if (inp>thresh) - phongcorr= (inp-thresh)/(inp*(1.0f-thresh)); - else - phongcorr= 0.0f; - } - else if (ma->sbias!=0.0f && ((lar->mode & LA_SHAD_RAY) || lar->shb)) { - if (inp>ma->sbias) - phongcorr= (inp-ma->sbias)/(inp*(1.0f-ma->sbias)); - else - phongcorr= 0.0f; - } - } - } - - /* diffuse shaders */ - if (lar->mode & LA_NO_DIFF) { - is = 0.0f; /* skip shaders */ - } - else if (lar->type==LA_HEMI) { - is = 0.5f * inp + 0.5f; - } - else { - - if (lar->type==LA_AREA) - inp= area_lamp_energy_multisample(lar, shi->co, vn); - - /* diffuse shaders (oren nayer gets inp from area light) */ - if (ma->diff_shader==MA_DIFF_ORENNAYAR) is= OrenNayar_Diff(inp, vn, lv, view, ma->roughness); - else if (ma->diff_shader==MA_DIFF_TOON) is= Toon_Diff(vn, lv, view, ma->param[0], ma->param[1]); - else if (ma->diff_shader==MA_DIFF_MINNAERT) is= Minnaert_Diff(inp, vn, view, ma->darkness); - else if (ma->diff_shader==MA_DIFF_FRESNEL) is= Fresnel_Diff(vn, lv, view, ma->param[0], ma->param[1]); - else is= inp; /* Lambert */ - } - - /* 'is' is diffuse */ - if ((ma->shade_flag & MA_CUBIC) && is > 0.0f && is < 1.0f) { - is= 3.0f * is * is - 2.0f * is * is * is; /* nicer termination of shades */ - } - - i= is*phongcorr; - - if (i>0.0f) { - i*= visifac*shi->refl; - } - i_noshad= i; - - vn = shi->vn; /* bring back original vector, we use special specular shaders for tangent */ - if (ma->mode & MA_TANGENT_V) - vn= shi->tang; - - /* init transp shadow */ - shadfac[0]= shadfac[1]= shadfac[2]= shadfac[3]= 1.0f; - - /* shadow and spec, (visifac==0 outside spot) */ - if (visifac> 0.0f) { - - if ((R.r.mode & R_SHADOW)) { - if (ma->mode & MA_SHADOW) { - if (lar->shb || (lar->mode & LA_SHAD_RAY)) { - - if (vn==vnor) /* tangent trigger */ - lamp_get_shadow(lar, shi, dot_v3v3(shi->vn, lv), shadfac, shi->depth); - else - lamp_get_shadow(lar, shi, inp, shadfac, shi->depth); - - /* warning, here it skips the loop */ - if ((lar->mode & LA_ONLYSHADOW) && i>0.0f) { - - shadfac[3]= i*lar->energy*(1.0f-shadfac[3]); - shr->shad[0] -= shadfac[3]*shi->r*(1.0f-lashdw[0]); - shr->shad[1] -= shadfac[3]*shi->g*(1.0f-lashdw[1]); - shr->shad[2] -= shadfac[3]*shi->b*(1.0f-lashdw[2]); - - if (!(lar->mode & LA_NO_SPEC)) { - shr->spec[0] -= shadfac[3]*shi->specr*(1.0f-lashdw[0]); - shr->spec[1] -= shadfac[3]*shi->specg*(1.0f-lashdw[1]); - shr->spec[2] -= shadfac[3]*shi->specb*(1.0f-lashdw[2]); - } - - return; - } - - i*= shadfac[3]; - shr->shad[3] = shadfac[3]; /* store this for possible check in troublesome cases */ - } - else { - shr->shad[3] = 1.0f; /* No shadow at all! */ - } - } - } - - /* in case 'no diffuse' we still do most calculus, spec can be in shadow.*/ - if (!(lar->mode & LA_NO_DIFF)) { - if (i>0.0f) { - if (ma->mode & MA_SHADOW_TRA) { - const float tcol[3] = { - i * shadfac[0] * lacol[0], - i * shadfac[1] * lacol[1], - i * shadfac[2] * lacol[2], - }; - add_to_diffuse(shr->shad, shi, is, tcol); - } - else { - const float tcol[3] = { - i * lacol[0], - i * lacol[1], - i * lacol[2], - }; - add_to_diffuse(shr->shad, shi, is, tcol); - } - } - /* add light for colored shadow */ - if (i_noshad>i && !(lashdw[0]==0 && lashdw[1]==0 && lashdw[2]==0)) { - const float tcol[3] = { - lashdw[0] * (i_noshad - i) * lacol[0], - lashdw[1] * (i_noshad - i) * lacol[1], - lashdw[2] * (i_noshad - i) * lacol[2], - }; - add_to_diffuse(shr->shad, shi, is, tcol); - } - if (i_noshad>0.0f) { - if (passflag & (SCE_PASS_DIFFUSE|SCE_PASS_SHADOW) || - ((passflag & SCE_PASS_COMBINED) && !(shi->combinedflag & SCE_PASS_SHADOW))) - { - const float tcol[3] = { - i_noshad * lacol[0], - i_noshad * lacol[1], - i_noshad * lacol[2] - }; - add_to_diffuse(shr->diff, shi, is, tcol); - } - else { - copy_v3_v3(shr->diff, shr->shad); - } - } - } - - /* specularity */ - shadfac[3]*= phongcorr; /* note, shadfac not allowed to be stored nonlocal */ - - if (shadfac[3]>0.0f && shi->spec!=0.0f && !(lar->mode & LA_NO_SPEC) && !(lar->mode & LA_ONLYSHADOW)) { - - if (!(passflag & (SCE_PASS_COMBINED | SCE_PASS_SPEC))) { - /* pass */ - } - else if (lar->type == LA_HEMI) { - float t; - /* hemi uses no spec shaders (yet) */ - - lv[0]+= view[0]; - lv[1]+= view[1]; - lv[2]+= view[2]; - - normalize_v3(lv); - - t= vn[0]*lv[0]+vn[1]*lv[1]+vn[2]*lv[2]; - - if (lar->type==LA_HEMI) { - t= 0.5f*t+0.5f; - } - - t= shadfac[3]*shi->spec*spec(t, shi->har); - - shr->spec[0]+= t*(lacol[0] * shi->specr); - shr->spec[1]+= t*(lacol[1] * shi->specg); - shr->spec[2]+= t*(lacol[2] * shi->specb); - } - else { - /* specular shaders */ - float specfac, t; - - if (ma->spec_shader==MA_SPEC_PHONG) - specfac= Phong_Spec(vn, lv, view, shi->har, (vlr->flag & R_TANGENT) || (ma->mode & MA_TANGENT_V)); - else if (ma->spec_shader==MA_SPEC_COOKTORR) - specfac= CookTorr_Spec(vn, lv, view, shi->har, (vlr->flag & R_TANGENT) || (ma->mode & MA_TANGENT_V)); - else if (ma->spec_shader==MA_SPEC_BLINN) - specfac= Blinn_Spec(vn, lv, view, ma->refrac, (float)shi->har, (vlr->flag & R_TANGENT) || (ma->mode & MA_TANGENT_V)); - else if (ma->spec_shader==MA_SPEC_WARDISO) - specfac= WardIso_Spec( vn, lv, view, ma->rms, (vlr->flag & R_TANGENT) || (ma->mode & MA_TANGENT_V)); - else - specfac= Toon_Spec(vn, lv, view, ma->param[2], ma->param[3], (vlr->flag & R_TANGENT) || (ma->mode & MA_TANGENT_V)); - - /* area lamp correction */ - if (lar->type==LA_AREA) specfac*= inp; - - t= shadfac[3]*shi->spec*visifac*specfac; - - if (ma->mode & MA_RAMP_SPEC) { - float spec[3]; - do_specular_ramp(shi, specfac, t, spec); - shr->spec[0]+= t*(lacol[0] * spec[0]); - shr->spec[1]+= t*(lacol[1] * spec[1]); - shr->spec[2]+= t*(lacol[2] * spec[2]); - } - else { - shr->spec[0]+= t*(lacol[0] * shi->specr); - shr->spec[1]+= t*(lacol[1] * shi->specg); - shr->spec[2]+= t*(lacol[2] * shi->specb); - } - } - } - } -} - -static void shade_lamp_loop_only_shadow(ShadeInput *shi, ShadeResult *shr) -{ - - if (R.r.mode & R_SHADOW) { - ListBase *lights; - LampRen *lar; - GroupObject *go; - float inpr, lv[3]; - float /* *view, */ shadfac[4]; - float ir, accum, visifac, lampdist; - float shaded = 0.0f, lightness = 0.0f; - - - /* view= shi->view; */ /* UNUSED */ - accum= ir= 0.0f; - - lights= get_lights(shi); - for (go=lights->first; go; go= go->next) { - lar= go->lampren; - if (lar==NULL) continue; - - if (lar->mode & LA_LAYER) if ((lar->lay & shi->obi->lay)==0) continue; - if ((lar->lay & shi->lay)==0) continue; - - if (lar->shb || (lar->mode & LA_SHAD_RAY)) { - visifac= lamp_get_visibility(lar, shi->co, lv, &lampdist); - ir+= 1.0f; - - if (visifac <= 0.0f) { - if (shi->mat->shadowonly_flag == MA_SO_OLD) - accum+= 1.0f; - - continue; - } - inpr= dot_v3v3(shi->vn, lv); - if (inpr <= 0.0f) { - if (shi->mat->shadowonly_flag == MA_SO_OLD) - accum+= 1.0f; - - continue; - } - - lamp_get_shadow(lar, shi, inpr, shadfac, shi->depth); - - if (shi->mat->shadowonly_flag == MA_SO_OLD) { - /* Old "Shadows Only" */ - accum+= (1.0f-visifac) + (visifac)*IMB_colormanagement_get_luminance(shadfac)*shadfac[3]; - } - else { - shaded += IMB_colormanagement_get_luminance(shadfac)*shadfac[3] * visifac * lar->energy; - - if (shi->mat->shadowonly_flag == MA_SO_SHADOW) { - lightness += visifac * lar->energy; - } - } - } - } - - /* Apply shadows as alpha */ - if (ir>0.0f) { - if (shi->mat->shadowonly_flag == MA_SO_OLD) { - accum = 1.0f - accum/ir; - } - else { - if (shi->mat->shadowonly_flag == MA_SO_SHADOW) { - if (lightness > 0.0f) { - /* Get shadow value from between 0.0f and non-shadowed lightness */ - accum = (lightness - shaded) / (lightness); - } - else { - accum = 0.0f; - } - } - else { /* shadowonly_flag == MA_SO_SHADED */ - /* Use shaded value */ - accum = 1.0f - shaded; - } - } - - shr->alpha= (shi->alpha)*(accum); - if (shr->alpha<0.0f) shr->alpha=0.0f; - } - else { - /* If "fully shaded", use full alpha even on areas that have no lights */ - if (shi->mat->shadowonly_flag == MA_SO_SHADED) shr->alpha=shi->alpha; - else shr->alpha= 0.f; - } - } - - /* quite disputable this... also note it doesn't mirror-raytrace */ - if ((R.wrld.mode & (WO_AMB_OCC|WO_ENV_LIGHT)) && shi->amb!=0.0f) { - float f; - - if (R.wrld.mode & WO_AMB_OCC) { - f= R.wrld.aoenergy*shi->amb; - - if (R.wrld.aomix==WO_AOADD) { - if (shi->mat->shadowonly_flag == MA_SO_OLD) { - f= f*(1.0f - IMB_colormanagement_get_luminance(shi->ao)); - shr->alpha= (shr->alpha + f)*f; - } - else { - shr->alpha -= f*IMB_colormanagement_get_luminance(shi->ao); - if (shr->alpha<0.0f) shr->alpha=0.0f; - } - } - else /* AO Multiply */ - shr->alpha= (1.0f - f)*shr->alpha + f*(1.0f - (1.0f - shr->alpha)*IMB_colormanagement_get_luminance(shi->ao)); - } - - if (R.wrld.mode & WO_ENV_LIGHT) { - if (shi->mat->shadowonly_flag == MA_SO_OLD) { - f= R.wrld.ao_env_energy*shi->amb*(1.0f - IMB_colormanagement_get_luminance(shi->env)); - shr->alpha= (shr->alpha + f)*f; - } - else { - f= R.wrld.ao_env_energy*shi->amb; - shr->alpha -= f*IMB_colormanagement_get_luminance(shi->env); - if (shr->alpha<0.0f) shr->alpha=0.0f; - } - } - } -} - -/* let's map negative light as if it mirrors positive light, otherwise negative values disappear */ -static void wrld_exposure_correct(float diff[3]) -{ - - diff[0]= R.wrld.linfac*(1.0f-expf( diff[0]*R.wrld.logfac) ); - diff[1]= R.wrld.linfac*(1.0f-expf( diff[1]*R.wrld.logfac) ); - diff[2]= R.wrld.linfac*(1.0f-expf( diff[2]*R.wrld.logfac) ); -} - -void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr) -{ - /* Passes which might need to know material color. - * - * It seems to be faster to just calculate material color - * even if the pass doesn't really need it than trying to - * figure out whether color is really needed or not. - */ - const int color_passes = - SCE_PASS_COMBINED | SCE_PASS_RGBA | SCE_PASS_DIFFUSE | SCE_PASS_SPEC | - SCE_PASS_REFLECT | SCE_PASS_NORMAL | SCE_PASS_REFRACT | SCE_PASS_EMIT | SCE_PASS_SHADOW; - - Material *ma= shi->mat; - int passflag= shi->passflag; - - memset(shr, 0, sizeof(ShadeResult)); - - if (!(shi->mode & MA_TRANSP)) shi->alpha = 1.0f; - - /* separate loop */ - if (ma->mode & MA_ONLYSHADOW) { - shade_lamp_loop_only_shadow(shi, shr); - return; - } - - /* envmap hack, always reset */ - shi->refcol[0]= shi->refcol[1]= shi->refcol[2]= shi->refcol[3]= 0.0f; - - /* material color itself */ - if (passflag & color_passes) { - if (false) { - /* pass */ - } -#ifdef WITH_FREESTYLE - else if (ma->vcol_alpha) { - shi->r= shi->vcol[0]; - shi->g= shi->vcol[1]; - shi->b= shi->vcol[2]; - shi->alpha= shi->vcol[3]; - } -#endif - else if (ma->mode & (MA_VERTEXCOLP)) { - float neg_alpha = 1.0f - shi->vcol[3]; - shi->r= shi->r*neg_alpha + shi->vcol[0]*shi->vcol[3]; - shi->g= shi->g*neg_alpha + shi->vcol[1]*shi->vcol[3]; - shi->b= shi->b*neg_alpha + shi->vcol[2]*shi->vcol[3]; - } - if (ma->texco) { - do_material_tex(shi, &R); - if (!(shi->mode & MA_TRANSP)) shi->alpha = 1.0f; - } - - shr->col[0]= shi->r*shi->alpha; - shr->col[1]= shi->g*shi->alpha; - shr->col[2]= shi->b*shi->alpha; - shr->col[3]= shi->alpha; - - if ((ma->sss_flag & MA_DIFF_SSS) && !sss_pass_done(&R, ma)) { - if (ma->sss_texfac == 0.0f) { - shi->r= shi->g= shi->b= shi->alpha= 1.0f; - shr->col[0]= shr->col[1]= shr->col[2]= shr->col[3]= 1.0f; - } - else { - shi->r= pow(max_ff(shi->r, 0.0f), ma->sss_texfac); - shi->g= pow(max_ff(shi->g, 0.0f), ma->sss_texfac); - shi->b= pow(max_ff(shi->b, 0.0f), ma->sss_texfac); - shi->alpha= pow(max_ff(shi->alpha, 0.0f), ma->sss_texfac); - - shr->col[0]= pow(max_ff(shr->col[0], 0.0f), ma->sss_texfac); - shr->col[1]= pow(max_ff(shr->col[1], 0.0f), ma->sss_texfac); - shr->col[2]= pow(max_ff(shr->col[2], 0.0f), ma->sss_texfac); - shr->col[3]= pow(max_ff(shr->col[3], 0.0f), ma->sss_texfac); - } - } - } - - if (ma->mode & MA_SHLESS) { - shr->combined[0]= shi->r; - shr->combined[1]= shi->g; - shr->combined[2]= shi->b; - shr->alpha= shi->alpha; - goto finally_shadeless; - } - - if ( (ma->mode & (MA_VERTEXCOL|MA_VERTEXCOLP))== MA_VERTEXCOL ) { /* vertexcolor light */ - shr->emit[0]= shi->r*(shi->emit+shi->vcol[0]*shi->vcol[3]); - shr->emit[1]= shi->g*(shi->emit+shi->vcol[1]*shi->vcol[3]); - shr->emit[2]= shi->b*(shi->emit+shi->vcol[2]*shi->vcol[3]); - } - else { - shr->emit[0]= shi->r*shi->emit; - shr->emit[1]= shi->g*shi->emit; - shr->emit[2]= shi->b*shi->emit; - } - - /* AO pass */ - if (((passflag & SCE_PASS_COMBINED) && (shi->combinedflag & (SCE_PASS_AO|SCE_PASS_ENVIRONMENT|SCE_PASS_INDIRECT))) || - (passflag & (SCE_PASS_AO|SCE_PASS_ENVIRONMENT|SCE_PASS_INDIRECT))) { - if ((R.wrld.mode & (WO_AMB_OCC|WO_ENV_LIGHT|WO_INDIRECT_LIGHT)) && (R.r.mode & R_SHADOW)) { - /* AO was calculated for scanline already */ - if (shi->depth || shi->volume_depth) - ambient_occlusion(shi); - copy_v3_v3(shr->ao, shi->ao); - copy_v3_v3(shr->env, shi->env); /* XXX multiply */ - copy_v3_v3(shr->indirect, shi->indirect); /* XXX multiply */ - } - else { - shr->ao[0]= shr->ao[1]= shr->ao[2]= 1.0f; - zero_v3(shr->env); - zero_v3(shr->indirect); - } - } - - /* lighting pass */ - if (passflag & (SCE_PASS_COMBINED|SCE_PASS_DIFFUSE|SCE_PASS_SPEC|SCE_PASS_SHADOW)) { - GroupObject *go; - ListBase *lights; - LampRen *lar; - - lights= get_lights(shi); - for (go=lights->first; go; go= go->next) { - lar= go->lampren; - if (lar==NULL) continue; - - /* test for lamp layer */ - if (lar->mode & LA_LAYER) if ((lar->lay & shi->obi->lay)==0) continue; - if ((lar->lay & shi->lay)==0) continue; - - /* accumulates in shr->diff and shr->spec and shr->shad (diffuse with shadow!) */ - shade_one_light(lar, shi, shr, passflag); - } - - /* this check is to prevent only shadow lamps from producing negative - * colors.*/ - if (shr->spec[0] < 0) shr->spec[0] = 0; - if (shr->spec[1] < 0) shr->spec[1] = 0; - if (shr->spec[2] < 0) shr->spec[2] = 0; - - if (shr->shad[0] < 0) shr->shad[0] = 0; - if (shr->shad[1] < 0) shr->shad[1] = 0; - if (shr->shad[2] < 0) shr->shad[2] = 0; - - if (ma->sss_flag & MA_DIFF_SSS) { - float sss[3], col[3], invalpha, texfac= ma->sss_texfac; - - /* this will return false in the preprocess stage */ - if (sample_sss(&R, ma, shi->co, sss)) { - invalpha= (shr->col[3] > FLT_EPSILON)? 1.0f/shr->col[3]: 1.0f; - - if (texfac==0.0f) { - copy_v3_v3(col, shr->col); - mul_v3_fl(col, invalpha); - } - else if (texfac==1.0f) { - col[0]= col[1]= col[2]= 1.0f; - mul_v3_fl(col, invalpha); - } - else { - copy_v3_v3(col, shr->col); - mul_v3_fl(col, invalpha); - col[0]= pow(max_ff(col[0], 0.0f), 1.0f-texfac); - col[1]= pow(max_ff(col[1], 0.0f), 1.0f-texfac); - col[2]= pow(max_ff(col[2], 0.0f), 1.0f-texfac); - } - - shr->diff[0]= sss[0]*col[0]; - shr->diff[1]= sss[1]*col[1]; - shr->diff[2]= sss[2]*col[2]; - - if (shi->combinedflag & SCE_PASS_SHADOW) { - shr->shad[0]= shr->diff[0]; - shr->shad[1]= shr->diff[1]; - shr->shad[2]= shr->diff[2]; - } - } - } - - if (shi->combinedflag & SCE_PASS_SHADOW) - copy_v3_v3(shr->diffshad, shr->shad); - else - copy_v3_v3(shr->diffshad, shr->diff); - - copy_v3_v3(shr->combined, shr->diffshad); - - /* calculate shadow pass, we use a multiplication mask */ - /* Even if diff = 0,0,0, it does matter what the shadow pass is, since we may want it 'for itself'! */ - if (passflag & SCE_PASS_SHADOW) { - if (shr->diff[0]!=0.0f) shr->shad[0]= shr->shad[0]/shr->diff[0]; - /* can't determine proper shadow from shad/diff (0/0), so use shadow intensity */ - else if (shr->shad[0]==0.0f) shr->shad[0]= shr->shad[3]; - - if (shr->diff[1]!=0.0f) shr->shad[1]= shr->shad[1]/shr->diff[1]; - else if (shr->shad[1]==0.0f) shr->shad[1]= shr->shad[3]; - - if (shr->diff[2]!=0.0f) shr->shad[2]= shr->shad[2]/shr->diff[2]; - else if (shr->shad[2]==0.0f) shr->shad[2]= shr->shad[3]; - } - - /* exposure correction */ - if ((R.wrld.exp!=0.0f || R.wrld.range!=1.0f) && !R.sss_points) { - wrld_exposure_correct(shr->combined); /* has no spec! */ - wrld_exposure_correct(shr->spec); - } - } - - /* alpha in end, spec can influence it */ - if (passflag & (SCE_PASS_COMBINED)) { - if ((ma->fresnel_tra!=0.0f) && (shi->mode & MA_TRANSP)) - shi->alpha*= fresnel_fac(shi->view, shi->vn, ma->fresnel_tra_i, ma->fresnel_tra); - - /* note: shi->mode! */ - if (shi->mode & MA_TRANSP && (shi->mode & (MA_ZTRANSP|MA_RAYTRANSP))) { - if (shi->spectra!=0.0f) { - float t = max_fff(shr->spec[0], shr->spec[1], shr->spec[2]); - t *= shi->spectra; - if (t>1.0f) t= 1.0f; - shi->alpha= (1.0f-t)*shi->alpha+t; - } - } - } - shr->alpha= shi->alpha; - - /* from now stuff everything in shr->combined: ambient, AO, ramps, exposure */ - if (!(ma->sss_flag & MA_DIFF_SSS) || !sss_pass_done(&R, ma)) { - if (R.r.mode & R_SHADOW) { - /* add AO in combined? */ - if (R.wrld.mode & WO_AMB_OCC) - if (shi->combinedflag & SCE_PASS_AO) - ambient_occlusion_apply(shi, shr); - - if (R.wrld.mode & WO_ENV_LIGHT) - if (shi->combinedflag & SCE_PASS_ENVIRONMENT) - environment_lighting_apply(shi, shr); - - if (R.wrld.mode & WO_INDIRECT_LIGHT) - if (shi->combinedflag & SCE_PASS_INDIRECT) - indirect_lighting_apply(shi, shr); - } - - shr->combined[0]+= shi->ambr; - shr->combined[1]+= shi->ambg; - shr->combined[2]+= shi->ambb; - - if (ma->mode & MA_RAMP_COL) ramp_diffuse_result(shr->combined, shi); - } - - if (ma->mode & MA_RAMP_SPEC) ramp_spec_result(shr->spec, shi); - - /* refcol is for envmap only */ - if (shi->refcol[0]!=0.0f) { - float result[3]; - - result[0]= shi->mirr*shi->refcol[1] + (1.0f - shi->mirr*shi->refcol[0])*shr->combined[0]; - result[1]= shi->mirg*shi->refcol[2] + (1.0f - shi->mirg*shi->refcol[0])*shr->combined[1]; - result[2]= shi->mirb*shi->refcol[3] + (1.0f - shi->mirb*shi->refcol[0])*shr->combined[2]; - - if (passflag & SCE_PASS_REFLECT) - sub_v3_v3v3(shr->refl, result, shr->combined); - - if (shi->combinedflag & SCE_PASS_REFLECT) - copy_v3_v3(shr->combined, result); - - } - - /* and add emit and spec */ - if (shi->combinedflag & SCE_PASS_EMIT) - add_v3_v3(shr->combined, shr->emit); - if (shi->combinedflag & SCE_PASS_SPEC) - add_v3_v3(shr->combined, shr->spec); - - - /* Last section of this function applies to shadeless colors too */ -finally_shadeless: - - /* modulate by the object color */ - if ((ma->shade_flag & MA_OBCOLOR) && shi->obr->ob) { - if (!(ma->sss_flag & MA_DIFF_SSS) || !sss_pass_done(&R, ma)) { - float obcol[4]; - - copy_v4_v4(obcol, shi->obr->ob->col); - CLAMP(obcol[3], 0.0f, 1.0f); - - shr->combined[0] *= obcol[0]; - shr->combined[1] *= obcol[1]; - shr->combined[2] *= obcol[2]; - if (shi->mode & MA_TRANSP) shr->alpha *= obcol[3]; - } - } - - shr->combined[3]= shr->alpha; -} - -/* used for "Lamp Data" shader node */ -static float lamp_get_data_internal(ShadeInput *shi, GroupObject *go, float col[4], float lv[3], float *dist, float shadow[4]) -{ - LampRen *lar = go->lampren; - float visifac, inp; - - if (!lar - || ((lar->mode & LA_LAYER) && (lar->lay & shi->obi->lay) == 0) - || (lar->lay & shi->lay) == 0) - return 0.0f; - - if (lar->mode & LA_TEXTURE) - do_lamp_tex(lar, lv, shi, col, LA_TEXTURE); - - visifac = lamp_get_visibility(lar, shi->co, lv, dist); - - if (visifac == 0.0f - || lar->type == LA_HEMI - || (lar->type != LA_SPOT && !(lar->mode & LA_SHAD_RAY)) - || (R.r.scemode & R_BUTS_PREVIEW)) - return visifac; - - inp = dot_v3v3(shi->vn, lv); - - if (inp > 0.0f) { - float shadfac[4]; - - shadow[0] = lar->shdwr; - shadow[1] = lar->shdwg; - shadow[2] = lar->shdwb; - - if (lar->mode & LA_SHAD_TEX) - do_lamp_tex(lar, lv, shi, shadow, LA_SHAD_TEX); - - if (R.r.mode & R_SHADOW) { - lamp_get_shadow(lar, shi, inp, shadfac, shi->depth); - - shadow[0] = 1.0f - ((1.0f - shadfac[0] * shadfac[3]) * (1.0f - shadow[0])); - shadow[1] = 1.0f - ((1.0f - shadfac[1] * shadfac[3]) * (1.0f - shadow[1])); - shadow[2] = 1.0f - ((1.0f - shadfac[2] * shadfac[3]) * (1.0f - shadow[2])); - } - } - - return visifac; -} - -float RE_lamp_get_data(ShadeInput *shi, Object *lamp_obj, float col[4], float lv[3], float *dist, float shadow[4]) -{ - col[0] = col[1] = col[2] = 0.0f; - col[3] = 1.0f; - copy_v3_v3(lv, shi->vn); - *dist = 1.0f; - shadow[0] = shadow[1] = shadow[2] = shadow[3] = 1.0f; - - if (lamp_obj->type == OB_LAMP) { - GroupObject *go; - Lamp *lamp = (Lamp *)lamp_obj->data; - - col[0] = lamp->r * lamp->energy; - col[1] = lamp->g * lamp->energy; - col[2] = lamp->b * lamp->energy; - - if (R.r.scemode & R_BUTS_PREVIEW) { - for (go = R.lights.first; go; go = go->next) { - /* "Lamp.002" is main key light of material preview */ - if (STREQ(go->ob->id.name + 2, "Lamp.002")) - return lamp_get_data_internal(shi, go, col, lv, dist, shadow); - } - return 0.0f; - } - - if (shi->mat && shi->mat->group) { - for (go = shi->mat->group->gobject.first; go; go = go->next) { - if (go->ob == lamp_obj) - return lamp_get_data_internal(shi, go, col, lv, dist, shadow); - } - } - - for (go = R.lights.first; go; go = go->next) { - if (go->ob == lamp_obj) - return lamp_get_data_internal(shi, go, col, lv, dist, shadow); - } - } - - return 0.0f; -} - -const float (*RE_object_instance_get_matrix(struct ObjectInstanceRen *obi, int matrix_id))[4] -{ - if (obi) { - switch (matrix_id) { - case RE_OBJECT_INSTANCE_MATRIX_OB: - return (const float(*)[4])obi->obmat; - case RE_OBJECT_INSTANCE_MATRIX_OBINV: - return (const float(*)[4])obi->obinvmat; - case RE_OBJECT_INSTANCE_MATRIX_LOCALTOVIEW: - return (const float(*)[4])obi->localtoviewmat; - case RE_OBJECT_INSTANCE_MATRIX_LOCALTOVIEWINV: - return (const float(*)[4])obi->localtoviewinvmat; - } - } - return NULL; -} - -float RE_object_instance_get_object_pass_index(struct ObjectInstanceRen *obi) -{ - return obi->ob->index; -} - -float RE_object_instance_get_random_id(struct ObjectInstanceRen *obi) -{ - return obi->random_id; -} - -const float (*RE_render_current_get_matrix(int matrix_id))[4] -{ - switch (matrix_id) { - case RE_VIEW_MATRIX: - return (const float(*)[4])R.viewmat; - case RE_VIEWINV_MATRIX: - return (const float(*)[4])R.viewinv; - } - return NULL; -} - -float RE_fresnel_dielectric(float incoming[3], float normal[3], float eta) -{ - /* compute fresnel reflectance without explicitly computing - * the refracted direction */ - float c = fabs(dot_v3v3(incoming, normal)); - float g = eta * eta - 1.0 + c * c; - float result; - - if (g > 0.0) { - g = sqrtf(g); - float A = (g - c) / (g + c); - float B = (c * (g + c) - 1.0) / (c * (g - c) + 1.0); - result = 0.5 * A * A * (1.0 + B * B); - } - else { - result = 1.0; /* TIR (no refracted component) */ - } - - return result; -} diff --git a/source/blender/render/intern/source/sss.c b/source/blender/render/intern/source/sss.c deleted file mode 100644 index c29da9b17c6..00000000000 --- a/source/blender/render/intern/source/sss.c +++ /dev/null @@ -1,1074 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2007 Blender Foundation. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/render/intern/source/sss.c - * \ingroup render - */ - -/* Possible Improvements: - * - add fresnel terms - * - adapt Rd table to scale, now with small scale there are a lot of misses? - * - possible interesting method: perform sss on all samples in the tree, - * and then use those values interpolated somehow later. can also do this - * filtering on demand for speed. since we are doing things in screen - * space now there is an exact correspondence - * - avoid duplicate shading (filtering points in advance, irradiance cache - * like lookup?) - * - lower resolution samples - */ - -#include <math.h> -#include <string.h> -#include <stdio.h> -#include <string.h> - -/* external modules: */ -#include "MEM_guardedalloc.h" - -#include "BLI_math.h" -#include "BLI_blenlib.h" -#include "BLI_utildefines.h" -#include "BLI_ghash.h" -#include "BLI_memarena.h" - -#include "BLT_translation.h" - - -#include "DNA_material_types.h" - -#include "BKE_global.h" -#include "BKE_main.h" -#include "BKE_scene.h" - - -/* this module */ -#include "render_types.h" -#include "sss.h" - -/* Generic Multiple Scattering API */ - -/* Relevant papers: - * [1] A Practical Model for Subsurface Light Transport - * [2] A Rapid Hierarchical Rendering Technique for Translucent Materials - * [3] Efficient Rendering of Local Subsurface Scattering - * [4] Implementing a skin BSSRDF (or several...) - */ - -/* Defines */ - -#define RD_TABLE_RANGE 100.0f -#define RD_TABLE_RANGE_2 10000.0f -#define RD_TABLE_SIZE 10000 - -#define MAX_OCTREE_NODE_POINTS 8 -#define MAX_OCTREE_DEPTH 15 - -/* Struct Definitions */ - -struct ScatterSettings { - float eta; /* index of refraction */ - float sigma_a; /* absorption coefficient */ - float sigma_s_; /* reduced scattering coefficient */ - float sigma_t_; /* reduced extinction coefficient */ - float sigma; /* effective extinction coefficient */ - float Fdr; /* diffuse fresnel reflectance */ - float D; /* diffusion constant */ - float A; - float alpha_; /* reduced albedo */ - float zr; /* distance of virtual lightsource above surface */ - float zv; /* distance of virtual lightsource below surface */ - float ld; /* mean free path */ - float ro; /* diffuse reflectance */ - float color; - float invsigma_t_; - float frontweight; - float backweight; - - float *tableRd; /* lookup table to avoid computing Rd */ - float *tableRd2; /* lookup table to avoid computing Rd for bigger values */ -}; - -typedef struct ScatterPoint { - float co[3]; - float rad[3]; - float area; - int back; -} ScatterPoint; - -typedef struct ScatterNode { - float co[3]; - float rad[3]; - float backrad[3]; - float area, backarea; - - int totpoint; - ScatterPoint *points; - - float split[3]; - struct ScatterNode *child[8]; -} ScatterNode; - -struct ScatterTree { - MemArena *arena; - - ScatterSettings *ss[3]; - float error, scale; - - ScatterNode *root; - ScatterPoint *points; - ScatterPoint **refpoints; - ScatterPoint **tmppoints; - int totpoint; - float min[3], max[3]; -}; - -typedef struct ScatterResult { - float rad[3]; - float backrad[3]; - float rdsum[3]; - float backrdsum[3]; -} ScatterResult; - -/* Functions for BSSRDF reparametrization in to more intuitive parameters, - * see [2] section 4 for more info. */ - -static float f_Rd(float alpha_, float A, float ro) -{ - float sq; - - sq = sqrtf(3.0f * (1.0f - alpha_)); - return (alpha_/2.0f)*(1.0f + expf((-4.0f/3.0f)*A*sq))*expf(-sq) - ro; -} - -static float compute_reduced_albedo(ScatterSettings *ss) -{ - const float tolerance= 1e-8; - const int max_iteration_count= 20; - float d, fsub, xn_1= 0.0f, xn= 1.0f, fxn, fxn_1; - int i; - - /* use secant method to compute reduced albedo using Rd function inverse - * with a given reflectance */ - fxn= f_Rd(xn, ss->A, ss->ro); - fxn_1= f_Rd(xn_1, ss->A, ss->ro); - - for (i= 0; i < max_iteration_count; i++) { - fsub= (fxn - fxn_1); - if (fabsf(fsub) < tolerance) - break; - d= ((xn - xn_1)/fsub)*fxn; - if (fabsf(d) < tolerance) - break; - - xn_1= xn; - fxn_1= fxn; - xn= xn - d; - - if (xn > 1.0f) xn= 1.0f; - if (xn_1 > 1.0f) xn_1= 1.0f; - - fxn= f_Rd(xn, ss->A, ss->ro); - } - - /* avoid division by zero later */ - if (xn <= 0.0f) - xn= 0.00001f; - - return xn; -} - -/* Exponential falloff functions */ - -static float Rd_rsquare(ScatterSettings *ss, float rr) -{ - float sr, sv, Rdr, Rdv; - - sr = sqrtf(rr + ss->zr * ss->zr); - sv = sqrtf(rr + ss->zv * ss->zv); - - Rdr= ss->zr*(1.0f + ss->sigma*sr)*expf(-ss->sigma*sr)/(sr*sr*sr); - Rdv= ss->zv*(1.0f + ss->sigma*sv)*expf(-ss->sigma*sv)/(sv*sv*sv); - - return /*ss->alpha_*/(1.0f/(4.0f*(float)M_PI))*(Rdr + Rdv); -} - -static float Rd(ScatterSettings *ss, float r) -{ - return Rd_rsquare(ss, r*r); -} - -/* table lookups for Rd. this avoids expensive exp calls. we use two - * separate tables as well for lower and higher numbers to improve - * precision, since the number are poorly distributed because we do - * a lookup with the squared distance for smaller distances, saving - * another sqrt. */ - -static void approximate_Rd_rgb(ScatterSettings **ss, float rr, float *rd) -{ - float indexf, t, idxf; - int index; - - if (rr > (RD_TABLE_RANGE_2 * RD_TABLE_RANGE_2)) { - /* pass */ - } - else if (rr > RD_TABLE_RANGE) { - rr = sqrtf(rr); - indexf= rr*(RD_TABLE_SIZE/RD_TABLE_RANGE_2); - index= (int)indexf; - idxf= (float)index; - t= indexf - idxf; - - if (index >= 0 && index < RD_TABLE_SIZE) { - rd[0]= (ss[0]->tableRd2[index]*(1-t) + ss[0]->tableRd2[index+1]*t); - rd[1]= (ss[1]->tableRd2[index]*(1-t) + ss[1]->tableRd2[index+1]*t); - rd[2]= (ss[2]->tableRd2[index]*(1-t) + ss[2]->tableRd2[index+1]*t); - return; - } - } - else { - indexf= rr*(RD_TABLE_SIZE/RD_TABLE_RANGE); - index= (int)indexf; - idxf= (float)index; - t= indexf - idxf; - - if (index >= 0 && index < RD_TABLE_SIZE) { - rd[0]= (ss[0]->tableRd[index]*(1-t) + ss[0]->tableRd[index+1]*t); - rd[1]= (ss[1]->tableRd[index]*(1-t) + ss[1]->tableRd[index+1]*t); - rd[2]= (ss[2]->tableRd[index]*(1-t) + ss[2]->tableRd[index+1]*t); - return; - } - } - - /* fallback to slow Rd computation */ - rd[0]= Rd_rsquare(ss[0], rr); - rd[1]= Rd_rsquare(ss[1], rr); - rd[2]= Rd_rsquare(ss[2], rr); -} - -static void build_Rd_table(ScatterSettings *ss) -{ - float r; - int i, size = RD_TABLE_SIZE+1; - - ss->tableRd= MEM_mallocN(sizeof(float)*size, "scatterTableRd"); - ss->tableRd2= MEM_mallocN(sizeof(float)*size, "scatterTableRd"); - - for (i= 0; i < size; i++) { - r= i*(RD_TABLE_RANGE/RD_TABLE_SIZE); -#if 0 - if (r < ss->invsigma_t_*ss->invsigma_t_) { - r= ss->invsigma_t_*ss->invsigma_t_; - } -#endif - ss->tableRd[i]= Rd(ss, sqrtf(r)); - - r= i*(RD_TABLE_RANGE_2/RD_TABLE_SIZE); -#if 0 - if (r < ss->invsigma_t_) { - r= ss->invsigma_t_; - } -#endif - ss->tableRd2[i]= Rd(ss, r); - } -} - -ScatterSettings *scatter_settings_new(float refl, float radius, float ior, float reflfac, float frontweight, float backweight) -{ - ScatterSettings *ss; - - ss= MEM_callocN(sizeof(ScatterSettings), "ScatterSettings"); - - /* see [1] and [3] for these formulas */ - ss->eta= ior; - ss->Fdr= -1.440f/ior*ior + 0.710f/ior + 0.668f + 0.0636f*ior; - ss->A= (1.0f + ss->Fdr)/(1.0f - ss->Fdr); - ss->ld= radius; - ss->ro= min_ff(refl, 0.99f); - ss->color= ss->ro*reflfac + (1.0f-reflfac); - - ss->alpha_= compute_reduced_albedo(ss); - - ss->sigma= 1.0f/ss->ld; - ss->sigma_t_= ss->sigma/sqrtf(3.0f*(1.0f - ss->alpha_)); - ss->sigma_s_= ss->alpha_*ss->sigma_t_; - ss->sigma_a= ss->sigma_t_ - ss->sigma_s_; - - ss->D= 1.0f/(3.0f*ss->sigma_t_); - - ss->zr= 1.0f/ss->sigma_t_; - ss->zv= ss->zr + 4.0f*ss->A*ss->D; - - ss->invsigma_t_= 1.0f/ss->sigma_t_; - - ss->frontweight= frontweight; - ss->backweight= backweight; - - /* precompute a table of Rd values for quick lookup */ - build_Rd_table(ss); - - return ss; -} - -void scatter_settings_free(ScatterSettings *ss) -{ - MEM_freeN(ss->tableRd); - MEM_freeN(ss->tableRd2); - MEM_freeN(ss); -} - -/* Hierarchical method as in [2]. */ - -/* traversal */ - -#define SUBNODE_INDEX(co, split) \ - ((co[0]>=split[0]) + (co[1]>=split[1])*2 + (co[2]>=split[2])*4) - -static void add_radiance(ScatterTree *tree, float *frontrad, float *backrad, float area, float backarea, float rr, ScatterResult *result) -{ - float rd[3], frontrd[3], backrd[3]; - - approximate_Rd_rgb(tree->ss, rr, rd); - - if (frontrad && area) { - frontrd[0] = rd[0]*area; - frontrd[1] = rd[1]*area; - frontrd[2] = rd[2]*area; - - result->rad[0] += frontrad[0]*frontrd[0]; - result->rad[1] += frontrad[1]*frontrd[1]; - result->rad[2] += frontrad[2]*frontrd[2]; - - result->rdsum[0] += frontrd[0]; - result->rdsum[1] += frontrd[1]; - result->rdsum[2] += frontrd[2]; - } - if (backrad && backarea) { - backrd[0] = rd[0]*backarea; - backrd[1] = rd[1]*backarea; - backrd[2] = rd[2]*backarea; - - result->backrad[0] += backrad[0]*backrd[0]; - result->backrad[1] += backrad[1]*backrd[1]; - result->backrad[2] += backrad[2]*backrd[2]; - - result->backrdsum[0] += backrd[0]; - result->backrdsum[1] += backrd[1]; - result->backrdsum[2] += backrd[2]; - } -} - -static void traverse_octree(ScatterTree *tree, ScatterNode *node, const float co[3], int self, ScatterResult *result) -{ - float sub[3], dist; - int i, index = 0; - - if (node->totpoint > 0) { - /* leaf - add radiance from all samples */ - for (i=0; i<node->totpoint; i++) { - ScatterPoint *p= &node->points[i]; - - sub_v3_v3v3(sub, co, p->co); - dist= dot_v3v3(sub, sub); - - if (p->back) - add_radiance(tree, NULL, p->rad, 0.0f, p->area, dist, result); - else - add_radiance(tree, p->rad, NULL, p->area, 0.0f, dist, result); - } - } - else { - /* branch */ - if (self) - index = SUBNODE_INDEX(co, node->split); - - for (i=0; i<8; i++) { - if (node->child[i]) { - ScatterNode *subnode= node->child[i]; - - if (self && index == i) { - /* always traverse node containing the point */ - traverse_octree(tree, subnode, co, 1, result); - } - else { - /* decide subnode traversal based on maximum solid angle */ - sub_v3_v3v3(sub, co, subnode->co); - dist= dot_v3v3(sub, sub); - - /* actually area/dist > error, but this avoids division */ - if (subnode->area+subnode->backarea>tree->error*dist) { - traverse_octree(tree, subnode, co, 0, result); - } - else { - add_radiance(tree, subnode->rad, subnode->backrad, - subnode->area, subnode->backarea, dist, result); - } - } - } - } - } -} - -static void compute_radiance(ScatterTree *tree, const float co[3], float *rad) -{ - ScatterResult result; - float rdsum[3], backrad[3], backrdsum[3]; - - memset(&result, 0, sizeof(result)); - - traverse_octree(tree, tree->root, co, 1, &result); - - /* the original paper doesn't do this, but we normalize over the - * sampled area and multiply with the reflectance. this is because - * our point samples are incomplete, there are no samples on parts - * of the mesh not visible from the camera. this can not only make - * it darker, but also lead to ugly color shifts */ - - mul_v3_fl(result.rad, tree->ss[0]->frontweight); - mul_v3_fl(result.backrad, tree->ss[0]->backweight); - - copy_v3_v3(rad, result.rad); - add_v3_v3v3(backrad, result.rad, result.backrad); - - copy_v3_v3(rdsum, result.rdsum); - add_v3_v3v3(backrdsum, result.rdsum, result.backrdsum); - - if (rdsum[0] > 1e-16f) rad[0]= tree->ss[0]->color*rad[0]/rdsum[0]; - if (rdsum[1] > 1e-16f) rad[1]= tree->ss[1]->color*rad[1]/rdsum[1]; - if (rdsum[2] > 1e-16f) rad[2]= tree->ss[2]->color*rad[2]/rdsum[2]; - - if (backrdsum[0] > 1e-16f) backrad[0]= tree->ss[0]->color*backrad[0]/backrdsum[0]; - if (backrdsum[1] > 1e-16f) backrad[1]= tree->ss[1]->color*backrad[1]/backrdsum[1]; - if (backrdsum[2] > 1e-16f) backrad[2]= tree->ss[2]->color*backrad[2]/backrdsum[2]; - - rad[0]= MAX2(rad[0], backrad[0]); - rad[1]= MAX2(rad[1], backrad[1]); - rad[2]= MAX2(rad[2], backrad[2]); -} - -/* building */ - -static void sum_leaf_radiance(ScatterTree *UNUSED(tree), ScatterNode *node) -{ - ScatterPoint *p; - float rad, totrad= 0.0f, inv; - int i; - - node->co[0]= node->co[1]= node->co[2]= 0.0; - node->rad[0]= node->rad[1]= node->rad[2]= 0.0; - node->backrad[0]= node->backrad[1]= node->backrad[2]= 0.0; - - /* compute total rad, rad weighted average position, - * and total area */ - for (i=0; i<node->totpoint; i++) { - p= &node->points[i]; - - rad= p->area*fabsf(p->rad[0] + p->rad[1] + p->rad[2]); - totrad += rad; - - node->co[0] += rad*p->co[0]; - node->co[1] += rad*p->co[1]; - node->co[2] += rad*p->co[2]; - - if (p->back) { - node->backrad[0] += p->rad[0]*p->area; - node->backrad[1] += p->rad[1]*p->area; - node->backrad[2] += p->rad[2]*p->area; - - node->backarea += p->area; - } - else { - node->rad[0] += p->rad[0]*p->area; - node->rad[1] += p->rad[1]*p->area; - node->rad[2] += p->rad[2]*p->area; - - node->area += p->area; - } - } - - if (node->area > 1e-16f) { - inv= 1.0f/node->area; - node->rad[0] *= inv; - node->rad[1] *= inv; - node->rad[2] *= inv; - } - if (node->backarea > 1e-16f) { - inv= 1.0f/node->backarea; - node->backrad[0] *= inv; - node->backrad[1] *= inv; - node->backrad[2] *= inv; - } - - if (totrad > 1e-16f) { - inv= 1.0f/totrad; - node->co[0] *= inv; - node->co[1] *= inv; - node->co[2] *= inv; - } - else { - /* make sure that if radiance is 0.0f, we still have these points in - * the tree at a good position, they count for rdsum too */ - for (i=0; i<node->totpoint; i++) { - p= &node->points[i]; - - node->co[0] += p->co[0]; - node->co[1] += p->co[1]; - node->co[2] += p->co[2]; - } - - node->co[0] /= node->totpoint; - node->co[1] /= node->totpoint; - node->co[2] /= node->totpoint; - } -} - -static void sum_branch_radiance(ScatterTree *UNUSED(tree), ScatterNode *node) -{ - ScatterNode *subnode; - float rad, totrad= 0.0f, inv; - int i, totnode; - - node->co[0]= node->co[1]= node->co[2]= 0.0; - node->rad[0]= node->rad[1]= node->rad[2]= 0.0; - node->backrad[0]= node->backrad[1]= node->backrad[2]= 0.0; - - /* compute total rad, rad weighted average position, - * and total area */ - for (i=0; i<8; i++) { - if (node->child[i] == NULL) - continue; - - subnode= node->child[i]; - - rad= subnode->area*fabsf(subnode->rad[0] + subnode->rad[1] + subnode->rad[2]); - rad += subnode->backarea*fabsf(subnode->backrad[0] + subnode->backrad[1] + subnode->backrad[2]); - totrad += rad; - - node->co[0] += rad*subnode->co[0]; - node->co[1] += rad*subnode->co[1]; - node->co[2] += rad*subnode->co[2]; - - node->rad[0] += subnode->rad[0]*subnode->area; - node->rad[1] += subnode->rad[1]*subnode->area; - node->rad[2] += subnode->rad[2]*subnode->area; - - node->backrad[0] += subnode->backrad[0]*subnode->backarea; - node->backrad[1] += subnode->backrad[1]*subnode->backarea; - node->backrad[2] += subnode->backrad[2]*subnode->backarea; - - node->area += subnode->area; - node->backarea += subnode->backarea; - } - - if (node->area > 1e-16f) { - inv= 1.0f/node->area; - node->rad[0] *= inv; - node->rad[1] *= inv; - node->rad[2] *= inv; - } - if (node->backarea > 1e-16f) { - inv= 1.0f/node->backarea; - node->backrad[0] *= inv; - node->backrad[1] *= inv; - node->backrad[2] *= inv; - } - - if (totrad > 1e-16f) { - inv= 1.0f/totrad; - node->co[0] *= inv; - node->co[1] *= inv; - node->co[2] *= inv; - } - else { - /* make sure that if radiance is 0.0f, we still have these points in - * the tree at a good position, they count for rdsum too */ - totnode= 0; - - for (i=0; i<8; i++) { - if (node->child[i]) { - subnode= node->child[i]; - - node->co[0] += subnode->co[0]; - node->co[1] += subnode->co[1]; - node->co[2] += subnode->co[2]; - - totnode++; - } - } - - node->co[0] /= totnode; - node->co[1] /= totnode; - node->co[2] /= totnode; - } -} - -static void sum_radiance(ScatterTree *tree, ScatterNode *node) -{ - if (node->totpoint > 0) { - sum_leaf_radiance(tree, node); - } - else { - int i; - - for (i=0; i<8; i++) - if (node->child[i]) - sum_radiance(tree, node->child[i]); - - sum_branch_radiance(tree, node); - } -} - -static void subnode_middle(int i, float *mid, float *subsize, float *submid) -{ - int x= i & 1, y= i & 2, z= i & 4; - - submid[0]= mid[0] + ((x)? subsize[0]: -subsize[0]); - submid[1]= mid[1] + ((y)? subsize[1]: -subsize[1]); - submid[2]= mid[2] + ((z)? subsize[2]: -subsize[2]); -} - -static void create_octree_node(ScatterTree *tree, ScatterNode *node, float *mid, float *size, ScatterPoint **refpoints, int depth) -{ - ScatterNode *subnode; - ScatterPoint **subrefpoints, **tmppoints= tree->tmppoints; - int index, nsize[8], noffset[8], i, subco, used_nodes, usedi; - float submid[3], subsize[3]; - - /* stopping condition */ - if (node->totpoint <= MAX_OCTREE_NODE_POINTS || depth == MAX_OCTREE_DEPTH) { - for (i=0; i<node->totpoint; i++) - node->points[i]= *(refpoints[i]); - - return; - } - - subsize[0]= size[0]*0.5f; - subsize[1]= size[1]*0.5f; - subsize[2]= size[2]*0.5f; - - node->split[0]= mid[0]; - node->split[1]= mid[1]; - node->split[2]= mid[2]; - - memset(nsize, 0, sizeof(nsize)); - memset(noffset, 0, sizeof(noffset)); - - /* count points in subnodes */ - for (i=0; i<node->totpoint; i++) { - index= SUBNODE_INDEX(refpoints[i]->co, node->split); - tmppoints[i]= refpoints[i]; - nsize[index]++; - } - - /* here we check if only one subnode is used. if this is the case, we don't - * create a new node, but rather call this function again, with different - * size and middle position for the same node. */ - for (usedi=0, used_nodes=0, i=0; i<8; i++) { - if (nsize[i]) { - used_nodes++; - usedi = i; - } - if (i != 0) - noffset[i]= noffset[i-1]+nsize[i-1]; - } - - if (used_nodes <= 1) { - subnode_middle(usedi, mid, subsize, submid); - create_octree_node(tree, node, submid, subsize, refpoints, depth+1); - return; - } - - /* reorder refpoints by subnode */ - for (i=0; i<node->totpoint; i++) { - index= SUBNODE_INDEX(tmppoints[i]->co, node->split); - refpoints[noffset[index]]= tmppoints[i]; - noffset[index]++; - } - - /* create subnodes */ - for (subco=0, i=0; i<8; subco+=nsize[i], i++) { - if (nsize[i] > 0) { - subnode= BLI_memarena_alloc(tree->arena, sizeof(ScatterNode)); - node->child[i]= subnode; - subnode->points= node->points + subco; - subnode->totpoint= nsize[i]; - subrefpoints= refpoints + subco; - - subnode_middle(i, mid, subsize, submid); - - create_octree_node(tree, subnode, submid, subsize, subrefpoints, - depth+1); - } - else - node->child[i]= NULL; - } - - node->points= NULL; - node->totpoint= 0; -} - -/* public functions */ - -ScatterTree *scatter_tree_new(ScatterSettings *ss[3], float scale, float error, - float (*co)[3], float (*color)[3], float *area, int totpoint) -{ - ScatterTree *tree; - ScatterPoint *points, **refpoints; - int i; - - /* allocate tree */ - tree= MEM_callocN(sizeof(ScatterTree), "ScatterTree"); - tree->scale= scale; - tree->error= error; - tree->totpoint= totpoint; - - tree->ss[0]= ss[0]; - tree->ss[1]= ss[1]; - tree->ss[2]= ss[2]; - - points = MEM_callocN(sizeof(ScatterPoint) * totpoint, "ScatterPoints"); - refpoints = MEM_callocN(sizeof(ScatterPoint *) * totpoint, "ScatterRefPoints"); - - tree->points= points; - tree->refpoints= refpoints; - - /* build points */ - INIT_MINMAX(tree->min, tree->max); - - for (i=0; i<totpoint; i++) { - copy_v3_v3(points[i].co, co[i]); - copy_v3_v3(points[i].rad, color[i]); - points[i].area= fabsf(area[i])/(tree->scale*tree->scale); - points[i].back= (area[i] < 0.0f); - - mul_v3_fl(points[i].co, 1.0f / tree->scale); - minmax_v3v3_v3(tree->min, tree->max, points[i].co); - - refpoints[i]= points + i; - } - - return tree; -} - -void scatter_tree_build(ScatterTree *tree) -{ - ScatterPoint *newpoints, **tmppoints; - float mid[3], size[3]; - int totpoint= tree->totpoint; - - newpoints = MEM_callocN(sizeof(ScatterPoint) * totpoint, "ScatterPoints"); - tmppoints = MEM_callocN(sizeof(ScatterPoint *) * totpoint, "ScatterTmpPoints"); - tree->tmppoints= tmppoints; - - tree->arena= BLI_memarena_new(0x8000 * sizeof(ScatterNode), "sss tree arena"); - BLI_memarena_use_calloc(tree->arena); - - /* build tree */ - tree->root= BLI_memarena_alloc(tree->arena, sizeof(ScatterNode)); - tree->root->points= newpoints; - tree->root->totpoint= totpoint; - - mid[0]= (tree->min[0]+tree->max[0])*0.5f; - mid[1]= (tree->min[1]+tree->max[1])*0.5f; - mid[2]= (tree->min[2]+tree->max[2])*0.5f; - - size[0]= (tree->max[0]-tree->min[0])*0.5f; - size[1]= (tree->max[1]-tree->min[1])*0.5f; - size[2]= (tree->max[2]-tree->min[2])*0.5f; - - create_octree_node(tree, tree->root, mid, size, tree->refpoints, 0); - - MEM_freeN(tree->points); - MEM_freeN(tree->refpoints); - MEM_freeN(tree->tmppoints); - tree->refpoints= NULL; - tree->tmppoints= NULL; - tree->points= newpoints; - - /* sum radiance at nodes */ - sum_radiance(tree, tree->root); -} - -void scatter_tree_sample(ScatterTree *tree, const float co[3], float color[3]) -{ - float sco[3]; - - copy_v3_v3(sco, co); - mul_v3_fl(sco, 1.0f / tree->scale); - - compute_radiance(tree, sco, color); -} - -void scatter_tree_free(ScatterTree *tree) -{ - if (tree->arena) BLI_memarena_free(tree->arena); - if (tree->points) MEM_freeN(tree->points); - if (tree->refpoints) MEM_freeN(tree->refpoints); - - MEM_freeN(tree); -} - -/* Internal Renderer API */ - -/* sss tree building */ - -typedef struct SSSData { - ScatterTree *tree; - ScatterSettings *ss[3]; -} SSSData; - -typedef struct SSSPoints { - struct SSSPoints *next, *prev; - - float (*co)[3]; - float (*color)[3]; - float *area; - int totpoint; -} SSSPoints; - -static void sss_create_tree_mat(Render *re, Material *mat) -{ - SSSPoints *p; - RenderResult *rr; - ListBase points; - float (*co)[3] = NULL, (*color)[3] = NULL, *area = NULL; - int totpoint = 0, osa, osaflag, frsflag, partsdone; - - if (re->test_break(re->tbh)) - return; - - points.first= points.last= NULL; - - /* TODO: this is getting a bit ugly, copying all those variables and - * setting them back, maybe we need to create our own Render? */ - - /* do SSS preprocessing render */ - BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); - rr= re->result; - osa= re->osa; - osaflag= re->r.mode & R_OSA; - frsflag= re->r.mode & R_EDGE_FRS; - partsdone= re->i.partsdone; - - re->osa= 0; - re->r.mode &= ~(R_OSA | R_EDGE_FRS); - re->sss_points= &points; - re->sss_mat= mat; - re->i.partsdone = 0; - - if (!(re->r.scemode & (R_BUTS_PREVIEW|R_VIEWPORT_PREVIEW))) - re->result= NULL; - BLI_rw_mutex_unlock(&re->resultmutex); - - RE_TileProcessor(re); - - BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); - if (!(re->r.scemode & (R_BUTS_PREVIEW|R_VIEWPORT_PREVIEW))) { - RE_FreeRenderResult(re->result); - re->result= rr; - } - BLI_rw_mutex_unlock(&re->resultmutex); - - re->i.partsdone= partsdone; - re->sss_mat= NULL; - re->sss_points= NULL; - re->osa= osa; - if (osaflag) re->r.mode |= R_OSA; - if (frsflag) re->r.mode |= R_EDGE_FRS; - - /* no points? no tree */ - if (!points.first) - return; - - /* merge points together into a single buffer */ - if (!re->test_break(re->tbh)) { - for (totpoint=0, p=points.first; p; p=p->next) - totpoint += p->totpoint; - - co= MEM_mallocN(sizeof(*co)*totpoint, "SSSCo"); - color= MEM_mallocN(sizeof(*color)*totpoint, "SSSColor"); - area= MEM_mallocN(sizeof(*area)*totpoint, "SSSArea"); - - for (totpoint=0, p=points.first; p; p=p->next) { - memcpy(co+totpoint, p->co, sizeof(*co)*p->totpoint); - memcpy(color+totpoint, p->color, sizeof(*color)*p->totpoint); - memcpy(area+totpoint, p->area, sizeof(*area)*p->totpoint); - totpoint += p->totpoint; - } - } - - /* free points */ - for (p=points.first; p; p=p->next) { - MEM_freeN(p->co); - MEM_freeN(p->color); - MEM_freeN(p->area); - } - BLI_freelistN(&points); - - /* build tree */ - if (!re->test_break(re->tbh)) { - SSSData *sss= MEM_callocN(sizeof(*sss), "SSSData"); - float ior= mat->sss_ior, cfac= mat->sss_colfac; - const float *radius = mat->sss_radius; - float fw= mat->sss_front, bw= mat->sss_back; - float error = mat->sss_error; - - error= get_render_aosss_error(&re->r, error); - if ((re->r.scemode & (R_BUTS_PREVIEW|R_VIEWPORT_PREVIEW)) && error < 0.5f) - error= 0.5f; - - sss->ss[0]= scatter_settings_new(mat->sss_col[0], radius[0], ior, cfac, fw, bw); - sss->ss[1]= scatter_settings_new(mat->sss_col[1], radius[1], ior, cfac, fw, bw); - sss->ss[2]= scatter_settings_new(mat->sss_col[2], radius[2], ior, cfac, fw, bw); - sss->tree= scatter_tree_new(sss->ss, mat->sss_scale, error, - co, color, area, totpoint); - - MEM_freeN(co); - MEM_freeN(color); - MEM_freeN(area); - - scatter_tree_build(sss->tree); - - BLI_ghash_insert(re->sss_hash, mat, sss); - } - else { - if (co) MEM_freeN(co); - if (color) MEM_freeN(color); - if (area) MEM_freeN(area); - } -} - -void sss_add_points(Render *re, float (*co)[3], float (*color)[3], float *area, int totpoint) -{ - SSSPoints *p; - - if (totpoint > 0) { - p= MEM_callocN(sizeof(SSSPoints), "SSSPoints"); - - p->co= co; - p->color= color; - p->area= area; - p->totpoint= totpoint; - - BLI_thread_lock(LOCK_CUSTOM1); - BLI_addtail(re->sss_points, p); - BLI_thread_unlock(LOCK_CUSTOM1); - } -} - -static void sss_free_tree(SSSData *sss) -{ - scatter_tree_free(sss->tree); - scatter_settings_free(sss->ss[0]); - scatter_settings_free(sss->ss[1]); - scatter_settings_free(sss->ss[2]); - MEM_freeN(sss); -} - -/* public functions */ - -void make_sss_tree(Render *re) -{ - Material *mat; - bool infostr_set = false; - const char *prevstr = NULL; - - free_sss(re); - - re->sss_hash= BLI_ghash_ptr_new("make_sss_tree gh"); - - re->stats_draw(re->sdh, &re->i); - - for (mat= re->main->mat.first; mat; mat= mat->id.next) { - if (mat->id.us && (mat->flag & MA_IS_USED) && (mat->sss_flag & MA_DIFF_SSS)) { - if (!infostr_set) { - prevstr = re->i.infostr; - re->i.infostr = IFACE_("SSS preprocessing"); - infostr_set = true; - } - - sss_create_tree_mat(re, mat); - } - } - - /* XXX preview exception */ - /* localizing preview render data is not fun for node trees :( */ - if (re->main!=G.main) { - for (mat= G.main->mat.first; mat; mat= mat->id.next) { - if (mat->id.us && (mat->flag & MA_IS_USED) && (mat->sss_flag & MA_DIFF_SSS)) { - if (!infostr_set) { - prevstr = re->i.infostr; - re->i.infostr = IFACE_("SSS preprocessing"); - infostr_set = true; - } - - sss_create_tree_mat(re, mat); - } - } - } - - if (infostr_set) - re->i.infostr = prevstr; -} - -void free_sss(Render *re) -{ - if (re->sss_hash) { - GHashIterator gh_iter; - - GHASH_ITER (gh_iter, re->sss_hash) { - sss_free_tree(BLI_ghashIterator_getValue(&gh_iter)); - } - - BLI_ghash_free(re->sss_hash, NULL, NULL); - re->sss_hash= NULL; - } -} - -int sample_sss(Render *re, Material *mat, const float co[3], float color[3]) -{ - if (re->sss_hash) { - SSSData *sss= BLI_ghash_lookup(re->sss_hash, mat); - - if (sss) { - scatter_tree_sample(sss->tree, co, color); - return 1; - } - else { - color[0]= 0.0f; - color[1]= 0.0f; - color[2]= 0.0f; - } - } - - return 0; -} - -int sss_pass_done(struct Render *re, struct Material *mat) -{ - return ((re->flag & R_BAKING) || !(re->r.mode & R_SSS) || (re->sss_hash && BLI_ghash_lookup(re->sss_hash, mat))); -} - diff --git a/source/blender/render/intern/source/strand.c b/source/blender/render/intern/source/strand.c deleted file mode 100644 index 6b52d4aa419..00000000000 --- a/source/blender/render/intern/source/strand.c +++ /dev/null @@ -1,1069 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Contributors: Brecht Van Lommel. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/render/intern/source/strand.c - * \ingroup render - */ - - -#include <math.h> -#include <string.h> -#include <stdlib.h> - -#include "MEM_guardedalloc.h" - -#include "DNA_key_types.h" -#include "DNA_material_types.h" -#include "DNA_meshdata_types.h" - -#include "BLI_math.h" -#include "BLI_blenlib.h" -#include "BLI_utildefines.h" -#include "BLI_ghash.h" -#include "BLI_memarena.h" -#include "BLI_rand.h" - -#include "BKE_DerivedMesh.h" -#include "BKE_key.h" - - -#include "render_types.h" -#include "rendercore.h" -#include "renderdatabase.h" -#include "shading.h" -#include "strand.h" -#include "zbuf.h" - -/* *************** */ - -static float strand_eval_width(Material *ma, float strandco) -{ - float fac; - - strandco= 0.5f*(strandco + 1.0f); - - if (ma->strand_ease!=0.0f) { - if (ma->strand_ease<0.0f) - fac= pow(strandco, 1.0f+ma->strand_ease); - else - fac= pow(strandco, 1.0f/(1.0f-ma->strand_ease)); - } - else fac= strandco; - - return ((1.0f-fac)*ma->strand_sta + (fac)*ma->strand_end); -} - -void strand_eval_point(StrandSegment *sseg, StrandPoint *spoint) -{ - Material *ma; - StrandBuffer *strandbuf; - const float *simplify; - float p[4][3], data[4], cross[3], w, dx, dy, t; - int type; - - strandbuf= sseg->buffer; - ma= sseg->buffer->ma; - t= spoint->t; - type= (strandbuf->flag & R_STRAND_BSPLINE)? KEY_BSPLINE: KEY_CARDINAL; - - copy_v3_v3(p[0], sseg->v[0]->co); - copy_v3_v3(p[1], sseg->v[1]->co); - copy_v3_v3(p[2], sseg->v[2]->co); - copy_v3_v3(p[3], sseg->v[3]->co); - - if (sseg->obi->flag & R_TRANSFORMED) { - mul_m4_v3(sseg->obi->mat, p[0]); - mul_m4_v3(sseg->obi->mat, p[1]); - mul_m4_v3(sseg->obi->mat, p[2]); - mul_m4_v3(sseg->obi->mat, p[3]); - } - - if (t == 0.0f) { - copy_v3_v3(spoint->co, p[1]); - spoint->strandco= sseg->v[1]->strandco; - - spoint->dtstrandco= (sseg->v[2]->strandco - sseg->v[0]->strandco); - if (sseg->v[0] != sseg->v[1]) - spoint->dtstrandco *= 0.5f; - } - else if (t == 1.0f) { - copy_v3_v3(spoint->co, p[2]); - spoint->strandco= sseg->v[2]->strandco; - - spoint->dtstrandco= (sseg->v[3]->strandco - sseg->v[1]->strandco); - if (sseg->v[3] != sseg->v[2]) - spoint->dtstrandco *= 0.5f; - } - else { - key_curve_position_weights(t, data, type); - spoint->co[0]= data[0]*p[0][0] + data[1]*p[1][0] + data[2]*p[2][0] + data[3]*p[3][0]; - spoint->co[1]= data[0]*p[0][1] + data[1]*p[1][1] + data[2]*p[2][1] + data[3]*p[3][1]; - spoint->co[2]= data[0]*p[0][2] + data[1]*p[1][2] + data[2]*p[2][2] + data[3]*p[3][2]; - spoint->strandco= (1.0f-t)*sseg->v[1]->strandco + t*sseg->v[2]->strandco; - } - - key_curve_tangent_weights(t, data, type); - spoint->dtco[0]= data[0]*p[0][0] + data[1]*p[1][0] + data[2]*p[2][0] + data[3]*p[3][0]; - spoint->dtco[1]= data[0]*p[0][1] + data[1]*p[1][1] + data[2]*p[2][1] + data[3]*p[3][1]; - spoint->dtco[2]= data[0]*p[0][2] + data[1]*p[1][2] + data[2]*p[2][2] + data[3]*p[3][2]; - - normalize_v3_v3(spoint->tan, spoint->dtco); - normalize_v3_v3(spoint->nor, spoint->co); - negate_v3(spoint->nor); - - spoint->width= strand_eval_width(ma, spoint->strandco); - - /* simplification */ - simplify= RE_strandren_get_simplify(strandbuf->obr, sseg->strand, 0); - spoint->alpha= (simplify)? simplify[1]: 1.0f; - - /* outer points */ - cross_v3_v3v3(cross, spoint->co, spoint->tan); - - w= spoint->co[2]*strandbuf->winmat[2][3] + strandbuf->winmat[3][3]; - dx= strandbuf->winx*cross[0]*strandbuf->winmat[0][0]/w; - dy= strandbuf->winy*cross[1]*strandbuf->winmat[1][1]/w; - w = sqrtf(dx * dx + dy * dy); - - if (w > 0.0f) { - if (strandbuf->flag & R_STRAND_B_UNITS) { - const float crosslen= len_v3(cross); - w= 2.0f*crosslen*strandbuf->minwidth/w; - - if (spoint->width < w) { - spoint->alpha= spoint->width/w; - spoint->width= w; - } - - if (simplify) - /* squared because we only change width, not length */ - spoint->width *= simplify[0]*simplify[0]; - - mul_v3_fl(cross, spoint->width*0.5f/crosslen); - } - else - mul_v3_fl(cross, spoint->width/w); - } - - sub_v3_v3v3(spoint->co1, spoint->co, cross); - add_v3_v3v3(spoint->co2, spoint->co, cross); - - copy_v3_v3(spoint->dsco, cross); -} - -/* *************** */ - -static void interpolate_vec1(float *v1, float *v2, float t, float negt, float *v) -{ - v[0]= negt*v1[0] + t*v2[0]; -} - -static void interpolate_vec3(float *v1, float *v2, float t, float negt, float *v) -{ - v[0]= negt*v1[0] + t*v2[0]; - v[1]= negt*v1[1] + t*v2[1]; - v[2]= negt*v1[2] + t*v2[2]; -} - -static void interpolate_vec4(float *v1, float *v2, float t, float negt, float *v) -{ - v[0]= negt*v1[0] + t*v2[0]; - v[1]= negt*v1[1] + t*v2[1]; - v[2]= negt*v1[2] + t*v2[2]; - v[3]= negt*v1[3] + t*v2[3]; -} - -static void interpolate_shade_result(ShadeResult *shr1, ShadeResult *shr2, float t, ShadeResult *shr, int addpassflag) -{ - float negt= 1.0f - t; - - interpolate_vec4(shr1->combined, shr2->combined, t, negt, shr->combined); - - if (addpassflag & SCE_PASS_VECTOR) { - interpolate_vec4(shr1->winspeed, shr2->winspeed, t, negt, shr->winspeed); - } - /* optim... */ - if (addpassflag & ~(SCE_PASS_VECTOR)) { - if (addpassflag & SCE_PASS_Z) - interpolate_vec1(&shr1->z, &shr2->z, t, negt, &shr->z); - if (addpassflag & SCE_PASS_RGBA) - interpolate_vec4(shr1->col, shr2->col, t, negt, shr->col); - if (addpassflag & SCE_PASS_NORMAL) { - interpolate_vec3(shr1->nor, shr2->nor, t, negt, shr->nor); - normalize_v3(shr->nor); - } - if (addpassflag & SCE_PASS_EMIT) - interpolate_vec3(shr1->emit, shr2->emit, t, negt, shr->emit); - if (addpassflag & SCE_PASS_DIFFUSE) { - interpolate_vec3(shr1->diff, shr2->diff, t, negt, shr->diff); - interpolate_vec3(shr1->diffshad, shr2->diffshad, t, negt, shr->diffshad); - } - if (addpassflag & SCE_PASS_SPEC) - interpolate_vec3(shr1->spec, shr2->spec, t, negt, shr->spec); - if (addpassflag & SCE_PASS_SHADOW) - interpolate_vec3(shr1->shad, shr2->shad, t, negt, shr->shad); - if (addpassflag & SCE_PASS_AO) - interpolate_vec3(shr1->ao, shr2->ao, t, negt, shr->ao); - if (addpassflag & SCE_PASS_ENVIRONMENT) - interpolate_vec3(shr1->env, shr2->env, t, negt, shr->env); - if (addpassflag & SCE_PASS_INDIRECT) - interpolate_vec3(shr1->indirect, shr2->indirect, t, negt, shr->indirect); - if (addpassflag & SCE_PASS_REFLECT) - interpolate_vec3(shr1->refl, shr2->refl, t, negt, shr->refl); - if (addpassflag & SCE_PASS_REFRACT) - interpolate_vec3(shr1->refr, shr2->refr, t, negt, shr->refr); - if (addpassflag & SCE_PASS_MIST) - interpolate_vec1(&shr1->mist, &shr2->mist, t, negt, &shr->mist); - } -} - -static void strand_apply_shaderesult_alpha(ShadeResult *shr, float alpha) -{ - if (alpha < 1.0f) { - shr->combined[0] *= alpha; - shr->combined[1] *= alpha; - shr->combined[2] *= alpha; - shr->combined[3] *= alpha; - - shr->col[0] *= alpha; - shr->col[1] *= alpha; - shr->col[2] *= alpha; - shr->col[3] *= alpha; - - shr->alpha *= alpha; - } -} - -static void strand_shade_point(Render *re, ShadeSample *ssamp, StrandSegment *sseg, StrandVert *svert, StrandPoint *spoint) -{ - ShadeInput *shi= ssamp->shi; - ShadeResult *shr= ssamp->shr; - VlakRen vlr; - int seed; - - memset(&vlr, 0, sizeof(vlr)); - vlr.flag= R_SMOOTH; - if (sseg->buffer->ma->mode & MA_TANGENT_STR) - vlr.flag |= R_TANGENT; - - shi->vlr= &vlr; - shi->v1= NULL; - shi->v2= NULL; - shi->v3= NULL; - shi->strand= sseg->strand; - shi->obi= sseg->obi; - shi->obr= sseg->obi->obr; - - /* cache for shadow */ - shi->samplenr= re->shadowsamplenr[shi->thread]++; - - /* all samples */ - shi->mask= 0xFFFF; - - /* seed RNG for consistent results across tiles */ - seed = shi->strand->index + (svert - shi->strand->vert); - BLI_thread_srandom(shi->thread, seed); - - shade_input_set_strand(shi, sseg->strand, spoint); - shade_input_set_strand_texco(shi, sseg->strand, sseg->v[1], spoint); - - /* init material vars */ - shade_input_init_material(shi); - - /* shade */ - shade_samples_do_AO(ssamp); - shade_input_do_shade(shi, shr); - - /* apply simplification */ - strand_apply_shaderesult_alpha(shr, spoint->alpha); - - /* include lamphalos for strand, since halo layer was added already */ - if (re->flag & R_LAMPHALO) - if (shi->layflag & SCE_LAY_HALO) - renderspothalo(shi, shr->combined, shr->combined[3]); - - shi->strand= NULL; -} - -/* *************** */ - -struct StrandShadeCache { - GHash *resulthash; - GHash *refcounthash; - MemArena *memarena; -}; - -typedef struct StrandCacheEntry { - GHashPair pair; - ShadeResult shr; -} StrandCacheEntry; - -StrandShadeCache *strand_shade_cache_create(void) -{ - StrandShadeCache *cache; - - cache= MEM_callocN(sizeof(StrandShadeCache), "StrandShadeCache"); - cache->resulthash= BLI_ghash_pair_new("strand_shade_cache_create1 gh"); - cache->refcounthash= BLI_ghash_pair_new("strand_shade_cache_create2 gh"); - cache->memarena= BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "strand shade cache arena"); - - return cache; -} - -void strand_shade_cache_free(StrandShadeCache *cache) -{ - BLI_ghash_free(cache->refcounthash, NULL, NULL); - BLI_ghash_free(cache->resulthash, MEM_freeN, NULL); - BLI_memarena_free(cache->memarena); - MEM_freeN(cache); -} - -static GHashPair strand_shade_hash_pair(ObjectInstanceRen *obi, StrandVert *svert) -{ - GHashPair pair = {obi, svert}; - return pair; -} - -static void strand_shade_get(Render *re, StrandShadeCache *cache, ShadeSample *ssamp, StrandSegment *sseg, StrandVert *svert) -{ - StrandCacheEntry *entry; - StrandPoint p; - int *refcount; - GHashPair pair = strand_shade_hash_pair(sseg->obi, svert); - - entry= BLI_ghash_lookup(cache->resulthash, &pair); - refcount= BLI_ghash_lookup(cache->refcounthash, &pair); - - if (!entry) { - /* not shaded yet, shade and insert into hash */ - p.t= (sseg->v[1] == svert)? 0.0f: 1.0f; - strand_eval_point(sseg, &p); - strand_shade_point(re, ssamp, sseg, svert, &p); - - entry= MEM_callocN(sizeof(StrandCacheEntry), "StrandCacheEntry"); - entry->pair = pair; - entry->shr = ssamp->shr[0]; - BLI_ghash_insert(cache->resulthash, entry, entry); - } - else - /* already shaded, just copy previous result from hash */ - ssamp->shr[0]= entry->shr; - - /* lower reference count and remove if not needed anymore by any samples */ - (*refcount)--; - if (*refcount == 0) { - BLI_ghash_remove(cache->resulthash, &pair, MEM_freeN, NULL); - BLI_ghash_remove(cache->refcounthash, &pair, NULL, NULL); - } -} - -void strand_shade_segment(Render *re, StrandShadeCache *cache, StrandSegment *sseg, ShadeSample *ssamp, float t, float s, int addpassflag) -{ - ShadeResult shr1, shr2; - - /* get shading for two endpoints and interpolate */ - strand_shade_get(re, cache, ssamp, sseg, sseg->v[1]); - shr1= ssamp->shr[0]; - strand_shade_get(re, cache, ssamp, sseg, sseg->v[2]); - shr2= ssamp->shr[0]; - - interpolate_shade_result(&shr1, &shr2, t, ssamp->shr, addpassflag); - - /* apply alpha along width */ - if (sseg->buffer->widthfade != -1.0f) { - s = 1.0f - powf(fabsf(s), sseg->buffer->widthfade); - - strand_apply_shaderesult_alpha(ssamp->shr, s); - } -} - -void strand_shade_unref(StrandShadeCache *cache, ObjectInstanceRen *obi, StrandVert *svert) -{ - GHashPair pair = strand_shade_hash_pair(obi, svert); - int *refcount; - - /* lower reference count and remove if not needed anymore by any samples */ - refcount= BLI_ghash_lookup(cache->refcounthash, &pair); - - (*refcount)--; - if (*refcount == 0) { - BLI_ghash_remove(cache->resulthash, &pair, MEM_freeN, NULL); - BLI_ghash_remove(cache->refcounthash, &pair, NULL, NULL); - } -} - -static void strand_shade_refcount(StrandShadeCache *cache, StrandSegment *sseg, StrandVert *svert) -{ - GHashPair pair = strand_shade_hash_pair(sseg->obi, svert); - GHashPair *key; - int *refcount= BLI_ghash_lookup(cache->refcounthash, &pair); - - if (!refcount) { - key= BLI_memarena_alloc(cache->memarena, sizeof(GHashPair)); - *key = pair; - refcount= BLI_memarena_alloc(cache->memarena, sizeof(int)); - *refcount= 1; - BLI_ghash_insert(cache->refcounthash, key, refcount); - } - else - (*refcount)++; -} - -/* *************** */ - -typedef struct StrandPart { - Render *re; - ZSpan *zspan; - - APixstrand *apixbuf; - int *totapixbuf; - int *rectz; - int *rectmask; - intptr_t *rectdaps; - int rectx, recty; - int sample; - int shadow; - float (*jit)[2]; - int samples; - - StrandSegment *segment; - float t[3], s[3]; - - StrandShadeCache *cache; -} StrandPart; - -typedef struct StrandSortSegment { - struct StrandSortSegment *next; - int obi, strand, segment; - float z; -} StrandSortSegment; - -static int compare_strand_segment(const void *poin1, const void *poin2) -{ - const StrandSortSegment *seg1= (const StrandSortSegment*)poin1; - const StrandSortSegment *seg2= (const StrandSortSegment*)poin2; - - if (seg1->z < seg2->z) - return -1; - else if (seg1->z == seg2->z) - return 0; - else - return 1; -} - -static void do_strand_point_project(float winmat[4][4], ZSpan *zspan, float *co, float *hoco, float *zco) -{ - projectvert(co, winmat, hoco); - hoco_to_zco(zspan, zco, hoco); -} - -static void strand_project_point(float winmat[4][4], float winx, float winy, StrandPoint *spoint) -{ - float div; - - projectvert(spoint->co, winmat, spoint->hoco); - - div= 1.0f/spoint->hoco[3]; - spoint->x= spoint->hoco[0]*div*winx*0.5f; - spoint->y= spoint->hoco[1]*div*winy*0.5f; -} - -static APixstrand *addpsmainAstrand(ListBase *lb) -{ - APixstrMain *psm; - - psm= MEM_mallocN(sizeof(APixstrMain), "addpsmainA"); - BLI_addtail(lb, psm); - psm->ps = MEM_callocN(4096 * sizeof(APixstrand), "pixstr"); - - return psm->ps; -} - -static APixstrand *addpsAstrand(ZSpan *zspan) -{ - /* make new PS */ - if (zspan->apstrandmcounter==0) { - zspan->curpstrand= addpsmainAstrand(zspan->apsmbase); - zspan->apstrandmcounter= 4095; - } - else { - zspan->curpstrand++; - zspan->apstrandmcounter--; - } - return zspan->curpstrand; -} - -#define MAX_ZROW 2000 - -static void do_strand_fillac(void *handle, int x, int y, float u, float v, float z) -{ - StrandPart *spart= (StrandPart *)handle; - StrandShadeCache *cache= spart->cache; - StrandSegment *sseg= spart->segment; - APixstrand *apn, *apnew; - float t, s; - int offset, mask, obi, strnr, seg, zverg, bufferz, maskz=0; - - offset = y*spart->rectx + x; - obi= sseg->obi - spart->re->objectinstance; - strnr= sseg->strand->index + 1; - seg= sseg->v[1] - sseg->strand->vert; - mask= (1<<spart->sample); - - /* check against solid z-buffer */ - zverg= (int)z; - - if (spart->rectdaps) { - /* find the z of the sample */ - PixStr *ps; - intptr_t *rd= spart->rectdaps + offset; - - bufferz= 0x7FFFFFFF; - if (spart->rectmask) maskz= 0x7FFFFFFF; - - if (*rd) { - for (ps= (PixStr *)(*rd); ps; ps= ps->next) { - if (mask & ps->mask) { - bufferz= ps->z; - if (spart->rectmask) - maskz= ps->maskz; - break; - } - } - } - } - else { - bufferz= (spart->rectz)? spart->rectz[offset]: 0x7FFFFFFF; - if (spart->rectmask) - maskz= spart->rectmask[offset]; - } - -#define CHECK_ADD(n) \ - if (apn->p[n]==strnr && apn->obi[n]==obi && apn->seg[n]==seg) \ - { if (!(apn->mask[n] & mask)) { apn->mask[n] |= mask; apn->v[n] += t; apn->u[n] += s; } break; } (void)0 -#define CHECK_ASSIGN(n) \ - if (apn->p[n]==0) \ - {apn->obi[n]= obi; apn->p[n]= strnr; apn->z[n]= zverg; apn->mask[n]= mask; apn->v[n]= t; apn->u[n]= s; apn->seg[n]= seg; break; } (void)0 - - /* add to pixel list */ - if (zverg < bufferz && (spart->totapixbuf[offset] < MAX_ZROW)) { - if (!spart->rectmask || zverg > maskz) { - t = u * spart->t[0] + v * spart->t[1] + (1.0f - u - v) * spart->t[2]; - s = fabsf(u * spart->s[0] + v * spart->s[1] + (1.0f - u - v) * spart->s[2]); - - apn= spart->apixbuf + offset; - while (apn) { - CHECK_ADD(0); - CHECK_ADD(1); - CHECK_ADD(2); - CHECK_ADD(3); - CHECK_ASSIGN(0); - CHECK_ASSIGN(1); - CHECK_ASSIGN(2); - CHECK_ASSIGN(3); - - apnew= addpsAstrand(spart->zspan); - SWAP(APixstrand, *apnew, *apn); - apn->next= apnew; - CHECK_ASSIGN(0); - } - - if (cache) { - strand_shade_refcount(cache, sseg, sseg->v[1]); - strand_shade_refcount(cache, sseg, sseg->v[2]); - } - spart->totapixbuf[offset]++; - } - } -} - -/* width is calculated in hoco space, to ensure strands are visible */ -static int strand_test_clip(float winmat[4][4], ZSpan *UNUSED(zspan), float *bounds, float *co, float *zcomp, float widthx, float widthy) -{ - float hoco[4]; - int clipflag= 0; - - projectvert(co, winmat, hoco); - - /* we compare z without perspective division for segment sorting */ - *zcomp= hoco[2]; - - if (hoco[0]+widthx < bounds[0]*hoco[3]) clipflag |= 1; - else if (hoco[0]-widthx > bounds[1]*hoco[3]) clipflag |= 2; - - if (hoco[1]-widthy > bounds[3]*hoco[3]) clipflag |= 4; - else if (hoco[1]+widthy < bounds[2]*hoco[3]) clipflag |= 8; - - clipflag |= testclip(hoco); - - return clipflag; -} - -static void do_scanconvert_strand(Render *UNUSED(re), StrandPart *spart, ZSpan *zspan, float t, float dt, float *co1, float *co2, float *co3, float *co4, int sample) -{ - float jco1[3], jco2[3], jco3[3], jco4[3], jx, jy; - - copy_v3_v3(jco1, co1); - copy_v3_v3(jco2, co2); - copy_v3_v3(jco3, co3); - copy_v3_v3(jco4, co4); - - if (spart->jit) { - jx= -spart->jit[sample][0]; - jy= -spart->jit[sample][1]; - - jco1[0] += jx; jco1[1] += jy; - jco2[0] += jx; jco2[1] += jy; - jco3[0] += jx; jco3[1] += jy; - jco4[0] += jx; jco4[1] += jy; - - /* XXX mblur? */ - } - - spart->sample= sample; - - spart->t[0]= t-dt; - spart->s[0]= -1.0f; - spart->t[1]= t-dt; - spart->s[1]= 1.0f; - spart->t[2]= t; - spart->s[2]= 1.0f; - zspan_scanconvert_strand(zspan, spart, jco1, jco2, jco3, do_strand_fillac); - spart->t[0]= t-dt; - spart->s[0]= -1.0f; - spart->t[1]= t; - spart->s[1]= 1.0f; - spart->t[2]= t; - spart->s[2]= -1.0f; - zspan_scanconvert_strand(zspan, spart, jco1, jco3, jco4, do_strand_fillac); -} - -static void strand_render(Render *re, StrandSegment *sseg, float winmat[4][4], StrandPart *spart, ZSpan *zspan, int totzspan, StrandPoint *p1, StrandPoint *p2) -{ - if (spart) { - float t= p2->t; - float dt= p2->t - p1->t; - int a; - - for (a=0; a<spart->samples; a++) - do_scanconvert_strand(re, spart, zspan, t, dt, p1->zco2, p1->zco1, p2->zco1, p2->zco2, a); - } - else { - float hoco1[4], hoco2[4]; - int a, obi, index; - - obi= sseg->obi - re->objectinstance; - index= sseg->strand->index; - - projectvert(p1->co, winmat, hoco1); - projectvert(p2->co, winmat, hoco2); - - - for (a=0; a<totzspan; a++) { -#if 0 - /* render both strand and single pixel wire to counter aliasing */ - zbufclip4(re, &zspan[a], obi, index, p1->hoco2, p1->hoco1, p2->hoco1, p2->hoco2, p1->clip2, p1->clip1, p2->clip1, p2->clip2); -#endif - /* only render a line for now, which makes the shadow map more - * similar across frames, and so reduces flicker */ - zbufsinglewire(&zspan[a], obi, index, hoco1, hoco2); - } - } -} - -static int strand_segment_recursive(Render *re, float winmat[4][4], StrandPart *spart, ZSpan *zspan, int totzspan, StrandSegment *sseg, StrandPoint *p1, StrandPoint *p2, int depth) -{ - StrandPoint p; - StrandBuffer *buffer= sseg->buffer; - float dot, d1[2], d2[2], len1, len2; - - if (depth == buffer->maxdepth) - return 0; - - p.t= (p1->t + p2->t)*0.5f; - strand_eval_point(sseg, &p); - strand_project_point(buffer->winmat, buffer->winx, buffer->winy, &p); - - d1[0]= (p.x - p1->x); - d1[1]= (p.y - p1->y); - len1= d1[0]*d1[0] + d1[1]*d1[1]; - - d2[0]= (p2->x - p.x); - d2[1]= (p2->y - p.y); - len2= d2[0]*d2[0] + d2[1]*d2[1]; - - if (len1 == 0.0f || len2 == 0.0f) - return 0; - - dot= d1[0]*d2[0] + d1[1]*d2[1]; - if (dot*dot > sseg->sqadaptcos*len1*len2) - return 0; - - if (spart) { - do_strand_point_project(winmat, zspan, p.co1, p.hoco1, p.zco1); - do_strand_point_project(winmat, zspan, p.co2, p.hoco2, p.zco2); - } - else { -#if 0 - projectvert(p.co1, winmat, p.hoco1); - projectvert(p.co2, winmat, p.hoco2); - p.clip1= testclip(p.hoco1); - p.clip2= testclip(p.hoco2); -#endif - } - - if (!strand_segment_recursive(re, winmat, spart, zspan, totzspan, sseg, p1, &p, depth+1)) - strand_render(re, sseg, winmat, spart, zspan, totzspan, p1, &p); - if (!strand_segment_recursive(re, winmat, spart, zspan, totzspan, sseg, &p, p2, depth+1)) - strand_render(re, sseg, winmat, spart, zspan, totzspan, &p, p2); - - return 1; -} - -void render_strand_segment(Render *re, float winmat[4][4], StrandPart *spart, ZSpan *zspan, int totzspan, StrandSegment *sseg) -{ - StrandBuffer *buffer= sseg->buffer; - StrandPoint *p1= &sseg->point1; - StrandPoint *p2= &sseg->point2; - - p1->t= 0.0f; - p2->t= 1.0f; - - strand_eval_point(sseg, p1); - strand_project_point(buffer->winmat, buffer->winx, buffer->winy, p1); - strand_eval_point(sseg, p2); - strand_project_point(buffer->winmat, buffer->winx, buffer->winy, p2); - - if (spart) { - do_strand_point_project(winmat, zspan, p1->co1, p1->hoco1, p1->zco1); - do_strand_point_project(winmat, zspan, p1->co2, p1->hoco2, p1->zco2); - do_strand_point_project(winmat, zspan, p2->co1, p2->hoco1, p2->zco1); - do_strand_point_project(winmat, zspan, p2->co2, p2->hoco2, p2->zco2); - } - else { -#if 0 - projectvert(p1->co1, winmat, p1->hoco1); - projectvert(p1->co2, winmat, p1->hoco2); - projectvert(p2->co1, winmat, p2->hoco1); - projectvert(p2->co2, winmat, p2->hoco2); - p1->clip1= testclip(p1->hoco1); - p1->clip2= testclip(p1->hoco2); - p2->clip1= testclip(p2->hoco1); - p2->clip2= testclip(p2->hoco2); -#endif - } - - if (!strand_segment_recursive(re, winmat, spart, zspan, totzspan, sseg, p1, p2, 0)) - strand_render(re, sseg, winmat, spart, zspan, totzspan, p1, p2); -} - -/* render call to fill in strands */ -int zbuffer_strands_abuf(Render *re, RenderPart *pa, APixstrand *apixbuf, ListBase *apsmbase, unsigned int lay, int UNUSED(negzmask), float winmat[4][4], int winx, int winy, int samples, float (*jit)[2], float clipcrop, int shadow, StrandShadeCache *cache) -{ - ObjectRen *obr; - ObjectInstanceRen *obi; - ZSpan zspan; - StrandRen *strand = NULL; - StrandVert *svert; - StrandBound *sbound; - StrandPart spart; - StrandSegment sseg; - StrandSortSegment *sortsegments = NULL, *sortseg, *firstseg; - MemArena *memarena; - float z[4], bounds[4], obwinmat[4][4]; - int a, b, c, i, totsegment, clip[4]; - - if (re->test_break(re->tbh)) - return 0; - if (re->totstrand == 0) - return 0; - - /* setup StrandPart */ - memset(&spart, 0, sizeof(spart)); - - spart.re= re; - spart.rectx= pa->rectx; - spart.recty= pa->recty; - spart.apixbuf= apixbuf; - spart.zspan= &zspan; - spart.rectdaps= pa->rectdaps; - spart.rectz= pa->rectz; - spart.rectmask= pa->rectmask; - spart.cache= cache; - spart.shadow= shadow; - spart.jit= jit; - spart.samples= samples; - - zbuf_alloc_span(&zspan, pa->rectx, pa->recty, clipcrop); - - /* needed for transform from hoco to zbuffer co */ - zspan.zmulx= ((float)winx)/2.0f; - zspan.zmuly= ((float)winy)/2.0f; - - zspan.zofsx= -pa->disprect.xmin; - zspan.zofsy= -pa->disprect.ymin; - - /* to center the sample position */ - if (!shadow) { - zspan.zofsx -= 0.5f; - zspan.zofsy -= 0.5f; - } - - zspan.apsmbase= apsmbase; - - /* clipping setup */ - bounds[0]= (2*pa->disprect.xmin - winx-1)/(float)winx; - bounds[1]= (2*pa->disprect.xmax - winx+1)/(float)winx; - bounds[2]= (2*pa->disprect.ymin - winy-1)/(float)winy; - bounds[3]= (2*pa->disprect.ymax - winy+1)/(float)winy; - - memarena= BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "strand sort arena"); - firstseg= NULL; - totsegment= 0; - - /* for all object instances */ - for (obi=re->instancetable.first, i=0; obi; obi=obi->next, i++) { - Material *ma; - float widthx, widthy; - - obr= obi->obr; - - if (!obr->strandbuf || !(obr->strandbuf->lay & lay)) - continue; - - /* compute matrix and try clipping whole object */ - if (obi->flag & R_TRANSFORMED) - mul_m4_m4m4(obwinmat, winmat, obi->mat); - else - copy_m4_m4(obwinmat, winmat); - - /* test if we should skip it */ - ma = obr->strandbuf->ma; - - if (shadow && (!(ma->mode2 & MA_CASTSHADOW) || !(ma->mode & MA_SHADBUF))) - continue; - else if (!shadow && (ma->mode & MA_ONLYCAST)) - continue; - - if (clip_render_object(obi->obr->boundbox, bounds, obwinmat)) - continue; - - widthx= obr->strandbuf->maxwidth*obwinmat[0][0]; - widthy= obr->strandbuf->maxwidth*obwinmat[1][1]; - - /* for each bounding box containing a number of strands */ - sbound= obr->strandbuf->bound; - for (c=0; c<obr->strandbuf->totbound; c++, sbound++) { - if (clip_render_object(sbound->boundbox, bounds, obwinmat)) - continue; - - /* for each strand in this bounding box */ - for (a=sbound->start; a<sbound->end; a++) { - strand= RE_findOrAddStrand(obr, a); - svert= strand->vert; - - /* keep clipping and z depth for 4 control points */ - clip[1]= strand_test_clip(obwinmat, &zspan, bounds, svert->co, &z[1], widthx, widthy); - clip[2]= strand_test_clip(obwinmat, &zspan, bounds, (svert+1)->co, &z[2], widthx, widthy); - clip[0]= clip[1]; z[0]= z[1]; - - for (b=0; b<strand->totvert-1; b++, svert++) { - /* compute 4th point clipping and z depth */ - if (b < strand->totvert-2) { - clip[3]= strand_test_clip(obwinmat, &zspan, bounds, (svert+2)->co, &z[3], widthx, widthy); - } - else { - clip[3]= clip[2]; z[3]= z[2]; - } - - /* check clipping and add to sortsegments buffer */ - if (!(clip[0] & clip[1] & clip[2] & clip[3])) { - sortseg= BLI_memarena_alloc(memarena, sizeof(StrandSortSegment)); - sortseg->obi= i; - sortseg->strand= strand->index; - sortseg->segment= b; - - sortseg->z= 0.5f*(z[1] + z[2]); - - sortseg->next= firstseg; - firstseg= sortseg; - totsegment++; - } - - /* shift clipping and z depth */ - clip[0]= clip[1]; z[0]= z[1]; - clip[1]= clip[2]; z[1]= z[2]; - clip[2]= clip[3]; z[2]= z[3]; - } - } - } - } - - if (!re->test_break(re->tbh)) { - /* convert list to array and sort */ - sortsegments= MEM_mallocN(sizeof(StrandSortSegment)*totsegment, "StrandSortSegment"); - for (a=0, sortseg=firstseg; a<totsegment; a++, sortseg=sortseg->next) - sortsegments[a]= *sortseg; - qsort(sortsegments, totsegment, sizeof(StrandSortSegment), compare_strand_segment); - } - - BLI_memarena_free(memarena); - - spart.totapixbuf= MEM_callocN(sizeof(int)*pa->rectx*pa->recty, "totapixbuf"); - - if (!re->test_break(re->tbh)) { - /* render segments in sorted order */ - sortseg= sortsegments; - for (a=0; a<totsegment; a++, sortseg++) { - if (re->test_break(re->tbh)) - break; - - obi= &re->objectinstance[sortseg->obi]; - obr= obi->obr; - - sseg.obi= obi; - sseg.strand= RE_findOrAddStrand(obr, sortseg->strand); - sseg.buffer= sseg.strand->buffer; - sseg.sqadaptcos= sseg.buffer->adaptcos; - sseg.sqadaptcos *= sseg.sqadaptcos; - - svert= sseg.strand->vert + sortseg->segment; - sseg.v[0]= (sortseg->segment > 0)? (svert-1): svert; - sseg.v[1]= svert; - sseg.v[2]= svert+1; - sseg.v[3]= (sortseg->segment < sseg.strand->totvert-2)? svert+2: svert+1; - sseg.shaded= 0; - - spart.segment= &sseg; - - render_strand_segment(re, winmat, &spart, &zspan, 1, &sseg); - } - } - - if (sortsegments) - MEM_freeN(sortsegments); - MEM_freeN(spart.totapixbuf); - - zbuf_free_span(&zspan); - - return totsegment; -} - -/* *************** */ - -StrandSurface *cache_strand_surface(Render *re, ObjectRen *obr, DerivedMesh *dm, float mat[4][4], int timeoffset) -{ - StrandSurface *mesh; - MFace *mface; - MVert *mvert; - float (*co)[3]; - int a, totvert, totface; - - totvert= dm->getNumVerts(dm); - totface= dm->getNumTessFaces(dm); - - for (mesh = re->strandsurface.first; mesh; mesh = mesh->next) { - if ((mesh->obr.ob == obr->ob) && - (mesh->obr.par == obr->par) && - (mesh->obr.index == obr->index) && - (mesh->totvert == totvert) && - (mesh->totface == totface)) - { - break; - } - } - - if (!mesh) { - mesh= MEM_callocN(sizeof(StrandSurface), "StrandSurface"); - mesh->obr= *obr; - mesh->totvert= totvert; - mesh->totface= totface; - mesh->face= MEM_callocN(sizeof(int)*4*mesh->totface, "StrandSurfFaces"); - mesh->ao= MEM_callocN(sizeof(float)*3*mesh->totvert, "StrandSurfAO"); - mesh->env= MEM_callocN(sizeof(float)*3*mesh->totvert, "StrandSurfEnv"); - mesh->indirect= MEM_callocN(sizeof(float)*3*mesh->totvert, "StrandSurfIndirect"); - BLI_addtail(&re->strandsurface, mesh); - } - - if (timeoffset == -1 && !mesh->prevco) - mesh->prevco= co= MEM_callocN(sizeof(float)*3*mesh->totvert, "StrandSurfCo"); - else if (timeoffset == 0 && !mesh->co) - mesh->co= co= MEM_callocN(sizeof(float)*3*mesh->totvert, "StrandSurfCo"); - else if (timeoffset == 1 && !mesh->nextco) - mesh->nextco= co= MEM_callocN(sizeof(float)*3*mesh->totvert, "StrandSurfCo"); - else - return mesh; - - mvert= dm->getVertArray(dm); - for (a=0; a<mesh->totvert; a++, mvert++) { - copy_v3_v3(co[a], mvert->co); - mul_m4_v3(mat, co[a]); - } - - mface= dm->getTessFaceArray(dm); - for (a=0; a<mesh->totface; a++, mface++) { - mesh->face[a][0]= mface->v1; - mesh->face[a][1]= mface->v2; - mesh->face[a][2]= mface->v3; - mesh->face[a][3]= mface->v4; - } - - return mesh; -} - -void free_strand_surface(Render *re) -{ - StrandSurface *mesh; - - for (mesh=re->strandsurface.first; mesh; mesh=mesh->next) { - if (mesh->co) MEM_freeN(mesh->co); - if (mesh->prevco) MEM_freeN(mesh->prevco); - if (mesh->nextco) MEM_freeN(mesh->nextco); - if (mesh->ao) MEM_freeN(mesh->ao); - if (mesh->env) MEM_freeN(mesh->env); - if (mesh->indirect) MEM_freeN(mesh->indirect); - if (mesh->face) MEM_freeN(mesh->face); - } - - BLI_freelistN(&re->strandsurface); -} - -void strand_minmax(StrandRen *strand, float min[3], float max[3], const float width) -{ - StrandVert *svert; - const float width2 = width * 2.0f; - float vec[3]; - int a; - - for (a=0, svert=strand->vert; a<strand->totvert; a++, svert++) { - copy_v3_v3(vec, svert->co); - minmax_v3v3_v3(min, max, vec); - - if (width!=0.0f) { - add_v3_fl(vec, width); - minmax_v3v3_v3(min, max, vec); - add_v3_fl(vec, -width2); - minmax_v3v3_v3(min, max, vec); - } - } -} - diff --git a/source/blender/render/intern/source/sunsky.c b/source/blender/render/intern/source/sunsky.c deleted file mode 100644 index f0cf29e98ca..00000000000 --- a/source/blender/render/intern/source/sunsky.c +++ /dev/null @@ -1,506 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/render/intern/source/sunsky.c - * \ingroup render - * - * This feature comes from Preetham paper on "A Practical Analytic Model for Daylight" - * and example code from Brian Smits, another author of that paper in - * http://www.cs.utah.edu/vissim/papers/sunsky/code/ - */ - -#include "sunsky.h" -#include "BLI_math.h" - -/** - * These macros are defined for vector operations - * */ - -/** - * compute v1 = v2 op v3 - * v1, v2 and v3 are vectors contains 3 float - * */ -#define VEC3OPV(v1, v2, op, v3) \ - { \ - v1[0] = (v2[0] op v3[0]); \ - v1[1] = (v2[1] op v3[1]); \ - v1[2] = (v2[2] op v3[2]); \ - } (void)0 - -/** - * compute v1 = v2 op f1 - * v1, v2 are vectors contains 3 float - * and f1 is a float - * */ -#define VEC3OPF(v1, v2, op, f1) \ - { \ - v1[0] = (v2[0] op(f1)); \ - v1[1] = (v2[1] op(f1)); \ - v1[2] = (v2[2] op(f1)); \ - } (void)0 - -/** - * compute v1 = f1 op v2 - * v1, v2 are vectors contains 3 float - * and f1 is a float - * */ -#define FOPVEC3(v1, f1, op, v2) \ - { \ - v1[0] = ((f1) op v2[0]); \ - v1[1] = ((f1) op v2[1]); \ - v1[2] = ((f1) op v2[2]); \ - } (void)0 - -/** - * ClipColor: - * clip a color to range [0, 1]; - * */ -void ClipColor(float c[3]) -{ - if (c[0] > 1.0f) c[0] = 1.0f; - if (c[0] < 0.0f) c[0] = 0.0f; - if (c[1] > 1.0f) c[1] = 1.0f; - if (c[1] < 0.0f) c[1] = 0.0f; - if (c[2] > 1.0f) c[2] = 1.0f; - if (c[2] < 0.0f) c[2] = 0.0f; -} - -/** - * AngleBetween: - * compute angle between to direction - * all angles are in radians - * */ -static float AngleBetween(float thetav, float phiv, float theta, float phi) -{ - float cospsi = sinf(thetav) * sinf(theta) * cosf(phi - phiv) + cosf(thetav) * cosf(theta); - - if (cospsi > 1.0f) - return 0; - if (cospsi < -1.0f) - return M_PI; - - return acosf(cospsi); -} - -/** - * DirectionToThetaPhi: - * this function convert a direction to it's theta and phi value - * parameters: - * toSun: contains direction information - * theta, phi, are return values from this conversion - * */ -static void DirectionToThetaPhi(float *toSun, float *theta, float *phi) -{ - *theta = acosf(toSun[2]); - if (fabsf(*theta) < 1e-5f) - *phi = 0; - else - *phi = atan2f(toSun[1], toSun[0]); -} - -/** - * PerezFunction: - * compute perez function value based on input parameters - */ -static float PerezFunction(struct SunSky *sunsky, const float *lam, float theta, float gamma, float lvz) -{ - float den, num; - - den = ((1 + lam[0] * expf(lam[1])) * - (1 + lam[2] * expf(lam[3] * sunsky->theta) + lam[4] * cosf(sunsky->theta) * cosf(sunsky->theta))); - - num = ((1 + lam[0] * expf(lam[1] / cosf(theta))) * - (1 + lam[2] * expf(lam[3] * gamma) + lam[4] * cosf(gamma) * cosf(gamma))); - - return(lvz * num / den); -} - -/** - * InitSunSky: - * this function compute some sun,sky parameters according to input parameters and also initiate some other sun, sky parameters - * parameters: - * sunSky, is a structure that contains information about sun, sky and atmosphere, in this function, most of its values initiated - * turb, is atmosphere turbidity - * toSun, contains sun direction - * horizon_brighness, controls the brightness of the horizon colors - * spread, controls colors spreed at horizon - * sun_brightness, controls sun's brightness - * sun_size, controls sun's size - * back_scatter, controls back scatter light - * */ -void InitSunSky(struct SunSky *sunsky, float turb, const float toSun[3], float horizon_brightness, - float spread, float sun_brightness, float sun_size, float back_scatter, - float skyblendfac, short skyblendtype, float sky_exposure, float sky_colorspace) -{ - float theta2; - float theta3; - float T; - float T2; - float chi; - - sunsky->turbidity = turb; - - sunsky->horizon_brightness = horizon_brightness; - sunsky->spread = spread; - sunsky->sun_brightness = sun_brightness; - sunsky->sun_size = sun_size; - sunsky->backscattered_light = back_scatter; - sunsky->skyblendfac = skyblendfac; - sunsky->skyblendtype = skyblendtype; - sunsky->sky_exposure = -sky_exposure; - sunsky->sky_colorspace = sky_colorspace; - - sunsky->toSun[0] = toSun[0]; - sunsky->toSun[1] = toSun[1]; - sunsky->toSun[2] = toSun[2]; - - DirectionToThetaPhi(sunsky->toSun, &sunsky->theta, &sunsky->phi); - - sunsky->sunSolidAngle = 0.25 * M_PI * 1.39 * 1.39 / (150 * 150); /* = 6.7443e-05 */ - - theta2 = sunsky->theta * sunsky->theta; - theta3 = theta2 * sunsky->theta; - T = turb; - T2 = turb * turb; - - chi = (4.0f / 9.0f - T / 120.0f) * ((float)M_PI - 2.0f * sunsky->theta); - sunsky->zenith_Y = (4.0453f * T - 4.9710f) * tanf(chi) - 0.2155f * T + 2.4192f; - sunsky->zenith_Y *= 1000; /* conversion from kcd/m^2 to cd/m^2 */ - - if (sunsky->zenith_Y <= 0) - sunsky->zenith_Y = 1e-6; - - sunsky->zenith_x = - (+0.00165f * theta3 - 0.00374f * theta2 + 0.00208f * sunsky->theta + 0.0f) * T2 + - (-0.02902f * theta3 + 0.06377f * theta2 - 0.03202f * sunsky->theta + 0.00394f) * T + - (+0.11693f * theta3 - 0.21196f * theta2 + 0.06052f * sunsky->theta + 0.25885f); - - sunsky->zenith_y = - (+0.00275f * theta3 - 0.00610f * theta2 + 0.00316f * sunsky->theta + 0.0f) * T2 + - (-0.04214f * theta3 + 0.08970f * theta2 - 0.04153f * sunsky->theta + 0.00515f) * T + - (+0.15346f * theta3 - 0.26756f * theta2 + 0.06669f * sunsky->theta + 0.26688f); - - - sunsky->perez_Y[0] = 0.17872f * T - 1.46303f; - sunsky->perez_Y[1] = -0.35540f * T + 0.42749f; - sunsky->perez_Y[2] = -0.02266f * T + 5.32505f; - sunsky->perez_Y[3] = 0.12064f * T - 2.57705f; - sunsky->perez_Y[4] = -0.06696f * T + 0.37027f; - - sunsky->perez_x[0] = -0.01925f * T - 0.25922f; - sunsky->perez_x[1] = -0.06651f * T + 0.00081f; - sunsky->perez_x[2] = -0.00041f * T + 0.21247f; - sunsky->perez_x[3] = -0.06409f * T - 0.89887f; - sunsky->perez_x[4] = -0.00325f * T + 0.04517f; - - sunsky->perez_y[0] = -0.01669f * T - 0.26078f; - sunsky->perez_y[1] = -0.09495f * T + 0.00921f; - sunsky->perez_y[2] = -0.00792f * T + 0.21023f; - sunsky->perez_y[3] = -0.04405f * T - 1.65369f; - sunsky->perez_y[4] = -0.01092f * T + 0.05291f; - - /* suggested by glome in patch [#8063] */ - sunsky->perez_Y[0] *= sunsky->horizon_brightness; - sunsky->perez_x[0] *= sunsky->horizon_brightness; - sunsky->perez_y[0] *= sunsky->horizon_brightness; - - sunsky->perez_Y[1] *= sunsky->spread; - sunsky->perez_x[1] *= sunsky->spread; - sunsky->perez_y[1] *= sunsky->spread; - - sunsky->perez_Y[2] *= sunsky->sun_brightness; - sunsky->perez_x[2] *= sunsky->sun_brightness; - sunsky->perez_y[2] *= sunsky->sun_brightness; - - sunsky->perez_Y[3] *= sunsky->sun_size; - sunsky->perez_x[3] *= sunsky->sun_size; - sunsky->perez_y[3] *= sunsky->sun_size; - - sunsky->perez_Y[4] *= sunsky->backscattered_light; - sunsky->perez_x[4] *= sunsky->backscattered_light; - sunsky->perez_y[4] *= sunsky->backscattered_light; -} - -/** - * GetSkyXYZRadiance: - * this function compute sky radiance according to a view parameters `theta' and `phi'and sunSky values - * parameters: - * sunSky, sontains sun and sky parameters - * theta, is sun's theta - * phi, is sun's phi - * color_out, is computed color that shows sky radiance in XYZ color format - * */ -void GetSkyXYZRadiance(struct SunSky *sunsky, float theta, float phi, float color_out[3]) -{ - float gamma; - float x, y, Y, X, Z; - float hfade = 1, nfade = 1; - - - if (theta > (float)M_PI_2) { - hfade = 1.0f - (theta * (float)M_1_PI - 0.5f) * 2.0f; - hfade = hfade * hfade * (3.0f - 2.0f * hfade); - theta = M_PI_2; - } - - if (sunsky->theta > (float)M_PI_2) { - if (theta <= (float)M_PI_2) { - nfade = 1.0f - (0.5f - theta * (float)M_1_PI) * 2.0f; - nfade *= 1.0f - (sunsky->theta * (float)M_1_PI - 0.5f) * 2.0f; - nfade = nfade * nfade * (3.0f - 2.0f * nfade); - } - } - - gamma = AngleBetween(theta, phi, sunsky->theta, sunsky->phi); - - /* Compute xyY values */ - x = PerezFunction(sunsky, sunsky->perez_x, theta, gamma, sunsky->zenith_x); - y = PerezFunction(sunsky, sunsky->perez_y, theta, gamma, sunsky->zenith_y); - Y = 6.666666667e-5f * nfade * hfade * PerezFunction(sunsky, sunsky->perez_Y, theta, gamma, sunsky->zenith_Y); - - if (sunsky->sky_exposure != 0.0f) - Y = 1.0 - exp(Y * sunsky->sky_exposure); - - X = (x / y) * Y; - Z = ((1 - x - y) / y) * Y; - - color_out[0] = X; - color_out[1] = Y; - color_out[2] = Z; -} - -/** - * GetSkyXYZRadiancef: - * this function compute sky radiance according to a view direction `varg' and sunSky values - * parameters: - * sunSky, sontains sun and sky parameters - * varg, shows direction - * color_out, is computed color that shows sky radiance in XYZ color format - * */ -void GetSkyXYZRadiancef(struct SunSky *sunsky, const float varg[3], float color_out[3]) -{ - float theta, phi; - float v[3]; - - normalize_v3_v3(v, varg); - - if (v[2] < 0.001f) { - v[2] = 0.001f; - normalize_v3(v); - } - - DirectionToThetaPhi(v, &theta, &phi); - GetSkyXYZRadiance(sunsky, theta, phi, color_out); -} - -/** - * ComputeAttenuatedSunlight: - * this function compute attenuated sun light based on sun's theta and atmosphere turbidity - * parameters: - * theta, is sun's theta - * turbidity: is atmosphere turbidity - * fTau: contains computed attenuated sun light - * */ -static void ComputeAttenuatedSunlight(float theta, int turbidity, float fTau[3]) -{ - float fBeta; - float fTauR, fTauA; - float m; - float fAlpha; - - int i; - float fLambda[3]; - fLambda[0] = 0.65f; - fLambda[1] = 0.57f; - fLambda[2] = 0.475f; - - fAlpha = 1.3f; - fBeta = 0.04608365822050f * turbidity - 0.04586025928522f; - - m = 1.0f / (cosf(theta) + 0.15f * powf(93.885f - theta / (float)M_PI * 180.0f, -1.253f)); - - for (i = 0; i < 3; i++) { - /* Rayleigh Scattering */ - fTauR = expf(-m * 0.008735f * powf(fLambda[i], (float)(-4.08f))); - - /* Aerosal (water + dust) attenuation */ - fTauA = exp(-m * fBeta * powf(fLambda[i], -fAlpha)); - - fTau[i] = fTauR * fTauA; - } -} - -/** - * InitAtmosphere: - * this function initiate sunSky structure with user input parameters. - * parameters: - * sunSky, contains information about sun, and in this function some atmosphere parameters will initiated - * sun_intens, shows sun intensity value - * mief, Mie scattering factor this factor currently call with 1.0 - * rayf, Rayleigh scattering factor, this factor currently call with 1.0 - * inscattf, inscatter light factor that range from 0.0 to 1.0, 0.0 means no inscatter light and 1.0 means full inscatter light - * extincf, extinction light factor that range from 0.0 to 1.0, 0.0 means no extinction and 1.0 means full extinction - * disf, is distance factor, multiplied to pixle's z value to compute each pixle's distance to camera, - * */ -void InitAtmosphere(struct SunSky *sunSky, float sun_intens, float mief, float rayf, - float inscattf, float extincf, float disf) -{ - const float pi = M_PI; - const float n = 1.003f; /* refractive index */ - const float N = 2.545e25; - const float pn = 0.035f; - const float T = 2.0f; - float fTemp, fTemp2, fTemp3, fBeta, fBetaDash; - float c = (6.544f * T - 6.51f) * 1e-17f; - float K[3] = {0.685f, 0.679f, 0.670f}; - float vBetaMieTemp[3]; - - float fLambda[3], fLambda2[3], fLambda4[3]; - float vLambda2[3]; - float vLambda4[3]; - - int i; - - sunSky->atm_SunIntensity = sun_intens; - sunSky->atm_BetaMieMultiplier = mief; - sunSky->atm_BetaRayMultiplier = rayf; - sunSky->atm_InscatteringMultiplier = inscattf; - sunSky->atm_ExtinctionMultiplier = extincf; - sunSky->atm_DistanceMultiplier = disf; - - sunSky->atm_HGg = 0.8; - - fLambda[0] = 1 / 650e-9f; - fLambda[1] = 1 / 570e-9f; - fLambda[2] = 1 / 475e-9f; - for (i = 0; i < 3; i++) { - fLambda2[i] = fLambda[i] * fLambda[i]; - fLambda4[i] = fLambda2[i] * fLambda2[i]; - } - - vLambda2[0] = fLambda2[0]; - vLambda2[1] = fLambda2[1]; - vLambda2[2] = fLambda2[2]; - - vLambda4[0] = fLambda4[0]; - vLambda4[1] = fLambda4[1]; - vLambda4[2] = fLambda4[2]; - - /* Rayleigh scattering constants. */ - fTemp = pi * pi * (n * n - 1) * (n * n - 1) * (6 + 3 * pn) / (6 - 7 * pn) / N; - fBeta = 8 * fTemp * pi / 3; - - VEC3OPF(sunSky->atm_BetaRay, vLambda4, *, fBeta); - fBetaDash = fTemp / 2; - VEC3OPF(sunSky->atm_BetaDashRay, vLambda4, *, fBetaDash); - - - /* Mie scattering constants. */ - fTemp2 = 0.434f * c * (2 * pi) * (2 * pi) * 0.5f; - VEC3OPF(sunSky->atm_BetaDashMie, vLambda2, *, fTemp2); - - fTemp3 = 0.434f * c * pi * (2 * pi) * (2 * pi); - - VEC3OPV(vBetaMieTemp, K, *, fLambda); - VEC3OPF(sunSky->atm_BetaMie, vBetaMieTemp, *, fTemp3); - -} - -/** - * AtmospherePixleShader: - * this function apply atmosphere effect on a pixle color `rgb' at distance `s' - * parameters: - * sunSky, contains information about sun parameters and user values - * view, is camera view vector - * s, is distance - * rgb, contains rendered color value for a pixle - * */ -void AtmospherePixleShader(struct SunSky *sunSky, float view[3], float s, float rgb[3]) -{ - float costheta; - float Phase_1; - float Phase_2; - float sunColor[3]; - - float E[3]; - float E1[3]; - - - float I[3]; - float fTemp; - float vTemp1[3], vTemp2[3]; - - float sunDirection[3]; - - s *= sunSky->atm_DistanceMultiplier; - - sunDirection[0] = sunSky->toSun[0]; - sunDirection[1] = sunSky->toSun[1]; - sunDirection[2] = sunSky->toSun[2]; - - costheta = dot_v3v3(view, sunDirection); /* cos(theta) */ - Phase_1 = 1 + (costheta * costheta); /* Phase_1 */ - - VEC3OPF(sunSky->atm_BetaRay, sunSky->atm_BetaRay, *, sunSky->atm_BetaRayMultiplier); - VEC3OPF(sunSky->atm_BetaMie, sunSky->atm_BetaMie, *, sunSky->atm_BetaMieMultiplier); - VEC3OPV(sunSky->atm_BetaRM, sunSky->atm_BetaRay, +, sunSky->atm_BetaMie); - - /* e^(-(beta_1 + beta_2) * s) = E1 */ - VEC3OPF(E1, sunSky->atm_BetaRM, *, -s / (float)M_LN2); - E1[0] = exp(E1[0]); - E1[1] = exp(E1[1]); - E1[2] = exp(E1[2]); - - copy_v3_v3(E, E1); - - /* Phase2(theta) = (1-g^2)/(1+g-2g*cos(theta))^(3/2) */ - fTemp = 1 + sunSky->atm_HGg - 2 * sunSky->atm_HGg * costheta; - fTemp = fTemp * sqrtf(fTemp); - Phase_2 = (1 - sunSky->atm_HGg * sunSky->atm_HGg) / fTemp; - - VEC3OPF(vTemp1, sunSky->atm_BetaDashRay, *, Phase_1); - VEC3OPF(vTemp2, sunSky->atm_BetaDashMie, *, Phase_2); - - VEC3OPV(vTemp1, vTemp1, +, vTemp2); - FOPVEC3(vTemp2, 1.0f, -, E1); - VEC3OPV(vTemp1, vTemp1, *, vTemp2); - - FOPVEC3(vTemp2, 1.0f, /, sunSky->atm_BetaRM); - - VEC3OPV(I, vTemp1, *, vTemp2); - - VEC3OPF(I, I, *, sunSky->atm_InscatteringMultiplier); - VEC3OPF(E, E, *, sunSky->atm_ExtinctionMultiplier); - - /* scale to color sun */ - ComputeAttenuatedSunlight(sunSky->theta, sunSky->turbidity, sunColor); - VEC3OPV(E, E, *, sunColor); - - VEC3OPF(I, I, *, sunSky->atm_SunIntensity); - - VEC3OPV(rgb, rgb, *, E); - VEC3OPV(rgb, rgb, +, I); -} - -#undef VEC3OPV -#undef VEC3OPF -#undef FOPVEC3 - -/* EOF */ diff --git a/source/blender/render/intern/source/texture_ocean.c b/source/blender/render/intern/source/texture_ocean.c deleted file mode 100644 index a932123243d..00000000000 --- a/source/blender/render/intern/source/texture_ocean.c +++ /dev/null @@ -1,160 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * Contributors: Matt Ebb - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/render/intern/source/texture_ocean.c - * \ingroup bke - */ - -#include <stddef.h> - -#include "BLI_math.h" -#include "BLI_utildefines.h" - -#include "DNA_modifier_types.h" -#include "DNA_object_types.h" -#include "DNA_texture_types.h" - -#include "BKE_global.h" /* XXX */ - -#include "BKE_modifier.h" -#include "BKE_ocean.h" - -#include "render_types.h" -#include "RE_shader_ext.h" - -#include "texture.h" - -#include "texture_ocean.h" /* own include */ - - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -/* defined in pipeline.c, is hardcopy of active dynamic allocated Render */ -/* only to be used here in this file, it's for speed */ -extern struct Render R; -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - - -/* ***** actual texture sampling ***** */ -int ocean_texture(Tex *tex, const float texvec[2], TexResult *texres) -{ - OceanTex *ot = tex->ot; - ModifierData *md; - OceanModifierData *omd; - - texres->tin = 0.0f; - - if ( !(ot) || - !(ot->object) || - !(md = (ModifierData *)modifiers_findByType(ot->object, eModifierType_Ocean)) || - !(omd = (OceanModifierData *)md)->ocean) - { - return 0; - } - else { - const bool do_normals = (omd->flag & MOD_OCEAN_GENERATE_NORMALS) != 0; - int cfra = R.r.cfra; - int retval = TEX_INT; - - OceanResult ocr; - const float u = 0.5f + 0.5f * texvec[0]; - const float v = 0.5f + 0.5f * texvec[1]; - - if (omd->oceancache && omd->cached == true) { - - CLAMP(cfra, omd->bakestart, omd->bakeend); - cfra -= omd->bakestart; /* shift to 0 based */ - - BKE_ocean_cache_eval_uv(omd->oceancache, &ocr, cfra, u, v); - - } - else { /* non-cached */ - - if (G.is_rendering) - BKE_ocean_eval_uv_catrom(omd->ocean, &ocr, u, v); - else - BKE_ocean_eval_uv(omd->ocean, &ocr, u, v); - - ocr.foam = BKE_ocean_jminus_to_foam(ocr.Jminus, omd->foam_coverage); - } - - switch (ot->output) { - case TEX_OCN_DISPLACEMENT: - /* XYZ displacement */ - texres->tr = 0.5f + 0.5f * ocr.disp[0]; - texres->tg = 0.5f + 0.5f * ocr.disp[2]; - texres->tb = 0.5f + 0.5f * ocr.disp[1]; - - texres->tr = MAX2(0.0f, texres->tr); - texres->tg = MAX2(0.0f, texres->tg); - texres->tb = MAX2(0.0f, texres->tb); - - BRICONTRGB; - - retval = TEX_RGB; - break; - - case TEX_OCN_EMINUS: - /* -ve eigenvectors ? */ - texres->tr = ocr.Eminus[0]; - texres->tg = ocr.Eminus[2]; - texres->tb = ocr.Eminus[1]; - retval = TEX_RGB; - break; - - case TEX_OCN_EPLUS: - /* -ve eigenvectors ? */ - texres->tr = ocr.Eplus[0]; - texres->tg = ocr.Eplus[2]; - texres->tb = ocr.Eplus[1]; - retval = TEX_RGB; - break; - - case TEX_OCN_JPLUS: - texres->tin = ocr.Jplus; - retval = TEX_INT; - break; - - case TEX_OCN_FOAM: - - texres->tin = ocr.foam; - - BRICONT; - - retval = TEX_INT; - break; - } - - /* if normals needed */ - - if (texres->nor && do_normals) { - normalize_v3_v3(texres->nor, ocr.normal); - retval |= TEX_NOR; - } - - texres->ta = 1.0f; - - return retval; - } -} diff --git a/source/blender/render/intern/source/volume_precache.c b/source/blender/render/intern/source/volume_precache.c deleted file mode 100644 index 752a9df0b79..00000000000 --- a/source/blender/render/intern/source/volume_precache.c +++ /dev/null @@ -1,855 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): Matt Ebb, RaË™l Fern·ndez Hern·ndez (Farsthary). - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/render/intern/source/volume_precache.c - * \ingroup render - */ - - -#include <math.h> -#include <stdlib.h> -#include <string.h> -#include <float.h> - -#include "MEM_guardedalloc.h" - -#include "BLI_blenlib.h" -#include "BLI_math.h" -#include "BLI_task.h" -#include "BLI_threads.h" -#include "BLI_voxel.h" -#include "BLI_utildefines.h" - -#include "BLT_translation.h" - -#include "PIL_time.h" - -#include "RE_shader_ext.h" - -#include "DNA_material_types.h" - -#include "rayintersection.h" -#include "rayobject.h" -#include "render_types.h" -#include "rendercore.h" -#include "renderdatabase.h" -#include "volumetric.h" -#include "volume_precache.h" - -#include "atomic_ops.h" - - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -/* defined in pipeline.c, is hardcopy of active dynamic allocated Render */ -/* only to be used here in this file, it's for speed */ -extern struct Render R; -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -/* *** utility code to set up an individual raytree for objectinstance, for checking inside/outside *** */ - -/* Recursive test for intersections, from a point inside the mesh, to outside - * Number of intersections (depth) determine if a point is inside or outside the mesh */ -static int intersect_outside_volume(RayObject *tree, Isect *isect, float *offset, int limit, int depth) -{ - if (limit == 0) return depth; - - if (RE_rayobject_raycast(tree, isect)) { - - isect->start[0] = isect->start[0] + isect->dist*isect->dir[0]; - isect->start[1] = isect->start[1] + isect->dist*isect->dir[1]; - isect->start[2] = isect->start[2] + isect->dist*isect->dir[2]; - - isect->dist = FLT_MAX; - isect->skip = RE_SKIP_VLR_NEIGHBOUR; - isect->orig.face= isect->hit.face; - isect->orig.ob= isect->hit.ob; - - return intersect_outside_volume(tree, isect, offset, limit-1, depth+1); - } - else { - return depth; - } -} - -/* Uses ray tracing to check if a point is inside or outside an ObjectInstanceRen */ -static int point_inside_obi(RayObject *tree, ObjectInstanceRen *obi, const float co[3]) -{ - Isect isect= {{0}}; - float dir[3] = {0.0f, 0.0f, 1.0f}; - int final_depth=0, depth=0, limit=20; - - /* set up the isect */ - copy_v3_v3(isect.start, co); - copy_v3_v3(isect.dir, dir); - isect.mode= RE_RAY_MIRROR; - isect.last_hit= NULL; - isect.lay= -1; - - isect.dist = FLT_MAX; - isect.orig.face= NULL; - isect.orig.ob = NULL; - - RE_instance_rotate_ray(obi, &isect); - final_depth = intersect_outside_volume(tree, &isect, dir, limit, depth); - RE_instance_rotate_ray_restore(obi, &isect); - - /* even number of intersections: point is outside - * odd number: point is inside */ - if (final_depth % 2 == 0) return 0; - else return 1; -} - -/* find the bounding box of an objectinstance in global space */ -void global_bounds_obi(Render *re, ObjectInstanceRen *obi, float bbmin[3], float bbmax[3]) -{ - ObjectRen *obr = obi->obr; - VolumePrecache *vp = obi->volume_precache; - VertRen *ver= NULL; - float co[3]; - int a; - - if (vp->bbmin != NULL && vp->bbmax != NULL) { - copy_v3_v3(bbmin, vp->bbmin); - copy_v3_v3(bbmax, vp->bbmax); - return; - } - - vp->bbmin = MEM_callocN(sizeof(float)*3, "volume precache min boundbox corner"); - vp->bbmax = MEM_callocN(sizeof(float)*3, "volume precache max boundbox corner"); - - INIT_MINMAX(bbmin, bbmax); - - for (a=0; a<obr->totvert; a++) { - if ((a & 255)==0) ver= obr->vertnodes[a>>8].vert; - else ver++; - - copy_v3_v3(co, ver->co); - - /* transformed object instance in camera space */ - if (obi->flag & R_TRANSFORMED) - mul_m4_v3(obi->mat, co); - - /* convert to global space */ - mul_m4_v3(re->viewinv, co); - - minmax_v3v3_v3(vp->bbmin, vp->bbmax, co); - } - - copy_v3_v3(bbmin, vp->bbmin); - copy_v3_v3(bbmax, vp->bbmax); - -} - -/* *** light cache filtering *** */ - -static float get_avg_surrounds(float *cache, int *res, int xx, int yy, int zz) -{ - int x, y, z, x_, y_, z_; - int added=0; - float tot=0.0f; - - for (z=-1; z <= 1; z++) { - z_ = zz+z; - if (z_ >= 0 && z_ <= res[2]-1) { - - for (y=-1; y <= 1; y++) { - y_ = yy+y; - if (y_ >= 0 && y_ <= res[1]-1) { - - for (x=-1; x <= 1; x++) { - x_ = xx+x; - if (x_ >= 0 && x_ <= res[0]-1) { - const int64_t i = BLI_VOXEL_INDEX(x_, y_, z_, res); - - if (cache[i] > 0.0f) { - tot += cache[i]; - added++; - } - - } - } - } - } - } - } - - if (added > 0) tot /= added; - - return tot; -} - -/* function to filter the edges of the light cache, where there was no volume originally. - * For each voxel which was originally external to the mesh, it finds the average values of - * the surrounding internal voxels and sets the original external voxel to that average amount. - * Works almost a bit like a 'dilate' filter */ -static void lightcache_filter(VolumePrecache *vp) -{ - int x, y, z; - - for (z=0; z < vp->res[2]; z++) { - for (y=0; y < vp->res[1]; y++) { - for (x=0; x < vp->res[0]; x++) { - /* trigger for outside mesh */ - const int64_t i = BLI_VOXEL_INDEX(x, y, z, vp->res); - - if (vp->data_r[i] < -0.f) - vp->data_r[i] = get_avg_surrounds(vp->data_r, vp->res, x, y, z); - if (vp->data_g[i] < -0.f) - vp->data_g[i] = get_avg_surrounds(vp->data_g, vp->res, x, y, z); - if (vp->data_b[i] < -0.f) - vp->data_b[i] = get_avg_surrounds(vp->data_b, vp->res, x, y, z); - } - } - } -} - -#if 0 -static void lightcache_filter2(VolumePrecache *vp) -{ - int x, y, z; - float *new_r, *new_g, *new_b; - int field_size = vp->res[0]*vp->res[1]*vp->res[2]*sizeof(float); - - new_r = MEM_mallocN(field_size, "temp buffer for light cache filter r channel"); - new_g = MEM_mallocN(field_size, "temp buffer for light cache filter g channel"); - new_b = MEM_mallocN(field_size, "temp buffer for light cache filter b channel"); - - memcpy(new_r, vp->data_r, field_size); - memcpy(new_g, vp->data_g, field_size); - memcpy(new_b, vp->data_b, field_size); - - for (z=0; z < vp->res[2]; z++) { - for (y=0; y < vp->res[1]; y++) { - for (x=0; x < vp->res[0]; x++) { - /* trigger for outside mesh */ - const int64_t i = BLI_VOXEL_INDEX(x, y, z, vp->res); - if (vp->data_r[i] < -0.f) - new_r[i] = get_avg_surrounds(vp->data_r, vp->res, x, y, z); - if (vp->data_g[i] < -0.f) - new_g[i] = get_avg_surrounds(vp->data_g, vp->res, x, y, z); - if (vp->data_b[i] < -0.f) - new_b[i] = get_avg_surrounds(vp->data_b, vp->res, x, y, z); - } - } - } - - SWAP(float *, vp->data_r, new_r); - SWAP(float *, vp->data_g, new_g); - SWAP(float *, vp->data_b, new_b); - - if (new_r) { MEM_freeN(new_r); new_r=NULL; } - if (new_g) { MEM_freeN(new_g); new_g=NULL; } - if (new_b) { MEM_freeN(new_b); new_b=NULL; } -} -#endif - -/* has a pad of 1 voxel surrounding the core for boundary simulation */ -BLI_INLINE int64_t ms_I(int x, int y, int z, const int *n) -{ - /* different ordering to light cache */ - return ((int64_t)x * (int64_t)(n[1] + 2) * (int64_t)(n[2] + 2) + - (int64_t)y * (int64_t)(n[2] + 2) + - (int64_t)z); -} - -/* has a pad of 1 voxel surrounding the core for boundary simulation */ -BLI_INLINE int64_t v_I_pad(int x, int y, int z, const int *n) -{ - /* same ordering to light cache, with padding */ - return ((int64_t)z * (int64_t)(n[1] + 2) * (int64_t)(n[0] + 2) + - (int64_t)y * (int64_t)(n[0] + 2) + - (int64_t)x); -} - -BLI_INLINE int64_t lc_to_ms_I(int x, int y, int z, const int *n) -{ - /* converting light cache index to multiple scattering index */ - return ((int64_t)(x - 1) * ((int64_t)n[1] * (int64_t)n[2]) + - (int64_t)(y - 1) * ((int64_t)n[2]) + - (int64_t)(z - 1)); -} - -/* *** multiple scattering approximation *** */ - -/* get the total amount of light energy in the light cache. used to normalize after multiple scattering */ -static float total_ss_energy(Render *re, int do_test_break, VolumePrecache *vp) -{ - int x, y, z; - const int *res = vp->res; - float energy=0.f; - - for (z=0; z < res[2]; z++) { - for (y=0; y < res[1]; y++) { - for (x=0; x < res[0]; x++) { - const int64_t i = BLI_VOXEL_INDEX(x, y, z, res); - - if (vp->data_r[i] > 0.f) energy += vp->data_r[i]; - if (vp->data_g[i] > 0.f) energy += vp->data_g[i]; - if (vp->data_b[i] > 0.f) energy += vp->data_b[i]; - } - } - - if (do_test_break && re->test_break(re->tbh)) break; - } - - return energy; -} - -static float total_ms_energy(Render *re, int do_test_break, float *sr, float *sg, float *sb, const int res[3]) -{ - int x, y, z; - float energy=0.f; - - for (z=1;z<=res[2];z++) { - for (y=1;y<=res[1];y++) { - for (x=1;x<=res[0];x++) { - const int64_t i = ms_I(x, y, z, res); - - if (sr[i] > 0.f) energy += sr[i]; - if (sg[i] > 0.f) energy += sg[i]; - if (sb[i] > 0.f) energy += sb[i]; - } - } - - if (do_test_break && re->test_break(re->tbh)) break; - } - - return energy; -} - -/** - * \param n: the unpadded resolution - */ -static void ms_diffuse(Render *re, int do_test_break, const float *x0, float *x, float diff, const int n[3]) -{ - int i, j, k, l; - const float dt = VOL_MS_TIMESTEP; - int64_t size = (int64_t)n[0] * (int64_t)n[1] * (int64_t)n[2]; - const float a = dt * diff * size; - - for (l=0; l<20; l++) { - for (k=1; k<=n[2]; k++) { - for (j=1; j<=n[1]; j++) { - for (i=1; i<=n[0]; i++) { - x[v_I_pad(i, j, k, n)] = - ((x0[v_I_pad(i, j, k, n)]) + ( - (x0[v_I_pad(i - 1, j, k, n)] + - x0[v_I_pad(i + 1, j, k, n)] + - x0[v_I_pad(i, j - 1, k, n)] + - x0[v_I_pad(i, j + 1, k, n)] + - x0[v_I_pad(i, j, k - 1, n)] + - x0[v_I_pad(i, j, k + 1, n)]) * a) / (1 + 6 * a)); - } - } - - if (do_test_break && re->test_break(re->tbh)) break; - } - - if (re->test_break(re->tbh)) break; - } -} - -static void multiple_scattering_diffusion(Render *re, VolumePrecache *vp, Material *ma) -{ - const float diff = ma->vol.ms_diff * 0.001f; /* compensate for scaling for a nicer UI range */ - const int simframes = (int)(ma->vol.ms_spread * (float)max_iii(vp->res[0], vp->res[1], vp->res[2])); - const int shade_type = ma->vol.shade_type; - float fac = ma->vol.ms_intensity; - - int x, y, z, m; - const int *n = vp->res; - const int size = (n[0]+2)*(n[1]+2)*(n[2]+2); - const int do_test_break = (size > 100000); - double time, lasttime= PIL_check_seconds_timer(); - float total; - float c=1.0f; - float origf; /* factor for blending in original light cache */ - float energy_ss, energy_ms; - - float *sr0=(float *)MEM_callocN(size*sizeof(float), "temporary multiple scattering buffer"); - float *sr=(float *)MEM_callocN(size*sizeof(float), "temporary multiple scattering buffer"); - float *sg0=(float *)MEM_callocN(size*sizeof(float), "temporary multiple scattering buffer"); - float *sg=(float *)MEM_callocN(size*sizeof(float), "temporary multiple scattering buffer"); - float *sb0=(float *)MEM_callocN(size*sizeof(float), "temporary multiple scattering buffer"); - float *sb=(float *)MEM_callocN(size*sizeof(float), "temporary multiple scattering buffer"); - - total = (float)(n[0]*n[1]*n[2]*simframes); - - energy_ss = total_ss_energy(re, do_test_break, vp); - - /* Scattering as diffusion pass */ - for (m=0; m<simframes; m++) { - /* add sources */ - for (z=1; z<=n[2]; z++) { - for (y=1; y<=n[1]; y++) { - for (x=1; x<=n[0]; x++) { - const int64_t i = lc_to_ms_I(x, y, z, n); //lc index - const int64_t j = ms_I(x, y, z, n); //ms index - - time= PIL_check_seconds_timer(); - c++; - if (vp->data_r[i] > 0.0f) - sr[j] += vp->data_r[i]; - if (vp->data_g[i] > 0.0f) - sg[j] += vp->data_g[i]; - if (vp->data_b[i] > 0.0f) - sb[j] += vp->data_b[i]; - - /* Displays progress every second */ - if (time-lasttime>1.0) { - char str[64]; - BLI_snprintf(str, sizeof(str), IFACE_("Simulating multiple scattering: %d%%"), - (int)(100.0f * (c / total))); - re->i.infostr = str; - re->stats_draw(re->sdh, &re->i); - re->i.infostr = NULL; - lasttime= time; - } - } - } - - if (do_test_break && re->test_break(re->tbh)) break; - } - - if (re->test_break(re->tbh)) break; - - SWAP(float *, sr, sr0); - SWAP(float *, sg, sg0); - SWAP(float *, sb, sb0); - - /* main diffusion simulation */ - ms_diffuse(re, do_test_break, sr0, sr, diff, n); - ms_diffuse(re, do_test_break, sg0, sg, diff, n); - ms_diffuse(re, do_test_break, sb0, sb, diff, n); - - if (re->test_break(re->tbh)) break; - } - - /* normalization factor to conserve energy */ - energy_ms = total_ms_energy(re, do_test_break, sr, sg, sb, n); - fac *= (energy_ss / energy_ms); - - /* blend multiple scattering back in the light cache */ - if (shade_type == MA_VOL_SHADE_SHADEDPLUSMULTIPLE) { - /* conserve energy - half single, half multiple */ - origf = 0.5f; - fac *= 0.5f; - } - else { - origf = 0.0f; - } - - for (z=1;z<=n[2];z++) { - for (y=1;y<=n[1];y++) { - for (x=1;x<=n[0];x++) { - const int64_t i = lc_to_ms_I(x, y, z, n); //lc index - const int64_t j = ms_I(x, y, z, n); //ms index - - vp->data_r[i] = origf * vp->data_r[i] + fac * sr[j]; - vp->data_g[i] = origf * vp->data_g[i] + fac * sg[j]; - vp->data_b[i] = origf * vp->data_b[i] + fac * sb[j]; - } - } - - if (do_test_break && re->test_break(re->tbh)) break; - } - - MEM_freeN(sr0); - MEM_freeN(sr); - MEM_freeN(sg0); - MEM_freeN(sg); - MEM_freeN(sb0); - MEM_freeN(sb); -} - - - -#if 0 /* debug stuff */ -static void *vol_precache_part_test(void *data) -{ - VolPrecachePart *pa = data; - - printf("part number: %d\n", pa->num); - printf("done: %d\n", pa->done); - printf("x min: %d x max: %d\n", pa->minx, pa->maxx); - printf("y min: %d y max: %d\n", pa->miny, pa->maxy); - printf("z min: %d z max: %d\n", pa->minz, pa->maxz); - - return NULL; -} -#endif - -/* Iterate over the 3d voxel grid, and fill the voxels with scattering information - * - * It's stored in memory as 3 big float grids next to each other, one for each RGB channel. - * I'm guessing the memory alignment may work out better this way for the purposes - * of doing linear interpolation, but I haven't actually tested this theory! :) - */ -typedef struct VolPrecacheState { - double lasttime; - unsigned int doneparts; - unsigned int totparts; -} VolPrecacheState; - -static void vol_precache_part(TaskPool * __restrict pool, void *taskdata, int UNUSED(threadid)) -{ - VolPrecacheState *state = (VolPrecacheState *)BLI_task_pool_userdata(pool); - VolPrecachePart *pa = (VolPrecachePart *)taskdata; - Render *re = pa->re; - - ObjectInstanceRen *obi = pa->obi; - RayObject *tree = pa->tree; - ShadeInput *shi = pa->shi; - float scatter_col[3] = {0.f, 0.f, 0.f}; - float co[3], cco[3], view[3]; - int x, y, z; - int res[3]; - double time; - - if (re->test_break && re->test_break(re->tbh)) - return; - - //printf("thread id %d\n", threadid); - - res[0]= pa->res[0]; - res[1]= pa->res[1]; - res[2]= pa->res[2]; - - for (z= pa->minz; z < pa->maxz; z++) { - co[2] = pa->bbmin[2] + (pa->voxel[2] * (z + 0.5f)); - - for (y= pa->miny; y < pa->maxy; y++) { - co[1] = pa->bbmin[1] + (pa->voxel[1] * (y + 0.5f)); - - for (x=pa->minx; x < pa->maxx; x++) { - int64_t i; - co[0] = pa->bbmin[0] + (pa->voxel[0] * (x + 0.5f)); - - if (re->test_break && re->test_break(re->tbh)) - break; - - /* convert from world->camera space for shading */ - mul_v3_m4v3(cco, pa->viewmat, co); - - i = BLI_VOXEL_INDEX(x, y, z, res); - - /* don't bother if the point is not inside the volume mesh */ - if (!point_inside_obi(tree, obi, cco)) { - obi->volume_precache->data_r[i] = -1.0f; - obi->volume_precache->data_g[i] = -1.0f; - obi->volume_precache->data_b[i] = -1.0f; - continue; - } - - copy_v3_v3(view, cco); - normalize_v3(view); - vol_get_scattering(shi, scatter_col, cco, view); - - obi->volume_precache->data_r[i] = scatter_col[0]; - obi->volume_precache->data_g[i] = scatter_col[1]; - obi->volume_precache->data_b[i] = scatter_col[2]; - - } - } - } - - unsigned int doneparts = atomic_add_and_fetch_u(&state->doneparts, 1); - - time = PIL_check_seconds_timer(); - if (time - state->lasttime > 1.0) { - ThreadMutex *mutex = BLI_task_pool_user_mutex(pool); - - if (BLI_mutex_trylock(mutex)) { - char str[64]; - float ratio = (float)doneparts/(float)state->totparts; - BLI_snprintf(str, sizeof(str), IFACE_("Precaching volume: %d%%"), (int)(100.0f * ratio)); - re->i.infostr = str; - re->stats_draw(re->sdh, &re->i); - re->i.infostr = NULL; - state->lasttime = time; - - BLI_mutex_unlock(mutex); - } - } -} - -static void precache_setup_shadeinput(Render *re, ObjectInstanceRen *obi, Material *ma, ShadeInput *shi) -{ - memset(shi, 0, sizeof(ShadeInput)); - shi->depth= 1; - shi->mask= 1; - shi->mat = ma; - shi->vlr = NULL; - memcpy(&shi->r, &shi->mat->r, 23*sizeof(float)); /* note, keep this synced with render_types.h */ - shi->har= shi->mat->har; - shi->obi= obi; - shi->obr= obi->obr; - shi->lay = re->lay; -} - -static void precache_launch_parts(Render *re, RayObject *tree, ShadeInput *shi, ObjectInstanceRen *obi) -{ - TaskScheduler *task_scheduler; - TaskPool *task_pool; - VolumePrecache *vp = obi->volume_precache; - VolPrecacheState state; - int i=0, x, y, z; - float voxel[3]; - int sizex, sizey, sizez; - float bbmin[3], bbmax[3]; - const int *res; - int minx, maxx; - int miny, maxy; - int minz, maxz; - int totthread = re->r.threads; - int parts[3]; - - if (!vp) return; - - /* currently we just subdivide the box, number of threads per side */ - parts[0] = parts[1] = parts[2] = totthread; - res = vp->res; - - /* setup task scheduler */ - memset(&state, 0, sizeof(state)); - state.doneparts = 0; - state.totparts = parts[0]*parts[1]*parts[2]; - state.lasttime = PIL_check_seconds_timer(); - - task_scheduler = BLI_task_scheduler_create(totthread); - task_pool = BLI_task_pool_create(task_scheduler, &state); - - /* using boundbox in worldspace */ - global_bounds_obi(re, obi, bbmin, bbmax); - sub_v3_v3v3(voxel, bbmax, bbmin); - - voxel[0] /= (float)res[0]; - voxel[1] /= (float)res[1]; - voxel[2] /= (float)res[2]; - - for (x=0; x < parts[0]; x++) { - sizex = ceil(res[0] / (float)parts[0]); - minx = x * sizex; - maxx = minx + sizex; - maxx = (maxx>res[0])?res[0]:maxx; - - for (y=0; y < parts[1]; y++) { - sizey = ceil(res[1] / (float)parts[1]); - miny = y * sizey; - maxy = miny + sizey; - maxy = (maxy>res[1])?res[1]:maxy; - - for (z=0; z < parts[2]; z++) { - VolPrecachePart *pa= MEM_callocN(sizeof(VolPrecachePart), "new precache part"); - - sizez = ceil(res[2] / (float)parts[2]); - minz = z * sizez; - maxz = minz + sizez; - maxz = (maxz>res[2])?res[2]:maxz; - - pa->re = re; - pa->num = i; - pa->tree = tree; - pa->shi = shi; - pa->obi = obi; - copy_m4_m4(pa->viewmat, re->viewmat); - - copy_v3_v3(pa->bbmin, bbmin); - copy_v3_v3(pa->voxel, voxel); - copy_v3_v3_int(pa->res, res); - - pa->minx = minx; pa->maxx = maxx; - pa->miny = miny; pa->maxy = maxy; - pa->minz = minz; pa->maxz = maxz; - - BLI_task_pool_push(task_pool, vol_precache_part, pa, true, TASK_PRIORITY_HIGH); - - i++; - } - } - } - - /* work and wait until tasks are done */ - BLI_task_pool_work_and_wait(task_pool); - - /* free */ - BLI_task_pool_free(task_pool); - BLI_task_scheduler_free(task_scheduler); -} - -/* calculate resolution from bounding box in world space */ -static int precache_resolution(Render *re, VolumePrecache *vp, ObjectInstanceRen *obi, int res) -{ - float dim[3], div; - float bbmin[3], bbmax[3]; - - /* bound box in global space */ - global_bounds_obi(re, obi, bbmin, bbmax); - sub_v3_v3v3(dim, bbmax, bbmin); - - div = max_fff(dim[0], dim[1], dim[2]); - dim[0] /= div; - dim[1] /= div; - dim[2] /= div; - - vp->res[0] = ceil(dim[0] * res); - vp->res[1] = ceil(dim[1] * res); - vp->res[2] = ceil(dim[2] * res); - - if ((vp->res[0] < 1) || (vp->res[1] < 1) || (vp->res[2] < 1)) - return 0; - - return 1; -} - -/* Precache a volume into a 3D voxel grid. - * The voxel grid is stored in the ObjectInstanceRen, - * in camera space, aligned with the ObjectRen's bounding box. - * Resolution is defined by the user. - */ -static void vol_precache_objectinstance_threads(Render *re, ObjectInstanceRen *obi, Material *ma) -{ - VolumePrecache *vp; - RayObject *tree; - ShadeInput shi; - - R = *re; - - /* create a raytree with just the faces of the instanced ObjectRen, - * used for checking if the cached point is inside or outside. */ - tree = makeraytree_object(&R, obi); - if (!tree) return; - - vp = MEM_callocN(sizeof(VolumePrecache), "volume light cache"); - obi->volume_precache = vp; - - if (!precache_resolution(re, vp, obi, ma->vol.precache_resolution)) { - MEM_freeN(vp); - vp = NULL; - return; - } - - vp->data_r = MEM_callocN(sizeof(float)*vp->res[0]*vp->res[1]*vp->res[2], "volume light cache data red channel"); - vp->data_g = MEM_callocN(sizeof(float)*vp->res[0]*vp->res[1]*vp->res[2], "volume light cache data green channel"); - vp->data_b = MEM_callocN(sizeof(float)*vp->res[0]*vp->res[1]*vp->res[2], "volume light cache data blue channel"); - if (vp->data_r==NULL || vp->data_g==NULL || vp->data_b==NULL) { - MEM_freeN(vp); - return; - } - - /* Need a shadeinput to calculate scattering */ - precache_setup_shadeinput(re, obi, ma, &shi); - - precache_launch_parts(re, tree, &shi, obi); - - if (tree) { - /* TODO: makeraytree_object creates a tree and saves it on OBI, - * if we free this tree we should also clear other pointers to it */ - //RE_rayobject_free(tree); - //tree= NULL; - } - - if (ELEM(ma->vol.shade_type, MA_VOL_SHADE_MULTIPLE, MA_VOL_SHADE_SHADEDPLUSMULTIPLE)) { - /* this should be before the filtering */ - multiple_scattering_diffusion(re, obi->volume_precache, ma); - } - - lightcache_filter(obi->volume_precache); -} - -static int using_lightcache(Material *ma) -{ - return (((ma->vol.shadeflag & MA_VOL_PRECACHESHADING) && (ma->vol.shade_type == MA_VOL_SHADE_SHADED)) || - (ELEM(ma->vol.shade_type, MA_VOL_SHADE_MULTIPLE, MA_VOL_SHADE_SHADEDPLUSMULTIPLE))); -} - -/* loop through all objects (and their associated materials) - * marked for pre-caching in convertblender.c, and pre-cache them */ -void volume_precache(Render *re) -{ - ObjectInstanceRen *obi; - VolumeOb *vo; - - re->i.infostr = IFACE_("Volume preprocessing"); - re->stats_draw(re->sdh, &re->i); - - for (vo= re->volumes.first; vo; vo= vo->next) { - if (using_lightcache(vo->ma)) { - for (obi= re->instancetable.first; obi; obi= obi->next) { - if (obi->obr == vo->obr) { - vol_precache_objectinstance_threads(re, obi, vo->ma); - - if (re->test_break && re->test_break(re->tbh)) - break; - } - } - - if (re->test_break && re->test_break(re->tbh)) - break; - } - } - - re->i.infostr = NULL; - re->stats_draw(re->sdh, &re->i); -} - -void free_volume_precache(Render *re) -{ - ObjectInstanceRen *obi; - - for (obi= re->instancetable.first; obi; obi= obi->next) { - if (obi->volume_precache != NULL) { - MEM_freeN(obi->volume_precache->data_r); - MEM_freeN(obi->volume_precache->data_g); - MEM_freeN(obi->volume_precache->data_b); - MEM_freeN(obi->volume_precache->bbmin); - MEM_freeN(obi->volume_precache->bbmax); - MEM_freeN(obi->volume_precache); - obi->volume_precache = NULL; - } - } - - BLI_freelistN(&re->volumes); -} - -int point_inside_volume_objectinstance(Render *re, ObjectInstanceRen *obi, const float co[3]) -{ - RayObject *tree; - int inside=0; - - tree = makeraytree_object(re, obi); - if (!tree) return 0; - - inside = point_inside_obi(tree, obi, co); - - //TODO: makeraytree_object creates a tree and saves it on OBI, if we free this tree we should also clear other pointers to it - //RE_rayobject_free(tree); - //tree= NULL; - - return inside; -} - diff --git a/source/blender/render/intern/source/volumetric.c b/source/blender/render/intern/source/volumetric.c deleted file mode 100644 index e12a7246254..00000000000 --- a/source/blender/render/intern/source/volumetric.c +++ /dev/null @@ -1,834 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): Matt Ebb, Raul Fernandez Hernandez (Farsthary) - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/render/intern/source/volumetric.c - * \ingroup render - */ - -#include <math.h> -#include <stdlib.h> -#include <string.h> -#include <float.h> - -#include "BLI_math.h" -#include "BLI_rand.h" -#include "BLI_voxel.h" -#include "BLI_utildefines.h" - -#include "RE_shader_ext.h" - -#include "IMB_colormanagement.h" - -#include "DNA_material_types.h" -#include "DNA_group_types.h" -#include "DNA_lamp_types.h" -#include "DNA_meta_types.h" - - -#include "render_types.h" -#include "pixelshading.h" -#include "rayintersection.h" -#include "rayobject.h" -#include "renderdatabase.h" -#include "shading.h" -#include "shadbuf.h" -#include "texture.h" -#include "volumetric.h" -#include "volume_precache.h" - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -/* defined in pipeline.c, is hardcopy of active dynamic allocated Render */ -/* only to be used here in this file, it's for speed */ -extern struct Render R; -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -/* tracing */ -static float vol_get_shadow(ShadeInput *shi, LampRen *lar, const float co[3]) -{ - float visibility = 1.f; - - if (lar->shb) { - float dxco[3] = {0.f, 0.f, 0.f}, dyco[3] = {0.f, 0.f, 0.f}; - - visibility = testshadowbuf(&R, lar->shb, co, dxco, dyco, 1.0, 0.0); - } - else if (lar->mode & LA_SHAD_RAY) { - /* trace shadow manually, no good lamp api atm */ - Isect is; - - copy_v3_v3(is.start, co); - if (lar->type == LA_SUN || lar->type == LA_HEMI) { - is.dir[0] = -lar->vec[0]; - is.dir[1] = -lar->vec[1]; - is.dir[2] = -lar->vec[2]; - is.dist = R.maxdist; - } - else { - sub_v3_v3v3(is.dir, lar->co, is.start); - is.dist = normalize_v3(is.dir); - } - - is.mode = RE_RAY_MIRROR; - is.check = RE_CHECK_VLR_NON_SOLID_MATERIAL; - is.skip = 0; - - if (lar->mode & (LA_LAYER | LA_LAYER_SHADOW)) - is.lay = lar->lay; - else - is.lay = -1; - - is.orig.ob = NULL; - is.orig.face = NULL; - is.last_hit = lar->last_hit[shi->thread]; - - RE_instance_rotate_ray(shi->obi, &is); - - if (RE_rayobject_raycast(R.raytree, &is)) { - RE_instance_rotate_ray_restore(shi->obi, &is); - - visibility = 0.f; - } - - lar->last_hit[shi->thread] = is.last_hit; - } - return visibility; -} - -static int vol_get_bounds(ShadeInput *shi, const float co[3], const float vec[3], float hitco[3], Isect *isect, int intersect_type) -{ - - copy_v3_v3(isect->start, co); - copy_v3_v3(isect->dir, vec); - isect->dist = FLT_MAX; - isect->mode = RE_RAY_MIRROR; - isect->last_hit = NULL; - isect->lay = -1; - isect->check = RE_CHECK_VLR_NONE; - - if (intersect_type == VOL_BOUNDS_DEPTH) { - isect->skip = RE_SKIP_VLR_NEIGHBOUR; - isect->orig.face = (void *)shi->vlr; - isect->orig.ob = (void *)shi->obi; - } - else { // if (intersect_type == VOL_BOUNDS_SS) { - isect->skip = 0; - isect->orig.face = NULL; - isect->orig.ob = NULL; - } - - RE_instance_rotate_ray(shi->obi, isect); - - if (RE_rayobject_raycast(R.raytree, isect)) { - RE_instance_rotate_ray_restore(shi->obi, isect); - - hitco[0] = isect->start[0] + isect->dist * isect->dir[0]; - hitco[1] = isect->start[1] + isect->dist * isect->dir[1]; - hitco[2] = isect->start[2] + isect->dist * isect->dir[2]; - return 1; - } - else { - return 0; - } -} - -static void shade_intersection(ShadeInput *shi, float col_r[4], Isect *is) -{ - ShadeInput shi_new; - ShadeResult shr_new; - - memset(&shi_new, 0, sizeof(ShadeInput)); - - shi_new.mask = shi->mask; - shi_new.osatex = shi->osatex; - shi_new.thread = shi->thread; - shi_new.depth = shi->depth + 1; - shi_new.volume_depth = shi->volume_depth + 1; - shi_new.xs = shi->xs; - shi_new.ys = shi->ys; - shi_new.lay = shi->lay; - shi_new.passflag = SCE_PASS_COMBINED; /* result of tracing needs no pass info */ - shi_new.combinedflag = 0xFFFFFF; /* ray trace does all options */ - - copy_v3_v3(shi_new.camera_co, is->start); - - memset(&shr_new, 0, sizeof(ShadeResult)); - - /* hardcoded limit of 100 for now - prevents problems in weird geometry */ - if (shi->volume_depth < 100) { - shade_ray(is, &shi_new, &shr_new); - } - - copy_v3_v3(col_r, shr_new.combined); - col_r[3] = shr_new.alpha; -} - -static void vol_trace_behind(ShadeInput *shi, VlakRen *vlr, const float co[3], float col_r[4]) -{ - Isect isect; - - copy_v3_v3(isect.start, co); - copy_v3_v3(isect.dir, shi->view); - isect.dist = FLT_MAX; - - isect.mode = RE_RAY_MIRROR; - isect.check = RE_CHECK_VLR_NONE; - isect.skip = RE_SKIP_VLR_NEIGHBOUR; - isect.orig.ob = (void *) shi->obi; - isect.orig.face = (void *)vlr; - isect.last_hit = NULL; - isect.lay = -1; - - /* check to see if there's anything behind the volume, otherwise shade the sky */ - RE_instance_rotate_ray(shi->obi, &isect); - - if (RE_rayobject_raycast(R.raytree, &isect)) { - RE_instance_rotate_ray_restore(shi->obi, &isect); - - shade_intersection(shi, col_r, &isect); - } - else { - shadeSkyView(col_r, co, shi->view, NULL, shi->thread); - shadeSunView(col_r, shi->view); - } -} - - -/* trilinear interpolation */ -static void vol_get_precached_scattering(Render *re, ShadeInput *shi, float scatter_col[3], const float co[3]) -{ - VolumePrecache *vp = shi->obi->volume_precache; - float bbmin[3], bbmax[3], dim[3]; - float world_co[3], sample_co[3]; - - if (!vp) return; - - /* find sample point in global space bounding box 0.0-1.0 */ - global_bounds_obi(re, shi->obi, bbmin, bbmax); - sub_v3_v3v3(dim, bbmax, bbmin); - mul_v3_m4v3(world_co, re->viewinv, co); - - /* sample_co in 0.0-1.0 */ - sample_co[0] = (world_co[0] - bbmin[0]) / dim[0]; - sample_co[1] = (world_co[1] - bbmin[1]) / dim[1]; - sample_co[2] = (world_co[2] - bbmin[2]) / dim[2]; - - scatter_col[0] = BLI_voxel_sample_triquadratic(vp->data_r, vp->res, sample_co); - scatter_col[1] = BLI_voxel_sample_triquadratic(vp->data_g, vp->res, sample_co); - scatter_col[2] = BLI_voxel_sample_triquadratic(vp->data_b, vp->res, sample_co); -} - -/* Meta object density, brute force for now - * (might be good enough anyway, don't need huge number of metaobs to model volumetric objects */ -static float metadensity(Object *ob, const float co[3]) -{ - float mat[4][4], imat[4][4], dens = 0.f; - MetaBall *mb = (MetaBall *)ob->data; - MetaElem *ml; - - /* transform co to meta-element */ - float tco[3] = {co[0], co[1], co[2]}; - mul_m4_m4m4(mat, R.viewmat, ob->obmat); - invert_m4_m4(imat, mat); - mul_m4_v3(imat, tco); - - for (ml = mb->elems.first; ml; ml = ml->next) { - float bmat[3][3], dist2; - - /* element rotation transform */ - float tp[3] = {ml->x - tco[0], ml->y - tco[1], ml->z - tco[2]}; - quat_to_mat3(bmat, ml->quat); - transpose_m3(bmat); /* rot.only, so inverse == transpose */ - mul_m3_v3(bmat, tp); - - /* MB_BALL default */ - switch (ml->type) { - case MB_ELIPSOID: - tp[0] /= ml->expx; - tp[1] /= ml->expy; - tp[2] /= ml->expz; - break; - case MB_CUBE: - tp[2] = (tp[2] > ml->expz) ? (tp[2] - ml->expz) : ((tp[2] < -ml->expz) ? (tp[2] + ml->expz) : 0.f); - /* no break, xy as plane */ - ATTR_FALLTHROUGH; - case MB_PLANE: - tp[1] = (tp[1] > ml->expy) ? (tp[1] - ml->expy) : ((tp[1] < -ml->expy) ? (tp[1] + ml->expy) : 0.f); - /* no break, x as tube */ - ATTR_FALLTHROUGH; - case MB_TUBE: - tp[0] = (tp[0] > ml->expx) ? (tp[0] - ml->expx) : ((tp[0] < -ml->expx) ? (tp[0] + ml->expx) : 0.f); - } - - /* ml->rad2 is not set */ - dist2 = 1.0f - (dot_v3v3(tp, tp) / (ml->rad * ml->rad)); - if (dist2 > 0.f) - dens += (ml->flag & MB_NEGATIVE) ? -ml->s * dist2 * dist2 * dist2 : ml->s * dist2 * dist2 * dist2; - } - - dens -= mb->thresh; - return (dens < 0.f) ? 0.f : dens; -} - -float vol_get_density(struct ShadeInput *shi, const float co[3]) -{ - float density = shi->mat->vol.density; - float density_scale = shi->mat->vol.density_scale; - - if (shi->mat->mapto_textured & MAP_DENSITY) - do_volume_tex(shi, co, MAP_DENSITY, NULL, &density, &R); - - /* if meta-object, modulate by metadensity without increasing it */ - if (shi->obi->obr->ob->type == OB_MBALL) { - const float md = metadensity(shi->obi->obr->ob, co); - if (md < 1.f) density *= md; - } - - return density * density_scale; -} - - -/* Color of light that gets scattered out by the volume */ -/* Uses same physically based scattering parameter as in transmission calculations, - * along with artificial reflection scale/reflection color tint */ -static void vol_get_reflection_color(ShadeInput *shi, float ref_col[3], const float co[3]) -{ - float scatter = shi->mat->vol.scattering; - float reflection = shi->mat->vol.reflection; - copy_v3_v3(ref_col, shi->mat->vol.reflection_col); - - if (shi->mat->mapto_textured & (MAP_SCATTERING + MAP_REFLECTION_COL)) - do_volume_tex(shi, co, MAP_SCATTERING + MAP_REFLECTION_COL, ref_col, &scatter, &R); - - /* only one single float parameter at a time... :s */ - if (shi->mat->mapto_textured & (MAP_REFLECTION)) - do_volume_tex(shi, co, MAP_REFLECTION, NULL, &reflection, &R); - - ref_col[0] = reflection * ref_col[0] * scatter; - ref_col[1] = reflection * ref_col[1] * scatter; - ref_col[2] = reflection * ref_col[2] * scatter; -} - -/* compute emission component, amount of radiance to add per segment - * can be textured with 'emit' */ -static void vol_get_emission(ShadeInput *shi, float emission_col[3], const float co[3]) -{ - float emission = shi->mat->vol.emission; - copy_v3_v3(emission_col, shi->mat->vol.emission_col); - - if (shi->mat->mapto_textured & (MAP_EMISSION + MAP_EMISSION_COL)) - do_volume_tex(shi, co, MAP_EMISSION + MAP_EMISSION_COL, emission_col, &emission, &R); - - emission_col[0] = emission_col[0] * emission; - emission_col[1] = emission_col[1] * emission; - emission_col[2] = emission_col[2] * emission; -} - - -/* A combination of scattering and absorption -> known as sigma T. - * This can possibly use a specific scattering color, - * and absorption multiplier factor too, but these parameters are left out for simplicity. - * It's easy enough to get a good wide range of results with just these two parameters. */ -static void vol_get_sigma_t(ShadeInput *shi, float sigma_t[3], const float co[3]) -{ - /* technically absorption, but named transmission color - * since it describes the effect of the coloring *after* absorption */ - float transmission_col[3] = {shi->mat->vol.transmission_col[0], shi->mat->vol.transmission_col[1], shi->mat->vol.transmission_col[2]}; - float scattering = shi->mat->vol.scattering; - - if (shi->mat->mapto_textured & (MAP_SCATTERING + MAP_TRANSMISSION_COL)) - do_volume_tex(shi, co, MAP_SCATTERING + MAP_TRANSMISSION_COL, transmission_col, &scattering, &R); - - sigma_t[0] = (1.0f - transmission_col[0]) + scattering; - sigma_t[1] = (1.0f - transmission_col[1]) + scattering; - sigma_t[2] = (1.0f - transmission_col[2]) + scattering; -} - -/* phase function - determines in which directions the light - * is scattered in the volume relative to incoming direction - * and view direction */ -static float vol_get_phasefunc(ShadeInput *UNUSED(shi), float g, const float w[3], const float wp[3]) -{ - const float normalize = 0.25f; // = 1.f/4.f = M_PI/(4.f*M_PI) - - /* normalization constant is 1/4 rather than 1/4pi, since - * Blender's shading system doesn't normalize for - * energy conservation - eg. multiplying by pdf ( 1/pi for a lambert brdf ). - * This means that lambert surfaces in Blender are pi times brighter than they 'should be' - * and therefore, with correct energy conservation, volumes will darker than other solid objects, - * for the same lighting intensity. - * To correct this, scale up the phase function values by pi - * until Blender's shading system supports this better. --matt - */ - - if (g == 0.f) { /* isotropic */ - return normalize * 1.f; - } - else { /* schlick */ - const float k = 1.55f * g - 0.55f * g * g * g; - const float kcostheta = k * dot_v3v3(w, wp); - return normalize * (1.f - k * k) / ((1.f - kcostheta) * (1.f - kcostheta)); - } - - /* not used, but here for reference: */ -#if 0 - switch (phasefunc_type) { - case MA_VOL_PH_MIEHAZY: - return normalize * (0.5f + 4.5f * powf(0.5 * (1.f + costheta), 8.f)); - case MA_VOL_PH_MIEMURKY: - return normalize * (0.5f + 16.5f * powf(0.5 * (1.f + costheta), 32.f)); - case MA_VOL_PH_RAYLEIGH: - return normalize * 3.f / 4.f * (1 + costheta * costheta); - case MA_VOL_PH_HG: - return normalize * (1.f - g * g) / powf(1.f + g * g - 2.f * g * costheta, 1.5f); - case MA_VOL_PH_SCHLICK: - { - const float k = 1.55f * g - 0.55f * g * g * g; - const float kcostheta = k * costheta; - return normalize * (1.f - k * k) / ((1.f - kcostheta) * (1.f - kcostheta)); - } - case MA_VOL_PH_ISOTROPIC: - default: - return normalize * 1.f; - } -#endif -} - -/* Compute transmittance = e^(-attenuation) */ -static void vol_get_transmittance_seg(ShadeInput *shi, float tr[3], float stepsize, const float co[3], float density) -{ - /* input density = density at co */ - float tau[3] = {0.f, 0.f, 0.f}; - const float stepd = density * stepsize; - float sigma_t[3]; - - vol_get_sigma_t(shi, sigma_t, co); - - /* homogeneous volume within the sampled distance */ - tau[0] += stepd * sigma_t[0]; - tau[1] += stepd * sigma_t[1]; - tau[2] += stepd * sigma_t[2]; - - tr[0] *= expf(-tau[0]); - tr[1] *= expf(-tau[1]); - tr[2] *= expf(-tau[2]); -} - -/* Compute transmittance = e^(-attenuation) */ -static void vol_get_transmittance(ShadeInput *shi, float tr[3], const float co[3], const float endco[3]) -{ - float p[3] = {co[0], co[1], co[2]}; - float step_vec[3] = {endco[0] - co[0], endco[1] - co[1], endco[2] - co[2]}; - float tau[3] = {0.f, 0.f, 0.f}; - - float t0 = 0.f; - float t1 = normalize_v3(step_vec); - float pt0 = t0; - - t0 += shi->mat->vol.stepsize * ((shi->mat->vol.stepsize_type == MA_VOL_STEP_CONSTANT) ? 0.5f : BLI_thread_frand(shi->thread)); - p[0] += t0 * step_vec[0]; - p[1] += t0 * step_vec[1]; - p[2] += t0 * step_vec[2]; - mul_v3_fl(step_vec, shi->mat->vol.stepsize); - - for (; t0 < t1; pt0 = t0, t0 += shi->mat->vol.stepsize) { - const float d = vol_get_density(shi, p); - const float stepd = (t0 - pt0) * d; - float sigma_t[3]; - - vol_get_sigma_t(shi, sigma_t, p); - - tau[0] += stepd * sigma_t[0]; - tau[1] += stepd * sigma_t[1]; - tau[2] += stepd * sigma_t[2]; - - add_v3_v3(p, step_vec); - } - - /* return transmittance */ - tr[0] = expf(-tau[0]); - tr[1] = expf(-tau[1]); - tr[2] = expf(-tau[2]); -} - -static void vol_shade_one_lamp(struct ShadeInput *shi, const float co[3], const float view[3], LampRen *lar, float lacol[3]) -{ - float visifac, lv[3], lampdist; - float tr[3] = {1.0, 1.0, 1.0}; - float hitco[3], *atten_co; - float p, ref_col[3]; - - if (lar->mode & LA_LAYER) if ((lar->lay & shi->obi->lay) == 0) return; - if ((lar->lay & shi->lay) == 0) return; - if (lar->energy == 0.0f) return; - - if ((visifac = lamp_get_visibility(lar, co, lv, &lampdist)) == 0.f) return; - - copy_v3_v3(lacol, &lar->r); - - if (lar->mode & LA_TEXTURE) { - shi->osatex = 0; - do_lamp_tex(lar, lv, shi, lacol, LA_TEXTURE); - } - - mul_v3_fl(lacol, visifac); - - if (ELEM(lar->type, LA_SUN, LA_HEMI)) - copy_v3_v3(lv, lar->vec); - negate_v3(lv); - - if (shi->mat->vol.shade_type == MA_VOL_SHADE_SHADOWED) { - mul_v3_fl(lacol, vol_get_shadow(shi, lar, co)); - } - else if (ELEM(shi->mat->vol.shade_type, MA_VOL_SHADE_SHADED, MA_VOL_SHADE_MULTIPLE, MA_VOL_SHADE_SHADEDPLUSMULTIPLE)) { - Isect is; - - if (shi->mat->vol.shadeflag & MA_VOL_RECV_EXT_SHADOW) { - mul_v3_fl(lacol, vol_get_shadow(shi, lar, co)); - if (IMB_colormanagement_get_luminance(lacol) < 0.001f) return; - } - - /* find minimum of volume bounds, or lamp coord */ - if (vol_get_bounds(shi, co, lv, hitco, &is, VOL_BOUNDS_SS)) { - float dist = len_v3v3(co, hitco); - VlakRen *vlr = (VlakRen *)is.hit.face; - - /* simple internal shadowing */ - if (vlr->mat->material_type == MA_TYPE_SURFACE) { - lacol[0] = lacol[1] = lacol[2] = 0.0f; - return; - } - - if (ELEM(lar->type, LA_SUN, LA_HEMI)) - /* infinite lights, can never be inside volume */ - atten_co = hitco; - else if (lampdist < dist) { - atten_co = lar->co; - } - else - atten_co = hitco; - - vol_get_transmittance(shi, tr, co, atten_co); - - mul_v3_v3v3(lacol, lacol, tr); - } - else { - /* Point is on the outside edge of the volume, - * therefore no attenuation, full transmission. - * Radiance from lamp remains unchanged */ - } - } - - if (IMB_colormanagement_get_luminance(lacol) < 0.001f) return; - - normalize_v3(lv); - p = vol_get_phasefunc(shi, shi->mat->vol.asymmetry, view, lv); - - /* physically based scattering with non-physically based RGB gain */ - vol_get_reflection_color(shi, ref_col, co); - - lacol[0] *= p * ref_col[0]; - lacol[1] *= p * ref_col[1]; - lacol[2] *= p * ref_col[2]; -} - -/* single scattering only for now */ -void vol_get_scattering(ShadeInput *shi, float scatter_col[3], const float co[3], const float view[3]) -{ - ListBase *lights; - GroupObject *go; - LampRen *lar; - - zero_v3(scatter_col); - - lights = get_lights(shi); - for (go = lights->first; go; go = go->next) { - float lacol[3] = {0.f, 0.f, 0.f}; - lar = go->lampren; - - if (lar) { - vol_shade_one_lamp(shi, co, view, lar, lacol); - add_v3_v3(scatter_col, lacol); - } - } -} - - -/* - * The main volumetric integrator, using an emission/absorption/scattering model. - * - * Incoming radiance = - * - * outgoing radiance from behind surface * beam transmittance/attenuation - * + added radiance from all points along the ray due to participating media - * --> radiance for each segment = - * (radiance added by scattering + radiance added by emission) * beam transmittance/attenuation - */ - -/* For ease of use, I've also introduced a 'reflection' and 'reflection color' parameter, which isn't - * physically correct. This works as an RGB tint/gain on out-scattered light, but doesn't affect the light - * that is transmitted through the volume. While having wavelength dependent absorption/scattering is more correct, - * it also makes it harder to control the overall look of the volume since coloring the outscattered light results - * in the inverse color being transmitted through the rest of the volume. - */ -static void volumeintegrate(struct ShadeInput *shi, float col[4], const float co[3], const float endco[3]) -{ - float radiance[3] = {0.f, 0.f, 0.f}; - float tr[3] = {1.f, 1.f, 1.f}; - float p[3] = {co[0], co[1], co[2]}; - float step_vec[3] = {endco[0] - co[0], endco[1] - co[1], endco[2] - co[2]}; - const float stepsize = shi->mat->vol.stepsize; - - float t0 = 0.f; - float pt0 = t0; - float t1 = normalize_v3(step_vec); /* returns vector length */ - - t0 += stepsize * ((shi->mat->vol.stepsize_type == MA_VOL_STEP_CONSTANT) ? 0.5f : BLI_thread_frand(shi->thread)); - p[0] += t0 * step_vec[0]; - p[1] += t0 * step_vec[1]; - p[2] += t0 * step_vec[2]; - mul_v3_fl(step_vec, stepsize); - - for (; t0 < t1; pt0 = t0, t0 += stepsize) { - const float density = vol_get_density(shi, p); - - if (density > 0.00001f) { - float scatter_col[3] = {0.f, 0.f, 0.f}, emit_col[3]; - const float stepd = (t0 - pt0) * density; - - /* transmittance component (alpha) */ - vol_get_transmittance_seg(shi, tr, stepsize, co, density); - - if (t0 > t1 * 0.25f) { - /* only use depth cutoff after we've traced a little way into the volume */ - if (IMB_colormanagement_get_luminance(tr) < shi->mat->vol.depth_cutoff) break; - } - - vol_get_emission(shi, emit_col, p); - - if (shi->obi->volume_precache) { - float p2[3]; - - p2[0] = p[0] + (step_vec[0] * 0.5f); - p2[1] = p[1] + (step_vec[1] * 0.5f); - p2[2] = p[2] + (step_vec[2] * 0.5f); - - vol_get_precached_scattering(&R, shi, scatter_col, p2); - } - else - vol_get_scattering(shi, scatter_col, p, shi->view); - - radiance[0] += stepd * tr[0] * (emit_col[0] + scatter_col[0]); - radiance[1] += stepd * tr[1] * (emit_col[1] + scatter_col[1]); - radiance[2] += stepd * tr[2] * (emit_col[2] + scatter_col[2]); - } - add_v3_v3(p, step_vec); - } - - /* multiply original color (from behind volume) with transmittance over entire distance */ - mul_v3_v3v3(col, tr, col); - add_v3_v3(col, radiance); - - /* alpha <-- transmission luminance */ - col[3] = 1.0f - IMB_colormanagement_get_luminance(tr); -} - -/* the main entry point for volume shading */ -static void volume_trace(struct ShadeInput *shi, struct ShadeResult *shr, int inside_volume) -{ - float hitco[3], col[4] = {0.f, 0.f, 0.f, 0.f}; - const float *startco, *endco; - int trace_behind = 1; - const int ztransp = ((shi->depth == 0) && (shi->mat->mode & MA_TRANSP) && (shi->mat->mode & MA_ZTRANSP)); - Isect is; - - /* check for shading an internal face a volume object directly */ - if (inside_volume == VOL_SHADE_INSIDE) - trace_behind = 0; - else if (inside_volume == VOL_SHADE_OUTSIDE) { - if (shi->flippednor) - inside_volume = VOL_SHADE_INSIDE; - } - - if (ztransp && inside_volume == VOL_SHADE_INSIDE) { - MatInside *mi; - int render_this = 0; - - /* don't render the backfaces of ztransp volume materials. - * - * volume shading renders the internal volume from between the - * ' view intersection of the solid volume to the - * intersection on the other side, as part of the shading of - * the front face. - * - * Because ztransp renders both front and back faces independently - * this will double up, so here we prevent rendering the backface as well, - * which would otherwise render the volume in between the camera and the backface - * --matt */ - - for (mi = R.render_volumes_inside.first; mi; mi = mi->next) { - /* weak... */ - if (mi->ma == shi->mat) render_this = 1; - } - if (!render_this) return; - } - - - if (inside_volume == VOL_SHADE_INSIDE) { - startco = shi->camera_co; - endco = shi->co; - - if (trace_behind) { - if (!ztransp) - /* trace behind the volume object */ - vol_trace_behind(shi, shi->vlr, endco, col); - } - else { - /* we're tracing through the volume between the camera - * and a solid surface, so use that pre-shaded radiance */ - copy_v4_v4(col, shr->combined); - } - - /* shade volume from 'camera' to 1st hit point */ - volumeintegrate(shi, col, startco, endco); - } - /* trace to find a backface, the other side bounds of the volume */ - /* (ray intersect ignores front faces here) */ - else if (vol_get_bounds(shi, shi->co, shi->view, hitco, &is, VOL_BOUNDS_DEPTH)) { - VlakRen *vlr = (VlakRen *)is.hit.face; - - startco = shi->co; - endco = hitco; - - if (!ztransp) { - /* if it's another face in the same material */ - if (vlr->mat == shi->mat) { - /* trace behind the 2nd (raytrace) hit point */ - vol_trace_behind(shi, (VlakRen *)is.hit.face, endco, col); - } - else { - shade_intersection(shi, col, &is); - } - } - - /* shade volume from 1st hit point to 2nd hit point */ - volumeintegrate(shi, col, startco, endco); - } - - if (ztransp) - col[3] = col[3] > 1.f ? 1.f : col[3]; - else - col[3] = 1.f; - - copy_v3_v3(shr->combined, col); - shr->alpha = col[3]; - - copy_v3_v3(shr->diff, shr->combined); - copy_v3_v3(shr->diffshad, shr->diff); -} - -/* Traces a shadow through the object, - * pretty much gets the transmission over a ray path */ -void shade_volume_shadow(struct ShadeInput *shi, struct ShadeResult *shr, struct Isect *last_is) -{ - float hitco[3]; - float tr[3] = {1.0, 1.0, 1.0}; - Isect is = {{0}}; - const float *startco, *endco; - - memset(shr, 0, sizeof(ShadeResult)); - - /* if 1st hit normal is facing away from the camera, - * then we're inside the volume already. */ - if (shi->flippednor) { - startco = last_is->start; - endco = shi->co; - } - - /* trace to find a backface, the other side bounds of the volume */ - /* (ray intersect ignores front faces here) */ - else if (vol_get_bounds(shi, shi->co, shi->view, hitco, &is, VOL_BOUNDS_DEPTH)) { - startco = shi->co; - endco = hitco; - } - else { - shr->combined[0] = shr->combined[1] = shr->combined[2] = 0.f; - shr->alpha = shr->combined[3] = 1.f; - return; - } - - vol_get_transmittance(shi, tr, startco, endco); - - - /* if we hit another face in the same volume bounds */ - /* shift raytrace coordinates to the hit point, to avoid shading volume twice */ - /* due to idiosyncracy in ray_trace_shadow_tra() */ - if (is.hit.ob == shi->obi) { - copy_v3_v3(shi->co, hitco); - last_is->dist += is.dist; - shi->vlr = (VlakRen *)is.hit.face; - } - - - copy_v3_v3(shr->combined, tr); - shr->combined[3] = 1.0f - IMB_colormanagement_get_luminance(tr); - shr->alpha = shr->combined[3]; -} - - -/* delivers a fully filled in ShadeResult, for all passes */ -void shade_volume_outside(ShadeInput *shi, ShadeResult *shr) -{ - memset(shr, 0, sizeof(ShadeResult)); - volume_trace(shi, shr, VOL_SHADE_OUTSIDE); -} - - -void shade_volume_inside(ShadeInput *shi, ShadeResult *shr) -{ - MatInside *m; - Material *mat_backup; - ObjectInstanceRen *obi_backup; - float prev_alpha = shr->alpha; - - /* XXX: extend to multiple volumes perhaps later */ - mat_backup = shi->mat; - obi_backup = shi->obi; - - m = R.render_volumes_inside.first; - shi->mat = m->ma; - shi->obi = m->obi; - shi->obr = m->obi->obr; - - volume_trace(shi, shr, VOL_SHADE_INSIDE); - - shr->alpha = shr->alpha + prev_alpha; - CLAMP(shr->alpha, 0.0f, 1.0f); - - shi->mat = mat_backup; - shi->obi = obi_backup; - shi->obr = obi_backup->obr; -} diff --git a/source/blender/render/intern/source/voxeldata.c b/source/blender/render/intern/source/voxeldata.c deleted file mode 100644 index c45bde300e7..00000000000 --- a/source/blender/render/intern/source/voxeldata.c +++ /dev/null @@ -1,571 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): Raul Fernandez Hernandez (Farsthary), Matt Ebb. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/render/intern/source/voxeldata.c - * \ingroup render - */ - - -#include <math.h> -#include <stdlib.h> -#include <stdio.h> - -#ifdef WIN32 -#include "BLI_winstuff.h" -#endif - -#include "MEM_guardedalloc.h" - -#include "BLI_math.h" -#include "BLI_blenlib.h" -#include "BLI_threads.h" -#include "BLI_voxel.h" -#include "BLI_utildefines.h" - -#include "BLT_translation.h" - -#include "IMB_imbuf.h" -#include "IMB_imbuf_types.h" - -#include "BKE_cloth.h" -#include "BKE_global.h" -#include "BKE_image.h" -#include "BKE_main.h" -#include "BKE_modifier.h" - -#include "smoke_API.h" -#include "BPH_mass_spring.h" - -#include "DNA_texture_types.h" -#include "DNA_object_force_types.h" -#include "DNA_object_types.h" -#include "DNA_particle_types.h" -#include "DNA_modifier_types.h" -#include "DNA_smoke_types.h" - - -#include "render_types.h" -#include "texture.h" -#include "voxeldata.h" - -static bool is_vd_res_ok(VoxelData *vd) -{ - /* arbitrary large value so corrupt headers don't break */ - const int min = 1, max = 100000; - return (vd->resol[0] >= min && vd->resol[0] <= max) && - (vd->resol[1] >= min && vd->resol[1] <= max) && - (vd->resol[2] >= min && vd->resol[2] <= max); -} - -/* use size_t because the result may exceed INT_MAX */ -static size_t vd_resol_size(VoxelData *vd) -{ - return (size_t)vd->resol[0] * (size_t)vd->resol[1] * (size_t)vd->resol[2]; -} - -static int load_frame_blendervoxel(VoxelData *vd, FILE *fp, int frame) -{ - const size_t size = vd_resol_size(vd); - size_t offset = sizeof(VoxelDataHeader); - - if (is_vd_res_ok(vd) == false) - return 0; - - vd->dataset = MEM_mapallocN(sizeof(float) * size, "voxel dataset"); - if (vd->dataset == NULL) return 0; - - if (fseek(fp, frame * size * sizeof(float) + offset, 0) == -1) - return 0; - if (fread(vd->dataset, sizeof(float), size, fp) != size) - return 0; - - vd->cachedframe = frame; - vd->ok = 1; - return 1; -} - -static int load_frame_raw8(VoxelData *vd, FILE *fp, int frame) -{ - const size_t size = vd_resol_size(vd); - size_t i; - char *data_c; - - if (is_vd_res_ok(vd) == false) - return 0; - - vd->dataset = MEM_mapallocN(sizeof(float) * size, "voxel dataset"); - if (vd->dataset == NULL) return 0; - data_c = (char *)MEM_mallocN(sizeof(char) * size, "temporary voxel file reading storage"); - if (data_c == NULL) { - MEM_freeN(vd->dataset); - vd->dataset = NULL; - return 0; - } - - if (fseek(fp, (frame - 1) * size * sizeof(char), 0) == -1) { - MEM_freeN(data_c); - MEM_freeN(vd->dataset); - vd->dataset = NULL; - return 0; - } - if (fread(data_c, sizeof(char), size, fp) != size) { - MEM_freeN(data_c); - MEM_freeN(vd->dataset); - vd->dataset = NULL; - return 0; - } - - for (i = 0; i < size; i++) { - vd->dataset[i] = (float)data_c[i] / 255.f; - } - MEM_freeN(data_c); - - vd->cachedframe = frame; - vd->ok = 1; - return 1; -} - -static void load_frame_image_sequence(VoxelData *vd, Tex *tex) -{ - ImBuf *ibuf; - Image *ima = tex->ima; - ImageUser *tiuser = &tex->iuser; - ImageUser iuser = *(tiuser); - int x = 0, y = 0, z = 0; - const float *rf; - - if (!ima) return; - if (iuser.frames == 0) return; - - ima->source = IMA_SRC_SEQUENCE; - iuser.framenr = 1 + iuser.offset; - - /* find the first valid ibuf and use it to initialize the resolution of the data set */ - /* need to do this in advance so we know how much memory to allocate */ - ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL); - while (!ibuf && (iuser.framenr < iuser.frames)) { - iuser.framenr++; - ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL); - } - if (!ibuf) return; - if (!ibuf->rect_float) IMB_float_from_rect(ibuf); - - vd->flag |= TEX_VD_STILL; - vd->resol[0] = ibuf->x; - vd->resol[1] = ibuf->y; - vd->resol[2] = iuser.frames; - vd->dataset = MEM_mapallocN(sizeof(float) * vd_resol_size(vd), "voxel dataset"); - - for (z = 0; z < iuser.frames; z++) { - /* get a new ibuf for each frame */ - if (z > 0) { - iuser.framenr++; - BKE_image_release_ibuf(ima, ibuf, NULL); - ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL); - if (!ibuf) break; - if (!ibuf->rect_float) IMB_float_from_rect(ibuf); - } - rf = ibuf->rect_float; - - for (y = 0; y < ibuf->y; y++) { - for (x = 0; x < ibuf->x; x++) { - /* currently averaged to monchrome */ - vd->dataset[BLI_VOXEL_INDEX(x, y, z, vd->resol)] = (rf[0] + rf[1] + rf[2]) / 3.0f; - rf += 4; - } - } - - BKE_image_free_anim_ibufs(ima, iuser.framenr); - } - - BKE_image_release_ibuf(ima, ibuf, NULL); - - vd->ok = 1; - return; -} - -static int read_voxeldata_header(FILE *fp, struct VoxelData *vd) -{ - VoxelDataHeader *h = (VoxelDataHeader *)MEM_mallocN(sizeof(VoxelDataHeader), "voxel data header"); - - rewind(fp); - if (fread(h, sizeof(VoxelDataHeader), 1, fp) != 1) { - MEM_freeN(h); - return 0; - } - - vd->resol[0] = h->resolX; - vd->resol[1] = h->resolY; - vd->resol[2] = h->resolZ; - - MEM_freeN(h); - return 1; -} - -static void init_frame_smoke(VoxelData *vd, int cfra) -{ -#ifdef WITH_SMOKE - Object *ob; - ModifierData *md; - - vd->dataset = NULL; - if (vd->object == NULL) return; - ob = vd->object; - - /* draw code for smoke */ - if ((md = (ModifierData *)modifiers_findByType(ob, eModifierType_Smoke))) { - SmokeModifierData *smd = (SmokeModifierData *)md; - SmokeDomainSettings *sds = smd->domain; - - if (sds && sds->fluid) { - BLI_rw_mutex_lock(sds->fluid_mutex, THREAD_LOCK_READ); - - if (!sds->fluid) { - BLI_rw_mutex_unlock(sds->fluid_mutex); - return; - } - - if (cfra < sds->point_cache[0]->startframe) - ; /* don't show smoke before simulation starts, this could be made an option in the future */ - else if (vd->smoked_type == TEX_VD_SMOKEHEAT) { - size_t totRes; - size_t i; - float *heat; - - if (!smoke_has_heat(sds->fluid)) { - BLI_rw_mutex_unlock(sds->fluid_mutex); - return; - } - - copy_v3_v3_int(vd->resol, sds->res); - totRes = vd_resol_size(vd); - vd->dataset = MEM_mapallocN(sizeof(float) * (totRes), "smoke data"); - /* get heat data */ - heat = smoke_get_heat(sds->fluid); - - /* scale heat values from -2.0-2.0 to 0.0-1.0 */ - for (i = 0; i < totRes; i++) { - vd->dataset[i] = (heat[i] + 2.0f) / 4.0f; - } - } - else if (vd->smoked_type == TEX_VD_SMOKEVEL) { - size_t totRes; - size_t i; - float *xvel, *yvel, *zvel; - - copy_v3_v3_int(vd->resol, sds->res); - totRes = vd_resol_size(vd); - vd->dataset = MEM_mapallocN(sizeof(float) * (totRes), "smoke data"); - /* get velocity data */ - xvel = smoke_get_velocity_x(sds->fluid); - yvel = smoke_get_velocity_y(sds->fluid); - zvel = smoke_get_velocity_z(sds->fluid); - - /* map velocities between 0 and 0.3f */ - for (i = 0; i < totRes; i++) { - vd->dataset[i] = sqrtf(xvel[i] * xvel[i] + yvel[i] * yvel[i] + zvel[i] * zvel[i]) * 3.0f; - } - - } - else if (vd->smoked_type == TEX_VD_SMOKEFLAME) { - size_t totRes; - float *flame; - - if (sds->flags & MOD_SMOKE_HIGHRES) { - if (!smoke_turbulence_has_fuel(sds->wt)) { - BLI_rw_mutex_unlock(sds->fluid_mutex); - return; - } - smoke_turbulence_get_res(sds->wt, vd->resol); - flame = smoke_turbulence_get_flame(sds->wt); - } - else { - if (!smoke_has_fuel(sds->fluid)) { - BLI_rw_mutex_unlock(sds->fluid_mutex); - return; - } - copy_v3_v3_int(vd->resol, sds->res); - flame = smoke_get_flame(sds->fluid); - } - - /* always store copy, as smoke internal data can change */ - totRes = vd_resol_size(vd); - vd->dataset = MEM_mapallocN(sizeof(float)*(totRes), "smoke data"); - memcpy(vd->dataset, flame, sizeof(float)*totRes); - } - else { - size_t totCells; - int depth = 4; - vd->data_type = TEX_VD_RGBA_PREMUL; - - /* data resolution */ - if (sds->flags & MOD_SMOKE_HIGHRES) { - smoke_turbulence_get_res(sds->wt, vd->resol); - } - else { - copy_v3_v3_int(vd->resol, sds->res); - } - - /* TODO: is_vd_res_ok(rvd) doesnt check this resolution */ - totCells = vd_resol_size(vd) * depth; - /* always store copy, as smoke internal data can change */ - vd->dataset = MEM_mapallocN(sizeof(float) * totCells, "smoke data"); - - if (sds->flags & MOD_SMOKE_HIGHRES) { - if (smoke_turbulence_has_colors(sds->wt)) { - smoke_turbulence_get_rgba(sds->wt, vd->dataset, 1); - } - else { - smoke_turbulence_get_rgba_from_density(sds->wt, sds->active_color, vd->dataset, 1); - } - } - else { - if (smoke_has_colors(sds->fluid)) { - smoke_get_rgba(sds->fluid, vd->dataset, 1); - } - else { - smoke_get_rgba_from_density(sds->fluid, sds->active_color, vd->dataset, 1); - } - } - } /* end of fluid condition */ - - BLI_rw_mutex_unlock(sds->fluid_mutex); - } - } - - vd->ok = 1; - -#else // WITH_SMOKE - (void)vd; - (void)cfra; - - vd->dataset = NULL; -#endif -} - -static void init_frame_hair(VoxelData *vd, int UNUSED(cfra)) -{ - Object *ob; - ModifierData *md; - - vd->dataset = NULL; - if (vd->object == NULL) return; - ob = vd->object; - - if ((md = (ModifierData *)modifiers_findByType(ob, eModifierType_ParticleSystem))) { - ParticleSystemModifierData *pmd = (ParticleSystemModifierData *)md; - - if (pmd->psys && pmd->psys->clmd) { - vd->ok |= BPH_cloth_solver_get_texture_data(ob, pmd->psys->clmd, vd); - } - } -} - -void cache_voxeldata(Tex *tex, int scene_frame) -{ - VoxelData *vd = tex->vd; - FILE *fp; - int curframe; - char path[sizeof(vd->source_path)]; - - /* only re-cache if dataset needs updating */ - if ((vd->flag & TEX_VD_STILL) || (vd->cachedframe == scene_frame)) - if (vd->ok) return; - - /* clear out old cache, ready for new */ - if (vd->dataset) { - MEM_freeN(vd->dataset); - vd->dataset = NULL; - } - /* reset data_type */ - vd->data_type = TEX_VD_INTENSITY; - - if (vd->flag & TEX_VD_STILL) - curframe = vd->still_frame; - else - curframe = scene_frame; - - BLI_strncpy(path, vd->source_path, sizeof(path)); - - /* each type is responsible for setting to true */ - vd->ok = false; - - switch (vd->file_format) { - case TEX_VD_IMAGE_SEQUENCE: - load_frame_image_sequence(vd, tex); - return; - case TEX_VD_SMOKE: - init_frame_smoke(vd, scene_frame); - return; - case TEX_VD_HAIR: - init_frame_hair(vd, scene_frame); - return; - case TEX_VD_BLENDERVOXEL: - BLI_path_abs(path, G.main->name); - fp = BLI_fopen(path, "rb"); - if (!fp) return; - - if (read_voxeldata_header(fp, vd)) - load_frame_blendervoxel(vd, fp, curframe - 1); - - fclose(fp); - return; - case TEX_VD_RAW_8BIT: - BLI_path_abs(path, G.main->name); - fp = BLI_fopen(path, "rb"); - if (!fp) return; - - load_frame_raw8(vd, fp, curframe); - fclose(fp); - return; - } -} - -void make_voxeldata(struct Render *re) -{ - Tex *tex; - - re->i.infostr = IFACE_("Loading voxel datasets"); - re->stats_draw(re->sdh, &re->i); - - /* XXX: should be doing only textures used in this render */ - for (tex = re->main->tex.first; tex; tex = tex->id.next) { - if (tex->id.us && tex->type == TEX_VOXELDATA) { - cache_voxeldata(tex, re->r.cfra); - } - } - - re->i.infostr = NULL; - re->stats_draw(re->sdh, &re->i); - -} - -int voxeldatatex(struct Tex *tex, const float texvec[3], struct TexResult *texres) -{ - VoxelData *vd = tex->vd; - float co[3], offset[3] = {0.5, 0.5, 0.5}, a; - int retval = (vd->data_type == TEX_VD_RGBA_PREMUL) ? TEX_RGB : TEX_INT; - int depth = (vd->data_type == TEX_VD_RGBA_PREMUL) ? 4 : 1; - int ch; - - if (vd->dataset == NULL) { - texres->tin = 0.0f; - return 0; - } - - /* scale lookup from 0.0-1.0 (original location) to -1.0, 1.0, consistent with image texture tex coords */ - /* in implementation this works backwards, bringing sample locations from -1.0, 1.0 - * to the range 0.0, 1.0, before looking up in the voxel structure. */ - copy_v3_v3(co, texvec); - mul_v3_fl(co, 0.5f); - add_v3_v3(co, offset); - - /* co is now in the range 0.0, 1.0 */ - switch (vd->extend) { - case TEX_CLIP: - { - if ((co[0] < 0.f || co[0] > 1.f) || (co[1] < 0.f || co[1] > 1.f) || (co[2] < 0.f || co[2] > 1.f)) { - texres->tin = 0.f; - return retval; - } - break; - } - case TEX_REPEAT: - { - co[0] = co[0] - floorf(co[0]); - co[1] = co[1] - floorf(co[1]); - co[2] = co[2] - floorf(co[2]); - break; - } - case TEX_EXTEND: - { - CLAMP(co[0], 0.f, 1.f); - CLAMP(co[1], 0.f, 1.f); - CLAMP(co[2], 0.f, 1.f); - break; - } - } - - for (ch = 0; ch < depth; ch++) { - float *dataset = vd->dataset + ch*vd->resol[0]*vd->resol[1]*vd->resol[2]; - float *result = &texres->tin; - - if (vd->data_type == TEX_VD_RGBA_PREMUL) { - switch (ch) { - case 0: - result = &texres->tr; - break; - case 1: - result = &texres->tg; - break; - case 2: - result = &texres->tb; - break; - } - } - - switch (vd->interp_type) { - case TEX_VD_NEARESTNEIGHBOR: - *result = BLI_voxel_sample_nearest(dataset, vd->resol, co); - break; - case TEX_VD_LINEAR: - *result = BLI_voxel_sample_trilinear(dataset, vd->resol, co); - break; - case TEX_VD_QUADRATIC: - *result = BLI_voxel_sample_triquadratic(dataset, vd->resol, co); - break; - case TEX_VD_TRICUBIC_CATROM: - case TEX_VD_TRICUBIC_BSPLINE: - *result = BLI_voxel_sample_tricubic(dataset, vd->resol, co, (vd->interp_type == TEX_VD_TRICUBIC_BSPLINE)); - break; - } - } - - a = texres->tin; - texres->tin *= vd->int_multiplier; - BRICONT; - - if (vd->data_type == TEX_VD_RGBA_PREMUL) { - /* unmultiply */ - if (a>0.001f) { - texres->tr /= a; - texres->tg /= a; - texres->tb /= a; - } - texres->talpha = 1; - } - else { - texres->tr = texres->tin; - texres->tg = texres->tin; - texres->tb = texres->tin; - } - - texres->ta = texres->tin; - BRICONTRGB; - - return retval; -} diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c index e948662df00..3837383c4c7 100644 --- a/source/blender/render/intern/source/zbuf.c +++ b/source/blender/render/intern/source/zbuf.c @@ -34,40 +34,11 @@ /* Common includes */ /*---------------------------------------------------------------------------*/ -#include <math.h> -#include <float.h> -#include <stdlib.h> -#include <limits.h> #include <string.h> -#include "BLI_math.h" -#include "BLI_blenlib.h" -#include "BLI_jitter_2d.h" -#include "BLI_threads.h" -#include "BLI_utildefines.h" - #include "MEM_guardedalloc.h" -#include "DNA_lamp_types.h" -#include "DNA_node_types.h" -#include "DNA_meshdata_types.h" -#include "DNA_material_types.h" - -#include "BKE_global.h" -#include "BKE_material.h" - - -#include "RE_render_ext.h" - -/* local includes */ -#include "pixelblending.h" -#include "render_result.h" -#include "render_types.h" -#include "renderdatabase.h" -#include "rendercore.h" -#include "shadbuf.h" -#include "shading.h" -#include "strand.h" +#include "BLI_math_base.h" /* own includes */ #include "zbuf.h" @@ -77,17 +48,10 @@ # pragma GCC diagnostic ignored "-Wdouble-promotion" #endif -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -/* defined in pipeline.c, is hardcopy of active dynamic allocated Render */ -/* only to be used here in this file, it's for speed */ -extern struct Render R; -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - - /* ****************** Spans ******************************* */ /* each zbuffer has coordinates transformed to local rect coordinates, so we can simply clip */ -void zbuf_alloc_span(ZSpan *zspan, int rectx, int recty, float clipcrop) +void zbuf_alloc_span(ZSpan *zspan, int rectx, int recty) { memset(zspan, 0, sizeof(ZSpan)); @@ -96,8 +60,6 @@ void zbuf_alloc_span(ZSpan *zspan, int rectx, int recty, float clipcrop) zspan->span1= MEM_mallocN(recty*sizeof(float), "zspan"); zspan->span2= MEM_mallocN(recty*sizeof(float), "zspan"); - - zspan->clipcrop= clipcrop; } void zbuf_free_span(ZSpan *zspan) @@ -200,1312 +162,6 @@ static void zbuf_add_to_span(ZSpan *zspan, const float v1[2], const float v2[2]) /* Functions */ /*-----------------------------------------------------------*/ -void fillrect(int *rect, int x, int y, int val) -{ - int len, *drect; - - len= x*y; - drect= rect; - while (len>0) { - len--; - *drect= val; - drect++; - } -} - -/* based on Liang&Barsky, for clipping of pyramidical volume */ -static short cliptestf(float a, float b, float c, float d, float *u1, float *u2) -{ - float p= a + b, q= c + d, r; - - if (p<0.0f) { - if (q<p) return 0; - else if (q<0.0f) { - r= q/p; - if (r>*u2) return 0; - else if (r>*u1) *u1=r; - } - } - else { - if (p>0.0f) { - if (q<0.0f) return 0; - else if (q<p) { - r= q/p; - if (r<*u1) return 0; - else if (r<*u2) *u2=r; - } - } - else if (q<0.0f) return 0; - } - return 1; -} - -int testclip(const float v[4]) -{ - float abs4; /* WATCH IT: this function should do the same as cliptestf, otherwise troubles in zbufclip()*/ - short c=0; - - /* if we set clip flags, the clipping should be at least larger than epsilon. - * prevents issues with vertices lying exact on borders */ - abs4= fabsf(v[3]) + FLT_EPSILON; - - if ( v[0] < -abs4) c+=1; - else if ( v[0] > abs4) c+=2; - - if ( v[1] > abs4) c+=4; - else if ( v[1] < -abs4) c+=8; - - if (v[2] < -abs4) c+=16; /* this used to be " if (v[2]<0) ", see clippz() */ - else if (v[2]> abs4) c+= 32; - - return c; -} - - - -/* ************* ACCUMULATION ZBUF ************ */ - - -static APixstr *addpsmainA(ListBase *lb) -{ - APixstrMain *psm; - - psm= MEM_mallocN(sizeof(APixstrMain), "addpsmainA"); - BLI_addtail(lb, psm); - psm->ps= MEM_callocN(4096*sizeof(APixstr), "pixstr"); - - return psm->ps; -} - -void freepsA(ListBase *lb) -{ - APixstrMain *psm, *psmnext; - - for (psm= lb->first; psm; psm= psmnext) { - psmnext= psm->next; - if (psm->ps) - MEM_freeN(psm->ps); - MEM_freeN(psm); - } -} - -static APixstr *addpsA(ZSpan *zspan) -{ - /* make new PS */ - if (zspan->apsmcounter==0) { - zspan->curpstr= addpsmainA(zspan->apsmbase); - zspan->apsmcounter= 4095; - } - else { - zspan->curpstr++; - zspan->apsmcounter--; - } - return zspan->curpstr; -} - -static void zbuffillAc4(ZSpan *zspan, int obi, int zvlnr, - const float *v1, const float *v2, const float *v3, const float *v4) -{ - APixstr *ap, *apofs, *apn; - double zxd, zyd, zy0, zverg; - float x0, y0, z0; - float x1, y1, z1, x2, y2, z2, xx1; - const float *span1, *span2; - int *rz, *rm, x, y; - int sn1, sn2, rectx, *rectzofs, *rectmaskofs, my0, my2, mask; - - /* init */ - zbuf_init_span(zspan); - - /* set spans */ - zbuf_add_to_span(zspan, v1, v2); - zbuf_add_to_span(zspan, v2, v3); - if (v4) { - zbuf_add_to_span(zspan, v3, v4); - zbuf_add_to_span(zspan, v4, v1); - } - else - zbuf_add_to_span(zspan, v3, v1); - - /* clipped */ - if (zspan->minp2==NULL || zspan->maxp2==NULL) return; - - my0 = max_ii(zspan->miny1, zspan->miny2); - my2 = min_ii(zspan->maxy1, zspan->maxy2); - - if (my2<my0) return; - - /* ZBUF DX DY, in floats still */ - x1= v1[0]- v2[0]; - x2= v2[0]- v3[0]; - y1= v1[1]- v2[1]; - y2= v2[1]- v3[1]; - z1= v1[2]- v2[2]; - z2= v2[2]- v3[2]; - x0= y1*z2-z1*y2; - y0= z1*x2-x1*z2; - z0= x1*y2-y1*x2; - - if (z0==0.0f) return; - - xx1= (x0*v1[0] + y0*v1[1])/z0 + v1[2]; - - zxd= -(double)x0/(double)z0; - zyd= -(double)y0/(double)z0; - zy0= ((double)my2)*zyd + (double)xx1; - - /* start-offset in rect */ - rectx= zspan->rectx; - rectzofs= (int *)(zspan->arectz+rectx*(my2)); - rectmaskofs= (int *)(zspan->rectmask+rectx*(my2)); - apofs= (zspan->apixbuf+ rectx*(my2)); - mask= zspan->mask; - - /* correct span */ - sn1= (my0 + my2)/2; - if (zspan->span1[sn1] < zspan->span2[sn1]) { - span1= zspan->span1+my2; - span2= zspan->span2+my2; - } - else { - span1= zspan->span2+my2; - span2= zspan->span1+my2; - } - - for (y=my2; y>=my0; y--, span1--, span2--) { - - sn1= floor(*span1); - sn2= floor(*span2); - sn1++; - - if (sn2>=rectx) sn2= rectx-1; - if (sn1<0) sn1= 0; - - if (sn2>=sn1) { - int intzverg; - - zverg= (double)sn1*zxd + zy0; - rz= rectzofs+sn1; - rm= rectmaskofs+sn1; - ap= apofs+sn1; - x= sn2-sn1; - - zverg-= zspan->polygon_offset; - - while (x>=0) { - intzverg = round_db_to_int_clamp(zverg); - - if ( intzverg < *rz) { - if (!zspan->rectmask || intzverg > *rm) { - - apn= ap; - while (apn) { - if (apn->p[0]==0) {apn->obi[0]= obi; apn->p[0]= zvlnr; apn->z[0]= intzverg; apn->mask[0]= mask; break; } - if (apn->p[0]==zvlnr && apn->obi[0]==obi) {apn->mask[0]|= mask; break; } - if (apn->p[1]==0) {apn->obi[1]= obi; apn->p[1]= zvlnr; apn->z[1]= intzverg; apn->mask[1]= mask; break; } - if (apn->p[1]==zvlnr && apn->obi[1]==obi) {apn->mask[1]|= mask; break; } - if (apn->p[2]==0) {apn->obi[2]= obi; apn->p[2]= zvlnr; apn->z[2]= intzverg; apn->mask[2]= mask; break; } - if (apn->p[2]==zvlnr && apn->obi[2]==obi) {apn->mask[2]|= mask; break; } - if (apn->p[3]==0) {apn->obi[3]= obi; apn->p[3]= zvlnr; apn->z[3]= intzverg; apn->mask[3]= mask; break; } - if (apn->p[3]==zvlnr && apn->obi[3]==obi) {apn->mask[3]|= mask; break; } - if (apn->next==NULL) apn->next= addpsA(zspan); - apn= apn->next; - } - } - } - zverg+= zxd; - rz++; - rm++; - ap++; - x--; - } - } - - zy0-=zyd; - rectzofs-= rectx; - rectmaskofs-= rectx; - apofs-= rectx; - } -} - - - -static void zbuflineAc(ZSpan *zspan, int obi, int zvlnr, const float vec1[3], const float vec2[3]) -{ - APixstr *ap, *apn; - const int *rectz, *rectmask; - int start, end, x, y, oldx, oldy, ofs; - int dz, vergz, mask, maxtest=0; - float dx, dy; - float v1[3], v2[3]; - - dx= vec2[0]-vec1[0]; - dy= vec2[1]-vec1[1]; - - mask= zspan->mask; - - if (fabsf(dx) > fabsf(dy)) { - - /* all lines from left to right */ - if (vec1[0]<vec2[0]) { - copy_v3_v3(v1, vec1); - copy_v3_v3(v2, vec2); - } - else { - copy_v3_v3(v2, vec1); - copy_v3_v3(v1, vec2); - dx= -dx; dy= -dy; - } - - start= floor(v1[0]); - end= start+floor(dx); - if (end>=zspan->rectx) end= zspan->rectx-1; - - oldy= floor(v1[1]); - dy/= dx; - - vergz= v1[2]; - vergz-= zspan->polygon_offset; - dz= (v2[2]-v1[2])/dx; - if (vergz>0x50000000 && dz>0) maxtest= 1; /* prevent overflow */ - - rectz= (int *)(zspan->arectz+zspan->rectx*(oldy) +start); - rectmask= (int *)(zspan->rectmask+zspan->rectx*(oldy) +start); - ap= (zspan->apixbuf+ zspan->rectx*(oldy) +start); - - if (dy<0) ofs= -zspan->rectx; - else ofs= zspan->rectx; - - for (x= start; x<=end; x++, rectz++, rectmask++, ap++) { - - y= floor(v1[1]); - if (y!=oldy) { - oldy= y; - rectz+= ofs; - rectmask+= ofs; - ap+= ofs; - } - - if (x>=0 && y>=0 && y<zspan->recty) { - if (vergz<*rectz) { - if (!zspan->rectmask || vergz>*rectmask) { - - apn= ap; - while (apn) { /* loop unrolled */ - if (apn->p[0]==0) {apn->obi[0]= obi; apn->p[0]= zvlnr; apn->z[0]= vergz; apn->mask[0]= mask; break; } - if (apn->p[0]==zvlnr && apn->obi[0]==obi) {apn->mask[0]|= mask; break; } - if (apn->p[1]==0) {apn->obi[1]= obi; apn->p[1]= zvlnr; apn->z[1]= vergz; apn->mask[1]= mask; break; } - if (apn->p[1]==zvlnr && apn->obi[1]==obi) {apn->mask[1]|= mask; break; } - if (apn->p[2]==0) {apn->obi[2]= obi; apn->p[2]= zvlnr; apn->z[2]= vergz; apn->mask[2]= mask; break; } - if (apn->p[2]==zvlnr && apn->obi[2]==obi) {apn->mask[2]|= mask; break; } - if (apn->p[3]==0) {apn->obi[3]= obi; apn->p[3]= zvlnr; apn->z[3]= vergz; apn->mask[3]= mask; break; } - if (apn->p[3]==zvlnr && apn->obi[3]==obi) {apn->mask[3]|= mask; break; } - if (apn->next == NULL) apn->next = addpsA(zspan); - apn= apn->next; - } - } - } - } - - v1[1]+= dy; - if (maxtest && (vergz > 0x7FFFFFF0 - dz)) vergz= 0x7FFFFFF0; - else vergz+= dz; - } - } - else { - - /* all lines from top to bottom */ - if (vec1[1]<vec2[1]) { - copy_v3_v3(v1, vec1); - copy_v3_v3(v2, vec2); - } - else { - copy_v3_v3(v2, vec1); - copy_v3_v3(v1, vec2); - dx= -dx; dy= -dy; - } - - start= floor(v1[1]); - end= start+floor(dy); - - if (start>=zspan->recty || end<0) return; - - if (end>=zspan->recty) end= zspan->recty-1; - - oldx= floor(v1[0]); - dx/= dy; - - vergz= v1[2]; - vergz-= zspan->polygon_offset; - dz= (v2[2]-v1[2])/dy; - if (vergz>0x50000000 && dz>0) maxtest= 1; /* prevent overflow */ - - rectz= (int *)( zspan->arectz+ (start)*zspan->rectx+ oldx ); - rectmask= (int *)( zspan->rectmask+ (start)*zspan->rectx+ oldx ); - ap= (zspan->apixbuf+ zspan->rectx*(start) +oldx); - - if (dx<0) ofs= -1; - else ofs= 1; - - for (y= start; y<=end; y++, rectz+=zspan->rectx, rectmask+=zspan->rectx, ap+=zspan->rectx) { - - x= floor(v1[0]); - if (x!=oldx) { - oldx= x; - rectz+= ofs; - rectmask+= ofs; - ap+= ofs; - } - - if (x>=0 && y>=0 && x<zspan->rectx) { - if (vergz<*rectz) { - if (!zspan->rectmask || vergz>*rectmask) { - - apn= ap; - while (apn) { /* loop unrolled */ - if (apn->p[0]==0) {apn->obi[0]= obi; apn->p[0]= zvlnr; apn->z[0]= vergz; apn->mask[0]= mask; break; } - if (apn->p[0]==zvlnr) {apn->mask[0]|= mask; break; } - if (apn->p[1]==0) {apn->obi[1]= obi; apn->p[1]= zvlnr; apn->z[1]= vergz; apn->mask[1]= mask; break; } - if (apn->p[1]==zvlnr) {apn->mask[1]|= mask; break; } - if (apn->p[2]==0) {apn->obi[2]= obi; apn->p[2]= zvlnr; apn->z[2]= vergz; apn->mask[2]= mask; break; } - if (apn->p[2]==zvlnr) {apn->mask[2]|= mask; break; } - if (apn->p[3]==0) {apn->obi[3]= obi; apn->p[3]= zvlnr; apn->z[3]= vergz; apn->mask[3]= mask; break; } - if (apn->p[3]==zvlnr) {apn->mask[3]|= mask; break; } - if (apn->next == NULL) apn->next = addpsA(zspan); - apn= apn->next; - } - } - } - } - - v1[0]+= dx; - if (maxtest && (vergz > 0x7FFFFFF0 - dz)) vergz= 0x7FFFFFF0; - else vergz+= dz; - } - } -} - -/* ************* NORMAL ZBUFFER ************ */ - -static void zbufline(ZSpan *zspan, int obi, int zvlnr, const float vec1[3], const float vec2[3]) -{ - int *rectz, *rectp, *recto, *rectmask; - int start, end, x, y, oldx, oldy, ofs; - int dz, vergz, maxtest= 0; - float dx, dy; - float v1[3], v2[3]; - - dx= vec2[0]-vec1[0]; - dy= vec2[1]-vec1[1]; - - if (fabsf(dx) > fabsf(dy)) { - - /* all lines from left to right */ - if (vec1[0]<vec2[0]) { - copy_v3_v3(v1, vec1); - copy_v3_v3(v2, vec2); - } - else { - copy_v3_v3(v2, vec1); - copy_v3_v3(v1, vec2); - dx= -dx; dy= -dy; - } - - start= floor(v1[0]); - end= start+floor(dx); - if (end>=zspan->rectx) end= zspan->rectx-1; - - oldy= floor(v1[1]); - dy/= dx; - - vergz= floor(v1[2]); - dz= floor((v2[2]-v1[2])/dx); - if (vergz>0x50000000 && dz>0) maxtest= 1; /* prevent overflow */ - - rectz= zspan->rectz + oldy*zspan->rectx+ start; - rectp= zspan->rectp + oldy*zspan->rectx+ start; - recto= zspan->recto + oldy*zspan->rectx+ start; - rectmask= zspan->rectmask + oldy*zspan->rectx+ start; - - if (dy<0) ofs= -zspan->rectx; - else ofs= zspan->rectx; - - for (x= start; x<=end; x++, rectz++, rectp++, recto++, rectmask++) { - - y= floor(v1[1]); - if (y!=oldy) { - oldy= y; - rectz+= ofs; - rectp+= ofs; - recto+= ofs; - rectmask+= ofs; - } - - if (x>=0 && y>=0 && y<zspan->recty) { - if (vergz<*rectz) { - if (!zspan->rectmask || vergz>*rectmask) { - *recto= obi; - *rectz= vergz; - *rectp= zvlnr; - } - } - } - - v1[1]+= dy; - - if (maxtest && (vergz > 0x7FFFFFF0 - dz)) vergz= 0x7FFFFFF0; - else vergz+= dz; - } - } - else { - /* all lines from top to bottom */ - if (vec1[1]<vec2[1]) { - copy_v3_v3(v1, vec1); - copy_v3_v3(v2, vec2); - } - else { - copy_v3_v3(v2, vec1); - copy_v3_v3(v1, vec2); - dx= -dx; dy= -dy; - } - - start= floor(v1[1]); - end= start+floor(dy); - - if (end>=zspan->recty) end= zspan->recty-1; - - oldx= floor(v1[0]); - dx/= dy; - - vergz= floor(v1[2]); - dz= floor((v2[2]-v1[2])/dy); - if (vergz>0x50000000 && dz>0) maxtest= 1; /* prevent overflow */ - - rectz= zspan->rectz + start*zspan->rectx+ oldx; - rectp= zspan->rectp + start*zspan->rectx+ oldx; - recto= zspan->recto + start*zspan->rectx+ oldx; - rectmask= zspan->rectmask + start*zspan->rectx+ oldx; - - if (dx<0) ofs= -1; - else ofs= 1; - - for (y= start; y<=end; y++, rectz+=zspan->rectx, rectp+=zspan->rectx, recto+=zspan->rectx, rectmask+=zspan->rectx) { - - x= floor(v1[0]); - if (x!=oldx) { - oldx= x; - rectz+= ofs; - rectp+= ofs; - recto+= ofs; - rectmask+= ofs; - } - - if (x>=0 && y>=0 && x<zspan->rectx) { - if (vergz<*rectz) { - if (!zspan->rectmask || vergz>*rectmask) { - *rectz= vergz; - *rectp= zvlnr; - *recto= obi; - } - } - } - - v1[0]+= dx; - if (maxtest && (vergz > 0x7FFFFFF0 - dz)) vergz= 0x7FFFFFF0; - else vergz+= dz; - } - } -} - -static void zbufline_onlyZ(ZSpan *zspan, int UNUSED(obi), int UNUSED(zvlnr), const float vec1[3], const float vec2[3]) -{ - int *rectz, *rectz1= NULL; - int start, end, x, y, oldx, oldy, ofs; - int dz, vergz, maxtest= 0; - float dx, dy; - float v1[3], v2[3]; - - dx= vec2[0]-vec1[0]; - dy= vec2[1]-vec1[1]; - - if (fabsf(dx) > fabsf(dy)) { - - /* all lines from left to right */ - if (vec1[0]<vec2[0]) { - copy_v3_v3(v1, vec1); - copy_v3_v3(v2, vec2); - } - else { - copy_v3_v3(v2, vec1); - copy_v3_v3(v1, vec2); - dx= -dx; dy= -dy; - } - - start= floor(v1[0]); - end= start+floor(dx); - if (end>=zspan->rectx) end= zspan->rectx-1; - - oldy= floor(v1[1]); - dy/= dx; - - vergz= floor(v1[2]); - dz= floor((v2[2]-v1[2])/dx); - if (vergz>0x50000000 && dz>0) maxtest= 1; /* prevent overflow */ - - rectz= zspan->rectz + oldy*zspan->rectx+ start; - if (zspan->rectz1) - rectz1= zspan->rectz1 + oldy*zspan->rectx+ start; - - if (dy<0) ofs= -zspan->rectx; - else ofs= zspan->rectx; - - for (x= start; x<=end; x++, rectz++) { - - y= floor(v1[1]); - if (y!=oldy) { - oldy= y; - rectz+= ofs; - if (rectz1) rectz1+= ofs; - } - - if (x>=0 && y>=0 && y<zspan->recty) { - if (vergz < *rectz) { - if (rectz1) *rectz1= *rectz; - *rectz= vergz; - } - else if (rectz1 && vergz < *rectz1) - *rectz1= vergz; - } - - v1[1]+= dy; - - if (maxtest && (vergz > 0x7FFFFFF0 - dz)) vergz= 0x7FFFFFF0; - else vergz+= dz; - - if (rectz1) rectz1++; - } - } - else { - /* all lines from top to bottom */ - if (vec1[1]<vec2[1]) { - copy_v3_v3(v1, vec1); - copy_v3_v3(v2, vec2); - } - else { - copy_v3_v3(v2, vec1); - copy_v3_v3(v1, vec2); - dx= -dx; dy= -dy; - } - - start= floor(v1[1]); - end= start+floor(dy); - - if (end>=zspan->recty) end= zspan->recty-1; - - oldx= floor(v1[0]); - dx/= dy; - - vergz= floor(v1[2]); - dz= floor((v2[2]-v1[2])/dy); - if (vergz>0x50000000 && dz>0) maxtest= 1; /* prevent overflow */ - - rectz= zspan->rectz + start*zspan->rectx+ oldx; - if (zspan->rectz1) - rectz1= zspan->rectz1 + start*zspan->rectx+ oldx; - - if (dx<0) ofs= -1; - else ofs= 1; - - for (y= start; y<=end; y++, rectz+=zspan->rectx) { - - x= floor(v1[0]); - if (x!=oldx) { - oldx= x; - rectz+= ofs; - if (rectz1) rectz1+= ofs; - } - - if (x>=0 && y>=0 && x<zspan->rectx) { - if (vergz < *rectz) { - if (rectz1) *rectz1= *rectz; - *rectz= vergz; - } - else if (rectz1 && vergz < *rectz1) - *rectz1= vergz; - } - - v1[0]+= dx; - if (maxtest && (vergz > 0x7FFFFFF0 - dz)) vergz= 0x7FFFFFF0; - else vergz+= dz; - - if (rectz1) - rectz1+=zspan->rectx; - } - } -} - - -static int clipline(float v1[4], float v2[4]) /* return 0: do not draw */ -{ - float dz, dw, u1=0.0, u2=1.0; - float dx, dy, v13; - - dz= v2[2]-v1[2]; - dw= v2[3]-v1[3]; - - /* this 1.01 is for clipping x and y just a tinsy larger. that way it is - * filled in with zbufwire correctly when rendering in parts. otherwise - * you see line endings at edges... */ - - if (cliptestf(-dz, -dw, v1[3], v1[2], &u1, &u2)) { - if (cliptestf(dz, -dw, v1[3], -v1[2], &u1, &u2)) { - - dx= v2[0]-v1[0]; - dz= 1.01f*(v2[3]-v1[3]); - v13= 1.01f*v1[3]; - - if (cliptestf(-dx, -dz, v1[0], v13, &u1, &u2)) { - if (cliptestf(dx, -dz, v13, -v1[0], &u1, &u2)) { - - dy= v2[1]-v1[1]; - - if (cliptestf(-dy, -dz, v1[1], v13, &u1, &u2)) { - if (cliptestf(dy, -dz, v13, -v1[1], &u1, &u2)) { - - if (u2<1.0f) { - v2[0]= v1[0]+u2*dx; - v2[1]= v1[1]+u2*dy; - v2[2]= v1[2]+u2*dz; - v2[3]= v1[3]+u2*dw; - } - if (u1>0.0f) { - v1[0]= v1[0]+u1*dx; - v1[1]= v1[1]+u1*dy; - v1[2]= v1[2]+u1*dz; - v1[3]= v1[3]+u1*dw; - } - return 1; - } - } - } - } - } - } - - return 0; -} - -void hoco_to_zco(ZSpan *zspan, float zco[3], const float hoco[4]) -{ - float div; - - div= 1.0f/hoco[3]; - zco[0]= zspan->zmulx*(1.0f+hoco[0]*div) + zspan->zofsx; - zco[1]= zspan->zmuly*(1.0f+hoco[1]*div) + zspan->zofsy; - zco[2]= 0x7FFFFFFF *(hoco[2]*div); -} - -void zbufclipwire(ZSpan *zspan, int obi, int zvlnr, int ec, - const float ho1[4], const float ho2[4], const float ho3[4], const float ho4[4], - const int c1, const int c2, const int c3, const int c4) -{ - float vez[20]; - int and, or; - - /* edgecode: 1= draw */ - if (ec==0) return; - - if (ho4) { - and= (c1 & c2 & c3 & c4); - or= (c1 | c2 | c3 | c4); - } - else { - and= (c1 & c2 & c3); - or= (c1 | c2 | c3); - } - - if (or) { /* not in the middle */ - if (and) { /* out completely */ - return; - } - else { /* clipping */ - - if (ec & ME_V1V2) { - copy_v4_v4(vez, ho1); - copy_v4_v4(vez+4, ho2); - if ( clipline(vez, vez+4)) { - hoco_to_zco(zspan, vez, vez); - hoco_to_zco(zspan, vez+4, vez+4); - zspan->zbuflinefunc(zspan, obi, zvlnr, vez, vez+4); - } - } - if (ec & ME_V2V3) { - copy_v4_v4(vez, ho2); - copy_v4_v4(vez+4, ho3); - if ( clipline(vez, vez+4)) { - hoco_to_zco(zspan, vez, vez); - hoco_to_zco(zspan, vez+4, vez+4); - zspan->zbuflinefunc(zspan, obi, zvlnr, vez, vez+4); - } - } - if (ho4) { - if (ec & ME_V3V4) { - copy_v4_v4(vez, ho3); - copy_v4_v4(vez+4, ho4); - if ( clipline(vez, vez+4)) { - hoco_to_zco(zspan, vez, vez); - hoco_to_zco(zspan, vez+4, vez+4); - zspan->zbuflinefunc(zspan, obi, zvlnr, vez, vez+4); - } - } - if (ec & ME_V4V1) { - copy_v4_v4(vez, ho4); - copy_v4_v4(vez+4, ho1); - if ( clipline(vez, vez+4)) { - hoco_to_zco(zspan, vez, vez); - hoco_to_zco(zspan, vez+4, vez+4); - zspan->zbuflinefunc(zspan, obi, zvlnr, vez, vez+4); - } - } - } - else { - if (ec & ME_V3V1) { - copy_v4_v4(vez, ho3); - copy_v4_v4(vez+4, ho1); - if ( clipline(vez, vez+4)) { - hoco_to_zco(zspan, vez, vez); - hoco_to_zco(zspan, vez+4, vez+4); - zspan->zbuflinefunc(zspan, obi, zvlnr, vez, vez+4); - } - } - } - - return; - } - } - - hoco_to_zco(zspan, vez, ho1); - hoco_to_zco(zspan, vez+4, ho2); - hoco_to_zco(zspan, vez+8, ho3); - if (ho4) { - hoco_to_zco(zspan, vez+12, ho4); - - if (ec & ME_V3V4) zspan->zbuflinefunc(zspan, obi, zvlnr, vez+8, vez+12); - if (ec & ME_V4V1) zspan->zbuflinefunc(zspan, obi, zvlnr, vez+12, vez); - } - else { - if (ec & ME_V3V1) zspan->zbuflinefunc(zspan, obi, zvlnr, vez+8, vez); - } - - if (ec & ME_V1V2) zspan->zbuflinefunc(zspan, obi, zvlnr, vez, vez+4); - if (ec & ME_V2V3) zspan->zbuflinefunc(zspan, obi, zvlnr, vez+4, vez+8); - -} - -void zbufsinglewire(ZSpan *zspan, int obi, int zvlnr, const float ho1[4], const float ho2[4]) -{ - float f1[4], f2[4]; - int c1, c2; - - c1= testclip(ho1); - c2= testclip(ho2); - - if (c1 | c2) { /* not in the middle */ - if (!(c1 & c2)) { /* not out completely */ - copy_v4_v4(f1, ho1); - copy_v4_v4(f2, ho2); - - if (clipline(f1, f2)) { - hoco_to_zco(zspan, f1, f1); - hoco_to_zco(zspan, f2, f2); - zspan->zbuflinefunc(zspan, obi, zvlnr, f1, f2); - } - } - } - else { - hoco_to_zco(zspan, f1, ho1); - hoco_to_zco(zspan, f2, ho2); - - zspan->zbuflinefunc(zspan, obi, zvlnr, f1, f2); - } -} - -/** - * Fill the z buffer, but invert z order, and add the face index to - * the corresponding face buffer. - * - * This is one of the z buffer fill functions called in zbufclip() and - * zbufwireclip(). - * - * \param v1 [4 floats, world coordinates] first vertex - * \param v2 [4 floats, world coordinates] second vertex - * \param v3 [4 floats, world coordinates] third vertex - */ - -/* WATCH IT: zbuffillGLinv4 and zbuffillGL4 are identical except for a 2 lines, - * commented below */ -static void zbuffillGLinv4(ZSpan *zspan, int obi, int zvlnr, - const float *v1, const float *v2, const float *v3, const float *v4) -{ - double zxd, zyd, zy0, zverg; - float x0, y0, z0; - float x1, y1, z1, x2, y2, z2, xx1; - const float *span1, *span2; - int *rectoofs, *ro; - int *rectpofs, *rp; - const int *rectmaskofs, *rm; - int *rz, x, y; - int sn1, sn2, rectx, *rectzofs, my0, my2; - - /* init */ - zbuf_init_span(zspan); - - /* set spans */ - zbuf_add_to_span(zspan, v1, v2); - zbuf_add_to_span(zspan, v2, v3); - if (v4) { - zbuf_add_to_span(zspan, v3, v4); - zbuf_add_to_span(zspan, v4, v1); - } - else - zbuf_add_to_span(zspan, v3, v1); - - /* clipped */ - if (zspan->minp2==NULL || zspan->maxp2==NULL) return; - - my0 = max_ii(zspan->miny1, zspan->miny2); - my2 = min_ii(zspan->maxy1, zspan->maxy2); - - // printf("my %d %d\n", my0, my2); - if (my2<my0) return; - - - /* ZBUF DX DY, in floats still */ - x1= v1[0]- v2[0]; - x2= v2[0]- v3[0]; - y1= v1[1]- v2[1]; - y2= v2[1]- v3[1]; - z1= v1[2]- v2[2]; - z2= v2[2]- v3[2]; - x0= y1*z2-z1*y2; - y0= z1*x2-x1*z2; - z0= x1*y2-y1*x2; - - if (z0==0.0f) return; - - xx1= (x0*v1[0] + y0*v1[1])/z0 + v1[2]; - - zxd= -(double)x0/(double)z0; - zyd= -(double)y0/(double)z0; - zy0= ((double)my2)*zyd + (double)xx1; - - /* start-offset in rect */ - rectx= zspan->rectx; - rectzofs= (zspan->rectz+rectx*my2); - rectpofs= (zspan->rectp+rectx*my2); - rectoofs= (zspan->recto+rectx*my2); - rectmaskofs= (zspan->rectmask+rectx*my2); - - /* correct span */ - sn1= (my0 + my2)/2; - if (zspan->span1[sn1] < zspan->span2[sn1]) { - span1= zspan->span1+my2; - span2= zspan->span2+my2; - } - else { - span1= zspan->span2+my2; - span2= zspan->span1+my2; - } - - for (y=my2; y>=my0; y--, span1--, span2--) { - - sn1= floor(*span1); - sn2= floor(*span2); - sn1++; - - if (sn2>=rectx) sn2= rectx-1; - if (sn1<0) sn1= 0; - - if (sn2>=sn1) { - int intzverg; - - zverg= (double)sn1*zxd + zy0; - rz= rectzofs+sn1; - rp= rectpofs+sn1; - ro= rectoofs+sn1; - rm= rectmaskofs+sn1; - x= sn2-sn1; - - while (x>=0) { - intzverg = round_db_to_int_clamp(zverg); - - if ( intzverg > *rz || *rz==0x7FFFFFFF) { /* UNIQUE LINE: see comment above */ - if (!zspan->rectmask || intzverg > *rm) { - *ro= obi; /* UNIQUE LINE: see comment above (order differs) */ - *rz= intzverg; - *rp= zvlnr; - } - } - zverg+= zxd; - rz++; - rp++; - ro++; - rm++; - x--; - } - } - - zy0-=zyd; - rectzofs-= rectx; - rectpofs-= rectx; - rectoofs-= rectx; - rectmaskofs-= rectx; - } -} - -/* uses spanbuffers */ - -/* WATCH IT: zbuffillGLinv4 and zbuffillGL4 are identical except for a 2 lines, - * commented below */ -static void zbuffillGL4(ZSpan *zspan, int obi, int zvlnr, - const float *v1, const float *v2, const float *v3, const float *v4) -{ - double zxd, zyd, zy0, zverg; - float x0, y0, z0; - float x1, y1, z1, x2, y2, z2, xx1; - const float *span1, *span2; - int *rectoofs, *ro; - int *rectpofs, *rp; - const int *rectmaskofs, *rm; - int *rz, x, y; - int sn1, sn2, rectx, *rectzofs, my0, my2; - - /* init */ - zbuf_init_span(zspan); - - /* set spans */ - zbuf_add_to_span(zspan, v1, v2); - zbuf_add_to_span(zspan, v2, v3); - if (v4) { - zbuf_add_to_span(zspan, v3, v4); - zbuf_add_to_span(zspan, v4, v1); - } - else - zbuf_add_to_span(zspan, v3, v1); - - /* clipped */ - if (zspan->minp2==NULL || zspan->maxp2==NULL) return; - - my0 = max_ii(zspan->miny1, zspan->miny2); - my2 = min_ii(zspan->maxy1, zspan->maxy2); - - // printf("my %d %d\n", my0, my2); - if (my2<my0) return; - - - /* ZBUF DX DY, in floats still */ - x1= v1[0]- v2[0]; - x2= v2[0]- v3[0]; - y1= v1[1]- v2[1]; - y2= v2[1]- v3[1]; - z1= v1[2]- v2[2]; - z2= v2[2]- v3[2]; - x0= y1*z2-z1*y2; - y0= z1*x2-x1*z2; - z0= x1*y2-y1*x2; - - if (z0==0.0f) return; - - xx1= (x0*v1[0] + y0*v1[1])/z0 + v1[2]; - - zxd= -(double)x0/(double)z0; - zyd= -(double)y0/(double)z0; - zy0= ((double)my2)*zyd + (double)xx1; - - /* start-offset in rect */ - rectx= zspan->rectx; - rectzofs= (zspan->rectz+rectx*my2); - rectpofs= (zspan->rectp+rectx*my2); - rectoofs= (zspan->recto+rectx*my2); - rectmaskofs= (zspan->rectmask+rectx*my2); - - /* correct span */ - sn1= (my0 + my2)/2; - if (zspan->span1[sn1] < zspan->span2[sn1]) { - span1= zspan->span1+my2; - span2= zspan->span2+my2; - } - else { - span1= zspan->span2+my2; - span2= zspan->span1+my2; - } - - for (y=my2; y>=my0; y--, span1--, span2--) { - - sn1= floor(*span1); - sn2= floor(*span2); - sn1++; - - if (sn2>=rectx) sn2= rectx-1; - if (sn1<0) sn1= 0; - - if (sn2>=sn1) { - int intzverg; - - zverg= (double)sn1*zxd + zy0; - rz= rectzofs+sn1; - rp= rectpofs+sn1; - ro= rectoofs+sn1; - rm= rectmaskofs+sn1; - x= sn2-sn1; - - while (x>=0) { - intzverg = round_db_to_int_clamp(zverg); - - if (intzverg < *rz) { /* ONLY UNIQUE LINE: see comment above */ - if (!zspan->rectmask || intzverg > *rm) { - *rz= intzverg; - *rp= zvlnr; - *ro= obi; /* UNIQUE LINE: see comment above (order differs) */ - } - } - zverg+= zxd; - rz++; - rp++; - ro++; - rm++; - x--; - } - } - - zy0-=zyd; - rectzofs-= rectx; - rectpofs-= rectx; - rectoofs-= rectx; - rectmaskofs-= rectx; - } -} - -/** - * Fill the z buffer. The face buffer is not operated on! - * - * This is one of the z buffer fill functions called in zbufclip() and - * zbufwireclip(). - * - * \param v1 [4 floats, world coordinates] first vertex - * \param v2 [4 floats, world coordinates] second vertex - * \param v3 [4 floats, world coordinates] third vertex - */ - -/* now: filling two Z values, the closest and 2nd closest */ -static void zbuffillGL_onlyZ(ZSpan *zspan, int UNUSED(obi), int UNUSED(zvlnr), - const float *v1, const float *v2, const float *v3, const float *v4) -{ - double zxd, zyd, zy0, zverg; - float x0, y0, z0; - float x1, y1, z1, x2, y2, z2, xx1; - const float *span1, *span2; - int *rz, *rz1, x, y; - int sn1, sn2, rectx, *rectzofs, *rectzofs1= NULL, my0, my2; - - /* init */ - zbuf_init_span(zspan); - - /* set spans */ - zbuf_add_to_span(zspan, v1, v2); - zbuf_add_to_span(zspan, v2, v3); - if (v4) { - zbuf_add_to_span(zspan, v3, v4); - zbuf_add_to_span(zspan, v4, v1); - } - else - zbuf_add_to_span(zspan, v3, v1); - - /* clipped */ - if (zspan->minp2==NULL || zspan->maxp2==NULL) return; - - my0 = max_ii(zspan->miny1, zspan->miny2); - my2 = min_ii(zspan->maxy1, zspan->maxy2); - - // printf("my %d %d\n", my0, my2); - if (my2<my0) return; - - - /* ZBUF DX DY, in floats still */ - x1= v1[0]- v2[0]; - x2= v2[0]- v3[0]; - y1= v1[1]- v2[1]; - y2= v2[1]- v3[1]; - z1= v1[2]- v2[2]; - z2= v2[2]- v3[2]; - x0= y1*z2-z1*y2; - y0= z1*x2-x1*z2; - z0= x1*y2-y1*x2; - - if (z0==0.0f) return; - - xx1= (x0*v1[0] + y0*v1[1])/z0 + v1[2]; - - zxd= -(double)x0/(double)z0; - zyd= -(double)y0/(double)z0; - zy0= ((double)my2)*zyd + (double)xx1; - - /* start-offset in rect */ - rectx= zspan->rectx; - rectzofs= (zspan->rectz+rectx*my2); - if (zspan->rectz1) - rectzofs1= (zspan->rectz1+rectx*my2); - - /* correct span */ - sn1= (my0 + my2)/2; - if (zspan->span1[sn1] < zspan->span2[sn1]) { - span1= zspan->span1+my2; - span2= zspan->span2+my2; - } - else { - span1= zspan->span2+my2; - span2= zspan->span1+my2; - } - - for (y=my2; y>=my0; y--, span1--, span2--) { - - sn1= floor(*span1); - sn2= floor(*span2); - sn1++; - - if (sn2>=rectx) sn2= rectx-1; - if (sn1<0) sn1= 0; - - if (sn2>=sn1) { - zverg= (double)sn1*zxd + zy0; - rz= rectzofs+sn1; - rz1= rectzofs1+sn1; - x= sn2-sn1; - - while (x>=0) { - int zvergi = round_db_to_int_clamp(zverg); - - /* option: maintain two depth values, closest and 2nd closest */ - if (zvergi < *rz) { - if (rectzofs1) *rz1= *rz; - *rz= zvergi; - } - else if (rectzofs1 && zvergi < *rz1) - *rz1= zvergi; - - zverg+= zxd; - - rz++; - rz1++; - x--; - } - } - - zy0-=zyd; - rectzofs-= rectx; - if (rectzofs1) rectzofs1-= rectx; - } -} - -/* 2d scanconvert for tria, calls func for each x, y coordinate and gives UV barycentrics */ -void zspan_scanconvert_strand(ZSpan *zspan, void *handle, float *v1, float *v2, float *v3, void (*func)(void *, int, int, float, float, float) ) -{ - float x0, y0, x1, y1, x2, y2, z0, z1, z2, z; - float u, v, uxd, uyd, vxd, vyd, uy0, vy0, zxd, zyd, zy0, xx1; - const float *span1, *span2; - int x, y, sn1, sn2, rectx= zspan->rectx, my0, my2; - - /* init */ - zbuf_init_span(zspan); - - /* set spans */ - zbuf_add_to_span(zspan, v1, v2); - zbuf_add_to_span(zspan, v2, v3); - zbuf_add_to_span(zspan, v3, v1); - - /* clipped */ - if (zspan->minp2==NULL || zspan->maxp2==NULL) return; - - my0 = max_ii(zspan->miny1, zspan->miny2); - my2 = min_ii(zspan->maxy1, zspan->maxy2); - - // printf("my %d %d\n", my0, my2); - if (my2<my0) return; - - /* ZBUF DX DY, in floats still */ - x1= v1[0]- v2[0]; - x2= v2[0]- v3[0]; - y1= v1[1]- v2[1]; - y2= v2[1]- v3[1]; - z1= v1[2]- v2[2]; - z2= v2[2]- v3[2]; - - x0= y1*z2-z1*y2; - y0= z1*x2-x1*z2; - z0= x1*y2-y1*x2; - - if (z0==0.0f) return; - - xx1= (x0*v1[0] + y0*v1[1])/z0 + v1[2]; - zxd= -(double)x0/(double)z0; - zyd= -(double)y0/(double)z0; - zy0= ((double)my2)*zyd + (double)xx1; - - z1= 1.0f; /* (u1 - u2) */ - z2= 0.0f; /* (u2 - u3) */ - - x0= y1*z2-z1*y2; - y0= z1*x2-x1*z2; - - xx1= (x0*v1[0] + y0*v1[1])/z0 + 1.0f; - uxd= -(double)x0/(double)z0; - uyd= -(double)y0/(double)z0; - uy0= ((double)my2)*uyd + (double)xx1; - - z1= -1.0f; /* (v1 - v2) */ - z2= 1.0f; /* (v2 - v3) */ - - x0= y1*z2-z1*y2; - y0= z1*x2-x1*z2; - - xx1= (x0*v1[0] + y0*v1[1])/z0; - vxd= -(double)x0/(double)z0; - vyd= -(double)y0/(double)z0; - vy0= ((double)my2)*vyd + (double)xx1; - - /* correct span */ - sn1= (my0 + my2)/2; - if (zspan->span1[sn1] < zspan->span2[sn1]) { - span1= zspan->span1+my2; - span2= zspan->span2+my2; - } - else { - span1= zspan->span2+my2; - span2= zspan->span1+my2; - } - - for (y=my2; y>=my0; y--, span1--, span2--) { - - sn1= floor(*span1); - sn2= floor(*span2); - sn1++; - - if (sn2>=rectx) sn2= rectx-1; - if (sn1<0) sn1= 0; - - u= (double)sn1*uxd + uy0; - v= (double)sn1*vxd + vy0; - z= (double)sn1*zxd + zy0; - - for (x= sn1; x<=sn2; x++, u+=uxd, v+=vxd, z+=zxd) - func(handle, x, y, u, v, z); - - uy0 -= uyd; - vy0 -= vyd; - zy0 -= zyd; - } -} - /* scanconvert for strand triangles, calls func for each x, y coordinate and gives UV barycentrics and z */ void zspan_scanconvert(ZSpan *zspan, void *handle, float *v1, float *v2, float *v3, void (*func)(void *, int, int, float, float) ) @@ -1585,2154 +241,4 @@ void zspan_scanconvert(ZSpan *zspan, void *handle, float *v1, float *v2, float * } } - - -/** - * (clip pyramid) - * Sets lambda: flag, and parametrize the clipping of vertices in - * viewspace coordinates. lambda = -1 means no clipping, lambda in [0, 1] means a clipping. - * Note: uses globals. - * \param v1 start coordinate s - * \param v2 target coordinate t - * \param b2 - * \param b3 - * \param a index for coordinate (x, y, or z) - */ - -static void clippyra(float *lambda, float *v1, float *v2, int *b2, int *b3, int a, float clipcrop) -{ - float da, dw, u1=0.0, u2=1.0; - float v13; - - lambda[0]= -1.0; - lambda[1]= -1.0; - - da= v2[a]-v1[a]; - /* prob; we clip slightly larger, osa renders add 2 pixels on edges, should become variable? */ - /* or better; increase r.winx/y size, but thats quite a complex one. do it later */ - if (a==2) { - dw= (v2[3]-v1[3]); - v13= v1[3]; - } - else { - dw= clipcrop*(v2[3]-v1[3]); - v13= clipcrop*v1[3]; - } - /* according the original article by Liang&Barsky, for clipping of - * homogeneous coordinates with viewplane, the value of "0" is used instead of "-w" . - * This differs from the other clipping cases (like left or top) and I considered - * it to be not so 'homogenic'. But later it has proven to be an error, - * who would have thought that of L&B! - */ - - if (cliptestf(-da, -dw, v13, v1[a], &u1, &u2)) { - if (cliptestf(da, -dw, v13, -v1[a], &u1, &u2)) { - *b3=1; - if (u2<1.0f) { - lambda[1]= u2; - *b2=1; - } - else lambda[1]=1.0; /* u2 */ - if (u1>0.0f) { - lambda[0] = u1; - *b2 = 1; - } - else { - lambda[0] = 0.0; - } - } - } -} - -/** - * (make vertex pyramide clip) - * Checks lambda and uses this to make decision about clipping the line - * segment from v1 to v2. lambda is the factor by which the vector is - * cut. ( calculate s + l * ( t - s )). The result is appended to the - * vertex list of this face. - * - * - * \param v1 start coordinate s - * \param v2 target coordinate t - * \param b1 - * \param b2 - * \param clve vertex vector. - */ - -static void makevertpyra(float *vez, float *lambda, float **trias, float *v1, float *v2, int *b1, int *clve) -{ - float l1, l2, *adr; - - l1= lambda[0]; - l2= lambda[1]; - - if (l1!= -1.0f) { - if (l1!= 0.0f) { - adr= vez+4*(*clve); - trias[*b1]=adr; - (*clve)++; - adr[0]= v1[0]+l1*(v2[0]-v1[0]); - adr[1]= v1[1]+l1*(v2[1]-v1[1]); - adr[2]= v1[2]+l1*(v2[2]-v1[2]); - adr[3]= v1[3]+l1*(v2[3]-v1[3]); - } - else trias[*b1]= v1; - - (*b1)++; - } - if (l2!= -1.0f) { - if (l2!= 1.0f) { - adr= vez+4*(*clve); - trias[*b1]=adr; - (*clve)++; - adr[0]= v1[0]+l2*(v2[0]-v1[0]); - adr[1]= v1[1]+l2*(v2[1]-v1[1]); - adr[2]= v1[2]+l2*(v2[2]-v1[2]); - adr[3]= v1[3]+l2*(v2[3]-v1[3]); - (*b1)++; - } - } -} - -/* ------------------------------------------------------------------------- */ - -void projectverto(const float v1[3], float winmat[4][4], float adr[4]) -{ - /* calcs homogenic coord of vertex v1 */ - float x, y, z; - - x = v1[0]; - y = v1[1]; - z = v1[2]; - adr[0] = x * winmat[0][0] + z * winmat[2][0] + winmat[3][0]; - adr[1] = y * winmat[1][1] + z * winmat[2][1] + winmat[3][1]; - adr[2] = z * winmat[2][2] + winmat[3][2]; - adr[3] = z * winmat[2][3] + winmat[3][3]; - - //printf("hoco %f %f %f %f\n", adr[0], adr[1], adr[2], adr[3]); -} - -/* ------------------------------------------------------------------------- */ - -void projectvert(const float v1[3], float winmat[4][4], float adr[4]) -{ - /* calcs homogenic coord of vertex v1 */ - float x, y, z; - - x = v1[0]; - y = v1[1]; - z = v1[2]; - adr[0] = x * winmat[0][0] + y * winmat[1][0] + z * winmat[2][0] + winmat[3][0]; - adr[1] = x * winmat[0][1] + y * winmat[1][1] + z * winmat[2][1] + winmat[3][1]; - adr[2] = x * winmat[0][2] + y * winmat[1][2] + z * winmat[2][2] + winmat[3][2]; - adr[3] = x * winmat[0][3] + y * winmat[1][3] + z * winmat[2][3] + winmat[3][3]; -} - -/* ------------------------------------------------------------------------- */ - -#define ZBUF_PROJECT_CACHE_SIZE 256 - -typedef struct ZbufProjectCache { - int index, clip; - float ho[4]; -} ZbufProjectCache; - -static void zbuf_project_cache_clear(ZbufProjectCache *cache, int size) -{ - int i; - - if (size > ZBUF_PROJECT_CACHE_SIZE) - size= ZBUF_PROJECT_CACHE_SIZE; - - memset(cache, 0, sizeof(ZbufProjectCache)*size); - for (i=0; i<size; i++) - cache[i].index= -1; -} - -static int zbuf_shadow_project(ZbufProjectCache *cache, int index, float winmat[4][4], float *co, float *ho) -{ - int cindex= index & 255; - - if (cache[cindex].index == index) { - copy_v4_v4(ho, cache[cindex].ho); - return cache[cindex].clip; - } - else { - int clipflag; - projectvert(co, winmat, ho); - clipflag= testclip(ho); - - copy_v4_v4(cache[cindex].ho, ho); - cache[cindex].clip= clipflag; - cache[cindex].index= index; - - return clipflag; - } -} - -static void zbuffer_part_bounds(int winx, int winy, RenderPart *pa, float *bounds) -{ - bounds[0]= (2*pa->disprect.xmin - winx-1)/(float)winx; - bounds[1]= (2*pa->disprect.xmax - winx+1)/(float)winx; - bounds[2]= (2*pa->disprect.ymin - winy-1)/(float)winy; - bounds[3]= (2*pa->disprect.ymax - winy+1)/(float)winy; -} - -static int zbuf_part_project(ZbufProjectCache *cache, int index, float winmat[4][4], float *bounds, float *co, float *ho) -{ - float vec[3]; - int cindex= index & 255; - - if (cache[cindex].index == index) { - copy_v4_v4(ho, cache[cindex].ho); - return cache[cindex].clip; - } - else { - float wco; - int clipflag= 0; - copy_v3_v3(vec, co); - projectvert(co, winmat, ho); - - wco= ho[3]; - if (ho[0] < bounds[0]*wco) clipflag |= 1; - else if (ho[0] > bounds[1]*wco) clipflag |= 2; - if (ho[1] > bounds[3]*wco) clipflag |= 4; - else if (ho[1] < bounds[2]*wco) clipflag |= 8; - - copy_v4_v4(cache[cindex].ho, ho); - cache[cindex].clip= clipflag; - cache[cindex].index= index; - - return clipflag; - } -} - -void zbuf_render_project(float winmat[4][4], const float co[3], float ho[4]) -{ - float vec[3]; - - copy_v3_v3(vec, co); - projectvert(vec, winmat, ho); -} - -void zbuf_make_winmat(Render *re, float winmat[4][4]) -{ - if (re->r.mode & R_PANORAMA) { - float panomat[4][4]; - - unit_m4(panomat); - - panomat[0][0]= re->panoco; - panomat[0][2]= re->panosi; - panomat[2][0]= -re->panosi; - panomat[2][2]= re->panoco; - - mul_m4_m4m4(winmat, re->winmat, panomat); - } - else - copy_m4_m4(winmat, re->winmat); -} - -/* do zbuffering and clip, f1 f2 f3 are hocos, c1 c2 c3 are clipping flags */ - -void zbufclip(ZSpan *zspan, int obi, int zvlnr, - const float f1[4], const float f2[4], const float f3[4], - const int c1, const int c2, const int c3) -{ - float *vlzp[32][3], lambda[3][2]; - float vez[400], *trias[40]; - - if (c1 | c2 | c3) { /* not in middle */ - if (c1 & c2 & c3) { /* completely out */ - return; - } - else { /* clipping */ - int arg, v, b, clipflag[3], b1, b2, b3, c4, clve=3, clvlo, clvl=1; - float *fp; - - vez[0]= f1[0]; vez[1]= f1[1]; vez[2]= f1[2]; vez[3]= f1[3]; - vez[4]= f2[0]; vez[5]= f2[1]; vez[6]= f2[2]; vez[7]= f2[3]; - vez[8]= f3[0]; vez[9]= f3[1]; vez[10]= f3[2];vez[11]= f3[3]; - - vlzp[0][0]= vez; - vlzp[0][1]= vez+4; - vlzp[0][2]= vez+8; - - clipflag[0]= ( (c1 & 48) | (c2 & 48) | (c3 & 48) ); - if (clipflag[0]==0) { /* othwerwise it needs to be calculated again, after the first (z) clip */ - clipflag[1]= ( (c1 & 3) | (c2 & 3) | (c3 & 3) ); - clipflag[2]= ( (c1 & 12) | (c2 & 12) | (c3 & 12) ); - } - else clipflag[1]=clipflag[2]= 0; - - for (b=0;b<3;b++) { - - if (clipflag[b]) { - - clvlo= clvl; - - for (v=0; v<clvlo; v++) { - - if (vlzp[v][0]!=NULL) { /* face is still there */ - b2= b3 =0; /* clip flags */ - - if (b==0) arg= 2; - else if (b==1) arg= 0; - else arg= 1; - - clippyra(lambda[0], vlzp[v][0], vlzp[v][1], &b2, &b3, arg, zspan->clipcrop); - clippyra(lambda[1], vlzp[v][1], vlzp[v][2], &b2, &b3, arg, zspan->clipcrop); - clippyra(lambda[2], vlzp[v][2], vlzp[v][0], &b2, &b3, arg, zspan->clipcrop); - - if (b2==0 && b3==1) { - /* completely 'in', but we copy because of last for () loop in this section */; - vlzp[clvl][0]= vlzp[v][0]; - vlzp[clvl][1]= vlzp[v][1]; - vlzp[clvl][2]= vlzp[v][2]; - vlzp[v][0]= NULL; - clvl++; - } - else if (b3==0) { - vlzp[v][0]= NULL; - /* completely 'out' */; - } - else { - b1=0; - makevertpyra(vez, lambda[0], trias, vlzp[v][0], vlzp[v][1], &b1, &clve); - makevertpyra(vez, lambda[1], trias, vlzp[v][1], vlzp[v][2], &b1, &clve); - makevertpyra(vez, lambda[2], trias, vlzp[v][2], vlzp[v][0], &b1, &clve); - - /* after front clip done: now set clip flags */ - if (b==0) { - clipflag[1]= clipflag[2]= 0; - f1= vez; - for (b3=0; b3<clve; b3++) { - c4= testclip(f1); - clipflag[1] |= (c4 & 3); - clipflag[2] |= (c4 & 12); - f1+= 4; - } - } - - vlzp[v][0]= NULL; - if (b1>2) { - for (b3=3; b3<=b1; b3++) { - vlzp[clvl][0]= trias[0]; - vlzp[clvl][1]= trias[b3-2]; - vlzp[clvl][2]= trias[b3-1]; - clvl++; - } - } - } - } - } - } - } - - /* warning, clip overflow, this should never happen! */ - BLI_assert(!(clve > 38 || clvl > 31)); - - /* perspective division */ - fp = vez; - for (b = 0; b < clve; b++) { - hoco_to_zco(zspan, fp, fp); - fp += 4; - } - for (b = 1; b < clvl; b++) { - if (vlzp[b][0]) { - zspan->zbuffunc(zspan, obi, zvlnr, vlzp[b][0], vlzp[b][1], vlzp[b][2], NULL); - } - } - return; - } - } - - /* perspective division: HCS to ZCS */ - hoco_to_zco(zspan, vez, f1); - hoco_to_zco(zspan, vez+4, f2); - hoco_to_zco(zspan, vez+8, f3); - zspan->zbuffunc(zspan, obi, zvlnr, vez, vez+4, vez+8, NULL); -} - -void zbufclip4(ZSpan *zspan, int obi, int zvlnr, - const float f1[4], const float f2[4], const float f3[4], const float f4[4], - const int c1, const int c2, const int c3, const int c4) -{ - float vez[16]; - - if (c1 | c2 | c3 | c4) { /* not in middle */ - if (c1 & c2 & c3 & c4) { /* completely out */ - return; - } - else { /* clipping */ - zbufclip(zspan, obi, zvlnr, f1, f2, f3, c1, c2, c3); - zbufclip(zspan, obi, zvlnr, f1, f3, f4, c1, c3, c4); - } - return; - } - - /* perspective division: HCS to ZCS */ - hoco_to_zco(zspan, vez, f1); - hoco_to_zco(zspan, vez+4, f2); - hoco_to_zco(zspan, vez+8, f3); - hoco_to_zco(zspan, vez+12, f4); - - zspan->zbuffunc(zspan, obi, zvlnr, vez, vez+4, vez+8, vez+12); -} - -/* ************** ZMASK ******************************** */ - -#define EXTEND_PIXEL(a) if (temprectp[a]) { z += rectz[a]; tot++; } (void)0 - -/* changes the zbuffer to be ready for z-masking: applies an extend-filter, and then clears */ -static void zmask_rect(int *rectz, int *rectp, int xs, int ys, int neg) -{ - int len=0, x, y; - int *temprectp; - int row1, row2, row3, *curp, *curz; - - temprectp= MEM_dupallocN(rectp); - - /* extend: if pixel is not filled in, we check surrounding pixels and average z value */ - - for (y=1; y<=ys; y++) { - /* setup row indices */ - row1= (y-2)*xs; - row2= row1 + xs; - row3= row2 + xs; - if (y==1) - row1= row2; - else if (y==ys) - row3= row2; - - curp= rectp + (y-1)*xs; - curz= rectz + (y-1)*xs; - - for (x=0; x<xs; x++, curp++, curz++) { - if (curp[0]==0) { - int tot= 0; - float z= 0.0f; - - EXTEND_PIXEL(row1); - EXTEND_PIXEL(row2); - EXTEND_PIXEL(row3); - EXTEND_PIXEL(row1 + 1); - EXTEND_PIXEL(row3 + 1); - if (x!=xs-1) { - EXTEND_PIXEL(row1 + 2); - EXTEND_PIXEL(row2 + 2); - EXTEND_PIXEL(row3 + 2); - } - if (tot) { - len++; - curz[0]= (int)(z/(float)tot); - curp[0]= -1; /* env */ - } - } - - if (x!=0) { - row1++; row2++; row3++; - } - } - } - - MEM_freeN(temprectp); - - if (neg) { - /* z values for negative are already correct */ - } - else { - /* clear not filled z values */ - for (len= xs*ys -1; len>=0; len--) { - if (rectp[len]==0) { - rectz[len] = -0x7FFFFFFF; - rectp[len]= -1; /* env code */ - } - } - } -} - - -/* ***************** ZBUFFER MAIN ROUTINES **************** */ - -void zbuffer_solid(RenderPart *pa, RenderLayer *rl, void(*fillfunc)(RenderPart *, ZSpan *, int, void *), void *data) -{ - ZbufProjectCache cache[ZBUF_PROJECT_CACHE_SIZE]; - ZSpan zspans[16], *zspan; /* 16 = RE_MAX_OSA */ - VlakRen *vlr= NULL; - VertRen *v1, *v2, *v3, *v4; - Material *ma = NULL; - ObjectInstanceRen *obi; - ObjectRen *obr; - float obwinmat[4][4], winmat[4][4], bounds[4]; - float ho1[4], ho2[4], ho3[4], ho4[4]={0}; - unsigned int lay= (1 << 20) - 1, lay_zmask= 0; - int i, v, zvlnr, zsample, samples, c1, c2, c3, c4=0; - short nofill=0, env=0, wire=0, zmaskpass=0; - const bool all_z = (rl->layflag & SCE_LAY_ALL_Z) && !(rl->layflag & SCE_LAY_ZMASK); - const bool neg_zmask = (rl->layflag & SCE_LAY_ZMASK) && (rl->layflag & SCE_LAY_NEG_ZMASK); - - zbuf_make_winmat(&R, winmat); - - samples= (R.osa? R.osa: 1); - samples= MIN2(4, samples-pa->sample); - - for (zsample=0; zsample<samples; zsample++) { - zspan= &zspans[zsample]; - - zbuffer_part_bounds(R.winx, R.winy, pa, bounds); - zbuf_alloc_span(zspan, pa->rectx, pa->recty, R.clipcrop); - - /* needed for transform from hoco to zbuffer co */ - zspan->zmulx= ((float)R.winx)/2.0f; - zspan->zmuly= ((float)R.winy)/2.0f; - - if (R.osa) { - zspan->zofsx= -pa->disprect.xmin - R.jit[pa->sample+zsample][0]; - zspan->zofsy= -pa->disprect.ymin - R.jit[pa->sample+zsample][1]; - } - else if (R.i.curblur) { - zspan->zofsx= -pa->disprect.xmin - R.mblur_jit[R.i.curblur-1][0]; - zspan->zofsy= -pa->disprect.ymin - R.mblur_jit[R.i.curblur-1][1]; - } - else { - zspan->zofsx= -pa->disprect.xmin; - zspan->zofsy= -pa->disprect.ymin; - } - /* to center the sample position */ - zspan->zofsx -= 0.5f; - zspan->zofsy -= 0.5f; - - /* the buffers */ - if (zsample == samples-1) { - zspan->rectp= pa->rectp; - zspan->recto= pa->recto; - - if (neg_zmask) - zspan->rectz= pa->rectmask; - else - zspan->rectz= pa->rectz; - } - else { - zspan->recto= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "recto"); - zspan->rectp= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectp"); - zspan->rectz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectz"); - } - - fillrect(zspan->rectz, pa->rectx, pa->recty, 0x7FFFFFFF); - fillrect(zspan->rectp, pa->rectx, pa->recty, 0); - fillrect(zspan->recto, pa->rectx, pa->recty, 0); - } - - /* in case zmask we fill Z for objects in lay_zmask first, then clear Z, and then do normal zbuffering */ - if (rl->layflag & SCE_LAY_ZMASK) - zmaskpass= 1; - - for (; zmaskpass >=0; zmaskpass--) { - ma= NULL; - - /* filling methods */ - for (zsample=0; zsample<samples; zsample++) { - zspan= &zspans[zsample]; - - if (zmaskpass && neg_zmask) - zspan->zbuffunc= zbuffillGLinv4; - else - zspan->zbuffunc= zbuffillGL4; - zspan->zbuflinefunc= zbufline; - } - - /* regular zbuffering loop, does all sample buffers */ - for (i=0, obi=R.instancetable.first; obi; i++, obi=obi->next) { - obr= obi->obr; - - /* continue happens in 2 different ways... zmaskpass only does lay_zmask stuff */ - if (zmaskpass) { - if ((obi->lay & lay_zmask)==0) - continue; - } - else if (!all_z && !(obi->lay & (lay|lay_zmask))) - continue; - - if (obi->flag & R_TRANSFORMED) - mul_m4_m4m4(obwinmat, winmat, obi->mat); - else - copy_m4_m4(obwinmat, winmat); - - if (clip_render_object(obi->obr->boundbox, bounds, obwinmat)) - continue; - - zbuf_project_cache_clear(cache, obr->totvert); - - for (v=0; v<obr->totvlak; v++) { - if ((v & 255)==0) vlr= obr->vlaknodes[v>>8].vlak; - else vlr++; - - /* the cases: visible for render, only z values, zmask, nothing */ - if (obi->lay & lay) { - if (vlr->mat!=ma) { - ma= vlr->mat; - nofill= (ma->mode & MA_ONLYCAST) || ((ma->mode & MA_TRANSP) && (ma->mode & MA_ZTRANSP)); - env= (ma->mode & MA_ENV); - wire= (ma->material_type == MA_TYPE_WIRE); - - for (zsample=0; zsample<samples; zsample++) { - if (ma->mode & MA_ZINV || (zmaskpass && neg_zmask)) - zspans[zsample].zbuffunc= zbuffillGLinv4; - else - zspans[zsample].zbuffunc= zbuffillGL4; - } - } - } - else if (all_z || (obi->lay & lay_zmask)) { - env= 1; - nofill= 0; - ma= NULL; - } - else { - nofill= 1; - ma= NULL; /* otherwise nofill can hang */ - } - - if (!(vlr->flag & R_HIDDEN) && nofill==0) { - unsigned short partclip; - - v1= vlr->v1; - v2= vlr->v2; - v3= vlr->v3; - v4= vlr->v4; - - c1= zbuf_part_project(cache, v1->index, obwinmat, bounds, v1->co, ho1); - c2= zbuf_part_project(cache, v2->index, obwinmat, bounds, v2->co, ho2); - c3= zbuf_part_project(cache, v3->index, obwinmat, bounds, v3->co, ho3); - - /* partclipping doesn't need viewplane clipping */ - partclip= c1 & c2 & c3; - if (v4) { - c4= zbuf_part_project(cache, v4->index, obwinmat, bounds, v4->co, ho4); - partclip &= c4; - } - - if (partclip==0) { - - if (env) zvlnr= -1; - else zvlnr= v+1; - - c1= testclip(ho1); - c2= testclip(ho2); - c3= testclip(ho3); - if (v4) - c4= testclip(ho4); - - for (zsample=0; zsample<samples; zsample++) { - zspan= &zspans[zsample]; - - if (wire) { - if (v4) - zbufclipwire(zspan, i, zvlnr, vlr->ec, ho1, ho2, ho3, ho4, c1, c2, c3, c4); - else - zbufclipwire(zspan, i, zvlnr, vlr->ec, ho1, ho2, ho3, NULL, c1, c2, c3, 0); - } - else { - /* strands allow to be filled in as quad */ - if (v4 && (vlr->flag & R_STRAND)) { - zbufclip4(zspan, i, zvlnr, ho1, ho2, ho3, ho4, c1, c2, c3, c4); - } - else { - zbufclip(zspan, i, zvlnr, ho1, ho2, ho3, c1, c2, c3); - if (v4) - zbufclip(zspan, i, (env)? zvlnr: zvlnr+RE_QUAD_OFFS, ho1, ho3, ho4, c1, c3, c4); - } - } - } - } - } - } - } - - /* clear all z to close value, so it works as mask for next passes (ztra+strand) */ - if (zmaskpass) { - for (zsample=0; zsample<samples; zsample++) { - zspan= &zspans[zsample]; - - if (neg_zmask) { - zspan->rectmask= zspan->rectz; - if (zsample == samples-1) - zspan->rectz= pa->rectz; - else - zspan->rectz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectz"); - fillrect(zspan->rectz, pa->rectx, pa->recty, 0x7FFFFFFF); - - zmask_rect(zspan->rectmask, zspan->rectp, pa->rectx, pa->recty, 1); - } - else - zmask_rect(zspan->rectz, zspan->rectp, pa->rectx, pa->recty, 0); - } - } - } - - for (zsample=0; zsample<samples; zsample++) { - zspan= &zspans[zsample]; - - if (fillfunc) - fillfunc(pa, zspan, pa->sample+zsample, data); - - if (zsample != samples-1) { - MEM_freeN(zspan->rectz); - MEM_freeN(zspan->rectp); - MEM_freeN(zspan->recto); - if (zspan->rectmask) - MEM_freeN(zspan->rectmask); - } - - zbuf_free_span(zspan); - } -} - -void zbuffer_shadow(Render *re, float winmat[4][4], LampRen *lar, int *rectz, int size, float jitx, float jity) -{ - ZbufProjectCache cache[ZBUF_PROJECT_CACHE_SIZE]; - ZSpan zspan; - ObjectInstanceRen *obi; - ObjectRen *obr; - VlakRen *vlr= NULL; - Material *ma= NULL; - StrandSegment sseg; - StrandRen *strand= NULL; - StrandVert *svert; - StrandBound *sbound; - float obwinmat[4][4], ho1[4], ho2[4], ho3[4], ho4[4]; - int a, b, c, i, c1, c2, c3, c4, ok=1, lay= -1; - - if (lar->mode & (LA_LAYER|LA_LAYER_SHADOW)) lay= lar->lay; - - /* 1.0f for clipping in clippyra()... bad stuff actually */ - zbuf_alloc_span(&zspan, size, size, 1.0f); - zspan.zmulx= ((float)size)/2.0f; - zspan.zmuly= ((float)size)/2.0f; - /* -0.5f to center the sample position */ - zspan.zofsx= jitx - 0.5f; - zspan.zofsy= jity - 0.5f; - - /* the buffers */ - zspan.rectz= rectz; - fillrect(rectz, size, size, 0x7FFFFFFE); - if (lar->buftype==LA_SHADBUF_HALFWAY) { - zspan.rectz1= MEM_mallocN(size*size*sizeof(int), "seconday z buffer"); - fillrect(zspan.rectz1, size, size, 0x7FFFFFFE); - } - - /* filling methods */ - zspan.zbuflinefunc= zbufline_onlyZ; - zspan.zbuffunc= zbuffillGL_onlyZ; - - for (i=0, obi=re->instancetable.first; obi; i++, obi=obi->next) { - obr= obi->obr; - - if (obr->ob==re->excludeob) - continue; - else if (!(obi->lay & lay)) - continue; - - if (obi->flag & R_TRANSFORMED) - mul_m4_m4m4(obwinmat, winmat, obi->mat); - else - copy_m4_m4(obwinmat, winmat); - - if (clip_render_object(obi->obr->boundbox, NULL, obwinmat)) - continue; - - zbuf_project_cache_clear(cache, obr->totvert); - - /* faces */ - for (a=0; a<obr->totvlak; a++) { - - if ((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; - else vlr++; - - /* note, these conditions are copied in shadowbuf_autoclip() */ - if (vlr->mat!= ma) { - ma= vlr->mat; - ok= 1; - if ((ma->mode2 & MA_CASTSHADOW)==0 || (ma->mode & MA_SHADBUF)==0) ok= 0; - } - - if (ok && (obi->lay & lay) && !(vlr->flag & R_HIDDEN)) { - c1= zbuf_shadow_project(cache, vlr->v1->index, obwinmat, vlr->v1->co, ho1); - c2= zbuf_shadow_project(cache, vlr->v2->index, obwinmat, vlr->v2->co, ho2); - c3= zbuf_shadow_project(cache, vlr->v3->index, obwinmat, vlr->v3->co, ho3); - - if ((ma->material_type == MA_TYPE_WIRE) || (vlr->flag & R_STRAND)) { - if (vlr->v4) { - c4= zbuf_shadow_project(cache, vlr->v4->index, obwinmat, vlr->v4->co, ho4); - zbufclipwire(&zspan, 0, a+1, vlr->ec, ho1, ho2, ho3, ho4, c1, c2, c3, c4); - } - else - zbufclipwire(&zspan, 0, a+1, vlr->ec, ho1, ho2, ho3, NULL, c1, c2, c3, 0); - } - else { - if (vlr->v4) { - c4= zbuf_shadow_project(cache, vlr->v4->index, obwinmat, vlr->v4->co, ho4); - zbufclip4(&zspan, 0, 0, ho1, ho2, ho3, ho4, c1, c2, c3, c4); - } - else - zbufclip(&zspan, 0, 0, ho1, ho2, ho3, c1, c2, c3); - } - } - - if ((a & 255)==255 && re->test_break(re->tbh)) - break; - } - - /* strands */ - if (obr->strandbuf) { - /* for each bounding box containing a number of strands */ - sbound= obr->strandbuf->bound; - for (c=0; c<obr->strandbuf->totbound; c++, sbound++) { - if (clip_render_object(sbound->boundbox, NULL, obwinmat)) - continue; - - /* for each strand in this bounding box */ - for (a=sbound->start; a<sbound->end; a++) { - strand= RE_findOrAddStrand(obr, a); - - sseg.obi= obi; - sseg.buffer= strand->buffer; - sseg.sqadaptcos= sseg.buffer->adaptcos; - sseg.sqadaptcos *= sseg.sqadaptcos; - sseg.strand= strand; - svert= strand->vert; - - /* note, these conditions are copied in shadowbuf_autoclip() */ - if (sseg.buffer->ma!= ma) { - ma= sseg.buffer->ma; - ok= 1; - if ((ma->mode2 & MA_CASTSHADOW)==0 || (ma->mode & MA_SHADBUF)==0) ok= 0; - } - - if (ok && (sseg.buffer->lay & lay)) { - zbuf_project_cache_clear(cache, strand->totvert); - - for (b=0; b<strand->totvert-1; b++, svert++) { - sseg.v[0]= (b > 0)? (svert-1): svert; - sseg.v[1]= svert; - sseg.v[2]= svert+1; - sseg.v[3]= (b < strand->totvert-2)? svert+2: svert+1; - - c1= zbuf_shadow_project(cache, sseg.v[0]-strand->vert, obwinmat, sseg.v[0]->co, ho1); - c2= zbuf_shadow_project(cache, sseg.v[1]-strand->vert, obwinmat, sseg.v[1]->co, ho2); - c3= zbuf_shadow_project(cache, sseg.v[2]-strand->vert, obwinmat, sseg.v[2]->co, ho3); - c4= zbuf_shadow_project(cache, sseg.v[3]-strand->vert, obwinmat, sseg.v[3]->co, ho4); - - if (!(c1 & c2 & c3 & c4)) - render_strand_segment(re, winmat, NULL, &zspan, 1, &sseg); - } - } - - if ((a & 255)==255 && re->test_break(re->tbh)) - break; - } - } - } - - if (re->test_break(re->tbh)) - break; - } - - /* merge buffers */ - if (lar->buftype==LA_SHADBUF_HALFWAY) { - for (a=size*size -1; a>=0; a--) - rectz[a]= (rectz[a]>>1) + (zspan.rectz1[a]>>1); - - MEM_freeN(zspan.rectz1); - } - - zbuf_free_span(&zspan); -} - -static void zbuffill_sss(ZSpan *zspan, int obi, int zvlnr, - const float *v1, const float *v2, const float *v3, const float *v4) -{ - double zxd, zyd, zy0, z; - float x0, y0, x1, y1, x2, y2, z0, z1, z2, xx1, *span1, *span2; - int x, y, sn1, sn2, rectx= zspan->rectx, my0, my2; - /* init */ - zbuf_init_span(zspan); - - /* set spans */ - zbuf_add_to_span(zspan, v1, v2); - zbuf_add_to_span(zspan, v2, v3); - if (v4) { - zbuf_add_to_span(zspan, v3, v4); - zbuf_add_to_span(zspan, v4, v1); - } - else - zbuf_add_to_span(zspan, v3, v1); - - /* clipped */ - if (zspan->minp2==NULL || zspan->maxp2==NULL) return; - - my0 = max_ii(zspan->miny1, zspan->miny2); - my2 = min_ii(zspan->maxy1, zspan->maxy2); - - if (my2<my0) return; - - /* ZBUF DX DY, in floats still */ - x1= v1[0]- v2[0]; - x2= v2[0]- v3[0]; - y1= v1[1]- v2[1]; - y2= v2[1]- v3[1]; - z1= v1[2]- v2[2]; - z2= v2[2]- v3[2]; - - x0= y1*z2-z1*y2; - y0= z1*x2-x1*z2; - z0= x1*y2-y1*x2; - - if (z0==0.0f) return; - - xx1= (x0*v1[0] + y0*v1[1])/z0 + v1[2]; - zxd= -(double)x0/(double)z0; - zyd= -(double)y0/(double)z0; - zy0= ((double)my2)*zyd + (double)xx1; - - /* correct span */ - sn1= (my0 + my2)/2; - if (zspan->span1[sn1] < zspan->span2[sn1]) { - span1= zspan->span1+my2; - span2= zspan->span2+my2; - } - else { - span1= zspan->span2+my2; - span2= zspan->span1+my2; - } - - for (y=my2; y>=my0; y--, span1--, span2--) { - sn1= floor(*span1); - sn2= floor(*span2); - sn1++; - - if (sn2>=rectx) sn2= rectx-1; - if (sn1<0) sn1= 0; - - z= (double)sn1*zxd + zy0; - - for (x= sn1; x<=sn2; x++, z+=zxd) - zspan->sss_func(zspan->sss_handle, obi, zvlnr, x, y, z); - - zy0 -= zyd; - } -} - -void zbuffer_sss(RenderPart *pa, unsigned int lay, void *handle, void (*func)(void *, int, int, int, int, int)) -{ - ZbufProjectCache cache[ZBUF_PROJECT_CACHE_SIZE]; - ZSpan zspan; - ObjectInstanceRen *obi; - ObjectRen *obr; - VlakRen *vlr= NULL; - VertRen *v1, *v2, *v3, *v4; - Material *ma = NULL, *sss_ma = R.sss_mat; - float obwinmat[4][4], winmat[4][4], bounds[4]; - float ho1[4], ho2[4], ho3[4], ho4[4]={0}; - int i, v, zvlnr, c1, c2, c3, c4=0; - short nofill=0, env=0, wire=0; - - zbuf_make_winmat(&R, winmat); - zbuffer_part_bounds(R.winx, R.winy, pa, bounds); - zbuf_alloc_span(&zspan, pa->rectx, pa->recty, R.clipcrop); - - zspan.sss_handle= handle; - zspan.sss_func= func; - - /* needed for transform from hoco to zbuffer co */ - zspan.zmulx= ((float)R.winx)/2.0f; - zspan.zmuly= ((float)R.winy)/2.0f; - - /* -0.5f to center the sample position */ - zspan.zofsx= -pa->disprect.xmin - 0.5f; - zspan.zofsy= -pa->disprect.ymin - 0.5f; - - /* filling methods */ - zspan.zbuffunc= zbuffill_sss; - - /* fill front and back zbuffer */ - if (pa->rectz) { - fillrect(pa->recto, pa->rectx, pa->recty, 0); - fillrect(pa->rectp, pa->rectx, pa->recty, 0); - fillrect(pa->rectz, pa->rectx, pa->recty, 0x7FFFFFFF); - } - if (pa->rectbackz) { - fillrect(pa->rectbacko, pa->rectx, pa->recty, 0); - fillrect(pa->rectbackp, pa->rectx, pa->recty, 0); - fillrect(pa->rectbackz, pa->rectx, pa->recty, -0x7FFFFFFF); - } - - for (i=0, obi=R.instancetable.first; obi; i++, obi=obi->next) { - obr= obi->obr; - - if (!(obi->lay & lay)) - continue; - - if (obi->flag & R_TRANSFORMED) - mul_m4_m4m4(obwinmat, winmat, obi->mat); - else - copy_m4_m4(obwinmat, winmat); - - if (clip_render_object(obi->obr->boundbox, bounds, obwinmat)) - continue; - - zbuf_project_cache_clear(cache, obr->totvert); - - for (v=0; v<obr->totvlak; v++) { - if ((v & 255)==0) vlr= obr->vlaknodes[v>>8].vlak; - else vlr++; - - if (material_in_material(vlr->mat, sss_ma)) { - /* three cases, visible for render, only z values and nothing */ - if (obi->lay & lay) { - if (vlr->mat!=ma) { - ma= vlr->mat; - nofill= ma->mode & MA_ONLYCAST; - env= (ma->mode & MA_ENV); - wire= (ma->material_type == MA_TYPE_WIRE); - } - } - else { - nofill= 1; - ma= NULL; /* otherwise nofill can hang */ - } - - if (nofill==0 && wire==0 && env==0) { - unsigned short partclip; - - v1= vlr->v1; - v2= vlr->v2; - v3= vlr->v3; - v4= vlr->v4; - - c1= zbuf_part_project(cache, v1->index, obwinmat, bounds, v1->co, ho1); - c2= zbuf_part_project(cache, v2->index, obwinmat, bounds, v2->co, ho2); - c3= zbuf_part_project(cache, v3->index, obwinmat, bounds, v3->co, ho3); - - /* partclipping doesn't need viewplane clipping */ - partclip= c1 & c2 & c3; - if (v4) { - c4= zbuf_part_project(cache, v4->index, obwinmat, bounds, v4->co, ho4); - partclip &= c4; - } - - if (partclip==0) { - c1= testclip(ho1); - c2= testclip(ho2); - c3= testclip(ho3); - - zvlnr= v+1; - zbufclip(&zspan, i, zvlnr, ho1, ho2, ho3, c1, c2, c3); - if (v4) { - c4= testclip(ho4); - zbufclip(&zspan, i, zvlnr+RE_QUAD_OFFS, ho1, ho3, ho4, c1, c3, c4); - } - } - } - } - } - } - - zbuf_free_span(&zspan); -} - -/* ******************** ABUF ************************* */ - -/** - * Copy results from the solid face z buffering to the transparent - * buffer. - */ -static void copyto_abufz(RenderPart *pa, int *arectz, int *rectmask, int sample) -{ - PixStr *ps; - int x, y, *rza, *rma; - intptr_t *rd; - - if (R.osa==0) { - if (!pa->rectz) - fillrect(arectz, pa->rectx, pa->recty, 0x7FFFFFFE); - else - memcpy(arectz, pa->rectz, sizeof(int)*pa->rectx*pa->recty); - - if (rectmask && pa->rectmask) - memcpy(rectmask, pa->rectmask, sizeof(int)*pa->rectx*pa->recty); - - return; - } - else if (!pa->rectdaps) { - fillrect(arectz, pa->rectx, pa->recty, 0x7FFFFFFE); - return; - } - - rza= arectz; - rma= rectmask; - rd= pa->rectdaps; - - sample= (1<<sample); - - for (y=0; y<pa->recty; y++) { - for (x=0; x<pa->rectx; x++) { - - *rza= 0x7FFFFFFF; - if (rectmask) *rma= 0x7FFFFFFF; - if (*rd) { - /* when there's a sky pixstruct, fill in sky-Z, otherwise solid Z */ - for (ps= (PixStr *)(*rd); ps; ps= ps->next) { - if (sample & ps->mask) { - *rza= ps->z; - if (rectmask) *rma= ps->maskz; - break; - } - } - } - - rza++; - rma++; - rd++; - } - } -} - - -/* ------------------------------------------------------------------------ */ - -/** - * Do accumulation z buffering. - */ - -static int zbuffer_abuf(Render *re, RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase, unsigned int lay, int negzmask, float winmat[4][4], int winx, int winy, int samples, float (*jit)[2], float UNUSED(clipcrop), int shadow) -{ - ZbufProjectCache cache[ZBUF_PROJECT_CACHE_SIZE]; - ZSpan zspans[16], *zspan; /* MAX_OSA */ - Material *ma=NULL; - ObjectInstanceRen *obi; - ObjectRen *obr; - VlakRen *vlr=NULL; - VertRen *v1, *v2, *v3, *v4; - float vec[3], hoco[4], mul, zval, fval; - float obwinmat[4][4], bounds[4], ho1[4], ho2[4], ho3[4], ho4[4]={0}; - int i, v, zvlnr, c1, c2, c3, c4=0, dofill= 0; - int zsample, polygon_offset; - - zbuffer_part_bounds(winx, winy, pa, bounds); - - for (zsample=0; zsample<samples; zsample++) { - zspan= &zspans[zsample]; - - zbuf_alloc_span(zspan, pa->rectx, pa->recty, re->clipcrop); - - /* needed for transform from hoco to zbuffer co */ - zspan->zmulx= ((float)winx)/2.0f; - zspan->zmuly= ((float)winy)/2.0f; - - /* the buffers */ - zspan->arectz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "Arectz"); - zspan->apixbuf= APixbuf; - zspan->apsmbase= apsmbase; - - if (negzmask) - zspan->rectmask= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "Arectmask"); - - /* filling methods */ - zspan->zbuffunc= zbuffillAc4; - zspan->zbuflinefunc= zbuflineAc; - - copyto_abufz(pa, zspan->arectz, zspan->rectmask, zsample); /* init zbuffer */ - zspan->mask= 1<<zsample; - - if (jit) { - zspan->zofsx= -pa->disprect.xmin - jit[zsample][0]; - zspan->zofsy= -pa->disprect.ymin - jit[zsample][1]; - } - else { - zspan->zofsx= -pa->disprect.xmin; - zspan->zofsy= -pa->disprect.ymin; - } - - /* to center the sample position */ - zspan->zofsx -= 0.5f; - zspan->zofsy -= 0.5f; - } - - /* we use this to test if nothing was filled in */ - zvlnr= 0; - - for (i=0, obi=re->instancetable.first; obi; i++, obi=obi->next) { - obr= obi->obr; - - if (!(obi->lay & lay)) - continue; - - if (obi->flag & R_TRANSFORMED) - mul_m4_m4m4(obwinmat, winmat, obi->mat); - else - copy_m4_m4(obwinmat, winmat); - - if (clip_render_object(obi->obr->boundbox, bounds, obwinmat)) - continue; - - zbuf_project_cache_clear(cache, obr->totvert); - - for (v=0; v<obr->totvlak; v++) { - if ((v & 255)==0) - vlr= obr->vlaknodes[v>>8].vlak; - else vlr++; - - if (vlr->mat!=ma) { - ma= vlr->mat; - if (shadow) - dofill= (ma->mode2 & MA_CASTSHADOW) && (ma->mode & MA_SHADBUF); - else - dofill= (((ma->mode & MA_TRANSP) && (ma->mode & MA_ZTRANSP)) && !(ma->mode & MA_ONLYCAST)); - } - - if (dofill) { - if (!(vlr->flag & R_HIDDEN) && (obi->lay & lay)) { - unsigned short partclip; - - v1= vlr->v1; - v2= vlr->v2; - v3= vlr->v3; - v4= vlr->v4; - - c1= zbuf_part_project(cache, v1->index, obwinmat, bounds, v1->co, ho1); - c2= zbuf_part_project(cache, v2->index, obwinmat, bounds, v2->co, ho2); - c3= zbuf_part_project(cache, v3->index, obwinmat, bounds, v3->co, ho3); - - /* partclipping doesn't need viewplane clipping */ - partclip= c1 & c2 & c3; - if (v4) { - c4= zbuf_part_project(cache, v4->index, obwinmat, bounds, v4->co, ho4); - partclip &= c4; - } - - if (partclip==0) { - /* a little advantage for transp rendering (a z offset) */ - if (!shadow && ma->zoffs != 0.0f) { - mul= 0x7FFFFFFF; - zval= mul*(1.0f+ho1[2]/ho1[3]); - - copy_v3_v3(vec, v1->co); - /* z is negative, otherwise its being clipped */ - vec[2]-= ma->zoffs; - projectverto(vec, obwinmat, hoco); - fval= mul*(1.0f+hoco[2]/hoco[3]); - - polygon_offset= (int)fabsf(zval - fval); - } - else polygon_offset= 0; - - zvlnr= v+1; - - c1= testclip(ho1); - c2= testclip(ho2); - c3= testclip(ho3); - if (v4) - c4= testclip(ho4); - - for (zsample=0; zsample<samples; zsample++) { - zspan= &zspans[zsample]; - zspan->polygon_offset= polygon_offset; - - if (ma->material_type == MA_TYPE_WIRE) { - if (v4) - zbufclipwire(zspan, i, zvlnr, vlr->ec, ho1, ho2, ho3, ho4, c1, c2, c3, c4); - else - zbufclipwire(zspan, i, zvlnr, vlr->ec, ho1, ho2, ho3, NULL, c1, c2, c3, 0); - } - else { - if (v4 && (vlr->flag & R_STRAND)) { - zbufclip4(zspan, i, zvlnr, ho1, ho2, ho3, ho4, c1, c2, c3, c4); - } - else { - zbufclip(zspan, i, zvlnr, ho1, ho2, ho3, c1, c2, c3); - if (v4) - zbufclip(zspan, i, zvlnr+RE_QUAD_OFFS, ho1, ho3, ho4, c1, c3, c4); - } - } - } - } - if ((v & 255)==255) - if (re->test_break(re->tbh)) - break; - } - } - } - - if (re->test_break(re->tbh)) break; - } - - for (zsample=0; zsample<samples; zsample++) { - zspan= &zspans[zsample]; - MEM_freeN(zspan->arectz); - if (zspan->rectmask) - MEM_freeN(zspan->rectmask); - zbuf_free_span(zspan); - } - - return zvlnr; -} - -static int zbuffer_abuf_render(RenderPart *pa, APixstr *APixbuf, APixstrand *APixbufstrand, ListBase *apsmbase, RenderLayer *rl, StrandShadeCache *sscache) -{ - float winmat[4][4], (*jit)[2]; - int samples, negzmask, doztra= 0; - - samples= (R.osa)? R.osa: 1; - negzmask= ((rl->layflag & SCE_LAY_ZMASK) && (rl->layflag & SCE_LAY_NEG_ZMASK)); - - if (R.osa) - jit= R.jit; - else if (R.i.curblur) - jit= &R.mblur_jit[R.i.curblur-1]; - else - jit= NULL; - - zbuf_make_winmat(&R, winmat); - - if (rl->layflag & SCE_LAY_ZTRA) - doztra+= zbuffer_abuf(&R, pa, APixbuf, apsmbase, (1 << 20) - 1, negzmask, winmat, R.winx, R.winy, samples, jit, R.clipcrop, 0); - if ((rl->layflag & SCE_LAY_STRAND) && APixbufstrand) - doztra+= zbuffer_strands_abuf(&R, pa, APixbufstrand, apsmbase, (1 << 20) - 1, negzmask, winmat, R.winx, R.winy, samples, jit, R.clipcrop, 0, sscache); - - return doztra; -} - -void zbuffer_abuf_shadow(Render *re, LampRen *lar, float winmat[4][4], APixstr *APixbuf, APixstrand *APixbufstrand, ListBase *apsmbase, int size, int samples, float (*jit)[2]) -{ - RenderPart pa; - int lay= -1; - - if (lar->mode & LA_LAYER) lay= lar->lay; - - memset(&pa, 0, sizeof(RenderPart)); - pa.rectx= size; - pa.recty= size; - pa.disprect.xmin = 0; - pa.disprect.ymin = 0; - pa.disprect.xmax = size; - pa.disprect.ymax = size; - - zbuffer_abuf(re, &pa, APixbuf, apsmbase, lay, 0, winmat, size, size, samples, jit, 1.0f, 1); - if (APixbufstrand) - zbuffer_strands_abuf(re, &pa, APixbufstrand, apsmbase, lay, 0, winmat, size, size, samples, jit, 1.0f, 1, NULL); -} - -/* different rules for speed in transparent pass... */ -/* speed pointer NULL = sky, we clear */ -/* else if either alpha is full or no solid was filled in: copy speed */ -/* else fill in minimum speed */ -static void add_transp_speed(RenderLayer *rl, int offset, float speed[4], float alpha, intptr_t *rdrect) -{ - RenderPass *rpass; - - for (rpass= rl->passes.first; rpass; rpass= rpass->next) { - if (STREQ(rpass->name, RE_PASSNAME_VECTOR)) { - float *fp= rpass->rect + 4*offset; - - if (speed==NULL) { - /* clear */ - if (fp[0]==PASS_VECTOR_MAX) fp[0]= 0.0f; - if (fp[1]==PASS_VECTOR_MAX) fp[1]= 0.0f; - if (fp[2]==PASS_VECTOR_MAX) fp[2]= 0.0f; - if (fp[3]==PASS_VECTOR_MAX) fp[3]= 0.0f; - } - else if (rdrect==NULL || rdrect[offset]==0 || alpha>0.95f) { - copy_v4_v4(fp, speed); - } - else { - /* add minimum speed in pixel */ - if ( (ABS(speed[0]) + ABS(speed[1]))< (ABS(fp[0]) + ABS(fp[1])) ) { - fp[0]= speed[0]; - fp[1]= speed[1]; - } - if ( (ABS(speed[2]) + ABS(speed[3]))< (ABS(fp[2]) + ABS(fp[3])) ) { - fp[2]= speed[2]; - fp[3]= speed[3]; - } - } - break; - } - } -} - -static void add_transp_obindex(RenderLayer *rl, int offset, Object *ob) -{ - RenderPass *rpass; - - for (rpass= rl->passes.first; rpass; rpass= rpass->next) { - if (STREQ(rpass->name, RE_PASSNAME_INDEXOB)) { - float *fp= rpass->rect + offset; - *fp= (float)ob->index; - break; - } - } -} - -static void add_transp_material_index(RenderLayer *rl, int offset, Material *mat) -{ - RenderPass *rpass; - - for (rpass= rl->passes.first; rpass; rpass= rpass->next) { - if (STREQ(rpass->name, RE_PASSNAME_INDEXMA)) { - float *fp= rpass->rect + offset; - *fp= (float)mat->index; - break; - } - } -} - -/* ONLY OSA! merge all shaderesult samples to one */ -/* target should have been cleared */ -static void merge_transp_passes(RenderLayer *rl, ShadeResult *shr) -{ - RenderPass *rpass; - float weight= 1.0f/((float)R.osa); - int delta= sizeof(ShadeResult)/4; - - for (rpass= rl->passes.first; rpass; rpass= rpass->next) { - float *col = NULL; - int pixsize = 3; - - if (STREQ(rpass->name, RE_PASSNAME_RGBA)) { - col = shr->col; - pixsize = 4; - } - else if (STREQ(rpass->name, RE_PASSNAME_EMIT)) { - col = shr->emit; - } - else if (STREQ(rpass->name, RE_PASSNAME_DIFFUSE)) { - col = shr->diff; - } - else if (STREQ(rpass->name, RE_PASSNAME_SPEC)) { - col = shr->spec; - } - else if (STREQ(rpass->name, RE_PASSNAME_SHADOW)) { - col = shr->shad; - } - else if (STREQ(rpass->name, RE_PASSNAME_AO)) { - col = shr->ao; - } - else if (STREQ(rpass->name, RE_PASSNAME_ENVIRONMENT)) { - col = shr->env; - } - else if (STREQ(rpass->name, RE_PASSNAME_INDIRECT)) { - col = shr->indirect; - } - else if (STREQ(rpass->name, RE_PASSNAME_REFLECT)) { - col = shr->refl; - } - else if (STREQ(rpass->name, RE_PASSNAME_REFRACT)) { - col = shr->refr; - } - else if (STREQ(rpass->name, RE_PASSNAME_NORMAL)) { - col = shr->nor; - } - else if (STREQ(rpass->name, RE_PASSNAME_MIST)) { - col = &shr->mist; - pixsize = 1; - } - else if (STREQ(rpass->name, RE_PASSNAME_Z)) { - col = &shr->z; - pixsize = 1; - } - else if (STREQ(rpass->name, RE_PASSNAME_VECTOR)) { - ShadeResult *shr_t = shr+1; - float *fp = shr->winspeed; /* was initialized */ - int samp; - - /* add minimum speed in pixel */ - for (samp = 1; samp<R.osa; samp++, shr_t++) { - - if (shr_t->combined[3] > 0.0f) { - const float *speed = shr_t->winspeed; - - if ( (ABS(speed[0]) + ABS(speed[1]))< (ABS(fp[0]) + ABS(fp[1])) ) { - fp[0] = speed[0]; - fp[1] = speed[1]; - } - if ( (ABS(speed[2]) + ABS(speed[3]))< (ABS(fp[2]) + ABS(fp[3])) ) { - fp[2] = speed[2]; - fp[3] = speed[3]; - } - } - } - } - - if (col) { - const float *fp= col+delta; - int samp; - - for (samp= 1; samp<R.osa; samp++, fp+=delta) { - col[0]+= fp[0]; - if (pixsize>1) { - col[1]+= fp[1]; - col[2]+= fp[2]; - if (pixsize==4) col[3]+= fp[3]; - } - } - col[0]*= weight; - if (pixsize>1) { - col[1]*= weight; - col[2]*= weight; - if (pixsize==4) col[3]*= weight; - } - } - } - -} - -static void add_transp_passes(RenderLayer *rl, int offset, ShadeResult *shr, float alpha) -{ - RenderPass *rpass; - - for (rpass= rl->passes.first; rpass; rpass= rpass->next) { - float *fp, *col= NULL; - int pixsize= 3; - - if (STREQ(rpass->name, RE_PASSNAME_Z)) { - fp = rpass->rect + offset; - if (shr->z < *fp) - *fp = shr->z; - } - else if (STREQ(rpass->name, RE_PASSNAME_RGBA)) { - fp = rpass->rect + 4*offset; - addAlphaOverFloat(fp, shr->col); - } - else if (STREQ(rpass->name, RE_PASSNAME_EMIT)) { - col = shr->emit; - } - else if (STREQ(rpass->name, RE_PASSNAME_DIFFUSE)) { - col = shr->diff; - } - else if (STREQ(rpass->name, RE_PASSNAME_SPEC)) { - col = shr->spec; - } - else if (STREQ(rpass->name, RE_PASSNAME_SHADOW)) { - col = shr->shad; - } - else if (STREQ(rpass->name, RE_PASSNAME_AO)) { - col = shr->ao; - } - else if (STREQ(rpass->name, RE_PASSNAME_ENVIRONMENT)) { - col = shr->env; - } - else if (STREQ(rpass->name, RE_PASSNAME_INDIRECT)) { - col = shr->indirect; - } - else if (STREQ(rpass->name, RE_PASSNAME_REFLECT)) { - col = shr->refl; - } - else if (STREQ(rpass->name, RE_PASSNAME_REFRACT)) { - col = shr->refr; - } - else if (STREQ(rpass->name, RE_PASSNAME_NORMAL)) { - col = shr->nor; - } - else if (STREQ(rpass->name, RE_PASSNAME_MIST)) { - col = &shr->mist; - pixsize = 1; - } - - if (col) { - fp= rpass->rect + pixsize*offset; - fp[0]= col[0] + (1.0f-alpha)*fp[0]; - if (pixsize==3) { - fp[1]= col[1] + (1.0f-alpha)*fp[1]; - fp[2]= col[2] + (1.0f-alpha)*fp[2]; - } - } - } -} - -typedef struct ZTranspRow { - int obi; - int z; - int p; - int mask; - int segment; - float u, v; -} ZTranspRow; - -static int vergzvlak(const void *a1, const void *a2) -{ - const ZTranspRow *r1 = a1, *r2 = a2; - - if (r1->z < r2->z) return 1; - else if (r1->z > r2->z) return -1; - return 0; -} - -static void shade_strand_samples(StrandShadeCache *cache, ShadeSample *ssamp, int UNUSED(x), int UNUSED(y), ZTranspRow *row, int addpassflag) -{ - StrandSegment sseg; - StrandVert *svert; - ObjectInstanceRen *obi; - ObjectRen *obr; - - obi= R.objectinstance + row->obi; - obr= obi->obr; - - sseg.obi= obi; - sseg.strand= RE_findOrAddStrand(obr, row->p-1); - sseg.buffer= sseg.strand->buffer; - - svert= sseg.strand->vert + row->segment; - sseg.v[0]= (row->segment > 0)? (svert-1): svert; - sseg.v[1]= svert; - sseg.v[2]= svert+1; - sseg.v[3]= (row->segment < sseg.strand->totvert-2)? svert+2: svert+1; - - ssamp->tot= 1; - strand_shade_segment(&R, cache, &sseg, ssamp, row->v, row->u, addpassflag); - ssamp->shi[0].mask= row->mask; -} - -static void unref_strand_samples(StrandShadeCache *cache, ZTranspRow *row, int totface) -{ - StrandVert *svert; - ObjectInstanceRen *obi; - ObjectRen *obr; - StrandRen *strand; - - /* remove references to samples that are not being rendered, but we still - * need to remove them so that the reference count of strand vertex shade - * samples correctly drops to zero */ - while (totface > 0) { - totface--; - - if (row[totface].segment != -1) { - obi= R.objectinstance + row[totface].obi; - obr= obi->obr; - strand= RE_findOrAddStrand(obr, row[totface].p-1); - svert= strand->vert + row[totface].segment; - - strand_shade_unref(cache, obi, svert); - strand_shade_unref(cache, obi, svert+1); - } - } -} - -static void shade_tra_samples_fill(ShadeSample *ssamp, int x, int y, int z, int obi, int facenr, int curmask) -{ - ShadeInput *shi= ssamp->shi; - float xs, ys; - - ssamp->tot= 0; - - shade_input_set_triangle(shi, obi, facenr, 1); - - /* officially should always be true... we have no sky info */ - if (shi->vlr) { - - /* full osa is only set for OSA renders */ - if (shi->vlr->flag & R_FULL_OSA) { - short shi_inc= 0, samp; - - for (samp=0; samp<R.osa; samp++) { - if (curmask & (1<<samp)) { - xs= (float)x + R.jit[samp][0] + 0.5f; /* zbuffer has this inverse corrected, ensures (xs, ys) are inside pixel */ - ys= (float)y + R.jit[samp][1] + 0.5f; - - if (shi_inc) { - shade_input_copy_triangle(shi+1, shi); - shi++; - } - shi->mask= (1<<samp); - shi->samplenr= R.shadowsamplenr[shi->thread]++; - shade_input_set_viewco(shi, x, y, xs, ys, (float)z); - shade_input_set_uv(shi); - if (shi_inc==0) - shade_input_set_normals(shi); - else /* XXX shi->flippednor messes up otherwise */ - shade_input_set_vertex_normals(shi); - - shi_inc= 1; - } - } - } - else { - if (R.osa) { - short b= R.samples->centmask[curmask]; - xs= (float)x + R.samples->centLut[b & 15] + 0.5f; - ys= (float)y + R.samples->centLut[b>>4] + 0.5f; - } - else if (R.i.curblur) { - xs= (float)x + R.mblur_jit[R.i.curblur-1][0] + 0.5f; - ys= (float)y + R.mblur_jit[R.i.curblur-1][1] + 0.5f; - } - else { - xs= (float)x + 0.5f; - ys= (float)y + 0.5f; - } - shi->mask= curmask; - shi->samplenr= R.shadowsamplenr[shi->thread]++; - shade_input_set_viewco(shi, x, y, xs, ys, (float)z); - shade_input_set_uv(shi); - shade_input_set_normals(shi); - } - - /* total sample amount, shi->sample is static set in initialize */ - ssamp->tot= shi->sample+1; - } -} - -static int shade_tra_samples(ShadeSample *ssamp, StrandShadeCache *cache, int x, int y, ZTranspRow *row, int addpassflag) -{ - if (row->segment != -1) { - shade_strand_samples(cache, ssamp, x, y, row, addpassflag); - return 1; - } - - shade_tra_samples_fill(ssamp, x, y, row->z, row->obi, row->p, row->mask); - - if (ssamp->tot) { - ShadeInput *shi= ssamp->shi; - ShadeResult *shr= ssamp->shr; - int samp; - - /* if AO? */ - shade_samples_do_AO(ssamp); - - /* if shade (all shadepinputs have same passflag) */ - if (shi->passflag & ~(SCE_PASS_Z|SCE_PASS_INDEXOB|SCE_PASS_INDEXMA)) { - for (samp=0; samp<ssamp->tot; samp++, shi++, shr++) { - shade_input_set_shade_texco(shi); - shade_input_do_shade(shi, shr); - - /* include lamphalos for ztra, since halo layer was added already */ - if (R.flag & R_LAMPHALO) - if (shi->layflag & SCE_LAY_HALO) - renderspothalo(shi, shr->combined, shr->combined[3]); - } - } - else if (shi->passflag & SCE_PASS_Z) { - for (samp=0; samp<ssamp->tot; samp++, shi++, shr++) - shr->z= -shi->co[2]; - } - - return 1; - } - return 0; -} - -static int addtosamp_shr(ShadeResult *samp_shr, ShadeSample *ssamp, int addpassflag) -{ - int a, sample, osa = (R.osa? R.osa: 1), retval = osa; - - for (a=0; a < osa; a++, samp_shr++) { - ShadeInput *shi= ssamp->shi; - ShadeResult *shr= ssamp->shr; - - for (sample=0; sample<ssamp->tot; sample++, shi++, shr++) { - - if (shi->mask & (1<<a)) { - float fac= (1.0f - samp_shr->combined[3])*shr->combined[3]; - - addAlphaUnderFloat(samp_shr->combined, shr->combined); - - samp_shr->z = min_ff(samp_shr->z, shr->z); - - if (addpassflag & SCE_PASS_VECTOR) { - copy_v4_v4(samp_shr->winspeed, shr->winspeed); - } - /* optim... */ - if (addpassflag & ~(SCE_PASS_VECTOR)) { - - if (addpassflag & SCE_PASS_RGBA) - addAlphaUnderFloat(samp_shr->col, shr->col); - - if (addpassflag & SCE_PASS_NORMAL) - madd_v3_v3fl(samp_shr->nor, shr->nor, fac); - - if (addpassflag & SCE_PASS_EMIT) - madd_v3_v3fl(samp_shr->emit, shr->emit, fac); - - if (addpassflag & SCE_PASS_DIFFUSE) - madd_v3_v3fl(samp_shr->diff, shr->diff, fac); - - if (addpassflag & SCE_PASS_SPEC) - madd_v3_v3fl(samp_shr->spec, shr->spec, fac); - - if (addpassflag & SCE_PASS_SHADOW) - madd_v3_v3fl(samp_shr->shad, shr->shad, fac); - - if (addpassflag & SCE_PASS_AO) - madd_v3_v3fl(samp_shr->ao, shr->ao, fac); - - if (addpassflag & SCE_PASS_ENVIRONMENT) - madd_v3_v3fl(samp_shr->env, shr->env, fac); - - if (addpassflag & SCE_PASS_INDIRECT) - madd_v3_v3fl(samp_shr->indirect, shr->indirect, fac); - - if (addpassflag & SCE_PASS_REFLECT) - madd_v3_v3fl(samp_shr->refl, shr->refl, fac); - - if (addpassflag & SCE_PASS_REFRACT) - madd_v3_v3fl(samp_shr->refr, shr->refr, fac); - - if (addpassflag & SCE_PASS_MIST) - samp_shr->mist= samp_shr->mist+fac*shr->mist; - - } - } - } - - if (samp_shr->combined[3]>0.999f) retval--; - } - return retval; -} - -static void reset_sky_speedvectors(RenderPart *pa, RenderLayer *rl, float *rectf) -{ - /* speed vector exception... if solid render was done, sky pixels are set to zero already */ - /* for all pixels with alpha zero, we re-initialize speed again then */ - float *fp, *col; - int a; - - fp = RE_RenderLayerGetPass(rl, RE_PASSNAME_VECTOR, R.viewname); - if (fp==NULL) return; - col= rectf+3; - - for (a= 4*pa->rectx*pa->recty -4; a>=0; a-=4) { - if (col[a]==0.0f) { - fp[a]= PASS_VECTOR_MAX; - fp[a+1]= PASS_VECTOR_MAX; - fp[a+2]= PASS_VECTOR_MAX; - fp[a+3]= PASS_VECTOR_MAX; - } - } -} - -#define MAX_ZROW 2000 - -/* main render call to do the z-transparent layer */ -/* returns a mask, only if a) transp rendered and b) solid was rendered */ -unsigned short *zbuffer_transp_shade(RenderPart *pa, RenderLayer *rl, float *pass, ListBase *UNUSED(psmlist)) -{ - RenderResult *rr= pa->result; - ShadeSample ssamp; - APixstr *APixbuf; /* Zbuffer: linked list of face samples */ - APixstrand *APixbufstrand = NULL; - APixstr *ap, *aprect, *apn; - APixstrand *apstrand, *aprectstrand, *apnstrand; - ListBase apsmbase={NULL, NULL}; - ShadeResult samp_shr[16]; /* MAX_OSA */ - ZTranspRow zrow[MAX_ZROW]; - StrandShadeCache *sscache= NULL; - RenderLayer *rlpp[RE_MAX_OSA]; - float sampalpha, alpha, *passrect= pass; - intptr_t *rdrect; - int x, y, crop=0, a, b, totface, totfullsample, totsample, doztra; - int addpassflag, offs= 0, od, osa = (R.osa? R.osa: 1); - unsigned short *ztramask= NULL, filled; - - /* looks nicer for calling code */ - if (R.test_break(R.tbh)) - return NULL; - - if (R.osa > 16) { /* MAX_OSA */ - printf("zbuffer_transp_shade: osa too large\n"); - G.is_break = true; - return NULL; - } - - APixbuf= MEM_callocN(pa->rectx*pa->recty*sizeof(APixstr), "APixbuf"); - if (R.totstrand && (rl->layflag & SCE_LAY_STRAND)) { - APixbufstrand= MEM_callocN(pa->rectx*pa->recty*sizeof(APixstrand), "APixbufstrand"); - sscache= strand_shade_cache_create(); - } - - /* general shader info, passes */ - shade_sample_initialize(&ssamp, pa, rl); - addpassflag= rl->passflag & ~(SCE_PASS_COMBINED); - - if (R.osa) - sampalpha= 1.0f/(float)R.osa; - else - sampalpha= 1.0f; - - /* fill the Apixbuf */ - doztra= zbuffer_abuf_render(pa, APixbuf, APixbufstrand, &apsmbase, rl, sscache); - - if (doztra == 0) { - /* nothing filled in */ - MEM_freeN(APixbuf); - if (APixbufstrand) - MEM_freeN(APixbufstrand); - if (sscache) - strand_shade_cache_free(sscache); - freepsA(&apsmbase); - return NULL; - } - - aprect= APixbuf; - aprectstrand= APixbufstrand; - rdrect= pa->rectdaps; - - /* needed for correct zbuf/index pass */ - totfullsample= get_sample_layers(pa, rl, rlpp); - - /* irregular shadowb buffer creation */ - if (R.r.mode & R_SHADOW) - ISB_create(pa, APixbuf); - - /* masks, to have correct alpha combine */ - if (R.osa && (rl->layflag & SCE_LAY_SOLID) && pa->fullresult.first==NULL) - ztramask= MEM_callocN(pa->rectx*pa->recty*sizeof(short), "ztramask"); - - /* zero alpha pixels get speed vector max again */ - if (addpassflag & SCE_PASS_VECTOR) - if (rl->layflag & SCE_LAY_SOLID) { - float *rect = RE_RenderLayerGetPass(rl, RE_PASSNAME_COMBINED, R.viewname); - reset_sky_speedvectors(pa, rl, rl->acolrect ? rl->acolrect : rect); /* if acolrect is set we use it */ - } - /* filtered render, for now we assume only 1 filter size */ - if (pa->crop) { - crop= 1; - offs= pa->rectx + 1; - passrect+= 4*offs; - aprect+= offs; - aprectstrand+= offs; - } - - /* init scanline updates */ - rr->renrect.ymin = 0; - rr->renrect.ymax = -pa->crop; - rr->renlay= rl; - - /* render the tile */ - for (y=pa->disprect.ymin+crop; y<pa->disprect.ymax-crop; y++, rr->renrect.ymax++) { - pass= passrect; - ap= aprect; - apstrand= aprectstrand; - od= offs; - - if (R.test_break(R.tbh)) - break; - - for (x=pa->disprect.xmin+crop; x<pa->disprect.xmax-crop; x++, ap++, apstrand++, pass+=4, od++) { - - if (ap->p[0]==0 && (!APixbufstrand || apstrand->p[0]==0)) { - if (addpassflag & SCE_PASS_VECTOR) - add_transp_speed(rl, od, NULL, 0.0f, rdrect); - } - else { - /* sort in z */ - totface= 0; - apn= ap; - while (apn) { - for (a=0; a<4; a++) { - if (apn->p[a]) { - zrow[totface].obi= apn->obi[a]; - zrow[totface].z= apn->z[a]; - zrow[totface].p= apn->p[a]; - zrow[totface].mask= apn->mask[a]; - zrow[totface].segment= -1; - totface++; - if (totface>=MAX_ZROW) totface= MAX_ZROW-1; - } - else break; - } - apn= apn->next; - } - - apnstrand= (APixbufstrand)? apstrand: NULL; - while (apnstrand) { - for (a=0; a<4; a++) { - if (apnstrand->p[a]) { - zrow[totface].obi= apnstrand->obi[a]; - zrow[totface].z= apnstrand->z[a]; - zrow[totface].p= apnstrand->p[a]; - zrow[totface].mask= apnstrand->mask[a]; - zrow[totface].segment= apnstrand->seg[a]; - - if (R.osa) { - totsample= 0; - for (b=0; b<R.osa; b++) - if (zrow[totface].mask & (1<<b)) - totsample++; - } - else - totsample= 1; - - zrow[totface].u= apnstrand->u[a]/totsample; - zrow[totface].v= apnstrand->v[a]/totsample; - totface++; - if (totface>=MAX_ZROW) totface= MAX_ZROW-1; - } - } - apnstrand= apnstrand->next; - } - - if (totface==2) { - if (zrow[0].z < zrow[1].z) { - SWAP(ZTranspRow, zrow[0], zrow[1]); - } - - } - else if (totface>2) { - qsort(zrow, totface, sizeof(ZTranspRow), vergzvlak); - } - - /* front face does index pass for transparent, no AA or filters, but yes FSA */ - if (addpassflag & SCE_PASS_INDEXOB) { - ObjectRen *obr= R.objectinstance[zrow[totface-1].obi].obr; - if (obr->ob) { - for (a= 0; a<totfullsample; a++) - add_transp_obindex(rlpp[a], od, obr->ob); - } - } - if (addpassflag & SCE_PASS_INDEXMA) { - ObjectRen *obr = R.objectinstance[zrow[totface-1].obi].obr; - int p = zrow[totface-1].p; - Material *mat = NULL; - - if (zrow[totface-1].segment == -1) { - int facenr = (p - 1) & RE_QUAD_MASK; - VlakRen *vlr = NULL; - - if (facenr >= 0 && facenr < obr->totvlak) - vlr = RE_findOrAddVlak(obr, facenr); - - if (vlr) - mat = vlr->mat; - } - else { - StrandRen *strand = RE_findOrAddStrand(obr, p - 1); - - if (strand) - mat = strand->buffer->ma; - } - - if (mat) { - for (a= 0; a<totfullsample; a++) - add_transp_material_index(rlpp[a], od, mat); - } - } - - /* for each mask-sample we alpha-under colors. then in end it's added using filter */ - memset(samp_shr, 0, sizeof(ShadeResult)*osa); - for (a=0; a<osa; a++) { - samp_shr[a].z= 10e10f; - if (addpassflag & SCE_PASS_VECTOR) { - samp_shr[a].winspeed[0]= PASS_VECTOR_MAX; - samp_shr[a].winspeed[1]= PASS_VECTOR_MAX; - samp_shr[a].winspeed[2]= PASS_VECTOR_MAX; - samp_shr[a].winspeed[3]= PASS_VECTOR_MAX; - } - } - - if (R.osa==0) { - while (totface>0) { - totface--; - - if (shade_tra_samples(&ssamp, sscache, x, y, &zrow[totface], addpassflag)) { - filled= addtosamp_shr(samp_shr, &ssamp, addpassflag); - addAlphaUnderFloat(pass, ssamp.shr[0].combined); - - if (filled == 0) { - if (sscache) - unref_strand_samples(sscache, zrow, totface); - break; - } - } - } - - alpha= samp_shr->combined[3]; - if (alpha!=0.0f) { - add_transp_passes(rl, od, samp_shr, alpha); - if (addpassflag & SCE_PASS_VECTOR) - add_transp_speed(rl, od, samp_shr->winspeed, alpha, rdrect); - } - } - else { - short *sp= (short *)(ztramask+od); - - while (totface>0) { - totface--; - - if (shade_tra_samples(&ssamp, sscache, x, y, &zrow[totface], addpassflag)) { - filled= addtosamp_shr(samp_shr, &ssamp, addpassflag); - - if (ztramask) - *sp |= zrow[totface].mask; - if (filled==0) { - if (sscache) - unref_strand_samples(sscache, zrow, totface); - break; - } - } - } - - /* multisample buffers or filtered mask filling? */ - if (pa->fullresult.first) { - for (a=0; a<R.osa; a++) { - alpha= samp_shr[a].combined[3]; - if (alpha != 0.0f) { - RenderLayer *rl_other = ssamp.rlpp[a]; - - float *rect = RE_RenderLayerGetPass(rl_other , RE_PASSNAME_COMBINED, R.viewname); - addAlphaOverFloat(rect + 4 * od, samp_shr[a].combined); - - add_transp_passes(rl_other , od, &samp_shr[a], alpha); - if (addpassflag & SCE_PASS_VECTOR) - add_transp_speed(rl_other , od, samp_shr[a].winspeed, alpha, rdrect); - } - } - } - else { - alpha= 0.0f; - - /* note; cannot use pass[3] for alpha due to filtermask */ - for (a=0; a<R.osa; a++) { - add_filt_fmask(1<<a, samp_shr[a].combined, pass, rr->rectx); - alpha+= samp_shr[a].combined[3]; - } - - if (addpassflag) { - alpha*= sampalpha; - - /* merge all in one, and then add */ - merge_transp_passes(rl, samp_shr); - add_transp_passes(rl, od, samp_shr, alpha); - - if (addpassflag & SCE_PASS_VECTOR) - add_transp_speed(rl, od, samp_shr[0].winspeed, alpha, rdrect); - } - } - } - } - } - - aprect+= pa->rectx; - aprectstrand+= pa->rectx; - passrect+= 4*pa->rectx; - offs+= pa->rectx; - } - - /* disable scanline updating */ - rr->renlay= NULL; - - MEM_freeN(APixbuf); - if (APixbufstrand) - MEM_freeN(APixbufstrand); - if (sscache) - strand_shade_cache_free(sscache); - freepsA(&apsmbase); - - if (R.r.mode & R_SHADOW) - ISB_free(pa); - - return ztramask; -} - - /* end of zbuf.c */ diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index e138a880b6e..e30028eb3d3 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -871,13 +871,6 @@ int wm_homefile_read( G.main->name[0] = '\0'; - if (use_userdef) { - /* When loading factory settings, the reset solid OpenGL lights need to be applied. */ - if (!G.background) { - GPU_default_lights(); - } - } - /* start with save preference untitled.blend */ G.save_over = 0; @@ -1010,7 +1003,7 @@ static void wm_history_file_update(void) /* screen can be NULL */ -static ImBuf *blend_file_thumb(const bContext *C, Scene *scene, ViewLayer *view_layer, bScreen *screen, BlendThumbnail **thumb_pt) +static ImBuf *blend_file_thumb(const bContext *C, Scene *scene, bScreen *screen, BlendThumbnail **thumb_pt) { /* will be scaled down, but gives some nice oversampling */ ImBuf *ibuf; @@ -1049,14 +1042,14 @@ static ImBuf *blend_file_thumb(const bContext *C, Scene *scene, ViewLayer *view_ if (scene->camera) { ibuf = ED_view3d_draw_offscreen_imbuf_simple( - depsgraph, scene, view_layer, OB_SOLID, scene->camera, + depsgraph, scene, OB_SOLID, scene->camera, BLEN_THUMB_SIZE * 2, BLEN_THUMB_SIZE * 2, IB_rect, V3D_OFSDRAW_NONE, R_ALPHAPREMUL, 0, NULL, NULL, err_out); } else { ibuf = ED_view3d_draw_offscreen_imbuf( - depsgraph, scene, view_layer, OB_SOLID, v3d, ar, + depsgraph, scene, OB_SOLID, v3d, ar, BLEN_THUMB_SIZE * 2, BLEN_THUMB_SIZE * 2, IB_rect, V3D_OFSDRAW_NONE, R_ALPHAPREMUL, 0, NULL, NULL, err_out); @@ -1152,7 +1145,7 @@ static int wm_file_write(bContext *C, const char *filepath, int fileflags, Repor /* Main now can store a .blend thumbnail, usefull for background mode or thumbnail customization. */ main_thumb = thumb = CTX_data_main(C)->blen_thumb; if ((U.flag & USER_SAVE_PREVIEWS) && BLI_thread_is_main()) { - ibuf_thumb = blend_file_thumb(C, CTX_data_scene(C), CTX_data_view_layer(C), CTX_wm_screen(C), &thumb); + ibuf_thumb = blend_file_thumb(C, CTX_data_scene(C), CTX_wm_screen(C), &thumb); } /* operator now handles overwrite checks */ diff --git a/source/blender/windowmanager/intern/wm_files_link.c b/source/blender/windowmanager/intern/wm_files_link.c index a33df1bc1f2..97f738f37da 100644 --- a/source/blender/windowmanager/intern/wm_files_link.c +++ b/source/blender/windowmanager/intern/wm_files_link.c @@ -76,8 +76,6 @@ #include "ED_screen.h" -#include "GPU_material.h" - #include "RNA_access.h" #include "RNA_define.h" diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index 2af478b9470..0317c138e9c 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -118,7 +118,6 @@ #include "BLT_lang.h" #include "GPU_material.h" -#include "GPU_buffers.h" #include "GPU_draw.h" #include "GPU_init_exit.h" @@ -467,7 +466,6 @@ void WM_exit_ext(bContext *C, const bool do_python) BKE_subsurf_osd_cleanup(); #endif - GPU_global_buffer_pool_free(); GPU_free_unused_buffers(); GPU_exit(); |