svn merge ^/trunk/blender -r46100:46200
authorOve Murberg Henriksen <sorayasilvermoon@hotmail.com>
Sun, 6 May 2012 23:06:24 +0000 (23:06 +0000)
committerOve Murberg Henriksen <sorayasilvermoon@hotmail.com>
Sun, 6 May 2012 23:06:24 +0000 (23:06 +0000)
386 files changed:
CMakeLists.txt
GNUmakefile
SConstruct
build_files/cmake/cmake_consistency_check.py
build_files/cmake/cmake_netbeans_project.py
build_files/cmake/cmake_qtcreator_project.py
build_files/cmake/cmake_static_check_cppcheck.py
build_files/cmake/cmake_static_check_sparse.py
build_files/cmake/cmake_static_check_splint.py
build_files/cmake/example_scripts/make_quicky.py
build_files/cmake/project_info.py
build_files/scons/config/win32-vc-config.py
build_files/scons/config/win64-vc-config.py
doc/blender_file_format/BlendFileDnaExporter_25.py
doc/blender_file_format/BlendFileReader.py
doc/python_api/examples/bpy.types.Mesh.py
doc/python_api/rst/bgl.rst
intern/cycles/app/cycles_xml.cpp
intern/cycles/blender/addon/__init__.py
intern/cycles/blender/addon/ui.py
intern/cycles/blender/blender_camera.cpp
intern/cycles/blender/blender_mesh.cpp
intern/cycles/blender/blender_object.cpp
intern/cycles/blender/blender_session.cpp
intern/cycles/blender/blender_sync.cpp
intern/cycles/blender/blender_sync.h
intern/cycles/blender/blender_util.h
intern/cycles/bvh/bvh_build.cpp
intern/cycles/kernel/kernel_bvh.h
intern/cycles/kernel/kernel_camera.h
intern/cycles/kernel/kernel_compat_opencl.h
intern/cycles/kernel/kernel_emission.h
intern/cycles/kernel/kernel_light.h
intern/cycles/kernel/kernel_object.h
intern/cycles/kernel/kernel_passes.h
intern/cycles/kernel/kernel_path.h
intern/cycles/kernel/kernel_shader.h
intern/cycles/kernel/kernel_textures.h
intern/cycles/kernel/kernel_triangle.h
intern/cycles/kernel/kernel_types.h
intern/cycles/kernel/svm/svm_gamma.h
intern/cycles/kernel/svm/svm_light_path.h
intern/cycles/kernel/svm/svm_tex_coord.h
intern/cycles/kernel/svm/svm_types.h
intern/cycles/render/CMakeLists.txt
intern/cycles/render/attribute.cpp
intern/cycles/render/attribute.h
intern/cycles/render/buffers.cpp
intern/cycles/render/camera.cpp
intern/cycles/render/camera.h
intern/cycles/render/film.cpp
intern/cycles/render/film.h
intern/cycles/render/graph.cpp
intern/cycles/render/integrator.cpp
intern/cycles/render/integrator.h
intern/cycles/render/mesh.cpp
intern/cycles/render/mesh.h
intern/cycles/render/mesh_displace.cpp
intern/cycles/render/nodes.cpp
intern/cycles/render/object.cpp
intern/cycles/render/object.h
intern/cycles/render/scene.cpp
intern/cycles/render/scene.h
intern/cycles/render/shader.cpp
intern/cycles/render/shader.h
intern/cycles/render/svm.cpp
intern/cycles/render/svm.h
intern/cycles/subd/subd_dice.cpp
intern/cycles/util/util_boundbox.h
intern/cycles/util/util_math.h
intern/cycles/util/util_transform.cpp
intern/cycles/util/util_transform.h
intern/smoke/intern/smoke_API.cpp
release/scripts/startup/bl_ui/properties_animviz.py
release/scripts/startup/bl_ui/properties_data_armature.py
release/scripts/startup/bl_ui/properties_data_lamp.py
release/scripts/startup/bl_ui/properties_data_modifier.py
release/scripts/startup/bl_ui/properties_game.py
release/scripts/startup/bl_ui/properties_object.py
release/scripts/startup/bl_ui/properties_physics_smoke.py
release/scripts/startup/bl_ui/space_clip.py
release/scripts/startup/bl_ui/space_info.py
release/scripts/startup/bl_ui/space_view3d.py
source/blender/avi/AVI_avi.h
source/blender/avi/intern/avi.c
source/blender/avi/intern/avirgb.c
source/blender/avi/intern/codecs.c
source/blender/avi/intern/endian.c
source/blender/avi/intern/endian.h
source/blender/avi/intern/mjpeg.c
source/blender/avi/intern/options.c
source/blender/avi/intern/rgb32.c
source/blender/blenkernel/BKE_blender.h
source/blender/blenkernel/BKE_brush.h
source/blender/blenkernel/BKE_customdata.h
source/blender/blenkernel/BKE_deform.h
source/blender/blenkernel/BKE_displist.h
source/blender/blenkernel/BKE_dynamicpaint.h
source/blender/blenkernel/BKE_node.h
source/blender/blenkernel/BKE_object.h
source/blender/blenkernel/BKE_ocean.h
source/blender/blenkernel/BKE_tracking.h
source/blender/blenkernel/BKE_utildefines.h
source/blender/blenkernel/intern/anim.c
source/blender/blenkernel/intern/blender.c
source/blender/blenkernel/intern/booleanops_mesh.c
source/blender/blenkernel/intern/brush.c
source/blender/blenkernel/intern/cdderivedmesh.c
source/blender/blenkernel/intern/context.c
source/blender/blenkernel/intern/customdata.c
source/blender/blenkernel/intern/displist.c
source/blender/blenkernel/intern/dynamicpaint.c
source/blender/blenkernel/intern/editderivedmesh.c
source/blender/blenkernel/intern/group.c
source/blender/blenkernel/intern/ipo.c
source/blender/blenkernel/intern/lamp.c
source/blender/blenkernel/intern/movieclip.c
source/blender/blenkernel/intern/object.c
source/blender/blenkernel/intern/particle.c
source/blender/blenkernel/intern/screen.c
source/blender/blenkernel/intern/sequencer.c
source/blender/blenkernel/intern/softbody.c
source/blender/blenkernel/intern/subsurf_ccg.c
source/blender/blenkernel/intern/text.c
source/blender/blenkernel/intern/tracking.c
source/blender/blenkernel/intern/writeffmpeg.c
source/blender/blenkernel/intern/writeframeserver.c
source/blender/blenlib/BLI_fileops.h
source/blender/blenlib/BLI_ghash.h
source/blender/blenlib/BLI_math_matrix.h
source/blender/blenlib/BLI_memarena.h
source/blender/blenlib/BLI_threads.h
source/blender/blenlib/PIL_time.h
source/blender/blenlib/intern/BLI_args.c
source/blender/blenlib/intern/bpath.c
source/blender/blenlib/intern/cpu.c
source/blender/blenlib/intern/jitter.c
source/blender/blenlib/intern/math_matrix.c
source/blender/blenlib/intern/noise.c
source/blender/blenlib/intern/pbvh.c
source/blender/blenlib/intern/storage.c
source/blender/blenlib/intern/string_cursor_utf8.c
source/blender/blenlib/intern/threads.c
source/blender/blenlib/intern/winstuff.c
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/writefile.c
source/blender/blenpluginapi/documentation.h
source/blender/blenpluginapi/externdef.h
source/blender/blenpluginapi/floatpatch.h
source/blender/blenpluginapi/iff.h
source/blender/blenpluginapi/plugin.h
source/blender/blenpluginapi/util.h
source/blender/bmesh/intern/bmesh_core.c
source/blender/bmesh/intern/bmesh_interp.c
source/blender/bmesh/intern/bmesh_interp.h
source/blender/bmesh/intern/bmesh_mesh.c
source/blender/bmesh/intern/bmesh_private.h
source/blender/bmesh/operators/bmo_primitive.c
source/blender/collada/AnimationImporter.cpp
source/blender/collada/AnimationImporter.h
source/blender/collada/DocumentImporter.cpp
source/blender/collada/DocumentImporter.h
source/blender/collada/MeshImporter.cpp
source/blender/collada/MeshImporter.h
source/blender/editors/animation/keyframing.c
source/blender/editors/armature/editarmature.c
source/blender/editors/armature/editarmature_retarget.c
source/blender/editors/armature/poseUtils.c
source/blender/editors/armature/poseobject.c
source/blender/editors/curve/editcurve.c
source/blender/editors/datafiles/Bfont.c
source/blender/editors/datafiles/startup.blend.c
source/blender/editors/gpencil/gpencil_paint.c
source/blender/editors/include/ED_clip.h
source/blender/editors/include/ED_fluidsim.h
source/blender/editors/include/ED_particle.h
source/blender/editors/include/ED_physics.h
source/blender/editors/include/UI_resources.h
source/blender/editors/interface/interface.c
source/blender/editors/interface/interface_handlers.c
source/blender/editors/interface/interface_layout.c
source/blender/editors/interface/interface_templates.c
source/blender/editors/interface/interface_utils.c
source/blender/editors/interface/resources.c
source/blender/editors/mesh/editmesh_tools.c
source/blender/editors/mesh/mesh_data.c
source/blender/editors/mesh/mesh_navmesh.c
source/blender/editors/mesh/meshtools.c
source/blender/editors/object/object_add.c
source/blender/editors/object/object_bake.c
source/blender/editors/object/object_constraint.c
source/blender/editors/object/object_edit.c
source/blender/editors/object/object_group.c
source/blender/editors/object/object_hook.c
source/blender/editors/object/object_modifier.c
source/blender/editors/object/object_relations.c
source/blender/editors/object/object_select.c
source/blender/editors/object/object_transform.c
source/blender/editors/object/object_vgroup.c
source/blender/editors/physics/particle_edit.c
source/blender/editors/physics/physics_fluid.c
source/blender/editors/render/render_preview.c
source/blender/editors/render/render_shading.c
source/blender/editors/sculpt_paint/paint_hide.c
source/blender/editors/sculpt_paint/paint_image.c
source/blender/editors/sculpt_paint/paint_stroke.c
source/blender/editors/sculpt_paint/paint_undo.c
source/blender/editors/sculpt_paint/paint_vertex.c
source/blender/editors/sound/sound_ops.c
source/blender/editors/space_clip/CMakeLists.txt
source/blender/editors/space_clip/SConscript
source/blender/editors/space_clip/clip_buttons.c
source/blender/editors/space_clip/clip_draw.c
source/blender/editors/space_clip/clip_editor.c
source/blender/editors/space_clip/clip_graph_ops.c
source/blender/editors/space_clip/clip_intern.h
source/blender/editors/space_clip/clip_ops.c
source/blender/editors/space_clip/space_clip.c
source/blender/editors/space_clip/tracking_ops.c
source/blender/editors/space_info/info_stats.c
source/blender/editors/space_logic/logic_buttons.c
source/blender/editors/space_node/drawnode.c
source/blender/editors/space_node/node_buttons.c
source/blender/editors/space_node/node_draw.c
source/blender/editors/space_node/node_edit.c
source/blender/editors/space_node/node_intern.h
source/blender/editors/space_node/node_ops.c
source/blender/editors/space_sequencer/sequencer_add.c
source/blender/editors/space_sequencer/sequencer_edit.c
source/blender/editors/space_sequencer/sequencer_scopes.c
source/blender/editors/space_sequencer/sequencer_select.c
source/blender/editors/space_time/space_time.c
source/blender/editors/space_view3d/drawanimviz.c
source/blender/editors/space_view3d/drawmesh.c
source/blender/editors/space_view3d/drawobject.c
source/blender/editors/space_view3d/view3d_intern.h
source/blender/editors/space_view3d/view3d_select.c
source/blender/editors/space_view3d/view3d_snap.c
source/blender/editors/transform/transform.c
source/blender/editors/transform/transform_conversions.c
source/blender/editors/transform/transform_ops.c
source/blender/editors/uvedit/uvedit_ops.c
source/blender/editors/uvedit/uvedit_parametrizer.c
source/blender/editors/uvedit/uvedit_parametrizer.h
source/blender/editors/uvedit/uvedit_smart_stitch.c
source/blender/editors/uvedit/uvedit_unwrap_ops.c
source/blender/gpu/CMakeLists.txt
source/blender/gpu/GPU_extensions.h
source/blender/gpu/GPU_material.h
source/blender/gpu/SConscript
source/blender/gpu/intern/gpu_codegen.c
source/blender/gpu/intern/gpu_extensions.c
source/blender/gpu/intern/gpu_material.c
source/blender/gpu/intern/gpu_shader_material.glsl.c [deleted file]
source/blender/gpu/intern/gpu_shader_vertex.glsl.c [deleted file]
source/blender/gpu/shaders/gpu_shader_material.glsl [moved from source/blender/gpu/intern/gpu_shader_material.glsl with 97% similarity]
source/blender/gpu/shaders/gpu_shader_material.glsl.c [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_sep_gaussian_blur_frag.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_sep_gaussian_blur_frag.glsl.c [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_sep_gaussian_blur_vert.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_sep_gaussian_blur_vert.glsl.c [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_vertex.glsl [moved from source/blender/gpu/intern/gpu_shader_vertex.glsl with 100% similarity]
source/blender/gpu/shaders/gpu_shader_vertex.glsl.c [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_vsm_store_frag.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_vsm_store_frag.glsl.c [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_vsm_store_vert.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_vsm_store_vert.glsl.c [new file with mode: 0644]
source/blender/imbuf/IMB_imbuf_types.h
source/blender/imbuf/intern/IMB_allocimbuf.h
source/blender/imbuf/intern/IMB_anim.h
source/blender/imbuf/intern/IMB_filter.h
source/blender/imbuf/intern/cineon/cineonfile.h
source/blender/imbuf/intern/cineon/cineonlib.c
source/blender/imbuf/intern/cineon/cineonlib.h
source/blender/imbuf/intern/cineon/dpxfile.h
source/blender/imbuf/intern/cineon/dpxlib.c
source/blender/imbuf/intern/cineon/dpxlib.h
source/blender/imbuf/intern/cineon/logImageCore.c
source/blender/imbuf/intern/cineon/logImageCore.h
source/blender/imbuf/intern/cineon/logImageLib.c
source/blender/imbuf/intern/cineon/logImageLib.h
source/blender/imbuf/intern/cineon/logmemfile.c
source/blender/imbuf/intern/cineon/logmemfile.h
source/blender/imbuf/intern/dds/ColorBlock.h
source/blender/imbuf/intern/dds/DirectDrawSurface.h
source/blender/imbuf/intern/filter.c
source/blender/imbuf/intern/imageprocess.c
source/blender/imbuf/intern/imbuf.h
source/blender/imbuf/intern/imbuf_cocoa.m
source/blender/imbuf/intern/indexer.c
source/blender/imbuf/intern/tiff.c
source/blender/imbuf/intern/util.c
source/blender/makesdna/DNA_boid_types.h
source/blender/makesdna/DNA_group_types.h
source/blender/makesdna/DNA_lamp_types.h
source/blender/makesdna/DNA_node_types.h
source/blender/makesdna/DNA_object_fluidsim.h
source/blender/makesdna/DNA_object_force.h
source/blender/makesdna/DNA_property_types.h
source/blender/makesdna/DNA_space_types.h
source/blender/makesdna/DNA_tracking_types.h
source/blender/makesdna/intern/dna_genfile.c
source/blender/makesrna/RNA_access.h
source/blender/makesrna/RNA_enum_types.h
source/blender/makesrna/intern/rna_access.c
source/blender/makesrna/intern/rna_animviz.c
source/blender/makesrna/intern/rna_image_api.c
source/blender/makesrna/intern/rna_lamp.c
source/blender/makesrna/intern/rna_material_api.c
source/blender/makesrna/intern/rna_nodetree.c
source/blender/makesrna/intern/rna_object_api.c
source/blender/makesrna/intern/rna_pose_api.c
source/blender/makesrna/intern/rna_scene.c
source/blender/makesrna/intern/rna_scene_api.c
source/blender/makesrna/intern/rna_screen.c
source/blender/makesrna/intern/rna_space.c
source/blender/makesrna/intern/rna_test.c
source/blender/makesrna/intern/rna_userdef.c
source/blender/makesrna/rna_cleanup/rna_cleaner.py
source/blender/makesrna/rna_cleanup/rna_cleaner_merge.py
source/blender/modifiers/intern/MOD_explode.c
source/blender/modifiers/intern/MOD_meshdeform.c
source/blender/modifiers/intern/MOD_mirror.c
source/blender/modifiers/intern/MOD_particlesystem.c
source/blender/nodes/composite/nodes/node_composite_blur.c
source/blender/nodes/composite/nodes/node_composite_chromaMatte.c
source/blender/nodes/composite/nodes/node_composite_colorMatte.c
source/blender/nodes/composite/nodes/node_composite_colorSpill.c
source/blender/nodes/composite/nodes/node_composite_diffMatte.c
source/blender/nodes/composite/nodes/node_composite_distanceMatte.c
source/blender/nodes/composite/nodes/node_composite_image.c
source/blender/nodes/composite/nodes/node_composite_outputFile.c
source/blender/nodes/composite/nodes/node_composite_sepcombHSVA.c
source/blender/nodes/intern/node_common.c
source/blender/nodes/shader/nodes/node_shader_light_path.c
source/blender/nodes/shader/nodes/node_shader_valToRgb.c
source/blender/python/bmesh/bmesh_py_types.h
source/blender/python/bmesh/bmesh_py_types_customdata.c
source/blender/python/bmesh/bmesh_py_types_meshdata.c
source/blender/python/bmesh/bmesh_py_types_meshdata.h
source/blender/python/intern/bpy_rna.c
source/blender/python/mathutils/mathutils.h
source/blender/python/mathutils/mathutils_Color.c
source/blender/python/mathutils/mathutils_Color.h
source/blender/python/mathutils/mathutils_Euler.c
source/blender/python/mathutils/mathutils_Euler.h
source/blender/python/mathutils/mathutils_Matrix.c
source/blender/python/mathutils/mathutils_Quaternion.h
source/blender/python/mathutils/mathutils_Vector.h
source/blender/python/mathutils/mathutils_geometry.c
source/blender/python/mathutils/mathutils_geometry.h
source/blender/quicktime/apple/quicktime_export.c
source/blender/quicktime/apple/quicktime_import.c
source/blender/render/intern/include/gammaCorrectionTables.h
source/blender/render/intern/include/initrender.h
source/blender/render/intern/include/occlusion.h
source/blender/render/intern/include/rendercore.h
source/blender/render/intern/include/shadbuf.h
source/blender/render/intern/include/texture.h
source/blender/render/intern/raytrace/rayobject.cpp
source/blender/render/intern/raytrace/rayobject_internal.h
source/blender/render/intern/source/convertblender.c
source/blender/render/intern/source/envmap.c
source/blender/render/intern/source/external_engine.c
source/blender/render/intern/source/gammaCorrectionTables.c
source/blender/render/intern/source/imagetexture.c
source/blender/render/intern/source/occlusion.c
source/blender/render/intern/source/pipeline.c
source/blender/render/intern/source/pixelblending.c
source/blender/render/intern/source/render_result.c
source/blender/render/intern/source/sss.c
source/blender/render/intern/source/sunsky.c
source/blender/windowmanager/intern/wm_event_system.c
source/blender/windowmanager/intern/wm_keymap.c
source/blender/windowmanager/intern/wm_operators.c
source/blenderplayer/bad_level_call_stubs/stubs.c
source/creator/CMakeLists.txt
source/creator/creator.c
source/gameengine/Converter/KX_ConvertProperties.h
source/gameengine/GameLogic/SCA_ActuatorSensor.h
source/gameengine/Ketsji/KX_Light.cpp
source/gameengine/Ketsji/KX_Light.h
source/gameengine/Ketsji/KX_PythonSeq.h
source/gameengine/Ketsji/KX_VertexProxy.cpp
source/gameengine/Rasterizer/RAS_IRasterizer.h
source/gameengine/VideoTexture/Texture.cpp

index 16de9a4..4363674 100644 (file)
@@ -228,6 +228,10 @@ if(UNIX AND NOT APPLE)
        option(WITH_INSTALL_PORTABLE "Install redistributeable runtime, otherwise install into CMAKE_INSTALL_PREFIX" ON)
 endif()
 option(WITH_PYTHON_INSTALL       "Copy system python into the blender install folder" ON)
+option(WITH_PYTHON_INSTALL_NUMPY "Copy system numpy into the blender install folder"  ON)
+set(PYTHON_NUMPY_PATH            "" CACHE PATH "Python to python site-packages or dist-packages containing 'numpy' module")
+mark_as_advanced(PYTHON_NUMPY_PATH)
+
 option(WITH_MINGW64                   "Use the 64-bit version of MinGW" OFF)
 mark_as_advanced(WITH_MINGW64)
 
@@ -303,7 +307,7 @@ endif()
 #-----------------------------------------------------------------------------
 # Check for conflicting/unsupported configurations
 
-if(NOT WITH_BLENDER AND NOT WITH_PLAYER)
+if(NOT WITH_BLENDER AND NOT WITH_PLAYER AND NOT WITH_CYCLES_TEST)
        message(FATAL_ERROR "At least one of WITH_BLENDER or WITH_PLAYER must be enabled, nothing to do!")
 endif()
 
@@ -1612,6 +1616,49 @@ if(WITH_PYTHON)
                                                        "to a valid python include path. Containing "
                                                        "Python.h for python version \"${PYTHON_VERSION}\"")
        endif()
+
+       if(WITH_PYTHON_INSTALL AND WITH_PYTHON_INSTALL_NUMPY)
+               # set but invalid
+               if(NOT ${PYTHON_NUMPY_PATH} STREQUAL "")
+                       if(NOT EXISTS "${PYTHON_NUMPY_PATH}/numpy")
+                               message(WARNING "PYTHON_NUMPY_PATH is invalid, numpy not found in '${PYTHON_NUMPY_PATH}' "
+                                               "WITH_PYTHON_INSTALL_NUMPY option will be ignored when installing python")
+                               set(WITH_PYTHON_INSTALL_NUMPY OFF)
+                       endif()
+               # not set, so initialize
+               else()
+                       string(REPLACE "." ";" _PY_VER_SPLIT "${PYTHON_VERSION}")
+                       list(GET _PY_VER_SPLIT 0 _PY_VER_MAJOR)
+
+                       # re-cache
+                       unset(PYTHON_NUMPY_PATH CACHE)
+                       find_path(PYTHON_NUMPY_PATH
+                         NAMES
+                           numpy
+                         HINTS
+                           "${PYTHON_LIBPATH}/python${PYTHON_VERSION}/"
+                           "${PYTHON_LIBPATH}/python${_PY_VER_MAJOR}/"
+                         PATH_SUFFIXES
+                           site-packages
+                           dist-packages
+                       )
+
+                       if(NOT EXISTS "${PYTHON_NUMPY_PATH}")
+                               message(WARNING "'numpy' path could not be found in:\n"
+                                               "'${PYTHON_LIBPATH}/python${PYTHON_VERSION}/site-packages/numpy', "
+                                               "'${PYTHON_LIBPATH}/python${_PY_VER_MAJOR}/site-packages/numpy', "
+                                               "'${PYTHON_LIBPATH}/python${PYTHON_VERSION}/dist-packages/numpy', "
+                                               "'${PYTHON_LIBPATH}/python${_PY_VER_MAJOR}/dist-packages/numpy', "
+                                               "WITH_PYTHON_INSTALL_NUMPY option will be ignored when installing python")
+                               set(WITH_PYTHON_INSTALL_NUMPY OFF)
+                       else()
+                               message(STATUS "numpy found at '${PYTHON_NUMPY_PATH}'")
+                       endif()
+
+                       unset(_PY_VER_SPLIT)
+                       unset(_PY_VER_MAJOR)
+               endif()
+       endif()
 endif()
 
 
@@ -1668,7 +1715,7 @@ if(FIRST_RUN)
                _setting)
                set(_msg "   * ${_setting}")
                string(LENGTH "${_msg}" _len)
-               while("28" GREATER "${_len}")
+               while("32" GREATER "${_len}")
                        set(_msg "${_msg} ")
                         math(EXPR _len "${_len} + 1")
                endwhile()
@@ -1728,6 +1775,7 @@ if(FIRST_RUN)
 
        info_cfg_text("Python:")
        info_cfg_option(WITH_PYTHON_INSTALL)
+       info_cfg_option(WITH_PYTHON_INSTALL_NUMPY)
        info_cfg_option(WITH_PYTHON_MODULE)
        info_cfg_option(WITH_PYTHON_SAFETY)
 
index b448f93..ebd2db6 100644 (file)
@@ -164,6 +164,7 @@ help:
        @echo "  * test_cmake      - runs our own cmake file checker which detects errors in the cmake file list definitions"
        @echo "  * test_pep8       - checks all python script are pep8 which are tagged to use the stricter formatting"
        @echo "  * test_deprecated - checks for deprecation tags in our code which may need to be removed"
+       @echo "  * test_style      - checks C/C++ conforms with blenders style guide: http://wiki.blender.org/index.php/Dev:Doc/CodeStyle"
        @echo ""
        @echo "Static Source Code Checking (not assosiated with building blender)"
        @echo "  * check_cppcheck    - run blender source through cppcheck (C & C++)"
@@ -201,28 +202,31 @@ test:
 
 # run pep8 check check on scripts we distribute.
 test_pep8:
-       python3 source/tests/pep8.py > test_pep8.log 2>&1
+       python3.2 source/tests/pep8.py > test_pep8.log 2>&1
        @echo "written: test_pep8.log"
 
 # run some checks on our cmakefiles.
 test_cmake:
-       python3 build_files/cmake/cmake_consistency_check.py > test_cmake_consistency.log 2>&1
+       python3.2 build_files/cmake/cmake_consistency_check.py > test_cmake_consistency.log 2>&1
        @echo "written: test_cmake_consistency.log"
 
 # run deprecation tests, see if we have anything to remove.
 test_deprecated:
-       python3 source/tests/check_deprecated.py
+       python3.2 source/tests/check_deprecated.py
 
+test_style:
+       # run our own checks on C/C++ style
+       PYTHONIOENCODING=utf_8 python3.2 $(BLENDER_DIR)/source/tools/check_style_c.py $(BLENDER_DIR)/source/blender $(BLENDER_DIR)/source/creator
 
 # -----------------------------------------------------------------------------
 # Project Files
 #
 
 project_qtcreator:
-       python3 build_files/cmake/cmake_qtcreator_project.py $(BUILD_DIR)
+       python3.2 build_files/cmake/cmake_qtcreator_project.py $(BUILD_DIR)
 
 project_netbeans:
-       python3 build_files/cmake/cmake_netbeans_project.py $(BUILD_DIR)
+       python3.2 build_files/cmake/cmake_netbeans_project.py $(BUILD_DIR)
 
 project_eclipse:
        cmake -G"Eclipse CDT4 - Unix Makefiles" -H$(BLENDER_DIR) -B$(BUILD_DIR)
@@ -234,22 +238,21 @@ project_eclipse:
 
 check_cppcheck:
        $(CMAKE_CONFIG)
-       cd $(BUILD_DIR) ; python3 $(BLENDER_DIR)/build_files/cmake/cmake_static_check_cppcheck.py
+       cd $(BUILD_DIR) ; python3.2 $(BLENDER_DIR)/build_files/cmake/cmake_static_check_cppcheck.py
 
 check_splint:
        $(CMAKE_CONFIG)
-       cd $(BUILD_DIR) ; python3 $(BLENDER_DIR)/build_files/cmake/cmake_static_check_splint.py
+       cd $(BUILD_DIR) ; python3.2 $(BLENDER_DIR)/build_files/cmake/cmake_static_check_splint.py
 
 check_sparse:
        $(CMAKE_CONFIG)
-       cd $(BUILD_DIR) ; python3 $(BLENDER_DIR)/build_files/cmake/cmake_static_check_sparse.py
+       cd $(BUILD_DIR) ; python3.2 $(BLENDER_DIR)/build_files/cmake/cmake_static_check_sparse.py
 
 check_spelling_py:
-       cd $(BUILD_DIR) ; PYTHONIOENCODING=utf_8 python3 $(BLENDER_DIR)/source/tools/spell_check_source.py $(BLENDER_DIR)/release/scripts
+       cd $(BUILD_DIR) ; PYTHONIOENCODING=utf_8 python3.2 $(BLENDER_DIR)/source/tools/spell_check_source.py $(BLENDER_DIR)/release/scripts
 
 check_spelling_c:
-       cd $(BUILD_DIR) ; PYTHONIOENCODING=utf_8 python3 $(BLENDER_DIR)/source/tools/spell_check_source.py $(BLENDER_DIR)/source
-
+       cd $(BUILD_DIR) ; PYTHONIOENCODING=utf_8 python3.2 $(BLENDER_DIR)/source/tools/spell_check_source.py $(BLENDER_DIR)/source
 
 # -----------------------------------------------------------------------------
 # Documentation
@@ -270,7 +273,7 @@ doc_dna:
        @echo "docs written into: '$(BLENDER_DIR)/doc/blender_file_format/dna.html'"
 
 doc_man:
-       python3 doc/manpage/blender.1.py $(BUILD_DIR)/bin/blender
+       python3.2 doc/manpage/blender.1.py $(BUILD_DIR)/bin/blender
 
 
 clean:
index b1603fd..46ce989 100644 (file)
@@ -805,6 +805,7 @@ if env['OURPLATFORM'] == 'win64-mingw':
         dllsources.append('${LCGDIR}/sdl/lib/SDL.dll')
        
     dllsources.append('${LCGDIR}/thumbhandler/lib/BlendThumb64.dll')
+    dllsources.append('${LCGDIR}/binaries/pthreadGC2-w64.dll')
     dllsources.append('#source/icons/blender.exe.manifest')
 
     windlls = env.Install(dir=env['BF_INSTALLDIR'], source = dllsources)
index 65a9442..072bbb1 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3.2
 
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
index 45c19ad..aa6124a 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3.2
 
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
index 8cabc75..32d2048 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3.2
 
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
index 436470a..c340ca5 100644 (file)
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3.2
 
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
index bd7629e..db1b14e 100644 (file)
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3.2
 
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
index edfefa3..f538fa6 100644 (file)
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3.2
 
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
index a4e0d33..9b853fc 100755 (executable)
@@ -1,4 +1,4 @@
-#! /usr/bin/env python
+#!/usr/bin/env python3.2
 
 # ##### BEGIN GPL LICENSE BLOCK #####
 #
index 3f64ac5..a80ae62 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3.2
 
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
index 5ed845c..d7af0eb 100644 (file)
@@ -163,7 +163,7 @@ BF_BOOST_LIB = 'libboost_date_time-vc90-mt-s-1_47 libboost_filesystem-vc90-mt-s-
 BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
 
 #CUDA
-WITH_BF_CYCLES_CUDA_BINARIES = True
+WITH_BF_CYCLES_CUDA_BINARIES = False
 #BF_CYCLES_CUDA_NVCC = "" # Path to the nvidia compiler
 BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_13', 'sm_20', 'sm_21']
 
index f8a67d7..3a376be 100644 (file)
@@ -160,7 +160,7 @@ BF_BOOST_LIB = 'libboost_date_time-vc90-mt-s-1_47 libboost_filesystem-vc90-mt-s-
 BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
 
 #CUDA
-WITH_BF_CYCLES_CUDA_BINARIES = True
+WITH_BF_CYCLES_CUDA_BINARIES = False
 #BF_CYCLES_CUDA_NVCC = "" # Path to the nvidia compiler
 BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_13', 'sm_20', 'sm_21']
 
index a201f61..b7b89c8 100755 (executable)
@@ -1,4 +1,4 @@
-#! /usr/bin/env python3
+#!/usr/bin/env python3.2
 
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
index 88eb71b..b7091ad 100644 (file)
@@ -1,4 +1,4 @@
-#! /usr/bin/env python3
+#!/usr/bin/env python3.2
 
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
index 69edf2c..1ee5118 100644 (file)
@@ -38,4 +38,3 @@ for poly in me.polygons:
     for loop_index in range(poly.loop_start, poly.loop_start + poly.loop_total):
         print("    Vertex: %d" % me.loops[loop_index].vertex_index)
         print("    UV: %r" % uv_layer[loop_index].uv)
-    
index 8fe7658..9f7817c 100644 (file)
@@ -27,7 +27,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Operate on the accumulation buffer.
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/accum.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glAccum.xml>`_
 
    :type op: Enumerated constant
    :arg op: The accumulation buffer operation.
@@ -39,7 +39,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Specify the alpha test function.
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/alphafunc.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glAlphaFunc.xml>`_
 
    :type func: Enumerated constant
    :arg func: Specifies the alpha comparison function.
@@ -52,7 +52,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Determine if textures are loaded in texture memory
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/aretexturesresident.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glAreTexturesResident.xml>`_
 
    :type n: int
    :arg n: Specifies the number of textures to be queried.
@@ -68,7 +68,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Delimit the vertices of a primitive or a group of like primatives
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/begin.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glBegin.xml>`_
 
    :type mode: Enumerated constant
    :arg mode: Specifies the primitive that will be create from vertices between
@@ -79,7 +79,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Bind a named texture to a texturing target
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/bindtexture.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glBindTexture.xml>`_
 
    :type target: Enumerated constant
    :arg target: Specifies the target to which the texture is bound.
@@ -91,7 +91,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Draw a bitmap
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/bitmap.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glBitmap.xml>`_
 
    :type width, height: int
    :arg width, height: Specify the pixel width and height of the bitmap image.
@@ -109,7 +109,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Specify pixel arithmetic
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/blendfunc.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glBlendFunc.xml>`_
 
    :type sfactor: Enumerated constant
    :arg sfactor: Specifies how the red, green, blue, and alpha source blending factors are
@@ -123,7 +123,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Execute a display list
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/calllist.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glCallList.xml>`_
 
    :type list: unsigned int
    :arg list: Specifies the integer name of the display list to be executed.
@@ -133,7 +133,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Execute a list of display lists
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/calllists.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glCallLists.xml>`_
 
    :type n: int
    :arg n: Specifies the number of display lists to be executed.
@@ -149,7 +149,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Clear buffers to preset values
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/clear.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glClear.xml>`_
 
    :type mask: Enumerated constant(s)
    :arg mask: Bitwise OR of masks that indicate the buffers to be cleared.
@@ -159,7 +159,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Specify clear values for the accumulation buffer
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/clearaccum.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glClearAccum.xml>`_
 
    :type red, green, blue, alpha: float
    :arg red, green, blue, alpha: Specify the red, green, blue, and alpha values used when the
@@ -170,7 +170,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Specify clear values for the color buffers
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/clearcolor.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glClearColor.xml>`_
 
    :type red, green, blue, alpha: float
    :arg red, green, blue, alpha: Specify the red, green, blue, and alpha values used when the
@@ -181,7 +181,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Specify the clear value for the depth buffer
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/cleardepth.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glClearDepth.xml>`_
 
    :type depth: int
    :arg depth: Specifies the depth value used when the depth buffer is cleared.
@@ -192,7 +192,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Specify the clear value for the color index buffers
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/clearindex.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glClearIndex.xml>`_
 
    :type c: float
    :arg c: Specifies the index used when the color index buffers are cleared.
@@ -203,7 +203,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Specify the clear value for the stencil buffer
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/clearstencil.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glClearStencil.xml>`_
 
    :type s: int
    :arg s: Specifies the index used when the stencil buffer is cleared. The initial value is 0.
@@ -213,7 +213,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Specify a plane against which all geometry is clipped
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/clipplane.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glClipPlane.xml>`_
 
    :type plane: Enumerated constant
    :arg plane: Specifies which clipping plane is being positioned.
@@ -232,7 +232,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Set a new color.
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/color.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glColor.xml>`_
 
    :type red, green, blue, alpha: Depends on function prototype.
    :arg red, green, blue: Specify new red, green, and blue values for the current color.
@@ -244,7 +244,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Enable and disable writing of frame buffer color components
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/colormask.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glColorMask.xml>`_
 
    :type red, green, blue, alpha: int (boolean)
    :arg red, green, blue, alpha: Specify whether red, green, blue, and alpha can or cannot be
@@ -256,7 +256,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Cause a material color to track the current color
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/colormaterial.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glColorMaterial.xml>`_
 
    :type face: Enumerated constant
    :arg face: Specifies whether front, back, or both front and back material parameters should
@@ -269,7 +269,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Copy pixels in the frame buffer
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/copypixels.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glCopyPixels.xml>`_
 
    :type x, y: int
    :arg x, y: Specify the window coordinates of the lower left corner of the rectangular
@@ -314,7 +314,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Specify whether front- or back-facing facets can be culled
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/cullface.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glCullFace.xml>`_
 
    :type mode: Enumerated constant
    :arg mode: Specifies whether front- or back-facing facets are candidates for culling.
@@ -324,7 +324,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Delete a contiguous group of display lists
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/deletelists.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glDeleteLists.xml>`_
 
    :type list: unsigned int
    :arg list: Specifies the integer name of the first display list to delete
@@ -336,7 +336,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Delete named textures
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/deletetextures.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glDeleteTextures.xml>`_
 
    :type n: int
    :arg n: Specifies the number of textures to be deleted
@@ -348,7 +348,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Specify the value used for depth buffer comparisons
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/depthfunc.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glDepthFunc.xml>`_
 
    :type func: Enumerated constant
    :arg func: Specifies the depth comparison function.
@@ -358,7 +358,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Enable or disable writing into the depth buffer
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/depthmask.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glDepthMask.xml>`_
 
    :type flag: int (boolean)
    :arg flag: Specifies whether the depth buffer is enabled for writing. If flag is GL_FALSE,
@@ -370,7 +370,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Specify mapping of depth values from normalized device coordinates to window coordinates
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/depthrange.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glDepthRange.xml>`_
 
    :type zNear: int
    :arg zNear: Specifies the mapping of the near clipping plane to window coordinates.
@@ -384,7 +384,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Disable server-side GL capabilities
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/enable.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glEnable.xml>`_
 
    :type cap: Enumerated constant
    :arg cap: Specifies a symbolic constant indicating a GL capability.
@@ -394,7 +394,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Specify which color buffers are to be drawn into
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/drawbuffer.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glDrawBuffer.xml>`_
 
    :type mode: Enumerated constant
    :arg mode: Specifies up to four color buffers to be drawn into.
@@ -404,7 +404,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Write a block of pixels to the frame buffer
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/drawpixels.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glDrawPixels.xml>`_
 
    :type width, height: int
    :arg width, height: Specify the dimensions of the pixel rectangle to be
@@ -423,7 +423,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Flag edges as either boundary or non-boundary
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/edgeflag.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glEdgeFlag.xml>`_
 
    :type flag: Depends of function prototype
    :arg flag: Specifies the current edge flag value.The initial value is GL_TRUE.
@@ -433,7 +433,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Enable server-side GL capabilities
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/enable.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glEnable.xml>`_
 
    :type cap: Enumerated constant
    :arg cap: Specifies a symbolic constant indicating a GL capability.
@@ -443,14 +443,14 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Delimit the vertices of a primitive or group of like primitives
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/begin.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glBegin.xml>`_
 
 
 .. function:: glEndList():
 
    Create or replace a display list
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/newlist.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glNewList.xml>`_
 
 
 .. function:: glEvalCoord (u,v):
@@ -460,7 +460,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Evaluate enabled one- and two-dimensional maps
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/evalcoord.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glEvalCoord.xml>`_
 
    :type u: Depends on function prototype.
    :arg u: Specifies a value that is the domain coordinate u to the basis function defined
@@ -478,7 +478,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Compute a one- or two-dimensional grid of points or lines
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/evalmesh.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glEvalMesh.xml>`_
 
    :type mode: Enumerated constant
    :arg mode: In glEvalMesh1, specifies whether to compute a one-dimensional
@@ -493,7 +493,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Generate and evaluate a single point in a mesh
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/evalpoint.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glEvalPoint.xml>`_
 
    :type i: int
    :arg i: Specifies the integer value for grid domain variable i.
@@ -505,7 +505,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Controls feedback mode
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/feedbackbuffer.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glFeedbackBuffer.xml>`_
 
    :type size: int
    :arg size: Specifies the maximum number of values that can be written into buffer.
@@ -520,14 +520,14 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Block until all GL execution is complete
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/finish.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glFinish.xml>`_
 
 
 .. function:: glFlush():
 
    Force Execution of GL commands in finite time
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/flush.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glFlush.xml>`_
 
 
 .. function:: glFog (pname, param):
@@ -536,7 +536,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Specify fog parameters
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/fog.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glFog.xml>`_
 
    :type pname: Enumerated constant
    :arg pname: Specifies a single-valued fog parameter. If the function prototype
@@ -551,7 +551,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Define front- and back-facing polygons
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/frontface.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glFrontFace.xml>`_
 
    :type mode: Enumerated constant
    :arg mode: Specifies the orientation of front-facing polygons.
@@ -561,7 +561,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Multiply the current matrix by a perspective matrix
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/frustum.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glFrustum.xml>`_
 
    :type left, right: double (float)
    :arg left, right: Specify the coordinates for the left and right vertical
@@ -578,7 +578,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Generate a contiguous set of empty display lists
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/genlists.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glGenLists.xml>`_
 
    :type range: int
    :arg range: Specifies the number of contiguous empty display lists to be generated.
@@ -588,7 +588,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Generate texture names
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/gentextures.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glGenTextures.xml>`_
 
    :type n: int
    :arg n: Specifies the number of textures name to be generated.
@@ -602,7 +602,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Return the value or values of a selected parameter
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/get.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glGet.xml>`_
 
    :type pname: Enumerated constant
    :arg pname: Specifies the parameter value to be returned.
@@ -614,7 +614,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Return the coefficients of the specified clipping plane
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/getclipplane.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glGetClipPlane.xml>`_
 
    :type plane: Enumerated constant
    :arg plane: Specifies a clipping plane. The number of clipping planes depends on the
@@ -629,7 +629,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Return error information
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/geterror.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glGetError.xml>`_
 
 
 .. function:: glGetLight (light, pname, params):
@@ -638,7 +638,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Return light source parameter values
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/getlight.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glGetLight.xml>`_
 
    :type light: Enumerated constant
    :arg light: Specifies a light source. The number of possible lights depends on the
@@ -656,7 +656,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Return evaluator parameters
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/getmap.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glGetMap.xml>`_
 
    :type target: Enumerated constant
    :arg target: Specifies the symbolic name of a map.
@@ -672,7 +672,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Return material parameters
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/getmaterial.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glGetMaterial.xml>`_
 
    :type face: Enumerated constant
    :arg face: Specifies which of the two materials is being queried.
@@ -689,7 +689,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Return the specified pixel map
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/getpixelmap.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glGetPixelMap.xml>`_
 
    :type map:  Enumerated constant
    :arg map: Specifies the name of the pixel map to return.
@@ -701,7 +701,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Return the polygon stipple pattern
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/getpolygonstipple.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glGetPolygonStipple.xml>`_
 
    :type mask: :class:`bgl.Buffer` object I{type GL_BYTE}
    :arg mask: Returns the stipple pattern. The initial value is all 1's.
@@ -711,7 +711,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Return a string describing the current GL connection
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/getstring.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glGetString.xml>`_
 
    :type name: Enumerated constant
    :arg name: Specifies a symbolic constant.
@@ -724,7 +724,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Return texture environment parameters
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/gettexenv.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glGetTexEnv.xml>`_
 
    :type target: Enumerated constant
    :arg target: Specifies a texture environment. Must be GL_TEXTURE_ENV.
@@ -740,7 +740,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Return texture coordinate generation parameters
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/gettexgen.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glGetTexGen.xml>`_
 
    :type coord: Enumerated constant
    :arg coord: Specifies a texture coordinate.
@@ -754,7 +754,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Return a texture image
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/getteximage.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glGetTexImage.xml>`_
 
    :type target: Enumerated constant
    :arg target: Specifies which texture is to be obtained.
@@ -776,7 +776,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    return texture parameter values for a specific level of detail
 
-   .. seealso:: U{opengl.org/developers/documentation/man_pages/hardcopy/GL/html/gl/gettexlevelparameter.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glGetTexLevelParameter.xml>`_
 
    :type target: Enumerated constant
    :arg target: Specifies the symbolic name of the target texture.
@@ -795,7 +795,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Return texture parameter values
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/gettexparameter.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glGetTexParameter.xml>`_
 
    :type target: Enumerated constant
    :arg target: Specifies the symbolic name of the target texture.
@@ -809,7 +809,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Specify implementation-specific hints
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/hint.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glHint.xml>`_
 
    :type target: Enumerated constant
    :arg target: Specifies a symbolic constant indicating the behavior to be
@@ -824,7 +824,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Set the current color index
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/index_.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glIndex.xml>`_
 
    :type c: :class:`bgl.Buffer` object. Depends on function prototype.
    :arg c: Specifies a pointer to a one element array that contains the new value for
@@ -835,14 +835,14 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Initialize the name stack
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/initnames.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glInitNames.xml>`_
 
 
 .. function:: glIsEnabled(cap):
 
    Test whether a capability is enabled
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/isenabled.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glIsEnabled.xml>`_
 
    :type cap: Enumerated constant
    :arg cap: Specifies a constant representing a GL capability.
@@ -852,7 +852,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Determine if a name corresponds to a display-list
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/islist.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glIsList.xml>`_
 
    :type list: unsigned int
    :arg list: Specifies a potential display-list name.
@@ -862,7 +862,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Determine if a name corresponds to a texture
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/istexture.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glIsTexture.xml>`_
 
    :type texture: unsigned int
    :arg texture: Specifies a value that may be the name of a texture.
@@ -874,7 +874,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Set the light source parameters
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/light.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glLight.xml>`_
 
    :type light: Enumerated constant
    :arg light: Specifies a light. The number of lights depends on the implementation,
@@ -894,7 +894,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Set the lighting model parameters
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/lightmodel.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glLightModel.xml>`_
 
    :type pname:  Enumerated constant
    :arg pname: Specifies a single-value light model parameter.
@@ -907,7 +907,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Specify the line stipple pattern
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/linestipple.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glLineStipple.xml>`_
 
    :type factor: int
    :arg factor: Specifies a multiplier for each bit in the line stipple pattern.
@@ -924,7 +924,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Specify the width of rasterized lines.
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/linewidth.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glLineWidth.xml>`_
 
    :type width: float
    :arg width: Specifies the width of rasterized lines. The initial value is 1.
@@ -934,7 +934,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Set the display-list base for glCallLists
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/listbase.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glListBase.xml>`_
 
    :type base: unsigned int
    :arg base: Specifies an integer offset that will be added to glCallLists
@@ -945,7 +945,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Replace the current matrix with the identity matrix
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/loadidentity.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glLoadIdentity.xml>`_
 
 
 .. function:: glLoadMatrix (m):
@@ -954,7 +954,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Replace the current matrix with the specified matrix
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/loadmatrix.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glLoadMatrix.xml>`_
 
    :type m: :class:`bgl.Buffer` object. Depends on function prototype.
    :arg m: Specifies a pointer to 16 consecutive values, which are used as the elements
@@ -965,7 +965,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Load a name onto the name stack.
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/loadname.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glLoadName.xml>`_
 
    :type name: unsigned int
    :arg name: Specifies a name that will replace the top value on the name stack.
@@ -975,7 +975,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Specify a logical pixel operation for color index rendering
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/logicop.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glLogicOp.xml>`_
 
    :type opcode: Enumerated constant
    :arg opcode: Specifies a symbolic constant that selects a logical operation.
@@ -987,7 +987,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Define a one-dimensional evaluator
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/map1.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glMap1.xml>`_
 
    :type target: Enumerated constant
    :arg target: Specifies the kind of values that are generated by the evaluator.
@@ -1012,7 +1012,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Define a two-dimensional evaluator
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/map2.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glMap2.xml>`_
 
    :type target: Enumerated constant
    :arg target: Specifies the kind of values that are generated by the evaluator.
@@ -1053,7 +1053,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Define a one- or two-dimensional mesh
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/mapgrid.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glMapGrid.xml>`_
 
    :type un: int
    :arg un: Specifies the number of partitions in the grid range interval
@@ -1072,7 +1072,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Specify material parameters for the lighting model.
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/material.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glMaterial.xml>`_
 
    :type face: Enumerated constant
    :arg face: Specifies which face or faces are being updated. Must be one of:
@@ -1089,7 +1089,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Specify which matrix is the current matrix.
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/matrixmode.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glMatrixMode.xml>`_
 
    :type mode: Enumerated constant
    :arg mode: Specifies which matrix stack is the target for subsequent matrix operations.
@@ -1101,7 +1101,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Multiply the current matrix with the specified matrix
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/multmatrix.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glMultMatrix.xml>`_
 
    :type m: :class:`bgl.Buffer` object. Depends on function prototype.
    :arg m: Points to 16 consecutive values that are used as the elements of a 4x4 column
@@ -1112,7 +1112,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Create or replace a display list
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/newlist.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glNewList.xml>`_
 
    :type list: unsigned int
    :arg list: Specifies the display list name
@@ -1127,7 +1127,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Set the current normal vector
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/normal.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glNormal.xml>`_
 
    :type nx, ny, nz: Depends on function prototype. (non - 'v' prototypes only)
    :arg nx, ny, nz: Specify the x, y, and z coordinates of the new current normal.
@@ -1141,7 +1141,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Multiply the current matrix with an orthographic matrix
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/ortho.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glOrtho.xml>`_
 
    :type left, right: double (float)
    :arg left, right: Specify the coordinates for the left and
@@ -1158,7 +1158,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Place a marker in the feedback buffer
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/passthrough.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glPassThrough.xml>`_
 
    :type token: float
    :arg token: Specifies a marker value to be placed in the feedback
@@ -1171,7 +1171,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Set up pixel transfer maps
 
-   .. seealso::  `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/pixelmap.html>`_
+   .. seealso::  `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glPixelMap.xml>`_
 
    :type map: Enumerated constant
    :arg map: Specifies a symbolic map name.
@@ -1187,7 +1187,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Set pixel storage modes
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/pixelstore.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glPixelStore.xml>`_
 
    :type pname: Enumerated constant
    :arg pname: Specifies the symbolic name of the parameter to be set.
@@ -1203,7 +1203,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Set pixel transfer modes
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/pixeltransfer.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glPixelTransfer.xml>`_
 
    :type pname: Enumerated constant
    :arg pname: Specifies the symbolic name of the pixel transfer parameter to be set.
@@ -1215,7 +1215,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Specify the pixel zoom factors
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/pixelzoom.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glPixelZoom.xml>`_
 
    :type xfactor, yfactor: float
    :arg xfactor, yfactor: Specify the x and y zoom factors for pixel write operations.
@@ -1225,7 +1225,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Specify the diameter of rasterized points
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/pointsize.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glPointSize.xml>`_
 
    :type size: float
    :arg size: Specifies the diameter of rasterized points. The initial value is 1.
@@ -1235,7 +1235,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Select a polygon rasterization mode
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/polygonmode.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glPolygonMode.xml>`_
 
    :type face: Enumerated constant
    :arg face: Specifies the polygons that mode applies to.
@@ -1250,7 +1250,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Set the scale and units used to calculate depth values
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/polygonoffset.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glPolygonOffset.xml>`_
 
    :type factor: float
    :arg factor: Specifies a scale factor that is used to create a variable depth
@@ -1264,7 +1264,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Set the polygon stippling pattern
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/polygonstipple.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glPolygonStipple.xml>`_
 
    :type mask: :class:`bgl.Buffer` object I{type GL_BYTE}
    :arg mask: Specifies a pointer to a 32x32 stipple pattern that will be unpacked
@@ -1275,35 +1275,35 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Pop the server attribute stack
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/pushattrib.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glPopAttrib.xml>`_
 
 
 .. function:: glPopClientAttrib():
 
    Pop the client attribute stack
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/pushclientattrib.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glPopClientAttrib.xml>`_
 
 
 .. function:: glPopMatrix():
 
    Pop the current matrix stack
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/pushmatrix.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glPopMatrix.xml>`_
 
 
 .. function:: glPopName():
 
    Pop the name stack
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/pushname.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glPopName.xml>`_
 
 
 .. function:: glPrioritizeTextures(n, textures, priorities):
 
    Set texture residence priority
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/prioritizetextures.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glPrioritizeTextures.xml>`_
 
    :type n: int
    :arg n: Specifies the number of textures to be prioritized.
@@ -1319,7 +1319,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Push the server attribute stack
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/pushattrib.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glPushAttrib.xml>`_
 
    :type mask: Enumerated constant(s)
    :arg mask: Specifies a mask that indicates which attributes to save.
@@ -1329,7 +1329,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Push the client attribute stack
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/pushclientattrib.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glPushClientAttrib.xml>`_
 
    :type mask: Enumerated constant(s)
    :arg mask: Specifies a mask that indicates which attributes to save.
@@ -1339,14 +1339,14 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Push the current matrix stack
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/pushmatrix.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glPushMatrix.xml>`_
 
 
 .. function:: glPushName(name):
 
    Push the name stack
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/pushname.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glPushName.xml>`_
 
    :type name: unsigned int
    :arg name: Specifies a name that will be pushed onto the name stack.
@@ -1362,7 +1362,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Specify the raster position for pixel operations
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/rasterpos.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glRasterPos.xml>`_
 
    :type x, y, z, w: Depends on function prototype. (z and w for '3' and '4' prototypes only)
    :arg x, y, z, w: Specify the x,y,z, and w object coordinates (if present) for the
@@ -1394,7 +1394,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Select a color buffer source for pixels.
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/readbuffer.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glReadBuffer.xml>`_
 
    :type mode: Enumerated constant
    :arg mode: Specifies a color buffer.
@@ -1404,7 +1404,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Read a block of pixels from the frame buffer
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/readpixels.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glReadPixels.xml>`_
 
    :type x, y: int
    :arg x, y: Specify the window coordinates of the first pixel that is read
@@ -1427,7 +1427,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Draw a rectangle
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/rect.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glRect.xml>`_
 
    :type x1, y1: Depends on function prototype. (for non 'v' prototypes only)
    :arg x1, y1: Specify one vertex of a rectangle
@@ -1442,7 +1442,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Set rasterization mode
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/rendermode.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glRenderMode.xml>`_
 
    :type mode: Enumerated constant
    :arg mode: Specifies the rasterization mode.
@@ -1454,7 +1454,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Multiply the current matrix by a rotation matrix
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/rotate.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glRotate.xml>`_
 
    :type angle:  Depends on function prototype.
    :arg angle:  Specifies the angle of rotation in degrees.
@@ -1468,7 +1468,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Multiply the current matrix by a general scaling matrix
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/scale.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glScale.xml>`_
 
    :type x, y, z: Depends on function prototype.
    :arg x, y, z: Specify scale factors along the x, y, and z axes, respectively.
@@ -1478,7 +1478,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Define the scissor box
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/scissor.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glScissor.xml>`_
 
    :type x, y: int
    :arg x, y: Specify the lower left corner of the scissor box. Initially (0, 0).
@@ -1492,7 +1492,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Establish a buffer for selection mode values
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/selectbuffer.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glSelectBuffer.xml>`_
 
    :type size: int
    :arg size: Specifies the size of buffer
@@ -1504,7 +1504,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Select flat or smooth shading
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/shademodel.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glShadeModel.xml>`_
 
    :type mode: Enumerated constant
    :arg mode: Specifies a symbolic value representing a shading technique.
@@ -1514,7 +1514,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Set function and reference value for stencil testing
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/stencilfunc.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glStencilFuc.xml>`_
 
    :type func: Enumerated constant
    :arg func: Specifies the test function.
@@ -1531,7 +1531,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Control the writing of individual bits in the stencil planes
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/stencilmask.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glStencilMask.xml>`_
 
    :type mask: unsigned int
    :arg mask: Specifies a bit mask to enable and disable writing of individual bits
@@ -1542,7 +1542,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Set stencil test actions
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/stencilop.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glStencilOp.xml>`_
 
    :type fail: Enumerated constant
    :arg fail: Specifies the action to take when the stencil test fails.
@@ -1570,7 +1570,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Set the current texture coordinates
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/texcoord.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glTexCoord.xml>`_
 
    :type s, t, r, q: Depends on function prototype. (r and q for '3' and '4' prototypes only)
    :arg s, t, r, q: Specify s, t, r, and q texture coordinates. Not all parameters are
@@ -1586,7 +1586,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Set texture environment parameters
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/texenv.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glTexEnv.xml>`_
 
    :type target: Enumerated constant
    :arg target: Specifies a texture environment. Must be GL_TEXTURE_ENV.
@@ -1605,7 +1605,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Control the generation of texture coordinates
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/texgen.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glTexGen.xml>`_
 
    :type coord: Enumerated constant
    :arg coord: Specifies a texture coordinate.
@@ -1623,7 +1623,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Specify a one-dimensional texture image
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/teximage1d.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glTexImage1D.xml>`_
 
    :type target: Enumerated constant
    :arg target: Specifies the target texture.
@@ -1650,7 +1650,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Specify a two-dimensional texture image
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/teximage2d.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glTexImage2D.xml>`_
 
    :type target: Enumerated constant
    :arg target: Specifies the target texture.
@@ -1683,7 +1683,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Set texture parameters
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/texparameter.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glTexParameter.xml>`_
 
    :type target: Enumerated constant
    :arg target: Specifies the target texture.
@@ -1700,7 +1700,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Multiply the current matrix by a translation matrix
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/translate.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glTranslate.xml>`_
 
    :type x, y, z: Depends on function prototype.
    :arg x, y, z: Specify the x, y, and z coordinates of a translation vector.
@@ -1715,7 +1715,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Specify a vertex
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/vertex.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glVertex.xml>`_
 
    :type x, y, z, w: Depends on function prototype (z and w for '3' and '4' prototypes only)
    :arg x, y, z, w: Specify x, y, z, and w coordinates of a vertex. Not all parameters
@@ -1731,7 +1731,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
 
    Set the viewport
 
-   .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/viewport.html>`_
+   .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glViewport.xml>`_
 
    :type x, y: int
    :arg x, y: Specify the lower left corner of the viewport rectangle,
index b954ff4..82f1338 100644 (file)
@@ -284,8 +284,7 @@ static void xml_read_camera(const XMLReadState& state, pugi::xml_node node)
        xml_read_float(&cam->farclip, node, "farclip");
        xml_read_float(&cam->aperturesize, node, "aperturesize"); // 0.5*focallength/fstop
        xml_read_float(&cam->focaldistance, node, "focaldistance");
-       xml_read_float(&cam->shutteropen, node, "shutteropen");
-       xml_read_float(&cam->shutterclose, node, "shutterclose");
+       xml_read_float(&cam->shuttertime, node, "shuttertime");
 
        if(xml_equal_string(node, "type", "orthographic"))
                cam->type = CAMERA_ORTHOGRAPHIC;
@@ -705,7 +704,7 @@ static void xml_read_mesh(const XMLReadState& state, pugi::xml_node node)
        }
 
        /* temporary for test compatibility */
-       mesh->attributes.remove(Attribute::STD_VERTEX_NORMAL);
+       mesh->attributes.remove(ATTR_STD_VERTEX_NORMAL);
 }
 
 /* Patch */
@@ -766,7 +765,7 @@ static void xml_read_patch(const XMLReadState& state, pugi::xml_node node)
                delete patch;
 
                /* temporary for test compatibility */
-               mesh->attributes.remove(Attribute::STD_VERTEX_NORMAL);
+               mesh->attributes.remove(ATTR_STD_VERTEX_NORMAL);
        }
 }
 
