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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/intern
diff options
context:
space:
mode:
Diffstat (limited to 'intern')
-rw-r--r--intern/audaspace/CMakeLists.txt2
-rw-r--r--intern/audaspace/intern/AUD_C-API.cpp49
-rw-r--r--intern/audaspace/intern/AUD_C-API.h2
-rw-r--r--intern/cycles/blender/addon/engine.py7
-rw-r--r--intern/cycles/blender/addon/properties.py18
-rw-r--r--intern/cycles/blender/addon/ui.py17
-rw-r--r--intern/cycles/blender/blender_camera.cpp30
-rw-r--r--intern/cycles/blender/blender_curves.cpp12
-rw-r--r--intern/cycles/blender/blender_mesh.cpp7
-rw-r--r--intern/cycles/blender/blender_object.cpp35
-rw-r--r--intern/cycles/blender/blender_session.cpp3
-rw-r--r--intern/cycles/blender/blender_shader.cpp32
-rw-r--r--intern/cycles/blender/blender_sync.cpp8
-rw-r--r--intern/cycles/blender/blender_texture.cpp10
-rw-r--r--intern/cycles/blender/blender_util.h16
-rw-r--r--intern/cycles/bvh/bvh.cpp126
-rw-r--r--intern/cycles/bvh/bvh.h9
-rw-r--r--intern/cycles/bvh/bvh_binning.cpp6
-rw-r--r--intern/cycles/bvh/bvh_build.cpp18
-rw-r--r--intern/cycles/bvh/bvh_params.h4
-rw-r--r--intern/cycles/bvh/bvh_split.cpp237
-rw-r--r--intern/cycles/bvh/bvh_split.h53
-rw-r--r--intern/cycles/cmake/external_libs.cmake16
-rw-r--r--intern/cycles/device/device_memory.h9
-rw-r--r--intern/cycles/device/device_network.cpp6
-rw-r--r--intern/cycles/device/device_opencl.cpp17
-rw-r--r--intern/cycles/kernel/geom/geom_bvh_shadow.h8
-rw-r--r--intern/cycles/kernel/geom/geom_bvh_subsurface.h6
-rw-r--r--intern/cycles/kernel/geom/geom_bvh_traversal.h6
-rw-r--r--intern/cycles/kernel/geom/geom_bvh_volume.h6
-rw-r--r--intern/cycles/kernel/geom/geom_bvh_volume_all.h26
-rw-r--r--intern/cycles/kernel/geom/geom_object.h68
-rw-r--r--intern/cycles/kernel/geom/geom_qbvh_shadow.h8
-rw-r--r--intern/cycles/kernel/geom/geom_qbvh_subsurface.h6
-rw-r--r--intern/cycles/kernel/geom/geom_qbvh_traversal.h6
-rw-r--r--intern/cycles/kernel/geom/geom_qbvh_volume.h6
-rw-r--r--intern/cycles/kernel/geom/geom_qbvh_volume_all.h26
-rw-r--r--intern/cycles/kernel/geom/geom_triangle_intersect.h34
-rw-r--r--intern/cycles/kernel/kernel_bake.h11
-rw-r--r--intern/cycles/kernel/kernel_camera.h7
-rw-r--r--intern/cycles/kernel/kernel_compat_cpu.h50
-rw-r--r--intern/cycles/kernel/kernel_light.h2
-rw-r--r--intern/cycles/kernel/kernel_path_surface.h4
-rw-r--r--intern/cycles/kernel/kernel_types.h2
-rw-r--r--intern/cycles/kernel/kernel_volume.h12
-rw-r--r--intern/cycles/kernel/osl/background.cpp4
-rw-r--r--intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp2
-rw-r--r--intern/cycles/kernel/osl/bsdf_phong_ramp.cpp2
-rw-r--r--intern/cycles/kernel/osl/emissive.cpp2
-rw-r--r--intern/cycles/kernel/osl/osl_bssrdf.cpp4
-rw-r--r--intern/cycles/kernel/osl/osl_closures.h15
-rw-r--r--intern/cycles/kernel/osl/osl_services.h49
-rw-r--r--intern/cycles/kernel/osl/osl_shader.cpp434
-rw-r--r--intern/cycles/kernel/shaders/node_brick_texture.osl1
-rw-r--r--intern/cycles/kernel/shaders/node_environment_texture.osl3
-rw-r--r--intern/cycles/kernel/split/kernel_data_init.h4
-rw-r--r--intern/cycles/kernel/svm/svm_attribute.h11
-rw-r--r--intern/cycles/kernel/svm/svm_brick.h1
-rw-r--r--intern/cycles/kernel/svm/svm_closure.h8
-rw-r--r--intern/cycles/kernel/svm/svm_types.h2
-rw-r--r--intern/cycles/kernel/svm/svm_voxel.h9
-rw-r--r--intern/cycles/render/camera.cpp35
-rw-r--r--intern/cycles/render/camera.h14
-rw-r--r--intern/cycles/render/film.cpp8
-rw-r--r--intern/cycles/render/graph.cpp23
-rw-r--r--intern/cycles/render/image.cpp9
-rw-r--r--intern/cycles/render/image.h7
-rw-r--r--intern/cycles/render/integrator.cpp1
-rw-r--r--intern/cycles/render/mesh.cpp2
-rw-r--r--intern/cycles/render/mesh_displace.cpp2
-rw-r--r--intern/cycles/render/nodes.cpp61
-rw-r--r--intern/cycles/render/nodes.h1
-rw-r--r--intern/cycles/render/shader.cpp12
-rw-r--r--intern/cycles/render/svm.cpp6
-rw-r--r--intern/cycles/render/tile.cpp2
-rw-r--r--intern/cycles/util/util_math.h11
-rw-r--r--intern/cycles/util/util_optimization.h2
-rw-r--r--intern/cycles/util/util_transform.h7
-rw-r--r--intern/cycles/util/util_vector.h48
-rw-r--r--intern/elbeem/intern/simulation_object.cpp2
-rw-r--r--intern/ghost/SConscript3
-rw-r--r--intern/ghost/intern/GHOST_C-api.cpp19
-rw-r--r--intern/ghost/intern/GHOST_ContextCGL.h9
-rw-r--r--intern/ghost/intern/GHOST_ContextCGL.mm7
-rw-r--r--intern/ghost/intern/GHOST_ContextGLX.cpp108
-rw-r--r--intern/ghost/intern/GHOST_DisplayManagerX11.cpp5
-rw-r--r--intern/ghost/intern/GHOST_SystemCocoa.h5
-rw-r--r--intern/ghost/intern/GHOST_SystemCocoa.mm56
-rw-r--r--intern/ghost/intern/GHOST_WindowCocoa.mm27
-rw-r--r--intern/glew-mx/SConscript5
-rw-r--r--intern/glew-mx/glew-mx.h2
-rw-r--r--intern/glew-mx/intern/glew-mx.c9
-rw-r--r--intern/iksolver/intern/IK_Solver.cpp6
-rw-r--r--intern/opencolorio/SConscript4
-rw-r--r--intern/opensubdiv/CMakeLists.txt1
-rw-r--r--intern/opensubdiv/SConscript22
-rw-r--r--intern/opensubdiv/gpu_shader_opensubd_display.glsl164
-rw-r--r--intern/opensubdiv/opensubdiv_capi.cc90
-rw-r--r--intern/opensubdiv/opensubdiv_capi.h9
-rw-r--r--intern/opensubdiv/opensubdiv_converter.cc428
-rw-r--r--intern/opensubdiv/opensubdiv_converter_capi.h6
-rw-r--r--intern/opensubdiv/opensubdiv_evaluator_capi.cc12
-rw-r--r--intern/opensubdiv/opensubdiv_gpu_capi.cc182
-rw-r--r--intern/opensubdiv/opensubdiv_intern.h5
-rw-r--r--intern/opensubdiv/opensubdiv_partitioned.h77
-rw-r--r--intern/opensubdiv/opensubdiv_utils_capi.cc29
-rw-r--r--intern/smoke/intern/MERSENNETWISTER.h44
107 files changed, 1892 insertions, 1289 deletions
diff --git a/intern/audaspace/CMakeLists.txt b/intern/audaspace/CMakeLists.txt
index 7fecb1a48a7..b3682a77875 100644
--- a/intern/audaspace/CMakeLists.txt
+++ b/intern/audaspace/CMakeLists.txt
@@ -164,6 +164,8 @@ set(SRC
intern/AUD_SequencerHandle.h
intern/AUD_SequencerReader.cpp
intern/AUD_SequencerReader.h
+ intern/AUD_Set.cpp
+ intern/AUD_Set.h
intern/AUD_SilenceFactory.cpp
intern/AUD_SilenceFactory.h
intern/AUD_SilenceReader.cpp
diff --git a/intern/audaspace/intern/AUD_C-API.cpp b/intern/audaspace/intern/AUD_C-API.cpp
index 48a3c7b2ded..341f1cd3f6b 100644
--- a/intern/audaspace/intern/AUD_C-API.cpp
+++ b/intern/audaspace/intern/AUD_C-API.cpp
@@ -41,7 +41,6 @@
# include "AUD_PyAPI.h"
#endif
-#include <set>
#include <cstdlib>
#include <cstring>
#include <cmath>
@@ -814,10 +813,9 @@ int AUD_Device_read(AUD_Device *device, data_t *buffer, int length)
void AUD_Device_free(AUD_Device *device)
{
- assert(device);
-
try {
- delete device;
+ if(device != &AUD_device)
+ delete device;
}
catch(AUD_Exception&)
{
@@ -1225,44 +1223,6 @@ void AUD_Handle_free(AUD_Handle *handle)
delete handle;
}
-void *AUD_createSet()
-{
- return new std::set<void *>();
-}
-
-void AUD_destroySet(void *set)
-{
- delete reinterpret_cast<std::set<void *>*>(set);
-}
-
-char AUD_removeSet(void *set, void *entry)
-{
- if (set)
- return reinterpret_cast<std::set<void *>*>(set)->erase(entry);
- return 0;
-}
-
-void AUD_addSet(void *set, void *entry)
-{
- if (entry)
- reinterpret_cast<std::set<void *>*>(set)->insert(entry);
-}
-
-void *AUD_getSet(void *set)
-{
- if (set) {
- std::set<void *>* rset = reinterpret_cast<std::set<void *>*>(set);
- if (!rset->empty()) {
- std::set<void *>::iterator it = rset->begin();
- void *result = *it;
- rset->erase(it);
- return result;
- }
- }
-
- return NULL;
-}
-
const char *AUD_mixdown(AUD_Sound *sound, unsigned int start, unsigned int length, unsigned int buffersize, const char *filename, AUD_DeviceSpecs specs, AUD_Container format, AUD_Codec codec, unsigned int bitrate)
{
try {
@@ -1347,6 +1307,11 @@ AUD_Device *AUD_openMixdownDevice(AUD_DeviceSpecs specs, AUD_Sound *sequencer, f
}
}
+AUD_Device *AUD_Device_getCurrent(void)
+{
+ return &AUD_device;
+}
+
int AUD_isJackSupported(void)
{
#ifdef WITH_JACK
diff --git a/intern/audaspace/intern/AUD_C-API.h b/intern/audaspace/intern/AUD_C-API.h
index f53dfcefedd..bdbe751b140 100644
--- a/intern/audaspace/intern/AUD_C-API.h
+++ b/intern/audaspace/intern/AUD_C-API.h
@@ -811,6 +811,8 @@ extern void *AUD_getPythonSound(AUD_Sound *sound);
extern AUD_Sound *AUD_getSoundFromPython(void *sound);
#endif
+extern AUD_Device *AUD_Device_getCurrent(void);
+
extern int AUD_isJackSupported(void);
#ifdef __cplusplus
diff --git a/intern/cycles/blender/addon/engine.py b/intern/cycles/blender/addon/engine.py
index c936b900d75..030f0dbbf14 100644
--- a/intern/cycles/blender/addon/engine.py
+++ b/intern/cycles/blender/addon/engine.py
@@ -30,8 +30,8 @@ def _is_using_buggy_driver():
version = bgl.glGetString(bgl.GL_VERSION)
if version.endswith("Compatibility Profile Context"):
# Old HD 4xxx and 5xxx series drivers did not have driver version
- # in the version string, but thsoe cards do not quite work and
- # cusing crashes.
+ # in the version string, but those cards do not quite work and
+ # causing crashes.
return True
regex = re.compile(".*Compatibility Profile Context ([0-9]+(\.[0-9]+)+)$")
if not regex.match(version):
@@ -49,12 +49,13 @@ def _workaround_buggy_drivers():
print("Cycles: OpenGL driver known to be buggy, disabling OpenCL platform.")
_cycles.opencl_disable()
+
def init():
import bpy
import _cycles
import os.path
- # Workaroud posibly buggy legacy drivers which crashes on the OpenCL
+ # Workaround possibly buggy legacy drivers which crashes on the OpenCL
# device enumeration.
#
# This checks are not really correct because they might still fail
diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py
index 3417435fcbd..c3139831ca2 100644
--- a/intern/cycles/blender/addon/properties.py
+++ b/intern/cycles/blender/addon/properties.py
@@ -463,11 +463,6 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
description="Use BVH spatial splits: longer builder time, faster render",
default=False,
)
- cls.use_cache = BoolProperty(
- name="Cache BVH",
- description="Cache last built BVH to disk for faster re-render if no geometry changed",
- default=False,
- )
cls.tile_order = EnumProperty(
name="Tile Order",
description="Tile order for rendering",
@@ -524,6 +519,17 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
min=0.0, max=5.0
)
+ cls.motion_blur_position = EnumProperty(
+ name="Motion Blur Position",
+ default='CENTER',
+ description="Offset for the shutter's time interval, allows to change the motion blur trails",
+ items=(
+ ('START', "Start on Frame", "The shutter opens at the current frame"),
+ ('CENTER', "Center on Frame", "The shutter is open during the current frame"),
+ ('END', "End on Frame", "The shutter closes at the current frame"),
+ ),
+ )
+
@classmethod
def unregister(cls):
del bpy.types.Scene.cycles
@@ -743,7 +749,7 @@ class CyclesWorldSettings(bpy.types.PropertyGroup):
name="Map Resolution",
description="Importance map size is resolution x resolution; "
"higher values potentially produce less noise, at the cost of memory and speed",
- min=4, max=8096,
+ min=4, max=8192,
default=256,
)
cls.samples = IntProperty(
diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py
index fdb2afdb5e9..3700da3263e 100644
--- a/intern/cycles/blender/addon/ui.py
+++ b/intern/cycles/blender/addon/ui.py
@@ -259,11 +259,14 @@ class CyclesRender_PT_motion_blur(CyclesButtonsPanel, Panel):
def draw(self, context):
layout = self.layout
- rd = context.scene.render
+ scene = context.scene
+ cscene = scene.cycles
+ rd = scene.render
layout.active = rd.use_motion_blur
- row = layout.row()
- row.prop(rd, "motion_blur_shutter")
+ col = layout.column()
+ col.prop(cscene, "motion_blur_position", text="Position")
+ col.prop(rd, "motion_blur_shutter")
class CyclesRender_PT_film(CyclesButtonsPanel, Panel):
@@ -332,7 +335,6 @@ class CyclesRender_PT_performance(CyclesButtonsPanel, Panel):
col.separator()
col.label(text="Final Render:")
- col.prop(cscene, "use_cache")
col.prop(rd, "use_persistent_data", text="Persistent Images")
col.separator()
@@ -438,6 +440,7 @@ class CyclesRender_PT_layer_passes(CyclesButtonsPanel, Panel):
class CyclesRender_PT_views(CyclesButtonsPanel, Panel):
bl_label = "Views"
bl_context = "render_layer"
+ bl_options = {'DEFAULT_CLOSED'}
def draw_header(self, context):
rd = context.scene.render
@@ -1163,13 +1166,17 @@ class CyclesMaterial_PT_settings(CyclesButtonsPanel, Panel):
col.prop(mat, "alpha")
col.separator()
- col.prop(mat, "pass_index")
+ col.label("Viewport Alpha:")
+ col.prop(mat.game_settings, "alpha_blend", text="")
col = split.column(align=True)
col.label("Viewport Specular:")
col.prop(mat, "specular_color", text="")
col.prop(mat, "specular_hardness", text="Hardness")
+ col.separator()
+ col.prop(mat, "pass_index")
+
class CyclesTexture_PT_context(CyclesButtonsPanel, Panel):
bl_label = ""
diff --git a/intern/cycles/blender/blender_camera.cpp b/intern/cycles/blender/blender_camera.cpp
index 0a79bfbf793..491b5632ed5 100644
--- a/intern/cycles/blender/blender_camera.cpp
+++ b/intern/cycles/blender/blender_camera.cpp
@@ -36,6 +36,7 @@ struct BlenderCamera {
float lens;
float shuttertime;
+ Camera::MotionPosition motion_position;
float aperturesize;
uint apertureblades;
@@ -83,6 +84,7 @@ static void blender_camera_init(BlenderCamera *bcam, BL::RenderSettings b_render
bcam->sensor_height = 18.0f;
bcam->sensor_fit = BlenderCamera::AUTO;
bcam->shuttertime = 1.0f;
+ bcam->motion_position = Camera::MOTION_POSITION_CENTER;
bcam->border.right = 1.0f;
bcam->border.top = 1.0f;
bcam->pano_viewplane.right = 1.0f;
@@ -107,9 +109,9 @@ static float blender_camera_focal_distance(BL::RenderEngine b_engine, BL::Object
b_engine.camera_model_matrix(b_ob, b_ob_matrix);
Transform obmat = get_transform(b_ob_matrix);
Transform dofmat = get_transform(b_dof_object.matrix_world());
- Transform mat = transform_inverse(obmat) * dofmat;
-
- return fabsf(transform_get_column(&mat, 3).z);
+ float3 view_dir = normalize(transform_get_column(&obmat, 2));
+ float3 dof_dir = transform_get_column(&obmat, 3) - transform_get_column(&dofmat, 3);
+ return fabsf(dot(view_dir, dof_dir));
}
static void blender_camera_from_object(BlenderCamera *bcam, BL::RenderEngine b_engine, BL::Object b_ob, bool skip_panorama = false)
@@ -409,6 +411,7 @@ static void blender_camera_sync(Camera *cam, BlenderCamera *bcam, int width, int
cam->shuttertime = bcam->shuttertime;
cam->fov_pre = cam->fov;
cam->fov_post = cam->fov;
+ cam->motion_position = bcam->motion_position;
/* border */
cam->border = bcam->border;
@@ -431,6 +434,22 @@ void BlenderSync::sync_camera(BL::RenderSettings b_render, BL::Object b_override
bcam.pixelaspect.y = b_render.pixel_aspect_y();
bcam.shuttertime = b_render.motion_blur_shutter();
+ PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
+ switch(RNA_enum_get(&cscene, "motion_blur_position")) {
+ case 0:
+ bcam.motion_position = Camera::MOTION_POSITION_START;
+ break;
+ case 1:
+ bcam.motion_position = Camera::MOTION_POSITION_CENTER;
+ break;
+ case 2:
+ bcam.motion_position = Camera::MOTION_POSITION_END;
+ break;
+ default:
+ bcam.motion_position = Camera::MOTION_POSITION_CENTER;
+ break;
+ }
+
/* border */
if(b_render.use_border()) {
bcam.border.left = b_render.border_min_x();
@@ -487,6 +506,11 @@ void BlenderSync::sync_camera_motion(BL::RenderSettings b_render,
BlenderCamera bcam;
float aspectratio, sensor_size;
blender_camera_init(&bcam, b_render);
+
+ /* TODO(sergey): Consider making it a part of blender_camera_init(). */
+ bcam.pixelaspect.x = b_render.pixel_aspect_x();
+ bcam.pixelaspect.y = b_render.pixel_aspect_y();
+
blender_camera_from_object(&bcam, b_engine, b_ob);
blender_camera_viewplane(&bcam,
width, height,
diff --git a/intern/cycles/blender/blender_curves.cpp b/intern/cycles/blender/blender_curves.cpp
index dba801fc4df..6a119081bfd 100644
--- a/intern/cycles/blender/blender_curves.cpp
+++ b/intern/cycles/blender/blender_curves.cpp
@@ -145,7 +145,7 @@ bool ObtainCacheParticleData(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, Par
int totchild = background ? b_psys.child_particles.length() : (int)((float)b_psys.child_particles.length() * (float)b_part.draw_percentage() / 100.0f);
int totcurves = totchild;
- if(b_part.child_type() == 0)
+ if(b_part.child_type() == 0 || totchild == 0)
totcurves += totparts;
if(totcurves == 0)
@@ -169,7 +169,7 @@ bool ObtainCacheParticleData(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, Par
CData->psys_closetip.push_back(get_boolean(cpsys, "use_closetip"));
int pa_no = 0;
- if(!(b_part.child_type() == 0))
+ if(!(b_part.child_type() == 0) && totchild != 0)
pa_no = totparts;
int num_add = (totparts+totchild - pa_no);
@@ -233,14 +233,14 @@ bool ObtainCacheParticleUV(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, Parti
int totchild = background ? b_psys.child_particles.length() : (int)((float)b_psys.child_particles.length() * (float)b_part.draw_percentage() / 100.0f);
int totcurves = totchild;
- if(b_part.child_type() == 0)
+ if(b_part.child_type() == 0 || totchild == 0)
totcurves += totparts;
if(totcurves == 0)
continue;
int pa_no = 0;
- if(!(b_part.child_type() == 0))
+ if(!(b_part.child_type() == 0) && totchild != 0)
pa_no = totparts;
int num_add = (totparts+totchild - pa_no);
@@ -287,14 +287,14 @@ bool ObtainCacheParticleVcol(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, Par
int totchild = background ? b_psys.child_particles.length() : (int)((float)b_psys.child_particles.length() * (float)b_part.draw_percentage() / 100.0f);
int totcurves = totchild;
- if(b_part.child_type() == 0)
+ if(b_part.child_type() == 0 || totchild == 0)
totcurves += totparts;
if(totcurves == 0)
continue;
int pa_no = 0;
- if(!(b_part.child_type() == 0))
+ if(!(b_part.child_type() == 0) && totchild != 0)
pa_no = totparts;
int num_add = (totparts+totchild - pa_no);
diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp
index e81170ac411..c2ccef548c7 100644
--- a/intern/cycles/blender/blender_mesh.cpp
+++ b/intern/cycles/blender/blender_mesh.cpp
@@ -85,7 +85,7 @@ static void mikk_get_texture_coordinate(const SMikkTSpaceContext *context, float
BL::MeshTextureFace tf = userdata->layer->data[face_num];
float3 tfuv;
- switch (vert_num) {
+ switch(vert_num) {
case 0:
tfuv = get_float3(tf.uv1());
break;
@@ -842,6 +842,7 @@ void BlenderSync::sync_mesh_motion(BL::Object b_ob, Object *object, float motion
return;
}
+ /* TODO(sergey): Perform preliminary check for number of verticies. */
if(numverts) {
/* find attributes */
Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
@@ -873,7 +874,9 @@ void BlenderSync::sync_mesh_motion(BL::Object b_ob, Object *object, float motion
/* in case of new attribute, we verify if there really was any motion */
if(new_attribute) {
- if(i != numverts || memcmp(mP, &mesh->verts[0], sizeof(float3)*numverts) == 0) {
+ if(b_mesh.vertices.length() != numverts ||
+ memcmp(mP, &mesh->verts[0], sizeof(float3)*numverts) == 0)
+ {
/* no motion, remove attributes again */
VLOG(1) << "No actual deformation motion for object " << b_ob.name();
mesh->attributes.remove(ATTR_STD_MOTION_VERTEX_POSITION);
diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp
index 432c4aaa078..11593807a00 100644
--- a/intern/cycles/blender/blender_object.cpp
+++ b/intern/cycles/blender/blender_object.cpp
@@ -558,11 +558,20 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, float motion_time)
bool cancel = false;
bool use_portal = false;
+ uint layer_override = get_layer(b_engine.layer_override());
for(; b_sce && !cancel; b_sce = b_sce.background_set()) {
+ /* Render layer's scene_layer is affected by local view already,
+ * which is not a desired behavior here.
+ */
+ uint scene_layers = layer_override ? layer_override : get_layer(b_scene.layers());
for(b_sce.object_bases.begin(b_base); b_base != b_sce.object_bases.end() && !cancel; ++b_base) {
BL::Object b_ob = b_base->object();
bool hide = (render_layer.use_viewport_visibility)? b_ob.hide(): b_ob.hide_render();
- uint ob_layer = get_layer(b_base->layers(), b_base->layers_local_view(), render_layer.use_localview, object_is_light(b_ob));
+ uint ob_layer = get_layer(b_base->layers(),
+ b_base->layers_local_view(),
+ render_layer.use_localview,
+ object_is_light(b_ob),
+ scene_layers);
hide = hide || !(ob_layer & scene_layer);
if(!hide) {
@@ -676,6 +685,28 @@ void BlenderSync::sync_motion(BL::RenderSettings b_render,
Camera prevcam = *(scene->camera);
int frame_center = b_scene.frame_current();
+ float frame_center_delta = 0.0f;
+
+ if(scene->need_motion() != Scene::MOTION_PASS &&
+ scene->camera->motion_position != Camera::MOTION_POSITION_CENTER)
+ {
+ float shuttertime = scene->camera->shuttertime;
+ if(scene->camera->motion_position == Camera::MOTION_POSITION_END) {
+ frame_center_delta = -shuttertime * 0.5f;
+ }
+ else {
+ assert(scene->camera->motion_position == Camera::MOTION_POSITION_START);
+ frame_center_delta = shuttertime * 0.5f;
+ }
+ float time = frame_center + frame_center_delta;
+ int frame = (int)floorf(time);
+ float subframe = time - frame;
+ python_thread_state_restore(python_thread_state);
+ b_engine.frame_set(frame, subframe);
+ python_thread_state_save(python_thread_state);
+ sync_camera_motion(b_render, b_cam, width, height, 0.0f);
+ sync_objects(b_v3d, 0.0f);
+ }
/* always sample these times for camera motion */
motion_times.insert(-1.0f);
@@ -695,7 +726,7 @@ void BlenderSync::sync_motion(BL::RenderSettings b_render,
shuttertime = scene->camera->shuttertime;
/* compute frame and subframe time */
- float time = frame_center + relative_time * shuttertime * 0.5f;
+ float time = frame_center + frame_center_delta + relative_time * shuttertime * 0.5f;
int frame = (int)floorf(time);
float subframe = time - frame;
diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp
index 04d05ee7b3c..088748cc0ae 100644
--- a/intern/cycles/blender/blender_session.cpp
+++ b/intern/cycles/blender/blender_session.cpp
@@ -1194,7 +1194,8 @@ bool BlenderSession::builtin_image_float_pixels(const string &builtin_name, void
if(b_node.is_a(&RNA_ShaderNodeTexPointDensity)) {
BL::ShaderNodeTexPointDensity b_point_density_node(b_node);
int length;
- b_point_density_node.calc_point_density(b_scene, &length, &pixels);
+ int settings = background ? 1 : 0; /* 1 - render settings, 0 - vewport settings. */
+ b_point_density_node.calc_point_density(b_scene, settings, &length, &pixels);
}
}
diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp
index 0f0be78abd8..2beeaa5e07a 100644
--- a/intern/cycles/blender/blender_shader.cpp
+++ b/intern/cycles/blender/blender_shader.cpp
@@ -88,7 +88,7 @@ static float3 get_node_output_vector(BL::Node b_node, const string& name)
static ShaderSocketType convert_socket_type(BL::NodeSocket b_socket)
{
- switch (b_socket.type()) {
+ switch(b_socket.type()) {
case BL::NodeSocket::type_VALUE:
return SHADER_SOCKET_FLOAT;
case BL::NodeSocket::type_INT:
@@ -283,7 +283,7 @@ static ShaderNode *add_node(Scene *scene,
else if(b_node.is_a(&RNA_ShaderNodeVectorTransform)) {
BL::ShaderNodeVectorTransform b_vector_transform_node(b_node);
VectorTransformNode *vtransform = new VectorTransformNode();
- vtransform->type = VectorTransformNode::type_enum[b_vector_transform_node.type()];
+ vtransform->type = VectorTransformNode::type_enum[b_vector_transform_node.vector_type()];
vtransform->convert_from = VectorTransformNode::convert_space_enum[b_vector_transform_node.convert_from()];
vtransform->convert_to = VectorTransformNode::convert_space_enum[b_vector_transform_node.convert_to()];
node = vtransform;
@@ -332,17 +332,16 @@ static ShaderNode *add_node(Scene *scene,
BL::ShaderNodeBsdfAnisotropic b_aniso_node(b_node);
AnisotropicBsdfNode *aniso = new AnisotropicBsdfNode();
- switch (b_aniso_node.distribution())
- {
- case BL::ShaderNodeBsdfAnisotropic::distribution_BECKMANN:
- aniso->distribution = ustring("Beckmann");
- break;
- case BL::ShaderNodeBsdfAnisotropic::distribution_GGX:
- aniso->distribution = ustring("GGX");
- break;
- case BL::ShaderNodeBsdfAnisotropic::distribution_ASHIKHMIN_SHIRLEY:
- aniso->distribution = ustring("Ashikhmin-Shirley");
- break;
+ switch(b_aniso_node.distribution()) {
+ case BL::ShaderNodeBsdfAnisotropic::distribution_BECKMANN:
+ aniso->distribution = ustring("Beckmann");
+ break;
+ case BL::ShaderNodeBsdfAnisotropic::distribution_GGX:
+ aniso->distribution = ustring("GGX");
+ break;
+ case BL::ShaderNodeBsdfAnisotropic::distribution_ASHIKHMIN_SHIRLEY:
+ aniso->distribution = ustring("Ashikhmin-Shirley");
+ break;
}
node = aniso;
@@ -633,11 +632,12 @@ static ShaderNode *add_node(Scene *scene,
if(b_image.is_updated()) {
scene->image_manager->tag_reload_image(env->filename,
env->builtin_data,
- INTERPOLATION_LINEAR,
+ (InterpolationType)b_env_node.interpolation(),
EXTENSION_REPEAT);
}
}
env->color_space = EnvironmentTextureNode::color_space_enum[(int)b_env_node.color_space()];
+ env->interpolation = (InterpolationType)b_env_node.interpolation();
env->projection = EnvironmentTextureNode::projection_enum[(int)b_env_node.projection()];
get_tex_mapping(&env->tex_mapping, b_env_node.texture_mapping());
node = env;
@@ -767,7 +767,7 @@ static ShaderNode *add_node(Scene *scene,
point_density->filename,
point_density->builtin_data,
point_density->interpolation,
- EXTENSION_REPEAT);
+ EXTENSION_CLIP);
}
node = point_density;
}
@@ -1176,7 +1176,7 @@ void BlenderSync::sync_world(bool update_all)
PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
/* when doing preview render check for BI's transparency settings,
- * this is so because bledner's preview render routines are not able
+ * this is so because Blender's preview render routines are not able
* to tweak all cycles's settings depending on different circumstances
*/
if(b_engine.is_preview() == false)
diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp
index 8888d219aac..986e90c59f7 100644
--- a/intern/cycles/blender/blender_sync.cpp
+++ b/intern/cycles/blender/blender_sync.cpp
@@ -161,7 +161,12 @@ void BlenderSync::sync_data(BL::RenderSettings b_render,
mesh_synced.clear(); /* use for objects and motion sync */
- sync_objects(b_v3d);
+ if(scene->need_motion() == Scene::MOTION_PASS ||
+ scene->need_motion() == Scene::MOTION_NONE ||
+ scene->camera->motion_position == Camera::MOTION_POSITION_CENTER)
+ {
+ sync_objects(b_v3d);
+ }
sync_motion(b_render,
b_v3d,
b_override,
@@ -427,7 +432,6 @@ SceneParams BlenderSync::get_scene_params(BL::Scene b_scene, bool background, bo
params.bvh_type = (SceneParams::BVHType)RNA_enum_get(&cscene, "debug_bvh_type");
params.use_bvh_spatial_split = RNA_boolean_get(&cscene, "debug_use_spatial_splits");
- params.use_bvh_cache = (background)? RNA_boolean_get(&cscene, "use_cache"): false;
if(background && params.shadingsystem != SHADINGSYSTEM_OSL)
params.persistent_data = r.use_persistent_data();
diff --git a/intern/cycles/blender/blender_texture.cpp b/intern/cycles/blender/blender_texture.cpp
index cb4dd1792d0..18f66560b10 100644
--- a/intern/cycles/blender/blender_texture.cpp
+++ b/intern/cycles/blender/blender_texture.cpp
@@ -68,10 +68,12 @@ static void density_particle_system_texture_space(
float3 particle_size = make_float3(radius, radius, radius);
for(int i = 0; i < b_particle_system.particles.length(); ++i) {
BL::Particle particle = b_particle_system.particles[i];
- float3 location = get_float3(particle.location());
- location = transform_point(&itfm, location);
- min = ccl::min(min, location - particle_size);
- max = ccl::max(max, location + particle_size);
+ if(particle.alive_state() == BL::Particle::alive_state_ALIVE) {
+ float3 location = get_float3(particle.location());
+ location = transform_point(&itfm, location);
+ min = ccl::min(min, location - particle_size);
+ max = ccl::max(max, location + particle_size);
+ }
}
/* Calculate texture space from the particle bounds. */
loc = (min + max) * 0.5f;
diff --git a/intern/cycles/blender/blender_util.h b/intern/cycles/blender/blender_util.h
index 165242d0dff..bd1c37a7560 100644
--- a/intern/cycles/blender/blender_util.h
+++ b/intern/cycles/blender/blender_util.h
@@ -196,7 +196,11 @@ static inline uint get_layer(BL::Array<int, 20> array)
return layer;
}
-static inline uint get_layer(BL::Array<int, 20> array, BL::Array<int, 8> local_array, bool use_local, bool is_light = false)
+static inline uint get_layer(BL::Array<int, 20> array,
+ BL::Array<int, 8> local_array,
+ bool use_local,
+ bool is_light = false,
+ uint scene_layers = (1 << 20) - 1)
{
uint layer = 0;
@@ -205,9 +209,13 @@ static inline uint get_layer(BL::Array<int, 20> array, BL::Array<int, 8> local_a
layer |= (1 << i);
if(is_light) {
- /* consider lamps on all local view layers */
- for(uint i = 0; i < 8; i++)
- layer |= (1 << (20+i));
+ /* Consider light is visible if it was visible without layer
+ * override, which matches behavior of Blender Internal.
+ */
+ if(layer & scene_layers) {
+ for(uint i = 0; i < 8; i++)
+ layer |= (1 << (20+i));
+ }
}
else {
for(uint i = 0; i < 8; i++)
diff --git a/intern/cycles/bvh/bvh.cpp b/intern/cycles/bvh/bvh.cpp
index 350ca16f6e2..4a5f8b1bda6 100644
--- a/intern/cycles/bvh/bvh.cpp
+++ b/intern/cycles/bvh/bvh.cpp
@@ -25,7 +25,6 @@
#include "bvh_node.h"
#include "bvh_params.h"
-#include "util_cache.h"
#include "util_debug.h"
#include "util_foreach.h"
#include "util_logging.h"
@@ -70,125 +69,12 @@ BVH *BVH::create(const BVHParams& params, const vector<Object*>& objects)
return new RegularBVH(params, objects);
}
-/* Cache */
-
-bool BVH::cache_read(CacheData& key)
-{
- key.add(system_cpu_bits());
- key.add(&params, sizeof(params));
-
- foreach(Object *ob, objects) {
- Mesh *mesh = ob->mesh;
-
- key.add(mesh->verts);
- key.add(mesh->triangles);
- key.add(mesh->curve_keys);
- key.add(mesh->curves);
- key.add(&ob->bounds, sizeof(ob->bounds));
- key.add(&ob->visibility, sizeof(ob->visibility));
- key.add(&mesh->transform_applied, sizeof(bool));
-
- if(mesh->use_motion_blur) {
- Attribute *attr = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
- if(attr)
- key.add(attr->buffer);
-
- attr = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
- if(attr)
- key.add(attr->buffer);
- }
- }
-
- CacheData value;
-
- if(Cache::global.lookup(key, value)) {
- cache_filename = key.get_filename();
-
- if(!(value.read(pack.root_index) &&
- value.read(pack.SAH) &&
- value.read(pack.nodes) &&
- value.read(pack.leaf_nodes) &&
- value.read(pack.object_node) &&
- value.read(pack.tri_woop) &&
- value.read(pack.prim_type) &&
- value.read(pack.prim_visibility) &&
- value.read(pack.prim_index) &&
- value.read(pack.prim_object)))
- {
- /* Clear the pack if load failed. */
- pack.root_index = 0;
- pack.SAH = 0.0f;
- pack.nodes.clear();
- pack.leaf_nodes.clear();
- pack.object_node.clear();
- pack.tri_woop.clear();
- pack.prim_type.clear();
- pack.prim_visibility.clear();
- pack.prim_index.clear();
- pack.prim_object.clear();
- return false;
- }
- return true;
- }
-
- return false;
-}
-
-void BVH::cache_write(CacheData& key)
-{
- CacheData value;
-
- value.add(pack.root_index);
- value.add(pack.SAH);
-
- value.add(pack.nodes);
- value.add(pack.leaf_nodes);
- value.add(pack.object_node);
- value.add(pack.tri_woop);
- value.add(pack.prim_type);
- value.add(pack.prim_visibility);
- value.add(pack.prim_index);
- value.add(pack.prim_object);
-
- Cache::global.insert(key, value);
-
- cache_filename = key.get_filename();
-}
-
-void BVH::clear_cache_except()
-{
- set<string> except;
-
- if(!cache_filename.empty())
- except.insert(cache_filename);
-
- foreach(Object *ob, objects) {
- Mesh *mesh = ob->mesh;
- BVH *bvh = mesh->bvh;
-
- if(bvh && !bvh->cache_filename.empty())
- except.insert(bvh->cache_filename);
- }
-
- Cache::global.clear_except("bvh", except);
-}
-
/* Building */
void BVH::build(Progress& progress)
{
progress.set_substatus("Building BVH");
- /* cache read */
- CacheData key("bvh");
-
- if(params.use_cache) {
- progress.set_substatus("Looking in BVH cache");
-
- if(cache_read(key))
- return;
- }
-
/* build nodes */
BVHBuild bvh_build(objects,
pack.prim_type,
@@ -227,18 +113,6 @@ void BVH::build(Progress& progress)
/* free build nodes */
root->deleteSubtree();
-
- if(progress.get_cancel()) return;
-
- /* cache write */
- if(params.use_cache) {
- progress.set_substatus("Writing BVH cache");
- cache_write(key);
-
- /* clear other bvh files from cache */
- if(params.top_level)
- clear_cache_except();
- }
}
/* Refitting */
diff --git a/intern/cycles/bvh/bvh.h b/intern/cycles/bvh/bvh.h
index 669d2ccdcd5..272a3fa1514 100644
--- a/intern/cycles/bvh/bvh.h
+++ b/intern/cycles/bvh/bvh.h
@@ -20,7 +20,6 @@
#include "bvh_params.h"
-#include "util_string.h"
#include "util_types.h"
#include "util_vector.h"
@@ -30,7 +29,6 @@ class BVHNode;
struct BVHStackEntry;
class BVHParams;
class BoundBox;
-class CacheData;
class LeafNode;
class Object;
class Progress;
@@ -87,7 +85,6 @@ public:
PackedBVH pack;
BVHParams params;
vector<Object*> objects;
- string cache_filename;
static BVH *create(const BVHParams& params, const vector<Object*>& objects);
virtual ~BVH() {}
@@ -95,15 +92,9 @@ public:
void build(Progress& progress);
void refit(Progress& progress);
- void clear_cache_except();
-
protected:
BVH(const BVHParams& params, const vector<Object*>& objects);
- /* cache */
- bool cache_read(CacheData& key);
- void cache_write(CacheData& key);
-
/* triangles and strands*/
void pack_primitives();
void pack_triangle(int idx, float4 woop[3]);
diff --git a/intern/cycles/bvh/bvh_binning.cpp b/intern/cycles/bvh/bvh_binning.cpp
index db96490a36f..8745e39c21e 100644
--- a/intern/cycles/bvh/bvh_binning.cpp
+++ b/intern/cycles/bvh/bvh_binning.cpp
@@ -76,8 +76,8 @@ BVHObjectBinning::BVHObjectBinning(const BVHRange& job, BVHReference *prims)
prefetch_L2(&prims[start() + i + 8]);
/* map even and odd primitive to bin */
- BVHReference prim0 = prims[start() + i + 0];
- BVHReference prim1 = prims[start() + i + 1];
+ const BVHReference& prim0 = prims[start() + i + 0];
+ const BVHReference& prim1 = prims[start() + i + 1];
int4 bin0 = get_bin(prim0.bounds());
int4 bin1 = get_bin(prim1.bounds());
@@ -96,7 +96,7 @@ BVHObjectBinning::BVHObjectBinning(const BVHRange& job, BVHReference *prims)
/* for uneven number of primitives */
if(i < ssize_t(size())) {
/* map primitive to bin */
- BVHReference prim0 = prims[start() + i];
+ const BVHReference& prim0 = prims[start() + i];
int4 bin0 = get_bin(prim0.bounds());
/* increase bounds of bins */
diff --git a/intern/cycles/bvh/bvh_build.cpp b/intern/cycles/bvh/bvh_build.cpp
index a44ad656316..45b0aaa2d63 100644
--- a/intern/cycles/bvh/bvh_build.cpp
+++ b/intern/cycles/bvh/bvh_build.cpp
@@ -234,8 +234,14 @@ BVHNode* BVHBuild::run()
return NULL;
/* init spatial splits */
- if(params.top_level) /* todo: get rid of this */
+ if(params.top_level) {
+ /* NOTE: Technically it is supported by the builder but it's not really
+ * optimized for speed yet and not really clear yet if it has measurable
+ * improvement on render time. Needs some extra investigation before
+ * enabling spatial split for top level BVH.
+ */
params.use_spatial_split = false;
+ }
spatial_min_overlap = root.bounds().safe_area() * params.spatial_split_alpha;
spatial_right_bounds.clear();
@@ -276,6 +282,8 @@ BVHNode* BVHBuild::run()
else if(!params.use_spatial_split) {
/*rotate(rootnode, 4, 5);*/
rootnode->update_visibility();
+ }
+ if(rootnode != NULL) {
VLOG(1) << "BVH build statistics:\n"
<< " Build time: " << time_dt() - build_start_time << "\n"
<< " Total number of nodes: "
@@ -525,11 +533,9 @@ BVHNode* BVHBuild::create_leaf_node(const BVHRange& range)
/* Extend an array when needed. */
if(prim_type.size() < range.end()) {
assert(params.use_spatial_split);
- /* TODO(sergey): We might want to look into different policies of
- * re-allocation here, so on the one hand we would not do as much
- * re-allocations and on the other hand will have small memory
- * overhead.
- */
+ prim_type.reserve(references.size());
+ prim_index.reserve(references.size());
+ prim_object.reserve(references.size());
prim_type.resize(range.end());
prim_index.resize(range.end());
prim_object.resize(range.end());
diff --git a/intern/cycles/bvh/bvh_params.h b/intern/cycles/bvh/bvh_params.h
index af8d8eeb3ee..faa995c3f29 100644
--- a/intern/cycles/bvh/bvh_params.h
+++ b/intern/cycles/bvh/bvh_params.h
@@ -43,9 +43,6 @@ public:
/* object or mesh level bvh */
bool top_level;
- /* disk cache */
- bool use_cache;
-
/* QBVH */
bool use_qbvh;
@@ -71,7 +68,6 @@ public:
max_curve_leaf_size = 2;
top_level = false;
- use_cache = false;
use_qbvh = false;
}
diff --git a/intern/cycles/bvh/bvh_split.cpp b/intern/cycles/bvh/bvh_split.cpp
index 2290c4143ad..534c1aa73b5 100644
--- a/intern/cycles/bvh/bvh_split.cpp
+++ b/intern/cycles/bvh/bvh_split.cpp
@@ -191,11 +191,16 @@ void BVHSpatialSplit::split(BVHBuild *builder, BVHRange& left, BVHRange& right,
}
}
- /* duplicate or unsplit references intersecting both sides. */
+ /* Duplicate or unsplit references intersecting both sides.
+ *
+ * Duplication happens into a temporary pre-allocated vector in order to
+ * reduce number of memmove() calls happening in vector.insert().
+ */
+ vector<BVHReference> new_refs;
+ new_refs.reserve(right_start - left_end);
while(left_end < right_start) {
/* split reference. */
BVHReference lref, rref;
-
split_reference(builder, lref, rref, refs[left_end], this->dim, this->pos);
/* compute SAH for duplicate/unsplit candidates. */
@@ -234,61 +239,36 @@ void BVHSpatialSplit::split(BVHBuild *builder, BVHRange& left, BVHRange& right,
left_bounds = ldb;
right_bounds = rdb;
refs[left_end++] = lref;
- refs.insert(refs.begin() + right_end, rref);
+ new_refs.push_back(rref);
right_end++;
}
}
-
+ /* Insert duplicated references into actual array in one go. */
+ if(new_refs.size() != 0) {
+ refs.insert(refs.begin() + right_end - new_refs.size(),
+ new_refs.begin(),
+ new_refs.end());
+ }
left = BVHRange(left_bounds, left_start, left_end - left_start);
right = BVHRange(right_bounds, right_start, right_end - right_start);
}
-void BVHSpatialSplit::split_reference(BVHBuild *builder, BVHReference& left, BVHReference& right, const BVHReference& ref, int dim, float pos)
+void BVHSpatialSplit::split_triangle_primitive(const Mesh *mesh,
+ const Transform *tfm,
+ int prim_index,
+ int dim,
+ float pos,
+ BoundBox& left_bounds,
+ BoundBox& right_bounds)
{
- /* initialize boundboxes */
- BoundBox left_bounds = BoundBox::empty;
- BoundBox right_bounds = BoundBox::empty;
-
- /* loop over vertices/edges. */
- Object *ob = builder->objects[ref.prim_object()];
- const Mesh *mesh = ob->mesh;
-
- if(ref.prim_type() & PRIMITIVE_ALL_TRIANGLE) {
- const int *inds = mesh->triangles[ref.prim_index()].v;
- const float3 *verts = &mesh->verts[0];
- const float3* v1 = &verts[inds[2]];
-
- for(int i = 0; i < 3; i++) {
- const float3* v0 = v1;
- int vindex = inds[i];
- v1 = &verts[vindex];
- float v0p = (*v0)[dim];
- float v1p = (*v1)[dim];
-
- /* insert vertex to the boxes it belongs to. */
- if(v0p <= pos)
- left_bounds.grow(*v0);
-
- if(v0p >= pos)
- right_bounds.grow(*v0);
-
- /* edge intersects the plane => insert intersection to both boxes. */
- if((v0p < pos && v1p > pos) || (v0p > pos && v1p < pos)) {
- float3 t = lerp(*v0, *v1, clamp((pos - v0p) / (v1p - v0p), 0.0f, 1.0f));
- left_bounds.grow(t);
- right_bounds.grow(t);
- }
- }
- }
- else {
- /* curve split: NOTE - Currently ignores curve width and needs to be fixed.*/
- const int k0 = mesh->curves[ref.prim_index()].first_key + PRIMITIVE_UNPACK_SEGMENT(ref.prim_type());
- const int k1 = k0 + 1;
- const float4 key0 = mesh->curve_keys[k0];
- const float4 key1 = mesh->curve_keys[k1];
- const float3 v0 = float4_to_float3(key0);
- const float3 v1 = float4_to_float3(key1);
-
+ const int *inds = mesh->triangles[prim_index].v;
+ const float3 *verts = &mesh->verts[0];
+ float3 v1 = tfm ? transform_point(tfm, verts[inds[2]]) : verts[inds[2]];
+
+ for(int i = 0; i < 3; i++) {
+ float3 v0 = v1;
+ int vindex = inds[i];
+ v1 = tfm ? transform_point(tfm, verts[vindex]) : verts[vindex];
float v0p = v0[dim];
float v1p = v1[dim];
@@ -299,12 +279,6 @@ void BVHSpatialSplit::split_reference(BVHBuild *builder, BVHReference& left, BVH
if(v0p >= pos)
right_bounds.grow(v0);
- if(v1p <= pos)
- left_bounds.grow(v1);
-
- if(v1p >= pos)
- right_bounds.grow(v1);
-
/* edge intersects the plane => insert intersection to both boxes. */
if((v0p < pos && v1p > pos) || (v0p > pos && v1p < pos)) {
float3 t = lerp(v0, v1, clamp((pos - v0p) / (v1p - v0p), 0.0f, 1.0f));
@@ -312,6 +286,159 @@ void BVHSpatialSplit::split_reference(BVHBuild *builder, BVHReference& left, BVH
right_bounds.grow(t);
}
}
+}
+
+void BVHSpatialSplit::split_curve_primitive(const Mesh *mesh,
+ const Transform *tfm,
+ int prim_index,
+ int segment_index,
+ int dim,
+ float pos,
+ BoundBox& left_bounds,
+ BoundBox& right_bounds)
+{
+ /* curve split: NOTE - Currently ignores curve width and needs to be fixed.*/
+ const int k0 = mesh->curves[prim_index].first_key + segment_index;
+ const int k1 = k0 + 1;
+ const float4& key0 = mesh->curve_keys[k0];
+ const float4& key1 = mesh->curve_keys[k1];
+ float3 v0 = float4_to_float3(key0);
+ float3 v1 = float4_to_float3(key1);
+
+ if(tfm != NULL) {
+ v0 = transform_point(tfm, v0);
+ v1 = transform_point(tfm, v1);
+ }
+
+ float v0p = v0[dim];
+ float v1p = v1[dim];
+
+ /* insert vertex to the boxes it belongs to. */
+ if(v0p <= pos)
+ left_bounds.grow(v0);
+
+ if(v0p >= pos)
+ right_bounds.grow(v0);
+
+ if(v1p <= pos)
+ left_bounds.grow(v1);
+
+ if(v1p >= pos)
+ right_bounds.grow(v1);
+
+ /* edge intersects the plane => insert intersection to both boxes. */
+ if((v0p < pos && v1p > pos) || (v0p > pos && v1p < pos)) {
+ float3 t = lerp(v0, v1, clamp((pos - v0p) / (v1p - v0p), 0.0f, 1.0f));
+ left_bounds.grow(t);
+ right_bounds.grow(t);
+ }
+}
+
+void BVHSpatialSplit::split_triangle_reference(const BVHReference& ref,
+ const Mesh *mesh,
+ int dim,
+ float pos,
+ BoundBox& left_bounds,
+ BoundBox& right_bounds)
+{
+ split_triangle_primitive(mesh,
+ NULL,
+ ref.prim_index(),
+ dim,
+ pos,
+ left_bounds,
+ right_bounds);
+}
+
+void BVHSpatialSplit::split_curve_reference(const BVHReference& ref,
+ const Mesh *mesh,
+ int dim,
+ float pos,
+ BoundBox& left_bounds,
+ BoundBox& right_bounds)
+{
+ split_curve_primitive(mesh,
+ NULL,
+ ref.prim_index(),
+ PRIMITIVE_UNPACK_SEGMENT(ref.prim_type()),
+ dim,
+ pos,
+ left_bounds,
+ right_bounds);
+}
+
+void BVHSpatialSplit::split_object_reference(const Object *object,
+ int dim,
+ float pos,
+ BoundBox& left_bounds,
+ BoundBox& right_bounds)
+{
+ Mesh *mesh = object->mesh;
+ for(int tri_idx = 0; tri_idx < mesh->triangles.size(); ++tri_idx) {
+ split_triangle_primitive(mesh,
+ &object->tfm,
+ tri_idx,
+ dim,
+ pos,
+ left_bounds,
+ right_bounds);
+ }
+ for(int curve_idx = 0; curve_idx < mesh->curves.size(); ++curve_idx) {
+ Mesh::Curve &curve = mesh->curves[curve_idx];
+ for(int segment_idx = 0;
+ segment_idx < curve.num_keys - 1;
+ ++segment_idx)
+ {
+ split_curve_primitive(mesh,
+ &object->tfm,
+ curve_idx,
+ segment_idx,
+ dim,
+ pos,
+ left_bounds,
+ right_bounds);
+ }
+ }
+}
+
+void BVHSpatialSplit::split_reference(BVHBuild *builder,
+ BVHReference& left,
+ BVHReference& right,
+ const BVHReference& ref,
+ int dim,
+ float pos)
+{
+ /* initialize boundboxes */
+ BoundBox left_bounds = BoundBox::empty;
+ BoundBox right_bounds = BoundBox::empty;
+
+ /* loop over vertices/edges. */
+ Object *ob = builder->objects[ref.prim_object()];
+ const Mesh *mesh = ob->mesh;
+
+ if(ref.prim_type() & PRIMITIVE_ALL_TRIANGLE) {
+ split_triangle_reference(ref,
+ mesh,
+ dim,
+ pos,
+ left_bounds,
+ right_bounds);
+ }
+ else if(ref.prim_type() & PRIMITIVE_ALL_CURVE) {
+ split_curve_reference(ref,
+ mesh,
+ dim,
+ pos,
+ left_bounds,
+ right_bounds);
+ }
+ else {
+ split_object_reference(ob,
+ dim,
+ pos,
+ left_bounds,
+ right_bounds);
+ }
/* intersect with original bounds. */
left_bounds.max[dim] = pos;
diff --git a/intern/cycles/bvh/bvh_split.h b/intern/cycles/bvh/bvh_split.h
index 5b739311e5f..1e46bb66203 100644
--- a/intern/cycles/bvh/bvh_split.h
+++ b/intern/cycles/bvh/bvh_split.h
@@ -55,7 +55,58 @@ public:
BVHSpatialSplit(BVHBuild *builder, const BVHRange& range, float nodeSAH);
void split(BVHBuild *builder, BVHRange& left, BVHRange& right, const BVHRange& range);
- void split_reference(BVHBuild *builder, BVHReference& left, BVHReference& right, const BVHReference& ref, int dim, float pos);
+ void split_reference(BVHBuild *builder,
+ BVHReference& left,
+ BVHReference& right,
+ const BVHReference& ref,
+ int dim,
+ float pos);
+
+protected:
+ /* Lower-level functions which calculates boundaries of left and right nodes
+ * needed for spatial split.
+ *
+ * Operates directly with primitive specified by it's index, reused by higher
+ * level splitting functions.
+ */
+ void split_triangle_primitive(const Mesh *mesh,
+ const Transform *tfm,
+ int prim_index,
+ int dim,
+ float pos,
+ BoundBox& left_bounds,
+ BoundBox& right_bounds);
+ void split_curve_primitive(const Mesh *mesh,
+ const Transform *tfm,
+ int prim_index,
+ int segment_index,
+ int dim,
+ float pos,
+ BoundBox& left_bounds,
+ BoundBox& right_bounds);
+
+ /* Lower-level functions which calculates boundaries of left and right nodes
+ * needed for spatial split.
+ *
+ * Operates with BVHReference, internally uses lower level API functions.
+ */
+ void split_triangle_reference(const BVHReference& ref,
+ const Mesh *mesh,
+ int dim,
+ float pos,
+ BoundBox& left_bounds,
+ BoundBox& right_bounds);
+ void split_curve_reference(const BVHReference& ref,
+ const Mesh *mesh,
+ int dim,
+ float pos,
+ BoundBox& left_bounds,
+ BoundBox& right_bounds);
+ void split_object_reference(const Object *object,
+ int dim,
+ float pos,
+ BoundBox& left_bounds,
+ BoundBox& right_bounds);
};
/* Mixed Object-Spatial Split */
diff --git a/intern/cycles/cmake/external_libs.cmake b/intern/cycles/cmake/external_libs.cmake
index d7c59f42a5e..10a166b6e44 100644
--- a/intern/cycles/cmake/external_libs.cmake
+++ b/intern/cycles/cmake/external_libs.cmake
@@ -87,6 +87,13 @@ if(CYCLES_STANDALONE_REPOSITORY)
find_package(OpenEXR)
####
+ # OpenShadingLanguage
+ if(WITH_CYCLES_OSL)
+ find_package(OpenShadingLanguage REQUIRED)
+ find_package(LLVM REQUIRED)
+ endif()
+
+ ####
# Boost
set(__boost_packages filesystem regex system thread date_time)
if(WITH_CYCLES_NETWORK)
@@ -97,6 +104,8 @@ if(CYCLES_STANDALONE_REPOSITORY)
# libraries works, could be different for someone's else libs..
if(APPLE OR MSVC)
list(APPEND __boost_packages wave)
+ elseif(NOT (${OSL_LIBRARY_VERSION_MAJOR} EQUAL "1" AND ${OSL_LIBRARY_VERSION_MINOR} LESS "6"))
+ list(APPEND __boost_packages wave)
endif()
endif()
find_package(Boost 1.48 COMPONENTS ${__boost_packages} REQUIRED)
@@ -114,13 +123,6 @@ if(CYCLES_STANDALONE_REPOSITORY)
set(BOOST_DEFINITIONS "-DBOOST_ALL_NO_LIB")
####
- # OpenShadingLanguage
- if(WITH_CYCLES_OSL)
- find_package(OpenShadingLanguage REQUIRED)
- find_package(LLVM REQUIRED)
- endif()
-
- ####
# Logging
if(WITH_CYCLES_LOGGING)
find_package(Glog REQUIRED)
diff --git a/intern/cycles/device/device_memory.h b/intern/cycles/device/device_memory.h
index ba79f8c88ae..8c32d03135e 100644
--- a/intern/cycles/device/device_memory.h
+++ b/intern/cycles/device/device_memory.h
@@ -211,7 +211,10 @@ public:
T *resize(size_t width, size_t height = 0, size_t depth = 0)
{
data_size = width * ((height == 0)? 1: height) * ((depth == 0)? 1: depth);
- data.resize(data_size);
+ if(data.resize(data_size) == NULL) {
+ clear();
+ return NULL;
+ }
data_width = width;
data_height = height;
data_depth = depth;
@@ -226,7 +229,9 @@ public:
T *copy(T *ptr, size_t width, size_t height = 0, size_t depth = 0)
{
T *mem = resize(width, height, depth);
- memcpy(mem, ptr, memory_size());
+ if(mem != NULL) {
+ memcpy(mem, ptr, memory_size());
+ }
return mem;
}
diff --git a/intern/cycles/device/device_network.cpp b/intern/cycles/device/device_network.cpp
index d1f941ad9f2..afa35224aba 100644
--- a/intern/cycles/device/device_network.cpp
+++ b/intern/cycles/device/device_network.cpp
@@ -574,13 +574,13 @@ protected:
network_device_memory mem;
string name;
InterpolationType interpolation;
- ExtensionType extension_typr;
+ ExtensionType extension_type;
device_ptr client_pointer;
rcv.read(name);
rcv.read(mem);
rcv.read(interpolation);
- rcv.read(extension);
+ rcv.read(extension_type);
lock.unlock();
client_pointer = mem.device_pointer;
@@ -596,7 +596,7 @@ protected:
rcv.read_buffer((uint8_t*)mem.data_pointer, data_size);
- device->tex_alloc(name.c_str(), mem, interpolation, extension);
+ device->tex_alloc(name.c_str(), mem, interpolation, extension_type);
pointer_mapping_insert(client_pointer, mem.device_pointer);
}
diff --git a/intern/cycles/device/device_opencl.cpp b/intern/cycles/device/device_opencl.cpp
index fee9a8a803d..7f16a73d966 100644
--- a/intern/cycles/device/device_opencl.cpp
+++ b/intern/cycles/device/device_opencl.cpp
@@ -313,7 +313,7 @@ void opencl_get_usable_devices(vector<OpenCLPlatformDevice> *usable_devices)
continue;
}
if(!opencl_device_version_check(device_id)) {
- FIRST_VLOG(2) << "Ignoting device " << device_name
+ FIRST_VLOG(2) << "Ignoring device " << device_name
<< " due to old compiler version.";
continue;
}
@@ -327,8 +327,8 @@ void opencl_get_usable_devices(vector<OpenCLPlatformDevice> *usable_devices)
&device_type,
NULL) != CL_SUCCESS)
{
- FIRST_VLOG(2) << "Ignoting device " << device_name
- << ", faield to fetch device type.";
+ FIRST_VLOG(2) << "Ignoring device " << device_name
+ << ", failed to fetch device type.";
continue;
}
FIRST_VLOG(2) << "Adding new device " << device_name << ".";
@@ -339,7 +339,7 @@ void opencl_get_usable_devices(vector<OpenCLPlatformDevice> *usable_devices)
device_name));
}
else {
- FIRST_VLOG(2) << "Ignoting device " << device_name
+ FIRST_VLOG(2) << "Ignoring device " << device_name
<< ", not officially supported yet.";
}
}
@@ -581,7 +581,7 @@ public:
ProgramName program_name,
thread_scoped_lock& slot_locker)
{
- switch (program_name) {
+ switch(program_name) {
case OCL_DEV_BASE_PROGRAM:
store_something<cl_program>(platform,
device,
@@ -995,6 +995,7 @@ public:
VLOG(2) << "Loaded kernel from " << clbin << ".";
}
else {
+ VLOG(2) << "Kernel file " << clbin << " either doesn't exist or failed to be loaded by driver.";
string init_kernel_source = "#include \"kernels/opencl/kernel.cl\" // " + kernel_md5 + "\n";
/* If does not exist or loading binary failed, compile kernel. */
@@ -1605,7 +1606,7 @@ protected:
* mega kernel is not getting feature-based optimizations.
*
* Ideally we need always compile kernel with as less features
- * enabed as possible to keep performance at it's max.
+ * enabled as possible to keep performance at it's max.
*/
return "";
}
@@ -3689,7 +3690,7 @@ string device_opencl_capabilities(void)
APPEND_STRING_INFO(clGetDeviceInfo, id, "\t\t\tDevice " name, what)
vector<cl_device_id> device_ids;
- for (cl_uint platform = 0; platform < num_platforms; ++platform) {
+ for(cl_uint platform = 0; platform < num_platforms; ++platform) {
cl_platform_id platform_id = platform_ids[platform];
result += string_printf("Platform #%u\n", platform);
@@ -3714,7 +3715,7 @@ string device_opencl_capabilities(void)
num_devices,
&device_ids[0],
NULL));
- for (cl_uint device = 0; device < num_devices; ++device) {
+ for(cl_uint device = 0; device < num_devices; ++device) {
cl_device_id device_id = device_ids[device];
result += string_printf("\t\tDevice: #%u\n", device);
diff --git a/intern/cycles/kernel/geom/geom_bvh_shadow.h b/intern/cycles/kernel/geom/geom_bvh_shadow.h
index e4cba99dc96..cb3f75f2a8f 100644
--- a/intern/cycles/kernel/geom/geom_bvh_shadow.h
+++ b/intern/cycles/kernel/geom/geom_bvh_shadow.h
@@ -59,7 +59,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
float isect_t = tmax;
#if BVH_FEATURE(BVH_MOTION)
- Transform ob_tfm;
+ Transform ob_itfm;
#endif
#if BVH_FEATURE(BVH_INSTANCING)
@@ -302,7 +302,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
object = kernel_tex_fetch(__prim_object, -primAddr-1);
#if BVH_FEATURE(BVH_MOTION)
- bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_tfm);
+ bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_itfm);
#else
bvh_instance_push(kg, object, ray, &P, &dir, &idir, &isect_t);
#endif
@@ -338,7 +338,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
float t_fac;
#if BVH_FEATURE(BVH_MOTION)
- bvh_instance_motion_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac, &ob_tfm);
+ bvh_instance_motion_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac, &ob_itfm);
#else
bvh_instance_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac);
#endif
@@ -353,7 +353,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
float ignore_t = FLT_MAX;
#if BVH_FEATURE(BVH_MOTION)
- bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &ignore_t, &ob_tfm);
+ bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &ignore_t, &ob_itfm);
#else
bvh_instance_pop(kg, object, ray, &P, &dir, &idir, &ignore_t);
#endif
diff --git a/intern/cycles/kernel/geom/geom_bvh_subsurface.h b/intern/cycles/kernel/geom/geom_bvh_subsurface.h
index a73139f9c88..a093b9b55aa 100644
--- a/intern/cycles/kernel/geom/geom_bvh_subsurface.h
+++ b/intern/cycles/kernel/geom/geom_bvh_subsurface.h
@@ -63,7 +63,7 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
uint num_hits = 0;
#if BVH_FEATURE(BVH_MOTION)
- Transform ob_tfm;
+ Transform ob_itfm;
#endif
#if defined(__KERNEL_SSE2__)
@@ -240,7 +240,7 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
object = subsurface_object;
#if BVH_FEATURE(BVH_MOTION)
- bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_tfm);
+ bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_itfm);
#else
bvh_instance_push(kg, object, ray, &P, &dir, &idir, &isect_t);
#endif
@@ -278,7 +278,7 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
/* instance pop */
#if BVH_FEATURE(BVH_MOTION)
- bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_tfm);
+ bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_itfm);
#else
bvh_instance_pop(kg, object, ray, &P, &dir, &idir, &isect_t);
#endif
diff --git a/intern/cycles/kernel/geom/geom_bvh_traversal.h b/intern/cycles/kernel/geom/geom_bvh_traversal.h
index 73d79fd78ee..13d118b6d19 100644
--- a/intern/cycles/kernel/geom/geom_bvh_traversal.h
+++ b/intern/cycles/kernel/geom/geom_bvh_traversal.h
@@ -65,7 +65,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
int object = OBJECT_NONE;
#if BVH_FEATURE(BVH_MOTION)
- Transform ob_tfm;
+ Transform ob_itfm;
#endif
isect->t = ray->t;
@@ -342,7 +342,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
object = kernel_tex_fetch(__prim_object, -primAddr-1);
#if BVH_FEATURE(BVH_MOTION)
- bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_tfm);
+ bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_itfm);
#else
bvh_instance_push(kg, object, ray, &P, &dir, &idir, &isect->t);
#endif
@@ -378,7 +378,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
/* instance pop */
#if BVH_FEATURE(BVH_MOTION)
- bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_tfm);
+ bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_itfm);
#else
bvh_instance_pop(kg, object, ray, &P, &dir, &idir, &isect->t);
#endif
diff --git a/intern/cycles/kernel/geom/geom_bvh_volume.h b/intern/cycles/kernel/geom/geom_bvh_volume.h
index 41c784869f2..656cd6e7a0e 100644
--- a/intern/cycles/kernel/geom/geom_bvh_volume.h
+++ b/intern/cycles/kernel/geom/geom_bvh_volume.h
@@ -59,7 +59,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
const uint visibility = PATH_RAY_ALL_VISIBILITY;
#if BVH_FEATURE(BVH_MOTION)
- Transform ob_tfm;
+ Transform ob_itfm;
#endif
isect->t = ray->t;
@@ -267,7 +267,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
if(object_flag & SD_OBJECT_HAS_VOLUME) {
#if BVH_FEATURE(BVH_MOTION)
- bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_tfm);
+ bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_itfm);
#else
bvh_instance_push(kg, object, ray, &P, &dir, &idir, &isect->t);
#endif
@@ -307,7 +307,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
/* instance pop */
#if BVH_FEATURE(BVH_MOTION)
- bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_tfm);
+ bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_itfm);
#else
bvh_instance_pop(kg, object, ray, &P, &dir, &idir, &isect->t);
#endif
diff --git a/intern/cycles/kernel/geom/geom_bvh_volume_all.h b/intern/cycles/kernel/geom/geom_bvh_volume_all.h
index b6db36f4b17..8f7e3adae51 100644
--- a/intern/cycles/kernel/geom/geom_bvh_volume_all.h
+++ b/intern/cycles/kernel/geom/geom_bvh_volume_all.h
@@ -62,7 +62,7 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
const uint visibility = PATH_RAY_ALL_VISIBILITY;
#if BVH_FEATURE(BVH_MOTION)
- Transform ob_tfm;
+ Transform ob_itfm;
#endif
#if BVH_FEATURE(BVH_INSTANCING)
@@ -230,10 +230,10 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
if(num_hits == max_hits) {
#if BVH_FEATURE(BVH_INSTANCING)
#if BVH_FEATURE(BVH_MOTION)
- float t_fac = len(transform_direction(&ob_tfm, 1.0f/idir));
+ float t_fac = 1.0f / len(transform_direction(&ob_itfm, dir));
#else
- Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
- float t_fac = len(transform_direction(&tfm, 1.0f/idir));
+ Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
+ float t_fac = 1.0f / len(transform_direction(&itfm, dir));
#endif
for(int i = 0; i < num_hits_in_instance; i++) {
(isect_array-i-1)->t *= t_fac;
@@ -268,10 +268,10 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
if(num_hits == max_hits) {
#if BVH_FEATURE(BVH_INSTANCING)
# if BVH_FEATURE(BVH_MOTION)
- float t_fac = len(transform_direction(&ob_tfm, 1.0f/idir));
+ float t_fac = 1.0f / len(transform_direction(&ob_itfm, dir));
# else
- Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
- float t_fac = len(transform_direction(&tfm, 1.0f/idir));
+ Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
+ float t_fac = 1.0f / len(transform_direction(&itfm, dir));
#endif
for(int i = 0; i < num_hits_in_instance; i++) {
(isect_array-i-1)->t *= t_fac;
@@ -311,10 +311,10 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
if(num_hits == max_hits) {
#if BVH_FEATURE(BVH_INSTANCING)
# if BVH_FEATURE(BVH_MOTION)
- float t_fac = len(transform_direction(&ob_tfm, 1.0f/idir));
+ float t_fac = 1.0f / len(transform_direction(&ob_itfm, dir));
# else
- Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
- float t_fac = len(transform_direction(&tfm, 1.0f/idir));
+ Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
+ float t_fac = 1.0f / len(transform_direction(&itfm, dir));
#endif
for(int i = 0; i < num_hits_in_instance; i++) {
(isect_array-i-1)->t *= t_fac;
@@ -341,7 +341,7 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
if(object_flag & SD_OBJECT_HAS_VOLUME) {
#if BVH_FEATURE(BVH_MOTION)
- bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_tfm);
+ bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_itfm);
#else
bvh_instance_push(kg, object, ray, &P, &dir, &idir, &isect_t);
#endif
@@ -384,7 +384,7 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
if(num_hits_in_instance) {
float t_fac;
#if BVH_FEATURE(BVH_MOTION)
- bvh_instance_motion_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac, &ob_tfm);
+ bvh_instance_motion_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac, &ob_itfm);
#else
bvh_instance_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac);
#endif
@@ -397,7 +397,7 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
else {
float ignore_t = FLT_MAX;
#if BVH_FEATURE(BVH_MOTION)
- bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &ignore_t, &ob_tfm);
+ bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &ignore_t, &ob_itfm);
#else
bvh_instance_pop(kg, object, ray, &P, &dir, &idir, &ignore_t);
#endif
diff --git a/intern/cycles/kernel/geom/geom_object.h b/intern/cycles/kernel/geom/geom_object.h
index 9d0a008fff1..ffd2f3b778f 100644
--- a/intern/cycles/kernel/geom/geom_object.h
+++ b/intern/cycles/kernel/geom/geom_object.h
@@ -428,8 +428,8 @@ ccl_device_inline void qbvh_instance_push(KernelGlobals *kg,
ccl_device_inline void bvh_instance_pop(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *dir, float3 *idir, ccl_addr_space float *t)
{
if(*t != FLT_MAX) {
- Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
- *t *= len(transform_direction(&tfm, 1.0f/(*idir)));
+ Transform tfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
+ *t /= len(transform_direction(&tfm, ray->D));
}
*P = ray->P;
@@ -441,8 +441,8 @@ ccl_device_inline void bvh_instance_pop(KernelGlobals *kg, int object, const Ray
ccl_device_inline void bvh_instance_pop_factor(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *dir, float3 *idir, float *t_fac)
{
- Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
- *t_fac = len(transform_direction(&tfm, 1.0f/(*idir)));
+ Transform tfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
+ *t_fac = 1.0f / len(transform_direction(&tfm, ray->D));
*P = ray->P;
*dir = bvh_clamp_direction(ray->D);
@@ -453,15 +453,21 @@ ccl_device_inline void bvh_instance_pop_factor(KernelGlobals *kg, int object, co
#ifdef __OBJECT_MOTION__
/* Transform ray into object space to enter motion blurred object in BVH */
-ccl_device_inline void bvh_instance_motion_push(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *dir, float3 *idir, ccl_addr_space float *t, Transform *tfm)
+ccl_device_inline void bvh_instance_motion_push(KernelGlobals *kg,
+ int object,
+ const Ray *ray,
+ float3 *P,
+ float3 *dir,
+ float3 *idir,
+ ccl_addr_space float *t,
+ Transform *itfm)
{
- Transform itfm;
- *tfm = object_fetch_transform_motion_test(kg, object, ray->time, &itfm);
+ object_fetch_transform_motion_test(kg, object, ray->time, itfm);
- *P = transform_point(&itfm, ray->P);
+ *P = transform_point(itfm, ray->P);
float len;
- *dir = bvh_clamp_direction(normalize_len(transform_direction(&itfm, ray->D), &len));
+ *dir = bvh_clamp_direction(normalize_len(transform_direction(itfm, ray->D), &len));
*idir = bvh_inverse_direction(*dir);
if(*t != FLT_MAX)
@@ -475,18 +481,24 @@ ccl_device_inline void bvh_instance_motion_push(KernelGlobals *kg, int object, c
* TODO(sergey): Investigate if passing NULL instead of t1 gets optimized
* so we can avoid having this duplication.
*/
-ccl_device_inline void qbvh_instance_motion_push(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *dir, float3 *idir, float *t, float *t1, Transform *tfm)
+ccl_device_inline void qbvh_instance_motion_push(KernelGlobals *kg,
+ int object,
+ const Ray *ray,
+ float3 *P,
+ float3 *dir,
+ float3 *idir,
+ float *t,
+ float *t1,
+ Transform *itfm)
{
- Transform itfm;
- *tfm = object_fetch_transform_motion_test(kg, object, ray->time, &itfm);
+ object_fetch_transform_motion_test(kg, object, ray->time, itfm);
- *P = transform_point(&itfm, ray->P);
+ *P = transform_point(itfm, ray->P);
float len;
- *dir = bvh_clamp_direction(normalize_len(transform_direction(&itfm, ray->D), &len));
+ *dir = bvh_clamp_direction(normalize_len(transform_direction(itfm, ray->D), &len));
*idir = bvh_inverse_direction(*dir);
-
if(*t != FLT_MAX)
*t *= len;
@@ -497,10 +509,18 @@ ccl_device_inline void qbvh_instance_motion_push(KernelGlobals *kg, int object,
/* Transorm ray to exit motion blurred object in BVH */
-ccl_device_inline void bvh_instance_motion_pop(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *dir, float3 *idir, ccl_addr_space float *t, Transform *tfm)
+ccl_device_inline void bvh_instance_motion_pop(KernelGlobals *kg,
+ int object,
+ const Ray *ray,
+ float3 *P,
+ float3 *dir,
+ float3 *idir,
+ ccl_addr_space float *t,
+ Transform *itfm)
{
- if(*t != FLT_MAX)
- *t *= len(transform_direction(tfm, 1.0f/(*idir)));
+ if(*t != FLT_MAX) {
+ *t /= len(transform_direction(itfm, ray->D));
+ }
*P = ray->P;
*dir = bvh_clamp_direction(ray->D);
@@ -509,10 +529,16 @@ ccl_device_inline void bvh_instance_motion_pop(KernelGlobals *kg, int object, co
/* Same as above, but returns scale factor to apply to multiple intersection distances */
-ccl_device_inline void bvh_instance_motion_pop_factor(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *dir, float3 *idir, float *t_fac, Transform *tfm)
+ccl_device_inline void bvh_instance_motion_pop_factor(KernelGlobals *kg,
+ int object,
+ const Ray *ray,
+ float3 *P,
+ float3 *dir,
+ float3 *idir,
+ float *t_fac,
+ Transform *itfm)
{
- *t_fac = len(transform_direction(tfm, 1.0f/(*idir)));
-
+ *t_fac /= len(transform_direction(itfm, ray->D));
*P = ray->P;
*dir = bvh_clamp_direction(ray->D);
*idir = bvh_inverse_direction(*dir);
diff --git a/intern/cycles/kernel/geom/geom_qbvh_shadow.h b/intern/cycles/kernel/geom/geom_qbvh_shadow.h
index dc37e6ecfa4..4564d5baf5e 100644
--- a/intern/cycles/kernel/geom/geom_qbvh_shadow.h
+++ b/intern/cycles/kernel/geom/geom_qbvh_shadow.h
@@ -55,7 +55,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
float isect_t = tmax;
#if BVH_FEATURE(BVH_MOTION)
- Transform ob_tfm;
+ Transform ob_itfm;
#endif
*num_hits = 0;
@@ -317,7 +317,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
object = kernel_tex_fetch(__prim_object, -primAddr-1);
#if BVH_FEATURE(BVH_MOTION)
- bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_tfm);
+ bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_itfm);
#else
bvh_instance_push(kg, object, ray, &P, &dir, &idir, &isect_t);
#endif
@@ -357,7 +357,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
float t_fac;
#if BVH_FEATURE(BVH_MOTION)
- bvh_instance_motion_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac, &ob_tfm);
+ bvh_instance_motion_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac, &ob_itfm);
#else
bvh_instance_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac);
#endif
@@ -370,7 +370,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
float ignore_t = FLT_MAX;
#if BVH_FEATURE(BVH_MOTION)
- bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &ignore_t, &ob_tfm);
+ bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &ignore_t, &ob_itfm);
#else
bvh_instance_pop(kg, object, ray, &P, &dir, &idir, &ignore_t);
#endif
diff --git a/intern/cycles/kernel/geom/geom_qbvh_subsurface.h b/intern/cycles/kernel/geom/geom_qbvh_subsurface.h
index d85e1a4691e..fe231720cf7 100644
--- a/intern/cycles/kernel/geom/geom_qbvh_subsurface.h
+++ b/intern/cycles/kernel/geom/geom_qbvh_subsurface.h
@@ -58,7 +58,7 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
uint num_hits = 0;
#if BVH_FEATURE(BVH_MOTION)
- Transform ob_tfm;
+ Transform ob_itfm;
#endif
#ifndef __KERNEL_SSE41__
@@ -256,7 +256,7 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
object = subsurface_object;
#if BVH_FEATURE(BVH_MOTION)
- bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_tfm);
+ bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_itfm);
#else
bvh_instance_push(kg, object, ray, &P, &dir, &idir, &isect_t);
#endif
@@ -297,7 +297,7 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
/* Instance pop. */
#if BVH_FEATURE(BVH_MOTION)
- bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_tfm);
+ bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_itfm);
#else
bvh_instance_pop(kg, object, ray, &P, &dir, &idir, &isect_t);
#endif
diff --git a/intern/cycles/kernel/geom/geom_qbvh_traversal.h b/intern/cycles/kernel/geom/geom_qbvh_traversal.h
index 7e356ea062b..4e1678665c0 100644
--- a/intern/cycles/kernel/geom/geom_qbvh_traversal.h
+++ b/intern/cycles/kernel/geom/geom_qbvh_traversal.h
@@ -63,7 +63,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
int object = OBJECT_NONE;
#if BVH_FEATURE(BVH_MOTION)
- Transform ob_tfm;
+ Transform ob_itfm;
#endif
#ifndef __KERNEL_SSE41__
@@ -356,7 +356,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
object = kernel_tex_fetch(__prim_object, -primAddr-1);
#if BVH_FEATURE(BVH_MOTION)
- qbvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect->t, &nodeDist, &ob_tfm);
+ qbvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect->t, &nodeDist, &ob_itfm);
#else
qbvh_instance_push(kg, object, ray, &P, &dir, &idir, &isect->t, &nodeDist);
#endif
@@ -395,7 +395,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
/* Instance pop. */
#if BVH_FEATURE(BVH_MOTION)
- bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_tfm);
+ bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_itfm);
#else
bvh_instance_pop(kg, object, ray, &P, &dir, &idir, &isect->t);
#endif
diff --git a/intern/cycles/kernel/geom/geom_qbvh_volume.h b/intern/cycles/kernel/geom/geom_qbvh_volume.h
index d8cfa3a4061..40864471d13 100644
--- a/intern/cycles/kernel/geom/geom_qbvh_volume.h
+++ b/intern/cycles/kernel/geom/geom_qbvh_volume.h
@@ -54,7 +54,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
const uint visibility = PATH_RAY_ALL_VISIBILITY;
#if BVH_FEATURE(BVH_MOTION)
- Transform ob_tfm;
+ Transform ob_itfm;
#endif
#ifndef __KERNEL_SSE41__
@@ -281,7 +281,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
if(object_flag & SD_OBJECT_HAS_VOLUME) {
#if BVH_FEATURE(BVH_MOTION)
- bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_tfm);
+ bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_itfm);
#else
bvh_instance_push(kg, object, ray, &P, &dir, &idir, &isect->t);
#endif
@@ -322,7 +322,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
/* Instance pop. */
#if BVH_FEATURE(BVH_MOTION)
- bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_tfm);
+ bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_itfm);
#else
bvh_instance_pop(kg, object, ray, &P, &dir, &idir, &isect->t);
#endif
diff --git a/intern/cycles/kernel/geom/geom_qbvh_volume_all.h b/intern/cycles/kernel/geom/geom_qbvh_volume_all.h
index 056ca9a1ad9..75e4c4e8d96 100644
--- a/intern/cycles/kernel/geom/geom_qbvh_volume_all.h
+++ b/intern/cycles/kernel/geom/geom_qbvh_volume_all.h
@@ -57,7 +57,7 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
const uint visibility = PATH_RAY_ALL_VISIBILITY;
#if BVH_FEATURE(BVH_MOTION)
- Transform ob_tfm;
+ Transform ob_itfm;
#endif
uint num_hits = 0;
@@ -247,10 +247,10 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
if(num_hits == max_hits) {
#if BVH_FEATURE(BVH_INSTANCING)
#if BVH_FEATURE(BVH_MOTION)
- float t_fac = len(transform_direction(&ob_tfm, 1.0f/idir));
+ float t_fac = 1.0f / len(transform_direction(&ob_itfm, dir));
#else
- Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
- float t_fac = len(transform_direction(&tfm, 1.0f/idir));
+ Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
+ float t_fac = 1.0f / len(transform_direction(&itfm, dir));
#endif
for(int i = 0; i < num_hits_in_instance; i++) {
(isect_array-i-1)->t *= t_fac;
@@ -285,10 +285,10 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
if(num_hits == max_hits) {
#if BVH_FEATURE(BVH_INSTANCING)
# if BVH_FEATURE(BVH_MOTION)
- float t_fac = len(transform_direction(&ob_tfm, 1.0f/idir));
+ float t_fac = 1.0f / len(transform_direction(&ob_itfm, dir));
# else
- Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
- float t_fac = len(transform_direction(&tfm, 1.0f/idir));
+ Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
+ float t_fac = 1.0f / len(transform_direction(&itfm, dir));
#endif
for(int i = 0; i < num_hits_in_instance; i++) {
(isect_array-i-1)->t *= t_fac;
@@ -328,10 +328,10 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
if(num_hits == max_hits) {
#if BVH_FEATURE(BVH_INSTANCING)
# if BVH_FEATURE(BVH_MOTION)
- float t_fac = len(transform_direction(&ob_tfm, 1.0f/idir));
+ float t_fac = 1.0f / len(transform_direction(&ob_itfm, dir));
# else
- Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
- float t_fac = len(transform_direction(&tfm, 1.0f/idir));
+ Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
+ float t_fac = 1.0f / len(transform_direction(&itfm, dir));
#endif
for(int i = 0; i < num_hits_in_instance; i++) {
(isect_array-i-1)->t *= t_fac;
@@ -355,7 +355,7 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
if(object_flag & SD_OBJECT_HAS_VOLUME) {
#if BVH_FEATURE(BVH_MOTION)
- bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_tfm);
+ bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_itfm);
#else
bvh_instance_push(kg, object, ray, &P, &dir, &idir, &isect_t);
#endif
@@ -400,7 +400,7 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
if(num_hits_in_instance) {
float t_fac;
#if BVH_FEATURE(BVH_MOTION)
- bvh_instance_motion_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac, &ob_tfm);
+ bvh_instance_motion_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac, &ob_itfm);
#else
bvh_instance_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac);
#endif
@@ -413,7 +413,7 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
else {
float ignore_t = FLT_MAX;
#if BVH_FEATURE(BVH_MOTION)
- bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &ignore_t, &ob_tfm);
+ bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &ignore_t, &ob_itfm);
#else
bvh_instance_pop(kg, object, ray, &P, &dir, &idir, &ignore_t);
#endif
diff --git a/intern/cycles/kernel/geom/geom_triangle_intersect.h b/intern/cycles/kernel/geom/geom_triangle_intersect.h
index 3ef918dc842..ba309a1dc53 100644
--- a/intern/cycles/kernel/geom/geom_triangle_intersect.h
+++ b/intern/cycles/kernel/geom/geom_triangle_intersect.h
@@ -98,7 +98,7 @@ void triangle_intersect_precalc(float3 dir,
}
/* TODO(sergey): Make it general utility function. */
-ccl_device_inline float xor_signmast(float x, int y)
+ccl_device_inline float xor_signmask(float x, int y)
{
return __int_as_float(__float_as_int(x) ^ y);
}
@@ -140,13 +140,15 @@ ccl_device_inline bool triangle_intersect(KernelGlobals *kg,
/* Calculate scaled barycentric coordinates. */
float U = Cx * By - Cy * Bx;
- int sign_mask = (__float_as_int(U) & 0x80000000);
float V = Ax * Cy - Ay * Cx;
- if(sign_mask != (__float_as_int(V) & 0x80000000)) {
- return false;
- }
float W = Bx * Ay - By * Ax;
- if(sign_mask != (__float_as_int(W) & 0x80000000)) {
+ const int sign_mask = (__float_as_int(U) & 0x80000000);
+ /* TODO(sergey): Check if multiplication plus sign check is faster
+ * or at least same speed (but robust for endian types).
+ */
+ if(sign_mask != (__float_as_int(V) & 0x80000000) ||
+ sign_mask != (__float_as_int(W) & 0x80000000))
+ {
return false;
}
@@ -156,13 +158,13 @@ ccl_device_inline bool triangle_intersect(KernelGlobals *kg,
return false;
}
- /* Calculate scaled z−coordinates of vertices and use them to calculate
+ /* Calculate scaled z-coordinates of vertices and use them to calculate
* the hit distance.
*/
const float T = (U * A_kz + V * B_kz + W * C_kz) * Sz;
- const float sign_T = xor_signmast(T, sign_mask);
+ const float sign_T = xor_signmask(T, sign_mask);
if((sign_T < 0.0f) ||
- (sign_T > isect->t * xor_signmast(det, sign_mask)))
+ (sign_T > isect->t * xor_signmask(det, sign_mask)))
{
return false;
}
@@ -173,6 +175,16 @@ ccl_device_inline bool triangle_intersect(KernelGlobals *kg,
if(kernel_tex_fetch(__prim_visibility, triAddr) & visibility)
#endif
{
+#ifdef __KERNEL_GPU__
+ float4 a = tri_b - tri_a, b = tri_c - tri_a;
+ if(len_squared(make_float3(a.y*b.z - a.z*b.y,
+ a.z*b.x - a.x*b.z,
+ a.x*b.y - a.y*b.x)) == 0.0f)
+ {
+ return false;
+ }
+#endif
+
/* Normalize U, V, W, and T. */
const float inv_det = 1.0f / det;
isect->prim = triAddr;
@@ -253,9 +265,9 @@ ccl_device_inline void triangle_intersect_subsurface(
* the hit distance.
*/
const float T = (U * A_kz + V * B_kz + W * C_kz) * Sz;
- const float sign_T = xor_signmast(T, sign_mask);
+ const float sign_T = xor_signmask(T, sign_mask);
if((sign_T < 0.0f) ||
- (sign_T > tmax * xor_signmast(det, sign_mask)))
+ (sign_T > tmax * xor_signmask(det, sign_mask)))
{
return;
}
diff --git a/intern/cycles/kernel/kernel_bake.h b/intern/cycles/kernel/kernel_bake.h
index 2fca83c615f..0cb56461f29 100644
--- a/intern/cycles/kernel/kernel_bake.h
+++ b/intern/cycles/kernel/kernel_bake.h
@@ -31,6 +31,13 @@ ccl_device void compute_light_pass(KernelGlobals *kg, ShaderData *sd, PathRadian
float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
bool is_sss_sample = is_sss;
+ ray.P = sd->P + sd->Ng;
+ ray.D = -sd->Ng;
+ ray.t = FLT_MAX;
+#ifdef __CAMERA_MOTION__
+ ray.time = TIME_INVALID;
+#endif
+
/* init radiance */
path_radiance_init(&L_sample, kernel_data.film.use_light_pass);
@@ -143,7 +150,7 @@ ccl_device bool is_aa_pass(ShaderEvalType type)
ccl_device bool is_light_pass(ShaderEvalType type)
{
- switch (type) {
+ switch(type) {
case SHADER_EVAL_AO:
case SHADER_EVAL_COMBINED:
case SHADER_EVAL_SHADOW:
@@ -255,7 +262,7 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg, ccl_global uint4 *input,
sample);
}
- switch (type) {
+ switch(type) {
/* data passes */
case SHADER_EVAL_NORMAL:
{
diff --git a/intern/cycles/kernel/kernel_camera.h b/intern/cycles/kernel/kernel_camera.h
index 67651f96544..8d439ceb0d7 100644
--- a/intern/cycles/kernel/kernel_camera.h
+++ b/intern/cycles/kernel/kernel_camera.h
@@ -267,11 +267,14 @@ ccl_device void camera_sample_panorama(KernelGlobals *kg, float raster_x, float
/* ray differential */
ray->dP = differential3_zero();
+ Pcamera = transform_perspective(&rastertocamera, make_float3(raster_x, raster_y, 0.0f));
+ float3 Ddiff = normalize(transform_direction(&cameratoworld, panorama_to_direction(kg, Pcamera.x, Pcamera.y)));
+
Pcamera = transform_perspective(&rastertocamera, make_float3(raster_x + 1.0f, raster_y, 0.0f));
- ray->dD.dx = normalize(transform_direction(&cameratoworld, panorama_to_direction(kg, Pcamera.x, Pcamera.y))) - ray->D;
+ ray->dD.dx = normalize(transform_direction(&cameratoworld, panorama_to_direction(kg, Pcamera.x, Pcamera.y))) - Ddiff;
Pcamera = transform_perspective(&rastertocamera, make_float3(raster_x, raster_y + 1.0f, 0.0f));
- ray->dD.dy = normalize(transform_direction(&cameratoworld, panorama_to_direction(kg, Pcamera.x, Pcamera.y))) - ray->D;
+ ray->dD.dy = normalize(transform_direction(&cameratoworld, panorama_to_direction(kg, Pcamera.x, Pcamera.y))) - Ddiff;
#endif
}
diff --git a/intern/cycles/kernel/kernel_compat_cpu.h b/intern/cycles/kernel/kernel_compat_cpu.h
index d02670f630a..04c4cf35587 100644
--- a/intern/cycles/kernel/kernel_compat_cpu.h
+++ b/intern/cycles/kernel/kernel_compat_cpu.h
@@ -144,7 +144,7 @@ template<typename T> struct texture_image {
iy = wrap_periodic(iy, height);
break;
case EXTENSION_CLIP:
- if (x < 0.0f || y < 0.0f || x >= width || y >= height) {
+ if(x < 0.0f || y < 0.0f || x > 1.0f || y > 1.0f) {
return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
}
/* Fall through. */
@@ -168,16 +168,16 @@ template<typename T> struct texture_image {
niy = wrap_periodic(iy+1, height);
break;
case EXTENSION_CLIP:
- if (x < 0.0f || y < 0.0f || x >= width || y >= height) {
+ if(x < 0.0f || y < 0.0f || x > 1.0f || y > 1.0f) {
return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
}
/* Fall through. */
case EXTENSION_EXTEND:
- ix = wrap_clamp(ix, width);
- iy = wrap_clamp(iy, height);
-
nix = wrap_clamp(ix+1, width);
niy = wrap_clamp(iy+1, height);
+
+ ix = wrap_clamp(ix, width);
+ iy = wrap_clamp(iy, height);
break;
}
@@ -190,8 +190,8 @@ template<typename T> struct texture_image {
}
else {
/* Bicubic b-spline interpolation. */
- const float tx = frac(x*(float)width - 0.5f, &ix);
- const float ty = frac(y*(float)height - 0.5f, &iy);
+ float tx = frac(x*(float)width - 0.5f, &ix);
+ float ty = frac(y*(float)height - 0.5f, &iy);
int pix, piy, nnix, nniy;
switch(extension) {
case EXTENSION_REPEAT:
@@ -208,14 +208,11 @@ template<typename T> struct texture_image {
nniy = wrap_periodic(iy+2, height);
break;
case EXTENSION_CLIP:
- if (x < 0.0f || y < 0.0f || x >= width || y >= height) {
+ if(x < 0.0f || y < 0.0f || x > 1.0f || y > 1.0f) {
return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
}
/* Fall through. */
case EXTENSION_EXTEND:
- ix = wrap_clamp(ix, width);
- iy = wrap_clamp(iy, height);
-
pix = wrap_clamp(ix-1, width);
piy = wrap_clamp(iy-1, height);
@@ -224,6 +221,9 @@ template<typename T> struct texture_image {
nnix = wrap_clamp(ix+2, width);
nniy = wrap_clamp(iy+2, height);
+
+ ix = wrap_clamp(ix, width);
+ iy = wrap_clamp(iy, height);
break;
}
@@ -279,7 +279,9 @@ template<typename T> struct texture_image {
iz = wrap_periodic(iz, depth);
break;
case EXTENSION_CLIP:
- if (x < 0.0f || y < 0.0f || x >= width || y >= height) {
+ if(x < 0.0f || y < 0.0f || z < 0.0f ||
+ x > 1.0f || y > 1.0f || z > 1.0f)
+ {
return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
}
/* Fall through. */
@@ -308,18 +310,20 @@ template<typename T> struct texture_image {
niz = wrap_periodic(iz+1, depth);
break;
case EXTENSION_CLIP:
- if (x < 0.0f || y < 0.0f || x >= width || y >= height) {
+ if(x < 0.0f || y < 0.0f || z < 0.0f ||
+ x > 1.0f || y > 1.0f || z > 1.0f)
+ {
return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
}
/* Fall through. */
case EXTENSION_EXTEND:
- ix = wrap_clamp(ix, width);
- iy = wrap_clamp(iy, height);
- iz = wrap_clamp(iz, depth);
-
nix = wrap_clamp(ix+1, width);
niy = wrap_clamp(iy+1, height);
niz = wrap_clamp(iz+1, depth);
+
+ ix = wrap_clamp(ix, width);
+ iy = wrap_clamp(iy, height);
+ iz = wrap_clamp(iz, depth);
break;
}
@@ -363,15 +367,13 @@ template<typename T> struct texture_image {
nniz = wrap_periodic(iz+2, depth);
break;
case EXTENSION_CLIP:
- if (x < 0.0f || y < 0.0f || x >= width || y >= height) {
+ if(x < 0.0f || y < 0.0f || z < 0.0f ||
+ x > 1.0f || y > 1.0f || z > 1.0f)
+ {
return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
}
/* Fall through. */
case EXTENSION_EXTEND:
- ix = wrap_clamp(ix, width);
- iy = wrap_clamp(iy, height);
- iz = wrap_clamp(iz, depth);
-
pix = wrap_clamp(ix-1, width);
piy = wrap_clamp(iy-1, height);
piz = wrap_clamp(iz-1, depth);
@@ -383,6 +385,10 @@ template<typename T> struct texture_image {
nnix = wrap_clamp(ix+2, width);
nniy = wrap_clamp(iy+2, height);
nniz = wrap_clamp(iz+2, depth);
+
+ ix = wrap_clamp(ix, width);
+ iy = wrap_clamp(iy, height);
+ iz = wrap_clamp(iz, depth);
break;
}
diff --git a/intern/cycles/kernel/kernel_light.h b/intern/cycles/kernel/kernel_light.h
index eb2d39d5020..7590ec2d706 100644
--- a/intern/cycles/kernel/kernel_light.h
+++ b/intern/cycles/kernel/kernel_light.h
@@ -620,7 +620,7 @@ ccl_device void lamp_light_sample(KernelGlobals *kg, int lamp,
}
}
-#if defined(__KERNEL_CUDA__) && (defined(i386) || defined(_M_IX86))
+#if defined(__KERNEL_CUDA__) && (__CUDA_ARCH__ >= 500) && (defined(i386) || defined(_M_IX86))
ccl_device_noinline
#else
ccl_device
diff --git a/intern/cycles/kernel/kernel_path_surface.h b/intern/cycles/kernel/kernel_path_surface.h
index fe85a6b6e4b..4485be8a5b3 100644
--- a/intern/cycles/kernel/kernel_path_surface.h
+++ b/intern/cycles/kernel/kernel_path_surface.h
@@ -150,7 +150,7 @@ ccl_device bool kernel_branched_path_surface_bounce(KernelGlobals *kg, RNG *rng,
/* setup ray */
ray->P = ray_offset(ccl_fetch(sd, P), (label & LABEL_TRANSMIT)? -ccl_fetch(sd, Ng): ccl_fetch(sd, Ng));
- ray->D = bsdf_omega_in;
+ ray->D = normalize(bsdf_omega_in);
ray->t = FLT_MAX;
#ifdef __RAY_DIFFERENTIALS__
ray->dP = ccl_fetch(sd, dP);
@@ -257,7 +257,7 @@ ccl_device_inline bool kernel_path_surface_bounce(KernelGlobals *kg, ccl_addr_sp
/* setup ray */
ray->P = ray_offset(ccl_fetch(sd, P), (label & LABEL_TRANSMIT)? -ccl_fetch(sd, Ng): ccl_fetch(sd, Ng));
- ray->D = bsdf_omega_in;
+ ray->D = normalize(bsdf_omega_in);
if(state->bounce == 0)
ray->t -= ccl_fetch(sd, ray_length); /* clipping works through transparent */
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index acd2f5d0673..740a5f1f5d3 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -1036,7 +1036,7 @@ enum QueueNumber {
* contribution for AO are enqueued here.
*/
QUEUE_SHADOW_RAY_CAST_DL_RAYS = 3, /* All rays for which a shadow ray should be cast to determine radiance
- * contributuin for direct lighting are enqueued here.
+ * contributing for direct lighting are enqueued here.
*/
};
diff --git a/intern/cycles/kernel/kernel_volume.h b/intern/cycles/kernel/kernel_volume.h
index 27c0b44a80d..0a74a9deba9 100644
--- a/intern/cycles/kernel/kernel_volume.h
+++ b/intern/cycles/kernel/kernel_volume.h
@@ -374,7 +374,7 @@ ccl_device VolumeIntegrateResult kernel_volume_integrate_homogeneous(KernelGloba
/* distance sampling */
sample_t = kernel_volume_distance_sample(ray->t, sigma_t, channel, xi, &transmittance, &pdf);
- /* modifiy pdf for hit/miss decision */
+ /* modify pdf for hit/miss decision */
if(probalistic_scatter)
pdf *= make_float3(1.0f, 1.0f, 1.0f) - volume_color_transmittance(sigma_t, t);
@@ -422,7 +422,7 @@ ccl_device VolumeIntegrateResult kernel_volume_integrate_homogeneous(KernelGloba
/* heterogeneous volume distance sampling: integrate stepping through the
* volume until we reach the end, get absorbed entirely, or run out of
- * iterations. this does probalistically scatter or get transmitted through
+ * iterations. this does probabilistically scatter or get transmitted through
* for path tracing where we don't want to branch. */
ccl_device VolumeIntegrateResult kernel_volume_integrate_heterogeneous_distance(KernelGlobals *kg,
PathState *state, Ray *ray, ShaderData *sd, PathRadiance *L, float3 *throughput, RNG *rng)
@@ -610,7 +610,7 @@ typedef struct VolumeSegment {
/* record volume steps to the end of the volume.
*
* it would be nice if we could only record up to the point that we need to scatter,
- * but the entire segment is needed to do always scattering, rather than probalistically
+ * but the entire segment is needed to do always scattering, rather than probabilistically
* hitting or missing the volume. if we don't know the transmittance at the end of the
* volume we can't generate stratified distance samples up to that transmittance */
ccl_device void kernel_volume_decoupled_record(KernelGlobals *kg, PathState *state,
@@ -766,7 +766,7 @@ ccl_device VolumeIntegrateResult kernel_volume_decoupled_scatter(
sd->randb_closure = rphase*3.0f - channel;
float xi = rscatter;
- /* probalistic scattering decision based on transmittance */
+ /* probabilistic scattering decision based on transmittance */
if(probalistic_scatter) {
float sample_transmittance = kernel_volume_channel_get(segment->accum_transmittance, channel);
@@ -846,7 +846,7 @@ ccl_device VolumeIntegrateResult kernel_volume_decoupled_scatter(
float3 distance_pdf;
sample_t = prev_t + kernel_volume_distance_sample(step_t, step->sigma_t, channel, xi, &transmittance, &distance_pdf);
- /* modifiy pdf for hit/miss decision */
+ /* modify pdf for hit/miss decision */
if(probalistic_scatter)
distance_pdf *= make_float3(1.0f, 1.0f, 1.0f) - segment->accum_transmittance;
@@ -942,7 +942,7 @@ ccl_device VolumeIntegrateResult kernel_volume_decoupled_scatter(
/* decide if we need to use decoupled or not */
ccl_device bool kernel_volume_use_decoupled(KernelGlobals *kg, bool heterogeneous, bool direct, int sampling_method)
{
- /* decoupled ray marching for heterogenous volumes not supported on the GPU,
+ /* decoupled ray marching for heterogeneous volumes not supported on the GPU,
* which also means equiangular and multiple importance sampling is not
* support for that case */
#ifdef __KERNEL_GPU__
diff --git a/intern/cycles/kernel/osl/background.cpp b/intern/cycles/kernel/osl/background.cpp
index 2facced0914..4d70bc80006 100644
--- a/intern/cycles/kernel/osl/background.cpp
+++ b/intern/cycles/kernel/osl/background.cpp
@@ -77,7 +77,7 @@ public:
ClosureParam *closure_background_params()
{
static ClosureParam params[] = {
- CLOSURE_STRING_KEYPARAM("label"),
+ CLOSURE_STRING_KEYPARAM(GenericBackgroundClosure, label, "label"),
CLOSURE_FINISH_PARAM(GenericBackgroundClosure)
};
return params;
@@ -98,7 +98,7 @@ CCLOSURE_PREPARE(closure_holdout_prepare, HoldoutClosure)
ClosureParam *closure_ambient_occlusion_params()
{
static ClosureParam params[] = {
- CLOSURE_STRING_KEYPARAM("label"),
+ CLOSURE_STRING_KEYPARAM(AmbientOcclusionClosure, label, "label"),
CLOSURE_FINISH_PARAM(AmbientOcclusionClosure)
};
return params;
diff --git a/intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp b/intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp
index 43929fbe928..b3c71e4a706 100644
--- a/intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp
+++ b/intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp
@@ -93,7 +93,7 @@ ClosureParam *closure_bsdf_diffuse_ramp_params()
static ClosureParam params[] = {
CLOSURE_FLOAT3_PARAM(DiffuseRampClosure, sc.N),
CLOSURE_COLOR_ARRAY_PARAM(DiffuseRampClosure, colors, 8),
- CLOSURE_STRING_KEYPARAM("label"),
+ CLOSURE_STRING_KEYPARAM(DiffuseRampClosure, label, "label"),
CLOSURE_FINISH_PARAM(DiffuseRampClosure)
};
return params;
diff --git a/intern/cycles/kernel/osl/bsdf_phong_ramp.cpp b/intern/cycles/kernel/osl/bsdf_phong_ramp.cpp
index 497c4f0dc5c..99f510d31ed 100644
--- a/intern/cycles/kernel/osl/bsdf_phong_ramp.cpp
+++ b/intern/cycles/kernel/osl/bsdf_phong_ramp.cpp
@@ -93,7 +93,7 @@ ClosureParam *closure_bsdf_phong_ramp_params()
CLOSURE_FLOAT3_PARAM(PhongRampClosure, sc.N),
CLOSURE_FLOAT_PARAM(PhongRampClosure, sc.data0),
CLOSURE_COLOR_ARRAY_PARAM(PhongRampClosure, colors, 8),
- CLOSURE_STRING_KEYPARAM("label"),
+ CLOSURE_STRING_KEYPARAM(PhongRampClosure, label, "label"),
CLOSURE_FINISH_PARAM(PhongRampClosure)
};
return params;
diff --git a/intern/cycles/kernel/osl/emissive.cpp b/intern/cycles/kernel/osl/emissive.cpp
index 02935542c56..9a95fa57a81 100644
--- a/intern/cycles/kernel/osl/emissive.cpp
+++ b/intern/cycles/kernel/osl/emissive.cpp
@@ -77,7 +77,7 @@ public:
ClosureParam *closure_emission_params()
{
static ClosureParam params[] = {
- CLOSURE_STRING_KEYPARAM("label"),
+ CLOSURE_STRING_KEYPARAM(GenericEmissiveClosure, label, "label"),
CLOSURE_FINISH_PARAM(GenericEmissiveClosure)
};
return params;
diff --git a/intern/cycles/kernel/osl/osl_bssrdf.cpp b/intern/cycles/kernel/osl/osl_bssrdf.cpp
index 88998037751..bc395922077 100644
--- a/intern/cycles/kernel/osl/osl_bssrdf.cpp
+++ b/intern/cycles/kernel/osl/osl_bssrdf.cpp
@@ -69,7 +69,7 @@ ClosureParam *closure_bssrdf_cubic_params()
CLOSURE_FLOAT3_PARAM(CubicBSSRDFClosure, radius),
CLOSURE_FLOAT_PARAM(CubicBSSRDFClosure, sc.data1),
CLOSURE_FLOAT_PARAM(CubicBSSRDFClosure, sc.T.x),
- CLOSURE_STRING_KEYPARAM("label"),
+ CLOSURE_STRING_KEYPARAM(CubicBSSRDFClosure, label, "label"),
CLOSURE_FINISH_PARAM(CubicBSSRDFClosure)
};
return params;
@@ -97,7 +97,7 @@ ClosureParam *closure_bssrdf_gaussian_params()
CLOSURE_FLOAT3_PARAM(GaussianBSSRDFClosure, sc.N),
CLOSURE_FLOAT3_PARAM(GaussianBSSRDFClosure, radius),
CLOSURE_FLOAT_PARAM(GaussianBSSRDFClosure, sc.data1),
- CLOSURE_STRING_KEYPARAM("label"),
+ CLOSURE_STRING_KEYPARAM(GaussianBSSRDFClosure, label, "label"),
CLOSURE_FINISH_PARAM(GaussianBSSRDFClosure)
};
return params;
diff --git a/intern/cycles/kernel/osl/osl_closures.h b/intern/cycles/kernel/osl/osl_closures.h
index ef67ef52fc0..c0bf25ac1c7 100644
--- a/intern/cycles/kernel/osl/osl_closures.h
+++ b/intern/cycles/kernel/osl/osl_closures.h
@@ -72,12 +72,17 @@ void name(RendererServices *, int id, void *data) \
#define CCLOSURE_PREPARE_STATIC(name, classname) static CCLOSURE_PREPARE(name, classname)
#define CLOSURE_FLOAT3_PARAM(st, fld) \
- { TypeDesc::TypeVector, reckless_offsetof(st, fld), NULL, sizeof(OSL::Vec3) }
+ { TypeDesc::TypeVector, (int)reckless_offsetof(st, fld), NULL, sizeof(OSL::Vec3) }
#define TO_VEC3(v) OSL::Vec3(v.x, v.y, v.z)
#define TO_COLOR3(v) OSL::Color3(v.x, v.y, v.z)
#define TO_FLOAT3(v) make_float3(v[0], v[1], v[2])
+#if OSL_LIBRARY_VERSION_CODE < 10700
+# undef CLOSURE_STRING_KEYPARAM
+# define CLOSURE_STRING_KEYPARAM(st, fld, key) { TypeDesc::TypeString, 0, key, 0 }
+#endif
+
/* Closure */
class CClosurePrimitive {
@@ -97,6 +102,10 @@ public:
virtual void setup() {}
Category category;
+
+#if OSL_LIBRARY_VERSION_CODE >= 10700
+ OSL::ustring label;
+#endif
};
/* BSDF */
@@ -175,7 +184,7 @@ static ClosureParam *bsdf_##lower##_params() \
/* parameters */
#define BSDF_CLOSURE_CLASS_END(Upper, lower) \
- CLOSURE_STRING_KEYPARAM("label"), \
+ CLOSURE_STRING_KEYPARAM(Upper##Closure, label, "label"), \
CLOSURE_FINISH_PARAM(Upper##Closure) \
}; \
return params; \
@@ -223,7 +232,7 @@ static ClosureParam *volume_##lower##_params() \
/* parameters */
#define VOLUME_CLOSURE_CLASS_END(Upper, lower) \
- CLOSURE_STRING_KEYPARAM("label"), \
+ CLOSURE_STRING_KEYPARAM(Upper##Closure, label, "label"), \
CLOSURE_FINISH_PARAM(Upper##Closure) \
}; \
return params; \
diff --git a/intern/cycles/kernel/osl/osl_services.h b/intern/cycles/kernel/osl/osl_services.h
index 190234a7706..aa2befd6e98 100644
--- a/intern/cycles/kernel/osl/osl_services.h
+++ b/intern/cycles/kernel/osl/osl_services.h
@@ -104,6 +104,55 @@ public:
const OSL::Vec3 &dPdx, const OSL::Vec3 &dPdy,
const OSL::Vec3 &dPdz, int nchannels, float *result);
+#if OSL_LIBRARY_VERSION_CODE >= 10600
+ bool texture(ustring filename,
+ TextureHandle * /*texture_handle*/,
+ TexturePerthread * /*texture_thread_info*/,
+ TextureOpt &options,
+ OSL::ShaderGlobals *sg,
+ float s, float t,
+ float dsdx, float dtdx, float dsdy, float dtdy,
+ int nchannels,
+ float *result,
+ float * /*dresultds*/,
+ float * /*dresultdt*/)
+ {
+ /* TODO(sergey): Support derivatives. */
+ return texture(filename,
+ options,
+ sg,
+ s, t,
+ dsdx, dtdx, dsdy, dtdy,
+ nchannels,
+ result);
+ }
+
+ bool texture3d(ustring filename,
+ TextureHandle * /*texture_handle*/,
+ TexturePerthread * /*texture_thread_info*/,
+ TextureOpt &options,
+ OSL::ShaderGlobals *sg,
+ const OSL::Vec3 &P,
+ const OSL::Vec3 &dPdx,
+ const OSL::Vec3 &dPdy,
+ const OSL::Vec3 &dPdz,
+ int nchannels,
+ float *result,
+ float * /*dresultds*/,
+ float * /*dresultdt*/,
+ float * /*dresultdr*/)
+ {
+ /* TODO(sergey): Support derivatives. */
+ return texture3d(filename,
+ options,
+ sg,
+ P,
+ dPdx, dPdy, dPdz,
+ nchannels,
+ result);
+ }
+#endif
+
bool environment(ustring filename, TextureOpt &options,
OSL::ShaderGlobals *sg, const OSL::Vec3 &R,
const OSL::Vec3 &dRdx, const OSL::Vec3 &dRdy,
diff --git a/intern/cycles/kernel/osl/osl_shader.cpp b/intern/cycles/kernel/osl/osl_shader.cpp
index 8cfe0cbcbd4..2f234aa25ea 100644
--- a/intern/cycles/kernel/osl/osl_shader.cpp
+++ b/intern/cycles/kernel/osl/osl_shader.cpp
@@ -146,165 +146,175 @@ static void flatten_surface_closure_tree(ShaderData *sd, int path_flag,
/* OSL gives us a closure tree, we flatten it into arrays per
* closure type, for evaluation, sampling, etc later on. */
- if(closure->type == OSL::ClosureColor::COMPONENT) {
- OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure;
- CClosurePrimitive *prim = (CClosurePrimitive *)comp->data();
+#if OSL_LIBRARY_VERSION_CODE < 10700
+ switch(closure->type) {
+#else
+ switch(closure->id) {
+#endif
+ case OSL::ClosureColor::MUL: {
+ OSL::ClosureMul *mul = (OSL::ClosureMul *)closure;
+ flatten_surface_closure_tree(sd, path_flag, mul->closure, TO_FLOAT3(mul->weight) * weight);
+ break;
+ }
+ case OSL::ClosureColor::ADD: {
+ OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure;
+ flatten_surface_closure_tree(sd, path_flag, add->closureA, weight);
+ flatten_surface_closure_tree(sd, path_flag, add->closureB, weight);
+ break;
+ }
+ default: {
+ OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure;
+ CClosurePrimitive *prim = (CClosurePrimitive *)comp->data();
- if(prim) {
- ShaderClosure sc;
+ if(prim) {
+ ShaderClosure sc;
#ifdef OSL_SUPPORTS_WEIGHTED_CLOSURE_COMPONENTS
- weight = weight*TO_FLOAT3(comp->w);
+ weight = weight*TO_FLOAT3(comp->w);
#endif
- sc.weight = weight;
+ sc.weight = weight;
- prim->setup();
+ prim->setup();
- switch (prim->category) {
- case CClosurePrimitive::BSDF: {
- CBSDFClosure *bsdf = (CBSDFClosure *)prim;
- int scattering = bsdf->scattering();
+ switch(prim->category) {
+ case CClosurePrimitive::BSDF: {
+ CBSDFClosure *bsdf = (CBSDFClosure *)prim;
+ int scattering = bsdf->scattering();
- /* caustic options */
- if((scattering & LABEL_GLOSSY) && (path_flag & PATH_RAY_DIFFUSE)) {
- KernelGlobals *kg = sd->osl_globals;
+ /* caustic options */
+ if((scattering & LABEL_GLOSSY) && (path_flag & PATH_RAY_DIFFUSE)) {
+ KernelGlobals *kg = sd->osl_globals;
- if((!kernel_data.integrator.caustics_reflective && (scattering & LABEL_REFLECT)) ||
- (!kernel_data.integrator.caustics_refractive && (scattering & LABEL_TRANSMIT))) {
- return;
+ if((!kernel_data.integrator.caustics_reflective && (scattering & LABEL_REFLECT)) ||
+ (!kernel_data.integrator.caustics_refractive && (scattering & LABEL_TRANSMIT)))
+ {
+ return;
+ }
}
- }
- /* sample weight */
- float sample_weight = fabsf(average(weight));
+ /* sample weight */
+ float sample_weight = fabsf(average(weight));
- sc.sample_weight = sample_weight;
+ sc.sample_weight = sample_weight;
- sc.type = bsdf->sc.type;
- sc.N = bsdf->sc.N;
- sc.T = bsdf->sc.T;
- sc.data0 = bsdf->sc.data0;
- sc.data1 = bsdf->sc.data1;
- sc.data2 = bsdf->sc.data2;
- sc.prim = bsdf->sc.prim;
+ sc.type = bsdf->sc.type;
+ sc.N = bsdf->sc.N;
+ sc.T = bsdf->sc.T;
+ sc.data0 = bsdf->sc.data0;
+ sc.data1 = bsdf->sc.data1;
+ sc.data2 = bsdf->sc.data2;
+ sc.prim = bsdf->sc.prim;
- /* add */
- if(sc.sample_weight > CLOSURE_WEIGHT_CUTOFF && sd->num_closure < MAX_CLOSURE) {
- sd->closure[sd->num_closure++] = sc;
- sd->flag |= bsdf->shaderdata_flag();
- }
- break;
- }
- case CClosurePrimitive::Emissive: {
- /* sample weight */
- float sample_weight = fabsf(average(weight));
-
- sc.sample_weight = sample_weight;
- sc.type = CLOSURE_EMISSION_ID;
- sc.data0 = 0.0f;
- sc.data1 = 0.0f;
- sc.data2 = 0.0f;
- sc.prim = NULL;
-
- /* flag */
- if(sd->num_closure < MAX_CLOSURE) {
- sd->closure[sd->num_closure++] = sc;
- sd->flag |= SD_EMISSION;
- }
- break;
- }
- case CClosurePrimitive::AmbientOcclusion: {
- /* sample weight */
- float sample_weight = fabsf(average(weight));
-
- sc.sample_weight = sample_weight;
- sc.type = CLOSURE_AMBIENT_OCCLUSION_ID;
- sc.data0 = 0.0f;
- sc.data1 = 0.0f;
- sc.data2 = 0.0f;
- sc.prim = NULL;
-
- if(sd->num_closure < MAX_CLOSURE) {
- sd->closure[sd->num_closure++] = sc;
- sd->flag |= SD_AO;
- }
- break;
- }
- case CClosurePrimitive::Holdout: {
- sc.sample_weight = 0.0f;
- sc.type = CLOSURE_HOLDOUT_ID;
- sc.data0 = 0.0f;
- sc.data1 = 0.0f;
- sc.data2 = 0.0f;
- sc.prim = NULL;
-
- if(sd->num_closure < MAX_CLOSURE) {
- sd->closure[sd->num_closure++] = sc;
- sd->flag |= SD_HOLDOUT;
+ /* add */
+ if(sc.sample_weight > CLOSURE_WEIGHT_CUTOFF && sd->num_closure < MAX_CLOSURE) {
+ sd->closure[sd->num_closure++] = sc;
+ sd->flag |= bsdf->shaderdata_flag();
+ }
+ break;
}
- break;
- }
- case CClosurePrimitive::BSSRDF: {
- CBSSRDFClosure *bssrdf = (CBSSRDFClosure *)prim;
- float sample_weight = fabsf(average(weight));
+ case CClosurePrimitive::Emissive: {
+ /* sample weight */
+ float sample_weight = fabsf(average(weight));
- if(sample_weight > CLOSURE_WEIGHT_CUTOFF && sd->num_closure+2 < MAX_CLOSURE) {
sc.sample_weight = sample_weight;
-
- sc.type = bssrdf->sc.type;
- sc.N = bssrdf->sc.N;
- sc.data1 = bssrdf->sc.data1;
- sc.T.x = bssrdf->sc.T.x;
+ sc.type = CLOSURE_EMISSION_ID;
+ sc.data0 = 0.0f;
+ sc.data1 = 0.0f;
+ sc.data2 = 0.0f;
sc.prim = NULL;
- /* disable in case of diffuse ancestor, can't see it well then and
- * adds considerably noise due to probabilities of continuing path
- * getting lower and lower */
- if(path_flag & PATH_RAY_DIFFUSE_ANCESTOR)
- bssrdf->radius = make_float3(0.0f, 0.0f, 0.0f);
-
- /* create one closure for each color channel */
- if(fabsf(weight.x) > 0.0f) {
- sc.weight = make_float3(weight.x, 0.0f, 0.0f);
- sc.data0 = bssrdf->radius.x;
- sc.data1 = 0.0f;
- sd->flag |= bssrdf_setup(&sc, sc.type);
+ /* flag */
+ if(sd->num_closure < MAX_CLOSURE) {
sd->closure[sd->num_closure++] = sc;
+ sd->flag |= SD_EMISSION;
}
+ break;
+ }
+ case CClosurePrimitive::AmbientOcclusion: {
+ /* sample weight */
+ float sample_weight = fabsf(average(weight));
- if(fabsf(weight.y) > 0.0f) {
- sc.weight = make_float3(0.0f, weight.y, 0.0f);
- sc.data0 = bssrdf->radius.y;
- sc.data1 = 0.0f;
- sd->flag |= bssrdf_setup(&sc, sc.type);
+ sc.sample_weight = sample_weight;
+ sc.type = CLOSURE_AMBIENT_OCCLUSION_ID;
+ sc.data0 = 0.0f;
+ sc.data1 = 0.0f;
+ sc.data2 = 0.0f;
+ sc.prim = NULL;
+
+ if(sd->num_closure < MAX_CLOSURE) {
sd->closure[sd->num_closure++] = sc;
+ sd->flag |= SD_AO;
}
+ break;
+ }
+ case CClosurePrimitive::Holdout: {
+ sc.sample_weight = 0.0f;
+ sc.type = CLOSURE_HOLDOUT_ID;
+ sc.data0 = 0.0f;
+ sc.data1 = 0.0f;
+ sc.data2 = 0.0f;
+ sc.prim = NULL;
- if(fabsf(weight.z) > 0.0f) {
- sc.weight = make_float3(0.0f, 0.0f, weight.z);
- sc.data0 = bssrdf->radius.z;
- sc.data1 = 0.0f;
- sd->flag |= bssrdf_setup(&sc, sc.type);
+ if(sd->num_closure < MAX_CLOSURE) {
sd->closure[sd->num_closure++] = sc;
+ sd->flag |= SD_HOLDOUT;
+ }
+ break;
+ }
+ case CClosurePrimitive::BSSRDF: {
+ CBSSRDFClosure *bssrdf = (CBSSRDFClosure *)prim;
+ float sample_weight = fabsf(average(weight));
+
+ if(sample_weight > CLOSURE_WEIGHT_CUTOFF && sd->num_closure+2 < MAX_CLOSURE) {
+ sc.sample_weight = sample_weight;
+
+ sc.type = bssrdf->sc.type;
+ sc.N = bssrdf->sc.N;
+ sc.data1 = bssrdf->sc.data1;
+ sc.T.x = bssrdf->sc.T.x;
+ sc.prim = NULL;
+
+ /* disable in case of diffuse ancestor, can't see it well then and
+ * adds considerably noise due to probabilities of continuing path
+ * getting lower and lower */
+ if(path_flag & PATH_RAY_DIFFUSE_ANCESTOR)
+ bssrdf->radius = make_float3(0.0f, 0.0f, 0.0f);
+
+ /* create one closure for each color channel */
+ if(fabsf(weight.x) > 0.0f) {
+ sc.weight = make_float3(weight.x, 0.0f, 0.0f);
+ sc.data0 = bssrdf->radius.x;
+ sc.data1 = 0.0f;
+ sd->flag |= bssrdf_setup(&sc, sc.type);
+ sd->closure[sd->num_closure++] = sc;
+ }
+
+ if(fabsf(weight.y) > 0.0f) {
+ sc.weight = make_float3(0.0f, weight.y, 0.0f);
+ sc.data0 = bssrdf->radius.y;
+ sc.data1 = 0.0f;
+ sd->flag |= bssrdf_setup(&sc, sc.type);
+ sd->closure[sd->num_closure++] = sc;
+ }
+
+ if(fabsf(weight.z) > 0.0f) {
+ sc.weight = make_float3(0.0f, 0.0f, weight.z);
+ sc.data0 = bssrdf->radius.z;
+ sc.data1 = 0.0f;
+ sd->flag |= bssrdf_setup(&sc, sc.type);
+ sd->closure[sd->num_closure++] = sc;
+ }
}
+ break;
}
- break;
+ case CClosurePrimitive::Background:
+ case CClosurePrimitive::Volume:
+ break; /* not relevant */
}
- case CClosurePrimitive::Background:
- case CClosurePrimitive::Volume:
- break; /* not relevant */
}
+ break;
}
}
- else if(closure->type == OSL::ClosureColor::MUL) {
- OSL::ClosureMul *mul = (OSL::ClosureMul *)closure;
- flatten_surface_closure_tree(sd, path_flag, mul->closure, TO_FLOAT3(mul->weight) * weight);
- }
- else if(closure->type == OSL::ClosureColor::ADD) {
- OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure;
- flatten_surface_closure_tree(sd, path_flag, add->closureA, weight);
- flatten_surface_closure_tree(sd, path_flag, add->closureB, weight);
- }
}
void OSLShader::eval_surface(KernelGlobals *kg, ShaderData *sd, int path_flag, ShaderContext ctx)
@@ -335,27 +345,33 @@ static float3 flatten_background_closure_tree(const OSL::ClosureColor *closure)
* is only one supported closure type at the moment, which has no evaluation
* functions, so we just sum the weights */
- if(closure->type == OSL::ClosureColor::COMPONENT) {
- OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure;
- CClosurePrimitive *prim = (CClosurePrimitive *)comp->data();
-
- if(prim && prim->category == CClosurePrimitive::Background)
-#ifdef OSL_SUPPORTS_WEIGHTED_CLOSURE_COMPONENTS
- return TO_FLOAT3(comp->w);
+#if OSL_LIBRARY_VERSION_CODE < 10700
+ switch(closure->type) {
#else
- return make_float3(1.0f, 1.0f, 1.0f);
+ switch(closure->id) {
#endif
- }
- else if(closure->type == OSL::ClosureColor::MUL) {
- OSL::ClosureMul *mul = (OSL::ClosureMul *)closure;
+ case OSL::ClosureColor::MUL: {
+ OSL::ClosureMul *mul = (OSL::ClosureMul *)closure;
- return TO_FLOAT3(mul->weight) * flatten_background_closure_tree(mul->closure);
- }
- else if(closure->type == OSL::ClosureColor::ADD) {
- OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure;
+ return TO_FLOAT3(mul->weight) * flatten_background_closure_tree(mul->closure);
+ }
+ case OSL::ClosureColor::ADD: {
+ OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure;
- return flatten_background_closure_tree(add->closureA) +
- flatten_background_closure_tree(add->closureB);
+ return flatten_background_closure_tree(add->closureA) +
+ flatten_background_closure_tree(add->closureB);
+ }
+ default: {
+ OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure;
+ CClosurePrimitive *prim = (CClosurePrimitive *)comp->data();
+
+ if(prim && prim->category == CClosurePrimitive::Background)
+#ifdef OSL_SUPPORTS_WEIGHTED_CLOSURE_COMPONENTS
+ return TO_FLOAT3(comp->w);
+#else
+ return make_float3(1.0f, 1.0f, 1.0f);
+#endif
+ }
}
return make_float3(0.0f, 0.0f, 0.0f);
@@ -390,76 +406,84 @@ static void flatten_volume_closure_tree(ShaderData *sd,
/* OSL gives us a closure tree, we flatten it into arrays per
* closure type, for evaluation, sampling, etc later on. */
- if(closure->type == OSL::ClosureColor::COMPONENT) {
- OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure;
- CClosurePrimitive *prim = (CClosurePrimitive *)comp->data();
+#if OSL_LIBRARY_VERSION_CODE < 10700
+ switch(closure->type) {
+#else
+ switch(closure->id) {
+#endif
+ case OSL::ClosureColor::MUL: {
+ OSL::ClosureMul *mul = (OSL::ClosureMul *)closure;
+ flatten_volume_closure_tree(sd, mul->closure, TO_FLOAT3(mul->weight) * weight);
+ break;
+ }
+ case OSL::ClosureColor::ADD: {
+ OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure;
+ flatten_volume_closure_tree(sd, add->closureA, weight);
+ flatten_volume_closure_tree(sd, add->closureB, weight);
+ break;
+ }
+ default: {
+ OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure;
+ CClosurePrimitive *prim = (CClosurePrimitive *)comp->data();
- if(prim) {
- ShaderClosure sc;
+ if(prim) {
+ ShaderClosure sc;
#ifdef OSL_SUPPORTS_WEIGHTED_CLOSURE_COMPONENTS
- weight = weight*TO_FLOAT3(comp->w);
+ weight = weight*TO_FLOAT3(comp->w);
#endif
- sc.weight = weight;
-
- prim->setup();
-
- switch (prim->category) {
- case CClosurePrimitive::Volume: {
- CVolumeClosure *volume = (CVolumeClosure *)prim;
- /* sample weight */
- float sample_weight = fabsf(average(weight));
-
- sc.sample_weight = sample_weight;
- sc.type = volume->sc.type;
- sc.data0 = volume->sc.data0;
- sc.data1 = volume->sc.data1;
-
- /* add */
- if((sc.sample_weight > CLOSURE_WEIGHT_CUTOFF) &&
- (sd->num_closure < MAX_CLOSURE))
- {
- sd->closure[sd->num_closure++] = sc;
- sd->flag |= volume->shaderdata_flag();
+ sc.weight = weight;
+
+ prim->setup();
+
+ switch(prim->category) {
+ case CClosurePrimitive::Volume: {
+ CVolumeClosure *volume = (CVolumeClosure *)prim;
+ /* sample weight */
+ float sample_weight = fabsf(average(weight));
+
+ sc.sample_weight = sample_weight;
+ sc.type = volume->sc.type;
+ sc.data0 = volume->sc.data0;
+ sc.data1 = volume->sc.data1;
+
+ /* add */
+ if((sc.sample_weight > CLOSURE_WEIGHT_CUTOFF) &&
+ (sd->num_closure < MAX_CLOSURE))
+ {
+ sd->closure[sd->num_closure++] = sc;
+ sd->flag |= volume->shaderdata_flag();
+ }
+ break;
}
- break;
- }
- case CClosurePrimitive::Emissive: {
- /* sample weight */
- float sample_weight = fabsf(average(weight));
-
- sc.sample_weight = sample_weight;
- sc.type = CLOSURE_EMISSION_ID;
- sc.data0 = 0.0f;
- sc.data1 = 0.0f;
- sc.prim = NULL;
-
- /* flag */
- if(sd->num_closure < MAX_CLOSURE) {
- sd->closure[sd->num_closure++] = sc;
- sd->flag |= SD_EMISSION;
+ case CClosurePrimitive::Emissive: {
+ /* sample weight */
+ float sample_weight = fabsf(average(weight));
+
+ sc.sample_weight = sample_weight;
+ sc.type = CLOSURE_EMISSION_ID;
+ sc.data0 = 0.0f;
+ sc.data1 = 0.0f;
+ sc.prim = NULL;
+
+ /* flag */
+ if(sd->num_closure < MAX_CLOSURE) {
+ sd->closure[sd->num_closure++] = sc;
+ sd->flag |= SD_EMISSION;
+ }
+ break;
}
- break;
+ case CClosurePrimitive::Holdout:
+ break; /* not implemented */
+ case CClosurePrimitive::Background:
+ case CClosurePrimitive::BSDF:
+ case CClosurePrimitive::BSSRDF:
+ case CClosurePrimitive::AmbientOcclusion:
+ break; /* not relevant */
}
- case CClosurePrimitive::Holdout:
- break; /* not implemented */
- case CClosurePrimitive::Background:
- case CClosurePrimitive::BSDF:
- case CClosurePrimitive::BSSRDF:
- case CClosurePrimitive::AmbientOcclusion:
- break; /* not relevant */
}
}
}
- else if(closure->type == OSL::ClosureColor::MUL) {
- OSL::ClosureMul *mul = (OSL::ClosureMul *)closure;
- flatten_volume_closure_tree(sd, mul->closure, TO_FLOAT3(mul->weight) * weight);
- }
- else if(closure->type == OSL::ClosureColor::ADD) {
- OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure;
- flatten_volume_closure_tree(sd, add->closureA, weight);
- flatten_volume_closure_tree(sd, add->closureB, weight);
- }
}
void OSLShader::eval_volume(KernelGlobals *kg, ShaderData *sd, int path_flag, ShaderContext ctx)
diff --git a/intern/cycles/kernel/shaders/node_brick_texture.osl b/intern/cycles/kernel/shaders/node_brick_texture.osl
index e26e8dbff2c..35e01178ba8 100644
--- a/intern/cycles/kernel/shaders/node_brick_texture.osl
+++ b/intern/cycles/kernel/shaders/node_brick_texture.osl
@@ -22,6 +22,7 @@
float brick_noise(int n) /* fast integer noise */
{
int nn;
+ n = (n + 1013) & 2147483647;
n = (n >> 13) ^ n;
nn = (n * (n * n * 60493 + 19990303) + 1376312589) & 2147483647;
return 0.5 * ((float)nn / 1073741824.0);
diff --git a/intern/cycles/kernel/shaders/node_environment_texture.osl b/intern/cycles/kernel/shaders/node_environment_texture.osl
index 14f0226a0e5..3a0b782c98e 100644
--- a/intern/cycles/kernel/shaders/node_environment_texture.osl
+++ b/intern/cycles/kernel/shaders/node_environment_texture.osl
@@ -45,6 +45,7 @@ shader node_environment_texture(
vector Vector = P,
string filename = "",
string projection = "Equirectangular",
+ string interpolation = "linear",
string color_space = "sRGB",
int is_float = 1,
int use_alpha = 1,
@@ -64,7 +65,7 @@ shader node_environment_texture(
p = environment_texture_direction_to_mirrorball(p);
/* todo: use environment for better texture filtering of equirectangular */
- Color = (color)texture(filename, p[0], 1.0 - p[1], "wrap", "periodic", "alpha", Alpha);
+ Color = (color)texture(filename, p[0], 1.0 - p[1], "wrap", "periodic", "interp", interpolation, "alpha", Alpha);
if (use_alpha) {
Color = color_unpremultiply(Color, Alpha);
diff --git a/intern/cycles/kernel/split/kernel_data_init.h b/intern/cycles/kernel/split/kernel_data_init.h
index 421e2356f9b..4dab79a5c67 100644
--- a/intern/cycles/kernel/split/kernel_data_init.h
+++ b/intern/cycles/kernel/split/kernel_data_init.h
@@ -31,7 +31,7 @@
* Un-initialized Ray --------------| |--- Initialized Ray
* Un-initialized PathState --------| |--- Initialized PathState
* Un-initialized QueueData --------| |--- Initialized QueueData (to QUEUE_EMPTY_SLOT)
- * Un-initilaized QueueIndex -------| |--- Initialized QueueIndex (to 0)
+ * Un-initialized QueueIndex -------| |--- Initialized QueueIndex (to 0)
* Un-initialized use_queues_flag---| |--- Initialized use_queues_flag (to false)
* Un-initialized ray_state --------| |--- Initialized ray_state
* parallel_samples --------------- | |--- Initialized per_sample_output_buffers
@@ -383,7 +383,7 @@ ccl_device void kernel_data_init(
&Ray_coop[ray_index]);
if(Ray_coop[ray_index].t != 0.0f) {
- /* Initialize throuput, L_transparent, Ray, PathState;
+ /* Initialize throughput, L_transparent, Ray, PathState;
* These rays proceed with path-iteration.
*/
throughput_coop[ray_index] = make_float3(1.0f, 1.0f, 1.0f);
diff --git a/intern/cycles/kernel/svm/svm_attribute.h b/intern/cycles/kernel/svm/svm_attribute.h
index 025ae96f59d..63bbb27d873 100644
--- a/intern/cycles/kernel/svm/svm_attribute.h
+++ b/intern/cycles/kernel/svm/svm_attribute.h
@@ -22,6 +22,8 @@ ccl_device void svm_node_attr_init(KernelGlobals *kg, ShaderData *sd,
uint4 node, NodeAttributeType *type,
NodeAttributeType *mesh_type, AttributeElement *elem, int *offset, uint *out_offset)
{
+ *out_offset = node.z;
+ *type = (NodeAttributeType)node.w;
if(ccl_fetch(sd, object) != OBJECT_NONE) {
/* find attribute by unique id */
uint id = node.y;
@@ -32,6 +34,12 @@ ccl_device void svm_node_attr_init(KernelGlobals *kg, ShaderData *sd,
uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
while(attr_map.x != id) {
+ if(UNLIKELY(attr_map.x == ATTR_STD_NONE)) {
+ *elem = ATTR_ELEMENT_NONE;
+ *offset = 0;
+ *mesh_type = (NodeAttributeType)node.w;
+ return;
+ }
attr_offset += ATTR_PRIM_TYPES;
attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
}
@@ -47,9 +55,6 @@ ccl_device void svm_node_attr_init(KernelGlobals *kg, ShaderData *sd,
*offset = 0;
*mesh_type = (NodeAttributeType)node.w;
}
-
- *out_offset = node.z;
- *type = (NodeAttributeType)node.w;
}
ccl_device void svm_node_attr(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node)
diff --git a/intern/cycles/kernel/svm/svm_brick.h b/intern/cycles/kernel/svm/svm_brick.h
index fcf8f47b77e..9b0cf5ab8c4 100644
--- a/intern/cycles/kernel/svm/svm_brick.h
+++ b/intern/cycles/kernel/svm/svm_brick.h
@@ -21,6 +21,7 @@ CCL_NAMESPACE_BEGIN
ccl_device_noinline float brick_noise(int n) /* fast integer noise */
{
int nn;
+ n = (n + 1013) & 0x7fffffff;
n = (n >> 13) ^ n;
nn = (n * (n * n * 60493 + 19990303) + 1376312589) & 0x7fffffff;
return 0.5f * ((float)nn / 1073741824.0f);
diff --git a/intern/cycles/kernel/svm/svm_closure.h b/intern/cycles/kernel/svm/svm_closure.h
index 20105fd84f0..2120c892490 100644
--- a/intern/cycles/kernel/svm/svm_closure.h
+++ b/intern/cycles/kernel/svm/svm_closure.h
@@ -63,6 +63,9 @@ ccl_device_inline ShaderClosure *svm_node_closure_get_non_bsdf(ShaderData *sd, C
if(ccl_fetch(sd, num_closure) < MAX_CLOSURE) {
sc->weight *= mix_weight;
sc->type = type;
+ sc->data0 = 0.0f;
+ sc->data1 = 0.0f;
+ sc->data2 = 0.0f;
#ifdef __OSL__
sc->prim = NULL;
#endif
@@ -408,7 +411,10 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
sc->data1 = param2;
sc->data2 = -stack_load_float(stack, data_node.z);
- if(!(ccl_fetch(sd, type) & PRIMITIVE_ALL_CURVE)) {
+ if(stack_valid(data_node.y)) {
+ sc->T = normalize(stack_load_float3(stack, data_node.y));
+ }
+ else if(!(ccl_fetch(sd, type) & PRIMITIVE_ALL_CURVE)) {
sc->T = normalize(ccl_fetch(sd, dPdv));
sc->data2 = 0.0f;
}
diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h
index 641d30a5737..bf7e067616f 100644
--- a/intern/cycles/kernel/svm/svm_types.h
+++ b/intern/cycles/kernel/svm/svm_types.h
@@ -46,7 +46,7 @@ CCL_NAMESPACE_BEGIN
#define NODE_FEATURE_HAIR (1 << 1)
#define NODE_FEATURE_BUMP (1 << 2)
/* TODO(sergey): Consider using something like ((uint)(-1)).
- * Need to ceck carefully operand types around usage of this
+ * Need to check carefully operand types around usage of this
* define first.
*/
#define NODE_FEATURE_ALL (NODE_FEATURE_VOLUME|NODE_FEATURE_HAIR|NODE_FEATURE_BUMP)
diff --git a/intern/cycles/kernel/svm/svm_voxel.h b/intern/cycles/kernel/svm/svm_voxel.h
index bbb687dfce5..31cad5ec887 100644
--- a/intern/cycles/kernel/svm/svm_voxel.h
+++ b/intern/cycles/kernel/svm/svm_voxel.h
@@ -43,15 +43,6 @@ ccl_device void svm_node_tex_voxel(KernelGlobals *kg,
tfm.w = read_node_float(kg, offset);
co = transform_point(&tfm, co);
}
- if(co.x < 0.0f || co.y < 0.0f || co.z < 0.0f ||
- co.x > 1.0f || co.y > 1.0f || co.z > 1.0f)
- {
- if (stack_valid(density_out_offset))
- stack_store_float(stack, density_out_offset, 0.0f);
- if (stack_valid(color_out_offset))
- stack_store_float3(stack, color_out_offset, make_float3(0.0f, 0.0f, 0.0f));
- return;
- }
float4 r = kernel_tex_image_interp_3d(id, co.x, co.y, co.z);
if (stack_valid(density_out_offset))
stack_store_float(stack, density_out_offset, r.w);
diff --git a/intern/cycles/render/camera.cpp b/intern/cycles/render/camera.cpp
index df2a1d348d6..88ff7fbb70a 100644
--- a/intern/cycles/render/camera.cpp
+++ b/intern/cycles/render/camera.cpp
@@ -29,6 +29,7 @@ CCL_NAMESPACE_BEGIN
Camera::Camera()
{
shuttertime = 1.0f;
+ motion_position = MOTION_POSITION_CENTER;
aperturesize = 0.0f;
focaldistance = 10.0f;
@@ -53,6 +54,7 @@ Camera::Camera()
longitude_min = -M_PI_F;
longitude_max = M_PI_F;
fov = M_PI_4_F;
+ fov_pre = fov_post = fov;
sensorwidth = 0.036f;
sensorheight = 0.024f;
@@ -91,19 +93,26 @@ Camera::~Camera()
void Camera::compute_auto_viewplane()
{
- float aspect = (float)width/(float)height;
-
- if(width >= height) {
- viewplane.left = -aspect;
- viewplane.right = aspect;
- viewplane.bottom = -1.0f;
+ if(type == CAMERA_PANORAMA) {
+ viewplane.left = 0.0f;
+ viewplane.right = 1.0f;
+ viewplane.bottom = 0.0f;
viewplane.top = 1.0f;
}
else {
- viewplane.left = -1.0f;
- viewplane.right = 1.0f;
- viewplane.bottom = -1.0f/aspect;
- viewplane.top = 1.0f/aspect;
+ float aspect = (float)width/(float)height;
+ if(width >= height) {
+ viewplane.left = -aspect;
+ viewplane.right = aspect;
+ viewplane.bottom = -1.0f;
+ viewplane.top = 1.0f;
+ }
+ else {
+ viewplane.left = -1.0f;
+ viewplane.right = 1.0f;
+ viewplane.bottom = -1.0f/aspect;
+ viewplane.top = 1.0f/aspect;
+ }
}
}
@@ -417,9 +426,9 @@ BoundBox Camera::viewplane_bounds_get()
BoundBox bounds = BoundBox::empty;
if(type == CAMERA_PANORAMA) {
- bounds.grow(make_float3(cameratoworld.w.x,
- cameratoworld.w.y,
- cameratoworld.w.z));
+ bounds.grow(make_float3(cameratoworld.x.w,
+ cameratoworld.y.w,
+ cameratoworld.z.w));
}
else {
bounds.grow(transform_raster_to_world(0.0f, 0.0f));
diff --git a/intern/cycles/render/camera.h b/intern/cycles/render/camera.h
index 1bedb051112..53bd4f0bc14 100644
--- a/intern/cycles/render/camera.h
+++ b/intern/cycles/render/camera.h
@@ -32,12 +32,24 @@ class Scene;
/* Camera
*
* The camera parameters are quite standard, tested to be both compatible with
- * Renderman, and Blender after remapping. */
+ * Renderman, and Blender after remapping.
+ */
class Camera {
public:
+ /* Specifies an offset for the shutter's time interval. */
+ enum MotionPosition {
+ /* Shutter opens at the current frame. */
+ MOTION_POSITION_START,
+ /* Shutter is fully open at the current frame. */
+ MOTION_POSITION_CENTER,
+ /* Shutter closes at the current frame. */
+ MOTION_POSITION_END,
+ };
+
/* motion blur */
float shuttertime;
+ MotionPosition motion_position;
/* depth of field */
float focaldistance;
diff --git a/intern/cycles/render/film.cpp b/intern/cycles/render/film.cpp
index 7282b04a22e..58080289633 100644
--- a/intern/cycles/render/film.cpp
+++ b/intern/cycles/render/film.cpp
@@ -144,7 +144,13 @@ void Pass::add(PassType type, vector<Pass>& passes)
pass.exposure = false;
break;
case PASS_LIGHT:
- /* ignores */
+ /* This isn't a real pass, used by baking to see whether
+ * light data is needed or not.
+ *
+ * Set components to 0 so pass sort below happens in a
+ * determined way.
+ */
+ pass.components = 0;
break;
#ifdef WITH_CYCLES_DEBUG
case PASS_BVH_TRAVERSAL_STEPS:
diff --git a/intern/cycles/render/graph.cpp b/intern/cycles/render/graph.cpp
index e0537101247..f5ff091623b 100644
--- a/intern/cycles/render/graph.cpp
+++ b/intern/cycles/render/graph.cpp
@@ -336,6 +336,8 @@ void ShaderGraph::remove_unneeded_nodes()
vector<bool> removed(num_node_ids, false);
bool any_node_removed = false;
+ ShaderNode *geom = NULL;
+
/* find and unlink proxy nodes */
foreach(ShaderNode *node, nodes) {
if(node->special_type == SHADER_SPECIAL_TYPE_PROXY) {
@@ -423,12 +425,19 @@ void ShaderGraph::remove_unneeded_nodes()
BumpNode *bump = static_cast<BumpNode*>(node);
if(bump->outputs[0]->links.size()) {
- /* Height input not connected */
- /* ToDo: Strength zero? */
- if(!bump->inputs[0]->link) {
+ /* Height inputs is not connected. */
+ /* TODO(sergey): Ignore bump with zero strength. */
+ if(bump->inputs[0]->link == NULL) {
vector<ShaderInput*> inputs = bump->outputs[0]->links;
-
- relink(bump->inputs, inputs, NULL);
+ if(bump->inputs[4]->link == NULL) {
+ if(geom == NULL) {
+ geom = new GeometryNode();
+ }
+ relink(bump->inputs, inputs, geom->output("Normal"));
+ }
+ else {
+ relink(bump->inputs, inputs, bump->input("Normal")->link);
+ }
removed[bump->id] = true;
any_node_removed = true;
}
@@ -511,6 +520,10 @@ void ShaderGraph::remove_unneeded_nodes()
nodes = newnodes;
}
+
+ if(geom != NULL) {
+ add(geom);
+ }
}
void ShaderGraph::break_cycles(ShaderNode *node, vector<bool>& visited, vector<bool>& on_stack)
diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp
index 7bceb8a8bfa..486ae5b597f 100644
--- a/intern/cycles/render/image.cpp
+++ b/intern/cycles/render/image.cpp
@@ -69,6 +69,9 @@ void ImageManager::set_extended_image_limits(const DeviceInfo& info)
else if((info.type == DEVICE_CUDA || info.type == DEVICE_MULTI) && info.extended_images) {
tex_num_images = TEX_EXTENDED_NUM_IMAGES_GPU;
}
+ else if(info.pack_images) {
+ tex_num_images = TEX_PACKED_NUM_IMAGES;
+ }
}
bool ImageManager::set_animation_frame_update(int frame)
@@ -447,6 +450,9 @@ bool ImageManager::file_load_image(Image *img, device_vector<uchar4>& tex_img)
/* read RGBA pixels */
uchar *pixels = (uchar*)tex_img.resize(width, height, depth);
+ if(pixels == NULL) {
+ return false;
+ }
bool cmyk = false;
if(in) {
@@ -570,6 +576,9 @@ bool ImageManager::file_load_float_image(Image *img, device_vector<float4>& tex_
/* read RGBA pixels */
float *pixels = (float*)tex_img.resize(width, height, depth);
+ if(pixels == NULL) {
+ return false;
+ }
bool cmyk = false;
if(in) {
diff --git a/intern/cycles/render/image.h b/intern/cycles/render/image.h
index bcc58ae951b..c79c152afde 100644
--- a/intern/cycles/render/image.h
+++ b/intern/cycles/render/image.h
@@ -40,6 +40,13 @@ CCL_NAMESPACE_BEGIN
#define TEX_EXTENDED_NUM_IMAGES_CPU 1024
#define TEX_EXTENDED_IMAGE_BYTE_START TEX_EXTENDED_NUM_FLOAT_IMAGES
+/* Limitations for packed images.
+ *
+ * Technically number of textures is unlimited, but it should in
+ * fact be in sync with CPU limitations.
+ */
+#define TEX_PACKED_NUM_IMAGES 1024
+
/* color to use when textures are not found */
#define TEX_IMAGE_MISSING_R 1
#define TEX_IMAGE_MISSING_G 0
diff --git a/intern/cycles/render/integrator.cpp b/intern/cycles/render/integrator.cpp
index 465d7ea02c6..9f8d5b50ccd 100644
--- a/intern/cycles/render/integrator.cpp
+++ b/intern/cycles/render/integrator.cpp
@@ -100,6 +100,7 @@ void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene
* transparent shaders in the scene. Otherwise we can disable it
* to improve performance a bit. */
if(transparent_shadows) {
+ kintegrator->transparent_shadows = false;
foreach(Shader *shader, scene->shaders) {
/* keep this in sync with SD_HAS_TRANSPARENT_SHADOW in shader.cpp */
if((shader->has_surface_transparent && shader->use_transparent_shadow) || shader->has_volume) {
diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp
index 45685fe5927..57f194651f8 100644
--- a/intern/cycles/render/mesh.cpp
+++ b/intern/cycles/render/mesh.cpp
@@ -513,7 +513,6 @@ void Mesh::compute_bvh(SceneParams *params, Progress *progress, int n, int total
progress->set_status(msg, "Building BVH");
BVHParams bparams;
- bparams.use_cache = params->use_bvh_cache;
bparams.use_spatial_split = params->use_bvh_spatial_split;
bparams.use_qbvh = params->use_qbvh;
@@ -1084,7 +1083,6 @@ void MeshManager::device_update_bvh(Device *device, DeviceScene *dscene, Scene *
bparams.top_level = true;
bparams.use_qbvh = scene->params.use_qbvh;
bparams.use_spatial_split = scene->params.use_bvh_spatial_split;
- bparams.use_cache = scene->params.use_bvh_cache;
delete bvh;
bvh = BVH::create(bparams, scene->objects);
diff --git a/intern/cycles/render/mesh_displace.cpp b/intern/cycles/render/mesh_displace.cpp
index 1ba0c7f7291..801fffc774c 100644
--- a/intern/cycles/render/mesh_displace.cpp
+++ b/intern/cycles/render/mesh_displace.cpp
@@ -78,7 +78,7 @@ bool MeshManager::displace(Device *device, DeviceScene *dscene, Scene *scene, Me
int prim = mesh->tri_offset + i;
float u, v;
- switch (j) {
+ switch(j) {
case 0:
u = 1.0f;
v = 0.0f;
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index 7ed07ab6453..7ac872b8416 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -182,6 +182,21 @@ static ShaderEnum image_projection_init()
return enm;
}
+static const char* get_osl_interpolation_parameter(InterpolationType interpolation)
+{
+ switch(interpolation) {
+ case INTERPOLATION_CLOSEST:
+ return "closest";
+ case INTERPOLATION_CUBIC:
+ return "cubic";
+ case INTERPOLATION_SMART:
+ return "smart";
+ case INTERPOLATION_LINEAR:
+ default:
+ return "linear";
+ }
+}
+
ShaderEnum ImageTextureNode::color_space_enum = color_space_init();
ShaderEnum ImageTextureNode::projection_enum = image_projection_init();
@@ -362,22 +377,7 @@ void ImageTextureNode::compile(OSLCompiler& compiler)
compiler.parameter("projection_blend", projection_blend);
compiler.parameter("is_float", is_float);
compiler.parameter("use_alpha", !alpha_out->links.empty());
-
- switch (interpolation) {
- case INTERPOLATION_CLOSEST:
- compiler.parameter("interpolation", "closest");
- break;
- case INTERPOLATION_CUBIC:
- compiler.parameter("interpolation", "cubic");
- break;
- case INTERPOLATION_SMART:
- compiler.parameter("interpolation", "smart");
- break;
- case INTERPOLATION_LINEAR:
- default:
- compiler.parameter("interpolation", "linear");
- break;
- }
+ compiler.parameter("interpolation", get_osl_interpolation_parameter(interpolation));
switch(extension) {
case EXTENSION_EXTEND:
@@ -421,6 +421,7 @@ EnvironmentTextureNode::EnvironmentTextureNode()
filename = "";
builtin_data = NULL;
color_space = ustring("Color");
+ interpolation = INTERPOLATION_LINEAR;
projection = ustring("Equirectangular");
animated = false;
@@ -434,7 +435,7 @@ EnvironmentTextureNode::~EnvironmentTextureNode()
if(image_manager) {
image_manager->remove_image(filename,
builtin_data,
- INTERPOLATION_LINEAR,
+ interpolation,
EXTENSION_REPEAT);
}
}
@@ -477,7 +478,7 @@ void EnvironmentTextureNode::compile(SVMCompiler& compiler)
0,
is_float_bool,
is_linear,
- INTERPOLATION_LINEAR,
+ interpolation,
EXTENSION_REPEAT,
use_alpha);
is_float = (int)is_float_bool;
@@ -546,7 +547,7 @@ void EnvironmentTextureNode::compile(OSLCompiler& compiler)
0,
is_float_bool,
is_linear,
- INTERPOLATION_LINEAR,
+ interpolation,
EXTENSION_REPEAT,
use_alpha);
is_float = (int)is_float_bool;
@@ -564,6 +565,9 @@ void EnvironmentTextureNode::compile(OSLCompiler& compiler)
compiler.parameter("color_space", "Linear");
else
compiler.parameter("color_space", "sRGB");
+
+ compiler.parameter("interpolation", get_osl_interpolation_parameter(interpolation));
+
compiler.parameter("is_float", is_float);
compiler.parameter("use_alpha", !alpha_out->links.empty());
compiler.add(this, "node_environment_texture");
@@ -1381,7 +1385,7 @@ PointDensityTextureNode::~PointDensityTextureNode()
image_manager->remove_image(filename,
builtin_data,
interpolation,
- EXTENSION_REPEAT);
+ EXTENSION_CLIP);
}
}
@@ -1413,10 +1417,10 @@ void PointDensityTextureNode::compile(SVMCompiler& compiler)
image_manager = compiler.image_manager;
- if (use_density || use_color) {
- if (use_density)
+ if(use_density || use_color) {
+ if(use_density)
compiler.stack_assign(density_out);
- if (use_color)
+ if(use_color)
compiler.stack_assign(color_out);
if(slot == -1) {
@@ -1425,7 +1429,7 @@ void PointDensityTextureNode::compile(SVMCompiler& compiler)
false, 0,
is_float, is_linear,
interpolation,
- EXTENSION_REPEAT,
+ EXTENSION_CLIP,
true);
}
@@ -1466,14 +1470,14 @@ void PointDensityTextureNode::compile(OSLCompiler& compiler)
image_manager = compiler.image_manager;
- if (use_density || use_color) {
+ if(use_density || use_color) {
if(slot == -1) {
bool is_float, is_linear;
slot = image_manager->add_image(filename, builtin_data,
false, 0,
is_float, is_linear,
interpolation,
- EXTENSION_REPEAT,
+ EXTENSION_CLIP,
true);
}
@@ -1484,7 +1488,7 @@ void PointDensityTextureNode::compile(OSLCompiler& compiler)
compiler.parameter("mapping", transform_transpose(tfm));
compiler.parameter("use_mapping", 1);
}
- switch (interpolation) {
+ switch(interpolation) {
case INTERPOLATION_CLOSEST:
compiler.parameter("interpolation", "closest");
break;
@@ -1675,7 +1679,7 @@ void ConvertNode::compile(SVMCompiler& compiler)
compiler.stack_assign(in);
compiler.stack_assign(out);
- compiler.add_node(NODE_VALUE_V, in->stack_offset);
+ compiler.add_node(NODE_VALUE_V, out->stack_offset);
compiler.add_node(NODE_VALUE_V, in->value);
}
}
@@ -2354,6 +2358,7 @@ HairBsdfNode::HairBsdfNode()
add_input("Offset", SHADER_SOCKET_FLOAT);
add_input("RoughnessU", SHADER_SOCKET_FLOAT);
add_input("RoughnessV", SHADER_SOCKET_FLOAT);
+ add_input("Tangent", SHADER_SOCKET_VECTOR);
}
void HairBsdfNode::compile(SVMCompiler& compiler)
diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h
index 5065e68345a..39709c26398 100644
--- a/intern/cycles/render/nodes.h
+++ b/intern/cycles/render/nodes.h
@@ -116,6 +116,7 @@ public:
void *builtin_data;
ustring color_space;
ustring projection;
+ InterpolationType interpolation;
bool animated;
static ShaderEnum color_space_enum;
diff --git a/intern/cycles/render/shader.cpp b/intern/cycles/render/shader.cpp
index 31be2a3d3f4..aba3e7237d2 100644
--- a/intern/cycles/render/shader.cpp
+++ b/intern/cycles/render/shader.cpp
@@ -18,6 +18,7 @@
#include "camera.h"
#include "device.h"
#include "graph.h"
+#include "integrator.h"
#include "light.h"
#include "mesh.h"
#include "nodes.h"
@@ -338,6 +339,7 @@ void ShaderManager::device_update_common(Device *device,
uint *shader_flag = dscene->shader_flag.resize(shader_flag_size);
uint i = 0;
bool has_volumes = false;
+ bool has_transparent_shadow = false;
foreach(Shader *shader, scene->shaders) {
uint flag = 0;
@@ -355,8 +357,8 @@ void ShaderManager::device_update_common(Device *device,
flag |= SD_HAS_ONLY_VOLUME;
/* todo: this could check more fine grained, to skip useless volumes
- * enclosed inside an opaque bsdf, although we still need to handle
- * the case with camera inside volumes too */
+ * enclosed inside an opaque bsdf.
+ */
flag |= SD_HAS_TRANSPARENT_SHADOW;
}
if(shader->heterogeneous_volume && shader->has_heterogeneous_volume)
@@ -382,6 +384,8 @@ void ShaderManager::device_update_common(Device *device,
shader_flag[i++] = flag;
shader_flag[i++] = shader->pass_id;
+
+ has_transparent_shadow |= (flag & SD_HAS_TRANSPARENT_SHADOW);
}
device->tex_alloc("__shader_flag", dscene->shader_flag);
@@ -404,6 +408,10 @@ void ShaderManager::device_update_common(Device *device,
/* integrator */
KernelIntegrator *kintegrator = &dscene->data.integrator;
kintegrator->use_volumes = has_volumes;
+ /* TODO(sergey): De-duplicate with flags set in integrator.cpp. */
+ if(scene->integrator->transparent_shadows) {
+ kintegrator->transparent_shadows = has_transparent_shadow;
+ }
}
void ShaderManager::device_free_common(Device *device, DeviceScene *dscene, Scene *scene)
diff --git a/intern/cycles/render/svm.cpp b/intern/cycles/render/svm.cpp
index d0bd34915df..e81b2f3a827 100644
--- a/intern/cycles/render/svm.cpp
+++ b/intern/cycles/render/svm.cpp
@@ -121,7 +121,7 @@ int SVMCompiler::stack_size(ShaderSocketType type)
{
int size = 0;
- switch (type) {
+ switch(type) {
case SHADER_SOCKET_FLOAT:
case SHADER_SOCKET_INT:
size = 1;
@@ -624,7 +624,7 @@ void SVMCompiler::compile_type(Shader *shader, ShaderGraph *graph, ShaderType ty
ShaderNode *node = graph->output();
ShaderInput *clin = NULL;
- switch (type) {
+ switch(type) {
case SHADER_TYPE_SURFACE:
clin = node->input("Surface");
break;
@@ -654,7 +654,7 @@ void SVMCompiler::compile_type(Shader *shader, ShaderGraph *graph, ShaderType ty
if(clin->link) {
bool generate = false;
- switch (type) {
+ switch(type) {
case SHADER_TYPE_SURFACE: /* generate surface shader */
generate = true;
shader->has_surface = true;
diff --git a/intern/cycles/render/tile.cpp b/intern/cycles/render/tile.cpp
index 7e68ce84d94..1bec39431d8 100644
--- a/intern/cycles/render/tile.cpp
+++ b/intern/cycles/render/tile.cpp
@@ -199,7 +199,7 @@ list<Tile>::iterator TileManager::next_background_tile(int device, TileOrder til
int64_t distx = cordx;
int64_t disty = cordy;
- switch (tile_order) {
+ switch(tile_order) {
case TILE_CENTER:
distx = centx - (cur_tile.x + (cur_tile.w / 2));
disty = centy - (cur_tile.y + (cur_tile.h / 2));
diff --git a/intern/cycles/util/util_math.h b/intern/cycles/util/util_math.h
index 97c93516496..7d6dfd34e0e 100644
--- a/intern/cycles/util/util_math.h
+++ b/intern/cycles/util/util_math.h
@@ -1447,14 +1447,9 @@ ccl_device bool ray_triangle_intersect_uv(
return true;
}
-#if defined(__KERNEL_CUDA__) && (defined(i386) || defined(_M_IX86)) && (defined(__KERNEL_EXPERIMENTAL__) || __CUDA_ARCH__ == 500)
-ccl_device_noinline
-#else
-ccl_device
-#endif
-bool ray_quad_intersect(float3 ray_P, float3 ray_D, float ray_t,
- float3 quad_P, float3 quad_u, float3 quad_v,
- float3 *isect_P, float *isect_t)
+ccl_device bool ray_quad_intersect(float3 ray_P, float3 ray_D, float ray_t,
+ float3 quad_P, float3 quad_u, float3 quad_v,
+ float3 *isect_P, float *isect_t)
{
float3 v0 = quad_P - quad_u*0.5f - quad_v*0.5f;
float3 v1 = quad_P + quad_u*0.5f - quad_v*0.5f;
diff --git a/intern/cycles/util/util_optimization.h b/intern/cycles/util/util_optimization.h
index c951c35fc76..42d3ca69b3a 100644
--- a/intern/cycles/util/util_optimization.h
+++ b/intern/cycles/util/util_optimization.h
@@ -101,7 +101,7 @@
#ifdef _MSC_VER
#include <intrin.h>
-#else
+#elif (defined(__x86_64__) || defined(__i386__))
#include <x86intrin.h>
#endif
diff --git a/intern/cycles/util/util_transform.h b/intern/cycles/util/util_transform.h
index ba8d04b5c16..f01db64a79b 100644
--- a/intern/cycles/util/util_transform.h
+++ b/intern/cycles/util/util_transform.h
@@ -347,7 +347,12 @@ ccl_device_inline Transform transform_quick_inverse(Transform M)
* scale can be inverted but what about shearing? */
Transform R;
float det = M.x.x*(M.z.z*M.y.y - M.z.y*M.y.z) - M.y.x*(M.z.z*M.x.y - M.z.y*M.x.z) + M.z.x*(M.y.z*M.x.y - M.y.y*M.x.z);
-
+ if(det == 0.0f) {
+ M.x.x += 1e-8f;
+ M.y.y += 1e-8f;
+ M.z.z += 1e-8f;
+ det = M.x.x*(M.z.z*M.y.y - M.z.y*M.y.z) - M.y.x*(M.z.z*M.x.y - M.z.y*M.x.z) + M.z.x*(M.y.z*M.x.y - M.y.y*M.x.z);
+ }
det = (det != 0.0f)? 1.0f/det: 0.0f;
float3 Rx = det*make_float3(M.z.z*M.y.y - M.z.y*M.y.z, M.z.y*M.x.z - M.z.z*M.x.y, M.y.z*M.x.y - M.y.y*M.x.z);
diff --git a/intern/cycles/util/util_vector.h b/intern/cycles/util/util_vector.h
index 15a65be0ef0..623436483a0 100644
--- a/intern/cycles/util/util_vector.h
+++ b/intern/cycles/util/util_vector.h
@@ -105,6 +105,7 @@ public:
{
data = NULL;
datasize = 0;
+ capacity = 0;
}
array(size_t newsize)
@@ -112,10 +113,12 @@ public:
if(newsize == 0) {
data = NULL;
datasize = 0;
+ capacity = 0;
}
else {
data = (T*)util_aligned_malloc(sizeof(T)*newsize, alignment);
datasize = newsize;
+ capacity = datasize;
}
}
@@ -129,11 +132,13 @@ public:
if(from.datasize == 0) {
data = NULL;
datasize = 0;
+ capacity = 0;
}
else {
data = (T*)util_aligned_malloc(sizeof(T)*from.datasize, alignment);
memcpy(data, from.data, from.datasize*sizeof(T));
datasize = from.datasize;
+ capacity = datasize;
}
return *this;
@@ -142,6 +147,7 @@ public:
array& operator=(const vector<T>& from)
{
datasize = from.size();
+ capacity = datasize;
data = NULL;
if(datasize > 0) {
@@ -157,28 +163,39 @@ public:
util_aligned_free(data);
}
- void resize(size_t newsize)
+ T* resize(size_t newsize)
{
if(newsize == 0) {
clear();
}
else if(newsize != datasize) {
- T *newdata = (T*)util_aligned_malloc(sizeof(T)*newsize, alignment);
- if(data) {
- memcpy(newdata, data, ((datasize < newsize)? datasize: newsize)*sizeof(T));
- util_aligned_free(data);
+ if(newsize > capacity) {
+ T *newdata = (T*)util_aligned_malloc(sizeof(T)*newsize, alignment);
+ if(newdata == NULL) {
+ /* Allocation failed, likely out of memory. */
+ clear();
+ return NULL;
+ }
+ else if(data) {
+ memcpy(newdata, data, ((datasize < newsize)? datasize: newsize)*sizeof(T));
+ util_aligned_free(data);
+ }
+ data = newdata;
+ capacity = newsize;
}
-
- data = newdata;
datasize = newsize;
}
+ return data;
}
void clear()
{
- util_aligned_free(data);
- data = NULL;
+ if(data != NULL) {
+ util_aligned_free(data);
+ data = NULL;
+ }
datasize = 0;
+ capacity = 0;
}
size_t size() const
@@ -192,9 +209,22 @@ public:
return data[i];
}
+ void reserve(size_t newcapacity) {
+ if(newcapacity > capacity) {
+ T *newdata = (T*)util_aligned_malloc(sizeof(T)*newcapacity, alignment);
+ if(data) {
+ memcpy(newdata, data, ((datasize < newcapacity)? datasize: newcapacity)*sizeof(T));
+ util_aligned_free(data);
+ }
+ data = newdata;
+ capacity = newcapacity;
+ }
+ }
+
protected:
T *data;
size_t datasize;
+ size_t capacity;
};
CCL_NAMESPACE_END
diff --git a/intern/elbeem/intern/simulation_object.cpp b/intern/elbeem/intern/simulation_object.cpp
index 99c3b170634..f2f928f07dc 100644
--- a/intern/elbeem/intern/simulation_object.cpp
+++ b/intern/elbeem/intern/simulation_object.cpp
@@ -172,7 +172,7 @@ int SimulationObject::initializeLbmSimulation(ntlRenderGlobals *glob)
mpLbm->setParticleTracer( mpParts );
if(mpElbeemSettings) {
// set further settings from API struct init
- if(mpElbeemSettings->outputPath) this->mOutFilename = string(mpElbeemSettings->outputPath);
+ this->mOutFilename = string(mpElbeemSettings->outputPath);
mpLbm->initDomainTrafo( mpElbeemSettings->surfaceTrafo );
mpLbm->setSmoothing(1.0 * mpElbeemSettings->surfaceSmoothing, 1.0 * mpElbeemSettings->surfaceSmoothing);
mpLbm->setIsoSubdivs(mpElbeemSettings->surfaceSubdivs);
diff --git a/intern/ghost/SConscript b/intern/ghost/SConscript
index 025559e11a4..78566210047 100644
--- a/intern/ghost/SConscript
+++ b/intern/ghost/SConscript
@@ -48,7 +48,8 @@ sources.remove('intern' + os.sep + 'GHOST_ContextWGL.cpp')
pf = ['GHOST_DisplayManager', 'GHOST_System', 'GHOST_SystemPaths', 'GHOST_Window', 'GHOST_DropTarget', 'GHOST_NDOFManager', 'GHOST_Context']
-defs = env['BF_GL_DEFINITIONS']
+defs = []
+defs += env['BF_GL_DEFINITIONS']
if env['WITH_BF_GL_EGL']:
defs.append('WITH_EGL')
diff --git a/intern/ghost/intern/GHOST_C-api.cpp b/intern/ghost/intern/GHOST_C-api.cpp
index af992bf5a3c..9baa66abad9 100644
--- a/intern/ghost/intern/GHOST_C-api.cpp
+++ b/intern/ghost/intern/GHOST_C-api.cpp
@@ -358,27 +358,20 @@ GHOST_TSuccess GHOST_SetCursorGrab(GHOST_WindowHandle windowhandle,
int bounds[4], const int mouse_ungrab_xy[2])
{
GHOST_IWindow *window = (GHOST_IWindow *) windowhandle;
- GHOST_Rect bounds_rect, bounds_win;
- GHOST_TInt32 mouse_ungrab_xy_global[2];
+ GHOST_Rect bounds_rect;
+ GHOST_TInt32 mouse_xy[2];
if (bounds) {
- /* if this is X11 specific we need a function that converts */
- window->getClientBounds(bounds_win);
- window->clientToScreen(bounds[0], bounds_win.getHeight() - bounds[1], bounds_rect.m_l, bounds_rect.m_t);
- window->clientToScreen(bounds[2], bounds_win.getHeight() - bounds[3], bounds_rect.m_r, bounds_rect.m_b);
-
+ bounds_rect = GHOST_Rect(bounds[0], bounds[1], bounds[2], bounds[3]);
}
-
if (mouse_ungrab_xy) {
- if (bounds == NULL)
- window->getClientBounds(bounds_win);
- window->clientToScreen(mouse_ungrab_xy[0], bounds_win.getHeight() - mouse_ungrab_xy[1],
- mouse_ungrab_xy_global[0], mouse_ungrab_xy_global[1]);
+ mouse_xy[0] = mouse_ungrab_xy[0];
+ mouse_xy[1] = mouse_ungrab_xy[1];
}
return window->setCursorGrab(mode,
bounds ? &bounds_rect : NULL,
- mouse_ungrab_xy ? mouse_ungrab_xy_global : NULL);
+ mouse_ungrab_xy ? mouse_xy : NULL);
}
diff --git a/intern/ghost/intern/GHOST_ContextCGL.h b/intern/ghost/intern/GHOST_ContextCGL.h
index 92fdbfc53de..953235669a8 100644
--- a/intern/ghost/intern/GHOST_ContextCGL.h
+++ b/intern/ghost/intern/GHOST_ContextCGL.h
@@ -128,18 +128,9 @@ public:
private:
//void initContextCGLEW()
- /** The window containing the OpenGL view */
- NSWindow *m_window;
-
/** The openGL view */
NSOpenGLView *m_openGLView;
- const int m_contextProfileMask;
- const int m_contextMajorVersion;
- const int m_contextMinorVersion;
- const int m_contextFlags;
- const int m_contextResetNotificationStrategy;
-
/** The OpenGL drawing context */
NSOpenGLContext *m_openGLContext;
diff --git a/intern/ghost/intern/GHOST_ContextCGL.mm b/intern/ghost/intern/GHOST_ContextCGL.mm
index 51895e5fa1a..6a9c23ea72b 100644
--- a/intern/ghost/intern/GHOST_ContextCGL.mm
+++ b/intern/ghost/intern/GHOST_ContextCGL.mm
@@ -58,16 +58,9 @@ GHOST_ContextCGL::GHOST_ContextCGL(
int contextFlags,
int contextResetNotificationStrategy)
: GHOST_Context(stereoVisual, numOfAASamples),
- m_window(window),
m_openGLView(openGLView),
- m_contextProfileMask(contextProfileMask),
- m_contextMajorVersion(contextMajorVersion),
- m_contextMinorVersion(contextMinorVersion),
- m_contextFlags(contextFlags),
- m_contextResetNotificationStrategy(contextResetNotificationStrategy),
m_openGLContext(nil)
{
- assert(window != nil);
assert(openGLView != nil);
}
diff --git a/intern/ghost/intern/GHOST_ContextGLX.cpp b/intern/ghost/intern/GHOST_ContextGLX.cpp
index 3cce2236143..0ee8da15dea 100644
--- a/intern/ghost/intern/GHOST_ContextGLX.cpp
+++ b/intern/ghost/intern/GHOST_ContextGLX.cpp
@@ -40,6 +40,13 @@
#include <cstdio>
#include <cstring>
+/* needed for intel drivers (works w/ mesa-swrast & nvidia) */
+#define USE_GLXEW_INIT_WORKAROUND
+
+#ifdef USE_GLXEW_INIT_WORKAROUND
+static GLuint _glewStrLen(const GLubyte *s);
+static GLboolean _glewSearchExtension(const char *name, const GLubyte *start, const GLubyte *end);
+#endif
#ifdef WITH_GLEW_MX
GLXEWContext *glxewContext = NULL;
@@ -154,10 +161,54 @@ GHOST_TSuccess GHOST_ContextGLX::initializeDrawingContext()
XIOErrorHandler old_handler_io = XSetIOErrorHandler(GHOST_X11_ApplicationIOErrorHandler);
#endif
- /* needed so 'GLXEW_ARB_create_context' is valid */
- mxIgnoreNoVersion(1);
- initContextGLXEW();
- mxIgnoreNoVersion(0);
+
+
+ /* -------------------------------------------------------------------- */
+ /* Begin Inline Glew */
+
+#ifdef USE_GLXEW_INIT_WORKAROUND
+ const GLubyte *extStart = (GLubyte *)"";
+ const GLubyte *extEnd;
+ if (glXQueryExtension(m_display, NULL, NULL)) {
+ extStart = (const GLubyte *)glXGetClientString(m_display, GLX_EXTENSIONS);
+ if ((extStart == NULL) ||
+ (glXChooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC)glXGetProcAddressARB(
+ (const GLubyte *)"glXChooseFBConfig")) == NULL ||
+ (glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)glXGetProcAddressARB(
+ (const GLubyte *)"glXCreateContextAttribsARB")) == NULL)
+ {
+ extStart = (GLubyte *)"";
+ }
+ }
+ extEnd = extStart + _glewStrLen(extStart);
+
+#undef GLXEW_ARB_create_context
+ const bool GLXEW_ARB_create_context =
+ _glewSearchExtension("GLX_ARB_create_context", extStart, extEnd);
+#undef GLXEW_ARB_create_context_profile
+ const bool GLXEW_ARB_create_context_profile =
+ _glewSearchExtension("GLX_ARB_create_context_profile", extStart, extEnd);
+#undef GLXEW_ARB_create_context_robustness
+const bool GLXEW_ARB_create_context_robustness =
+ _glewSearchExtension("GLX_ARB_create_context_robustness", extStart, extEnd);
+#ifdef WITH_GLEW_ES
+#undef GLXEW_EXT_create_context_es_profile
+ const bool GLXEW_EXT_create_context_es_profile =
+ _glewSearchExtension("GLX_EXT_create_context_es_profile", extStart, extEnd);
+#undef GLXEW_EXT_create_context_es2_profile
+ const bool GLXEW_EXT_create_context_es2_profile =
+ _glewSearchExtension("GLX_EXT_create_context_es2_profile", extStart, extEnd);
+#endif /* WITH_GLEW_ES */
+
+ /* End Inline Glew */
+ /* -------------------------------------------------------------------- */
+#else
+ /* important to initialize only glxew (_not_ glew),
+ * since this breaks w/ Mesa's `swrast`, see: T46431 */
+ glxewInit();
+#endif /* USE_GLXEW_INIT_WORKAROUND */
+
+
if (GLXEW_ARB_create_context) {
int profileBitCore = m_contextProfileMask & GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
@@ -246,6 +297,7 @@ GHOST_TSuccess GHOST_ContextGLX::initializeDrawingContext()
if (framebuffer_config) {
m_context = glXCreateContextAttribsARB(m_display, framebuffer_config[0], s_sharedContext, True, attribs);
+ XFree(framebuffer_config);
}
}
else {
@@ -263,6 +315,10 @@ GHOST_TSuccess GHOST_ContextGLX::initializeDrawingContext()
glXMakeCurrent(m_display, m_window, m_context);
+ // Seems that this has to be called after MakeCurrent,
+ // which means we cannot use glX extensions until after we create a context
+ initContextGLXEW();
+
initClearGL();
::glXSwapBuffers(m_display, m_window);
@@ -404,5 +460,49 @@ int GHOST_X11_GL_GetAttributes(
GHOST_ASSERT(i <= attribs_max, "attribute size too small");
+ (void)attribs_max;
+
return i;
}
+
+
+/* excuse inlining part of glew */
+#ifdef USE_GLXEW_INIT_WORKAROUND
+static GLuint _glewStrLen(const GLubyte *s)
+{
+ GLuint i = 0;
+ if (s == NULL) return 0;
+ while (s[i] != '\0') i++;
+ return i;
+}
+
+static GLuint _glewStrCLen(const GLubyte *s, GLubyte c)
+{
+ GLuint i = 0;
+ if (s == NULL) return 0;
+ while (s[i] != '\0' && s[i] != c) i++;
+ return (s[i] == '\0' || s[i] == c) ? i : 0;
+}
+
+static GLboolean _glewStrSame(const GLubyte *a, const GLubyte *b, GLuint n)
+{
+ GLuint i = 0;
+ if (a == NULL || b == NULL)
+ return (a == NULL && b == NULL && n == 0) ? GL_TRUE : GL_FALSE;
+ while (i < n && a[i] != '\0' && b[i] != '\0' && a[i] == b[i]) i++;
+ return i == n ? GL_TRUE : GL_FALSE;
+}
+
+static GLboolean _glewSearchExtension(const char *name, const GLubyte *start, const GLubyte *end)
+{
+ const GLubyte *p;
+ GLuint len = _glewStrLen((const GLubyte *)name);
+ p = start;
+ while (p < end) {
+ GLuint n = _glewStrCLen(p, ' ');
+ if (len == n && _glewStrSame((const GLubyte *)name, p, n)) return GL_TRUE;
+ p += n + 1;
+ }
+ return GL_FALSE;
+}
+#endif /* USE_GLXEW_INIT_WORKAROUND */ \ No newline at end of file
diff --git a/intern/ghost/intern/GHOST_DisplayManagerX11.cpp b/intern/ghost/intern/GHOST_DisplayManagerX11.cpp
index 0cc116292c0..b3e6f2e53fa 100644
--- a/intern/ghost/intern/GHOST_DisplayManagerX11.cpp
+++ b/intern/ghost/intern/GHOST_DisplayManagerX11.cpp
@@ -117,7 +117,7 @@ getDisplaySetting(
if (dpy == NULL)
return GHOST_kFailure;
- (void) display;
+ (void)display;
#ifdef WITH_X11_XF86VMODE
int majorVersion, minorVersion;
@@ -149,6 +149,7 @@ getDisplaySetting(
GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n");
GHOST_ASSERT(index < 1, "Requested setting outside of valid range.\n");
+ (void)index;
setting.xPixels = DisplayWidth(dpy, DefaultScreen(dpy));
setting.yPixels = DisplayHeight(dpy, DefaultScreen(dpy));
@@ -267,6 +268,8 @@ setCurrentDisplaySetting(
return GHOST_kSuccess;
#else
+ (void)setting;
+
/* Just pretend the request was successful. */
return GHOST_kSuccess;
#endif
diff --git a/intern/ghost/intern/GHOST_SystemCocoa.h b/intern/ghost/intern/GHOST_SystemCocoa.h
index 3d6b40ee541..cfddd5b3781 100644
--- a/intern/ghost/intern/GHOST_SystemCocoa.h
+++ b/intern/ghost/intern/GHOST_SystemCocoa.h
@@ -297,9 +297,8 @@ protected:
*/
GHOST_TInt32 m_cursorDelta_x, m_cursorDelta_y;
- /** Multitouch trackpad availability */
- bool m_hasMultiTouchTrackpad;
-
+ /** Temporarily ignore momentum scroll events */
+ bool m_ignoreMomentumScroll;
};
#endif // __GHOST_SYSTEMCOCOA_H__
diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm
index b9686e5af9b..a3c48ff3b2d 100644
--- a/intern/ghost/intern/GHOST_SystemCocoa.mm
+++ b/intern/ghost/intern/GHOST_SystemCocoa.mm
@@ -284,7 +284,7 @@ extern "C" int GHOST_HACK_getFirstFile(char buf[FIRSTFILEBUFLG])
* CocoaAppDelegate
* ObjC object to capture applicationShouldTerminate, and send quit event
**/
-@interface CocoaAppDelegate : NSObject {
+@interface CocoaAppDelegate : NSObject <NSFileManagerDelegate> {
GHOST_SystemCocoa *systemCocoa;
}
- (void)setSystemCocoa:(GHOST_SystemCocoa *)sysCocoa;
@@ -370,12 +370,11 @@ GHOST_SystemCocoa::GHOST_SystemCocoa()
rstring = (char*)malloc( len );
sysctl( mib, 2, rstring, &len, NULL, 0 );
- m_hasMultiTouchTrackpad = false;
-
free( rstring );
rstring = NULL;
m_ignoreWindowSizedMessages = false;
+ m_ignoreMomentumScroll = false;
}
GHOST_SystemCocoa::~GHOST_SystemCocoa()
@@ -1223,10 +1222,10 @@ bool GHOST_SystemCocoa::handleTabletEvent(void *eventPtr)
NSEvent *event = (NSEvent *)eventPtr;
switch ([event subtype]) {
- case NX_SUBTYPE_TABLET_POINT:
+ case NSTabletPointEventSubtype:
handleTabletEvent(eventPtr, NSTabletPoint);
return true;
- case NX_SUBTYPE_TABLET_PROXIMITY:
+ case NSTabletProximityEventSubtype:
handleTabletEvent(eventPtr, NSTabletProximity);
return true;
default:
@@ -1317,6 +1316,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
GHOST_TInt32 x_warp, y_warp, x_accum, y_accum, x, y;
window->getCursorGrabInitPos(x_warp, y_warp);
+ window->screenToClientIntern(x_warp, y_warp, x_warp, y_warp);
window->getCursorGrabAccum(x_accum, y_accum);
x_accum += [event deltaX];
@@ -1368,6 +1368,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
//Post event
window->getCursorGrabInitPos(x_cur, y_cur);
+ window->screenToClientIntern(x_cur, y_cur, x_cur, y_cur);
window->clientToScreenIntern(x_cur + x_accum, y_cur + y_accum, x, y);
pushEvent(new GHOST_EventCursor([event timestamp] * 1000, GHOST_kEventCursorMove, window, x, y));
break;
@@ -1388,25 +1389,36 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
}
}
break;
-
- /* these events only happen on swiping trackpads or tablets */
- /* warning: using tablet + trackpad at same time frustrates this static variable */
- case NSEventTypeBeginGesture:
- m_hasMultiTouchTrackpad = 1;
- break;
- case NSEventTypeEndGesture:
- m_hasMultiTouchTrackpad = 0;
- break;
-
+
case NSScrollWheel:
{
- int *momentum = NULL;
+ NSEventPhase momentumPhase = NSEventPhaseNone;
+ NSEventPhase phase = NSEventPhaseNone;
+ bool hasMultiTouch = false;
if ([event respondsToSelector:@selector(momentumPhase)])
- momentum = (int *)[event momentumPhase];
+ momentumPhase = [event momentumPhase];
+ if ([event respondsToSelector:@selector(phase)])
+ phase = [event phase];
+ if ([event respondsToSelector:@selector(hasPreciseScrollingDeltas)])
+ hasMultiTouch = [event hasPreciseScrollingDeltas];
+
+ /* when pressing a key while momentum scrolling continues after
+ * lifting fingers off the trackpad, the action can unexpectedly
+ * change from e.g. scrolling to zooming. this works around the
+ * issue by ignoring momentum scroll after a key press */
+ if (momentumPhase)
+ {
+ if (m_ignoreMomentumScroll)
+ break;
+ }
+ else
+ {
+ m_ignoreMomentumScroll = false;
+ }
/* standard scrollwheel case, if no swiping happened, and no momentum (kinetic scroll) works */
- if (!m_hasMultiTouchTrackpad && momentum == NULL) {
+ if (!hasMultiTouch && momentumPhase == NSEventPhaseNone) {
GHOST_TInt32 delta;
double deltaF = [event deltaY];
@@ -1422,16 +1434,14 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
GHOST_TInt32 x, y;
double dx;
double dy;
-
+
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
- int phase = [event phase];
-
/* with 10.7 nice scrolling deltas are supported */
dx = [event scrollingDeltaX];
dy = [event scrollingDeltaY];
/* however, wacom tablet (intuos5) needs old deltas, it then has momentum and phase at zero */
- if (phase == 0 && momentum==NULL) {
+ if (phase == NSEventPhaseNone && momentumPhase == NSEventPhaseNone) {
dx = [event deltaX];
dy = [event deltaY];
}
@@ -1566,6 +1576,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleKeyEvent(void *eventPtr)
pushEvent( new GHOST_EventKey([event timestamp] * 1000, GHOST_kEventKeyUp, window, keyCode, 0, NULL) );
//printf("Key up rawCode=0x%x charsIgnoringModifiers=%c keyCode=%u ascii=%i %c utf8=%s\n",[event keyCode],[charsIgnoringModifiers length]>0?[charsIgnoringModifiers characterAtIndex:0]:' ',keyCode,ascii,ascii, utf8_buf);
}
+ m_ignoreMomentumScroll = true;
break;
case NSFlagsChanged:
@@ -1585,6 +1596,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleKeyEvent(void *eventPtr)
}
m_modifierMask = modifiers;
+ m_ignoreMomentumScroll = true;
break;
default:
diff --git a/intern/ghost/intern/GHOST_WindowCocoa.mm b/intern/ghost/intern/GHOST_WindowCocoa.mm
index f1f38cc14b3..38813e14a1b 100644
--- a/intern/ghost/intern/GHOST_WindowCocoa.mm
+++ b/intern/ghost/intern/GHOST_WindowCocoa.mm
@@ -393,16 +393,6 @@ enum {
systemCocoa->handleMouseEvent(event);
}
-- (void)beginGestureWithEvent:(NSEvent *)event
-{
- systemCocoa->handleMouseEvent(event);
-}
-
-- (void)endGestureWithEvent:(NSEvent *)event
-{
- systemCocoa->handleMouseEvent(event);
-}
-
- (void)tabletPoint:(NSEvent *)event
{
systemCocoa->handleTabletEvent(event,[event type]);
@@ -1195,18 +1185,18 @@ GHOST_Context *GHOST_WindowCocoa::newDrawingContext(GHOST_TDrawingContextType ty
#if defined(WITH_GL_PROFILE_CORE)
GHOST_Context *context = new GHOST_ContextCGL(
- m_initStereoVisual,
- m_initNumOfAASamples,
+ m_wantStereoVisual,
+ m_wantNumOfAASamples,
m_window,
m_openGLView,
- CGL_CONTEXT_OPENGL_CORE_PROFILE_BIT,
+ GL_CONTEXT_CORE_PROFILE_BIT,
3, 2,
GHOST_OPENGL_CGL_CONTEXT_FLAGS,
GHOST_OPENGL_CGL_RESET_NOTIFICATION_STRATEGY);
#elif defined(WITH_GL_PROFILE_ES20)
GHOST_Context *context = new GHOST_ContextCGL(
- m_initStereoVisual,
- m_initNumOfAASamples,
+ m_wantStereoVisual,
+ m_wantNumOfAASamples,
m_window,
m_openGLView,
CGL_CONTEXT_ES2_PROFILE_BIT_EXT,
@@ -1463,12 +1453,9 @@ GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorGrab(GHOST_TGrabCursorMode mode
if (mode != GHOST_kGrabDisable) {
//No need to perform grab without warp as it is always on in OS X
if (mode != GHOST_kGrabNormal) {
- GHOST_TInt32 x_old,y_old;
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- m_systemCocoa->getCursorPosition(x_old,y_old);
- screenToClientIntern(x_old, y_old, m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]);
- //Warp position is stored in client (window base) coordinates
+ m_systemCocoa->getCursorPosition(m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]);
setCursorGrabAccum(0, 0);
if (mode == GHOST_kGrabHide) {
@@ -1486,7 +1473,7 @@ GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorGrab(GHOST_TGrabCursorMode mode
}
else {
if (m_cursorGrab==GHOST_kGrabHide) {
- //No need to set again cursor position, as it has not changed for Cocoa
+ m_systemCocoa->setCursorPosition(m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]);
setWindowCursorVisibility(true);
}
diff --git a/intern/glew-mx/SConscript b/intern/glew-mx/SConscript
index 5c70958816c..546470d020c 100644
--- a/intern/glew-mx/SConscript
+++ b/intern/glew-mx/SConscript
@@ -5,9 +5,8 @@ import os
Import('env')
sources = ['intern/glew-mx.c']
-
-defs = env['BF_GL_DEFINITIONS']
-
+defs = []
+defs += env['BF_GL_DEFINITIONS']
incs = [
'.',
env['BF_GLEW_INC'],
diff --git a/intern/glew-mx/glew-mx.h b/intern/glew-mx/glew-mx.h
index 92450d67812..ed17ea4a0e6 100644
--- a/intern/glew-mx/glew-mx.h
+++ b/intern/glew-mx/glew-mx.h
@@ -95,8 +95,6 @@ MXContext *mxGetCurrentContext (void);
void mxMakeCurrentContext(MXContext *ctx);
void mxDestroyContext (MXContext *ctx);
-void mxIgnoreNoVersion(int ignore);
-
GLenum glew_chk(GLenum error, const char *file, int line, const char *text);
#ifndef NDEBUG
diff --git a/intern/glew-mx/intern/glew-mx.c b/intern/glew-mx/intern/glew-mx.c
index 78920670f68..6fbb1a7a2e2 100644
--- a/intern/glew-mx/intern/glew-mx.c
+++ b/intern/glew-mx/intern/glew-mx.c
@@ -34,8 +34,6 @@
#include <stdio.h>
#include <stdlib.h>
-static int ignore_version = 0;
-
#define CASE_CODE_RETURN_STR(code) case code: return #code;
static const char *get_glew_error_enum_string(GLenum error)
@@ -63,7 +61,7 @@ GLenum glew_chk(GLenum error, const char *file, int line, const char *text)
const char *code = get_glew_error_enum_string(error);
const char *msg = (const char *)glewGetErrorString(error);
- if (error == GLEW_ERROR_NO_GL_VERSION && ignore_version)
+ if (error == GLEW_ERROR_NO_GL_VERSION)
return GLEW_OK;
#ifndef NDEBUG
@@ -144,8 +142,3 @@ void mxDestroyContext(MXContext *ctx)
(void)ctx;
#endif
}
-
-void mxIgnoreNoVersion(int ignore)
-{
- ignore_version = ignore;
-}
diff --git a/intern/iksolver/intern/IK_Solver.cpp b/intern/iksolver/intern/IK_Solver.cpp
index 65ea4d64ab1..eb18cde3356 100644
--- a/intern/iksolver/intern/IK_Solver.cpp
+++ b/intern/iksolver/intern/IK_Solver.cpp
@@ -292,6 +292,7 @@ void IK_SolverAddGoal(IK_Solver *solver, IK_Segment *tip, float goal[3], float w
IK_QSolver *qsolver = (IK_QSolver *)solver;
IK_QSegment *qtip = (IK_QSegment *)tip;
+ // in case of composite segment the second segment is the tip
if (qtip->Composite())
qtip = qtip->Composite();
@@ -310,6 +311,7 @@ void IK_SolverAddGoalOrientation(IK_Solver *solver, IK_Segment *tip, float goal[
IK_QSolver *qsolver = (IK_QSolver *)solver;
IK_QSegment *qtip = (IK_QSegment *)tip;
+ // in case of composite segment the second segment is the tip
if (qtip->Composite())
qtip = qtip->Composite();
@@ -331,6 +333,10 @@ void IK_SolverSetPoleVectorConstraint(IK_Solver *solver, IK_Segment *tip, float
IK_QSolver *qsolver = (IK_QSolver *)solver;
IK_QSegment *qtip = (IK_QSegment *)tip;
+ // in case of composite segment the second segment is the tip
+ if (qtip->Composite())
+ qtip = qtip->Composite();
+
MT_Vector3 qgoal(goal);
MT_Vector3 qpolegoal(polegoal);
diff --git a/intern/opencolorio/SConscript b/intern/opencolorio/SConscript
index c2fb95a4d95..6be6a5ed90c 100644
--- a/intern/opencolorio/SConscript
+++ b/intern/opencolorio/SConscript
@@ -30,7 +30,9 @@ Import('env')
sources = env.Glob('*.cc')
incs = '. ../guardedalloc ../../source/blender/blenlib'
-defs = env['BF_GL_DEFINITIONS']
+defs = []
+
+defs += env['BF_GL_DEFINITIONS']
if env['WITH_BF_OCIO']:
defs.append('WITH_OCIO')
diff --git a/intern/opensubdiv/CMakeLists.txt b/intern/opensubdiv/CMakeLists.txt
index fceaeb94af9..a4dfe339728 100644
--- a/intern/opensubdiv/CMakeLists.txt
+++ b/intern/opensubdiv/CMakeLists.txt
@@ -47,7 +47,6 @@ set(SRC
opensubdiv_device_context_cuda.h
opensubdiv_device_context_opencl.h
opensubdiv_intern.h
- opensubdiv_partitioned.h
)
if(WITH_SUBSURF_WERROR)
diff --git a/intern/opensubdiv/SConscript b/intern/opensubdiv/SConscript
index 58926c6a94a..0532bae1c29 100644
--- a/intern/opensubdiv/SConscript
+++ b/intern/opensubdiv/SConscript
@@ -48,16 +48,18 @@ def checkOpenSubdivHeaderDefine(header, define):
return True
return False
-checkOpenSubdivHeaderDefine("tbbComputeController.h", 'OPENSUBDIV_HAS_TBB')
-checkOpenSubdivHeaderDefine("gcdComputeController.h", 'OPENSUBDIV_HAS_GCD')
-if checkOpenSubdivHeaderDefine("clComputeController.h", 'OPENSUBDIV_HAS_OPENCL'):
- defs += ['OPENSUBDIV_HAS_CLEW']
- incs += ' #/extern/clew/include'
-if checkOpenSubdivHeaderDefine("cudaComputeController.h", 'OPENSUBDIV_HAS_CUDA'):
- defs += ['OPENSUBDIV_HAS_CUEW']
- incs += ' #/extern/cuew/include'
-checkOpenSubdivHeaderDefine("glslTransformFeedbackComputeController.h", 'OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK')
-checkOpenSubdivHeaderDefine("osd/glslComputeController.h", 'OPENSUBDIV_HAS_GLSL_COMPUTE')
+checkOpenSubdivHeaderDefine("tbbEvaluator.h", 'OPENSUBDIV_HAS_TBB')
+#if checkOpenSubdivHeaderDefine("clEvaluator.h", 'OPENSUBDIV_HAS_OPENCL'):
+# defs += ['OPENSUBDIV_HAS_CLEW']
+# incs += ' #/extern/clew/include'
+#if checkOpenSubdivHeaderDefine("cudaEvaluator.h", 'OPENSUBDIV_HAS_CUDA'):
+# defs += ['OPENSUBDIV_HAS_CUEW']
+# incs += ' #/extern/cuew/include'
+checkOpenSubdivHeaderDefine("glXFBEvaluator.h", 'OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK')
+checkOpenSubdivHeaderDefine("glComputeEvaluator.h", 'OPENSUBDIV_HAS_GLSL_COMPUTE')
+
+if env['WITH_BF_LIBMV']:
+ defs += ['OPENSUBDIV_HAS_OPENMP']
# generated data files
sources.extend((
diff --git a/intern/opensubdiv/gpu_shader_opensubd_display.glsl b/intern/opensubdiv/gpu_shader_opensubd_display.glsl
index fb46971bce8..e2574b5989e 100644
--- a/intern/opensubdiv/gpu_shader_opensubd_display.glsl
+++ b/intern/opensubdiv/gpu_shader_opensubd_display.glsl
@@ -28,6 +28,7 @@
#extension GL_EXT_geometry_shader4 : enable
#extension GL_ARB_gpu_shader5 : enable
#extension GL_ARB_explicit_attrib_location : require
+#extension GL_ARB_uniform_buffer_object : require
struct VertexData {
vec4 position;
@@ -51,6 +52,10 @@ void main()
{
outpt.v.position = modelViewMatrix * position;
outpt.v.normal = normalize(normalMatrix * normal);
+ /* Some compilers expects gl_Position to be written.
+ * It's not needed once we explicitly switch to GLSL 1.40 or above.
+ */
+ gl_Position = outpt.v.position;
}
#endif /* VERTEX_SHADER */
@@ -197,15 +202,17 @@ struct LightSource {
vec4 diffuse;
vec4 specular;
vec4 spotDirection;
+#ifdef SUPPORT_COLOR_MATERIAL
float constantAttenuation;
float linearAttenuation;
float quadraticAttenuation;
float spotCutoff;
float spotExponent;
float spotCosCutoff;
+#endif
};
-uniform Lighting {
+layout(std140) uniform Lighting {
LightSource lightSource[MAX_LIGHTS];
int num_enabled_lights;
};
@@ -215,8 +222,6 @@ uniform vec4 specular;
uniform float shininess;
uniform sampler2D texture_buffer;
-uniform bool use_color_material;
-uniform bool use_texture_2d;
in block {
VertexData v;
@@ -236,99 +241,92 @@ void main()
vec3 L_diffuse = vec3(0.0);
vec3 L_specular = vec3(0.0);
- if (use_color_material == false) {
- /* Assume NUM_SOLID_LIGHTS directional lights. */
- for (int i = 0; i < NUM_SOLID_LIGHTS; i++) {
- vec3 light_direction = lightSource[i].position.xyz;
-
- /* Diffuse light. */
- vec3 light_diffuse = lightSource[i].diffuse.rgb;
- float diffuse_bsdf = max(dot(N, light_direction), 0.0);
- L_diffuse += light_diffuse * diffuse_bsdf;
-
- vec4 Plight = lightSource[i].position;
- vec3 l = (Plight.w == 0.0)
- ? normalize(Plight.xyz) : normalize(Plight.xyz -
- inpt.v.position.xyz);
+#ifndef USE_COLOR_MATERIAL
+ /* Assume NUM_SOLID_LIGHTS directional lights. */
+ for (int i = 0; i < NUM_SOLID_LIGHTS; i++) {
+ vec4 Plight = lightSource[i].position;
+#ifdef USE_DIRECTIONAL_LIGHT
+ vec3 l = (Plight.w == 0.0)
+ ? normalize(Plight.xyz)
+ : normalize(inpt.v.position.xyz);
+#else /* USE_DIRECTIONAL_LIGHT */
+ /* TODO(sergey): We can normalize it outside of the shader. */
+ vec3 l = normalize(Plight.xyz);
+#endif /* USE_DIRECTIONAL_LIGHT */
+ vec3 h = normalize(l + vec3(0, 0, 1));
+ float d = max(0.0, dot(N, l));
+ float s = pow(max(0.0, dot(N, h)), shininess);
+ L_diffuse += d * lightSource[i].diffuse.rgb;
+ L_specular += s * lightSource[i].specular.rgb;
+ }
+#else /* USE_COLOR_MATERIAL */
+ vec3 varying_position = inpt.v.position.xyz;
+ vec3 V = (gl_ProjectionMatrix[3][3] == 0.0) ?
+ normalize(varying_position): vec3(0.0, 0.0, -1.0);
+ for (int i = 0; i < num_enabled_lights; i++) {
+ /* todo: this is a slow check for disabled lights */
+ if (lightSource[i].specular.a == 0.0)
+ continue;
+
+ float intensity = 1.0;
+ vec3 light_direction;
+
+ if (lightSource[i].position.w == 0.0) {
+ /* directional light */
+ light_direction = lightSource[i].position.xyz;
+ }
+ else {
+ /* point light */
+ vec3 d = lightSource[i].position.xyz - varying_position;
+ light_direction = normalize(d);
+
+ /* spot light cone */
+ if (lightSource[i].spotCutoff < 90.0) {
+ float cosine = max(dot(light_direction,
+ -lightSource[i].spotDirection.xyz),
+ 0.0);
+ intensity = pow(cosine, lightSource[i].spotExponent);
+ intensity *= step(lightSource[i].spotCosCutoff, cosine);
+ }
- /* Specular light. */
- vec3 light_specular = lightSource[i].specular.rgb;
- vec3 H = normalize(l + vec3(0,0,1));
+ /* falloff */
+ float distance = length(d);
- float specular_bsdf = pow(max(dot(N, H), 0.0),
- shininess);
- L_specular += light_specular * specular_bsdf;
+ intensity /= lightSource[i].constantAttenuation +
+ lightSource[i].linearAttenuation * distance +
+ lightSource[i].quadraticAttenuation * distance * distance;
}
- }
- else {
- vec3 varying_position = inpt.v.position.xyz;
- vec3 V = (gl_ProjectionMatrix[3][3] == 0.0) ?
- normalize(varying_position): vec3(0.0, 0.0, -1.0);
- for (int i = 0; i < num_enabled_lights; i++) {
- /* todo: this is a slow check for disabled lights */
- if (lightSource[i].specular.a == 0.0)
- continue;
-
- float intensity = 1.0;
- vec3 light_direction;
-
- if (lightSource[i].position.w == 0.0) {
- /* directional light */
- light_direction = lightSource[i].position.xyz;
- }
- else {
- /* point light */
- vec3 d = lightSource[i].position.xyz - varying_position;
- light_direction = normalize(d);
-
- /* spot light cone */
- if (lightSource[i].spotCutoff < 90.0) {
- float cosine = max(dot(light_direction,
- -lightSource[i].spotDirection.xyz),
- 0.0);
- intensity = pow(cosine, lightSource[i].spotExponent);
- intensity *= step(lightSource[i].spotCosCutoff, cosine);
- }
-
- /* falloff */
- float distance = length(d);
-
- intensity /= lightSource[i].constantAttenuation +
- lightSource[i].linearAttenuation * distance +
- lightSource[i].quadraticAttenuation * distance * distance;
- }
- /* diffuse light */
- vec3 light_diffuse = lightSource[i].diffuse.rgb;
- float diffuse_bsdf = max(dot(N, light_direction), 0.0);
- L_diffuse += light_diffuse*diffuse_bsdf*intensity;
+ /* diffuse light */
+ vec3 light_diffuse = lightSource[i].diffuse.rgb;
+ float diffuse_bsdf = max(dot(N, light_direction), 0.0);
+ L_diffuse += light_diffuse*diffuse_bsdf*intensity;
- /* specular light */
- vec3 light_specular = lightSource[i].specular.rgb;
- vec3 H = normalize(light_direction - V);
+ /* specular light */
+ vec3 light_specular = lightSource[i].specular.rgb;
+ vec3 H = normalize(light_direction - V);
- float specular_bsdf = pow(max(dot(N, H), 0.0),
- gl_FrontMaterial.shininess);
- L_specular += light_specular*specular_bsdf * intensity;
- }
+ float specular_bsdf = pow(max(dot(N, H), 0.0),
+ gl_FrontMaterial.shininess);
+ L_specular += light_specular*specular_bsdf * intensity;
}
+#endif /* USE_COLOR_MATERIAL */
/* Compute diffuse color. */
- float alpha;
- if (use_texture_2d) {
- L_diffuse *= texture2D(texture_buffer, inpt.v.uv).rgb;
- }
- else {
- L_diffuse *= diffuse.rgb;
- }
- alpha = diffuse.a;
+#ifdef USE_TEXTURE_2D
+ L_diffuse *= texture2D(texture_buffer, inpt.v.uv).rgb;
+#else
+ L_diffuse *= diffuse.rgb;
+#endif
/* Sum lighting. */
- vec3 L = /*gl_FrontLightModelProduct.sceneColor.rgb +*/ L_diffuse;
- L += L_specular * specular.rgb;
+ vec3 L = L_diffuse;
+ if (shininess != 0) {
+ L += L_specular * specular.rgb;
+ }
/* Write out fragment color. */
- gl_FragColor = vec4(L, alpha);
+ gl_FragColor = vec4(L, diffuse.a);
#endif
}
diff --git a/intern/opensubdiv/opensubdiv_capi.cc b/intern/opensubdiv/opensubdiv_capi.cc
index e3bc5891c45..66598948daf 100644
--- a/intern/opensubdiv/opensubdiv_capi.cc
+++ b/intern/opensubdiv/opensubdiv_capi.cc
@@ -30,6 +30,7 @@
# include "iso646.h"
#endif
+#include <stdlib.h>
#include <GL/glew.h>
#include <opensubdiv/osd/glMesh.h>
@@ -68,7 +69,6 @@
#include <opensubdiv/far/stencilTable.h>
#include "opensubdiv_intern.h"
-#include "opensubdiv_partitioned.h"
#include "MEM_guardedalloc.h"
@@ -80,22 +80,22 @@ using OpenSubdiv::Osd::MeshBitset;
using OpenSubdiv::Far::StencilTable;
using OpenSubdiv::Osd::GLPatchTable;
-using OpenSubdiv::Osd::PartitionedMesh;
+using OpenSubdiv::Osd::Mesh;
/* CPU backend */
using OpenSubdiv::Osd::CpuGLVertexBuffer;
using OpenSubdiv::Osd::CpuEvaluator;
-typedef PartitionedMesh<CpuGLVertexBuffer,
- StencilTable,
- CpuEvaluator,
- GLPatchTable> OsdCpuMesh;
+typedef Mesh<CpuGLVertexBuffer,
+ StencilTable,
+ CpuEvaluator,
+ GLPatchTable> OsdCpuMesh;
#ifdef OPENSUBDIV_HAS_OPENMP
using OpenSubdiv::Osd::OmpEvaluator;
-typedef PartitionedMesh<CpuGLVertexBuffer,
- StencilTable,
- OmpEvaluator,
- GLPatchTable> OsdOmpMesh;
+typedef Mesh<CpuGLVertexBuffer,
+ StencilTable,
+ OmpEvaluator,
+ GLPatchTable> OsdOmpMesh;
#endif /* OPENSUBDIV_HAS_OPENMP */
#ifdef OPENSUBDIV_HAS_OPENCL
@@ -103,11 +103,11 @@ using OpenSubdiv::Osd::CLEvaluator;
using OpenSubdiv::Osd::CLGLVertexBuffer;
using OpenSubdiv::Osd::CLStencilTable;
/* TODO(sergey): Use CLDeviceCOntext similar to OSD examples? */
-typedef PartitionedMesh<CLGLVertexBuffer,
- CLStencilTable,
- CLEvaluator,
- GLPatchTable,
- CLDeviceContext> OsdCLMesh;
+typedef Mesh<CLGLVertexBuffer,
+ CLStencilTable,
+ CLEvaluator,
+ GLPatchTable,
+ CLDeviceContext> OsdCLMesh;
static CLDeviceContext g_clDeviceContext;
#endif /* OPENSUBDIV_HAS_OPENCL */
@@ -115,10 +115,10 @@ static CLDeviceContext g_clDeviceContext;
using OpenSubdiv::Osd::CudaEvaluator;
using OpenSubdiv::Osd::CudaGLVertexBuffer;
using OpenSubdiv::Osd::CudaStencilTable;
-typedef PartitionedMesh<CudaGLVertexBuffer,
- CudaStencilTable,
- CudaEvaluator,
- GLPatchTable> OsdCudaMesh;
+typedef Mesh<CudaGLVertexBuffer,
+ CudaStencilTable,
+ CudaEvaluator,
+ GLPatchTable> OsdCudaMesh;
static CudaDeviceContext g_cudaDeviceContext;
#endif /* OPENSUBDIV_HAS_CUDA */
@@ -126,20 +126,20 @@ static CudaDeviceContext g_cudaDeviceContext;
using OpenSubdiv::Osd::GLXFBEvaluator;
using OpenSubdiv::Osd::GLStencilTableTBO;
using OpenSubdiv::Osd::GLVertexBuffer;
-typedef PartitionedMesh<GLVertexBuffer,
- GLStencilTableTBO,
- GLXFBEvaluator,
- GLPatchTable> OsdGLSLTransformFeedbackMesh;
+typedef Mesh<GLVertexBuffer,
+ GLStencilTableTBO,
+ GLXFBEvaluator,
+ GLPatchTable> OsdGLSLTransformFeedbackMesh;
#endif /* OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK */
#ifdef OPENSUBDIV_HAS_GLSL_COMPUTE
using OpenSubdiv::Osd::GLComputeEvaluator;
using OpenSubdiv::Osd::GLStencilTableSSBO;
using OpenSubdiv::Osd::GLVertexBuffer;
-typedef PartitionedMesh<GLVertexBuffer,
- GLStencilTableSSBO,
- GLComputeEvaluator,
- GLPatchTable> OsdGLSLComputeMesh;
+typedef Mesh<GLVertexBuffer,
+ GLStencilTableSSBO,
+ GLComputeEvaluator,
+ GLPatchTable> OsdGLSLComputeMesh;
#endif
struct OpenSubdiv_GLMesh *openSubdiv_createOsdGLMeshFromTopologyRefiner(
@@ -156,14 +156,12 @@ struct OpenSubdiv_GLMesh *openSubdiv_createOsdGLMeshFromTopologyRefiner(
*/
bits.set(OpenSubdiv::Osd::MeshAdaptive, 0);
bits.set(OpenSubdiv::Osd::MeshUseSingleCreasePatch, 0);
- bits.set(OpenSubdiv::Osd::MeshInterleaveVarying, 0);
+ bits.set(OpenSubdiv::Osd::MeshInterleaveVarying, 1);
bits.set(OpenSubdiv::Osd::MeshFVarData, 1);
bits.set(OpenSubdiv::Osd::MeshEndCapBSplineBasis, 1);
- // bits.set(Osd::MeshEndCapGregoryBasis, 1);
- // bits.set(Osd::MeshEndCapLegacyGregory, 1);
- const int num_vertex_elements = 6;
- const int num_varying_elements = 0;
+ const int num_vertex_elements = 3;
+ const int num_varying_elements = 3;
GLMeshInterface *mesh = NULL;
TopologyRefiner *refiner = (TopologyRefiner*)topology_refiner;
@@ -297,7 +295,29 @@ const struct OpenSubdiv_TopologyRefinerDescr *openSubdiv_getGLMeshTopologyRefine
int openSubdiv_supportGPUDisplay(void)
{
- return GL_EXT_geometry_shader4 &&
- GL_ARB_gpu_shader5 &&
- glProgramParameteriEXT;
+ {
+ /* Currently Intel GPUs has hard time working on Windows.
+ *
+ * For until we've got access to a hardware which demonstrates
+ * the issue we disable OpenSubdiv on Intel GPUs.
+ */
+ static bool vendor_checked = false;
+ static bool is_intel = false;
+ if (!vendor_checked) {
+ vendor_checked = true;
+ const char *vendor = (const char *)glGetString(GL_VENDOR);
+ if (vendor != NULL && strstr(vendor, "Intel")) {
+ if(getenv("OPENSUBDIV_ALLOW_INTEL") == NULL) {
+ is_intel = true;
+ }
+ }
+ }
+ if (is_intel) {
+ return false;
+ }
+ }
+
+ return GLEW_EXT_geometry_shader4 &&
+ GLEW_ARB_gpu_shader5 &&
+ GLEW_ARB_uniform_buffer_object;
}
diff --git a/intern/opensubdiv/opensubdiv_capi.h b/intern/opensubdiv/opensubdiv_capi.h
index c86e739f12b..8010c39647d 100644
--- a/intern/opensubdiv/opensubdiv_capi.h
+++ b/intern/opensubdiv/opensubdiv_capi.h
@@ -85,7 +85,7 @@ const struct OpenSubdiv_TopologyRefinerDescr *openSubdiv_getGLMeshTopologyRefine
OpenSubdiv_GLMesh *gl_mesh);
/* ** Initialize/Deinitialize global OpenGL drawing buffers/GLSL programs ** */
-void openSubdiv_osdGLDisplayInit(void);
+bool openSubdiv_osdGLDisplayInit(void);
void openSubdiv_osdGLDisplayDeinit(void);
/* ** Evaluator API ** */
@@ -132,15 +132,16 @@ void openSubdiv_evaluateVarying(OpenSubdiv_EvaluatorDescr *evaluator_descr,
void openSubdiv_osdGLMeshDisplayPrepare(int use_osd_glsl,
int active_uv_index);
-/* Draw patches which corresponds to a given partition. */
+/* Draw specified patches. */
void openSubdiv_osdGLMeshDisplay(OpenSubdiv_GLMesh *gl_mesh,
int fill_quads,
- int start_partition,
- int num_partitions);
+ int start_patch,
+ int num_patches);
/* ** Utility functions ** */
int openSubdiv_supportGPUDisplay(void);
int openSubdiv_getAvailableEvaluators(void);
+void openSubdiv_init(void);
void openSubdiv_cleanup(void);
#ifdef __cplusplus
diff --git a/intern/opensubdiv/opensubdiv_converter.cc b/intern/opensubdiv/opensubdiv_converter.cc
index 119a7bf9340..3fadde68d32 100644
--- a/intern/opensubdiv/opensubdiv_converter.cc
+++ b/intern/opensubdiv/opensubdiv_converter.cc
@@ -37,6 +37,21 @@
#include <stack>
+#ifdef OPENSUBDIV_ORIENT_TOPOLOGY
+namespace {
+
+inline void reverse_face_verts(int *face_verts, int num_verts)
+{
+ int last_vert = face_verts[num_verts - 1];
+ for (int i = num_verts - 1; i > 0; --i) {
+ face_verts[i] = face_verts[i - 1];
+ }
+ face_verts[0] = last_vert;
+}
+
+} /* namespace */
+#endif /* OPENSUBDIV_ORIENT_TOPOLOGY */
+
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {
namespace Far {
@@ -49,22 +64,77 @@ inline int findInArray(T array, int value)
return (int)(std::find(array.begin(), array.end(), value) - array.begin());
}
-} /* namespace */
+#ifdef OPENSUBDIV_ORIENT_TOPOLOGY
+inline int get_loop_winding(int vert0_of_face, int vert1_of_face)
+{
+ int delta_face = vert1_of_face - vert0_of_face;
+ if (abs(delta_face) != 1) {
+ if (delta_face > 0) {
+ delta_face = -1;
+ }
+ else {
+ delta_face = 1;
+ }
+ }
+ return delta_face;
+}
-struct StackElem {
- StackElem(int face_start,
- int edge_start,
- int face_vert_start,
- bool append_start_edge = true)
- : face_start(face_start),
- edge_start(edge_start),
- face_vert_start(face_vert_start),
- append_start_edge(append_start_edge){}
- int face_start;
- int edge_start;
- int face_vert_start;
- bool append_start_edge;
-};
+inline void reverse_face_loops(IndexArray face_verts, IndexArray face_edges)
+{
+ for (int i = 0; i < face_verts.size() / 2; ++i) {
+ int j = face_verts.size() - i - 1;
+ if (i != j) {
+ std::swap(face_verts[i], face_verts[j]);
+ std::swap(face_edges[i], face_edges[j]);
+ }
+ }
+ reverse_face_verts(&face_verts[0], face_verts.size());
+}
+
+inline void check_oriented_vert_connectivity(const int num_vert_edges,
+ const int num_vert_faces,
+ const int *vert_edges,
+ const int *vert_faces,
+ const int *dst_vert_edges,
+ const int *dst_vert_faces)
+{
+# ifndef NDEBUG
+ for (int i = 0; i < num_vert_faces; ++i) {
+ bool found = false;
+ for (int j = 0; j < num_vert_faces; ++j) {
+ if (vert_faces[i] == dst_vert_faces[j]) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ assert(!"vert-faces connectivity ruined");
+ }
+ }
+ for (int i = 0; i < num_vert_edges; ++i) {
+ bool found = false;
+ for (int j = 0; j < num_vert_edges; ++j) {
+ if (vert_edges[i] == dst_vert_edges[j]) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ assert(!"vert-edges connectivity ruined");
+ }
+ }
+# else
+ (void)num_vert_edges;
+ (void)num_vert_faces;
+ (void)vert_edges;
+ (void)vert_faces;
+ (void)dst_vert_edges;
+ (void)dst_vert_faces;
+# endif
+}
+#endif
+
+} /* namespace */
template <>
inline bool TopologyRefinerFactory<OpenSubdiv_Converter>::resizeComponentTopology(
@@ -121,9 +191,73 @@ inline bool TopologyRefinerFactory<OpenSubdiv_Converter>::assignComponentTopolog
IndexArray dst_edge_faces = getBaseEdgeFaces(refiner, edge);
conv.get_edge_faces(&conv, edge, &dst_edge_faces[0]);
}
+#ifdef OPENSUBDIV_ORIENT_TOPOLOGY
+ /* Make face normals consistent. */
+ bool *face_used = new bool[num_faces];
+ memset(face_used, 0, sizeof(bool) * num_faces);
+ std::stack<int> traverse_stack;
+ int face_start = 0, num_traversed_faces = 0;
+ /* Traverse all islands. */
+ while (num_traversed_faces != num_faces) {
+ /* Find first face of any untraversed islands. */
+ while (face_used[face_start]) {
+ ++face_start;
+ }
+ /* Add first face to the stack. */
+ traverse_stack.push(face_start);
+ face_used[face_start] = true;
+ /* Go over whole connected component. */
+ while (!traverse_stack.empty()) {
+ int face = traverse_stack.top();
+ traverse_stack.pop();
+ IndexArray face_edges = getBaseFaceEdges(refiner, face);
+ ConstIndexArray face_verts = getBaseFaceVertices(refiner, face);
+ for (int edge_index = 0; edge_index < face_edges.size(); ++edge_index) {
+ const int edge = face_edges[edge_index];
+ ConstIndexArray edge_faces = getBaseEdgeFaces(refiner, edge);
+ if (edge_faces.size() != 2) {
+ /* Can't make consistent normals for non-manifolds. */
+ continue;
+ }
+ ConstIndexArray edge_verts = getBaseEdgeVertices(refiner, edge);
+ /* Get winding of the reference face. */
+ int vert0_of_face = findInArray(face_verts, edge_verts[0]),
+ vert1_of_face = findInArray(face_verts, edge_verts[1]);
+ int delta_face = get_loop_winding(vert0_of_face, vert1_of_face);
+ for (int edge_face = 0; edge_face < edge_faces.size(); ++edge_face) {
+ int other_face = edge_faces[edge_face];
+ /* Never re-traverse faces, only move forward. */
+ if (face_used[other_face]) {
+ continue;
+ }
+ IndexArray other_face_verts = getBaseFaceVertices(refiner,
+ other_face);
+ int vert0_of_other_face = findInArray(other_face_verts,
+ edge_verts[0]),
+ vert1_of_other_face = findInArray(other_face_verts,
+ edge_verts[1]);
+ int delta_other_face = get_loop_winding(vert0_of_other_face,
+ vert1_of_other_face);
+ if (delta_face * delta_other_face > 0) {
+ IndexArray other_face_verts = getBaseFaceVertices(refiner,
+ other_face),
+ other_face_edges = getBaseFaceEdges(refiner,
+ other_face);
+ reverse_face_loops(other_face_verts,
+ other_face_edges);
+ }
+ traverse_stack.push(other_face);
+ face_used[other_face] = true;
+ }
+ }
+ ++num_traversed_faces;
+ }
+ }
+#endif /* OPENSUBDIV_ORIENT_TOPOLOGY */
/* Vertex relations */
const int num_verts = conv.get_num_verts(&conv);
for (int vert = 0; vert < num_verts; ++vert) {
+
/* Vert-Faces */
IndexArray dst_vert_faces = getBaseVertexFaces(refiner, vert);
int num_vert_faces = conv.get_num_vert_faces(&conv, vert);
@@ -135,56 +269,101 @@ inline bool TopologyRefinerFactory<OpenSubdiv_Converter>::assignComponentTopolog
int *vert_edges = new int[num_vert_edges];
conv.get_vert_edges(&conv, vert, vert_edges);
#ifdef OPENSUBDIV_ORIENT_TOPOLOGY
- /* Order vertex edges and faces in a CCW order. */
- /* TODO(sergey): Look into possible optimizations here. */
- bool *face_used = new bool[num_faces];
+ /* ** Order vertex edges and faces in a CCW order. ** */
memset(face_used, 0, sizeof(bool) * num_faces);
- std::stack<StackElem> stack;
+ /* Number of edges and faces added to the ordered array. */
int edge_count_ordered = 0, face_count_ordered = 0;
- if (num_vert_edges == num_vert_faces) {
- /* Manifold vertex, start with any face and perform traversal. */
- int face_start = vert_faces[0];
- int face_vert_start = findInArray(getBaseFaceVertices(refiner, face_start), vert);
- int edge_start = getBaseFaceEdges(refiner, face_start)[face_vert_start];
- stack.push(StackElem(face_start, edge_start, face_vert_start));
+ /* Add loose edges straight into the edges array. */
+ bool has_fan_connections = false;
+ for (int i = 0; i < num_vert_edges; ++i) {
+ IndexArray edge_faces = getBaseEdgeFaces(refiner, vert_edges[i]);
+ if (edge_faces.size() == 0) {
+ dst_vert_edges[edge_count_ordered++] = vert_edges[i];
+ }
+ else if (edge_faces.size() > 2) {
+ has_fan_connections = true;
+ }
}
- else {
- /* ** Non-manifold vertex. Special handle here. ** */
- /* Add all loose edges adjacent to the vertex. */
- for (int i = 0; i < num_vert_edges; ++i) {
- IndexArray edge_faces = getBaseEdgeFaces(refiner, vert_edges[i]);
- if (edge_faces.size() == 0) {
- /* Can't really orient loose edges, just add then straight
- * to the vert-edges array.
- */
- dst_vert_edges[edge_count_ordered++] = vert_edges[i];
+ if (has_fan_connections) {
+ /* OpenSubdiv currently doesn't give us clues how to handle
+ * fan face connections. and since handling such connections
+ * complicates the loop below we simply don't do special
+ * orientation for them.
+ */
+ memcpy(&dst_vert_edges[0], vert_edges, sizeof(int) * num_vert_edges);
+ memcpy(&dst_vert_faces[0], vert_faces, sizeof(int) * num_vert_faces);
+ delete [] vert_edges;
+ delete [] vert_faces;
+ continue;
+ }
+ /* Perform at max numbder of vert-edges iteration and try to avoid
+ * deadlock here for malformed mesh.
+ */
+ for (int global_iter = 0; global_iter < num_vert_edges; ++global_iter) {
+ /* Numbr of edges and faces which are still to be ordered. */
+ int num_vert_edges_remained = num_vert_edges - edge_count_ordered,
+ num_vert_faces_remained = num_vert_faces - face_count_ordered;
+ if (num_vert_edges_remained == 0 && num_vert_faces_remained == 0) {
+ /* All done, nothing to do anymore. */
+ break;
+ }
+ /* Face, edge and face-vertex inndex to start traversal from. */
+ int face_start = -1, edge_start = -1, face_vert_start = -1;
+ if (num_vert_edges_remained == num_vert_faces_remained) {
+ /* Vertex is eitehr complete manifold or is connected to seevral
+ * manifold islands (hourglass-like configuration), can pick up
+ * random edge unused and start from it.
+ */
+ /* TODO(sergey): Start from previous edge from which traversal
+ * began at previous iteration.
+ */
+ for (int i = 0; i < num_vert_edges; ++i) {
+ face_start = vert_faces[i];
+ if (!face_used[face_start]) {
+ ConstIndexArray
+ face_verts = getBaseFaceVertices(refiner, face_start),
+ face_edges = getBaseFaceEdges(refiner, face_start);
+ face_vert_start = findInArray(face_verts, vert);
+ edge_start = face_edges[face_vert_start];
+ break;
+ }
}
- else if (edge_faces.size() == 1) {
- int edge_start = vert_edges[i];
- int face_start = edge_faces[0];
- int face_vert_start = findInArray(getBaseFaceVertices(refiner, face_start), vert);
- if (edge_start == (getBaseFaceEdges(refiner, face_start)[face_vert_start])) {
- stack.push(StackElem(face_start, edge_start, face_vert_start));
- face_used[face_start] = true;
+ }
+ else {
+ /* Special handle of non-manifold vertex. */
+ for (int i = 0; i < num_vert_edges; ++i) {
+ bool start_found = false;
+ edge_start = vert_edges[i];
+ IndexArray edge_faces = getBaseEdgeFaces(refiner, edge_start);
+ if (edge_faces.size() == 1) {
+ face_start = edge_faces[0];
+ if (!face_used[face_start]) {
+ ConstIndexArray
+ face_verts = getBaseFaceVertices(refiner, face_start),
+ face_edges = getBaseFaceEdges(refiner, face_start);
+ face_vert_start = findInArray(face_verts, vert);
+ if (edge_start == face_edges[face_vert_start]) {
+ start_found = true;
+ break;
+ }
+ }
}
+ if (start_found) {
+ break;
+ }
+ /* Reset indices for sanity check below. */
+ face_start = edge_start = face_vert_start = -1;
}
}
- }
- while (!stack.empty()) {
- StackElem& top = stack.top();
- int edge_start = top.edge_start;
- int face_start = top.face_start;
- int face_vert_start = top.face_vert_start;
- bool append_start_edge = top.append_start_edge;
- stack.pop();
- Index edge_first = edge_start;
-
+ /* Sanity check. */
+ assert(face_start != -1 &&
+ edge_start != -1 &&
+ face_vert_start != -1);
+ /* Traverse faces starting from the current one. */
+ int edge_first = edge_start;
dst_vert_faces[face_count_ordered++] = face_start;
- if (append_start_edge) {
- dst_vert_edges[edge_count_ordered++] = edge_start;
- }
+ dst_vert_edges[edge_count_ordered++] = edge_start;
face_used[face_start] = true;
-
while (edge_count_ordered < num_vert_edges) {
IndexArray face_verts = getBaseFaceVertices(refiner, face_start);
IndexArray face_edges = getBaseFaceEdges(refiner, face_start);
@@ -192,24 +371,9 @@ inline bool TopologyRefinerFactory<OpenSubdiv_Converter>::assignComponentTopolog
int face_edge_next = (face_edge_start > 0) ? (face_edge_start - 1) : (face_verts.size() - 1);
Index edge_next = face_edges[face_edge_next];
if (edge_next == edge_first) {
- /* TODO(sergey): Find more generic solution so non-manifold
- * edges combined with some manifold adjacent geometry is
- * handled correct.
+ /* Multiple manifolds found, stop for now and handle rest
+ * in the next iteration.
*/
- if (num_vert_edges == num_vert_faces &&
- edge_count_ordered != num_vert_edges)
- {
- IndexArray edge_faces = getBaseEdgeFaces(refiner, edge_next);
- for (int i = 0; i < num_vert_faces; ++i) {
- int face_start = edge_faces[i];
- if (!face_used[face_start]) {
- int edge_start = edge_next;
- int face_vert_start = findInArray(getBaseFaceVertices(refiner, face_start), vert);
- stack.push(StackElem(face_start, edge_start, face_vert_start, false));
- break;
- }
- }
- }
break;
}
dst_vert_edges[edge_count_ordered++] = edge_next;
@@ -221,16 +385,6 @@ inline bool TopologyRefinerFactory<OpenSubdiv_Converter>::assignComponentTopolog
break;
}
else if (edge_faces.size() != 2) {
- for (int i = 0; i < edge_faces.size(); ++i) {
- if (edge_faces[i] != face_start) {
- int face_start = edge_faces[i];
- if (!face_used[face_start]) {
- int edge_start = edge_next;
- int face_vert_start = findInArray(getBaseFaceVertices(refiner, face_start), vert);
- stack.push(StackElem(face_start, edge_start, face_vert_start, false));
- }
- }
- }
break;
}
assert(edge_faces.size() == 2);
@@ -242,45 +396,36 @@ inline bool TopologyRefinerFactory<OpenSubdiv_Converter>::assignComponentTopolog
edge_start = edge_next;
}
}
- delete [] face_used;
-
/* Verify ordering doesn't ruin connectivity information. */
assert(face_count_ordered == num_vert_faces);
assert(edge_count_ordered == num_vert_edges);
-#ifndef NDEBUG
- for (int i = 0; i < num_vert_faces; ++i) {
- bool found = false;
- for (int j = 0; j < num_vert_faces; ++j) {
- if (vert_faces[i] == dst_vert_faces[j]) {
- found = true;
- break;
- }
- }
- if (!found) {
- assert(!"vert-faces connectivity ruined");
- }
- }
- for (int i = 0; i < num_vert_edges; ++i) {
- bool found = false;
- for (int j = 0; j < num_vert_edges; ++j) {
- if (vert_edges[i] == dst_vert_edges[j]) {
- found = true;
- break;
- }
- }
- if (!found) {
- assert(!"vert-edges connectivity ruined");
- }
+ check_oriented_vert_connectivity(num_vert_edges,
+ num_vert_faces,
+ vert_edges,
+ vert_faces,
+ &dst_vert_edges[0],
+ &dst_vert_faces[0]);
+ /* For the release builds we're failing mesh construction so instead
+ * of nasty bugs the unsupported mesh will simply disappear from the
+ * viewport.
+ */
+ if (face_count_ordered != num_vert_faces ||
+ edge_count_ordered != num_vert_edges)
+ {
+ delete [] vert_edges;
+ delete [] vert_faces;
+ return false;
}
-#endif
#else /* OPENSUBDIV_ORIENT_TOPOLOGY */
memcpy(&dst_vert_edges[0], vert_edges, sizeof(int) * num_vert_edges);
memcpy(&dst_vert_faces[0], vert_faces, sizeof(int) * num_vert_faces);
#endif /* OPENSUBDIV_ORIENT_TOPOLOGY */
-
delete [] vert_edges;
delete [] vert_faces;
}
+#ifdef OPENSUBDIV_ORIENT_TOPOLOGY
+ delete [] face_used;
+#endif
populateBaseLocalIndices(refiner);
return true;
};
@@ -306,21 +451,31 @@ inline bool TopologyRefinerFactory<OpenSubdiv_Converter>::assignComponentTags(
setBaseEdgeSharpness(refiner, edge, sharpness);
}
-#if 0
- /* Non-manifold vertices can't be always smooth.
- * I.e. when there's loose edge adjacent to the vertex
- * opensubdiv expects vertices to be sharp. But this needs
- * some further investigation.
+ /* OpenSubdiv expects non-manifold vertices to be sharp but at the
+ * time it handles correct cases when vertex is a corner of plane.
+ * Currently mark verts which are adjacent to a loose edge as sharp,
+ * but this decision needs some more investigation.
*/
int num_vert = conv.get_num_verts(&conv);
for (int vert = 0; vert < num_vert; ++vert) {
- IndexArray vert_faces = getBaseVertexFaces(refiner, vert),
- vert_edges = getBaseVertexEdges(refiner, vert);
- if (vert_faces.size() != vert_edges.size()) {
- setBaseVertexSharpness(refiner, vert, Crease::SHARPNESS_INFINITE);
+ ConstIndexArray vert_edges = getBaseVertexEdges(refiner, vert);
+ for (int edge_index = 0; edge_index < vert_edges.size(); ++edge_index) {
+ int edge = vert_edges[edge_index];
+ ConstIndexArray edge_faces = getBaseEdgeFaces(refiner, edge);
+ if (edge_faces.size() == 0) {
+ setBaseVertexSharpness(refiner, vert, Crease::SHARPNESS_INFINITE);
+ break;
+ }
+ }
+ if (vert_edges.size() == 2) {
+ int edge0 = vert_edges[0],
+ edge1 = vert_edges[1];
+ float sharpness0 = conv.get_edge_sharpness(&conv, edge0),
+ sharpness1 = conv.get_edge_sharpness(&conv, edge1);
+ float sharpness = std::min(sharpness0, sharpness1);
+ setBaseVertexSharpness(refiner, vert, sharpness);
}
}
-#endif
return true;
}
@@ -427,6 +582,17 @@ int openSubdiv_topologyRefinerGetNumFaces(
return base_level.GetNumFaces();
}
+int openSubdiv_topologyRefinerGetNumFaceVerts(
+ const OpenSubdiv_TopologyRefinerDescr *topology_refiner,
+ int face)
+{
+ using OpenSubdiv::Far::TopologyLevel;
+ using OpenSubdiv::Far::TopologyRefiner;
+ const TopologyRefiner *refiner = (const TopologyRefiner *)topology_refiner;
+ const TopologyLevel &base_level = refiner->GetLevel(0);
+ return base_level.GetFaceVertices(face).size();
+}
+
int openSubdiv_topologyRefnerCompareConverter(
const OpenSubdiv_TopologyRefinerDescr *topology_refiner,
OpenSubdiv_Converter *converter)
@@ -473,11 +639,29 @@ int openSubdiv_topologyRefnerCompareConverter(
}
conv_face_verts.resize(face_verts.size());
converter->get_face_verts(converter, face, &conv_face_verts[0]);
+ bool direct_match = true;
for (int i = 0; i < face_verts.size(); ++i) {
if (conv_face_verts[i] != face_verts[i]) {
- return false;
+ direct_match = false;
+ break;
}
}
+ if (!direct_match) {
+ /* If face didn't match in direct direction we also test if it
+ * matches in reversed direction. This is because conversion might
+ * reverse loops to make normals consistent.
+ */
+#ifdef OPENSUBDIV_ORIENT_TOPOLOGY
+ reverse_face_verts(&conv_face_verts[0], conv_face_verts.size());
+ for (int i = 0; i < face_verts.size(); ++i) {
+ if (conv_face_verts[i] != face_verts[i]) {
+ return false;
+ }
+ }
+#else
+ return false;
+#endif
+ }
}
/* Compare sharpness. */
for (int edge = 0; edge < num_edges; ++edge) {
diff --git a/intern/opensubdiv/opensubdiv_converter_capi.h b/intern/opensubdiv/opensubdiv_converter_capi.h
index 7c96d3d8b96..ac1e8301a42 100644
--- a/intern/opensubdiv/opensubdiv_converter_capi.h
+++ b/intern/opensubdiv/opensubdiv_converter_capi.h
@@ -94,7 +94,7 @@ void openSubdiv_deleteTopologyRefinerDescr(
OpenSubdiv_TopologyRefinerDescr *topology_refiner);
/* TODO(sergey): Those calls are not strictly related on conversion.
- * needs some dedicated fiel perhaps.
+ * needs some dedicated file perhaps.
*/
int openSubdiv_topologyRefinerGetSubdivLevel(
@@ -109,6 +109,10 @@ int openSubdiv_topologyRefinerGetNumEdges(
int openSubdiv_topologyRefinerGetNumFaces(
const OpenSubdiv_TopologyRefinerDescr *topology_refiner);
+int openSubdiv_topologyRefinerGetNumFaceVerts(
+ const OpenSubdiv_TopologyRefinerDescr *topology_refiner,
+ int face);
+
int openSubdiv_topologyRefnerCompareConverter(
const OpenSubdiv_TopologyRefinerDescr *topology_refiner,
OpenSubdiv_Converter *converter);
diff --git a/intern/opensubdiv/opensubdiv_evaluator_capi.cc b/intern/opensubdiv/opensubdiv_evaluator_capi.cc
index b8527fda4e5..0da6b9daba8 100644
--- a/intern/opensubdiv/opensubdiv_evaluator_capi.cc
+++ b/intern/opensubdiv/opensubdiv_evaluator_capi.cc
@@ -351,15 +351,11 @@ OpenSubdiv_EvaluatorDescr *openSubdiv_createEvaluatorDescr(
const StencilTable *varying_stencils = NULL;
int num_total_verts = 0;
- /* Apply adaptive refinement to the mesh so that we can use the
+ /* Apply uniform refinement to the mesh so that we can use the
* limit evaluation API features.
- *
- * TODO(sergey): Once OpenSubdiv supports uniform meshes in limit
- * evlauation we need to switch to uniform here, which will match
- * original Blender subsurf.
*/
- TopologyRefiner::AdaptiveOptions options(subsurf_level);
- refiner->RefineAdaptive(options);
+ TopologyRefiner::UniformOptions options(subsurf_level);
+ refiner->RefineUniform(options);
/* Generate stencil table to update the bi-cubic patches control
* vertices after they have been re-posed (both for vertex & varying
@@ -367,7 +363,7 @@ OpenSubdiv_EvaluatorDescr *openSubdiv_createEvaluatorDescr(
*/
StencilTableFactory::Options soptions;
soptions.generateOffsets = true;
- soptions.generateIntermediateLevels = true;
+ soptions.generateIntermediateLevels = false;
vertex_stencils = StencilTableFactory::Create(*refiner, soptions);
diff --git a/intern/opensubdiv/opensubdiv_gpu_capi.cc b/intern/opensubdiv/opensubdiv_gpu_capi.cc
index d46211f3668..31996a1bab8 100644
--- a/intern/opensubdiv/opensubdiv_gpu_capi.cc
+++ b/intern/opensubdiv/opensubdiv_gpu_capi.cc
@@ -47,11 +47,7 @@
#include <opensubdiv/osd/cpuGLVertexBuffer.h>
#include <opensubdiv/osd/cpuEvaluator.h>
-#include "opensubdiv_partitioned.h"
-
-//using OpenSubdiv::FarPatchTables;
using OpenSubdiv::Osd::GLMeshInterface;
-//sing OpenSubdiv::PartitionedGLMeshInterface;
extern "C" char datatoc_gpu_shader_opensubd_display_glsl[];
@@ -62,19 +58,19 @@ typedef struct Light {
float diffuse[4];
float specular[4];
float spot_direction[4];
+#ifdef SUPPORT_COLOR_MATERIAL
float constant_attenuation;
float linear_attenuation;
float quadratic_attenuation;
float spot_cutoff;
float spot_exponent;
float spot_cos_cutoff;
- float pad[2];
+#endif
} Light;
typedef struct Lighting {
Light lights[MAX_LIGHTS];
int num_enabled;
- int pad[3];
} Lighting;
typedef struct Transform {
@@ -86,8 +82,10 @@ typedef struct Transform {
static bool g_use_osd_glsl = false;
static int g_active_uv_index = -1;
-static GLuint g_flat_fill_program = 0;
-static GLuint g_smooth_fill_program = 0;
+static GLuint g_flat_fill_solid_program = 0;
+static GLuint g_flat_fill_texture2d_program = 0;
+static GLuint g_smooth_fill_solid_program = 0;
+static GLuint g_smooth_fill_texture2d_program = 0;
static GLuint g_wireframe_program = 0;
static GLuint g_lighting_ub = 0;
@@ -216,7 +214,7 @@ GLuint compileShader(GLenum shaderType,
fprintf(stderr, "Section: %s\n", sdefine);
fprintf(stderr, "Defines: %s\n", define);
fprintf(stderr, "Source: %s\n", sources[2]);
- exit(1);
+ return 0;
}
return shader;
@@ -227,12 +225,21 @@ GLuint linkProgram(const char *define)
GLuint vertexShader = compileShader(GL_VERTEX_SHADER,
"VERTEX_SHADER",
define);
+ if (vertexShader == 0) {
+ return 0;
+ }
GLuint geometryShader = compileShader(GL_GEOMETRY_SHADER,
"GEOMETRY_SHADER",
define);
+ if (geometryShader == 0) {
+ return 0;
+ }
GLuint fragmentShader = compileShader(GL_FRAGMENT_SHADER,
"FRAGMENT_SHADER",
define);
+ if (fragmentShader == 0) {
+ return 0;
+ }
GLuint program = glCreateProgram();
@@ -281,7 +288,8 @@ GLuint linkProgram(const char *define)
glGetProgramInfoLog(program, sizeof(emsg), 0, emsg);
fprintf(stderr, "Error linking GLSL program : %s\n", emsg);
fprintf(stderr, "Defines: %s\n", define);
- exit(1);
+ glDeleteProgram(program);
+ return 0;
}
glUniformBlockBinding(program,
@@ -299,7 +307,7 @@ GLuint linkProgram(const char *define)
return program;
}
-void bindProgram(PartitionedGLMeshInterface * /*mesh*/,
+void bindProgram(GLMeshInterface * /*mesh*/,
int program)
{
glUseProgram(program);
@@ -324,15 +332,8 @@ void bindProgram(PartitionedGLMeshInterface * /*mesh*/,
glBindBufferBase(GL_UNIFORM_BUFFER, 0, g_lighting_ub);
/* Color */
- GLboolean use_lighting, use_color_material, use_texture_2d;
+ GLboolean use_lighting;
glGetBooleanv(GL_LIGHTING, &use_lighting);
- glGetBooleanv(GL_COLOR_MATERIAL, &use_color_material);
- glGetBooleanv(GL_TEXTURE_2D, &use_texture_2d);
-
- glUniform1i(glGetUniformLocation(program, "use_color_material"),
- use_color_material);
- glUniform1i(glGetUniformLocation(program, "use_texture_2d"),
- use_texture_2d);
if (use_lighting) {
float color[4];
@@ -372,12 +373,15 @@ void bindProgram(PartitionedGLMeshInterface * /*mesh*/,
} /* namespace */
-void openSubdiv_osdGLDisplayInit(void)
+bool openSubdiv_osdGLDisplayInit(void)
{
static bool need_init = true;
+ static bool init_success = false;
if (need_init) {
- g_flat_fill_program = linkProgram("#define FLAT_SHADING\n");
- g_smooth_fill_program = linkProgram("#define SMOOTH_SHADING\n");
+ g_flat_fill_solid_program = linkProgram("#define FLAT_SHADING\n");
+ g_flat_fill_texture2d_program = linkProgram("#define USE_TEXTURE_2D\n#define FLAT_SHADING\n");
+ g_smooth_fill_solid_program = linkProgram("#define SMOOTH_SHADING\n");
+ g_smooth_fill_texture2d_program = linkProgram("#define USE_TEXTURE_2D\n#define SMOOTH_SHADING\n");
g_wireframe_program = linkProgram("#define WIREFRAME\n");
glGenBuffers(1, &g_lighting_ub);
@@ -386,7 +390,13 @@ void openSubdiv_osdGLDisplayInit(void)
sizeof(g_lighting_data), NULL, GL_STATIC_DRAW);
need_init = false;
+ init_success = g_flat_fill_solid_program != 0 &&
+ g_flat_fill_texture2d_program != 0 &&
+ g_smooth_fill_solid_program != 0 &&
+ g_smooth_fill_texture2d_program != 0 &&
+ g_wireframe_program;
}
+ return init_success;
}
void openSubdiv_osdGLDisplayDeinit(void)
@@ -394,11 +404,17 @@ void openSubdiv_osdGLDisplayDeinit(void)
if (g_lighting_ub != 0) {
glDeleteBuffers(1, &g_lighting_ub);
}
- if (g_flat_fill_program) {
- glDeleteProgram(g_flat_fill_program);
+ if (g_flat_fill_solid_program) {
+ glDeleteProgram(g_flat_fill_solid_program);
+ }
+ if (g_flat_fill_texture2d_program) {
+ glDeleteProgram(g_flat_fill_texture2d_program);
}
- if (g_smooth_fill_program) {
- glDeleteProgram(g_flat_fill_program);
+ if (g_smooth_fill_solid_program) {
+ glDeleteProgram(g_flat_fill_solid_program);
+ }
+ if (g_smooth_fill_texture2d_program) {
+ glDeleteProgram(g_smooth_fill_texture2d_program);
}
if (g_wireframe_program) {
glDeleteProgram(g_wireframe_program);
@@ -444,6 +460,7 @@ void openSubdiv_osdGLMeshDisplayPrepare(int use_osd_glsl,
glGetLightfv(GL_LIGHT0 + i,
GL_SPOT_DIRECTION,
g_lighting_data.lights[i].spot_direction);
+#ifdef SUPPORT_COLOR_MATERIAL
glGetLightfv(GL_LIGHT0 + i,
GL_CONSTANT_ATTENUATION,
&g_lighting_data.lights[i].constant_attenuation);
@@ -461,10 +478,11 @@ void openSubdiv_osdGLMeshDisplayPrepare(int use_osd_glsl,
&g_lighting_data.lights[i].spot_exponent);
g_lighting_data.lights[i].spot_cos_cutoff =
cos(g_lighting_data.lights[i].spot_cutoff);
+#endif
}
}
-static GLuint preapre_patchDraw(PartitionedGLMeshInterface *mesh,
+static GLuint preapre_patchDraw(GLMeshInterface *mesh,
bool fill_quads)
{
GLint program = 0;
@@ -505,12 +523,26 @@ static GLuint preapre_patchDraw(PartitionedGLMeshInterface *mesh,
return program;
}
- program = g_smooth_fill_program;
if (fill_quads) {
int model;
+ GLboolean use_texture_2d;
glGetIntegerv(GL_SHADE_MODEL, &model);
+ glGetBooleanv(GL_TEXTURE_2D, &use_texture_2d);
if (model == GL_FLAT) {
- program = g_flat_fill_program;
+ if (use_texture_2d) {
+ program = g_flat_fill_texture2d_program;
+ }
+ else {
+ program = g_flat_fill_solid_program;
+ }
+ }
+ else {
+ if (use_texture_2d) {
+ program = g_smooth_fill_texture2d_program;
+ }
+ else {
+ program = g_smooth_fill_solid_program;
+ }
}
}
else {
@@ -528,13 +560,11 @@ static void perform_drawElements(GLuint program,
int num_elements,
int start_element)
{
- int mode = GL_QUADS;
if (program) {
glUniform1i(glGetUniformLocation(program, "PrimitiveIdBase"),
patch_index);
}
- mode = GL_LINES_ADJACENCY;
- glDrawElements(mode,
+ glDrawElements(GL_LINES_ADJACENCY,
num_elements,
GL_UNSIGNED_INT,
(void *)(start_element * sizeof(unsigned int)));
@@ -558,48 +588,43 @@ static void finish_patchDraw(bool fill_quads)
}
}
-#if 0
-static void draw_partition_patches_range(PartitionedGLMeshInterface *mesh,
+static void draw_partition_patches_range(GLMeshInterface *mesh,
GLuint program,
- int start_partition,
- int num_partitions)
+ int start_patch,
+ int num_patches)
{
- /* Glue patches from all partitions in the range together. */
- int patch_index = -1, start_element = -1, num_elements = 0;
- for (int partition = start_partition;
- partition < start_partition + num_partitions;
- ++partition)
- {
- OsdDrawContext::PatchArrayVector const &patches =
- mesh->GetPatchArrays(partition);
- for (int i = 0; i < (int)patches.size(); ++i) {
- OsdDrawContext::PatchArray const &patch = patches[i];
- OsdDrawContext::PatchDescriptor desc = patch.GetDescriptor();
- OpenSubdiv::FarPatchTables::Type patchType = desc.GetType();
- if (patchType == OpenSubdiv::FarPatchTables::QUADS) {
- if (start_element == -1) {
- patch_index = patch.GetPatchIndex();
- start_element = patch.GetVertIndex();
- }
+ int traversed_patches = 0, num_remained_patches = num_patches;
+ const OpenSubdiv::Osd::PatchArrayVector& patches =
+ mesh->GetPatchTable()->GetPatchArrays();
+ for (int i = 0; i < (int)patches.size(); ++i) {
+ const OpenSubdiv::Osd::PatchArray& patch = patches[i];
+ OpenSubdiv::Far::PatchDescriptor desc = patch.GetDescriptor();
+ OpenSubdiv::Far::PatchDescriptor::Type patchType = desc.GetType();
- assert(patch.GetVertIndex() == start_element + num_elements);
- num_elements += patch.GetNumIndices();
+ if (patchType == OpenSubdiv::Far::PatchDescriptor::QUADS) {
+ const int num_block_patches = patch.GetNumPatches();
+ if (start_patch >= traversed_patches &&
+ start_patch < traversed_patches + num_block_patches)
+ {
+ const int num_control_verts = desc.GetNumControlVertices();
+ const int start_draw_patch = start_patch - traversed_patches;
+ const int num_draw_patches = std::min(num_remained_patches,
+ num_block_patches - start_draw_patch);
+ perform_drawElements(program,
+ i,
+ num_draw_patches * num_control_verts,
+ patch.GetIndexBase() + start_draw_patch * num_control_verts);
+ num_remained_patches -= num_draw_patches;
}
- else {
- assert(!"Discontinuitied are not supported yet.");
+ if (num_remained_patches == 0) {
+ break;
}
+ traversed_patches += num_block_patches;
}
- }
-
- /* Perform actual draw. */
- perform_drawElements(program,
- patch_index,
- num_elements,
- start_element);
+ }
}
-#endif
-static void draw_all_patches(PartitionedGLMeshInterface *mesh,
+static void draw_all_patches(GLMeshInterface *mesh,
GLuint program)
{
const OpenSubdiv::Osd::PatchArrayVector& patches =
@@ -620,30 +645,25 @@ static void draw_all_patches(PartitionedGLMeshInterface *mesh,
void openSubdiv_osdGLMeshDisplay(OpenSubdiv_GLMesh *gl_mesh,
int fill_quads,
- int start_partition,
- int num_partitions)
+ int start_patch,
+ int num_patches)
{
- PartitionedGLMeshInterface *mesh =
- (PartitionedGLMeshInterface *)(gl_mesh->descriptor);
+ GLMeshInterface *mesh =
+ (GLMeshInterface *)(gl_mesh->descriptor);
/* Make sure all global invariants are initialized. */
- openSubdiv_osdGLDisplayInit();
+ if (!openSubdiv_osdGLDisplayInit()) {
+ return;
+ }
/* Setup GLSL/OpenGL to draw patches in current context. */
GLuint program = preapre_patchDraw(mesh, fill_quads != 0);
- if (start_partition != -1) {
-#if 0
+ if (start_patch != -1) {
draw_partition_patches_range(mesh,
program,
- start_partition,
- num_partitions);
-#else
- (void)num_partitions;
- if(start_partition == 0) {
- draw_all_patches(mesh, program);
- }
-#endif
+ start_patch,
+ num_patches);
}
else {
draw_all_patches(mesh, program);
diff --git a/intern/opensubdiv/opensubdiv_intern.h b/intern/opensubdiv/opensubdiv_intern.h
index 3e3925e74c4..ccb32f9d0ac 100644
--- a/intern/opensubdiv/opensubdiv_intern.h
+++ b/intern/opensubdiv/opensubdiv_intern.h
@@ -30,7 +30,10 @@
#ifdef NDEBUG
# undef OPENSUBDIV_VALIDATE_TOPOLOGY
#else
-# define OPENSUBDIV_VALIDATE_TOPOLOGY
+/* TODO(sergey): Always disabled for now, the check doesn't handle
+ * multiple non-manifolds from the OpenSubdiv side currently.
+ */
+# undef OPENSUBDIV_VALIDATE_TOPOLOGY
#endif
/* Currently OpenSubdiv expects topology to be oriented,
diff --git a/intern/opensubdiv/opensubdiv_partitioned.h b/intern/opensubdiv/opensubdiv_partitioned.h
deleted file mode 100644
index 7394a83cd0a..00000000000
--- a/intern/opensubdiv/opensubdiv_partitioned.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2013 Blender Foundation.
- * All rights reserved.
- *
- * Contributor(s): Sergey Sharybin
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-#ifndef __OPENSUBDIV_PATITIONED_H__
-#define __OPENSUBDIV_PATITIONED_H__
-
-#include <opensubdiv/osd/glMesh.h>
-#include <opensubdiv/osd/cpuEvaluator.h>
-#include <opensubdiv/osd/glVertexBuffer.h>
-
-namespace OpenSubdiv {
-namespace OPENSUBDIV_VERSION {
-namespace Osd {
-
-/* TODO(sergey): Re-implement partitioning. */
-
-#if 0
-template <class PATCH_TABLE>
-class PartitionedMeshInterface : public MeshInterface<PATCH_TABLE> {
- typedef PATCH_TABLE PatchTable;
- typedef typename PatchTable::VertexBufferBinding VertexBufferBinding;
-
-public:
-};
-
-typedef PartitionedMeshInterface<GLPatchTable> PartitionedGLMeshInterface;
-
-#endif
-
-#if 0
-template <typename VERTEX_BUFFER,
- typename STENCIL_TABLE,
- typename EVALUATOR,
- typename PATCH_TABLE,
- typename DEVICE_CONTEXT = void>
-class PartitionedMesh : public Mesh<VERTEX_BUFFER,
- STENCIL_TABLE,
- EVALUATOR,
- PATCH_TABLE,
- DEVICE_CONTEXT>
-{
-};
-#endif
-
-#define PartitionedGLMeshInterface GLMeshInterface
-#define PartitionedMesh Mesh
-
-} /* namespace Osd */
-} /* namespace OPENSUBDIV_VERSION */
-
-using namespace OPENSUBDIV_VERSION;
-
-} /* namespace OpenSubdiv */
-
-#endif /* __OPENSUBDIV_PATITIONED_H__ */
diff --git a/intern/opensubdiv/opensubdiv_utils_capi.cc b/intern/opensubdiv/opensubdiv_utils_capi.cc
index 5a2d017ed26..a945484ba61 100644
--- a/intern/opensubdiv/opensubdiv_utils_capi.cc
+++ b/intern/opensubdiv/opensubdiv_utils_capi.cc
@@ -26,6 +26,7 @@
#include "opensubdiv_capi.h"
+#include <cstring>
#include <GL/glew.h>
#ifdef _MSC_VER
@@ -71,12 +72,38 @@ int openSubdiv_getAvailableEvaluators(void)
#endif /* OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK */
#ifdef OPENSUBDIV_HAS_GLSL_COMPUTE
- flags |= OPENSUBDIV_EVALUATOR_GLSL_COMPUTE;
+ static bool vendor_checked = false;
+ static bool disable_glsl_compute = false;
+ /* Force disable GLSL Compute on AMD hardware because it has really
+ * hard time evaluating required shaders.
+ */
+ if (!vendor_checked) {
+ vendor_checked = true;
+ const char *vendor = (const char *)glGetString(GL_VENDOR);
+ const char *renderer = (const char *)glGetString(GL_RENDERER);
+ if (vendor != NULL && renderer != NULL) {
+ if (strstr(vendor, "ATI") ||
+ strstr(renderer, "Mesa DRI R") ||
+ (strstr(renderer, "Gallium ") && strstr(renderer, " on ATI ")))
+ {
+ disable_glsl_compute = true;
+ }
+ }
+ }
+ if (!disable_glsl_compute) {
+ flags |= OPENSUBDIV_EVALUATOR_GLSL_COMPUTE;
+ }
#endif /* OPENSUBDIV_HAS_GLSL_COMPUTE */
return flags;
}
+void openSubdiv_init(void)
+{
+ /* Ensure all OpenGL strings are cached. */
+ (void)openSubdiv_getAvailableEvaluators();
+}
+
void openSubdiv_cleanup(void)
{
openSubdiv_osdGLDisplayDeinit();
diff --git a/intern/smoke/intern/MERSENNETWISTER.h b/intern/smoke/intern/MERSENNETWISTER.h
index 5a9ccf88ae7..42b3fe19686 100644
--- a/intern/smoke/intern/MERSENNETWISTER.h
+++ b/intern/smoke/intern/MERSENNETWISTER.h
@@ -187,7 +187,7 @@ inline MTRand::uint32 MTRand::randInt()
if( left == 0 ) reload();
--left;
- register uint32 s1;
+ uint32 s1;
s1 = *pNext++;
s1 ^= (s1 >> 11);
s1 ^= (s1 << 7) & 0x9d2c5680UL;
@@ -232,9 +232,9 @@ inline void MTRand::seed( uint32 *const bigSeed, const uint32 seedLength )
// in each element are discarded.
// Just call seed() if you want to get array from /dev/urandom
initialize(19650218UL);
- register int i = 1;
- register uint32 j = 0;
- register int k = ( (uint32)N > seedLength ? (uint32)N : seedLength );
+ int i = 1;
+ uint32 j = 0;
+ int k = ( (uint32)N > seedLength ? (uint32)N : seedLength );
for( ; k; --k )
{
state[i] =
@@ -273,9 +273,9 @@ inline void MTRand::seed()
if( urandom )
{
uint32 bigSeed[N];
- register uint32 *s = bigSeed;
- register int i = N;
- register bool success = true;
+ uint32 *s = bigSeed;
+ int i = N;
+ bool success = true;
while( success && i-- )
success = fread( s++, sizeof(uint32), 1, urandom );
fclose(urandom);
@@ -294,9 +294,9 @@ inline void MTRand::initialize( const uint32 seed )
// See Knuth TAOCP Vol 2, 3rd Ed, p.106 for multiplier.
// In previous versions, most significant bits (MSBs) of the seed affect
// only MSBs of the state array. Modified 9 Jan 2002 by Makoto Matsumoto.
- register uint32 *s = state;
- register uint32 *r = state;
- register int i = 1;
+ uint32 *s = state;
+ uint32 *r = state;
+ int i = 1;
*s++ = seed & 0xffffffffUL;
for( ; i < N; ++i )
{
@@ -310,8 +310,8 @@ inline void MTRand::reload()
{
// Generate N new values in state
// Made clearer and faster by Matthew Bellew (matthew.bellew@home.com)
- register uint32 *p = state;
- register int i;
+ uint32 *p = state;
+ int i;
for( i = N - M; i--; ++p )
*p = twist( p[M], p[0], p[1] );
for( i = M; --i; ++p )
@@ -350,9 +350,9 @@ inline MTRand::uint32 MTRand::hash( time_t t, clock_t c )
inline void MTRand::save( uint32* saveArray ) const
{
- register uint32 *sa = saveArray;
- register const uint32 *s = state;
- register int i = N;
+ uint32 *sa = saveArray;
+ const uint32 *s = state;
+ int i = N;
for( ; i--; *sa++ = *s++ ) {}
*sa = left;
}
@@ -360,9 +360,9 @@ inline void MTRand::save( uint32* saveArray ) const
inline void MTRand::load( uint32 *const loadArray )
{
- register uint32 *s = state;
- register uint32 *la = loadArray;
- register int i = N;
+ uint32 *s = state;
+ uint32 *la = loadArray;
+ int i = N;
for( ; i--; *s++ = *la++ ) {}
left = *la;
pNext = &state[N-left];
@@ -371,8 +371,8 @@ inline void MTRand::load( uint32 *const loadArray )
inline std::ostream& operator<<( std::ostream& os, const MTRand& mtrand )
{
- register const MTRand::uint32 *s = mtrand.state;
- register int i = mtrand.N;
+ const MTRand::uint32 *s = mtrand.state;
+ int i = mtrand.N;
for( ; i--; os << *s++ << "\t" ) {}
return os << mtrand.left;
}
@@ -380,8 +380,8 @@ inline std::ostream& operator<<( std::ostream& os, const MTRand& mtrand )
inline std::istream& operator>>( std::istream& is, MTRand& mtrand )
{
- register MTRand::uint32 *s = mtrand.state;
- register int i = mtrand.N;
+ MTRand::uint32 *s = mtrand.state;
+ int i = mtrand.N;
for( ; i--; is >> *s++ ) {}
is >> mtrand.left;
mtrand.pNext = &mtrand.state[mtrand.N-mtrand.left];