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:
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();