index 4159108..4a60a32 100644 (file)
 bl_info = {
     "name": "Cycles Render Engine",
     "author": "",
-    "version": (0, 0),
-    "blender": (2, 6, 2),
+    "blender": (2, 6, 3),
     "location": "Info header, render engine menu",
-    "description": "Cycles Render Engine integration.",
+    "description": "Cycles Render Engine integration",
     "warning": "",
     "wiki_url": "http://wiki.blender.org/index.php/Dev:2.6/Source/Render/Cycles",
     "tracker_url": "",
index 0ed0858..8480b0a 100644 (file)
@@ -94,6 +94,29 @@ class CyclesRender_PT_integrator(CyclesButtonsPanel, Panel):
         col.prop(cscene, "blur_glossy")
 
 
+class CyclesRender_PT_motion_blur(CyclesButtonsPanel, Panel):
+    bl_label = "Motion Blur"
+    bl_options = {'DEFAULT_CLOSED'}
+
+    @classmethod
+    def poll(cls, context):
+        return False
+
+    def draw_header(self, context):
+        rd = context.scene.render
+
+        self.layout.prop(rd, "use_motion_blur", text="")
+
+    def draw(self, context):
+        layout = self.layout
+
+        rd = context.scene.render
+        layout.active = rd.use_motion_blur
+
+        row = layout.row()
+        row.prop(rd, "motion_blur_shutter")
+
+
 class CyclesRender_PT_film(CyclesButtonsPanel, Panel):
     bl_label = "Film"
 
@@ -202,10 +225,10 @@ class CyclesRender_PT_layers(CyclesButtonsPanel, Panel):
         col.prop(rl, "use_pass_combined")
         col.prop(rl, "use_pass_z")
         col.prop(rl, "use_pass_normal")
+        col.prop(rl, "use_pass_vector")
+        col.prop(rl, "use_pass_uv")
         col.prop(rl, "use_pass_object_index")
         col.prop(rl, "use_pass_material_index")
-        col.prop(rl, "use_pass_emit")
-        col.prop(rl, "use_pass_environment")
         col.prop(rl, "use_pass_ambient_occlusion")
         col.prop(rl, "use_pass_shadow")
 
@@ -227,6 +250,9 @@ class CyclesRender_PT_layers(CyclesButtonsPanel, Panel):
         row.prop(rl, "use_pass_transmission_indirect", text="Indirect", toggle=True)
         row.prop(rl, "use_pass_transmission_color", text="Color", toggle=True)
 
+        col.prop(rl, "use_pass_emit", text="Emission")
+        col.prop(rl, "use_pass_environment")
+
 
 class Cycles_PT_post_processing(CyclesButtonsPanel, Panel):
     bl_label = "Post Processing"
index a21b22b..55a32d8 100644 (file)
@@ -35,6 +35,7 @@ struct BlenderCamera {
        float ortho_scale;
 
        float lens;
+       float shuttertime;
 
        float aperturesize;
        uint apertureblades;
@@ -64,6 +65,7 @@ static void blender_camera_init(BlenderCamera *bcam)
        bcam->sensor_width = 32.0f;
        bcam->sensor_height = 18.0f;
        bcam->sensor_fit = BlenderCamera::AUTO;
+       bcam->shuttertime = 1.0f;
 }
 
 static float blender_camera_focal_distance(BL::Object b_ob, BL::Camera b_camera)
@@ -132,6 +134,28 @@ static void blender_camera_from_object(BlenderCamera *bcam, BL::Object b_ob)
        }
 }
 
