Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTon Roosendaal <ton@blender.org>2018-04-19 18:34:44 +0300
committerBrecht Van Lommel <brechtvanlommel@gmail.com>2018-04-19 18:35:25 +0300
commit51b796ff1528c52cc8b4079fab1003671652a4d9 (patch)
tree0dfc2d2dabe5e77959264f5b6667897569290a41 /source/blender
parent785e8a636a293941a4295e669cb5aeecfafae039 (diff)
Remove Blender Internal and legacy viewport from Blender 2.8.
Brecht authored this commit, but he gave me the honours to actually do it. Here it goes; Blender Internal. Bye bye, you did great! * Point density, voxel data, ocean, environment map textures were removed, as these only worked within BI rendering. Note that the ocean modifier and the Cycles point density shader node continue to work. * Dynamic paint using material shading was removed, as this only worked with BI. If we ever wanted to support this again probably it should go through the baking API. * GPU shader export through the Python API was removed. This only worked for the old BI GLSL shaders, which no longer exists. Doing something similar for Eevee would be significantly more complicated because it uses a lot of multiplass rendering and logic outside the shader, it's probably impractical. * Collada material import / export code is mostly gone, as it only worked for BI materials. We need to add Cycles / Eevee material support at some point. * The mesh noise operator was removed since it only worked with BI material texture slots. A displacement modifier can be used instead. * The delete texture paint slot operator was removed since it only worked for BI material texture slots. Could be added back with node support. * Not all legacy viewport features are supported in the new viewport, but their code was removed. If we need to bring anything back we can look at older git revisions. * There is some legacy viewport code that I could not remove yet, and some that I probably missed. * Shader node execution code was left mostly intact, even though it is not used anywhere now. We may eventually use this to replace the texture nodes with Cycles / Eevee shader nodes. * The Cycles Bake panel now includes settings for baking multires normal and displacement maps. The underlying code needs to be merged properly, and we plan to add back support for multires AO baking and add support to Cycles baking for features like vertex color, displacement, and other missing baking features. * This commit removes DNA and the Python API for BI material, lamp, world and scene settings. This breaks a lot of addons. * There is more DNA that can be removed or renamed, where Cycles or Eevee are reusing some old BI properties but the names are not really correct anymore. * Texture slots for materials, lamps and world were removed. They remain for brushes, particles and freestyle linestyles. * 'BLENDER_RENDER' remains in the COMPAT_ENGINES of UI panels. Cycles and other renderers use this to find all panels to show, minus a few panels that they have their own replacement for.
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/alembic/intern/abc_hair.cc4
-rw-r--r--source/blender/blenkernel/BKE_DerivedMesh.h133
-rw-r--r--source/blender/blenkernel/BKE_blender_version.h2
-rw-r--r--source/blender/blenkernel/BKE_camera.h5
-rw-r--r--source/blender/blenkernel/BKE_material.h11
-rw-r--r--source/blender/blenkernel/BKE_node.h22
-rw-r--r--source/blender/blenkernel/BKE_particle.h8
-rw-r--r--source/blender/blenkernel/BKE_pbvh.h6
-rw-r--r--source/blender/blenkernel/BKE_scene.h6
-rw-r--r--source/blender/blenkernel/BKE_sequencer.h2
-rw-r--r--source/blender/blenkernel/BKE_texture.h26
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c412
-rw-r--r--source/blender/blenkernel/intern/anim_sys.c32
-rw-r--r--source/blender/blenkernel/intern/bpath.c8
-rw-r--r--source/blender/blenkernel/intern/camera.c15
-rw-r--r--source/blender/blenkernel/intern/cdderivedmesh.c1345
-rw-r--r--source/blender/blenkernel/intern/dynamicpaint.c164
-rw-r--r--source/blender/blenkernel/intern/editderivedmesh.c662
-rw-r--r--source/blender/blenkernel/intern/ipo.c14
-rw-r--r--source/blender/blenkernel/intern/lamp.c46
-rw-r--r--source/blender/blenkernel/intern/library_query.c27
-rw-r--r--source/blender/blenkernel/intern/material.c546
-rw-r--r--source/blender/blenkernel/intern/node.c77
-rw-r--r--source/blender/blenkernel/intern/object.c3
-rw-r--r--source/blender/blenkernel/intern/object_dupli.c5
-rw-r--r--source/blender/blenkernel/intern/particle.c71
-rw-r--r--source/blender/blenkernel/intern/particle_child.c40
-rw-r--r--source/blender/blenkernel/intern/particle_distribute.c6
-rw-r--r--source/blender/blenkernel/intern/particle_system.c4
-rw-r--r--source/blender/blenkernel/intern/pbvh.c67
-rw-r--r--source/blender/blenkernel/intern/scene.c58
-rw-r--r--source/blender/blenkernel/intern/sequencer.c9
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c1979
-rw-r--r--source/blender/blenkernel/intern/texture.c439
-rw-r--r--source/blender/blenkernel/intern/world.c34
-rw-r--r--source/blender/blenkernel/intern/writeffmpeg.c11
-rw-r--r--source/blender/blenloader/intern/readfile.c117
-rw-r--r--source/blender/blenloader/intern/versioning_250.c273
-rw-r--r--source/blender/blenloader/intern/versioning_260.c58
-rw-r--r--source/blender/blenloader/intern/versioning_270.c41
-rw-r--r--source/blender/blenloader/intern/versioning_280.c29
-rw-r--r--source/blender/blenloader/intern/versioning_legacy.c355
-rw-r--r--source/blender/blenloader/intern/writefile.c44
-rw-r--r--source/blender/collada/DocumentExporter.cpp1
-rw-r--r--source/blender/collada/DocumentImporter.cpp146
-rw-r--r--source/blender/collada/DocumentImporter.h1
-rw-r--r--source/blender/collada/EffectExporter.cpp157
-rw-r--r--source/blender/collada/EffectExporter.h5
-rw-r--r--source/blender/collada/ImageExporter.cpp18
-rw-r--r--source/blender/collada/LightExporter.cpp26
-rw-r--r--source/blender/collada/MeshImporter.cpp64
-rw-r--r--source/blender/collada/MeshImporter.h10
-rw-r--r--source/blender/collada/collada_utils.cpp124
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.cc18
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.h1
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.cc17
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.h1
-rw-r--r--source/blender/draw/intern/draw_manager_shader.c6
-rw-r--r--source/blender/draw/modes/object_mode.c6
-rw-r--r--source/blender/editors/animation/anim_filter.c18
-rw-r--r--source/blender/editors/include/ED_buttons.h10
-rw-r--r--source/blender/editors/include/ED_render.h1
-rw-r--r--source/blender/editors/include/ED_uvedit.h2
-rw-r--r--source/blender/editors/include/ED_view3d.h17
-rw-r--r--source/blender/editors/io/io_collada.c1
-rw-r--r--source/blender/editors/mesh/editface.c6
-rw-r--r--source/blender/editors/mesh/editmesh_tools.c78
-rw-r--r--source/blender/editors/mesh/mesh_data.c3
-rw-r--r--source/blender/editors/mesh/mesh_intern.h1
-rw-r--r--source/blender/editors/mesh/mesh_ops.c1
-rw-r--r--source/blender/editors/object/object_add.c16
-rw-r--r--source/blender/editors/object/object_bake.c324
-rw-r--r--source/blender/editors/object/object_edit.c62
-rw-r--r--source/blender/editors/object/object_relations.c119
-rw-r--r--source/blender/editors/object/object_select.c39
-rw-r--r--source/blender/editors/physics/particle_edit.c4
-rw-r--r--source/blender/editors/render/render_intern.h5
-rw-r--r--source/blender/editors/render/render_internal.c618
-rw-r--r--source/blender/editors/render/render_opengl.c10
-rw-r--r--source/blender/editors/render/render_ops.c3
-rw-r--r--source/blender/editors/render/render_preview.c203
-rw-r--r--source/blender/editors/render/render_shading.c238
-rw-r--r--source/blender/editors/render/render_update.c235
-rw-r--r--source/blender/editors/sculpt_paint/paint_image.c2
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_proj.c140
-rw-r--r--source/blender/editors/sculpt_paint/paint_intern.h1
-rw-r--r--source/blender/editors/sculpt_paint/paint_ops.c1
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex.c4
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c15
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_undo.c5
-rw-r--r--source/blender/editors/space_api/spacetypes.c3
-rw-r--r--source/blender/editors/space_buttons/buttons_context.c217
-rw-r--r--source/blender/editors/space_buttons/buttons_intern.h1
-rw-r--r--source/blender/editors/space_buttons/buttons_texture.c205
-rw-r--r--source/blender/editors/space_image/image_edit.c5
-rw-r--r--source/blender/editors/space_image/image_ops.c2
-rw-r--r--source/blender/editors/space_image/space_image.c27
-rw-r--r--source/blender/editors/space_node/drawnode.c52
-rw-r--r--source/blender/editors/space_node/node_add.c14
-rw-r--r--source/blender/editors/space_node/node_draw.c4
-rw-r--r--source/blender/editors/space_node/node_edit.c77
-rw-r--r--source/blender/editors/space_node/node_ops.c2
-rw-r--r--source/blender/editors/space_node/node_templates.c5
-rw-r--r--source/blender/editors/space_node/space_node.c4
-rw-r--r--source/blender/editors/space_outliner/outliner_select.c89
-rw-r--r--source/blender/editors/space_outliner/outliner_tools.c14
-rw-r--r--source/blender/editors/space_outliner/outliner_tree.c20
-rw-r--r--source/blender/editors/space_view3d/CMakeLists.txt4
-rw-r--r--source/blender/editors/space_view3d/drawanimviz.c438
-rw-r--r--source/blender/editors/space_view3d/drawarmature.c3010
-rw-r--r--source/blender/editors/space_view3d/drawmesh.c364
-rw-r--r--source/blender/editors/space_view3d/drawobject.c9036
-rw-r--r--source/blender/editors/space_view3d/drawsimdebug.c209
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c848
-rw-r--r--source/blender/editors/space_view3d/view3d_draw_legacy.c1044
-rw-r--r--source/blender/editors/space_view3d/view3d_intern.h107
-rw-r--r--source/blender/editors/undo/ed_undo.c2
-rw-r--r--source/blender/editors/undo/memfile_undo.c2
-rw-r--r--source/blender/editors/uvedit/uvedit_draw.c70
-rw-r--r--source/blender/editors/uvedit/uvedit_ops.c90
-rw-r--r--source/blender/editors/uvedit/uvedit_unwrap_ops.c15
-rw-r--r--source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp26
-rw-r--r--source/blender/freestyle/intern/blender_interface/BlenderFileLoader.h1
-rw-r--r--source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp93
-rw-r--r--source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp4
-rw-r--r--source/blender/freestyle/intern/stroke/Stroke.h3
-rw-r--r--source/blender/gpu/CMakeLists.txt3
-rw-r--r--source/blender/gpu/GPU_buffers.h188
-rw-r--r--source/blender/gpu/GPU_draw.h40
-rw-r--r--source/blender/gpu/GPU_lamp.h77
-rw-r--r--source/blender/gpu/GPU_material.h110
-rw-r--r--source/blender/gpu/intern/gpu_buffers.c958
-rw-r--r--source/blender/gpu/intern/gpu_codegen.c402
-rw-r--r--source/blender/gpu/intern/gpu_codegen.h3
-rw-r--r--source/blender/gpu/intern/gpu_draw.c712
-rw-r--r--source/blender/gpu/intern/gpu_init_exit.c3
-rw-r--r--source/blender/gpu/intern/gpu_lamp.c458
-rw-r--r--source/blender/gpu/intern/gpu_lamp_private.h84
-rw-r--r--source/blender/gpu/intern/gpu_material.c2284
-rw-r--r--source/blender/gpu/intern/gpu_shader.c10
-rw-r--r--source/blender/gpu/shaders/gpu_shader_geometry.glsl5
-rw-r--r--source/blender/gpu/shaders/gpu_shader_material.glsl8
-rw-r--r--source/blender/gpu/shaders/gpu_shader_vertex.glsl4
-rw-r--r--source/blender/gpu/shaders/gpu_shader_vertex_world.glsl4
-rw-r--r--source/blender/makesdna/DNA_dynamicpaint_types.h3
-rw-r--r--source/blender/makesdna/DNA_lamp_types.h100
-rw-r--r--source/blender/makesdna/DNA_material_types.h302
-rw-r--r--source/blender/makesdna/DNA_modifier_types.h1
-rw-r--r--source/blender/makesdna/DNA_node_types.h5
-rw-r--r--source/blender/makesdna/DNA_object_types.h2
-rw-r--r--source/blender/makesdna/DNA_scene_types.h128
-rw-r--r--source/blender/makesdna/DNA_space_types.h18
-rw-r--r--source/blender/makesdna/DNA_texture_types.h132
-rw-r--r--source/blender/makesdna/DNA_world_types.h84
-rw-r--r--source/blender/makesrna/RNA_access.h13
-rw-r--r--source/blender/makesrna/intern/rna_color.c27
-rw-r--r--source/blender/makesrna/intern/rna_dynamicpaint.c12
-rw-r--r--source/blender/makesrna/intern/rna_lamp.c446
-rw-r--r--source/blender/makesrna/intern/rna_material.c1666
-rw-r--r--source/blender/makesrna/intern/rna_modifier.c5
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c76
-rw-r--r--source/blender/makesrna/intern/rna_scene.c350
-rw-r--r--source/blender/makesrna/intern/rna_sculpt_paint.c5
-rw-r--r--source/blender/makesrna/intern/rna_space.c68
-rw-r--r--source/blender/makesrna/intern/rna_texture.c611
-rw-r--r--source/blender/makesrna/intern/rna_texture_api.c51
-rw-r--r--source/blender/makesrna/intern/rna_userdef.c1
-rw-r--r--source/blender/makesrna/intern/rna_world.c296
-rw-r--r--source/blender/modifiers/intern/MOD_dynamicpaint.c12
-rw-r--r--source/blender/modifiers/intern/MOD_explode.c2
-rw-r--r--source/blender/modifiers/intern/MOD_uvproject.c128
-rw-r--r--source/blender/nodes/CMakeLists.txt5
-rw-r--r--source/blender/nodes/NOD_shader.h6
-rw-r--r--source/blender/nodes/NOD_static_types.h6
-rw-r--r--source/blender/nodes/intern/node_exec.c2
-rw-r--r--source/blender/nodes/shader/node_shader_tree.c53
-rw-r--r--source/blender/nodes/shader/node_shader_util.c47
-rw-r--r--source/blender/nodes/shader/node_shader_util.h5
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_camera.c19
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_fresnel.c29
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_geom.c163
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_lamp.c91
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_layer_weight.c40
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_material.c374
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_normal.c7
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_normal_map.c149
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_object_info.c7
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_output.c99
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_particle_info.c5
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_texture.c166
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_vectTransform.c83
-rw-r--r--source/blender/nodes/texture/node_texture_tree.c31
-rw-r--r--source/blender/nodes/texture/node_texture_util.c1
-rw-r--r--source/blender/nodes/texture/node_texture_util.h2
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_proc.c2
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_texture.c2
-rw-r--r--source/blender/physics/BPH_mass_spring.h2
-rw-r--r--source/blender/physics/intern/BPH_mass_spring.cpp21
-rw-r--r--source/blender/physics/intern/hair_volume.cpp53
-rw-r--r--source/blender/physics/intern/implicit.h2
-rw-r--r--source/blender/python/intern/gpu.c245
-rw-r--r--source/blender/python/intern/gpu_offscreen.c2
-rw-r--r--source/blender/render/CMakeLists.txt54
-rw-r--r--source/blender/render/extern/include/RE_bake.h3
-rw-r--r--source/blender/render/extern/include/RE_engine.h1
-rw-r--r--source/blender/render/extern/include/RE_pipeline.h54
-rw-r--r--source/blender/render/extern/include/RE_render_ext.h8
-rw-r--r--source/blender/render/extern/include/RE_shader_ext.h186
-rw-r--r--source/blender/render/intern/include/envmap.h54
-rw-r--r--source/blender/render/intern/include/initrender.h7
-rw-r--r--source/blender/render/intern/include/occlusion.h49
-rw-r--r--source/blender/render/intern/include/pixelblending.h65
-rw-r--r--source/blender/render/intern/include/pixelshading.h62
-rw-r--r--source/blender/render/intern/include/pointdensity.h52
-rw-r--r--source/blender/render/intern/include/raycounter.h74
-rw-r--r--source/blender/render/intern/include/rayintersection.h136
-rw-r--r--source/blender/render/intern/include/rayobject.h121
-rw-r--r--source/blender/render/intern/include/render_result.h2
-rw-r--r--source/blender/render/intern/include/render_types.h529
-rw-r--r--source/blender/render/intern/include/rendercore.h105
-rw-r--r--source/blender/render/intern/include/renderdatabase.h175
-rw-r--r--source/blender/render/intern/include/renderpipeline.h3
-rw-r--r--source/blender/render/intern/include/shadbuf.h112
-rw-r--r--source/blender/render/intern/include/shading.h105
-rw-r--r--source/blender/render/intern/include/sss.h67
-rw-r--r--source/blender/render/intern/include/strand.h99
-rw-r--r--source/blender/render/intern/include/sunsky.h81
-rw-r--r--source/blender/render/intern/include/texture.h17
-rw-r--r--source/blender/render/intern/include/texture_ocean.h35
-rw-r--r--source/blender/render/intern/include/volume_precache.h39
-rw-r--r--source/blender/render/intern/include/volumetric.h51
-rw-r--r--source/blender/render/intern/include/voxeldata.h47
-rw-r--r--source/blender/render/intern/include/zbuf.h101
-rw-r--r--source/blender/render/intern/raytrace/bvh.h407
-rw-r--r--source/blender/render/intern/raytrace/rayobject.cpp534
-rw-r--r--source/blender/render/intern/raytrace/rayobject_empty.cpp81
-rw-r--r--source/blender/render/intern/raytrace/rayobject_hint.h72
-rw-r--r--source/blender/render/intern/raytrace/rayobject_instance.cpp211
-rw-r--r--source/blender/render/intern/raytrace/rayobject_internal.h157
-rw-r--r--source/blender/render/intern/raytrace/rayobject_octree.cpp1101
-rw-r--r--source/blender/render/intern/raytrace/rayobject_qbvh.cpp160
-rw-r--r--source/blender/render/intern/raytrace/rayobject_raycounter.cpp91
-rw-r--r--source/blender/render/intern/raytrace/rayobject_rtbuild.cpp531
-rw-r--r--source/blender/render/intern/raytrace/rayobject_rtbuild.h125
-rw-r--r--source/blender/render/intern/raytrace/rayobject_svbvh.cpp192
-rw-r--r--source/blender/render/intern/raytrace/rayobject_vbvh.cpp206
-rw-r--r--source/blender/render/intern/raytrace/reorganize.h513
-rw-r--r--source/blender/render/intern/raytrace/svbvh.h317
-rw-r--r--source/blender/render/intern/raytrace/vbvh.h238
-rw-r--r--source/blender/render/intern/source/bake.c1343
-rw-r--r--source/blender/render/intern/source/bake_api.c70
-rw-r--r--source/blender/render/intern/source/convertblender.c5974
-rw-r--r--source/blender/render/intern/source/envmap.c819
-rw-r--r--source/blender/render/intern/source/external_engine.c23
-rw-r--r--source/blender/render/intern/source/imagetexture.c61
-rw-r--r--source/blender/render/intern/source/initrender.c340
-rw-r--r--source/blender/render/intern/source/multires_bake.c100
-rw-r--r--source/blender/render/intern/source/occlusion.c1533
-rw-r--r--source/blender/render/intern/source/pipeline.c1210
-rw-r--r--source/blender/render/intern/source/pixelblending.c400
-rw-r--r--source/blender/render/intern/source/pixelshading.c650
-rw-r--r--source/blender/render/intern/source/pointdensity.c125
-rw-r--r--source/blender/render/intern/source/rayshade.c2474
-rw-r--r--source/blender/render/intern/source/render_result.c23
-rw-r--r--source/blender/render/intern/source/render_texture.c2510
-rw-r--r--source/blender/render/intern/source/rendercore.c2028
-rw-r--r--source/blender/render/intern/source/renderdatabase.c1603
-rw-r--r--source/blender/render/intern/source/shadbuf.c2647
-rw-r--r--source/blender/render/intern/source/shadeinput.c1451
-rw-r--r--source/blender/render/intern/source/shadeoutput.c2162
-rw-r--r--source/blender/render/intern/source/sss.c1074
-rw-r--r--source/blender/render/intern/source/strand.c1069
-rw-r--r--source/blender/render/intern/source/sunsky.c506
-rw-r--r--source/blender/render/intern/source/texture_ocean.c160
-rw-r--r--source/blender/render/intern/source/volume_precache.c855
-rw-r--r--source/blender/render/intern/source/volumetric.c834
-rw-r--r--source/blender/render/intern/source/voxeldata.c571
-rw-r--r--source/blender/render/intern/source/zbuf.c3498
-rw-r--r--source/blender/windowmanager/intern/wm_files.c15
-rw-r--r--source/blender/windowmanager/intern/wm_files_link.c2
-rw-r--r--source/blender/windowmanager/intern/wm_init_exit.c2
282 files changed, 933 insertions, 80353 deletions
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(&params);
- BKE_camera_params_from_object(&params, 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(&params, re->winx, re->winy, 1.0f, 1.0f);
- BKE_camera_params_compute_matrix(&params);
-
- /* extract results */
- re_camera_params_get(re, &params, 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(&params, cam_ob);
re_camera_params_stereo3d(re, &params, 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(&params, re->winx, re->winy, re->r.xasp, re->r.yasp);
BKE_camera_params_compute_matrix(&params);
@@ -501,12 +190,6 @@ void RE_SetCamera(Render *re, Object *cam_ob)
re_camera_params_get(re, &params, 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();