+static Transform blender_camera_matrix(const Transform& tfm, CameraType type)
+{
+       Transform result;
+
+       if(type == CAMERA_ENVIRONMENT) {
+               /* make it so environment camera needs to be pointed in the direction
+                  of the positive x-axis to match an environment texture, this way
+                  it is looking at the center of the texture */
+               result = tfm *
+                       make_transform( 0.0f, -1.0f, 0.0f, 0.0f,
+                                       0.0f,  0.0f, 1.0f, 0.0f,
+                                      -1.0f,  0.0f, 0.0f, 0.0f,
+                                       0.0f,  0.0f, 0.0f, 1.0f);
+       }
+       else {
+               /* note the blender camera points along the negative z-axis */
+               result = tfm * transform_scale(1.0f, 1.0f, -1.0f);
+       }
+
+       return transform_clear_scale(result);
+}
+
 static void blender_camera_sync(Camera *cam, BlenderCamera *bcam, int width, int height)
 {
        /* copy camera to compare later */
@@ -224,24 +248,11 @@ static void blender_camera_sync(Camera *cam, BlenderCamera *bcam, int width, int
        cam->bladesrotation = bcam->aperturerotation;
 
        /* transform */
-       cam->matrix = bcam->matrix;
-
-       if(bcam->type == CAMERA_ENVIRONMENT) {
-               /* make it so environment camera needs to be pointed in the direction
-                  of the positive x-axis to match an environment texture, this way
-                  it is looking at the center of the texture */
-               cam->matrix = cam->matrix *
-                       make_transform( 0.0f, -1.0f, 0.0f, 0.0f,
-                                       0.0f,  0.0f, 1.0f, 0.0f,
-                                      -1.0f,  0.0f, 0.0f, 0.0f,
-                                       0.0f,  0.0f, 0.0f, 1.0f);
-       }
-       else {
-               /* note the blender camera points along the negative z-axis */
-               cam->matrix = cam->matrix * transform_scale(1.0f, 1.0f, -1.0f);
-       }
-
-       cam->matrix = transform_clear_scale(cam->matrix);
+       cam->matrix = blender_camera_matrix(bcam->matrix, bcam->type);
+       cam->motion.pre = cam->matrix;
+       cam->motion.post = cam->matrix;
+       cam->use_motion = false;
+       cam->shuttertime = bcam->shuttertime;
 
        /* set update flag */
        if(cam->modified(prevcam))
@@ -260,6 +271,7 @@ void BlenderSync::sync_camera(BL::Object b_override, int width, int height)
 
        bcam.pixelaspect.x = r.pixel_aspect_x();
        bcam.pixelaspect.y = r.pixel_aspect_y();
+       bcam.shuttertime = r.motion_blur_shutter();
 
        /* camera object */
        BL::Object b_ob = b_scene.camera();
@@ -277,6 +289,23 @@ void BlenderSync::sync_camera(BL::Object b_override, int width, int height)
        blender_camera_sync(cam, &bcam, width, height);
 }
 
+void BlenderSync::sync_camera_motion(BL::Object b_ob, int motion)
+{
+       Camera *cam = scene->camera;
+
+       Transform tfm = get_transform(b_ob.matrix_world());
+       tfm = blender_camera_matrix(tfm, cam->type);
+
+       if(tfm != cam->matrix) {
+               if(motion == -1)
+                       cam->motion.pre = tfm;
+               else
+                       cam->motion.post = tfm;
+
+               cam->use_motion = true;
+       }
+}
+
 /* Sync 3D View Camera */
 
 void BlenderSync::sync_view(BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, int width, int height)
@@ -288,6 +317,7 @@ void BlenderSync::sync_view(BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, int
        bcam.nearclip = b_v3d.clip_start();
        bcam.farclip = b_v3d.clip_end();
        bcam.lens = b_v3d.lens();
+       bcam.shuttertime = b_scene.render().motion_blur_shutter();
 
        if(b_rv3d.view_perspective() == BL::RegionView3D::view_perspective_CAMERA) {
                /* camera view */
index 7caa6b3..867cc71 100644 (file)
@@ -33,30 +33,6 @@ CCL_NAMESPACE_BEGIN
 
 /* Find/Add */
 
-static bool mesh_need_attribute(Scene *scene, Mesh *mesh, Attribute::Standard std)
-{
-       if(std == Attribute::STD_NONE)
-               return false;
-
-       foreach(uint shader, mesh->used_shaders)
-               if(scene->shaders[shader]->attributes.find(std))
-                       return true;
-       
-       return false;
-}
-
-static bool mesh_need_attribute(Scene *scene, Mesh *mesh, ustring name)
-{
-       if(name == ustring())
-               return false;
-
-       foreach(uint shader, mesh->used_shaders)
-               if(scene->shaders[shader]->attributes.find(name))
-                       return true;
-       
-       return false;
-}
-
 static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector<uint>& used_shaders)
 {
        /* create vertices */
@@ -66,7 +42,7 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector<
                mesh->verts.push_back(get_float3(v->co()));
 
        /* create vertex normals */
-       Attribute *attr_N = mesh->attributes.add(Attribute::STD_VERTEX_NORMAL);
+       Attribute *attr_N = mesh->attributes.add(ATTR_STD_VERTEX_NORMAL);
        float3 *N = attr_N->data_float3();
 
        for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v, ++N)
@@ -94,8 +70,8 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector<
        /* create generated coordinates. todo: we should actually get the orco
           coordinates from modifiers, for now we use texspace loc/size which
           is available in the api. */
-       if(mesh_need_attribute(scene, mesh, Attribute::STD_GENERATED)) {
-               Attribute *attr = mesh->attributes.add(Attribute::STD_GENERATED);
+       if(mesh->need_attribute(scene, ATTR_STD_GENERATED)) {
+               Attribute *attr = mesh->attributes.add(ATTR_STD_GENERATED);
                float3 loc = get_float3(b_mesh.texspace_location());
                float3 size = get_float3(b_mesh.texspace_size());
 
@@ -118,7 +94,7 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector<
                BL::Mesh::tessface_vertex_colors_iterator l;
 
                for(b_mesh.tessface_vertex_colors.begin(l); l != b_mesh.tessface_vertex_colors.end(); ++l) {
-                       if(!mesh_need_attribute(scene, mesh, ustring(l->name().c_str())))
+                       if(!mesh->need_attribute(scene, ustring(l->name().c_str())))
                                continue;
 
                        Attribute *attr = mesh->attributes.add(
@@ -150,10 +126,10 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector<
                BL::Mesh::tessface_uv_textures_iterator l;
 
                for(b_mesh.tessface_uv_textures.begin(l); l != b_mesh.tessface_uv_textures.end(); ++l) {
-                       Attribute::Standard std = (l->active_render())? Attribute::STD_UV: Attribute::STD_NONE;
+                       AttributeStandard std = (l->active_render())? ATTR_STD_UV: ATTR_STD_NONE;
                        ustring name = ustring(l->name().c_str());
 
-                       if(!(mesh_need_attribute(scene, mesh, name) || mesh_need_attribute(scene, mesh, std)))
+                       if(!(mesh->need_attribute(scene, name) || mesh->need_attribute(scene, std)))
                                continue;
 
                        Attribute *attr;
@@ -222,11 +198,11 @@ static void create_subd_mesh(Mesh *mesh, BL::Mesh b_mesh, PointerRNA *cmesh, con
 
 /* Sync */
 
-Mesh *BlenderSync::sync_mesh(BL::Object b_ob, bool holdout, bool object_updated)
+Mesh *BlenderSync::sync_mesh(BL::Object b_ob, bool object_updated)
 {
        /* test if we can instance or if the object is modified */
        BL::ID b_ob_data = b_ob.data();
-       BL::ID key = (object_is_modified(b_ob) || holdout)? b_ob: b_ob_data;
+       BL::ID key = (object_is_modified(b_ob))? b_ob: b_ob_data;
        BL::Material material_override = render_layer.material_override;
 
        /* find shader indices */
@@ -236,18 +212,14 @@ Mesh *BlenderSync::sync_mesh(BL::Object b_ob, bool holdout, bool object_updated)
        for(b_ob.material_slots.begin(slot); slot != b_ob.material_slots.end(); ++slot) {
                BL::Material material_override = render_layer.material_override;
 
-               if(holdout)
-                       find_shader(PointerRNA_NULL, used_shaders, scene->default_holdout);
-               else if(material_override)
+               if(material_override)
                        find_shader(material_override, used_shaders, scene->default_surface);
                else
                        find_shader(slot->material(), used_shaders, scene->default_surface);
        }
 
        if(used_shaders.size() == 0) {
-               if(holdout)
-                       used_shaders.push_back(scene->default_holdout);
-               else if(material_override)
+               if(material_override)
                        find_shader(material_override, used_shaders, scene->default_surface);
                else
                        used_shaders.push_back(scene->default_surface);
@@ -329,5 +301,38 @@ Mesh *BlenderSync::sync_mesh(BL::Object b_ob, bool holdout, bool object_updated)
        return mesh;
 }
 
+void BlenderSync::sync_mesh_motion(BL::Object b_ob, Mesh *mesh, int motion)
+{
+       /* todo: displacement, subdivision */
+       BL::ID b_ob_data = b_ob.data();
+       size_t size = mesh->verts.size();
+
+       /* skip objects without deforming modifiers. this is not a totally reliable,
+        * would need a more extensive check to see which objects are animated */
+       if(!size || !ccl::object_is_deform_modified(b_ob, b_scene, preview))
+               return;
+
+       /* get derived mesh */
+       BL::Mesh b_mesh = object_to_mesh(b_ob, b_scene, true, !preview);
+
+       if(b_mesh) {
+               BL::Mesh::vertices_iterator v;
+               AttributeStandard std = (motion == -1)? ATTR_STD_MOTION_PRE: ATTR_STD_MOTION_POST;
+               Attribute *attr_M = mesh->attributes.add(std);
+               float3 *M = attr_M->data_float3();
+               size_t i = 0, size = mesh->verts.size();
+
+               for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end() && i < size; ++v, M++, i++)
+                       *M = get_float3(v->co());
+
+               /* if number of vertices changed, or if coordinates stayed the same, drop it */
+               if(i != size || memcmp(M, &mesh->verts[0], sizeof(float3)*size) == 0)
+                       mesh->attributes.remove(std);
+
+               /* free derived mesh */
+               object_remove_mesh(b_data, b_mesh);
+       }
+}
+
 CCL_NAMESPACE_END
 
index 96faee1..bbf4805 100644 (file)
@@ -16,6 +16,7 @@
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
 
+#include "camera.h"
 #include "graph.h"
 #include "light.h"
 #include "mesh.h"
@@ -188,11 +189,12 @@ void BlenderSync::sync_background_light()
 
 /* Object */
 
-void BlenderSync::sync_object(BL::Object b_parent, int b_index, BL::Object b_ob, Transform& tfm, uint layer_flag)
+void BlenderSync::sync_object(BL::Object b_parent, int b_index, BL::Object b_ob, Transform& tfm, uint layer_flag, int motion)
 {
        /* light is handled separately */
        if(object_is_light(b_ob)) {
-               sync_light(b_parent, b_index, b_ob, tfm);
+               if(!motion)
+                       sync_light(b_parent, b_index, b_ob, tfm);
                return;
        }
 
@@ -200,25 +202,54 @@ void BlenderSync::sync_object(BL::Object b_parent, int b_index, BL::Object b_ob,
        if(!object_is_mesh(b_ob))
                return;
 
-       /* test if we need to sync */
+       /* key to lookup object */
        ObjectKey key(b_parent, b_index, b_ob);
        Object *object;
+
+       /* motion vector case */
+       if(motion) {
+               object = object_map.find(key);
+
+               if(object) {
+                       if(tfm != object->tfm) {
+                               if(motion == -1)
+                                       object->motion.pre = tfm;
+                               else
+                                       object->motion.post = tfm;
+
+                               object->use_motion = true;
+                       }
+
+                       sync_mesh_motion(b_ob, object->mesh, motion);
+               }
+
+               return;
+       }
+
+       /* test if we need to sync */
        bool object_updated = false;
 
        if(object_map.sync(&object, b_ob, b_parent, key))
                object_updated = true;
        
-       /* holdout? */
-       bool holdout = (layer_flag & render_layer.holdout_layer) != 0;
-
+       bool use_holdout = (layer_flag & render_layer.holdout_layer) != 0;
+       
        /* mesh sync */
-       object->mesh = sync_mesh(b_ob, holdout, object_updated);
+       object->mesh = sync_mesh(b_ob, object_updated);
+
+       if(use_holdout != object->use_holdout) {
+               object->use_holdout = use_holdout;
+               scene->object_manager->tag_update(scene);
+       }
 
        /* object sync */
        if(object_updated || (object->mesh && object->mesh->need_update)) {
                object->name = b_ob.name().c_str();
                object->pass_id = b_ob.pass_index();
                object->tfm = tfm;
+               object->motion.pre = tfm;
+               object->motion.post = tfm;
+               object->use_motion = false;
 
                /* visibility flags for both parent */
                object->visibility = object_ray_visibility(b_ob) & PATH_RAY_ALL;
@@ -238,16 +269,18 @@ void BlenderSync::sync_object(BL::Object b_parent, int b_index, BL::Object b_ob,
 
 /* Object Loop */
 
-void BlenderSync::sync_objects(BL::SpaceView3D b_v3d)
+void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, int motion)
 {
        /* layer data */
        uint scene_layer = render_layer.scene_layer;
        
-       /* prepare for sync */
-       light_map.pre_sync();
-       mesh_map.pre_sync();
-       object_map.pre_sync();
-       mesh_synced.clear();
+       if(!motion) {
+               /* prepare for sync */
+               light_map.pre_sync();
+               mesh_map.pre_sync();
+               object_map.pre_sync();
+               mesh_synced.clear();
+       }
 
        /* object loop */
        BL::Scene::objects_iterator b_ob;
@@ -270,7 +303,7 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d)
                                        bool dup_hide = (b_v3d)? b_dup_ob.hide(): b_dup_ob.hide_render();
 
                                        if(!(b_dup->hide() || dup_hide))
-                                               sync_object(*b_ob, b_index, b_dup_ob, tfm, ob_layer);
+                                               sync_object(*b_ob, b_index, b_dup_ob, tfm, ob_layer, motion);
 
                                        b_index++;
                                }
@@ -296,21 +329,50 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d)
                        if(!hide) {
                                /* object itself */
                                Transform tfm = get_transform(b_ob->matrix_world());
-                               sync_object(*b_ob, 0, *b_ob, tfm, ob_layer);
+                               sync_object(*b_ob, 0, *b_ob, tfm, ob_layer, motion);
                        }
                }
        }
 
-       sync_background_light();
+       if(!motion) {
+               sync_background_light();
+
+               /* handle removed data and modified pointers */
+               if(light_map.post_sync())
+                       scene->light_manager->tag_update(scene);
+               if(mesh_map.post_sync())
+                       scene->mesh_manager->tag_update(scene);
+               if(object_map.post_sync())
+                       scene->object_manager->tag_update(scene);
+               mesh_synced.clear();
+       }
+}
 
-       /* handle removed data and modified pointers */
-       if(light_map.post_sync())
-               scene->light_manager->tag_update(scene);
-       if(mesh_map.post_sync())
-               scene->mesh_manager->tag_update(scene);
-       if(object_map.post_sync())
-               scene->object_manager->tag_update(scene);
-       mesh_synced.clear();
+void BlenderSync::sync_motion(BL::SpaceView3D b_v3d, BL::Object b_override)
+{
+       if(scene->need_motion() == Scene::MOTION_NONE)
+               return;
+
+       /* get camera object here to deal with camera switch */
+       BL::Object b_cam = b_scene.camera();
+       if(b_override)
+               b_cam = b_override;
+
+       /* go back and forth one frame */
+       int frame = b_scene.frame_current();
+
+       for(int motion = -1; motion <= 1; motion += 2) {
+               scene_frame_set(b_scene, frame + motion);
+
+               /* camera object */
+               if(b_cam)
+                       sync_camera_motion(b_cam, motion);
+
+               /* mesh objects */
+               sync_objects(b_v3d, motion);
+       }
+
+       scene_frame_set(b_scene, frame);
 }
 
 CCL_NAMESPACE_END
index 5ece7aa..f79b999 100644 (file)
@@ -91,7 +91,7 @@ void BlenderSession::create_session()
 
        /* create sync */
        sync = new BlenderSync(b_data, b_scene, scene, !background);
-       sync->sync_data(b_v3d);
+       sync->sync_data(b_v3d, b_engine.camera_override());
 
        if(b_rv3d)
                sync->sync_view(b_v3d, b_rv3d, width, height);
@@ -130,6 +130,8 @@ static PassType get_pass_type(BL::RenderPass b_pass)
                        return PASS_OBJECT_ID;
                case BL::RenderPass::type_UV:
                        return PASS_UV;
+               case BL::RenderPass::type_VECTOR:
+                       return PASS_MOTION;
                case BL::RenderPass::type_MATERIAL_INDEX:
                        return PASS_MATERIAL_ID;
 
@@ -168,7 +170,6 @@ static PassType get_pass_type(BL::RenderPass b_pass)
                case BL::RenderPass::type_REFRACTION:
                case BL::RenderPass::type_SPECULAR:
                case BL::RenderPass::type_REFLECTION:
-               case BL::RenderPass::type_VECTOR:
                case BL::RenderPass::type_MIST:
                        return PASS_NONE;
        }
@@ -209,6 +210,8 @@ void BlenderSession::render()
                                BL::RenderPass b_pass(*b_pass_iter);
                                PassType pass_type = get_pass_type(b_pass);
 
+                               if(pass_type == PASS_MOTION && scene->integrator->motion_blur)
+                                       continue;
                                if(pass_type != PASS_NONE)
                                        Pass::add(pass_type, passes);
                        }
@@ -219,7 +222,7 @@ void BlenderSession::render()
                scene->film->tag_update(scene);
 
                /* update scene */
-               sync->sync_data(b_v3d, b_iter->name().c_str());
+               sync->sync_data(b_v3d, b_engine.camera_override(), b_iter->name().c_str());
 
                /* update session */
                int samples = sync->get_layer_samples();
@@ -310,7 +313,7 @@ void BlenderSession::synchronize()
        }
 
        /* data and camera synchronize */
-       sync->sync_data(b_v3d);
+       sync->sync_data(b_v3d, b_engine.camera_override());
 
        if(b_rv3d)
                sync->sync_view(b_v3d, b_rv3d, width, height);
index 41cd200..24cf10b 100644 (file)
@@ -121,19 +121,21 @@ bool BlenderSync::sync_recalc()
        return recalc;
 }
 
-void BlenderSync::sync_data(BL::SpaceView3D b_v3d, const char *layer)
+void BlenderSync::sync_data(BL::SpaceView3D b_v3d, BL::Object b_override, const char *layer)
 {
        sync_render_layers(b_v3d, layer);
        sync_integrator();
        sync_film();
        sync_shaders();
        sync_objects(b_v3d);
+       sync_motion(b_v3d, b_override);
 }
 
 /* Integrator */
 
 void BlenderSync::sync_integrator()
 {
+       BL::RenderSettings r = b_scene.render();
        PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
 
        experimental = (RNA_enum_get(&cscene, "feature_set") != 0);
@@ -160,6 +162,9 @@ void BlenderSync::sync_integrator()
        integrator->layer_flag = render_layer.layer;
 
        integrator->sample_clamp = get_float(cscene, "sample_clamp");
+#ifdef __MOTION__
+       integrator->motion_blur = (!preview && r.use_motion_blur());
+#endif
 
        if(integrator->modified(previntegrator))
                integrator->tag_update(scene);
index ab8e4bd..d6a7218 100644 (file)
@@ -54,7 +54,7 @@ public:
 
        /* sync */
        bool sync_recalc();
-       void sync_data(BL::SpaceView3D b_v3d, const char *layer = 0);
+       void sync_data(BL::SpaceView3D b_v3d, BL::Object b_override, const char *layer = 0);
        void sync_camera(BL::Object b_override, int width, int height);
        void sync_view(BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, int width, int height);
        int get_layer_samples() { return render_layer.samples; }
@@ -69,7 +69,8 @@ private:
        /* sync */
        void sync_lamps();
        void sync_materials();
-       void sync_objects(BL::SpaceView3D b_v3d);
+       void sync_objects(BL::SpaceView3D b_v3d, int motion = 0);
+       void sync_motion(BL::SpaceView3D b_v3d, BL::Object b_override);
        void sync_film();
        void sync_integrator();
        void sync_view();
@@ -78,10 +79,12 @@ private:
        void sync_shaders();
 
        void sync_nodes(Shader *shader, BL::ShaderNodeTree b_ntree);
-       Mesh *sync_mesh(BL::Object b_ob, bool holdout, bool object_updated);
-       void sync_object(BL::Object b_parent, int b_index, BL::Object b_object, Transform& tfm, uint layer_flag);
+       Mesh *sync_mesh(BL::Object b_ob, bool object_updated);
+       void sync_object(BL::Object b_parent, int b_index, BL::Object b_object, Transform& tfm, uint layer_flag, int motion);
        void sync_light(BL::Object b_parent, int b_index, BL::Object b_ob, Transform& tfm);
        void sync_background_light();
+       void sync_mesh_motion(BL::Object b_ob, Mesh *mesh, int motion);
+       void sync_camera_motion(BL::Object b_ob, int motion);
 
        /* util */
        void find_shader(BL::ID id, vector<uint>& used_shaders, int default_shader);
index 67f3a3a..9184e14 100644 (file)
@@ -49,8 +49,10 @@ void RE_engine_update_progress(struct RenderEngine *engine, float progress);
 void engine_tag_redraw(void *engine);
 void engine_tag_update(void *engine);
 int rna_Object_is_modified(void *ob, void *scene, int settings);
+int rna_Object_is_deform_modified(void *ob, void *scene, int settings);
 void BLI_timestr(double _time, char *str);
 void rna_ColorRamp_eval(void *coba, float position, float color[4]);
+void rna_Scene_frame_set(void *scene, int frame, float subframe);
 
 }
 
@@ -94,6 +96,16 @@ static inline bool object_is_modified(BL::Object self, BL::Scene scene, bool pre
        return rna_Object_is_modified(self.ptr.data, scene.ptr.data, (preview)? (1<<0): (1<<1))? true: false;
 }
 
+static inline bool object_is_deform_modified(BL::Object self, BL::Scene scene, bool preview)
+{
+       return rna_Object_is_deform_modified(self.ptr.data, scene.ptr.data, (preview)? (1<<0): (1<<1))? true: false;
+}
+
+static inline void scene_frame_set(BL::Scene scene, int frame)
+{
+       rna_Scene_frame_set(scene.ptr.data, frame, 0.0f);
+}
+
 /* Utilities */
 
 static inline Transform get_transform(BL::Array<float, 16> array)
index c5b4f1d..d865426 100644 (file)
@@ -175,7 +175,7 @@ BVHNode* BVHBuild::run()
        }
        else {
                /* multithreaded binning build */
-               BVHObjectBinning rootbin(root, &references[0]);
+               BVHObjectBinning rootbin(root, (references.size())? &references[0]: NULL);
                rootnode = build_node(rootbin, 0);
                task_pool.wait();
        }
index 523ae8a..5da4253 100644 (file)
@@ -57,7 +57,7 @@ __device_inline float3 bvh_inverse_direction(float3 dir)
 
 __device_inline void bvh_instance_push(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *idir, float *t, const float tmax)
 {
-       Transform tfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
+       Transform tfm = object_fetch_transform(kg, object, ray->time, OBJECT_INVERSE_TRANSFORM);
 
        *P = transform_point(&tfm, ray->P);
 
@@ -74,7 +74,7 @@ __device_inline void bvh_instance_push(KernelGlobals *kg, int object, const Ray
 
 __device_inline void bvh_instance_pop(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *idir, float *t, const float tmax)
 {
-       Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
+       Transform tfm = object_fetch_transform(kg, object, ray->time, OBJECT_TRANSFORM);
 
        if(*t != FLT_MAX)
                *t *= len(transform_direction(&tfm, 1.0f/(*idir)));
@@ -341,7 +341,7 @@ __device_inline float3 ray_offset(float3 P, float3 Ng)
 #endif
 }
 
-__device_inline float3 bvh_triangle_refine(KernelGlobals *kg, const Intersection *isect, const Ray *ray)
+__device_inline float3 bvh_triangle_refine(KernelGlobals *kg, ShaderData *sd, const Intersection *isect, const Ray *ray)
 {
        float3 P = ray->P;
        float3 D = ray->D;
@@ -349,7 +349,11 @@ __device_inline float3 bvh_triangle_refine(KernelGlobals *kg, const Intersection
 
 #ifdef __INTERSECTION_REFINE__
        if(isect->object != ~0) {
-               Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_INVERSE_TRANSFORM);
+#ifdef __MOTION__
+               Transform tfm = sd->ob_itfm;
+#else
+               Transform tfm = object_fetch_transform(kg, isect->object, ray->time, OBJECT_INVERSE_TRANSFORM);
+#endif
 
                P = transform_point(&tfm, P);
                D = transform_direction(&tfm, D*t);
@@ -366,7 +370,12 @@ __device_inline float3 bvh_triangle_refine(KernelGlobals *kg, const Intersection
        P = P + D*rt;
 
        if(isect->object != ~0) {
-               Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_TRANSFORM);
+#ifdef __MOTION__
+               Transform tfm = sd->ob_tfm;
+#else
+               Transform tfm = object_fetch_transform(kg, isect->object, ray->time, OBJECT_TRANSFORM);
+#endif
+
                P = transform_point(&tfm, P);
        }
 
index 58c4822..e4b10f6 100644 (file)
@@ -63,6 +63,11 @@ __device void camera_sample_perspective(KernelGlobals *kg, float raster_x, float
        /* transform ray from camera to world */
        Transform cameratoworld = kernel_data.cam.cameratoworld;
 
+#ifdef __MOTION__
+       if(kernel_data.cam.have_motion)
+               transform_motion_interpolate(&cameratoworld, &kernel_data.cam.motion, ray->time);
+#endif
+
        ray->P = transform_point(&cameratoworld, ray->P);
        ray->D = transform_direction(&cameratoworld, ray->D);
        ray->D = normalize(ray->D);
@@ -101,6 +106,11 @@ __device void camera_sample_orthographic(KernelGlobals *kg, float raster_x, floa
        /* transform ray from camera to world */
        Transform cameratoworld = kernel_data.cam.cameratoworld;
 
+#ifdef __MOTION__
+       if(kernel_data.cam.have_motion)
+               transform_motion_interpolate(&cameratoworld, &kernel_data.cam.motion, ray->time);
+#endif
+
        ray->P = transform_point(&cameratoworld, ray->P);
        ray->D = transform_direction(&cameratoworld, ray->D);
        ray->D = normalize(ray->D);
@@ -130,12 +140,17 @@ __device void camera_sample_environment(KernelGlobals *kg, float raster_x, float
        float3 Pcamera = transform_perspective(&rastertocamera, make_float3(raster_x, raster_y, 0.0f));
 
        /* create ray form raster position */
-       ray->P = make_float3(0.0, 0.0f, 0.0f);
+       ray->P = make_float3(0.0f, 0.0f, 0.0f);
        ray->D = equirectangular_to_direction(Pcamera.x, Pcamera.y);
 
        /* transform ray from camera to world */
        Transform cameratoworld = kernel_data.cam.cameratoworld;
 
+#ifdef __MOTION__
+       if(kernel_data.cam.have_motion)
+               transform_motion_interpolate(&cameratoworld, &kernel_data.cam.motion, ray->time);
+#endif
+
        ray->P = transform_point(&cameratoworld, ray->P);
        ray->D = transform_direction(&cameratoworld, ray->D);
        ray->D = normalize(ray->D);
@@ -162,14 +177,20 @@ __device void camera_sample_environment(KernelGlobals *kg, float raster_x, float
 
 /* Common */
 
-__device void camera_sample(KernelGlobals *kg, int x, int y, float filter_u, float filter_v, float lens_u, float lens_v, Ray *ray)
+__device void camera_sample(KernelGlobals *kg, int x, int y, float filter_u, float filter_v,
+       float lens_u, float lens_v, float time, Ray *ray)
 {
        /* pixel filter */
        float raster_x = x + kernel_tex_interp(__filter_table, filter_u, FILTER_TABLE_SIZE);
        float raster_y = y + kernel_tex_interp(__filter_table, filter_v, FILTER_TABLE_SIZE);
 
+#ifdef __MOTION__
        /* motion blur */
-       //ray->time = lerp(time_t, kernel_data.cam.shutter_open, kernel_data.cam.shutter_close);
+       if(kernel_data.cam.shuttertime == 0.0f)
+               ray->time = TIME_INVALID;
+       else
+               ray->time = 0.5f + (time - 0.5f)*kernel_data.cam.shuttertime;
+#endif
 
        /* sample */
        if(kernel_data.cam.type == CAMERA_PERSPECTIVE)
index 9fbd856..a9d1858 100644 (file)
@@ -78,7 +78,7 @@ __device float kernel_tex_interp_(__global float *data, int width, float x)
 
 #define make_float2(x, y) ((float2)(x, y))
 #ifdef __CL_NO_FLOAT3__
-#define make_float3(x, y, z) ((float4)(x, y, z, 0.0))
+#define make_float3(x, y, z) ((float4)(x, y, z, 0.0f))
 #else
 #define make_float3(x, y, z) ((float3)(x, y, z))
 #endif
index 764ac59..0ef1425 100644 (file)
@@ -21,7 +21,7 @@ CCL_NAMESPACE_BEGIN
 /* Direction Emission */
 
 __device float3 direct_emissive_eval(KernelGlobals *kg, float rando,
-       LightSample *ls, float u, float v, float3 I)
+       LightSample *ls, float u, float v, float3 I, float t, float time)
 {
        /* setup shading at emitter */
        ShaderData sd;
@@ -40,7 +40,7 @@ __device float3 direct_emissive_eval(KernelGlobals *kg, float rando,
        else
 #endif
        {
-               shader_setup_from_sample(kg, &sd, ls->P, ls->Ng, I, ls->shader, ls->object, ls->prim, u, v);
+               shader_setup_from_sample(kg, &sd, ls->P, ls->Ng, I, ls->shader, ls->object, ls->prim, u, v, t, time);
                ls->Ng = sd.Ng;
 
                /* no path flag, we're evaluating this for all closures. that's weak but
@@ -76,7 +76,7 @@ __device bool direct_emission(KernelGlobals *kg, ShaderData *sd, int lindex,
 #endif
        {
                /* sample a light and position on int */
-               light_sample(kg, randt, randu, randv, sd->P, &ls, &pdf);
+               light_sample(kg, randt, randu, randv, sd->time, sd->P, &ls, &pdf);
        }
 
        /* compute pdf */
@@ -87,7 +87,7 @@ __device bool direct_emission(KernelGlobals *kg, ShaderData *sd, int lindex,
                return false;
 
        /* evaluate closure */
-       float3 light_eval = direct_emissive_eval(kg, rando, &ls, randu, randv, -ls.D);
+       float3 light_eval = direct_emissive_eval(kg, rando, &ls, randu, randv, -ls.D, ls.t, sd->time);
 
        if(is_zero(light_eval))
                return false;
index 4226057..c2cf293 100644 (file)
@@ -251,7 +251,7 @@ __device float regular_light_pdf(KernelGlobals *kg,
 /* Triangle Light */
 
 __device void triangle_light_sample(KernelGlobals *kg, int prim, int object,
-       float randu, float randv, LightSample *ls)
+       float randu, float randv, float time, LightSample *ls)
 {
        /* triangle, so get position, normal, shader */
        ls->P = triangle_sample_MT(kg, prim, randu, randv);
@@ -264,8 +264,11 @@ __device void triangle_light_sample(KernelGlobals *kg, int prim, int object,
 #ifdef __INSTANCING__
        /* instance transform */
        if(ls->object >= 0) {
-               object_position_transform(kg, ls->object, &ls->P);
-               object_normal_transform(kg, ls->object, &ls->Ng);
+               Transform tfm = object_fetch_transform(kg, ls->object, time, OBJECT_TRANSFORM);
+               Transform itfm = object_fetch_transform(kg, ls->object, time, OBJECT_INVERSE_TRANSFORM);
+
+               ls->P = transform_point(&tfm, ls->P);
+               ls->Ng = transform_direction_transposed(&itfm, ls->Ng);
        }
 #endif
 }
@@ -313,7 +316,7 @@ __device int light_distribution_sample(KernelGlobals *kg, float randt)
 
 /* Generic Light */
 
-__device void light_sample(KernelGlobals *kg, float randt, float randu, float randv, float3 P, LightSample *ls, float *pdf)
+__device void light_sample(KernelGlobals *kg, float randt, float randu, float randv, float time, float3 P, LightSample *ls, float *pdf)
 {
        /* sample index */
        int index = light_distribution_sample(kg, randt);
@@ -324,7 +327,7 @@ __device void light_sample(KernelGlobals *kg, float randt, float randu, float ra
 
        if(prim >= 0) {
                int object = __float_as_int(l.w);
-               triangle_light_sample(kg, prim, object, randu, randv, ls);
+               triangle_light_sample(kg, prim, object, randu, randv, time, ls);
        }
        else {
                int point = -prim-1;
index b676f58..4a3ef55 100644 (file)
@@ -20,41 +20,91 @@ CCL_NAMESPACE_BEGIN
 
 enum ObjectTransform {
        OBJECT_TRANSFORM = 0,
-       OBJECT_INVERSE_TRANSFORM = 4,
-       OBJECT_NORMAL_TRANSFORM = 8,
-       OBJECT_PROPERTIES = 12
+       OBJECT_INVERSE_TRANSFORM = 3,
+       OBJECT_PROPERTIES = 6,
+       OBJECT_TRANSFORM_MOTION_PRE = 8,
+       OBJECT_TRANSFORM_MOTION_POST = 12
 };
 
-__device_inline Transform object_fetch_transform(KernelGlobals *kg, int object, enum ObjectTransform type)
+__device_inline Transform object_fetch_transform(KernelGlobals *kg, int object, float time, enum ObjectTransform type)
 {
        Transform tfm;
 
+#ifdef __MOTION__
+       /* if we do motion blur */
+       if(sd->flag & SD_OBJECT_MOTION) {
+               /* fetch motion transforms */
+               MotionTransform motion;
+
+               motion.pre.x = have_motion;
+               motion.pre.y = kernel_tex_fetch(__objects, offset + 1);
+               motion.pre.z = kernel_tex_fetch(__objects, offset + 2);
+               motion.pre.w = kernel_tex_fetch(__objects, offset + 3);
+
+               motion.post.x = kernel_tex_fetch(__objects, offset + 4);
+               motion.post.y = kernel_tex_fetch(__objects, offset + 5);
+               motion.post.z = kernel_tex_fetch(__objects, offset + 6);
+               motion.post.w = kernel_tex_fetch(__objects, offset + 7);
+
+               /* interpolate (todo: do only once per object) */
+               transform_motion_interpolate(&tfm, &motion, time);
+
+               /* invert */
+               if(type == OBJECT_INVERSE_TRANSFORM)
+                       tfm = transform_quick_inverse(tfm);
+
+               return tfm;
+       }
+#endif
+
        int offset = object*OBJECT_SIZE + (int)type;
 
        tfm.x = kernel_tex_fetch(__objects, offset + 0);
        tfm.y = kernel_tex_fetch(__objects, offset + 1);
        tfm.z = kernel_tex_fetch(__objects, offset + 2);
-       tfm.w = kernel_tex_fetch(__objects, offset + 3);
+       tfm.w = make_float4(0.0f, 0.0f, 0.0f, 1.0f);
 
        return tfm;
 }
 
-__device_inline void object_position_transform(KernelGlobals *kg, int object, float3 *P)
+__device_inline void object_position_transform(KernelGlobals *kg, ShaderData *sd, float3 *P)
 {
-       Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
+#ifdef __MOTION__
+       *P = transform_point(&sd->ob_tfm, *P);
+#else
+       Transform tfm = object_fetch_transform(kg, sd->object, TIME_INVALID, OBJECT_TRANSFORM);
        *P = transform_point(&tfm, *P);
+#endif
+}
+
+__device_inline void object_inverse_normal_transform(KernelGlobals *kg, ShaderData *sd, float3 *N)
+{
+#ifdef __MOTION__
+       *N = normalize(transform_direction_transposed(&sd->ob_tfm, *N));
+#else
+       Transform tfm = object_fetch_transform(kg, sd->object, TIME_INVALID, OBJECT_TRANSFORM);
+       *N = normalize(transform_direction_transposed(&tfm, *N));
+#endif
 }
 
-__device_inline void object_normal_transform(KernelGlobals *kg, int object, float3 *N)
+__device_inline void object_normal_transform(KernelGlobals *kg, ShaderData *sd, float3 *N)
 {
-       Transform tfm = object_fetch_transform(kg, object, OBJECT_NORMAL_TRANSFORM);
-       *N = normalize(transform_direction(&tfm, *N));
+#ifdef __MOTION__
+       *N = normalize(transform_direction_transposed(&sd->ob_itfm, *N));
+#else
+       Transform tfm = object_fetch_transform(kg, sd->object, TIME_INVALID, OBJECT_INVERSE_TRANSFORM);
+       *N = normalize(transform_direction_transposed(&tfm, *N));
+#endif
 }
 
-__device_inline void object_dir_transform(KernelGlobals *kg, int object, float3 *D)
+__device_inline void object_dir_transform(KernelGlobals *kg, ShaderData *sd, float3 *D)
 {
-       Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
+#ifdef __MOTION__
+       *D = transform_direction(&sd->ob_tfm, *D);
+#else
+       Transform tfm = object_fetch_transform(kg, sd->object, 0.0f, OBJECT_TRANSFORM);
        *D = transform_direction(&tfm, *D);
+#endif
 }
 
 __device_inline float object_surface_area(KernelGlobals *kg, int object)
index fd4ee17..f3ddda4 100644 (file)
@@ -72,9 +72,14 @@ __device_inline void kernel_write_data_passes(KernelGlobals *kg, __global float
                        kernel_write_pass_float3(buffer + kernel_data.film.pass_normal, sample, normal);
                }
                if(flag & PASS_UV) {
-                       float3 uv = make_float3(0.0f, 0.0f, 0.0f); /* todo: request and lookup */
+                       float3 uv = triangle_uv(kg, sd);
                        kernel_write_pass_float3(buffer + kernel_data.film.pass_uv, sample, uv);
                }
+               if(flag & PASS_MOTION) {
+                       float4 speed = triangle_motion_vector(kg, sd);
+                       kernel_write_pass_float4(buffer + kernel_data.film.pass_motion, sample, speed);
+                       kernel_write_pass_float(buffer + kernel_data.film.pass_motion_weight, sample, 1.0f);
+               }
        }
 
        if(flag & (PASS_DIFFUSE_INDIRECT|PASS_DIFFUSE_COLOR|PASS_DIFFUSE_DIRECT))
index 8ebac17..87d996e 100644 (file)
@@ -18,8 +18,8 @@
 
 #include "kernel_differential.h"
 #include "kernel_montecarlo.h"
-#include "kernel_triangle.h"
 #include "kernel_object.h"
+#include "kernel_triangle.h"
 #ifdef __QBVH__
 #include "kernel_qbvh.h"
 #else
@@ -277,12 +277,21 @@ __device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, R
 
                /* holdout */
 #ifdef __HOLDOUT__
-               if((sd.flag & SD_HOLDOUT) && (state.flag & PATH_RAY_CAMERA)) {
-                       float3 holdout_weight = shader_holdout_eval(kg, &sd);
+               if((sd.flag & (SD_HOLDOUT|SD_HOLDOUT_MASK)) && (state.flag & PATH_RAY_CAMERA)) {
+                       if(kernel_data.background.transparent) {
+                               float3 holdout_weight;
+                               
+                               if(sd.flag & SD_HOLDOUT_MASK)
+                                       holdout_weight = make_float3(1.0f, 1.0f, 1.0f);
+                               else
+                                       shader_holdout_eval(kg, &sd);
 
-                       if(kernel_data.background.transparent)
                                /* any throughput is ok, should all be identical here */
                                L_transparent += average(holdout_weight*throughput);
+                       }
+
+                       if(sd.flag & SD_HOLDOUT_MASK)
+                               break;
                }
 #endif
 
@@ -324,6 +333,9 @@ __device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, R
                                light_ray.P = ray_offset(sd.P, sd.Ng);
                                light_ray.D = ao_D;
                                light_ray.t = kernel_data.background.ao_distance;
+#ifdef __MOTION__
+                               light_ray.time = sd.time;
+#endif
 
                                if(!shadow_blocked(kg, &state, &light_ray, &ao_shadow)) {
                                        float3 ao_bsdf = shader_bsdf_diffuse(kg, &sd)*kernel_data.background.ao_factor;
@@ -346,6 +358,10 @@ __device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, R
                                BsdfEval L_light;
                                bool is_lamp;
 
+#ifdef __MOTION__
+                               light_ray.time = sd.time;
+#endif
+
 #ifdef __MULTI_LIGHT__
                                /* index -1 means randomly sample from distribution */
                                int i = (kernel_data.integrator.num_distribution)? -1: 0;
@@ -449,7 +465,13 @@ __device void kernel_path_trace(KernelGlobals *kg,
        float lens_u = path_rng(kg, &rng, sample, PRNG_LENS_U);
        float lens_v = path_rng(kg, &rng, sample, PRNG_LENS_V);
 
-       camera_sample(kg, x, y, filter_u, filter_v, lens_u, lens_v, &ray);
+#ifdef __MOTION__
+       float time = path_rng(kg, &rng, sample, PRNG_TIME);
+#else
+       float time = 0.0f;
+#endif
+
+       camera_sample(kg, x, y, filter_u, filter_v, lens_u, lens_v, time, &ray);
 
        /* integrate */
        float4 L = kernel_path_integrate(kg, &rng, sample, ray, buffer);
index 46ef5d2..af821ba 100644 (file)
@@ -53,16 +53,9 @@ __device_inline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
        float3 Ng = make_float3(Ns.x, Ns.y, Ns.z);
        int shader = __float_as_int(Ns.w);
 
-       /* vectors */
-       sd->P = bvh_triangle_refine(kg, isect, ray);
-       sd->Ng = Ng;
-       sd->N = Ng;
-       sd->I = -ray->D;
-       sd->shader = shader;
-
        /* triangle */
 #ifdef __INSTANCING__
-       sd->object = isect->object;
+       sd->object = (isect->object == ~0)? kernel_tex_fetch(__prim_object, isect->prim): isect->object;
 #endif
        sd->prim = prim;
 #ifdef __UV__
@@ -70,11 +63,28 @@ __device_inline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
        sd->v = isect->v;
 #endif
 
+       /* matrices and time */
+#ifdef __MOTION__
+       sd->ob_tfm = object_fetch_transform(kg, sd->object, ray->time, OBJECT_TRANSFORM);
+       sd->ob_itfm = object_fetch_transform(kg, sd->object, ray->time, OBJECT_INVERSE_TRANSFORM);
+
+       sd->time = ray->time;
+#endif
+
+       /* vectors */
+       sd->P = bvh_triangle_refine(kg, sd, isect, ray);
+       sd->Ng = Ng;
+       sd->N = Ng;
+       sd->I = -ray->D;
+       sd->shader = shader;
+       sd->ray_length = isect->t;
+
        /* smooth normal */
        if(sd->shader & SHADER_SMOOTH_NORMAL)
                sd->N = triangle_smooth_normal(kg, sd->prim, sd->u, sd->v);
 
        sd->flag = kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2);
+       sd->flag |= kernel_tex_fetch(__object_flag, sd->object);
 
 #ifdef __DPDU__
        /* dPdu/dPdv */
@@ -82,19 +92,15 @@ __device_inline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
 #endif
 
 #ifdef __INSTANCING__
-       if(sd->object != ~0) {
+       if(isect->object != ~0) {
                /* instance transform */
-               object_normal_transform(kg, sd->object, &sd->N);
-               object_normal_transform(kg, sd->object, &sd->Ng);
+               object_normal_transform(kg, sd, &sd->N);
+               object_normal_transform(kg, sd, &sd->Ng);
 #ifdef __DPDU__
-               object_dir_transform(kg, sd->object, &sd->dPdu);
-               object_dir_transform(kg, sd->object, &sd->dPdv);
+               object_dir_transform(kg, sd, &sd->dPdu);
+               object_dir_transform(kg, sd, &sd->dPdv);
 #endif
        }
-       else {
-               /* non-instanced object index */
-               sd->object = kernel_tex_fetch(__prim_object, isect->prim);
-       }
 #endif
 
        /* backfacing test */
@@ -122,7 +128,7 @@ __device_inline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
 
 __device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
        const float3 P, const float3 Ng, const float3 I,
-       int shader, int object, int prim,  float u, float v)
+       int shader, int object, int prim, float u, float v, float t, float time)
 {
        /* vectors */
        sd->P = P;
@@ -140,6 +146,7 @@ __device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
        sd->u = u;
        sd->v = v;
 #endif
+       sd->ray_length = t;
 
        /* detect instancing, for non-instanced the object index is -object-1 */
 #ifdef __INSTANCING__
@@ -155,17 +162,25 @@ __device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
        }
 #endif
 
+#ifdef __MOTION__
+       sd->time = time;
+
+       sd->ob_tfm = object_fetch_transform(kg, sd->object, time, OBJECT_TRANSFORM);
+       sd->ob_itfm = object_fetch_transform(kg, sd->object, time, OBJECT_INVERSE_TRANSFORM);
+#endif
+
        /* smooth normal */
        if(sd->shader & SHADER_SMOOTH_NORMAL) {
                sd->N = triangle_smooth_normal(kg, sd->prim, sd->u, sd->v);
 
 #ifdef __INSTANCING__
                if(instanced)
-                       object_normal_transform(kg, sd->object, &sd->N);
+                       object_normal_transform(kg, sd, &sd->N);
 #endif
        }
 
        sd->flag = kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2);
+       sd->flag |= kernel_tex_fetch(__object_flag, sd->object);
 
 #ifdef __DPDU__
        /* dPdu/dPdv */
@@ -178,8 +193,8 @@ __device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
 
 #ifdef __INSTANCING__
                if(instanced) {
-                       object_dir_transform(kg, sd->object, &sd->dPdu);
-                       object_dir_transform(kg, sd->object, &sd->dPdv);
+                       object_dir_transform(kg, sd, &sd->dPdu);
+                       object_dir_transform(kg, sd, &sd->dPdv);
                }
 #endif
        }
@@ -229,7 +244,7 @@ __device void shader_setup_from_displace(KernelGlobals *kg, ShaderData *sd,
 
        /* watch out: no instance transform currently */
 
-       shader_setup_from_sample(kg, sd, P, Ng, I, shader, object, prim, u, v);
+       shader_setup_from_sample(kg, sd, P, Ng, I, shader, object, prim, u, v, 0.0f, TIME_INVALID);
 }
 
 /* ShaderData setup from ray into background */
@@ -243,6 +258,10 @@ __device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderData
        sd->I = -sd->P;
        sd->shader = kernel_data.background.shader;
        sd->flag = kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2);
+#ifdef __MOTION__
+       sd->time = ray->time;
+#endif
+       sd->ray_length = 0.0f;
 
 #ifdef __INSTANCING__
        sd->object = ~0;
index 8bab735..f4de4c1 100644 (file)
@@ -39,6 +39,7 @@ KERNEL_TEX(float2, texture_float2, __light_background_conditional_cdf)
 /* shaders */
 KERNEL_TEX(uint4, texture_uint4, __svm_nodes)
 KERNEL_TEX(uint, texture_uint, __shader_flag)
+KERNEL_TEX(uint, texture_uint, __object_flag)
 
 /* camera/film */
 KERNEL_TEX(float, texture_float, __filter_table)
index 7eaf54d..1b3956c 100644 (file)
@@ -179,5 +179,68 @@ __device float3 triangle_attribute_float3(KernelGlobals *kg, const ShaderData *s
        }
 }
 
+/* motion */
+
+__device int triangle_find_attribute(KernelGlobals *kg, ShaderData *sd, uint id)
+{
+       /* find attribute by unique id */
+       uint attr_offset = sd->object*kernel_data.bvh.attributes_map_stride;
+       uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
+
+       while(attr_map.x != id)
+               attr_map = kernel_tex_fetch(__attributes_map, ++attr_offset);
+
+       /* return result */
+       return (attr_map.y == ATTR_ELEMENT_NONE)? ATTR_STD_NOT_FOUND: attr_map.z;
+}
+
+__device float4 triangle_motion_vector(KernelGlobals *kg, ShaderData *sd)
+{
+       float3 motion_pre = sd->P, motion_post = sd->P;
+
+       /* deformation motion */
+       int offset_pre = triangle_find_attribute(kg, sd, ATTR_STD_MOTION_PRE);
+       int offset_post = triangle_find_attribute(kg, sd, ATTR_STD_MOTION_POST);
+
+       if(offset_pre != ATTR_STD_NOT_FOUND)
+               motion_pre = triangle_attribute_float3(kg, sd, ATTR_ELEMENT_VERTEX, offset_pre, NULL, NULL);
+       if(offset_post != ATTR_STD_NOT_FOUND)
+               motion_post = triangle_attribute_float3(kg, sd, ATTR_ELEMENT_VERTEX, offset_post, NULL, NULL);
+
+       /* object motion. note that depending on the mesh having motion vectors, this
+          transformation was set match the world/object space of motion_pre/post */
+       Transform tfm;
+       
+       tfm = object_fetch_transform(kg, sd->object, TIME_INVALID, OBJECT_TRANSFORM_MOTION_PRE);
+       motion_pre = transform_point(&tfm, motion_pre);
+
+       tfm = object_fetch_transform(kg, sd->object, TIME_INVALID, OBJECT_TRANSFORM_MOTION_POST);
+       motion_post = transform_point(&tfm, motion_post);
+
+       /* camera motion */
+       tfm = kernel_data.cam.worldtoraster;
+       float3 P = transform_perspective(&tfm, sd->P);
+
+       tfm = kernel_data.cam.motion.pre;
+       motion_pre = transform_perspective(&tfm, motion_pre) - P;
+
+       tfm = kernel_data.cam.motion.post;
+       motion_post = P - transform_perspective(&tfm, motion_post);
+
+       return make_float4(motion_pre.x, motion_pre.y, motion_post.x, motion_post.y);
+}
+
+__device float3 triangle_uv(KernelGlobals *kg, ShaderData *sd)
+{
+       int offset_uv = triangle_find_attribute(kg, sd, ATTR_STD_UV);
+
+       if(offset_uv == ATTR_STD_NOT_FOUND)
+               return make_float3(0.0f, 0.0f, 0.0f);
+
+       float3 uv = triangle_attribute_float3(kg, sd, ATTR_ELEMENT_CORNER, offset_uv, NULL, NULL);
+       uv.z = 1.0f;
+       return uv;
+}
+
 CCL_NAMESPACE_END
 
index 102a2bb..85ee16f 100644 (file)
 #define __KERNEL_TYPES_H__
 
 #include "kernel_math.h"
-
 #include "svm/svm_types.h"
 
+#ifndef __KERNEL_GPU__
+#define __KERNEL_CPU__
+#endif
+
 CCL_NAMESPACE_BEGIN
 
 /* constants */
@@ -30,6 +33,7 @@ CCL_NAMESPACE_BEGIN
 #define LIGHT_SIZE                     4
 #define FILTER_TABLE_SIZE      256
 #define RAMP_TABLE_SIZE                256
+#define TIME_INVALID           FLT_MAX
 
 /* device capabilities */
 #ifdef __KERNEL_CPU__
@@ -75,6 +79,7 @@ CCL_NAMESPACE_BEGIN
 #define __PASSES__
 #define __BACKGROUND_MIS__
 #define __AO__
+//#define __MOTION__
 #endif
 
 //#define __MULTI_LIGHT__
@@ -90,14 +95,21 @@ enum ShaderEvalType {
        SHADER_EVAL_BACKGROUND
 };
 
-/* Path Tracing */
+/* Path Tracing
+ * note we need to keep the u/v pairs at even values */
 
 enum PathTraceDimension {
        PRNG_FILTER_U = 0,
        PRNG_FILTER_V = 1,
        PRNG_LENS_U = 2,
        PRNG_LENS_V = 3,
+#ifdef __MOTION__
+       PRNG_TIME = 4,
+       PRNG_UNUSED = 5,
+       PRNG_BASE_NUM = 6,
+#else
        PRNG_BASE_NUM = 4,
+#endif
 
        PRNG_BSDF_U = 0,
        PRNG_BSDF_V = 1,
@@ -177,7 +189,9 @@ typedef enum PassType {
        PASS_EMISSION = 65536,
        PASS_BACKGROUND = 131072,
        PASS_AO = 262144,
-       PASS_SHADOW = 524288
+       PASS_SHADOW = 524288,
+       PASS_MOTION = 1048576,
+       PASS_MOTION_WEIGHT = 2097152
 } PassType;
 
 #define PASS_ALL (~0)
@@ -275,6 +289,7 @@ typedef struct Ray {
        float3 P;
        float3 D;
        float t;
+       float time;
 
 #ifdef __RAY_DIFFERENTIALS__
        differential3 dP;
@@ -300,6 +315,21 @@ typedef enum AttributeElement {
        ATTR_ELEMENT_NONE
 } AttributeElement;
 
+typedef enum AttributeStandard {
+       ATTR_STD_NONE = 0,
+       ATTR_STD_VERTEX_NORMAL,
+       ATTR_STD_FACE_NORMAL,
+       ATTR_STD_UV,
+       ATTR_STD_GENERATED,
+       ATTR_STD_POSITION_UNDEFORMED,
+       ATTR_STD_POSITION_UNDISPLACED,
+       ATTR_STD_MOTION_PRE,
+       ATTR_STD_MOTION_POST,
+       ATTR_STD_NUM,
+
+       ATTR_STD_NOT_FOUND = ~0
+} AttributeStandard;
+
 /* Closure data */
 
 #define MAX_CLOSURE 8
@@ -340,7 +370,11 @@ enum ShaderDataFlag {
        SD_SAMPLE_AS_LIGHT = 128,                       /* direct light sample */
        SD_HAS_SURFACE_TRANSPARENT = 256,       /* has surface transparency */
        SD_HAS_VOLUME = 512,                            /* has volume shader */
-       SD_HOMOGENEOUS_VOLUME = 1024            /* has homogeneous volume */
+       SD_HOMOGENEOUS_VOLUME = 1024,           /* has homogeneous volume */
+
+       /* object flags */
+       SD_HOLDOUT_MASK = 2048,                         /* holdout for camera rays */
+       SD_OBJECT_MOTION = 4096                         /* has object motion blur */
 };
 
 typedef struct ShaderData {
@@ -365,6 +399,19 @@ typedef struct ShaderData {
        /* object id if there is one, ~0 otherwise */
        int object;
 
+       /* motion blur sample time */
+       float time;
+       
+       /* length of the ray being shaded */
+       float ray_length;
+
+#ifdef __MOTION__
+       /* object <-> world space transformations, cached to avoid
+        * re-interpolating them constantly for shading */
+       Transform ob_tfm;
+       Transform ob_itfm;
+#endif
+
 #ifdef __RAY_DIFFERENTIALS__
        /* differential of P. these are orthogonal to Ng, not N */
        differential3 dP;
@@ -422,8 +469,8 @@ typedef struct KernelCamera {
        float focaldistance;
 
        /* motion blur */
-       float shutteropen;
-       float shutterclose;
+       float shuttertime;
+       int have_motion;
 
        /* clipping */
        float nearclip;
@@ -437,6 +484,8 @@ typedef struct KernelCamera {
        Transform worldtoraster;
        Transform worldtondc;
        Transform worldtocamera;
+
+       MotionTransform motion;
 } KernelCamera;
 
 typedef struct KernelFilm {
@@ -448,27 +497,32 @@ typedef struct KernelFilm {
        int pass_combined;
        int pass_depth;
        int pass_normal;
-       int pass_pad;
+       int pass_motion;
 
+       int pass_motion_weight;
        int pass_uv;
        int pass_object_id;
        int pass_material_id;
-       int pass_diffuse_color;
 
+       int pass_diffuse_color;
        int pass_glossy_color;
        int pass_transmission_color;
        int pass_diffuse_indirect;
-       int pass_glossy_indirect;
 
+       int pass_glossy_indirect;
        int pass_transmission_indirect;
        int pass_diffuse_direct;
        int pass_glossy_direct;
-       int pass_transmission_direct;
 
+       int pass_transmission_direct;
        int pass_emission;
        int pass_background;
        int pass_ao;
+
        int pass_shadow;
+       int pass_pad1;
+       int pass_pad2;
+       int pass_pad3;
 } KernelFilm;
 
 typedef struct KernelBackground {
index 4a89670..c62a01a 100644 (file)
@@ -23,11 +23,11 @@ __device void svm_node_gamma(ShaderData *sd, float *stack, uint in_gamma, uint i
        float3 color = stack_load_float3(stack, in_color);
        float gamma = stack_load_float(stack, in_gamma);
 
-       if (color.x > 0.0)
+       if (color.x > 0.0f)
                color.x = powf(color.x, gamma);
-       if (color.y > 0.0)
+       if (color.y > 0.0f)
                color.y = powf(color.y, gamma);
-       if (color.z > 0.0)
+       if (color.z > 0.0f)
                color.z = powf(color.z, gamma);
 
        if (stack_valid(out_color))
index 1b13fd9..ebbcb5b 100644 (file)
@@ -33,6 +33,7 @@ __device void svm_node_light_path(ShaderData *sd, float *stack, uint type, uint
                case NODE_LP_reflection: info = (path_flag & PATH_RAY_REFLECT)? 1.0f: 0.0f; break;
                case NODE_LP_transmission: info = (path_flag & PATH_RAY_TRANSMIT)? 1.0f: 0.0f; break;
                case NODE_LP_backfacing: info = (sd->flag & SD_BACKFACING)? 1.0f: 0.0f; break;
+               case NODE_LP_ray_length: info = sd->ray_length; break;
        }
 
        stack_store_float(stack, out_offset, info);
index 98f8734..3b73cac 100644 (file)
@@ -33,8 +33,8 @@ __device void svm_node_tex_coord(KernelGlobals *kg, ShaderData *sd, float *stack
        switch(type) {
                case NODE_TEXCO_OBJECT: {
                        if(sd->object != ~0) {
-                               Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM);
-                               data = transform_point(&tfm, sd->P);
+                               data = sd->P;
+                               object_position_transform(kg, sd, &data);
                        }
                        else
                                data = sd->P;
@@ -42,8 +42,8 @@ __device void svm_node_tex_coord(KernelGlobals *kg, ShaderData *sd, float *stack
                }
                case NODE_TEXCO_NORMAL: {
                        if(sd->object != ~0) {
-                               Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM);
-                               data = transform_direction(&tfm, sd->N);
+                               data = sd->N;
+                               object_inverse_normal_transform(kg, sd, &data);
                        }
                        else
                                data = sd->N;
@@ -87,8 +87,8 @@ __device void svm_node_tex_coord_bump_dx(KernelGlobals *kg, ShaderData *sd, floa
        switch(type) {
                case NODE_TEXCO_OBJECT: {
                        if(sd->object != ~0) {
-                               Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM);
-                               data = transform_point(&tfm, sd->P + sd->dP.dx);
+                               data = sd->P + sd->dP.dx;
+                               object_position_transform(kg, sd, &data);
                        }
                        else
                                data = sd->P + sd->dP.dx;
@@ -96,8 +96,8 @@ __device void svm_node_tex_coord_bump_dx(KernelGlobals *kg, ShaderData *sd, floa
                }
                case NODE_TEXCO_NORMAL: {
                        if(sd->object != ~0) {
-                               Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM);
-                               data = transform_direction(&tfm, sd->N);
+                               data = sd->N;
+                               object_inverse_normal_transform(kg, sd, &data);
                        }
                        else
                                data = sd->N;
@@ -144,8 +144,8 @@ __device void svm_node_tex_coord_bump_dy(KernelGlobals *kg, ShaderData *sd, floa
        switch(type) {
                case NODE_TEXCO_OBJECT: {
                        if(sd->object != ~0) {
-                               Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM);
-                               data = transform_point(&tfm, sd->P + sd->dP.dy);
+                               data = sd->P + sd->dP.dy;
+                               object_position_transform(kg, sd, &data);
                        }
                        else
                                data = sd->P + sd->dP.dy;
@@ -153,8 +153,8 @@ __device void svm_node_tex_coord_bump_dy(KernelGlobals *kg, ShaderData *sd, floa
                }
                case NODE_TEXCO_NORMAL: {
                        if(sd->object != ~0) {
-                               Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM);
-                               data = normalize(transform_direction(&tfm, sd->N));
+                               data = sd->N;
+                               object_inverse_normal_transform(kg, sd, &data);
                        }
                        else
                                data = sd->N;
index fa7c211..8037c39 100644 (file)
@@ -115,7 +115,8 @@ typedef enum NodeLightPath {
        NODE_LP_singular,
        NODE_LP_reflection,
        NODE_LP_transmission,
-       NODE_LP_backfacing
+       NODE_LP_backfacing,
+       NODE_LP_ray_length
 } NodeLightPath;
 
 typedef enum NodeTexCoord {
index db92cf4..4d4fbfe 100644 (file)
@@ -16,7 +16,7 @@ set(SRC
        buffers.cpp
        camera.cpp
        film.cpp
-       # film_response.cpp  # XXX, why isn't this in?
+       # film_response.cpp (code unused)
        filter.cpp
        graph.cpp
        image.cpp
@@ -41,7 +41,7 @@ set(SRC_HEADERS
        buffers.h
        camera.h
        film.h
-       # film_response.h  # XXX, why isn't this in?
+       # film_response.h (code unused)
        filter.h
        graph.h
        image.h
index 9e90bf1..c1a089c 100644 (file)
@@ -31,7 +31,7 @@ void Attribute::set(ustring name_, TypeDesc type_, Element element_)
        name = name_;
        type = type_;
        element = element_;
-       std = STD_NONE;
+       std = ATTR_STD_NONE;
 
        /* string and matrix not supported! */
        assert(type == TypeDesc::TypeFloat || type == TypeDesc::TypeColor ||
@@ -81,20 +81,24 @@ bool Attribute::same_storage(TypeDesc a, TypeDesc b)
        return false;
 }
 
-ustring Attribute::standard_name(Attribute::Standard std)
+ustring Attribute::standard_name(AttributeStandard std)
 {
-       if(std == Attribute::STD_VERTEX_NORMAL)
+       if(std == ATTR_STD_VERTEX_NORMAL)
                return ustring("N");
-       else if(std == Attribute::STD_FACE_NORMAL)
+       else if(std == ATTR_STD_FACE_NORMAL)
                return ustring("Ng");
-       else if(std == Attribute::STD_UV)
+       else if(std == ATTR_STD_UV)
                return ustring("uv");
-       else if(std == Attribute::STD_GENERATED)
+       else if(std == ATTR_STD_GENERATED)
                return ustring("generated");
-       else if(std == Attribute::STD_POSITION_UNDEFORMED)
+       else if(std == ATTR_STD_POSITION_UNDEFORMED)
                return ustring("undeformed");
-       else if(std == Attribute::STD_POSITION_UNDISPLACED)
+       else if(std == ATTR_STD_POSITION_UNDISPLACED)
                return ustring("undisplaced");
+       else if(std == ATTR_STD_MOTION_PRE)
+               return ustring("motion_pre");
+       else if(std == ATTR_STD_MOTION_POST)
+               return ustring("motion_post");
 
        return ustring();
 }
@@ -164,24 +168,28 @@ void AttributeSet::remove(ustring name)
        }
 }
 
-Attribute *AttributeSet::add(Attribute::Standard std, ustring name)
+Attribute *AttributeSet::add(AttributeStandard std, ustring name)
 {
        Attribute *attr = NULL;
 
        if(name == ustring())
                name = Attribute::standard_name(std);
 
-       if(std == Attribute::STD_VERTEX_NORMAL)
+       if(std == ATTR_STD_VERTEX_NORMAL)
                attr = add(name, TypeDesc::TypeNormal, Attribute::VERTEX);
-       else if(std == Attribute::STD_FACE_NORMAL)
+       else if(std == ATTR_STD_FACE_NORMAL)
                attr = add(name, TypeDesc::TypeNormal, Attribute::FACE);
-       else if(std == Attribute::STD_UV)
+       else if(std == ATTR_STD_UV)
                attr = add(name, TypeDesc::TypePoint, Attribute::CORNER);
-       else if(std == Attribute::STD_GENERATED)
+       else if(std == ATTR_STD_GENERATED)
                attr = add(name, TypeDesc::TypePoint, Attribute::VERTEX);
-       else if(std == Attribute::STD_POSITION_UNDEFORMED)
+       else if(std == ATTR_STD_POSITION_UNDEFORMED)
                attr = add(name, TypeDesc::TypePoint, Attribute::VERTEX);
-       else if(std == Attribute::STD_POSITION_UNDISPLACED)
+       else if(std == ATTR_STD_POSITION_UNDISPLACED)
+               attr = add(name, TypeDesc::TypePoint, Attribute::VERTEX);
+       else if(std == ATTR_STD_MOTION_PRE)
+               attr = add(name, TypeDesc::TypePoint, Attribute::VERTEX);
+       else if(std == ATTR_STD_MOTION_POST)
                attr = add(name, TypeDesc::TypePoint, Attribute::VERTEX);
        else
                assert(0);
@@ -191,7 +199,7 @@ Attribute *AttributeSet::add(Attribute::Standard std, ustring name)
        return attr;
 }
 
-Attribute *AttributeSet::find(Attribute::Standard std)
+Attribute *AttributeSet::find(AttributeStandard std)
 {
        foreach(Attribute& attr, attributes)
                if(attr.std == std)
@@ -200,7 +208,7 @@ Attribute *AttributeSet::find(Attribute::Standard std)
        return NULL;
 }
 
-void AttributeSet::remove(Attribute::Standard std)
+void AttributeSet::remove(AttributeStandard std)
 {
        Attribute *attr = find(std);
 
@@ -218,7 +226,7 @@ void AttributeSet::remove(Attribute::Standard std)
 
 Attribute *AttributeSet::find(AttributeRequest& req)
 {
-       if(req.std == Attribute::STD_NONE)
+       if(req.std == ATTR_STD_NONE)
                return find(req.name);
        else
                return find(req.std);
@@ -240,14 +248,14 @@ void AttributeSet::clear()
 AttributeRequest::AttributeRequest(ustring name_)
 {
        name = name_;
-       std = Attribute::STD_NONE;
+       std = ATTR_STD_NONE;
 
        type = TypeDesc::TypeFloat;
        element = ATTR_ELEMENT_NONE;
        offset = 0;
 }
 
-AttributeRequest::AttributeRequest(Attribute::Standard std_)
+AttributeRequest::AttributeRequest(AttributeStandard std_)
 {
        name = ustring();
        std = std_;
@@ -296,7 +304,7 @@ void AttributeRequestSet::add(ustring name)
        requests.push_back(AttributeRequest(name));
 }
 
-void AttributeRequestSet::add(Attribute::Standard std)
+void AttributeRequestSet::add(AttributeStandard std)
 {
        foreach(AttributeRequest& req, requests)
                if(req.std == std)
@@ -308,7 +316,7 @@ void AttributeRequestSet::add(Attribute::Standard std)
 void AttributeRequestSet::add(AttributeRequestSet& reqs)
 {
        foreach(AttributeRequest& req, reqs.requests) {
-               if(req.std == Attribute::STD_NONE)
+               if(req.std == ATTR_STD_NONE)
                        add(req.name);
                else
                        add(req.std);
@@ -324,7 +332,7 @@ bool AttributeRequestSet::find(ustring name)
        return false;
 }
 
-bool AttributeRequestSet::find(Attribute::Standard std)
+bool AttributeRequestSet::find(AttributeStandard std)
 {
        foreach(AttributeRequest& req, requests)
                if(req.std == std)
index 7af4657..707d558 100644 (file)
@@ -47,19 +47,8 @@ public:
                CORNER
        };
 
-       enum Standard {
-               STD_NONE = 0,
-               STD_VERTEX_NORMAL,
-               STD_FACE_NORMAL,
-               STD_UV,
-               STD_GENERATED,
-               STD_POSITION_UNDEFORMED,
-               STD_POSITION_UNDISPLACED,
-               STD_NUM
-       };
-
        ustring name;
-       Standard std;
+       AttributeStandard std;
 
        TypeDesc type;
        vector<char> buffer;
@@ -82,7 +71,7 @@ public:
        const float *data_float() const { return (float*)data(); }
 
        static bool same_storage(TypeDesc a, TypeDesc b);
-       static ustring standard_name(Attribute::Standard std);
+       static ustring standard_name(AttributeStandard std);
 };
 
 /* Attribute Set
@@ -101,9 +90,9 @@ public:
        Attribute *find(ustring name);
        void remove(ustring name);
 
-       Attribute *add(Attribute::Standard std, ustring name = ustring());
-       Attribute *find(Attribute::Standard std);
-       void remove(Attribute::Standard std);
+       Attribute *add(AttributeStandard std, ustring name = ustring());
+       Attribute *find(AttributeStandard std);
+       void remove(AttributeStandard std);
 
        Attribute *find(AttributeRequest& req);
 
@@ -120,7 +109,7 @@ public:
 class AttributeRequest {
 public:
        ustring name;
-       Attribute::Standard std;
+       AttributeStandard std;
 
        /* temporary variables used by MeshManager */
        TypeDesc type;
@@ -128,7 +117,7 @@ public:
        int offset;
 
        AttributeRequest(ustring name_);
-       AttributeRequest(Attribute::Standard std);
+       AttributeRequest(AttributeStandard std);
 };
 
 /* AttributeRequestSet
@@ -143,11 +132,11 @@ public:
        ~AttributeRequestSet();
 
        void add(ustring name);
-       void add(Attribute::Standard std);
+       void add(AttributeStandard std);
        void add(AttributeRequestSet& reqs);
 
        bool find(ustring name);
-       bool find(Attribute::Standard std);
+       bool find(AttributeStandard std);
 
        size_t size();
        void clear();
index bda20a8..a80851b 100644 (file)
@@ -221,6 +221,28 @@ bool RenderBuffers::get_pass(PassType type, float exposure, int sample, int comp
                                        pixels[3] = 1.0f;
                                }
                        }
+                       else if(type == PASS_MOTION) {
+                               /* need to normalize by number of samples accumulated for motion */
+                               pass_offset = 0;
+                               foreach(Pass& color_pass, params.passes) {
+                                       if(color_pass.type == PASS_MOTION_WEIGHT)
+                                               break;
+                                       pass_offset += color_pass.components;
+                               }
+
+                               float *in_weight = (float*)buffer.data_pointer + pass_offset;
+
+                               for(int i = 0; i < size; i++, in += pass_stride, in_weight += pass_stride, pixels += 4) {
+                                       float4 f = make_float4(in[0], in[1], in[2], in[3]);
+                                       float w = in_weight[0];
+                                       float invw = (w > 0.0f)? 1.0f/w: 0.0f;
+
+                                       pixels[0] = f.x*invw;
+                                       pixels[1] = f.y*invw;
+                                       pixels[2] = f.z*invw;
+                                       pixels[3] = f.w*invw;
+                               }
+                       }
                        else {
                                for(int i = 0; i < size; i++, in += pass_stride, pixels += 4) {
                                        float4 f = make_float4(in[0], in[1], in[2], in[3]);
index f9290df..f0b7787 100644 (file)
@@ -25,8 +25,7 @@ CCL_NAMESPACE_BEGIN
 
 Camera::Camera()
 {
-       shutteropen = 0.0f;
-       shutterclose = 1.0f;
+       shuttertime = 1.0f;
 
        aperturesize = 0.0f;
        focaldistance = 10.0f;
@@ -35,6 +34,10 @@ Camera::Camera()
 
        matrix = transform_identity();
 
+       motion.pre = transform_identity();
+       motion.post = transform_identity();
+       use_motion = false;
+
        type = CAMERA_PERSPECTIVE;
        fov = M_PI_F/4.0f;
 
@@ -124,7 +127,7 @@ void Camera::update()
        need_device_update = true;
 }
 
-void Camera::device_update(Device *device, DeviceScene *dscene)
+void Camera::device_update(Device *device, DeviceScene *dscene, Scene *scene)
 {
        update();
 
@@ -140,10 +143,32 @@ void Camera::device_update(Device *device, DeviceScene *dscene)
        kcam->rastertocamera = rastertocamera;
        kcam->cameratoworld = cameratoworld;
        kcam->worldtoscreen = transform_inverse(screentoworld);
-       kcam->worldtoraster = transform_inverse(rastertoworld);
+       kcam->worldtoraster = worldtoraster;
        kcam->worldtondc = transform_inverse(ndctoworld);
        kcam->worldtocamera = transform_inverse(cameratoworld);
 
+       /* camera motion */
+       Scene::MotionType need_motion = scene->need_motion();
+       kcam->have_motion = 0;
+
+       if(need_motion == Scene::MOTION_PASS) {
+               if(use_motion) {
+                       kcam->motion.pre = transform_inverse(motion.pre * rastertocamera);
+                       kcam->motion.post = transform_inverse(motion.post * rastertocamera);
+               }
+               else {
+                       kcam->motion.pre = worldtoraster;
+                       kcam->motion.post = worldtoraster;
+               }
+       }
+       else if(need_motion == Scene::MOTION_BLUR) {
+               /* todo: exact camera position will not be hit this way */
+               if(use_motion) {
+                       transform_motion_decompose(&kcam->motion, &motion);
+                       kcam->have_motion = 1;
+               }
+       }
+
        /* depth of field */
        kcam->aperturesize = aperturesize;
        kcam->focaldistance = focaldistance;
@@ -151,8 +176,7 @@ void Camera::device_update(Device *device, DeviceScene *dscene)
        kcam->bladesrotation = bladesrotation;
 
        /* motion blur */
-       kcam->shutteropen = shutteropen;
-       kcam->shutterclose = shutterclose;
+       kcam->shuttertime= (need_motion == Scene::MOTION_BLUR)? shuttertime: 0.0f;
 
        /* type */
        kcam->type = type;
@@ -175,8 +199,7 @@ void Camera::device_free(Device *device, DeviceScene *dscene)
 
 bool Camera::modified(const Camera& cam)
 {
-       return !((shutteropen == cam.shutteropen) &&
-               (shutterclose == cam.shutterclose) &&
+       return !((shuttertime== cam.shuttertime) &&
                (aperturesize == cam.aperturesize) &&
                (blades == cam.blades) &&
                (bladesrotation == cam.bladesrotation) &&
@@ -192,7 +215,9 @@ bool Camera::modified(const Camera& cam)
                (right == cam.right) &&
                (bottom == cam.bottom) &&
                (top == cam.top) &&
-               (matrix == cam.matrix));
+               (matrix == cam.matrix) &&
+               (motion == cam.motion) &&
+               (use_motion == cam.use_motion));
 }
 
 void Camera::tag_update()
index cfcc540..9354897 100644 (file)
@@ -28,6 +28,7 @@ CCL_NAMESPACE_BEGIN
 
 class Device;
 class DeviceScene;
+class Scene;
 
 /* Camera
  *
@@ -37,8 +38,7 @@ class DeviceScene;
 class Camera {
 public:
        /* motion blur */
-       float shutteropen;
-       float shutterclose;
+       float shuttertime;
 
        /* depth of field */
        float focaldistance;
@@ -61,6 +61,10 @@ public:
        /* transformation */
        Transform matrix;
 
+       /* motion */
+       MotionTransform motion;
+       bool use_motion;
+
        /* computed camera parameters */
     Transform screentoworld;
        Transform rastertoworld;
@@ -82,7 +86,7 @@ public:
 
        void update();
 
-       void device_update(Device *device, DeviceScene *dscene);
+       void device_update(Device *device, DeviceScene *dscene, Scene *scene);
        void device_free(Device *device, DeviceScene *dscene);
 
        bool modified(const Camera& cam);
index cc17f86..55c89b7 100644 (file)
@@ -67,6 +67,13 @@ void Pass::add(PassType type, vector<Pass>& passes)
                case PASS_UV:
                        pass.components = 4;
                        break;
+               case PASS_MOTION:
+                       pass.components = 4;
+                       pass.divide_type = PASS_MOTION_WEIGHT;
+                       break;
+               case PASS_MOTION_WEIGHT:
+                       pass.components = 1;
+                       break;
                case PASS_OBJECT_ID:
                        pass.components = 1;
                        pass.filter = false;
@@ -154,6 +161,15 @@ bool Pass::equals(const vector<Pass>& A, const vector<Pass>& B)
        return true;
 }
 
+bool Pass::contains(const vector<Pass>& passes, PassType type)
+{
+       foreach(const Pass& pass, passes)
+               if(pass.type == type)
+                       return true;
+       
+       return false;
+}
+
 /* Film */
 
 Film::Film()
@@ -196,6 +212,12 @@ void Film::device_update(Device *device, DeviceScene *dscene)
                        case PASS_UV:
                                kfilm->pass_uv = kfilm->pass_stride;
                                break;
+                       case PASS_MOTION:
+                               kfilm->pass_motion = kfilm->pass_stride;
+                               break;
+                       case PASS_MOTION_WEIGHT:
+                               kfilm->pass_motion_weight = kfilm->pass_stride;
+                               break;
                        case PASS_OBJECT_ID:
                                kfilm->pass_object_id = kfilm->pass_stride;
                                break;
index 8a3dbbf..c7d2ee2 100644 (file)
@@ -40,6 +40,7 @@ public:
 
        static void add(PassType type, vector<Pass>& passes);
        static bool equals(const vector<Pass>& A, const vector<Pass>& B);
+       static bool contains(const vector<Pass>& passes, PassType);
 };
 
 class Film {
index cc29047..d9486de 100644 (file)
@@ -120,9 +120,9 @@ void ShaderNode::attributes(AttributeRequestSet *attributes)
        foreach(ShaderInput *input, inputs) {
                if(!input->link) {
                        if(input->default_value == ShaderInput::TEXTURE_GENERATED)
-                               attributes->add(Attribute::STD_GENERATED);
+                               attributes->add(ATTR_STD_GENERATED);
                        else if(input->default_value == ShaderInput::TEXTURE_UV)
-                               attributes->add(Attribute::STD_UV);
+                               attributes->add(ATTR_STD_UV);
                }
        }
 }
index c1f066d..b26ebfd 100644 (file)
@@ -45,6 +45,7 @@ Integrator::Integrator()
        seed = 0;
        layer_flag = ~0;
        sample_clamp = 0.0f;
+       motion_blur = false;
 
        need_update = true;
 }
@@ -125,7 +126,8 @@ bool Integrator::modified(const Integrator& integrator)
                filter_glossy == integrator.filter_glossy &&
                layer_flag == integrator.layer_flag &&
                seed == integrator.seed &&
-               sample_clamp == integrator.sample_clamp);
+               sample_clamp == integrator.sample_clamp &&
+               motion_blur == integrator.motion_blur);
 }
 
 void Integrator::tag_update(Scene *scene)
index 0817fca..afda41a 100644 (file)
@@ -47,6 +47,7 @@ public:
        int layer_flag;
 
        float sample_clamp;
+       bool motion_blur;
 
        bool need_update;
 
index 0ce16e6..5d96611 100644 (file)
@@ -113,11 +113,11 @@ void Mesh::compute_bounds()
 void Mesh::add_face_normals()
 {
        /* don't compute if already there */
-       if(attributes.find(Attribute::STD_FACE_NORMAL))
+       if(attributes.find(ATTR_STD_FACE_NORMAL))
                return;
 
        /* get attributes */
-       Attribute *attr_fN = attributes.add(Attribute::STD_FACE_NORMAL);
+       Attribute *attr_fN = attributes.add(ATTR_STD_FACE_NORMAL);
        float3 *fN = attr_fN->data_float3();
 
        /* compute face normals */
@@ -145,12 +145,12 @@ void Mesh::add_face_normals()
 void Mesh::add_vertex_normals()
 {
        /* don't compute if already there */
-       if(attributes.find(Attribute::STD_VERTEX_NORMAL))
+       if(attributes.find(ATTR_STD_VERTEX_NORMAL))
                return;
 
        /* get attributes */
-       Attribute *attr_fN = attributes.find(Attribute::STD_FACE_NORMAL);
-       Attribute *attr_vN = attributes.add(Attribute::STD_VERTEX_NORMAL);
+       Attribute *attr_fN = attributes.find(ATTR_STD_FACE_NORMAL);
+       Attribute *attr_vN = attributes.add(ATTR_STD_VERTEX_NORMAL);
 
        float3 *fN = attr_fN->data_float3();
        float3 *vN = attr_vN->data_float3();
@@ -179,8 +179,8 @@ void Mesh::add_vertex_normals()
 
 void Mesh::pack_normals(Scene *scene, float4 *normal, float4 *vnormal)
 {
-       Attribute *attr_fN = attributes.find(Attribute::STD_FACE_NORMAL);
-       Attribute *attr_vN = attributes.find(Attribute::STD_VERTEX_NORMAL);
+       Attribute *attr_fN = attributes.find(ATTR_STD_FACE_NORMAL);
+       Attribute *attr_vN = attributes.find(ATTR_STD_VERTEX_NORMAL);
 
        float3 *fN = attr_fN->data_float3();
        float3 *vN = attr_vN->data_float3();
@@ -348,7 +348,7 @@ void MeshManager::update_osl_attributes(Device *device, Scene *scene, vector<Att
                        else
                                osl_attr.type = TypeDesc::TypeColor;
 
-                       if(req.std != Attribute::STD_NONE) {
+                       if(req.std != ATTR_STD_NONE) {
                                /* if standard attribute, add lookup by std:: name convention */
                                ustring stdname = ustring(string("std::") + Attribute::standard_name(req.std).c_str());
                                og->attribute_map[i][stdname] = osl_attr;
@@ -371,7 +371,7 @@ void MeshManager::update_svm_attributes(Device *device, DeviceScene *dscene, Sce
        int attr_map_stride = 0;
 
        for(size_t i = 0; i < scene->meshes.size(); i++)
-               attr_map_stride = max(attr_map_stride, mesh_attributes[i].size());
+               attr_map_stride = max(attr_map_stride, mesh_attributes[i].size()+1);
 
        if(attr_map_stride == 0)
                return;
@@ -393,13 +393,12 @@ void MeshManager::update_svm_attributes(Device *device, DeviceScene *dscene, Sce
                AttributeRequestSet& attributes = mesh_attributes[j];
 
                /* set object attributes */
-               j = 0;
+               int index = i*attr_map_stride;
 
                foreach(AttributeRequest& req, attributes.requests) {
-                       int index = i*attr_map_stride + j;
                        uint id;
 
-                       if(req.std == Attribute::STD_NONE)
+                       if(req.std == ATTR_STD_NONE)
                                id = scene->shader_manager->get_attribute_id(req.name);
                        else
                                id = scene->shader_manager->get_attribute_id(req.std);
@@ -413,8 +412,14 @@ void MeshManager::update_svm_attributes(Device *device, DeviceScene *dscene, Sce
                        else
                                attr_map[index].w = NODE_ATTR_FLOAT3;
 
-                       j++;
+                       index++;
                }
+
+               /* terminator */
+               attr_map[index].x = ATTR_STD_NONE;
+               attr_map[index].y = 0;
+               attr_map[index].z = 0;
+               attr_map[index].w = 0;
        }
 
        /* copy to device */
@@ -434,6 +439,8 @@ void MeshManager::device_update_attributes(Device *device, DeviceScene *dscene,
        for(size_t i = 0; i < scene->meshes.size(); i++) {
                Mesh *mesh = scene->meshes[i];
 
+               scene->need_global_attributes(mesh_attributes[i]);
+
                foreach(uint sindex, mesh->used_shaders) {
                        Shader *shader = scene->shaders[sindex];
                        mesh_attributes[i].add(shader->attributes);
@@ -456,8 +463,8 @@ void MeshManager::device_update_attributes(Device *device, DeviceScene *dscene,
                        Attribute *mattr = mesh->attributes.find(req);
 
                        /* todo: get rid of this exception */
-                       if(!mattr && req.std == Attribute::STD_GENERATED) {
-                               mattr = mesh->attributes.add(Attribute::STD_GENERATED);
+                       if(!mattr && req.std == ATTR_STD_GENERATED) {
+                               mattr = mesh->attributes.add(ATTR_STD_GENERATED);
                                if(mesh->verts.size())
                                        memcpy(mattr->data_float3(), &mesh->verts[0], sizeof(float3)*mesh->verts.size());
                        }
@@ -489,19 +496,19 @@ void MeshManager::device_update_attributes(Device *device, DeviceScene *dscene,
                                float *data = mattr->data_float();
                                req.offset = attr_float.size();
 
+                               attr_float.resize(attr_float.size() + size);
+
                                for(size_t k = 0; k < size; k++)
-                                       attr_float.push_back(data[k]);
+                                       attr_float[req.offset+k] = data[k];
                        }
                        else {
                                float3 *data = mattr->data_float3();
                                req.offset = attr_float3.size();
 
-                               for(size_t k = 0; k < size; k++) {
-                                       float3 f3 = data[k];
-                                       float4 f4 = make_float4(f3.x, f3.y, f3.z, 0.0f);
+                               attr_float3.resize(attr_float3.size() + size);
 
-                                       attr_float3.push_back(f4);
-                               }
+                               for(size_t k = 0; k < size; k++)
+                                       attr_float3[req.offset+k] = float3_to_float4(data[k]);
                        }
 
                        /* mesh vertex/triangle index is global, not per object, so we sneak
@@ -712,8 +719,10 @@ void MeshManager::device_update(Device *device, DeviceScene *dscene, Scene *scen
        foreach(Shader *shader, scene->shaders)
                shader->need_update_attributes = false;
 
+       bool motion_blur = scene->need_motion() == Scene::MOTION_BLUR;
+
        foreach(Object *object, scene->objects)
-               object->compute_bounds();
+               object->compute_bounds(motion_blur);
 
        if(progress.get_cancel()) return;
 
@@ -759,5 +768,32 @@ void MeshManager::tag_update(Scene *scene)
        scene->object_manager->need_update = true;
 }
 
+bool Mesh::need_attribute(Scene *scene, AttributeStandard std)
+{
+       if(std == ATTR_STD_NONE)
+               return false;
+       
+       if(scene->need_global_attribute(std))
+               return true;
+
+       foreach(uint shader, used_shaders)
+               if(scene->shaders[shader]->attributes.find(std))
+                       return true;
+       
+       return false;
+}
+
+bool Mesh::need_attribute(Scene *scene, ustring name)
+{
+       if(name == ustring())
+               return false;
+
+       foreach(uint shader, used_shaders)
+               if(scene->shaders[shader]->attributes.find(name))
+                       return true;
+       
+       return false;
+}
+
 CCL_NAMESPACE_END
 
index 5852034..047a2d2 100644 (file)
@@ -98,6 +98,9 @@ public:
        void pack_verts(float4 *tri_verts, float4 *tri_vindex, size_t vert_offset);
        void compute_bvh(SceneParams *params, Progress& progress);
 
+       bool need_attribute(Scene *scene, AttributeStandard std);
+       bool need_attribute(Scene *scene, ustring name);
+
        void tag_update(Scene *scene, bool rebuild);
 };
 
index a6f8e3f..dea694a 100644 (file)
@@ -140,11 +140,11 @@ bool MeshManager::displace(Device *device, Scene *scene, Mesh *mesh, Progress& p
         * normals, as bump mapping in the shader will already alter the
         * vertex normal, so we start from the non-displaced vertex normals
         * to avoid applying the perturbation twice. */
-       mesh->attributes.remove(Attribute::STD_FACE_NORMAL);
+       mesh->attributes.remove(ATTR_STD_FACE_NORMAL);
        mesh->add_face_normals();
 
        if(mesh->displacement_method == Mesh::DISPLACE_TRUE) {
-               mesh->attributes.remove(Attribute::STD_VERTEX_NORMAL);
+               mesh->attributes.remove(ATTR_STD_VERTEX_NORMAL);
                mesh->add_vertex_normals();
        }
 
index d71438e..fd26c55 100644 (file)
@@ -1514,9 +1514,9 @@ TextureCoordinateNode::TextureCoordinateNode()
 void TextureCoordinateNode::attributes(AttributeRequestSet *attributes)
 {
        if(!output("Generated")->links.empty())
-               attributes->add(Attribute::STD_GENERATED);
+               attributes->add(ATTR_STD_GENERATED);
        if(!output("UV")->links.empty())
-               attributes->add(Attribute::STD_UV);
+               attributes->add(ATTR_STD_UV);
 
        ShaderNode::attributes(attributes);
 }
@@ -1546,7 +1546,7 @@ void TextureCoordinateNode::compile(SVMCompiler& compiler)
                        compiler.add_node(geom_node, NODE_GEOM_P, out->stack_offset);
                }
                else {
-                       int attr = compiler.attribute(Attribute::STD_GENERATED);
+                       int attr = compiler.attribute(ATTR_STD_GENERATED);
                        compiler.stack_assign(out);
                        compiler.add_node(attr_node, attr, out->stack_offset, NODE_ATTR_FLOAT3);
                }
@@ -1560,7 +1560,7 @@ void TextureCoordinateNode::compile(SVMCompiler& compiler)
 
        out = output("UV");
        if(!out->links.empty()) {
-               int attr = compiler.attribute(Attribute::STD_UV);
+               int attr = compiler.attribute(ATTR_STD_UV);
                compiler.stack_assign(out);
                compiler.add_node(attr_node, attr, out->stack_offset, NODE_ATTR_FLOAT3);
        }
@@ -1623,6 +1623,7 @@ LightPathNode::LightPathNode()
        add_output("Is Singular Ray", SHADER_SOCKET_FLOAT);
        add_output("Is Reflection Ray", SHADER_SOCKET_FLOAT);
        add_output("Is Transmission Ray", SHADER_SOCKET_FLOAT);
+       add_output("Ray Length", SHADER_SOCKET_FLOAT);
 }
 
 void LightPathNode::compile(SVMCompiler& compiler)
@@ -1671,6 +1672,13 @@ void LightPathNode::compile(SVMCompiler& compiler)
                compiler.stack_assign(out);
                compiler.add_node(NODE_LIGHT_PATH, NODE_LP_transmission, out->stack_offset);
        }
+       
+       out = output("Ray Length");
+       if(!out->links.empty()) {
+               compiler.stack_assign(out);
+               compiler.add_node(NODE_LIGHT_PATH, NODE_LP_ray_length, out->stack_offset);
+       }
+
 }
 
 void LightPathNode::compile(OSLCompiler& compiler)
index 28645d8..cae69c0 100644 (file)
@@ -38,15 +38,38 @@ Object::Object()
        visibility = ~0;
        pass_id = 0;
        bounds = BoundBox::empty;
+       motion.pre = transform_identity();
+       motion.post = transform_identity();
+       use_motion = false;
+       use_holdout = false;
 }
 
 Object::~Object()
 {
 }
 
-void Object::compute_bounds()
+void Object::compute_bounds(bool motion_blur)
 {
-       bounds = mesh->bounds.transformed(&tfm);
+       BoundBox mbounds = mesh->bounds;
+
+       if(motion_blur && use_motion) {
+               MotionTransform decomp;
+               transform_motion_decompose(&decomp, &motion);
+
+               bounds = BoundBox::empty;
+
+               /* todo: this is really terrible. according to pbrt there is a better
+                * way to find this iteratively, but did not find implementation yet
+                * or try to implement myself */
+               for(float t = 0.0f; t < 1.0f; t += 1.0f/128.0f) {
+                       Transform ttfm;
+
+                       transform_motion_interpolate(&ttfm, &decomp, t);
+                       bounds.grow(mbounds.transformed(&ttfm));
+               }
+       }
+       else
+               bounds = mbounds.transformed(&tfm);
 }
 
 void Object::apply_transform()
@@ -57,8 +80,8 @@ void Object::apply_transform()
        for(size_t i = 0; i < mesh->verts.size(); i++)
                mesh->verts[i] = transform_point(&tfm, mesh->verts[i]);
 
-       Attribute *attr_fN = mesh->attributes.find(Attribute::STD_FACE_NORMAL);
-       Attribute *attr_vN = mesh->attributes.find(Attribute::STD_VERTEX_NORMAL);
+       Attribute *attr_fN = mesh->attributes.find(ATTR_STD_FACE_NORMAL);
+       Attribute *attr_vN = mesh->attributes.find(ATTR_STD_VERTEX_NORMAL);
 
        Transform ntfm = transform_transpose(transform_inverse(tfm));
 
@@ -83,7 +106,7 @@ void Object::apply_transform()
 
        if(bounds.valid()) {
                mesh->compute_bounds();
-               compute_bounds();
+               compute_bounds(false);
        }
        
        tfm = transform_identity();
@@ -121,16 +144,18 @@ ObjectManager::~ObjectManager()
 void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
 {
        float4 *objects = dscene->objects.resize(OBJECT_SIZE*scene->objects.size());
+       uint *object_flag = dscene->object_flag.resize(OBJECT_SIZE*scene->objects.size());
        int i = 0;
        map<Mesh*, float> surface_area_map;
+       Scene::MotionType need_motion = scene->need_motion();
 
        foreach(Object *ob, scene->objects) {
                Mesh *mesh = ob->mesh;
+               uint flag = 0;
 
                /* compute transformations */
                Transform tfm = ob->tfm;
                Transform itfm = transform_inverse(tfm);
-               Transform ntfm = transform_transpose(itfm);
 
                /* compute surface area. for uniform scale we can do avoid the many
                   transform calls and share computation for instances */
@@ -171,10 +196,44 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene
                /* pack in texture */
                int offset = i*OBJECT_SIZE;
 
-               memcpy(&objects[offset], &tfm, sizeof(float4)*4);
-               memcpy(&objects[offset+4], &itfm, sizeof(float4)*4);
-               memcpy(&objects[offset+8], &ntfm, sizeof(float4)*4);
-               objects[offset+12] = make_float4(surface_area, pass_id, 0.0f, 0.0f);
+               memcpy(&objects[offset], &tfm, sizeof(float4)*3);
+               memcpy(&objects[offset+3], &itfm, sizeof(float4)*3);
+               objects[offset+6] = make_float4(surface_area, pass_id, 0.0f, 0.0f);
+
+               if(need_motion == Scene::MOTION_PASS) {
+                       /* motion transformations, is world/object space depending if mesh
+                          comes with deformed position in object space, or if we transform
+                          the shading point in world space */
+                       Transform mtfm_pre = ob->motion.pre;
+                       Transform mtfm_post = ob->motion.post;
+
+                       if(!mesh->attributes.find(ATTR_STD_MOTION_PRE))
+                               mtfm_pre = mtfm_pre * itfm;
+                       if(!mesh->attributes.find(ATTR_STD_MOTION_POST))
+                               mtfm_post = mtfm_post * itfm;
+
+                       memcpy(&objects[offset+8], &mtfm_pre, sizeof(float4)*4);
+                       memcpy(&objects[offset+12], &mtfm_post, sizeof(float4)*4);
+               }
+               else if(need_motion == Scene::MOTION_BLUR) {
+                       if(ob->use_motion) {
+                               /* decompose transformations for interpolation */
+                               MotionTransform decomp;
+
+                               transform_motion_decompose(&decomp, &ob->motion);
+                               memcpy(&objects[offset+8], &decomp, sizeof(float4)*8);
+                               flag |= SD_OBJECT_MOTION;
+                       }
+                       else {
+                               float4 no_motion = make_float4(FLT_MAX);
+                               memcpy(&objects[offset+8], &no_motion, sizeof(float4));
+                       }
+               }
+
+               /* object flag */
+               if(ob->use_holdout)
+                       flag |= SD_HOLDOUT_MASK;
+               object_flag[i] = flag;
 
                i++;
 
@@ -182,6 +241,7 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene
        }
 
        device->tex_alloc("__objects", dscene->objects);
+       device->tex_alloc("__object_flag", dscene->object_flag);
 }
 
 void ObjectManager::device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
@@ -216,6 +276,9 @@ void ObjectManager::device_free(Device *device, DeviceScene *dscene)
 {
        device->tex_free(dscene->objects);
        dscene->objects.clear();
+
+       device->tex_free(dscene->object_flag);
+       dscene->object_flag.clear();
 }
 
 void ObjectManager::apply_static_transforms(Scene *scene, Progress& progress)
@@ -225,6 +288,7 @@ void ObjectManager::apply_static_transforms(Scene *scene, Progress& progress)
 
        /* counter mesh users */
        map<Mesh*, int> mesh_users;
+       bool motion_blur = scene->need_motion() == Scene::MOTION_BLUR;
 
        foreach(Object *object, scene->objects) {
                map<Mesh*, int>::iterator it = mesh_users.find(object->mesh);
@@ -240,12 +304,14 @@ void ObjectManager::apply_static_transforms(Scene *scene, Progress& progress)
        /* apply transforms for objects with single user meshes */
        foreach(Object *object, scene->objects) {
                if(mesh_users[object->mesh] == 1) {
-                       if(!object->mesh->transform_applied) {
-                               object->apply_transform();
-                               object->mesh->transform_applied = true;
-                       }
+                       if(!(motion_blur && object->use_motion)) {
+                               if(!object->mesh->transform_applied) {
+                                       object->apply_transform();
+                                       object->mesh->transform_applied = true;
 
-                       if(progress.get_cancel()) return;
+                                       if(progress.get_cancel()) return;
+                               }
+                       }
                }
        }
 }
index 14da2cf..267052b 100644 (file)
@@ -44,13 +44,16 @@ public:
        int pass_id;
        vector<ParamValue> attributes;
        uint visibility;
+       MotionTransform motion;
+       bool use_motion;
+       bool use_holdout;
 
        Object();
        ~Object();
 
        void tag_update(Scene *scene);
 
-       void compute_bounds();
+       void compute_bounds(bool motion_blur);
        void apply_transform();
 };
 
index 079f274..b645333 100644 (file)
@@ -128,7 +128,7 @@ void Scene::device_update(Device *device_, Progress& progress)
        if(progress.get_cancel()) return;
 
        progress.set_status("Updating Camera");
-       camera->device_update(device, &dscene);
+       camera->device_update(device, &dscene, this);
 
        if(progress.get_cancel()) return;
 
@@ -166,6 +166,33 @@ void Scene::device_update(Device *device_, Progress& progress)
        device->const_copy_to("__data", &dscene.data, sizeof(dscene.data));
 }
 
+Scene::MotionType Scene::need_motion()
+{
+       if(integrator->motion_blur)
+               return MOTION_BLUR;
+       else if(Pass::contains(film->passes, PASS_MOTION))
+               return MOTION_PASS;
+       else
+               return MOTION_NONE;
+}
+
+bool Scene::need_global_attribute(AttributeStandard std)
+{
+       if(std == ATTR_STD_UV)
+               return Pass::contains(film->passes, PASS_UV);
+       if(std == ATTR_STD_MOTION_PRE || ATTR_STD_MOTION_POST)
+               return need_motion() == MOTION_PASS;
+       
+       return false;
+}
+
+void Scene::need_global_attributes(AttributeRequestSet& attributes)
+{
+       for(int std = ATTR_STD_NONE; std < ATTR_STD_NUM; std++)
+               if(need_global_attribute((AttributeStandard)std))
+                       attributes.add((AttributeStandard)std);
+}
+
 bool Scene::need_update()
 {
        return (need_reset() || film->need_update);
index af4301b..ca4d9fc 100644 (file)
@@ -33,6 +33,7 @@
 
 CCL_NAMESPACE_BEGIN
 
+class AttributeRequestSet;
 class Background;
 class Camera;
 class Device;
@@ -84,6 +85,7 @@ public:
        /* shaders */
        device_vector<uint4> svm_nodes;
        device_vector<uint> shader_flag;
+       device_vector<uint> object_flag;
 
        /* filter */
        device_vector<float> filter_table;
@@ -175,6 +177,12 @@ public:
 
        void device_update(Device *device, Progress& progress);
 
+       bool need_global_attribute(AttributeStandard std);
+       void need_global_attributes(AttributeRequestSet& attributes);
+
+       enum MotionType { MOTION_NONE = 0, MOTION_PASS, MOTION_BLUR };
+       MotionType need_motion();
+
        bool need_update();
        bool need_reset();
 };
index c1f7b35..f507091 100644 (file)
@@ -133,12 +133,12 @@ uint ShaderManager::get_attribute_id(ustring name)
        if(it != unique_attribute_id.end())
                return it->second;
        
-       uint id = (uint)Attribute::STD_NUM + unique_attribute_id.size();
+       uint id = (uint)ATTR_STD_NUM + unique_attribute_id.size();
        unique_attribute_id[name] = id;
        return id;
 }
 
-uint ShaderManager::get_attribute_id(Attribute::Standard std)
+uint ShaderManager::get_attribute_id(AttributeStandard std)
 {
        return (uint)std;
 }
index 35f3cfe..48d517c 100644 (file)
@@ -103,7 +103,7 @@ public:
 
        /* get globally unique id for a type of attribute */
        uint get_attribute_id(ustring name);
-       uint get_attribute_id(Attribute::Standard std);
+       uint get_attribute_id(AttributeStandard std);
 
        /* get shader id for mesh faces */
        int get_shader_id(uint shader, Mesh *mesh = NULL, bool smooth = false);
index a52e30c..1ff3ac2 100644 (file)
@@ -337,7 +337,7 @@ uint SVMCompiler::attribute(ustring name)
        return shader_manager->get_attribute_id(name);
 }
 
-uint SVMCompiler::attribute(Attribute::Standard std)
+uint SVMCompiler::attribute(AttributeStandard std)
 {
        return shader_manager->get_attribute_id(std);
 }
index 56c930f..0db68f4 100644 (file)
@@ -69,7 +69,7 @@ public:
        void add_node(const float4& f);
        void add_array(float4 *f, int num);
        uint attribute(ustring name);
-       uint attribute(Attribute::Standard std);
+       uint attribute(AttributeStandard std);
        uint encode_uchar4(uint x, uint y = 0, uint z = 0, uint w = 0);
        uint closure_mix_weight_offset() { return mix_weight_offset; }
 
index 6b29d1c..6e24bb4 100644 (file)
@@ -39,7 +39,7 @@ EdgeDice::EdgeDice(Mesh *mesh_, int shader_, bool smooth_, float dicing_rate_)
        smooth = smooth_;
        camera = NULL;
 
-       mesh->attributes.add(Attribute::STD_VERTEX_NORMAL);
+       mesh->attributes.add(ATTR_STD_VERTEX_NORMAL);
 }
 
 void EdgeDice::reserve(int num_verts, int num_tris)
@@ -49,7 +49,7 @@ void EdgeDice::reserve(int num_verts, int num_tris)
 
        mesh->reserve(vert_offset + num_verts, tri_offset + num_tris);
 
-       Attribute *attr_vN = mesh->attributes.add(Attribute::STD_VERTEX_NORMAL);
+       Attribute *attr_vN = mesh->attributes.add(ATTR_STD_VERTEX_NORMAL);
 
        mesh_P = &mesh->verts[0];
        mesh_N = attr_vN->data_float3();
index 9511b48..b35c4c1 100644 (file)
@@ -50,7 +50,7 @@ public:
        {
        }
 
-       static struct empty_t {} empty;
+       enum empty_t { empty = 0};
 
        __forceinline BoundBox(empty_t)
        : min(make_float3(FLT_MAX, FLT_MAX, FLT_MAX)), max(make_float3(-FLT_MAX, -FLT_MAX, -FLT_MAX))
index 53c1302..7b52724 100644 (file)
@@ -55,6 +55,10 @@ CCL_NAMESPACE_BEGIN
 #ifndef M_2_PI_F
 #define M_2_PI_F       ((float)0.636619772367581343075535053490057448)
 #endif
+#ifndef M_SQRT2_F
+#define M_SQRT2_F      ((float)1.41421356237309504880)
+#endif
+
 
 /* Scalar */
 
@@ -432,6 +436,11 @@ __device_inline float len(const float3 a)
        return sqrtf(dot(a, a));
 }
 
+__device_inline float len_squared(const float3 a)
+{
+       return dot(a, a);
+}
+
 #ifndef __KERNEL_OPENCL__
 
 __device_inline float3 normalize(const float3 a)
@@ -719,6 +728,45 @@ __device_inline float4 cross(const float4& a, const float4& b)
 #endif
 }
 
+__device_inline bool is_zero(const float4& a)
+{
+#ifdef __KERNEL_SSE__
+       return a == make_float4(0.0f);
+#else
+       return (a.x == 0.0f && a.y == 0.0f && a.z == 0.0f && a.w == 0.0f);
+#endif
+}
+
+__device_inline float reduce_add(const float4& a)
+{
+#ifdef __KERNEL_SSE__
+       float4 h = shuffle<1,0,3,2>(a) + a;
+       return _mm_cvtss_f32(shuffle<2,3,0,1>(h) + h); /* todo: efficiency? */
+#else
+       return ((a.x + a.y) + (a.z + a.w));
+#endif
+}
+
+__device_inline float average(const float4& a)
+{
+       return reduce_add(a) * 0.25f;
+}
+
+__device_inline float dot(const float4& a, const float4& b)
+{
+       return reduce_add(a * b);
+}
+
+__device_inline float len(const float4 a)
+{
+       return sqrtf(dot(a, a));
+}
+
+__device_inline float4 normalize(const float4 a)
+{
+       return a/len(a);
+}
+
 __device_inline float4 min(float4 a, float4 b)
 {
 #ifdef __KERNEL_SSE__
@@ -790,39 +838,6 @@ __device_inline void print_float4(const char *label, const float4& a)
 
 #endif
 
-#ifndef __KERNEL_OPENCL__
-
-__device_inline bool is_zero(const float4& a)
-{
-#ifdef __KERNEL_SSE__
-       return a == make_float4(0.0f);
-#else
-       return (a.x == 0.0f && a.y == 0.0f && a.z == 0.0f && a.w == 0.0f);
-#endif
-}
-
-__device_inline float reduce_add(const float4& a)
-{
-#ifdef __KERNEL_SSE__
-       float4 h = shuffle<1,0,3,2>(a) + a;
-       return _mm_cvtss_f32(shuffle<2,3,0,1>(h) + h); /* todo: efficiency? */
-#else
-       return ((a.x + a.y) + (a.z + a.w));
-#endif
-}
-
-__device_inline float average(const float4& a)
-{
-       return reduce_add(a) * 0.25f;
-}
-
-__device_inline float dot(const float4& a, const float4& b)
-{
-       return reduce_add(a * b);
-}
-
-#endif
-
 /* Int3 */
 
 #ifndef __KERNEL_OPENCL__
index 0fd2682..1780994 100644 (file)
@@ -53,6 +53,8 @@
 
 CCL_NAMESPACE_BEGIN
 
+/* Transform Inverse */
+
 static bool transform_matrix4_gj_inverse(float R[][4], float M[][4])
 {
        /* forward elimination */
@@ -151,5 +153,104 @@ Transform transform_inverse(const Transform& tfm)
        return tfmR;
 }
 
+/* Motion Transform */
+
+static float4 transform_to_quat(const Transform& tfm)
+{
+       double trace = tfm[0][0] + tfm[1][1] + tfm[2][2];
+       float4 qt;
+
+       if(trace > 0.0f) {
+               double s = sqrt(trace + 1.0);
+
+               qt.w = (float)(s/2.0);
+               s = 0.5/s;
+
+               qt.x = (float)((tfm[2][1] - tfm[1][2]) * s);
+               qt.y = (float)((tfm[0][2] - tfm[2][0]) * s);
+               qt.z = (float)((tfm[1][0] - tfm[0][1]) * s);
+       }
+       else {
+               int i = 0;
+
+               if(tfm[1][1] > tfm[i][i])
+                       i = 1;
+               if(tfm[2][2] > tfm[i][i])
+                       i = 2;
+
+               int j = (i + 1)%3;
+               int k = (j + 1)%3;
+
+               double s = sqrt((tfm[i][i] - (tfm[j][j] + tfm[k][k])) + 1.0);
+
+               double q[3];
+               q[i] = s * 0.5;
+               if(s != 0.0)
+                       s = 0.5/s;
+
+               double w = (tfm[k][j] - tfm[j][k]) * s;
+               q[j] = (tfm[j][i] + tfm[i][j]) * s;
+               q[k] = (tfm[k][i] + tfm[i][k]) * s;
+
+               qt.x = (float)q[0];
+               qt.y = (float)q[1];
+               qt.z = (float)q[2];
+               qt.w = (float)w;
+       }
+
+       return qt;
+}
+
+static void transform_decompose(Transform *decomp, const Transform *tfm)
+{
+       /* extract translation */
+       decomp->y = make_float4(tfm->x.w, tfm->y.w, tfm->z.w, 0.0f);
+
+       /* extract rotation */
+       Transform M = *tfm;
+       M.x.w = 0.0f; M.y.w = 0.0f; M.z.w = 0.0f; M.w.w = 1.0f;
+
+       Transform R = M;
+       float norm;
+       int iteration = 0;
+
+       do {
+               Transform Rnext;
+               Transform Rit = transform_inverse(transform_transpose(R));
+
+               for(int i = 0; i < 4; i++)
+                       for(int j = 0; j < 4; j++)
+                               Rnext[i][j] = 0.5f * (R[i][j] + Rit[i][j]);
+               
+               norm = 0.0f;
+               for(int i = 0; i < 3; i++) {
+                       norm = max(norm,