diff options
Diffstat (limited to 'intern')
172 files changed, 4784 insertions, 3302 deletions
diff --git a/intern/CMakeLists.txt b/intern/CMakeLists.txt index c85f0fddc34..71d2ef5e410 100644 --- a/intern/CMakeLists.txt +++ b/intern/CMakeLists.txt @@ -31,6 +31,7 @@ add_subdirectory(memutil) add_subdirectory(iksolver) add_subdirectory(opennl) add_subdirectory(mikktspace) +add_subdirectory(raskter) if(WITH_AUDASPACE) add_subdirectory(audaspace) diff --git a/intern/SConscript b/intern/SConscript index a1e7f840800..3bfdc2c4ca7 100644 --- a/intern/SConscript +++ b/intern/SConscript @@ -14,7 +14,8 @@ SConscript(['audaspace/SConscript', 'boolop/SConscript', 'opennl/SConscript', 'mikktspace/SConscript', - 'smoke/SConscript']) + 'smoke/SConscript', + 'raskter/SConscript']) if env ['WITH_BF_REMESH']: SConscript(['dualcon/SConscript']) diff --git a/intern/bsp/intern/BSP_CSGMesh_CFIterator.h b/intern/bsp/intern/BSP_CSGMesh_CFIterator.h index cadd3df4360..928d04eda20 100644 --- a/intern/bsp/intern/BSP_CSGMesh_CFIterator.h +++ b/intern/bsp/intern/BSP_CSGMesh_CFIterator.h @@ -127,10 +127,10 @@ BSP_CSGMeshVertexIt_Construct( BSP_CSGMesh_VertexIt * v_it = new BSP_CSGMesh_VertexIt; v_it->mesh = mesh; - if( output->num_elements > 0 ) + if ( output->num_elements > 0 ) v_it->pos = &mesh->VertexSet()[0]; output->it = v_it; -}; +} /** diff --git a/intern/container/CTR_UHeap.h b/intern/container/CTR_UHeap.h index ad3d7d2bb02..8711d4375cb 100644 --- a/intern/container/CTR_UHeap.h +++ b/intern/container/CTR_UHeap.h @@ -56,7 +56,7 @@ class CTR_UHeapable { public : int & HeapPos( - ){ + ) { return m_ind; }; float & @@ -93,7 +93,7 @@ protected : }; ~CTR_UHeapable( - ){ + ) { }; }; @@ -214,7 +214,7 @@ private: HeapType *base, int i, int j - ){ + ) { std::swap(m_vector[i],m_vector[j]); CTR_UHeapable *heap_i = base + m_vector[i]; diff --git a/intern/container/intern/CTR_List.cpp b/intern/container/intern/CTR_List.cpp index 2fc7b0261ef..c72d3ccf0d8 100644 --- a/intern/container/intern/CTR_List.cpp +++ b/intern/container/intern/CTR_List.cpp @@ -33,118 +33,95 @@ #include "CTR_List.h" -CTR_Link:: -CTR_Link( -) : +CTR_Link::CTR_Link() : m_next(0), m_prev(0) { } -CTR_Link:: -CTR_Link( - CTR_Link *next, - CTR_Link *prev -) : +CTR_Link::CTR_Link(CTR_Link *next, CTR_Link *prev) : m_next(next), m_prev(prev) { } - CTR_Link * -CTR_Link:: -getNext( -) const { +CTR_Link * +CTR_Link::getNext() const +{ return m_next; } - CTR_Link * -CTR_Link:: -getPrev( -) const { +CTR_Link * +CTR_Link::getPrev() const +{ return m_prev; } - bool -CTR_Link:: -isHead( -) const { +bool +CTR_Link::isHead() const +{ return m_prev == 0; } - bool -CTR_Link:: -isTail( -) const { +bool +CTR_Link::isTail() const +{ return m_next == 0; } - void -CTR_Link:: -insertBefore( - CTR_Link *link -) { - m_next = link; - m_prev = link->m_prev; - m_next->m_prev = this; - m_prev->m_next = this; +void +CTR_Link::insertBefore(CTR_Link *link) +{ + m_next = link; + m_prev = link->m_prev; + m_next->m_prev = this; + m_prev->m_next = this; } - void -CTR_Link:: -insertAfter( - CTR_Link *link -) { - m_next = link->m_next; - m_prev = link; - m_next->m_prev = this; - m_prev->m_next = this; +void +CTR_Link::insertAfter(CTR_Link *link) +{ + m_next = link->m_next; + m_prev = link; + m_next->m_prev = this; + m_prev->m_next = this; } - void -CTR_Link:: -remove( -) { - m_next->m_prev = m_prev; - m_prev->m_next = m_next; +void +CTR_Link::remove() +{ + m_next->m_prev = m_prev; + m_prev->m_next = m_next; } -CTR_List:: -CTR_List( -) : +CTR_List::CTR_List() : m_head(&m_tail, 0), m_tail(0, &m_head) { } - CTR_Link * -CTR_List:: -getHead( -) const { +CTR_Link * +CTR_List:: getHead() const +{ return m_head.getNext(); } - CTR_Link * -CTR_List:: -getTail( -) const { +CTR_Link * +CTR_List::getTail() const +{ return m_tail.getPrev(); } - void -CTR_List:: -addHead( - CTR_Link *link -) { +void +CTR_List::addHead(CTR_Link *link) +{ link->insertAfter(&m_head); } - void -CTR_List:: -addTail( - CTR_Link *link -) { +void +CTR_List::addTail(CTR_Link *link) +{ link->insertBefore(&m_tail); } diff --git a/intern/cycles/app/cycles_test.cpp b/intern/cycles/app/cycles_test.cpp index 0b8853d7036..f5890998adc 100644 --- a/intern/cycles/app/cycles_test.cpp +++ b/intern/cycles/app/cycles_test.cpp @@ -172,8 +172,8 @@ static void display() static void resize(int width, int height) { - options.width= width; - options.height= height; + options.width = width; + options.height = height; if(options.session) options.session->reset(session_buffer_params(), options.session_params.samples); @@ -197,8 +197,8 @@ static int files_parse(int argc, const char *argv[]) static void options_parse(int argc, const char **argv) { - options.width= 0; - options.height= 0; + options.width = 0; + options.height = 0; options.filepath = ""; options.session = NULL; options.quiet = false; diff --git a/intern/cycles/app/cycles_xml.cpp b/intern/cycles/app/cycles_xml.cpp index cfa4095104b..1190ee185fd 100644 --- a/intern/cycles/app/cycles_xml.cpp +++ b/intern/cycles/app/cycles_xml.cpp @@ -392,9 +392,9 @@ static void xml_read_shader_graph(const XMLReadState& state, Shader *shader, pug snode = dist; } else if(string_iequals(node.name(), "wave_texture")) { - WaveTextureNode *wood = new WaveTextureNode(); - xml_read_enum(&wood->type, WaveTextureNode::type_enum, node, "type"); - snode = wood; + WaveTextureNode *wave = new WaveTextureNode(); + xml_read_enum(&wave->type, WaveTextureNode::type_enum, node, "type"); + snode = wave; } else if(string_iequals(node.name(), "normal")) { snode = new NormalNode(); diff --git a/intern/cycles/blender/CMakeLists.txt b/intern/cycles/blender/CMakeLists.txt index 003c6c84f8f..a8c7eef89fa 100644 --- a/intern/cycles/blender/CMakeLists.txt +++ b/intern/cycles/blender/CMakeLists.txt @@ -22,6 +22,7 @@ set(SRC blender_camera.cpp blender_mesh.cpp blender_object.cpp + blender_particles.cpp blender_python.cpp blender_session.cpp blender_shader.cpp diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 8480b0a5256..3b906bb4bdf 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -488,9 +488,7 @@ class CyclesLamp_PT_lamp(CyclesButtonsPanel, Panel): col = split.column() col.prop(clamp, "cast_shadow") - if lamp.type == 'SPOT': - layout.label(text="Not supported, interpreted as point lamp.") - elif lamp.type == 'HEMI': + if lamp.type == 'HEMI': layout.label(text="Not supported, interpreted as sun lamp.") @@ -509,6 +507,29 @@ class CyclesLamp_PT_nodes(CyclesButtonsPanel, Panel): if not panel_node_draw(layout, lamp, 'OUTPUT_LAMP', 'Surface'): layout.prop(lamp, "color") +class CyclesLamp_PT_spot(CyclesButtonsPanel, Panel): + bl_label = "Spot Shape" + bl_context = "data" + + @classmethod + def poll(cls, context): + lamp = context.lamp + return (lamp and lamp.type == 'SPOT') and CyclesButtonsPanel.poll(context) + + def draw(self, context): + layout = self.layout + + lamp = context.lamp + + split = layout.split() + + col = split.column() + sub = col.column() + sub.prop(lamp, "spot_size", text="Size") + sub.prop(lamp, "spot_blend", text="Blend", slider=True) + + col = split.column() + col.prop(lamp, "show_cone") class CyclesWorld_PT_surface(CyclesButtonsPanel, Panel): bl_label = "Surface" diff --git a/intern/cycles/blender/blender_camera.cpp b/intern/cycles/blender/blender_camera.cpp index bdd02bb5086..122d0bd7c17 100644 --- a/intern/cycles/blender/blender_camera.cpp +++ b/intern/cycles/blender/blender_camera.cpp @@ -56,6 +56,11 @@ struct BlenderCamera { float sensor_width; float sensor_height; + float border_left; + float border_right; + float border_bottom; + float border_top; + Transform matrix; }; @@ -70,6 +75,8 @@ static void blender_camera_init(BlenderCamera *bcam) bcam->sensor_height = 18.0f; bcam->sensor_fit = BlenderCamera::AUTO; bcam->shuttertime = 1.0f; + bcam->border_right = 1.0f; + bcam->border_top = 1.0f; } static float blender_camera_focal_distance(BL::Object b_ob, BL::Camera b_camera) @@ -134,7 +141,7 @@ static void blender_camera_from_object(BlenderCamera *bcam, BL::Object b_ob) bcam->lens = b_camera.lens(); /* allow f/stop number to change aperture_size but still - give manual control over aperture radius */ + * give manual control over aperture radius */ int aperture_type = RNA_enum_get(&ccamera, "aperture_type"); if(aperture_type == 1) { @@ -172,8 +179,8 @@ static Transform blender_camera_matrix(const Transform& tfm, CameraType type) if(type == CAMERA_PANORAMA) { /* make it so environment camera needs to be pointed in the direction - of the positive x-axis to match an environment texture, this way - it is looking at the center of the texture */ + * of the positive x-axis to match an environment texture, this way + * it is looking at the center of the texture */ result = tfm * make_transform( 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, @@ -188,85 +195,94 @@ static Transform blender_camera_matrix(const Transform& tfm, CameraType type) return transform_clear_scale(result); } -static void blender_camera_sync(Camera *cam, BlenderCamera *bcam, int width, int height) +static void blender_camera_viewplane(BlenderCamera *bcam, int width, int height, + float *left, float *right, float *bottom, float *top, float *aspectratio, float *sensor_size) { - /* copy camera to compare later */ - Camera prevcam = *cam; - /* dimensions */ float xratio = width*bcam->pixelaspect.x; float yratio = height*bcam->pixelaspect.y; /* compute x/y aspect and ratio */ - float aspectratio, xaspect, yaspect; + float xaspect, yaspect; /* sensor fitting */ bool horizontal_fit; - float sensor_size; - - cam->sensorwidth = bcam->sensor_width; - cam->sensorheight = bcam->sensor_height; if(bcam->sensor_fit == BlenderCamera::AUTO) { horizontal_fit = (xratio > yratio); - sensor_size = bcam->sensor_width; + *sensor_size = bcam->sensor_width; } else if(bcam->sensor_fit == BlenderCamera::HORIZONTAL) { horizontal_fit = true; - sensor_size = bcam->sensor_width; + *sensor_size = bcam->sensor_width; } else { horizontal_fit = false; - sensor_size = bcam->sensor_height; + *sensor_size = bcam->sensor_height; } if(horizontal_fit) { - aspectratio= xratio/yratio; - xaspect= aspectratio; - yaspect= 1.0f; + *aspectratio = xratio/yratio; + xaspect = *aspectratio; + yaspect = 1.0f; } else { - aspectratio= yratio/xratio; - xaspect= 1.0f; - yaspect= aspectratio; + *aspectratio = yratio/xratio; + xaspect = 1.0f; + yaspect = *aspectratio; } /* modify aspect for orthographic scale */ if(bcam->type == CAMERA_ORTHOGRAPHIC) { - xaspect = xaspect*bcam->ortho_scale/(aspectratio*2.0f); - yaspect = yaspect*bcam->ortho_scale/(aspectratio*2.0f); - aspectratio = bcam->ortho_scale/2.0f; + xaspect = xaspect*bcam->ortho_scale/(*aspectratio*2.0f); + yaspect = yaspect*bcam->ortho_scale/(*aspectratio*2.0f); + *aspectratio = bcam->ortho_scale/2.0f; } if(bcam->type == CAMERA_PANORAMA) { /* set viewplane */ - cam->left = 0.0f; - cam->right = 1.0f; - cam->bottom = 0.0f; - cam->top = 1.0f; + *left = 0.0f; + *right = 1.0f; + *bottom = 0.0f; + *top = 1.0f; } else { /* set viewplane */ - cam->left = -xaspect; - cam->right = xaspect; - cam->bottom = -yaspect; - cam->top = yaspect; + *left = -xaspect; + *right = xaspect; + *bottom = -yaspect; + *top = yaspect; /* zoom for 3d camera view */ - cam->left *= bcam->zoom; - cam->right *= bcam->zoom; - cam->bottom *= bcam->zoom; - cam->top *= bcam->zoom; + *left *= bcam->zoom; + *right *= bcam->zoom; + *bottom *= bcam->zoom; + *top *= bcam->zoom; /* modify viewplane with camera shift and 3d camera view offset */ - float dx = 2.0f*(aspectratio*bcam->shift.x + bcam->offset.x*xaspect*2.0f); - float dy = 2.0f*(aspectratio*bcam->shift.y + bcam->offset.y*yaspect*2.0f); + float dx = 2.0f*(*aspectratio*bcam->shift.x + bcam->offset.x*xaspect*2.0f); + float dy = 2.0f*(*aspectratio*bcam->shift.y + bcam->offset.y*yaspect*2.0f); - cam->left += dx; - cam->right += dx; - cam->bottom += dy; - cam->top += dy; + *left += dx; + *right += dx; + *bottom += dy; + *top += dy; } +} + +static void blender_camera_sync(Camera *cam, BlenderCamera *bcam, int width, int height) +{ + /* copy camera to compare later */ + Camera prevcam = *cam; + float aspectratio, sensor_size; + + /* viewplane */ + blender_camera_viewplane(bcam, width, height, + &cam->left, &cam->right, &cam->bottom, &cam->top, &aspectratio, &sensor_size); + + /* sensor */ + cam->sensorwidth = bcam->sensor_width; + cam->sensorheight = bcam->sensor_height; /* clipping distances */ cam->nearclip = bcam->nearclip; @@ -281,7 +297,7 @@ static void blender_camera_sync(Camera *cam, BlenderCamera *bcam, int width, int cam->fisheye_lens = bcam->fisheye_lens; /* perspective */ - cam->fov = 2.0f*atan((0.5f*sensor_size)/bcam->lens/aspectratio); + cam->fov = 2.0f * atanf((0.5f * sensor_size) / bcam->lens / aspectratio); cam->focaldistance = bcam->focaldistance; cam->aperturesize = bcam->aperturesize; cam->blades = bcam->apertureblades; @@ -294,6 +310,12 @@ static void blender_camera_sync(Camera *cam, BlenderCamera *bcam, int width, int cam->use_motion = false; cam->shuttertime = bcam->shuttertime; + /* border */ + cam->border_left = bcam->border_left; + cam->border_right = bcam->border_right; + cam->border_bottom = bcam->border_bottom; + cam->border_top = bcam->border_top; + /* set update flag */ if(cam->modified(prevcam)) cam->tag_update(); @@ -313,6 +335,14 @@ void BlenderSync::sync_camera(BL::Object b_override, int width, int height) bcam.pixelaspect.y = r.pixel_aspect_y(); bcam.shuttertime = r.motion_blur_shutter(); + /* border */ + if(r.use_border()) { + bcam.border_left = r.border_min_x(); + bcam.border_right = r.border_max_x(); + bcam.border_bottom = r.border_min_y(); + bcam.border_top = r.border_max_y(); + } + /* camera object */ BL::Object b_ob = b_scene.camera(); @@ -348,67 +378,142 @@ void BlenderSync::sync_camera_motion(BL::Object b_ob, int motion) /* Sync 3D View Camera */ -void BlenderSync::sync_view(BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, int width, int height) +static void blender_camera_from_view(BlenderCamera *bcam, BL::Scene b_scene, BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, int width, int height) { - BlenderCamera bcam; - blender_camera_init(&bcam); - /* 3d view parameters */ - bcam.nearclip = b_v3d.clip_start(); - bcam.farclip = b_v3d.clip_end(); - bcam.lens = b_v3d.lens(); - bcam.shuttertime = b_scene.render().motion_blur_shutter(); + bcam->nearclip = b_v3d.clip_start(); + bcam->farclip = b_v3d.clip_end(); + bcam->lens = b_v3d.lens(); + bcam->shuttertime = b_scene.render().motion_blur_shutter(); if(b_rv3d.view_perspective() == BL::RegionView3D::view_perspective_CAMERA) { /* camera view */ BL::Object b_ob = (b_v3d.lock_camera_and_layers())? b_scene.camera(): b_v3d.camera(); if(b_ob) { - blender_camera_from_object(&bcam, b_ob); + blender_camera_from_object(bcam, b_ob); /* magic zoom formula */ - bcam.zoom = (float)b_rv3d.view_camera_zoom(); - bcam.zoom = (1.41421f + bcam.zoom/50.0f); - bcam.zoom *= bcam.zoom; - bcam.zoom = 2.0f/bcam.zoom; + bcam->zoom = (float)b_rv3d.view_camera_zoom(); + bcam->zoom = (1.41421f + bcam->zoom/50.0f); + bcam->zoom *= bcam->zoom; + bcam->zoom = 2.0f/bcam->zoom; /* offset */ - bcam.offset = get_float2(b_rv3d.view_camera_offset()); + bcam->offset = get_float2(b_rv3d.view_camera_offset()); } } else if(b_rv3d.view_perspective() == BL::RegionView3D::view_perspective_ORTHO) { /* orthographic view */ - bcam.farclip *= 0.5; - bcam.nearclip = -bcam.farclip; + bcam->farclip *= 0.5f; + bcam->nearclip = -bcam->farclip; - bcam.type = CAMERA_ORTHOGRAPHIC; - bcam.ortho_scale = b_rv3d.view_distance(); + bcam->type = CAMERA_ORTHOGRAPHIC; + bcam->ortho_scale = b_rv3d.view_distance(); } - bcam.zoom *= 2.0f; + bcam->zoom *= 2.0f; /* 3d view transform */ - bcam.matrix = transform_inverse(get_transform(b_rv3d.view_matrix())); + bcam->matrix = transform_inverse(get_transform(b_rv3d.view_matrix())); +} + +static void blender_camera_border(BlenderCamera *bcam, BL::Scene b_scene, BL::SpaceView3D b_v3d, + BL::RegionView3D b_rv3d, int width, int height) +{ + BL::RenderSettings r = b_scene.render(); + + if(!r.use_border()) + return; + + /* camera view? */ + if(!(b_rv3d && b_rv3d.view_perspective() == BL::RegionView3D::view_perspective_CAMERA)) + return; + + BL::Object b_ob = (b_v3d.lock_camera_and_layers())? b_scene.camera(): b_v3d.camera(); + + if(!b_ob) + return; + + bcam->border_left = r.border_min_x(); + bcam->border_right = r.border_max_x(); + bcam->border_bottom = r.border_min_y(); + bcam->border_top = r.border_max_y(); + + float cam_left, cam_right, cam_bottom, cam_top; + float view_left, view_right, view_bottom, view_top; + float view_aspect, cam_aspect, sensor_size; + + /* get viewport viewplane */ + BlenderCamera view_bcam; + blender_camera_init(&view_bcam); + blender_camera_from_view(&view_bcam, b_scene, b_v3d, b_rv3d, width, height); + + blender_camera_viewplane(&view_bcam, width, height, + &view_left, &view_right, &view_bottom, &view_top, &view_aspect, &sensor_size); + + view_left /= view_aspect; + view_right /= view_aspect; + view_bottom /= view_aspect; + view_top /= view_aspect; + + /* get camera viewplane */ + BlenderCamera cam_bcam; + blender_camera_init(&cam_bcam); + blender_camera_from_object(&cam_bcam, b_ob); + + width = (int)(r.resolution_x()*r.resolution_percentage()/100); + height = (int)(r.resolution_y()*r.resolution_percentage()/100); + + blender_camera_viewplane(&cam_bcam, width, height, + &cam_left, &cam_right, &cam_bottom, &cam_top, &cam_aspect, &sensor_size); + + cam_left /= cam_aspect; + cam_right /= cam_aspect; + cam_bottom /= cam_aspect; + cam_top /= cam_aspect; + + /* determine viewport subset matching camera border */ + float tmp_left = ((cam_left - view_left) / (view_right - view_left)); + float tmp_right = ((cam_right - view_left) / (view_right - view_left)); + float tmp_bottom = ((cam_bottom - view_bottom) / (view_top - view_bottom)); + float tmp_top = ((cam_top - view_bottom) / (view_top - view_bottom)); + + bcam->border_left = tmp_left + bcam->border_left*(tmp_right - tmp_left); + bcam->border_right = tmp_left + bcam->border_right*(tmp_right - tmp_left); + bcam->border_bottom = tmp_bottom + bcam->border_bottom*(tmp_top - tmp_bottom); + bcam->border_top = tmp_bottom + bcam->border_top*(tmp_top - tmp_bottom); + + /* clamp */ + bcam->border_left = max(bcam->border_left, 0.0f); + bcam->border_right = min(bcam->border_right, 1.0f); + bcam->border_bottom = max(bcam->border_bottom, 0.0f); + bcam->border_top = min(bcam->border_top, 1.0f); +} + +void BlenderSync::sync_view(BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, int width, int height) +{ + BlenderCamera bcam; + blender_camera_init(&bcam); + blender_camera_from_view(&bcam, b_scene, b_v3d, b_rv3d, width, height); + blender_camera_border(&bcam, b_scene, b_v3d, b_rv3d, width, height); - /* sync */ blender_camera_sync(scene->camera, &bcam, width, height); } -BufferParams BlenderSync::get_buffer_params(BL::Scene b_scene, BL::RegionView3D b_rv3d, int width, int height) +BufferParams BlenderSync::get_buffer_params(BL::Scene b_scene, Camera *cam, int width, int height) { BufferParams params; params.full_width = width; params.full_height = height; - /* border render */ - BL::RenderSettings r = b_scene.render(); - - if(!b_rv3d && r.use_border()) { - params.full_x = r.border_min_x()*width; - params.full_y = r.border_min_y()*height; - params.width = (int)(r.border_max_x()*width) - params.full_x; - params.height = (int)(r.border_max_y()*height) - params.full_y; + if(b_scene.render().use_border()) { + /* border render */ + params.full_x = cam->border_left*width; + params.full_y = cam->border_bottom*height; + params.width = (int)(cam->border_right*width) - params.full_x; + params.height = (int)(cam->border_top*height) - params.full_y; } else { params.width = width; diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp index ad91022de07..16e4ceded89 100644 --- a/intern/cycles/blender/blender_mesh.cpp +++ b/intern/cycles/blender/blender_mesh.cpp @@ -46,7 +46,7 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector< float3 *N = attr_N->data_float3(); for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v, ++N) - *N= get_float3(v->normal()); + *N = get_float3(v->normal()); /* create faces */ BL::Mesh::tessfaces_iterator f; @@ -68,8 +68,8 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector< } /* create generated coordinates. todo: we should actually get the orco - coordinates from modifiers, for now we use texspace loc/size which - is available in the api. */ + * coordinates from modifiers, for now we use texspace loc/size which + * is available in the api. */ if(mesh->need_attribute(scene, ATTR_STD_GENERATED)) { Attribute *attr = mesh->attributes.add(ATTR_STD_GENERATED); float3 loc = get_float3(b_mesh.texspace_location()); @@ -82,7 +82,6 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector< loc = loc*size - make_float3(0.5f, 0.5f, 0.5f); float3 *fdata = attr->data_float3(); - BL::Mesh::vertices_iterator v; size_t i = 0; for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v) @@ -176,13 +175,15 @@ static void create_subd_mesh(Mesh *mesh, BL::Mesh b_mesh, PointerRNA *cmesh, con for(b_mesh.tessfaces.begin(f); f != b_mesh.tessfaces.end(); ++f) { int4 vi = get_int4(f->vertices_raw()); - int n= (vi[3] == 0)? 3: 4; + int n = (vi[3] == 0) ? 3: 4; //int shader = used_shaders[f->material_index()]; if(n == 4) sdmesh.add_face(vi[0], vi[1], vi[2], vi[3]); - /*else - sdmesh.add_face(vi[0], vi[1], vi[2]);*/ +#if 0 + else + sdmesh.add_face(vi[0], vi[1], vi[2]); +#endif } /* finalize subd mesh */ @@ -210,8 +211,6 @@ Mesh *BlenderSync::sync_mesh(BL::Object b_ob, bool object_updated) BL::Object::material_slots_iterator slot; for(b_ob.material_slots.begin(slot); slot != b_ob.material_slots.end(); ++slot) { - BL::Material material_override = render_layer.material_override; - if(material_override) find_shader(material_override, used_shaders, scene->default_surface); else @@ -232,7 +231,7 @@ Mesh *BlenderSync::sync_mesh(BL::Object b_ob, bool object_updated) /* if transform was applied to mesh, need full update */ if(object_updated && mesh->transform_applied); /* test if shaders changed, these can be object level so mesh - does not get tagged for recalc */ + * does not get tagged for recalc */ else if(mesh->used_shaders != used_shaders); else { /* even if not tagged for recalc, we may need to sync anyway @@ -319,7 +318,7 @@ void BlenderSync::sync_mesh_motion(BL::Object b_ob, Mesh *mesh, int motion) AttributeStandard std = (motion == -1)? ATTR_STD_MOTION_PRE: ATTR_STD_MOTION_POST; Attribute *attr_M = mesh->attributes.add(std); float3 *M = attr_M->data_float3(); - size_t i = 0, size = mesh->verts.size(); + size_t i = 0; for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end() && i < size; ++v, M++, i++) *M = get_float3(v->co()); diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp index b04e0137e37..c4b58d6fa76 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -106,7 +106,9 @@ void BlenderSync::sync_light(BL::Object b_parent, int b_index, BL::Object b_ob, case BL::Lamp::type_SPOT: { BL::SpotLamp b_spot_lamp(b_lamp); light->size = b_spot_lamp.shadow_soft_size(); - light->type = LIGHT_POINT; + light->type = LIGHT_SPOT; + light->spot_angle = b_spot_lamp.spot_size(); + light->spot_smooth = b_spot_lamp.spot_blend(); break; } case BL::Lamp::type_HEMI: { @@ -190,7 +192,7 @@ void BlenderSync::sync_background_light() /* Object */ -void BlenderSync::sync_object(BL::Object b_parent, int b_index, BL::Object b_ob, Transform& tfm, uint layer_flag, int motion) +void BlenderSync::sync_object(BL::Object b_parent, int b_index, BL::Object b_ob, Transform& tfm, uint layer_flag, int motion, int particle_id) { /* light is handled separately */ if(object_is_light(b_ob)) { @@ -262,12 +264,18 @@ void BlenderSync::sync_object(BL::Object b_parent, int b_index, BL::Object b_ob, } /* camera flag is not actually used, instead is tested - against render layer flags */ + * against render layer flags */ if(object->visibility & PATH_RAY_CAMERA) { object->visibility |= layer_flag << PATH_RAY_LAYER_SHIFT; object->visibility &= ~PATH_RAY_CAMERA; } + object->particle_id = particle_id; + + /* particle sync */ + if (object_use_particles(b_ob)) + sync_particles(object, b_ob); + object->tag_update(scene); } } @@ -290,54 +298,51 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, int motion) /* object loop */ BL::Scene::objects_iterator b_ob; BL::Scene b_sce = b_scene; + int particle_offset = 0; for(; b_sce; b_sce = b_sce.background_set()) { for(b_sce.objects.begin(b_ob); b_ob != b_sce.objects.end(); ++b_ob) { bool hide = (render_layer.use_viewport_visibility)? b_ob->hide(): b_ob->hide_render(); uint ob_layer = get_layer(b_ob->layers()); + hide = hide || !(ob_layer & scene_layer); + + if(!hide) { + + int num_particles = object_count_particles(*b_ob); - if(!hide && (ob_layer & scene_layer)) { if(b_ob->is_duplicator()) { + hide = true; /* duplicators hidden by default */ + /* dupli objects */ object_create_duplilist(*b_ob, b_scene); BL::Object::dupli_list_iterator b_dup; - int b_index = 0; - for(b_ob->dupli_list.begin(b_dup); b_dup != b_ob->dupli_list.end(); ++b_dup) { Transform tfm = get_transform(b_dup->matrix()); BL::Object b_dup_ob = b_dup->object(); bool dup_hide = (b_v3d)? b_dup_ob.hide(): b_dup_ob.hide_render(); - if(!(b_dup->hide() || dup_hide)) - sync_object(*b_ob, b_index, b_dup_ob, tfm, ob_layer, motion); - - b_index++; + if(!(b_dup->hide() || dup_hide)) { + sync_object(*b_ob, b_dup->index(), b_dup_ob, tfm, ob_layer, motion, b_dup->particle_index() + particle_offset); + } } object_free_duplilist(*b_ob); - - hide = true; } /* check if we should render or hide particle emitter */ BL::Object::particle_systems_iterator b_psys; - bool render_emitter = false; - - for(b_ob->particle_systems.begin(b_psys); b_psys != b_ob->particle_systems.end(); ++b_psys) { - if(b_psys->settings().use_render_emitter()) { + for(b_ob->particle_systems.begin(b_psys); b_psys != b_ob->particle_systems.end(); ++b_psys) + if(b_psys->settings().use_render_emitter()) hide = false; - render_emitter = true; - } - else if(!render_emitter) - hide = true; - } if(!hide) { /* object itself */ Transform tfm = get_transform(b_ob->matrix_world()); - sync_object(*b_ob, 0, *b_ob, tfm, ob_layer, motion); + sync_object(*b_ob, 0, *b_ob, tfm, ob_layer, motion, 0); } + + particle_offset += num_particles; } } } diff --git a/intern/cycles/blender/blender_particles.cpp b/intern/cycles/blender/blender_particles.cpp new file mode 100644 index 00000000000..f591aaa6d83 --- /dev/null +++ b/intern/cycles/blender/blender_particles.cpp @@ -0,0 +1,162 @@ +/* + * Copyright 2011, Blender Foundation. + * + * 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. + */ + +#include "object.h" + +#include "mesh.h" +#include "blender_sync.h" +#include "blender_util.h" + +#include "util_foreach.h" + +CCL_NAMESPACE_BEGIN + +/* Utilities */ + + +/* Particles Sync */ + +bool BlenderSync::object_use_particles(BL::Object b_ob) +{ + /* Particle data is only needed for + * a) Billboard render mode if object's own material uses particle info + * b) object/group render mode if any dupli object's material uses particle info + * + * Note: Meshes have to be synced at this point! + */ + bool use_particles = false; + + BL::Object::particle_systems_iterator b_psys; + for (b_ob.particle_systems.begin(b_psys); b_psys != b_ob.particle_systems.end(); ++b_psys) { + switch (b_psys->settings().render_type()) { + /* XXX not implemented yet! + * billboards/strands would become part of the mesh data (?), + * so the mesh attributes would store whether particle info is required. + */ + #if 0 + case BL::ParticleSettings::render_type_BILLBOARD: + case BL::ParticleSettings::render_type_PATH: { /* for strand rendering */ + BL::ID key = (BKE_object_is_modified(b_ob))? b_ob: b_ob.data(); + Mesh *mesh = mesh_map.find(key); + if (mesh) { + use_particles |= mesh->need_attribute(scene, ATTR_STD_PARTICLE); + } + break; + } + #endif + + case BL::ParticleSettings::render_type_OBJECT: { + BL::Object b_dupli_ob = b_psys->settings().dupli_object(); + if (b_dupli_ob) { + BL::ID key = (BKE_object_is_modified(b_dupli_ob))? b_dupli_ob: b_dupli_ob.data(); + Mesh *mesh = mesh_map.find(key); + if (mesh) { + use_particles |= mesh->need_attribute(scene, ATTR_STD_PARTICLE); + } + } + break; + } + + case BL::ParticleSettings::render_type_GROUP: { + BL::Group b_dupli_group = b_psys->settings().dupli_group(); + if (b_dupli_group) { + BL::Group::objects_iterator b_gob; + for (b_dupli_group.objects.begin(b_gob); b_gob != b_dupli_group.objects.end(); ++b_gob) { + BL::ID key = (BKE_object_is_modified(*b_gob))? *b_gob: b_gob->data(); + Mesh *mesh = mesh_map.find(key); + if (mesh) { + use_particles |= mesh->need_attribute(scene, ATTR_STD_PARTICLE); + } + } + } + break; + } + + default: + /* avoid compiler warning */ + break; + } + } + + return use_particles; +} + +static bool use_particle_system(BL::ParticleSystem b_psys) +{ + /* only use duplicator particles? disabled particle info for + * halo and billboard to reduce particle count. + * Probably not necessary since particles don't contain a huge amount + * of data compared to other textures. + */ + #if 0 + int render_type = b_psys->settings().render_type(); + return (render_type == BL::ParticleSettings::render_type_OBJECT + || render_type == BL::ParticleSettings::render_type_GROUP); + #endif + + return true; +} + +static bool use_particle(BL::Particle b_pa) +{ + return b_pa.is_exist() && b_pa.is_visible() && b_pa.alive_state()==BL::Particle::alive_state_ALIVE; +} + +int BlenderSync::object_count_particles(BL::Object b_ob) +{ + int tot = 0; + BL::Object::particle_systems_iterator b_psys; + for(b_ob.particle_systems.begin(b_psys); b_psys != b_ob.particle_systems.end(); ++b_psys) { + if (use_particle_system(*b_psys)) { + BL::ParticleSystem::particles_iterator b_pa; + for(b_psys->particles.begin(b_pa); b_pa != b_psys->particles.end(); ++b_pa) { + if(use_particle(*b_pa)) + ++tot; + } + } + } + return tot; +} + +void BlenderSync::sync_particles(Object *ob, BL::Object b_ob) +{ + int tot = object_count_particles(b_ob); + + ob->particles.clear(); + ob->particles.reserve(tot); + + int index; + BL::Object::particle_systems_iterator b_psys; + for(b_ob.particle_systems.begin(b_psys); b_psys != b_ob.particle_systems.end(); ++b_psys) { + if (use_particle_system(*b_psys)) { + BL::ParticleSystem::particles_iterator b_pa; + for(b_psys->particles.begin(b_pa), index = 0; b_pa != b_psys->particles.end(); ++b_pa, ++index) { + if(use_particle(*b_pa)) { + Particle pa; + + pa.age = b_scene.frame_current() - b_pa->birth_time(); + pa.lifetime = b_pa->lifetime(); + + ob->particles.push_back(pa); + } + } + } + } +} + +CCL_NAMESPACE_END diff --git a/intern/cycles/blender/blender_python.cpp b/intern/cycles/blender/blender_python.cpp index 6e892095387..4560c2f8543 100644 --- a/intern/cycles/blender/blender_python.cpp +++ b/intern/cycles/blender/blender_python.cpp @@ -193,7 +193,8 @@ CCLDeviceInfo *compute_device_list(DeviceType type) foreach(DeviceInfo& info, devices) { if(info.type == type || - (info.type == DEVICE_MULTI && info.multi_devices[0].type == type)) { + (info.type == DEVICE_MULTI && info.multi_devices[0].type == type)) + { CCLDeviceInfo cinfo = {info.id.c_str(), info.description.c_str(), i++}; device_list.push_back(cinfo); } @@ -214,7 +215,7 @@ CCL_NAMESPACE_END void *CCL_python_module_init() { - PyObject *mod= PyModule_Create(&ccl::module); + PyObject *mod = PyModule_Create(&ccl::module); #ifdef WITH_OSL PyModule_AddObject(mod, "with_osl", Py_True); diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp index 997909f1b92..12d7d00fb61 100644 --- a/intern/cycles/blender/blender_session.cpp +++ b/intern/cycles/blender/blender_session.cpp @@ -83,8 +83,8 @@ void BlenderSession::create_session() SessionParams session_params = BlenderSync::get_session_params(b_userpref, b_scene, background); /* reset status/progress */ - last_status= ""; - last_progress= -1.0f; + last_status = ""; + last_progress = -1.0f; /* create scene */ scene = new Scene(scene_params); @@ -106,7 +106,7 @@ void BlenderSession::create_session() session->set_pause(BlenderSync::get_session_pause(b_scene, background)); /* set buffer parameters */ - BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, b_rv3d, width, height); + BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, scene->camera, width, height); session->reset(buffer_params, session_params.samples); } @@ -181,7 +181,7 @@ void BlenderSession::render() { /* get buffer parameters */ SessionParams session_params = BlenderSync::get_session_params(b_userpref, b_scene, background); - BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, b_rv3d, width, height); + BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, scene->camera, width, height); int w = buffer_params.width, h = buffer_params.height; /* create render result */ @@ -292,7 +292,8 @@ void BlenderSession::synchronize() SessionParams session_params = BlenderSync::get_session_params(b_userpref, b_scene, background); if(session->params.modified(session_params) || - scene->params.modified(scene_params)) { + scene->params.modified(scene_params)) + { free_session(); create_session(); session->start(); @@ -304,7 +305,7 @@ void BlenderSession::synchronize() session->set_pause(BlenderSync::get_session_pause(b_scene, background)); /* copy recalc flags, outside of mutex so we can decide to do the real - synchronization at a later time to not block on running updates */ + * synchronization at a later time to not block on running updates */ sync->sync_recalc(); /* try to acquire mutex. if we don't want to or can't, come back later */ @@ -326,7 +327,7 @@ void BlenderSession::synchronize() /* reset if needed */ if(scene->need_reset()) { - BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, b_rv3d, width, height); + BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, scene->camera, width, height); session->reset(buffer_params, session_params.samples); } } @@ -334,7 +335,7 @@ void BlenderSession::synchronize() bool BlenderSession::draw(int w, int h) { /* before drawing, we verify camera and viewport size changes, because - we do not get update callbacks for those, we must detect them here */ + * we do not get update callbacks for those, we must detect them here */ if(session->ready_to_reset()) { bool reset = false; @@ -364,7 +365,7 @@ bool BlenderSession::draw(int w, int h) /* reset if requested */ if(reset) { SessionParams session_params = BlenderSync::get_session_params(b_userpref, b_scene, background); - BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, b_rv3d, width, height); + BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, scene->camera, w, h); session->reset(buffer_params, session_params.samples); } @@ -374,7 +375,7 @@ bool BlenderSession::draw(int w, int h) update_status_progress(); /* draw */ - BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, b_rv3d, width, height); + BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, scene->camera, width, height); return !session->draw(buffer_params); } @@ -429,11 +430,11 @@ void BlenderSession::tag_redraw() { if(background) { /* update stats and progress, only for background here because - in 3d view we do it in draw for thread safety reasons */ + * in 3d view we do it in draw for thread safety reasons */ update_status_progress(); /* offline render, redraw if timeout passed */ - if(time_dt() - last_redraw_time > 1.0f) { + if(time_dt() - last_redraw_time > 1.0) { write_render_result(); engine_tag_redraw((RenderEngine*)b_engine.ptr.data); last_redraw_time = time_dt(); diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp index 75cc9115531..35fe4c67673 100644 --- a/intern/cycles/blender/blender_shader.cpp +++ b/intern/cycles/blender/blender_shader.cpp @@ -106,7 +106,7 @@ static void get_tex_mapping(TextureMapping *mapping, BL::ShaderNodeMapping b_map mapping->max = get_float3(b_mapping.max()); } -static ShaderNode *add_node(BL::BlendData b_data, ShaderGraph *graph, BL::ShaderNode b_node) +static ShaderNode *add_node(BL::BlendData b_data, BL::Scene b_scene, ShaderGraph *graph, BL::ShaderNode b_node) { ShaderNode *node = NULL; @@ -337,13 +337,17 @@ static ShaderNode *add_node(BL::BlendData b_data, ShaderGraph *graph, BL::Shader node = new ObjectInfoNode(); break; } + case BL::ShaderNode::type_PARTICLE_INFO: { + node = new ParticleInfoNode(); + break; + } case BL::ShaderNode::type_TEX_IMAGE: { BL::ShaderNodeTexImage b_image_node(b_node); BL::Image b_image(b_image_node.image()); ImageTextureNode *image = new ImageTextureNode(); /* todo: handle generated/builtin images */ if(b_image) - image->filename = blender_absolute_path(b_data, b_image, b_image.filepath()); + image->filename = image_user_file_path(b_image_node.image_user(), b_image, b_scene.frame_current()); image->color_space = ImageTextureNode::color_space_enum[(int)b_image_node.color_space()]; get_tex_mapping(&image->tex_mapping, b_image_node.texture_mapping()); node = image; @@ -354,7 +358,7 @@ static ShaderNode *add_node(BL::BlendData b_data, ShaderGraph *graph, BL::Shader BL::Image b_image(b_env_node.image()); EnvironmentTextureNode *env = new EnvironmentTextureNode(); if(b_image) - env->filename = blender_absolute_path(b_data, b_image, b_image.filepath()); + env->filename = image_user_file_path(b_env_node.image_user(), b_image, b_scene.frame_current()); env->color_space = EnvironmentTextureNode::color_space_enum[(int)b_env_node.color_space()]; env->projection = EnvironmentTextureNode::projection_enum[(int)b_env_node.projection()]; get_tex_mapping(&env->tex_mapping, b_env_node.texture_mapping()); @@ -530,7 +534,7 @@ static void set_default_value(ShaderInput *input, BL::NodeSocket sock) } } -static void add_nodes(BL::BlendData b_data, ShaderGraph *graph, BL::ShaderNodeTree b_ntree, PtrSockMap& sockets_map) +static void add_nodes(BL::BlendData b_data, BL::Scene b_scene, ShaderGraph *graph, BL::ShaderNodeTree b_ntree, PtrSockMap& sockets_map) { /* add nodes */ BL::ShaderNodeTree::nodes_iterator b_node; @@ -578,10 +582,10 @@ static void add_nodes(BL::BlendData b_data, ShaderGraph *graph, BL::ShaderNodeTr set_default_value(proxy->inputs[0], b_output->group_socket()); } - add_nodes(b_data, graph, b_group_ntree, group_sockmap); + add_nodes(b_data, b_scene, graph, b_group_ntree, group_sockmap); } else { - ShaderNode *node = add_node(b_data, graph, BL::ShaderNode(*b_node)); + ShaderNode *node = add_node(b_data, b_scene, graph, BL::ShaderNode(*b_node)); if(node) { BL::Node::inputs_iterator b_input; @@ -637,7 +641,7 @@ static void add_nodes(BL::BlendData b_data, ShaderGraph *graph, BL::ShaderNodeTr to_pair = sockets_map[b_to_sock.ptr.data]; /* either node may be NULL when the node was not exported, typically - because the node type is not supported */ + * because the node type is not supported */ if(from_pair.first && to_pair.first) { ShaderOutput *output = from_pair.first->output(from_pair.second.c_str()); ShaderInput *input = to_pair.first->input(to_pair.second.c_str()); @@ -671,7 +675,7 @@ void BlenderSync::sync_materials() PtrSockMap sock_to_node; BL::ShaderNodeTree b_ntree(b_mat->node_tree()); - add_nodes(b_data, graph, b_ntree, sock_to_node); + add_nodes(b_data, b_scene, graph, b_ntree, sock_to_node); } else { ShaderNode *closure, *out; @@ -712,7 +716,7 @@ void BlenderSync::sync_world() PtrSockMap sock_to_node; BL::ShaderNodeTree b_ntree(b_world.node_tree()); - add_nodes(b_data, graph, b_ntree, sock_to_node); + add_nodes(b_data, b_scene, graph, b_ntree, sock_to_node); } else if(b_world) { ShaderNode *closure, *out; @@ -771,7 +775,7 @@ void BlenderSync::sync_lamps() PtrSockMap sock_to_node; BL::ShaderNodeTree b_ntree(b_lamp->node_tree()); - add_nodes(b_data, graph, b_ntree, sock_to_node); + add_nodes(b_data, b_scene, graph, b_ntree, sock_to_node); } else { ShaderNode *closure, *out; @@ -780,7 +784,9 @@ void BlenderSync::sync_lamps() if(b_lamp->type() == BL::Lamp::type_POINT || b_lamp->type() == BL::Lamp::type_SPOT || b_lamp->type() == BL::Lamp::type_AREA) + { strength = 100.0f; + } closure = graph->add(new EmissionNode()); closure->input("Color")->value = get_float3(b_lamp->color()); diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp index 488fea8d12b..13040e551bd 100644 --- a/intern/cycles/blender/blender_sync.cpp +++ b/intern/cycles/blender/blender_sync.cpp @@ -63,7 +63,7 @@ BlenderSync::~BlenderSync() bool BlenderSync::sync_recalc() { /* sync recalc flags from blender to cycles. actual update is done separate, - so we can do it later on if doing it immediate is not suitable */ + * so we can do it later on if doing it immediate is not suitable */ BL::BlendData::materials_iterator b_mat; @@ -105,10 +105,13 @@ bool BlenderSync::sync_recalc() BL::BlendData::worlds_iterator b_world; - for(b_data.worlds.begin(b_world); b_world != b_data.worlds.end(); ++b_world) + for(b_data.worlds.begin(b_world); b_world != b_data.worlds.end(); ++b_world) { if(world_map == b_world->ptr.data && - (b_world->is_updated() || (b_world->node_tree() && b_world->node_tree().is_updated()))) + (b_world->is_updated() || (b_world->node_tree() && b_world->node_tree().is_updated()))) + { world_recalc = true; + } + } bool recalc = shader_map.has_recalc() || diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h index 10afd468850..8c31c4b86ba 100644 --- a/intern/cycles/blender/blender_sync.h +++ b/intern/cycles/blender/blender_sync.h @@ -63,7 +63,7 @@ public: static SceneParams get_scene_params(BL::Scene b_scene, bool background); static SessionParams get_session_params(BL::UserPreferences b_userpref, BL::Scene b_scene, bool background); static bool get_session_pause(BL::Scene b_scene, bool background); - static BufferParams get_buffer_params(BL::Scene b_scene, BL::RegionView3D b_rv3d, int width, int height); + static BufferParams get_buffer_params(BL::Scene b_scene, Camera *cam, int width, int height); private: /* sync */ @@ -80,17 +80,20 @@ private: void sync_nodes(Shader *shader, BL::ShaderNodeTree b_ntree); Mesh *sync_mesh(BL::Object b_ob, bool object_updated); - void sync_object(BL::Object b_parent, int b_index, BL::Object b_object, Transform& tfm, uint layer_flag, int motion); + void sync_object(BL::Object b_parent, int b_index, BL::Object b_object, Transform& tfm, uint layer_flag, int motion, int particle_id); void sync_light(BL::Object b_parent, int b_index, BL::Object b_ob, Transform& tfm); void sync_background_light(); void sync_mesh_motion(BL::Object b_ob, Mesh *mesh, int motion); void sync_camera_motion(BL::Object b_ob, int motion); + void sync_particles(Object *ob, BL::Object b_ob); /* util */ void find_shader(BL::ID id, vector<uint>& used_shaders, int default_shader); bool BKE_object_is_modified(BL::Object b_ob); bool object_is_mesh(BL::Object b_ob); bool object_is_light(BL::Object b_ob); + bool object_use_particles(BL::Object b_ob); + int object_count_particles(BL::Object b_ob); /* variables */ BL::BlendData b_data; diff --git a/intern/cycles/blender/blender_util.h b/intern/cycles/blender/blender_util.h index b01fa81ee40..b5a76836bed 100644 --- a/intern/cycles/blender/blender_util.h +++ b/intern/cycles/blender/blender_util.h @@ -27,7 +27,7 @@ #include "util_vector.h" /* Hacks to hook into Blender API - todo: clean this up ... */ + * todo: clean this up ... */ extern "C" { @@ -53,6 +53,8 @@ int rna_Object_is_deform_modified(void *ob, void *scene, int settings); void BLI_timestr(double _time, char *str); void rna_ColorRamp_eval(void *coba, float position, float color[4]); void rna_Scene_frame_set(void *scene, int frame, float subframe); +void BKE_image_user_frame_calc(void *iuser, int cfra, int fieldnr); +void BKE_image_user_file_path(void *iuser, void *ima, char *path); } @@ -101,6 +103,14 @@ static inline bool BKE_object_is_deform_modified(BL::Object self, BL::Scene scen return rna_Object_is_deform_modified(self.ptr.data, scene.ptr.data, (preview)? (1<<0): (1<<1))? true: false; } +static inline string image_user_file_path(BL::ImageUser iuser, BL::Image ima, int cfra) +{ + char filepath[1024]; + BKE_image_user_frame_calc(iuser.ptr.data, cfra, 0); + BKE_image_user_file_path(iuser.ptr.data, ima.ptr.data, filepath); + return string(filepath); +} + static inline void scene_frame_set(BL::Scene scene, int frame) { rna_Scene_frame_set(scene.ptr.data, frame, 0.0f); @@ -113,7 +123,7 @@ static inline Transform get_transform(BL::Array<float, 16> array) Transform tfm; /* we assume both types to be just 16 floats, and transpose because blender - use column major matrix order while we use row major */ + * use column major matrix order while we use row major */ memcpy(&tfm, &array, sizeof(float)*16); tfm = transform_transpose(tfm); @@ -156,12 +166,14 @@ static inline uint get_layer(BL::Array<int, 20> array) return layer; } -/*static inline float3 get_float3(PointerRNA& ptr, const char *name) +#if 0 +static inline float3 get_float3(PointerRNA& ptr, const char *name) { float3 f; RNA_float_get_array(&ptr, name, &f.x); return f; -}*/ +} +#endif static inline bool get_boolean(PointerRNA& ptr, const char *name) { diff --git a/intern/cycles/bvh/bvh.cpp b/intern/cycles/bvh/bvh.cpp index 15695dddf45..a383ad317ab 100644 --- a/intern/cycles/bvh/bvh.cpp +++ b/intern/cycles/bvh/bvh.cpp @@ -292,13 +292,13 @@ void BVH::pack_triangles() void BVH::pack_instances(size_t nodes_size) { /* The BVH's for instances are built separately, but for traversal all - BVH's are stored in global arrays. This function merges them into the - top level BVH, adjusting indexes and offsets where appropriate. */ + * BVH's are stored in global arrays. This function merges them into the + * top level BVH, adjusting indexes and offsets where appropriate. */ bool use_qbvh = params.use_qbvh; size_t nsize = (use_qbvh)? BVH_QNODE_SIZE: BVH_NODE_SIZE; /* adjust primitive index to point to the triangle in the global array, for - meshes with transform applied and already in the top level BVH */ + * meshes with transform applied and already in the top level BVH */ for(size_t i = 0; i < pack.prim_index.size(); i++) if(pack.prim_index[i] != -1) pack.prim_index[i] += objects[pack.prim_object[i]]->mesh->tri_offset; @@ -356,14 +356,14 @@ void BVH::pack_instances(size_t nodes_size) Mesh *mesh = ob->mesh; /* if mesh transform is applied, that means it's already in the top - level BVH, and we don't need to merge it in */ + * level BVH, and we don't need to merge it in */ if(mesh->transform_applied) { pack.object_node[object_offset++] = 0; continue; } /* if mesh already added once, don't add it again, but used set - node offset for this object */ + * node offset for this object */ map<Mesh*, int>::iterator it = mesh_map.find(mesh); if(mesh_map.find(mesh) != mesh_map.end()) { diff --git a/intern/cycles/bvh/bvh.h b/intern/cycles/bvh/bvh.h index 30ae7dac106..549f1e3ac1d 100644 --- a/intern/cycles/bvh/bvh.h +++ b/intern/cycles/bvh/bvh.h @@ -46,7 +46,7 @@ class Progress; struct PackedBVH { /* BVH nodes storage, one node is 4x int4, and contains two bounding boxes, - and child, triangle or object indexes dependening on the node type */ + * and child, triangle or object indexes dependening on the node type */ array<int4> nodes; /* object index to BVH node index mapping for instances */ array<int> object_node; @@ -55,12 +55,12 @@ struct PackedBVH { /* visibility visibilitys for primitives */ array<uint> prim_visibility; /* mapping from BVH primitive index to true primitive index, as primitives - may be duplicated due to spatial splits. -1 for instances. */ + * may be duplicated due to spatial splits. -1 for instances. */ array<int> prim_index; /* mapping from BVH primitive index, to the object id of that primitive. */ array<int> prim_object; /* quick array to lookup if a node is a leaf, not used for traversal, only - for instance BVH merging */ + * for instance BVH merging */ array<int> is_leaf; /* index of the root node. */ diff --git a/intern/cycles/bvh/bvh_binning.cpp b/intern/cycles/bvh/bvh_binning.cpp index e4b88584a33..05a674a47a7 100644 --- a/intern/cycles/bvh/bvh_binning.cpp +++ b/intern/cycles/bvh/bvh_binning.cpp @@ -200,7 +200,7 @@ void BVHObjectBinning::split(BVHReference* prims, BVHObjectBinning& left_o, BVHO } /* object medium split if we did not make progress, can happen when all - primitives have same centroid */ + * primitives have same centroid */ lgeom_bounds = BoundBox::empty; rgeom_bounds = BoundBox::empty; lcent_bounds = BoundBox::empty; diff --git a/intern/cycles/bvh/bvh_build.cpp b/intern/cycles/bvh/bvh_build.cpp index 28237aea611..705b805a3a9 100644 --- a/intern/cycles/bvh/bvh_build.cpp +++ b/intern/cycles/bvh/bvh_build.cpp @@ -196,14 +196,14 @@ BVHNode* BVHBuild::run() void BVHBuild::progress_update() { - if(time_dt() - progress_start_time < 0.25f) + if(time_dt() - progress_start_time < 0.25) return; double progress_start = (double)progress_count/(double)progress_total; double duplicates = (double)(progress_total - progress_original_total)/(double)progress_total; string msg = string_printf("Building BVH %.0f%%, duplicates %.0f%%", - progress_start*100.0f, duplicates*100.0f); + progress_start * 100.0, duplicates * 100.0); progress.set_substatus(msg); progress_start_time = time_dt(); diff --git a/intern/cycles/bvh/bvh_node.cpp b/intern/cycles/bvh/bvh_node.cpp index 4edfb4b70a4..7cc9bd333b0 100644 --- a/intern/cycles/bvh/bvh_node.cpp +++ b/intern/cycles/bvh/bvh_node.cpp @@ -52,7 +52,7 @@ int BVHNode::getSubtreeSize(BVH_STAT stat) const } if(!is_leaf()) - for(int i=0;i<num_children();i++) + for(int i = 0; i < num_children(); i++) cnt += get_child(i)->getSubtreeSize(stat); return cnt; @@ -60,7 +60,7 @@ int BVHNode::getSubtreeSize(BVH_STAT stat) const void BVHNode::deleteSubtree() { - for(int i=0;i<num_children();i++) + for(int i = 0; i < num_children(); i++) if(get_child(i)) get_child(i)->deleteSubtree(); @@ -71,7 +71,7 @@ float BVHNode::computeSubtreeSAHCost(const BVHParams& p, float probability) cons { float SAH = probability * p.cost(num_children(), num_triangles()); - for(int i=0;i<num_children();i++) { + for(int i = 0; i < num_children(); i++) { BVHNode *child = get_child(i); SAH += child->computeSubtreeSAHCost(p, probability * child->m_bounds.safe_area()/m_bounds.safe_area()); } diff --git a/intern/cycles/bvh/bvh_params.h b/intern/cycles/bvh/bvh_params.h index 0cf5e905fea..a78496d841d 100644 --- a/intern/cycles/bvh/bvh_params.h +++ b/intern/cycles/bvh/bvh_params.h @@ -98,11 +98,11 @@ class BVHReference public: __forceinline BVHReference() {} - __forceinline BVHReference(const BoundBox& bounds_, int prim_index, int prim_object) + __forceinline BVHReference(const BoundBox& bounds_, int prim_index_, int prim_object_) : rbounds(bounds_) { - rbounds.min.w = __int_as_float(prim_index); - rbounds.max.w = __int_as_float(prim_object); + rbounds.min.w = __int_as_float(prim_index_); + rbounds.max.w = __int_as_float(prim_object_); } __forceinline const BoundBox& bounds() const { return rbounds; } diff --git a/intern/cycles/bvh/bvh_sort.h b/intern/cycles/bvh/bvh_sort.h index ba35ba3fae7..18aafb5f1ff 100644 --- a/intern/cycles/bvh/bvh_sort.h +++ b/intern/cycles/bvh/bvh_sort.h @@ -1,4 +1,4 @@ - /* +/* * Adapted from code copyright 2009-2010 NVIDIA Corporation * Modifications Copyright 2011, Blender Foundation. * diff --git a/intern/cycles/device/device.cpp b/intern/cycles/device/device.cpp index 42dda1180c7..33040f287d1 100644 --- a/intern/cycles/device/device.cpp +++ b/intern/cycles/device/device.cpp @@ -124,7 +124,7 @@ void Device::draw_pixels(device_memory& rgba, int y, int w, int h, int dy, int w uint8_t *pixels = (uint8_t*)rgba.data_pointer; /* for multi devices, this assumes the ineffecient method that we allocate - all pixels on the device even though we only render to a subset */ + * all pixels on the device even though we only render to a subset */ pixels += 4*y*w; glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixels); diff --git a/intern/cycles/device/device_cpu.cpp b/intern/cycles/device/device_cpu.cpp index 5f422332cd2..070b20aec49 100644 --- a/intern/cycles/device/device_cpu.cpp +++ b/intern/cycles/device/device_cpu.cpp @@ -226,7 +226,7 @@ public: void task_add(DeviceTask& task) { /* split task into smaller ones, more than number of threads for uneven - workloads where some parts of the image render slower than others */ + * workloads where some parts of the image render slower than others */ list<DeviceTask> tasks; task.split(tasks, TaskScheduler::num_threads()*10); diff --git a/intern/cycles/device/device_cuda.cpp b/intern/cycles/device/device_cuda.cpp index 491a63a7cf2..357f99145b2 100644 --- a/intern/cycles/device/device_cuda.cpp +++ b/intern/cycles/device/device_cuda.cpp @@ -771,7 +771,7 @@ public: cuda_push_context(); /* for multi devices, this assumes the ineffecient method that we allocate - all pixels on the device even though we only render to a subset */ + * all pixels on the device even though we only render to a subset */ size_t offset = sizeof(uint8_t)*4*y*w; glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pmem.cuPBO); diff --git a/intern/cycles/device/device_network.h b/intern/cycles/device/device_network.h index 591216a77b9..e3afe46d2b0 100644 --- a/intern/cycles/device/device_network.h +++ b/intern/cycles/device/device_network.h @@ -126,8 +126,10 @@ typedef struct RPCReceive { if(len == data_size) { archive_str = (data.size())? string(&data[0], data.size()): string(""); - /*istringstream archive_stream(archive_str); - boost::archive::text_iarchive archive(archive_stream);*/ +#if 0 + istringstream archive_stream(archive_str); + boost::archive::text_iarchive archive(archive_stream); +#endif archive_stream = new istringstream(archive_str); archive = new boost::archive::text_iarchive(*archive_stream); diff --git a/intern/cycles/device/device_opencl.cpp b/intern/cycles/device/device_opencl.cpp index bb2b852d4e1..13ebeff70d2 100644 --- a/intern/cycles/device/device_opencl.cpp +++ b/intern/cycles/device/device_opencl.cpp @@ -239,7 +239,7 @@ public: } /* we don't check CL_DEVICE_VERSION since for e.g. nvidia sm 1.3 cards this is - 1.0 even if the language features are there, just limited shared memory */ + * 1.0 even if the language features are there, just limited shared memory */ return true; } @@ -344,8 +344,8 @@ public: bool compile_kernel(const string& kernel_path, const string& kernel_md5) { /* we compile kernels consisting of many files. unfortunately opencl - kernel caches do not seem to recognize changes in included files. - so we force recompile on changes by adding the md5 hash of all files */ + * kernel caches do not seem to recognize changes in included files. + * so we force recompile on changes by adding the md5 hash of all files */ string source = "#include \"kernel.cl\" // " + kernel_md5 + "\n"; source = path_source_replace_includes(source, kernel_path); @@ -680,8 +680,6 @@ public: else tasks.push_back(maintask); - DeviceTask task; - foreach(DeviceTask& task, tasks) { if(task.type == DeviceTask::TONEMAP) tonemap(task); diff --git a/intern/cycles/kernel/kernel_accumulate.h b/intern/cycles/kernel/kernel_accumulate.h index 6c3ade1c531..d99beb8905a 100644 --- a/intern/cycles/kernel/kernel_accumulate.h +++ b/intern/cycles/kernel/kernel_accumulate.h @@ -271,8 +271,8 @@ __device_inline float3 path_radiance_sum(KernelGlobals *kg, PathRadiance *L) #ifdef __PASSES__ if(L->use_light_pass) { /* this division is a bit ugly, but means we only have to keep track of - only a single throughput further along the path, here we recover just - the indirect parth that is not influenced by any particular BSDF type */ + * only a single throughput further along the path, here we recover just + * the indirect parth that is not influenced by any particular BSDF type */ L->direct_emission = safe_divide_color(L->direct_emission, L->direct_throughput); L->direct_diffuse += L->indirect_diffuse*L->direct_emission; L->direct_glossy += L->indirect_glossy*L->direct_emission; diff --git a/intern/cycles/kernel/kernel_bvh.h b/intern/cycles/kernel/kernel_bvh.h index 522f9861c35..34a44af8b8d 100644 --- a/intern/cycles/kernel/kernel_bvh.h +++ b/intern/cycles/kernel/kernel_bvh.h @@ -34,8 +34,8 @@ CCL_NAMESPACE_BEGIN #define TRI_NODE_SIZE 3 /* silly workaround for float extended precision that happens when compiling - without sse support on x86, it results in different results for float ops - that you would otherwise expect to compare correctly */ + * without sse support on x86, it results in different results for float ops + * that you would otherwise expect to compare correctly */ #if !defined(__i386__) || defined(__SSE__) #define NO_EXTENDED_PRECISION #else @@ -160,7 +160,7 @@ __device_inline void bvh_triangle_intersect(KernelGlobals *kg, Intersection *ise if(v >= 0.0f && u + v <= 1.0f) { #ifdef __VISIBILITY_FLAG__ /* visibility flag test. we do it here under the assumption - that most triangles are culled by node flags */ + * that most triangles are culled by node flags */ if(kernel_tex_fetch(__prim_visibility, triAddr) & visibility) #endif { diff --git a/intern/cycles/kernel/kernel_compat_cpu.h b/intern/cycles/kernel/kernel_compat_cpu.h index 2bd0b61b4fa..cc8f1f3323b 100644 --- a/intern/cycles/kernel/kernel_compat_cpu.h +++ b/intern/cycles/kernel/kernel_compat_cpu.h @@ -28,13 +28,13 @@ CCL_NAMESPACE_BEGIN /* Assertions inside the kernel only work for the CPU device, so we wrap it in - a macro which is empty for other devices */ + * a macro which is empty for other devices */ #define kernel_assert(cond) assert(cond) /* Texture types to be compatible with CUDA textures. These are really just - simple arrays and after inlining fetch hopefully revert to being a simple - pointer lookup. */ + * simple arrays and after inlining fetch hopefully revert to being a simple + * pointer lookup. */ template<typename T> struct texture { T fetch(int index) @@ -43,7 +43,8 @@ template<typename T> struct texture { return data[index]; } - /*__m128 fetch_m128(int index) +#if 0 + __m128 fetch_m128(int index) { kernel_assert(index >= 0 && index < width); return ((__m128*)data)[index]; @@ -53,7 +54,8 @@ template<typename T> struct texture { { kernel_assert(index >= 0 && index < width); return ((__m128i*)data)[index]; - }*/ + } +#endif float interp(float x, int size) { diff --git a/intern/cycles/kernel/kernel_differential.h b/intern/cycles/kernel/kernel_differential.h index 5b4290a7722..04027523ea5 100644 --- a/intern/cycles/kernel/kernel_differential.h +++ b/intern/cycles/kernel/kernel_differential.h @@ -49,9 +49,9 @@ __device void differential_dudv(differential *du, differential *dv, float3 dPdu, * mainly used for differentials of arbitrary mesh attributes. */ /* find most stable axis to project to 2D */ - float xn= fabsf(Ng.x); - float yn= fabsf(Ng.y); - float zn= fabsf(Ng.z); + float xn = fabsf(Ng.x); + float yn = fabsf(Ng.y); + float zn = fabsf(Ng.z); if(zn < xn || zn < yn) { if(yn < xn || yn < zn) { diff --git a/intern/cycles/kernel/kernel_emission.h b/intern/cycles/kernel/kernel_emission.h index 0ef1425e68a..f582ace69f0 100644 --- a/intern/cycles/kernel/kernel_emission.h +++ b/intern/cycles/kernel/kernel_emission.h @@ -44,7 +44,7 @@ __device float3 direct_emissive_eval(KernelGlobals *kg, float rando, ls->Ng = sd.Ng; /* no path flag, we're evaluating this for all closures. that's weak but - we'd have to do multiple evaluations otherwise */ + * we'd have to do multiple evaluations otherwise */ shader_eval_surface(kg, &sd, rando, 0); /* evaluate emissive closure */ @@ -104,13 +104,8 @@ __device bool direct_emission(KernelGlobals *kg, ShaderData *sd, int lindex, float mis_weight = power_heuristic(pdf, bsdf_pdf); light_eval *= mis_weight; } - /* todo: clean up these weights */ - else if(ls.shader & SHADER_AREA_LIGHT) - light_eval *= 0.25f; /* area lamp */ - else if(ls.t != FLT_MAX) - light_eval *= 0.25f*M_1_PI_F; /* point lamp */ - bsdf_eval_mul(eval, light_eval/pdf); + bsdf_eval_mul(eval, light_eval*(ls.eval_fac/pdf)); if(bsdf_eval_is_zero(eval)) return false; @@ -150,7 +145,7 @@ __device float3 indirect_emission(KernelGlobals *kg, ShaderData *sd, float t, in if(!(path_flag & PATH_RAY_MIS_SKIP) && (sd->flag & SD_SAMPLE_AS_LIGHT)) { /* multiple importance sampling, get triangle light pdf, - and compute weight with respect to BSDF pdf */ + * and compute weight with respect to BSDF pdf */ float pdf = triangle_light_pdf(kg, sd->Ng, sd->I, t); float mis_weight = power_heuristic(bsdf_pdf, pdf); @@ -177,7 +172,7 @@ __device float3 indirect_background(KernelGlobals *kg, Ray *ray, int path_flag, if(!(path_flag & PATH_RAY_MIS_SKIP) && res) { /* multiple importance sampling, get background light pdf for ray - direction, and compute weight with respect to BSDF pdf */ + * direction, and compute weight with respect to BSDF pdf */ float pdf = background_light_pdf(kg, ray->D); float mis_weight = power_heuristic(bsdf_pdf, pdf); diff --git a/intern/cycles/kernel/kernel_globals.h b/intern/cycles/kernel/kernel_globals.h index 1f2fc97e685..a99fffbc519 100644 --- a/intern/cycles/kernel/kernel_globals.h +++ b/intern/cycles/kernel/kernel_globals.h @@ -29,9 +29,9 @@ CCL_NAMESPACE_BEGIN /* On the CPU, we pass along the struct KernelGlobals to nearly everywhere in - the kernel, to access constant data. These are all stored as "textures", but - these are really just standard arrays. We can't use actually globals because - multiple renders may be running inside the same process. */ + * the kernel, to access constant data. These are all stored as "textures", but + * these are really just standard arrays. We can't use actually globals because + * multiple renders may be running inside the same process. */ #ifdef __KERNEL_CPU__ @@ -45,7 +45,7 @@ typedef struct KernelGlobals { #ifdef __OSL__ /* On the CPU, we also have the OSL globals here. Most data structures are shared - with SVM, the difference is in the shaders and object/mesh attributes. */ + * with SVM, the difference is in the shaders and object/mesh attributes. */ OSLGlobals osl; #endif @@ -54,9 +54,9 @@ typedef struct KernelGlobals { #endif /* For CUDA, constant memory textures must be globals, so we can't put them - into a struct. As a result we don't actually use this struct and use actual - globals and simply pass along a NULL pointer everywhere, which we hope gets - optimized out. */ + * into a struct. As a result we don't actually use this struct and use actual + * globals and simply pass along a NULL pointer everywhere, which we hope gets + * optimized out. */ #ifdef __KERNEL_CUDA__ diff --git a/intern/cycles/kernel/kernel_light.h b/intern/cycles/kernel/kernel_light.h index e9e7fbd4ca1..edc302cd6e3 100644 --- a/intern/cycles/kernel/kernel_light.h +++ b/intern/cycles/kernel/kernel_light.h @@ -23,6 +23,7 @@ typedef struct LightSample { float3 D; float3 Ng; float t; + float eval_fac; int object; int prim; int shader; @@ -63,8 +64,8 @@ __device float3 area_light_sample(float3 axisu, float3 axisv, float randu, float __device float3 background_light_sample(KernelGlobals *kg, float randu, float randv, float *pdf) { /* for the following, the CDF values are actually a pair of floats, with the - function value as X and the actual CDF as Y. The last entry's function - value is the CDF total. */ + * function value as X and the actual CDF as Y. The last entry's function + * value is the CDF total. */ int res = kernel_data.integrator.pdf_background_res; int cdf_count = res + 1; @@ -189,6 +190,7 @@ __device void regular_light_sample(KernelGlobals *kg, int point, ls->Ng = D; ls->D = -D; ls->t = FLT_MAX; + ls->eval_fac = 1.0f; } #ifdef __BACKGROUND_MIS__ else if(type == LIGHT_BACKGROUND) { @@ -199,6 +201,7 @@ __device void regular_light_sample(KernelGlobals *kg, int point, ls->Ng = D; ls->D = -D; ls->t = FLT_MAX; + ls->eval_fac = 1.0f; } #endif else { @@ -212,6 +215,36 @@ __device void regular_light_sample(KernelGlobals *kg, int point, ls->P += sphere_light_sample(P, ls->P, size, randu, randv); ls->Ng = normalize(P - ls->P); + ls->eval_fac = 0.25f*M_1_PI_F; + } + else if(type == LIGHT_SPOT) { + float4 data2 = kernel_tex_fetch(__light_data, point*LIGHT_SIZE + 2); + float size = data1.y; + + /* spot light */ + if(size > 0.0f) + ls->P += sphere_light_sample(P, ls->P, size, randu, randv); + + float3 dir = make_float3(data1.z, data1.w, data2.x); + float3 I = normalize(P - ls->P); + + float spot_angle = data2.y; + float spot_smooth = data2.z; + + float eval_fac = dot(dir, I); + + if(eval_fac <= spot_angle) { + eval_fac = 0.0f; + } + else { + float t = eval_fac - spot_angle; + + if(t < spot_smooth && spot_smooth != 0.0f) + eval_fac *= smoothstepf(t/spot_smooth); + } + + ls->Ng = I; + ls->eval_fac = eval_fac*0.25f*M_1_PI_F; } else { /* area light */ @@ -224,6 +257,7 @@ __device void regular_light_sample(KernelGlobals *kg, int point, ls->P += area_light_sample(axisu, axisv, randu, randv); ls->Ng = D; + ls->eval_fac = 0.25f; } ls->t = 0.0f; @@ -262,6 +296,7 @@ __device void triangle_light_sample(KernelGlobals *kg, int prim, int object, ls->prim = prim; ls->t = 0.0f; ls->type = LIGHT_AREA; + ls->eval_fac = 1.0f; #ifdef __INSTANCING__ /* instance transform */ @@ -291,9 +326,9 @@ __device float triangle_light_pdf(KernelGlobals *kg, __device int light_distribution_sample(KernelGlobals *kg, float randt) { /* this is basically std::upper_bound as used by pbrt, to find a point light or - triangle to emit from, proportional to area. a good improvement would be to - also sample proportional to power, though it's not so well defined with - OSL shaders. */ + * triangle to emit from, proportional to area. a good improvement would be to + * also sample proportional to power, though it's not so well defined with + * OSL shaders. */ int first = 0; int len = kernel_data.integrator.num_distribution + 1; @@ -356,6 +391,10 @@ __device float light_sample_pdf(KernelGlobals *kg, LightSample *ls, float3 I, fl __device void light_select(KernelGlobals *kg, int index, float randu, float randv, float3 P, LightSample *ls, float *pdf) { regular_light_sample(kg, index, randu, randv, P, ls, pdf); + + /* compute incoming direction and distance */ + if(ls->t != FLT_MAX) + ls->D = normalize_len(ls->P - P, &ls->t); } __device float light_select_pdf(KernelGlobals *kg, LightSample *ls, float3 I, float t) diff --git a/intern/cycles/kernel/kernel_montecarlo.h b/intern/cycles/kernel/kernel_montecarlo.h index bdd147f83d3..939f3915b6c 100644 --- a/intern/cycles/kernel/kernel_montecarlo.h +++ b/intern/cycles/kernel/kernel_montecarlo.h @@ -28,7 +28,7 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ + */ #ifndef __KERNEL_MONTECARLO_CL__ #define __KERNEL_MONTECARLO_CL__ diff --git a/intern/cycles/kernel/kernel_object.h b/intern/cycles/kernel/kernel_object.h index 05c45c490d8..18e0b1e8a87 100644 --- a/intern/cycles/kernel/kernel_object.h +++ b/intern/cycles/kernel/kernel_object.h @@ -154,10 +154,35 @@ __device_inline float object_random_number(KernelGlobals *kg, int object) return f.z; } +__device_inline uint object_particle_id(KernelGlobals *kg, int object) +{ + if(object == ~0) + return 0.0f; + + int offset = object*OBJECT_SIZE + OBJECT_PROPERTIES; + float4 f = kernel_tex_fetch(__objects, offset); + return __float_as_int(f.w); +} + __device int shader_pass_id(KernelGlobals *kg, ShaderData *sd) { return kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2 + 1); } +__device float particle_age(KernelGlobals *kg, int particle) +{ + int offset = particle*PARTICLE_SIZE; + float4 f = kernel_tex_fetch(__particles, offset); + return f.x; +} + +__device float particle_lifetime(KernelGlobals *kg, int particle) +{ + int offset = particle*PARTICLE_SIZE; + float4 f = kernel_tex_fetch(__particles, offset); + return f.y; +} + + CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/kernel_optimized.cpp b/intern/cycles/kernel/kernel_optimized.cpp index 393686bb203..0b662095133 100644 --- a/intern/cycles/kernel/kernel_optimized.cpp +++ b/intern/cycles/kernel/kernel_optimized.cpp @@ -17,8 +17,8 @@ */ /* Optimized CPU kernel entry points. This file is compiled with SSE3 - optimization flags and nearly all functions inlined, while kernel.cpp - is compiled without for other CPU's. */ + * optimization flags and nearly all functions inlined, while kernel.cpp + * is compiled without for other CPU's. */ #ifdef WITH_OPTIMIZED_KERNEL diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h index e0e17ee57dc..8dbf66c108c 100644 --- a/intern/cycles/kernel/kernel_path.h +++ b/intern/cycles/kernel/kernel_path.h @@ -59,7 +59,7 @@ __device_inline void path_state_init(PathState *state) __device_inline void path_state_next(KernelGlobals *kg, PathState *state, int label) { /* ray through transparent keeps same flags from previous ray and is - not counted as a regular bounce, transparent has separate max */ + * not counted as a regular bounce, transparent has separate max */ if(label & LABEL_TRANSPARENT) { state->flag |= PATH_RAY_TRANSPARENT; state->transparent_bounce++; @@ -137,9 +137,12 @@ __device_inline float path_state_terminate_probability(KernelGlobals *kg, PathSt (state->diffuse_bounce >= kernel_data.integrator.max_diffuse_bounce) || (state->glossy_bounce >= kernel_data.integrator.max_glossy_bounce) || (state->transmission_bounce >= kernel_data.integrator.max_transmission_bounce)) + { return 0.0f; - else if(state->bounce <= kernel_data.integrator.min_bounce) + } + else if(state->bounce <= kernel_data.integrator.min_bounce) { return 1.0f; + } } /* probalistic termination */ @@ -159,13 +162,13 @@ __device_inline bool shadow_blocked(KernelGlobals *kg, PathState *state, Ray *ra #ifdef __TRANSPARENT_SHADOWS__ if(result && kernel_data.integrator.transparent_shadows) { /* transparent shadows work in such a way to try to minimize overhead - in cases where we don't need them. after a regular shadow ray is - cast we check if the hit primitive was potentially transparent, and - only in that case start marching. this gives on extra ray cast for - the cases were we do want transparency. - - also note that for this to work correct, multi close sampling must - be used, since we don't pass a random number to shader_eval_surface */ + * in cases where we don't need them. after a regular shadow ray is + * cast we check if the hit primitive was potentially transparent, and + * only in that case start marching. this gives on extra ray cast for + * the cases were we do want transparency. + * + * also note that for this to work correct, multi close sampling must + * be used, since we don't pass a random number to shader_eval_surface */ if(shader_transparent_shadow(kg, &isect)) { float3 throughput = make_float3(1.0f, 1.0f, 1.0f); float3 Pend = ray->P + ray->D*ray->t; @@ -266,7 +269,7 @@ __device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, R kernel_write_data_passes(kg, buffer, &L, &sd, sample, state.flag, throughput); /* blurring of bsdf after bounces, for rays that have a small likelihood - of following this particular path (diffuse, rough glossy) */ + * of following this particular path (diffuse, rough glossy) */ if(kernel_data.integrator.filter_glossy != FLT_MAX) { float blur_pdf = kernel_data.integrator.filter_glossy*min_ray_pdf; @@ -305,8 +308,8 @@ __device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, R #endif /* path termination. this is a strange place to put the termination, it's - mainly due to the mixed in MIS that we use. gives too many unneeded - shader evaluations, only need emission if we are going to terminate */ + * mainly due to the mixed in MIS that we use. gives too many unneeded + * shader evaluations, only need emission if we are going to terminate */ float probability = path_state_terminate_probability(kg, &state, throughput); float terminate = path_rng(kg, rng, sample, rng_offset + PRNG_TERMINATE); @@ -365,7 +368,7 @@ __device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, R #ifdef __MULTI_LIGHT__ /* index -1 means randomly sample from distribution */ - int i = (kernel_data.integrator.num_distribution)? -1: 0; + int i = (kernel_data.integrator.num_all_lights)? 0: -1; for(; i < kernel_data.integrator.num_all_lights; i++) { #else diff --git a/intern/cycles/kernel/kernel_projection.h b/intern/cycles/kernel/kernel_projection.h index 72d36811626..64747bcb42e 100644 --- a/intern/cycles/kernel/kernel_projection.h +++ b/intern/cycles/kernel/kernel_projection.h @@ -28,7 +28,7 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ + */ #ifndef __KERNEL_PROJECTION_CL__ #define __KERNEL_PROJECTION_CL__ diff --git a/intern/cycles/kernel/kernel_random.h b/intern/cycles/kernel/kernel_random.h index 6d15100f8a3..9083b7cbfd7 100644 --- a/intern/cycles/kernel/kernel_random.h +++ b/intern/cycles/kernel/kernel_random.h @@ -23,8 +23,8 @@ typedef uint RNG; #ifdef __SOBOL__ /* skip initial numbers that are not as well distributed, especially the - first sequence is just 0 everywhere, which can be problematic for e.g. - path termination */ + * first sequence is just 0 everywhere, which can be problematic for e.g. + * path termination */ #define SOBOL_SKIP 64 /* High Dimensional Sobol */ @@ -66,7 +66,7 @@ __device uint sobol_inverse(uint i) } /* multidimensional sobol with generator matrices - dimension 0 and 1 are equal to van_der_corput() and sobol() respectively */ + * dimension 0 and 1 are equal to van_der_corput() and sobol() respectively */ __device uint sobol_dimension(KernelGlobals *kg, int index, int dimension) { uint result = 0; @@ -119,7 +119,7 @@ __device_inline float path_rng(KernelGlobals *kg, RNG *rng, int sample, int dime else shift = (*rng & 0xFFFF)/((float)0xFFFF); - return r + shift - floor(r + shift); + return r + shift - floorf(r + shift); #endif } diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h index 8e0d36705ad..53a41d58e20 100644 --- a/intern/cycles/kernel/kernel_shader.h +++ b/intern/cycles/kernel/kernel_shader.h @@ -520,7 +520,7 @@ __device float3 shader_emissive_eval(KernelGlobals *kg, ShaderData *sd) if(CLOSURE_IS_EMISSION(sc->type)) { #ifdef __OSL__ - eval += OSLShader::emissive_eval(sd)*sc->weight; + eval += OSLShader::emissive_eval(sd, sc)*sc->weight; #else eval += svm_emissive_eval(sd, sc)*sc->weight; #endif @@ -624,7 +624,7 @@ __device float3 shader_volume_eval_phase(KernelGlobals *kg, ShaderData *sd, if(CLOSURE_IS_VOLUME(sc->type)) { #ifdef __OSL__ - eval += OSLShader::volume_eval_phase(sd, omega_in, omega_out); + eval += OSLShader::volume_eval_phase(sd, sc, omega_in, omega_out); #else eval += volume_eval_phase(sd, sc, omega_in, omega_out); #endif diff --git a/intern/cycles/kernel/kernel_textures.h b/intern/cycles/kernel/kernel_textures.h index 482f886df3e..c1b8eed3dff 100644 --- a/intern/cycles/kernel/kernel_textures.h +++ b/intern/cycles/kernel/kernel_textures.h @@ -52,6 +52,9 @@ KERNEL_TEX(float4, texture_float4, __light_data) KERNEL_TEX(float2, texture_float2, __light_background_marginal_cdf) KERNEL_TEX(float2, texture_float2, __light_background_conditional_cdf) +/* particles */ +KERNEL_TEX(float4, texture_float4, __particles) + /* shaders */ KERNEL_TEX(uint4, texture_uint4, __svm_nodes) KERNEL_TEX(uint, texture_uint, __shader_flag) diff --git a/intern/cycles/kernel/kernel_triangle.h b/intern/cycles/kernel/kernel_triangle.h index 674c3b52539..384c3a8a506 100644 --- a/intern/cycles/kernel/kernel_triangle.h +++ b/intern/cycles/kernel/kernel_triangle.h @@ -208,7 +208,7 @@ __device float4 triangle_motion_vector(KernelGlobals *kg, ShaderData *sd) motion_post = triangle_attribute_float3(kg, sd, ATTR_ELEMENT_VERTEX, offset_post, NULL, NULL); /* object motion. note that depending on the mesh having motion vectors, this - transformation was set match the world/object space of motion_pre/post */ + * transformation was set match the world/object space of motion_pre/post */ Transform tfm; tfm = object_fetch_transform(kg, sd->object, TIME_INVALID, OBJECT_TRANSFORM_MOTION_PRE); @@ -220,7 +220,7 @@ __device float4 triangle_motion_vector(KernelGlobals *kg, ShaderData *sd) float3 P; /* camera motion, for perspective/orthographic motion.pre/post will be a - world-to-raster matrix, for panorama it's world-to-camera */ + * world-to-raster matrix, for panorama it's world-to-camera */ if (kernel_data.cam.type != CAMERA_PANORAMA) { tfm = kernel_data.cam.worldtoraster; P = transform_perspective(&tfm, sd->P); diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index a64c850d35a..77a800b0e67 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -33,12 +33,16 @@ CCL_NAMESPACE_BEGIN #define LIGHT_SIZE 4 #define FILTER_TABLE_SIZE 256 #define RAMP_TABLE_SIZE 256 +#define PARTICLE_SIZE 1 #define TIME_INVALID FLT_MAX /* device capabilities */ #ifdef __KERNEL_CPU__ #define __KERNEL_SHADING__ #define __KERNEL_ADV_SHADING__ +#ifdef WITH_OSL +#define __OSL__ +#endif #endif #ifdef __KERNEL_CUDA__ @@ -107,7 +111,6 @@ CCL_NAMESPACE_BEGIN #endif //#define __MULTI_LIGHT__ -//#define __OSL__ //#define __SOBOL_FULL_SCREEN__ //#define __QBVH__ @@ -283,7 +286,8 @@ typedef enum LightType { LIGHT_DISTANT, LIGHT_BACKGROUND, LIGHT_AREA, - LIGHT_AO + LIGHT_AO, + LIGHT_SPOT } LightType; /* Camera Type */ @@ -356,6 +360,7 @@ typedef enum AttributeStandard { ATTR_STD_POSITION_UNDISPLACED, ATTR_STD_MOTION_PRE, ATTR_STD_MOTION_POST, + ATTR_STD_PARTICLE, ATTR_STD_NUM, ATTR_STD_NOT_FOUND = ~0 diff --git a/intern/cycles/kernel/osl/background.cpp b/intern/cycles/kernel/osl/background.cpp index c35119ae9cf..81812a46b6c 100644 --- a/intern/cycles/kernel/osl/background.cpp +++ b/intern/cycles/kernel/osl/background.cpp @@ -48,17 +48,17 @@ using namespace OSL; /// class GenericBackgroundClosure : public BackgroundClosure { public: - GenericBackgroundClosure() { } + GenericBackgroundClosure() {} - void setup() {}; + void setup() {}; - size_t memsize () const { return sizeof(*this); } + size_t memsize() const { return sizeof(*this); } - const char *name () const { return "background"; } + const char *name() const { return "background"; } - void print_on (std::ostream &out) const { - out << name() << " ()"; - } + void print_on(std::ostream &out) const { + out << name() << " ()"; + } }; @@ -72,27 +72,29 @@ public: /// class HoldoutClosure : ClosurePrimitive { public: - HoldoutClosure () : ClosurePrimitive (Holdout) { } + HoldoutClosure () : ClosurePrimitive(Holdout) {} - void setup() {}; + void setup() {}; - size_t memsize () const { return sizeof(*this); } + size_t memsize() const { return sizeof(*this); } - const char *name () const { return "holdout"; } + const char *name() const { return "holdout"; } - void print_on (std::ostream &out) const { - out << name() << " ()"; - } + void print_on(std::ostream &out) const { + out << name() << " ()"; + } }; ClosureParam closure_background_params[] = { - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(GenericBackgroundClosure) }; + CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_FINISH_PARAM(GenericBackgroundClosure) +}; CLOSURE_PREPARE(closure_background_prepare, GenericBackgroundClosure) ClosureParam closure_holdout_params[] = { - CLOSURE_FINISH_PARAM(HoldoutClosure) }; + CLOSURE_FINISH_PARAM(HoldoutClosure) +}; CLOSURE_PREPARE(closure_holdout_prepare, HoldoutClosure) diff --git a/intern/cycles/kernel/osl/bsdf_ashikhmin_velvet.cpp b/intern/cycles/kernel/osl/bsdf_ashikhmin_velvet.cpp index a38c5b55cf5..cb6be6959f5 100644 --- a/intern/cycles/kernel/osl/bsdf_ashikhmin_velvet.cpp +++ b/intern/cycles/kernel/osl/bsdf_ashikhmin_velvet.cpp @@ -36,138 +36,142 @@ #include "osl_closures.h" +#include "util_math.h" + CCL_NAMESPACE_BEGIN using namespace OSL; class AshikhminVelvetClosure : public BSDFClosure { public: - Vec3 m_N; - float m_sigma; - float m_invsigma2; - - AshikhminVelvetClosure() : BSDFClosure(Labels::DIFFUSE) { } - - void setup() - { - m_sigma = std::max(m_sigma, 0.01f); - m_invsigma2 = 1.0f/(m_sigma * m_sigma); - } - - bool mergeable (const ClosurePrimitive *other) const { - const AshikhminVelvetClosure *comp = (const AshikhminVelvetClosure *)other; - return m_N == comp->m_N && m_sigma == comp->m_sigma && - BSDFClosure::mergeable(other); - } - - size_t memsize () const { return sizeof(*this); } - - const char *name () const { return "ashikhmin_velvet"; } - - void print_on (std::ostream &out) const - { - out << name() << " ("; - out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), "; - out << m_sigma; - out << ")"; - } - - float albedo (const Vec3 &omega_out) const - { + Vec3 m_N; + float m_sigma; + float m_invsigma2; + + AshikhminVelvetClosure() : BSDFClosure(Labels::DIFFUSE) {} + + void setup() + { + m_sigma = max(m_sigma, 0.01f); + m_invsigma2 = 1.0f / (m_sigma * m_sigma); + } + + bool mergeable(const ClosurePrimitive *other) const { + const AshikhminVelvetClosure *comp = (const AshikhminVelvetClosure *)other; + return m_N == comp->m_N && m_sigma == comp->m_sigma && + BSDFClosure::mergeable(other); + } + + size_t memsize() const { return sizeof(*this); } + + const char *name() const { return "ashikhmin_velvet"; } + + void print_on(std::ostream &out) const + { + out << name() << " ("; + out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), "; + out << m_sigma; + out << ")"; + } + + float albedo(const Vec3 &omega_out) const + { return 1.0f; - } - - Color3 eval_reflect (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - float cosNO = m_N.dot(omega_out); - float cosNI = m_N.dot(omega_in); - if (cosNO > 0 && cosNI > 0) { - Vec3 H = omega_in + omega_out; - H.normalize(); - - float cosNH = m_N.dot(H); - float cosHO = fabsf(omega_out.dot(H)); - - float cosNHdivHO = cosNH / cosHO; - cosNHdivHO = std::max(cosNHdivHO, 0.00001f); - - float fac1 = 2 * fabsf(cosNHdivHO * cosNO); - float fac2 = 2 * fabsf(cosNHdivHO * cosNI); - - float sinNH2 = 1 - cosNH * cosNH; - float sinNH4 = sinNH2 * sinNH2; - float cotangent2 = (cosNH * cosNH) / sinNH2; - - float D = expf(-cotangent2 * m_invsigma2) * m_invsigma2 * float(M_1_PI) / sinNH4; - float G = std::min(1.0f, std::min(fac1, fac2)); // TODO: derive G from D analytically - - float out = 0.25f * (D * G) / cosNO; - - pdf = 0.5f * (float) M_1_PI; - return Color3 (out, out, out); - } - return Color3 (0, 0, 0); - } - - Color3 eval_transmit (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - return Color3 (0, 0, 0); - } - - ustring sample (const Vec3 &Ng, - const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, - float randu, float randv, - Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, - float &pdf, Color3 &eval) const - { - // we are viewing the surface from above - send a ray out with uniform - // distribution over the hemisphere - sample_uniform_hemisphere (m_N, omega_out, randu, randv, omega_in, pdf); - if (Ng.dot(omega_in) > 0) { - Vec3 H = omega_in + omega_out; - H.normalize(); - - float cosNI = m_N.dot(omega_in); - float cosNO = m_N.dot(omega_out); - float cosNH = m_N.dot(H); - float cosHO = fabsf(omega_out.dot(H)); - - float cosNHdivHO = cosNH / cosHO; - cosNHdivHO = std::max(cosNHdivHO, 0.00001f); - - float fac1 = 2 * fabsf(cosNHdivHO * cosNO); - float fac2 = 2 * fabsf(cosNHdivHO * cosNI); - - float sinNH2 = 1 - cosNH * cosNH; - float sinNH4 = sinNH2 * sinNH2; - float cotangent2 = (cosNH * cosNH) / sinNH2; - - float D = expf(-cotangent2 * m_invsigma2) * m_invsigma2 * float(M_1_PI) / sinNH4; - float G = std::min(1.0f, std::min(fac1, fac2)); // TODO: derive G from D analytically - - float power = 0.25f * (D * G) / cosNO; - - eval.setValue(power, power, power); - - // TODO: find a better approximation for the retroreflective bounce - domega_in_dx = (2 * m_N.dot(domega_out_dx)) * m_N - domega_out_dx; - domega_in_dy = (2 * m_N.dot(domega_out_dy)) * m_N - domega_out_dy; - domega_in_dx *= 125; - domega_in_dy *= 125; - } else - pdf = 0; - return Labels::REFLECT; - } + } + + Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const + { + float cosNO = m_N.dot(omega_out); + float cosNI = m_N.dot(omega_in); + if (cosNO > 0 && cosNI > 0) { + Vec3 H = omega_in + omega_out; + H.normalize(); + + float cosNH = m_N.dot(H); + float cosHO = fabsf(omega_out.dot(H)); + + float cosNHdivHO = cosNH / cosHO; + cosNHdivHO = max(cosNHdivHO, 0.00001f); + + float fac1 = 2 * fabsf(cosNHdivHO * cosNO); + float fac2 = 2 * fabsf(cosNHdivHO * cosNI); + + float sinNH2 = 1 - cosNH * cosNH; + float sinNH4 = sinNH2 * sinNH2; + float cotangent2 = (cosNH * cosNH) / sinNH2; + + float D = expf(-cotangent2 * m_invsigma2) * m_invsigma2 * float(M_1_PI) / sinNH4; + float G = min(1.0f, min(fac1, fac2)); // TODO: derive G from D analytically + + float out = 0.25f * (D * G) / cosNO; + + pdf = 0.5f * (float) M_1_PI; + return Color3(out, out, out); + } + return Color3(0, 0, 0); + } + + Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const + { + return Color3(0, 0, 0); + } + + ustring sample(const Vec3 &Ng, + const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, + float randu, float randv, + Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, + float &pdf, Color3 &eval) const + { + // we are viewing the surface from above - send a ray out with uniform + // distribution over the hemisphere + sample_uniform_hemisphere(m_N, omega_out, randu, randv, omega_in, pdf); + if (Ng.dot(omega_in) > 0) { + Vec3 H = omega_in + omega_out; + H.normalize(); + + float cosNI = m_N.dot(omega_in); + float cosNO = m_N.dot(omega_out); + float cosNH = m_N.dot(H); + float cosHO = fabsf(omega_out.dot(H)); + + float cosNHdivHO = cosNH / cosHO; + cosNHdivHO = max(cosNHdivHO, 0.00001f); + + float fac1 = 2 * fabsf(cosNHdivHO * cosNO); + float fac2 = 2 * fabsf(cosNHdivHO * cosNI); + + float sinNH2 = 1 - cosNH * cosNH; + float sinNH4 = sinNH2 * sinNH2; + float cotangent2 = (cosNH * cosNH) / sinNH2; + + float D = expf(-cotangent2 * m_invsigma2) * m_invsigma2 * float(M_1_PI) / sinNH4; + float G = min(1.0f, min(fac1, fac2)); // TODO: derive G from D analytically + + float power = 0.25f * (D * G) / cosNO; + + eval.setValue(power, power, power); + + // TODO: find a better approximation for the retroreflective bounce + domega_in_dx = (2 * m_N.dot(domega_out_dx)) * m_N - domega_out_dx; + domega_in_dy = (2 * m_N.dot(domega_out_dy)) * m_N - domega_out_dy; + domega_in_dx *= 125; + domega_in_dy *= 125; + } + else + pdf = 0; + return Labels::REFLECT; + } }; ClosureParam bsdf_ashikhmin_velvet_params[] = { - CLOSURE_VECTOR_PARAM(AshikhminVelvetClosure, m_N), - CLOSURE_FLOAT_PARAM (AshikhminVelvetClosure, m_sigma), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(AshikhminVelvetClosure) }; + CLOSURE_VECTOR_PARAM(AshikhminVelvetClosure, m_N), + CLOSURE_FLOAT_PARAM(AshikhminVelvetClosure, m_sigma), + CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_FINISH_PARAM(AshikhminVelvetClosure) +}; CLOSURE_PREPARE(bsdf_ashikhmin_velvet_prepare, AshikhminVelvetClosure) diff --git a/intern/cycles/kernel/osl/bsdf_diffuse.cpp b/intern/cycles/kernel/osl/bsdf_diffuse.cpp index 0d4b3fa471f..582ac01d959 100644 --- a/intern/cycles/kernel/osl/bsdf_diffuse.cpp +++ b/intern/cycles/kernel/osl/bsdf_diffuse.cpp @@ -36,143 +36,149 @@ #include "osl_closures.h" +#include "util_math.h" + CCL_NAMESPACE_BEGIN using namespace OSL; class DiffuseClosure : public BSDFClosure { public: - Vec3 m_N; - - DiffuseClosure() : BSDFClosure(Labels::DIFFUSE) { } - - void setup() {}; - - bool mergeable (const ClosurePrimitive *other) const { - const DiffuseClosure *comp = (const DiffuseClosure *)other; - return m_N == comp->m_N && BSDFClosure::mergeable(other); - } - - size_t memsize () const { return sizeof(*this); } - - const char *name () const { return "diffuse"; } - - void print_on (std::ostream &out) const - { - out << name() << " ((" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "))"; - } - - float albedo (const Vec3 &omega_out) const - { - return 1.0f; - } - - Color3 eval_reflect (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - float cos_pi = std::max(m_N.dot(omega_in),0.0f) * (float) M_1_PI; - pdf = cos_pi; - return Color3 (cos_pi, cos_pi, cos_pi); - } - - Color3 eval_transmit (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - return Color3 (0, 0, 0); - } - - ustring sample (const Vec3 &Ng, - const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, - float randu, float randv, - Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, - float &pdf, Color3 &eval) const - { - // we are viewing the surface from the right side - send a ray out with cosine - // distribution over the hemisphere - sample_cos_hemisphere (m_N, omega_out, randu, randv, omega_in, pdf); - if (Ng.dot(omega_in) > 0) { - eval.setValue(pdf, pdf, pdf); - // TODO: find a better approximation for the diffuse bounce - domega_in_dx = (2 * m_N.dot(domega_out_dx)) * m_N - domega_out_dx; - domega_in_dy = (2 * m_N.dot(domega_out_dy)) * m_N - domega_out_dy; - domega_in_dx *= 125; - domega_in_dy *= 125; - } else - pdf = 0; - return Labels::REFLECT; - } + Vec3 m_N; + + DiffuseClosure() : BSDFClosure(Labels::DIFFUSE) {} + + void setup() {}; + + bool mergeable(const ClosurePrimitive *other) const { + const DiffuseClosure *comp = (const DiffuseClosure *)other; + return m_N == comp->m_N && BSDFClosure::mergeable(other); + } + + size_t memsize() const { return sizeof(*this); } + + const char *name() const { return "diffuse"; } + + void print_on(std::ostream &out) const + { + out << name() << " ((" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "))"; + } + + float albedo(const Vec3 &omega_out) const + { + return 1.0f; + } + + Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const + { + float cos_pi = max(m_N.dot(omega_in), 0.0f) * (float) M_1_PI; + pdf = cos_pi; + return Color3(cos_pi, cos_pi, cos_pi); + } + + Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const + { + return Color3(0, 0, 0); + } + + ustring sample(const Vec3 &Ng, + const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, + float randu, float randv, + Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, + float &pdf, Color3 &eval) const + { + // we are viewing the surface from the right side - send a ray out with cosine + // distribution over the hemisphere + sample_cos_hemisphere(m_N, omega_out, randu, randv, omega_in, pdf); + if (Ng.dot(omega_in) > 0) { + eval.setValue(pdf, pdf, pdf); + // TODO: find a better approximation for the diffuse bounce + domega_in_dx = (2 * m_N.dot(domega_out_dx)) * m_N - domega_out_dx; + domega_in_dy = (2 * m_N.dot(domega_out_dy)) * m_N - domega_out_dy; + domega_in_dx *= 125; + domega_in_dy *= 125; + } + else + pdf = 0; + return Labels::REFLECT; + } }; class TranslucentClosure : public BSDFClosure { public: - Vec3 m_N; - - TranslucentClosure() : BSDFClosure(Labels::DIFFUSE, Back) { } - - void setup() {}; - - bool mergeable (const ClosurePrimitive *other) const { - const TranslucentClosure *comp = (const TranslucentClosure *)other; - return m_N == comp->m_N && BSDFClosure::mergeable(other); - } - - size_t memsize () const { return sizeof(*this); } - - const char *name () const { return "translucent"; } - - void print_on (std::ostream &out) const - { - out << name() << " ((" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "))"; - } - - Color3 eval_reflect (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - return Color3 (0, 0, 0); - } - - float albedo (const Vec3 &omega_out) const - { - return 1.0f; - } - - Color3 eval_transmit (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - float cos_pi = std::max(-m_N.dot(omega_in), 0.0f) * (float) M_1_PI; - pdf = cos_pi; - return Color3 (cos_pi, cos_pi, cos_pi); - } - - ustring sample (const Vec3 &Ng, - const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, - float randu, float randv, - Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, - float &pdf, Color3 &eval) const - { - // we are viewing the surface from the right side - send a ray out with cosine - // distribution over the hemisphere - sample_cos_hemisphere (-m_N, omega_out, randu, randv, omega_in, pdf); - if (Ng.dot(omega_in) < 0) { - eval.setValue(pdf, pdf, pdf); - // TODO: find a better approximation for the diffuse bounce - domega_in_dx = (2 * m_N.dot(domega_out_dx)) * m_N - domega_out_dx; - domega_in_dy = (2 * m_N.dot(domega_out_dy)) * m_N - domega_out_dy; - domega_in_dx *= -125; - domega_in_dy *= -125; - } else - pdf = 0; - return Labels::TRANSMIT; - } + Vec3 m_N; + + TranslucentClosure() : BSDFClosure(Labels::DIFFUSE, Back) {} + + void setup() {}; + + bool mergeable(const ClosurePrimitive *other) const { + const TranslucentClosure *comp = (const TranslucentClosure *)other; + return m_N == comp->m_N && BSDFClosure::mergeable(other); + } + + size_t memsize() const { return sizeof(*this); } + + const char *name() const { return "translucent"; } + + void print_on(std::ostream &out) const + { + out << name() << " ((" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "))"; + } + + Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const + { + return Color3(0, 0, 0); + } + + float albedo(const Vec3 &omega_out) const + { + return 1.0f; + } + + Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const + { + float cos_pi = max(-m_N.dot(omega_in), 0.0f) * (float) M_1_PI; + pdf = cos_pi; + return Color3(cos_pi, cos_pi, cos_pi); + } + + ustring sample(const Vec3 &Ng, + const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, + float randu, float randv, + Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, + float &pdf, Color3 &eval) const + { + // we are viewing the surface from the right side - send a ray out with cosine + // distribution over the hemisphere + sample_cos_hemisphere(-m_N, omega_out, randu, randv, omega_in, pdf); + if (Ng.dot(omega_in) < 0) { + eval.setValue(pdf, pdf, pdf); + // TODO: find a better approximation for the diffuse bounce + domega_in_dx = (2 * m_N.dot(domega_out_dx)) * m_N - domega_out_dx; + domega_in_dy = (2 * m_N.dot(domega_out_dy)) * m_N - domega_out_dy; + domega_in_dx *= -125; + domega_in_dy *= -125; + } + else + pdf = 0; + return Labels::TRANSMIT; + } }; ClosureParam bsdf_diffuse_params[] = { - CLOSURE_VECTOR_PARAM (DiffuseClosure, m_N), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM (DiffuseClosure) }; + CLOSURE_VECTOR_PARAM(DiffuseClosure, m_N), + CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_FINISH_PARAM(DiffuseClosure) +}; ClosureParam bsdf_translucent_params[] = { - CLOSURE_VECTOR_PARAM (TranslucentClosure, m_N), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM (TranslucentClosure) }; + CLOSURE_VECTOR_PARAM(TranslucentClosure, m_N), + CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_FINISH_PARAM(TranslucentClosure) +}; CLOSURE_PREPARE(bsdf_diffuse_prepare, DiffuseClosure) CLOSURE_PREPARE(bsdf_translucent_prepare, TranslucentClosure) diff --git a/intern/cycles/kernel/osl/bsdf_microfacet.cpp b/intern/cycles/kernel/osl/bsdf_microfacet.cpp index d87268da81e..09730d8c3e1 100644 --- a/intern/cycles/kernel/osl/bsdf_microfacet.cpp +++ b/intern/cycles/kernel/osl/bsdf_microfacet.cpp @@ -52,85 +52,85 @@ CCL_NAMESPACE_BEGIN template <int Refractive = 0> class MicrofacetGGXClosure : public BSDFClosure { public: - Vec3 m_N; - float m_ag; // width parameter (roughness) - float m_eta; // index of refraction (for fresnel term) - MicrofacetGGXClosure() : BSDFClosure(Labels::GLOSSY, Refractive ? Back : Front) { m_eta = 1.0f; } + Vec3 m_N; + float m_ag; // width parameter (roughness) + float m_eta; // index of refraction (for fresnel term) + MicrofacetGGXClosure() : BSDFClosure(Labels::GLOSSY, Refractive ? Back : Front) { m_eta = 1.0f; } - void setup() + void setup() { m_ag = clamp(m_ag, 1e-5f, 1.0f); } - bool mergeable (const ClosurePrimitive *other) const { - const MicrofacetGGXClosure *comp = (const MicrofacetGGXClosure *)other; - return m_N == comp->m_N && m_ag == comp->m_ag && - m_eta == comp->m_eta && BSDFClosure::mergeable(other); - } + bool mergeable(const ClosurePrimitive *other) const { + const MicrofacetGGXClosure *comp = (const MicrofacetGGXClosure *)other; + return m_N == comp->m_N && m_ag == comp->m_ag && + m_eta == comp->m_eta && BSDFClosure::mergeable(other); + } - size_t memsize () const { return sizeof(*this); } + size_t memsize() const { return sizeof(*this); } - const char *name () const { - return Refractive ? "microfacet_ggx_refraction" : "microfacet_ggx"; - } + const char *name() const { + return Refractive ? "microfacet_ggx_refraction" : "microfacet_ggx"; + } - void print_on (std::ostream &out) const { - out << name() << " ("; - out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), "; - out << m_ag << ", "; - out << m_eta; - out << ")"; - } + void print_on(std::ostream &out) const { + out << name() << " ("; + out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), "; + out << m_ag << ", "; + out << m_eta; + out << ")"; + } - float albedo (const Vec3 &omega_out) const - { + float albedo(const Vec3 &omega_out) const + { return 1.0f; - } - - Color3 eval_reflect (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - if (Refractive == 1) return Color3 (0, 0, 0); - float cosNO = m_N.dot(omega_out); - float cosNI = m_N.dot(omega_in); - if (cosNI > 0 && cosNO > 0) { - // get half vector - Vec3 Hr = omega_in + omega_out; - Hr.normalize(); - // eq. 20: (F*G*D)/(4*in*on) - // eq. 33: first we calculate D(m) with m=Hr: - float alpha2 = m_ag * m_ag; - float cosThetaM = m_N.dot(Hr); - float cosThetaM2 = cosThetaM * cosThetaM; - float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2; - float cosThetaM4 = cosThetaM2 * cosThetaM2; - float D = alpha2 / ((float) M_PI * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2)); - // eq. 34: now calculate G1(i,m) and G1(o,m) - float G1o = 2 / (1 + sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO))); - float G1i = 2 / (1 + sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI))); - float G = G1o * G1i; - float out = (G * D) * 0.25f / cosNO; - // eq. 24 - float pm = D * cosThetaM; - // convert into pdf of the sampled direction - // eq. 38 - but see also: - // eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf - pdf = pm * 0.25f / Hr.dot(omega_out); - return Color3 (out, out, out); - } - return Color3 (0, 0, 0); - } - - Color3 eval_transmit (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - if (Refractive == 0) return Color3 (0, 0, 0); - float cosNO = m_N.dot(omega_out); - float cosNI = m_N.dot(omega_in); - if (cosNO <= 0 || cosNI >= 0) - return Color3 (0, 0, 0); // vectors on same side -- not possible - // compute half-vector of the refraction (eq. 16) - Vec3 ht = -(m_eta * omega_in + omega_out); - Vec3 Ht = ht; Ht.normalize(); - float cosHO = Ht.dot(omega_out); + } + + Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const + { + if (Refractive == 1) return Color3(0, 0, 0); + float cosNO = m_N.dot(omega_out); + float cosNI = m_N.dot(omega_in); + if (cosNI > 0 && cosNO > 0) { + // get half vector + Vec3 Hr = omega_in + omega_out; + Hr.normalize(); + // eq. 20: (F*G*D)/(4*in*on) + // eq. 33: first we calculate D(m) with m=Hr: + float alpha2 = m_ag * m_ag; + float cosThetaM = m_N.dot(Hr); + float cosThetaM2 = cosThetaM * cosThetaM; + float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2; + float cosThetaM4 = cosThetaM2 * cosThetaM2; + float D = alpha2 / ((float) M_PI * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2)); + // eq. 34: now calculate G1(i,m) and G1(o,m) + float G1o = 2 / (1 + sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO))); + float G1i = 2 / (1 + sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI))); + float G = G1o * G1i; + float out = (G * D) * 0.25f / cosNO; + // eq. 24 + float pm = D * cosThetaM; + // convert into pdf of the sampled direction + // eq. 38 - but see also: + // eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf + pdf = pm * 0.25f / Hr.dot(omega_out); + return Color3(out, out, out); + } + return Color3(0, 0, 0); + } + + Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const + { + if (Refractive == 0) return Color3(0, 0, 0); + float cosNO = m_N.dot(omega_out); + float cosNI = m_N.dot(omega_in); + if (cosNO <= 0 || cosNI >= 0) + return Color3(0, 0, 0); // vectors on same side -- not possible + // compute half-vector of the refraction (eq. 16) + Vec3 ht = -(m_eta * omega_in + omega_out); + Vec3 Ht = ht; Ht.normalize(); + float cosHO = Ht.dot(omega_out); float cosHI = Ht.dot(omega_in); // eq. 33: first we calculate D(m) with m=Ht: @@ -148,122 +148,123 @@ public: float invHt2 = 1 / ht.dot(ht); pdf = D * fabsf(cosThetaM) * (fabsf(cosHI) * (m_eta * m_eta)) * invHt2; float out = (fabsf(cosHI * cosHO) * (m_eta * m_eta) * (G * D) * invHt2) / cosNO; - return Color3 (out, out, out); - } - - ustring sample (const Vec3 &Ng, - const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, - float randu, float randv, - Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, - float &pdf, Color3 &eval) const - { - float cosNO = m_N.dot(omega_out); - if (cosNO > 0) { - Vec3 X, Y, Z = m_N; - make_orthonormals(Z, X, Y); - // generate a random microfacet normal m - // eq. 35,36: - // we take advantage of cos(atan(x)) == 1/sqrt(1+x^2) - // and sin(atan(x)) == x/sqrt(1+x^2) - float alpha2 = m_ag * m_ag; - float tanThetaM2 = alpha2 * randu / (1 - randu); - float cosThetaM = 1 / sqrtf(1 + tanThetaM2); - float sinThetaM = cosThetaM * sqrtf(tanThetaM2); - float phiM = 2 * float(M_PI) * randv; - Vec3 m = (cosf(phiM) * sinThetaM) * X + - (sinf(phiM) * sinThetaM) * Y + - cosThetaM * Z; - if (Refractive == 0) { - float cosMO = m.dot(omega_out); - if (cosMO > 0) { - // eq. 39 - compute actual reflected direction - omega_in = 2 * cosMO * m - omega_out; - if (Ng.dot(omega_in) > 0) { - // microfacet normal is visible to this ray - // eq. 33 - float cosThetaM2 = cosThetaM * cosThetaM; - float cosThetaM4 = cosThetaM2 * cosThetaM2; - float D = alpha2 / (float(M_PI) * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2)); - // eq. 24 - float pm = D * cosThetaM; - // convert into pdf of the sampled direction - // eq. 38 - but see also: - // eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf - pdf = pm * 0.25f / cosMO; - // eval BRDF*cosNI - float cosNI = m_N.dot(omega_in); - // eq. 34: now calculate G1(i,m) and G1(o,m) - float G1o = 2 / (1 + sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO))); - float G1i = 2 / (1 + sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI))); - float G = G1o * G1i; - // eq. 20: (F*G*D)/(4*in*on) - float out = (G * D) * 0.25f / cosNO; - eval.setValue(out, out, out); - domega_in_dx = (2 * m.dot(domega_out_dx)) * m - domega_out_dx; - domega_in_dy = (2 * m.dot(domega_out_dy)) * m - domega_out_dy; + return Color3(out, out, out); + } + + ustring sample(const Vec3 &Ng, + const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, + float randu, float randv, + Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, + float &pdf, Color3 &eval) const + { + float cosNO = m_N.dot(omega_out); + if (cosNO > 0) { + Vec3 X, Y, Z = m_N; + make_orthonormals(Z, X, Y); + // generate a random microfacet normal m + // eq. 35,36: + // we take advantage of cos(atan(x)) == 1/sqrt(1+x^2) + // and sin(atan(x)) == x/sqrt(1+x^2) + float alpha2 = m_ag * m_ag; + float tanThetaM2 = alpha2 * randu / (1 - randu); + float cosThetaM = 1 / sqrtf(1 + tanThetaM2); + float sinThetaM = cosThetaM * sqrtf(tanThetaM2); + float phiM = 2 * float(M_PI) * randv; + Vec3 m = (cosf(phiM) * sinThetaM) * X + + (sinf(phiM) * sinThetaM) * Y + + cosThetaM * Z; + if (Refractive == 0) { + float cosMO = m.dot(omega_out); + if (cosMO > 0) { + // eq. 39 - compute actual reflected direction + omega_in = 2 * cosMO * m - omega_out; + if (Ng.dot(omega_in) > 0) { + // microfacet normal is visible to this ray + // eq. 33 + float cosThetaM2 = cosThetaM * cosThetaM; + float cosThetaM4 = cosThetaM2 * cosThetaM2; + float D = alpha2 / (float(M_PI) * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2)); + // eq. 24 + float pm = D * cosThetaM; + // convert into pdf of the sampled direction + // eq. 38 - but see also: + // eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf + pdf = pm * 0.25f / cosMO; + // eval BRDF*cosNI + float cosNI = m_N.dot(omega_in); + // eq. 34: now calculate G1(i,m) and G1(o,m) + float G1o = 2 / (1 + sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO))); + float G1i = 2 / (1 + sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI))); + float G = G1o * G1i; + // eq. 20: (F*G*D)/(4*in*on) + float out = (G * D) * 0.25f / cosNO; + eval.setValue(out, out, out); + domega_in_dx = (2 * m.dot(domega_out_dx)) * m - domega_out_dx; + domega_in_dy = (2 * m.dot(domega_out_dy)) * m - domega_out_dy; /* disabled for now - gives texture filtering problems */ #if 0 - // Since there is some blur to this reflection, make the - // derivatives a bit bigger. In theory this varies with the - // roughness but the exact relationship is complex and - // requires more ops than are practical. - domega_in_dx *= 10; - domega_in_dy *= 10; + // Since there is some blur to this reflection, make the + // derivatives a bit bigger. In theory this varies with the + // roughness but the exact relationship is complex and + // requires more ops than are practical. + domega_in_dx *= 10; + domega_in_dy *= 10; #endif - } - } - } else { - // CAUTION: the i and o variables are inverted relative to the paper - // eq. 39 - compute actual refractive direction - Vec3 R, dRdx, dRdy; - Vec3 T, dTdx, dTdy; - bool inside; - fresnel_dielectric(m_eta, m, omega_out, domega_out_dx, domega_out_dy, - R, dRdx, dRdy, - T, dTdx, dTdy, - inside); - - if (!inside) { - omega_in = T; - domega_in_dx = dTdx; - domega_in_dy = dTdy; - // eq. 33 - float cosThetaM2 = cosThetaM * cosThetaM; - float cosThetaM4 = cosThetaM2 * cosThetaM2; - float D = alpha2 / (float(M_PI) * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2)); - // eq. 24 - float pm = D * cosThetaM; - // eval BRDF*cosNI - float cosNI = m_N.dot(omega_in); - // eq. 34: now calculate G1(i,m) and G1(o,m) - float G1o = 2 / (1 + sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO))); - float G1i = 2 / (1 + sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI))); - float G = G1o * G1i; - // eq. 21 - float cosHI = m.dot(omega_in); - float cosHO = m.dot(omega_out); - float Ht2 = m_eta * cosHI + cosHO; - Ht2 *= Ht2; - float out = (fabsf(cosHI * cosHO) * (m_eta * m_eta) * (G * D)) / (cosNO * Ht2); - // eq. 38 and eq. 17 - pdf = pm * (m_eta * m_eta) * fabsf(cosHI) / Ht2; - eval.setValue(out, out, out); + } + } + } + else { + // CAUTION: the i and o variables are inverted relative to the paper + // eq. 39 - compute actual refractive direction + Vec3 R, dRdx, dRdy; + Vec3 T, dTdx, dTdy; + bool inside; + fresnel_dielectric(m_eta, m, omega_out, domega_out_dx, domega_out_dy, + R, dRdx, dRdy, + T, dTdx, dTdy, + inside); + + if (!inside) { + omega_in = T; + domega_in_dx = dTdx; + domega_in_dy = dTdy; + // eq. 33 + float cosThetaM2 = cosThetaM * cosThetaM; + float cosThetaM4 = cosThetaM2 * cosThetaM2; + float D = alpha2 / (float(M_PI) * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2)); + // eq. 24 + float pm = D * cosThetaM; + // eval BRDF*cosNI + float cosNI = m_N.dot(omega_in); + // eq. 34: now calculate G1(i,m) and G1(o,m) + float G1o = 2 / (1 + sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO))); + float G1i = 2 / (1 + sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI))); + float G = G1o * G1i; + // eq. 21 + float cosHI = m.dot(omega_in); + float cosHO = m.dot(omega_out); + float Ht2 = m_eta * cosHI + cosHO; + Ht2 *= Ht2; + float out = (fabsf(cosHI * cosHO) * (m_eta * m_eta) * (G * D)) / (cosNO * Ht2); + // eq. 38 and eq. 17 + pdf = pm * (m_eta * m_eta) * fabsf(cosHI) / Ht2; + eval.setValue(out, out, out); /* disabled for now - gives texture filtering problems */ #if 0 - // Since there is some blur to this refraction, make the - // derivatives a bit bigger. In theory this varies with the - // roughness but the exact relationship is complex and - // requires more ops than are practical. - domega_in_dx *= 10; - domega_in_dy *= 10; + // Since there is some blur to this refraction, make the + // derivatives a bit bigger. In theory this varies with the + // roughness but the exact relationship is complex and + // requires more ops than are practical. + domega_in_dx *= 10; + domega_in_dy *= 10; #endif - } - } - } - return Refractive ? Labels::TRANSMIT : Labels::REFLECT; - } + } + } + } + return Refractive ? Labels::TRANSMIT : Labels::REFLECT; + } }; // microfacet model with Beckmann facet distribution @@ -271,89 +272,92 @@ public: template <int Refractive = 0> class MicrofacetBeckmannClosure : public BSDFClosure { public: - Vec3 m_N; - float m_ab; // width parameter (roughness) - float m_eta; // index of refraction (for fresnel term) - MicrofacetBeckmannClosure() : BSDFClosure(Labels::GLOSSY, Refractive ? Back : Front) { } + Vec3 m_N; + float m_ab; // width parameter (roughness) + float m_eta; // index of refraction (for fresnel term) + MicrofacetBeckmannClosure() : BSDFClosure(Labels::GLOSSY, Refractive ? Back : Front) { + } - void setup() + void setup() { m_ab = clamp(m_ab, 1e-5f, 1.0f); } - bool mergeable (const ClosurePrimitive *other) const { - const MicrofacetBeckmannClosure *comp = (const MicrofacetBeckmannClosure *)other; - return m_N == comp->m_N && m_ab == comp->m_ab && - m_eta == comp->m_eta && BSDFClosure::mergeable(other); - } - - size_t memsize () const { return sizeof(*this); } - - const char * name () const { - return Refractive ? "microfacet_beckmann_refraction" - : "microfacet_beckmann"; - } - - void print_on (std::ostream &out) const - { - out << name() << " ("; - out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), "; - out << m_ab << ", "; - out << m_eta; - out << ")"; - } - - float albedo (const Vec3 &omega_out) const - { + bool mergeable(const ClosurePrimitive *other) const { + const MicrofacetBeckmannClosure *comp = (const MicrofacetBeckmannClosure *)other; + return m_N == comp->m_N && m_ab == comp->m_ab && + m_eta == comp->m_eta && BSDFClosure::mergeable(other); + } + + size_t memsize() const { + return sizeof(*this); + } + + const char *name() const { + return Refractive ? "microfacet_beckmann_refraction" + : "microfacet_beckmann"; + } + + void print_on(std::ostream &out) const + { + out << name() << " ("; + out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), "; + out << m_ab << ", "; + out << m_eta; + out << ")"; + } + + float albedo(const Vec3 &omega_out) const + { return 1.0f; - } - - Color3 eval_reflect (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - if (Refractive == 1) return Color3 (0, 0, 0); - float cosNO = m_N.dot(omega_out); - float cosNI = m_N.dot(omega_in); - if (cosNO > 0 && cosNI > 0) { - // get half vector - Vec3 Hr = omega_in + omega_out; - Hr.normalize(); - // eq. 20: (F*G*D)/(4*in*on) - // eq. 25: first we calculate D(m) with m=Hr: - float alpha2 = m_ab * m_ab; - float cosThetaM = m_N.dot(Hr); - float cosThetaM2 = cosThetaM * cosThetaM; - float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2; - float cosThetaM4 = cosThetaM2 * cosThetaM2; - float D = expf(-tanThetaM2 / alpha2) / (float(M_PI) * alpha2 * cosThetaM4); - // eq. 26, 27: now calculate G1(i,m) and G1(o,m) - float ao = 1 / (m_ab * sqrtf((1 - cosNO * cosNO) / (cosNO * cosNO))); - float ai = 1 / (m_ab * sqrtf((1 - cosNI * cosNI) / (cosNI * cosNI))); - float G1o = ao < 1.6f ? (3.535f * ao + 2.181f * ao * ao) / (1 + 2.276f * ao + 2.577f * ao * ao) : 1.0f; - float G1i = ai < 1.6f ? (3.535f * ai + 2.181f * ai * ai) / (1 + 2.276f * ai + 2.577f * ai * ai) : 1.0f; - float G = G1o * G1i; - float out = (G * D) * 0.25f / cosNO; - // eq. 24 - float pm = D * cosThetaM; - // convert into pdf of the sampled direction - // eq. 38 - but see also: - // eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf - pdf = pm * 0.25f / Hr.dot(omega_out); - return Color3 (out, out, out); - } - return Color3 (0, 0, 0); - } - - Color3 eval_transmit (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - if (Refractive == 0) return Color3 (0, 0, 0); - float cosNO = m_N.dot(omega_out); - float cosNI = m_N.dot(omega_in); - if (cosNO <= 0 || cosNI >= 0) - return Color3 (0, 0, 0); - // compute half-vector of the refraction (eq. 16) - Vec3 ht = -(m_eta * omega_in + omega_out); - Vec3 Ht = ht; Ht.normalize(); - float cosHO = Ht.dot(omega_out); + } + + Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const + { + if (Refractive == 1) return Color3(0, 0, 0); + float cosNO = m_N.dot(omega_out); + float cosNI = m_N.dot(omega_in); + if (cosNO > 0 && cosNI > 0) { + // get half vector + Vec3 Hr = omega_in + omega_out; + Hr.normalize(); + // eq. 20: (F*G*D)/(4*in*on) + // eq. 25: first we calculate D(m) with m=Hr: + float alpha2 = m_ab * m_ab; + float cosThetaM = m_N.dot(Hr); + float cosThetaM2 = cosThetaM * cosThetaM; + float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2; + float cosThetaM4 = cosThetaM2 * cosThetaM2; + float D = expf(-tanThetaM2 / alpha2) / (float(M_PI) * alpha2 * cosThetaM4); + // eq. 26, 27: now calculate G1(i,m) and G1(o,m) + float ao = 1 / (m_ab * sqrtf((1 - cosNO * cosNO) / (cosNO * cosNO))); + float ai = 1 / (m_ab * sqrtf((1 - cosNI * cosNI) / (cosNI * cosNI))); + float G1o = ao < 1.6f ? (3.535f * ao + 2.181f * ao * ao) / (1 + 2.276f * ao + 2.577f * ao * ao) : 1.0f; + float G1i = ai < 1.6f ? (3.535f * ai + 2.181f * ai * ai) / (1 + 2.276f * ai + 2.577f * ai * ai) : 1.0f; + float G = G1o * G1i; + float out = (G * D) * 0.25f / cosNO; + // eq. 24 + float pm = D * cosThetaM; + // convert into pdf of the sampled direction + // eq. 38 - but see also: + // eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf + pdf = pm * 0.25f / Hr.dot(omega_out); + return Color3(out, out, out); + } + return Color3(0, 0, 0); + } + + Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const + { + if (Refractive == 0) return Color3(0, 0, 0); + float cosNO = m_N.dot(omega_out); + float cosNI = m_N.dot(omega_in); + if (cosNO <= 0 || cosNI >= 0) + return Color3(0, 0, 0); + // compute half-vector of the refraction (eq. 16) + Vec3 ht = -(m_eta * omega_in + omega_out); + Vec3 Ht = ht; Ht.normalize(); + float cosHO = Ht.dot(omega_out); float cosHI = Ht.dot(omega_in); // eq. 33: first we calculate D(m) with m=Ht: @@ -373,156 +377,161 @@ public: float invHt2 = 1 / ht.dot(ht); pdf = D * fabsf(cosThetaM) * (fabsf(cosHI) * (m_eta * m_eta)) * invHt2; float out = (fabsf(cosHI * cosHO) * (m_eta * m_eta) * (G * D) * invHt2) / cosNO; - return Color3 (out, out, out); - } - - ustring sample (const Vec3 &Ng, - const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, - float randu, float randv, - Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, - float &pdf, Color3 &eval) const - { - float cosNO = m_N.dot(omega_out); - if (cosNO > 0) { - Vec3 X, Y, Z = m_N; - make_orthonormals(Z, X, Y); - // generate a random microfacet normal m - // eq. 35,36: - // we take advantage of cos(atan(x)) == 1/sqrt(1+x^2) - // and sin(atan(x)) == x/sqrt(1+x^2) - float alpha2 = m_ab * m_ab; - float tanThetaM = sqrtf(-alpha2 * logf(1 - randu)); - float cosThetaM = 1 / sqrtf(1 + tanThetaM * tanThetaM); - float sinThetaM = cosThetaM * tanThetaM; - float phiM = 2 * float(M_PI) * randv; - Vec3 m = (cosf(phiM) * sinThetaM) * X + - (sinf(phiM) * sinThetaM) * Y + - cosThetaM * Z; - if (Refractive == 0) { - float cosMO = m.dot(omega_out); - if (cosMO > 0) { - // eq. 39 - compute actual reflected direction - omega_in = 2 * cosMO * m - omega_out; - if (Ng.dot(omega_in) > 0) { - // microfacet normal is visible to this ray - // eq. 25 - float cosThetaM2 = cosThetaM * cosThetaM; - float tanThetaM2 = tanThetaM * tanThetaM; - float cosThetaM4 = cosThetaM2 * cosThetaM2; - float D = expf(-tanThetaM2 / alpha2) / (float(M_PI) * alpha2 * cosThetaM4); - // eq. 24 - float pm = D * cosThetaM; - // convert into pdf of the sampled direction - // eq. 38 - but see also: - // eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf - pdf = pm * 0.25f / cosMO; - // Eval BRDF*cosNI - float cosNI = m_N.dot(omega_in); - // eq. 26, 27: now calculate G1(i,m) and G1(o,m) - float ao = 1 / (m_ab * sqrtf((1 - cosNO * cosNO) / (cosNO * cosNO))); - float ai = 1 / (m_ab * sqrtf((1 - cosNI * cosNI) / (cosNI * cosNI))); - float G1o = ao < 1.6f ? (3.535f * ao + 2.181f * ao * ao) / (1 + 2.276f * ao + 2.577f * ao * ao) : 1.0f; - float G1i = ai < 1.6f ? (3.535f * ai + 2.181f * ai * ai) / (1 + 2.276f * ai + 2.577f * ai * ai) : 1.0f; - float G = G1o * G1i; - // eq. 20: (F*G*D)/(4*in*on) - float out = (G * D) * 0.25f / cosNO; - eval.setValue(out, out, out); - domega_in_dx = (2 * m.dot(domega_out_dx)) * m - domega_out_dx; - domega_in_dy = (2 * m.dot(domega_out_dy)) * m - domega_out_dy; + return Color3(out, out, out); + } + + ustring sample(const Vec3 &Ng, + const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, + float randu, float randv, + Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, + float &pdf, Color3 &eval) const + { + float cosNO = m_N.dot(omega_out); + if (cosNO > 0) { + Vec3 X, Y, Z = m_N; + make_orthonormals(Z, X, Y); + // generate a random microfacet normal m + // eq. 35,36: + // we take advantage of cos(atan(x)) == 1/sqrt(1+x^2) + // and sin(atan(x)) == x/sqrt(1+x^2) + float alpha2 = m_ab * m_ab; + float tanThetaM = sqrtf(-alpha2 * logf(1 - randu)); + float cosThetaM = 1 / sqrtf(1 + tanThetaM * tanThetaM); + float sinThetaM = cosThetaM * tanThetaM; + float phiM = 2 * float(M_PI) * randv; + Vec3 m = (cosf(phiM) * sinThetaM) * X + + (sinf(phiM) * sinThetaM) * Y + + cosThetaM * Z; + if (Refractive == 0) { + float cosMO = m.dot(omega_out); + if (cosMO > 0) { + // eq. 39 - compute actual reflected direction + omega_in = 2 * cosMO * m - omega_out; + if (Ng.dot(omega_in) > 0) { + // microfacet normal is visible to this ray + // eq. 25 + float cosThetaM2 = cosThetaM * cosThetaM; + float tanThetaM2 = tanThetaM * tanThetaM; + float cosThetaM4 = cosThetaM2 * cosThetaM2; + float D = expf(-tanThetaM2 / alpha2) / (float(M_PI) * alpha2 * cosThetaM4); + // eq. 24 + float pm = D * cosThetaM; + // convert into pdf of the sampled direction + // eq. 38 - but see also: + // eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf + pdf = pm * 0.25f / cosMO; + // Eval BRDF*cosNI + float cosNI = m_N.dot(omega_in); + // eq. 26, 27: now calculate G1(i,m) and G1(o,m) + float ao = 1 / (m_ab * sqrtf((1 - cosNO * cosNO) / (cosNO * cosNO))); + float ai = 1 / (m_ab * sqrtf((1 - cosNI * cosNI) / (cosNI * cosNI))); + float G1o = ao < 1.6f ? (3.535f * ao + 2.181f * ao * ao) / (1 + 2.276f * ao + 2.577f * ao * ao) : 1.0f; + float G1i = ai < 1.6f ? (3.535f * ai + 2.181f * ai * ai) / (1 + 2.276f * ai + 2.577f * ai * ai) : 1.0f; + float G = G1o * G1i; + // eq. 20: (F*G*D)/(4*in*on) + float out = (G * D) * 0.25f / cosNO; + eval.setValue(out, out, out); + domega_in_dx = (2 * m.dot(domega_out_dx)) * m - domega_out_dx; + domega_in_dy = (2 * m.dot(domega_out_dy)) * m - domega_out_dy; /* disabled for now - gives texture filtering problems */ #if 0 - // Since there is some blur to this reflection, make the - // derivatives a bit bigger. In theory this varies with the - // roughness but the exact relationship is complex and - // requires more ops than are practical. - domega_in_dx *= 10; - domega_in_dy *= 10; + // Since there is some blur to this reflection, make the + // derivatives a bit bigger. In theory this varies with the + // roughness but the exact relationship is complex and + // requires more ops than are practical. + domega_in_dx *= 10; + domega_in_dy *= 10; #endif - } - } - } else { - // CAUTION: the i and o variables are inverted relative to the paper - // eq. 39 - compute actual refractive direction - Vec3 R, dRdx, dRdy; - Vec3 T, dTdx, dTdy; - bool inside; - fresnel_dielectric(m_eta, m, omega_out, domega_out_dx, domega_out_dy, - R, dRdx, dRdy, - T, dTdx, dTdy, - inside); - if (!inside) { - omega_in = T; - domega_in_dx = dTdx; - domega_in_dy = dTdy; - // eq. 33 - float cosThetaM2 = cosThetaM * cosThetaM; - float tanThetaM2 = tanThetaM * tanThetaM; - float cosThetaM4 = cosThetaM2 * cosThetaM2; - float D = expf(-tanThetaM2 / alpha2) / (float(M_PI) * alpha2 * cosThetaM4); - // eq. 24 - float pm = D * cosThetaM; - // eval BRDF*cosNI - float cosNI = m_N.dot(omega_in); - // eq. 26, 27: now calculate G1(i,m) and G1(o,m) - float ao = 1 / (m_ab * sqrtf((1 - cosNO * cosNO) / (cosNO * cosNO))); - float ai = 1 / (m_ab * sqrtf((1 - cosNI * cosNI) / (cosNI * cosNI))); - float G1o = ao < 1.6f ? (3.535f * ao + 2.181f * ao * ao) / (1 + 2.276f * ao + 2.577f * ao * ao) : 1.0f; - float G1i = ai < 1.6f ? (3.535f * ai + 2.181f * ai * ai) / (1 + 2.276f * ai + 2.577f * ai * ai) : 1.0f; - float G = G1o * G1i; - // eq. 21 - float cosHI = m.dot(omega_in); - float cosHO = m.dot(omega_out); - float Ht2 = m_eta * cosHI + cosHO; - Ht2 *= Ht2; - float out = (fabsf(cosHI * cosHO) * (m_eta * m_eta) * (G * D)) / (cosNO * Ht2); - // eq. 38 and eq. 17 - pdf = pm * (m_eta * m_eta) * fabsf(cosHI) / Ht2; - eval.setValue(out, out, out); + } + } + } + else { + // CAUTION: the i and o variables are inverted relative to the paper + // eq. 39 - compute actual refractive direction + Vec3 R, dRdx, dRdy; + Vec3 T, dTdx, dTdy; + bool inside; + fresnel_dielectric(m_eta, m, omega_out, domega_out_dx, domega_out_dy, + R, dRdx, dRdy, + T, dTdx, dTdy, + inside); + if (!inside) { + omega_in = T; + domega_in_dx = dTdx; + domega_in_dy = dTdy; + // eq. 33 + float cosThetaM2 = cosThetaM * cosThetaM; + float tanThetaM2 = tanThetaM * tanThetaM; + float cosThetaM4 = cosThetaM2 * cosThetaM2; + float D = expf(-tanThetaM2 / alpha2) / (float(M_PI) * alpha2 * cosThetaM4); + // eq. 24 + float pm = D * cosThetaM; + // eval BRDF*cosNI + float cosNI = m_N.dot(omega_in); + // eq. 26, 27: now calculate G1(i,m) and G1(o,m) + float ao = 1 / (m_ab * sqrtf((1 - cosNO * cosNO) / (cosNO * cosNO))); + float ai = 1 / (m_ab * sqrtf((1 - cosNI * cosNI) / (cosNI * cosNI))); + float G1o = ao < 1.6f ? (3.535f * ao + 2.181f * ao * ao) / (1 + 2.276f * ao + 2.577f * ao * ao) : 1.0f; + float G1i = ai < 1.6f ? (3.535f * ai + 2.181f * ai * ai) / (1 + 2.276f * ai + 2.577f * ai * ai) : 1.0f; + float G = G1o * G1i; + // eq. 21 + float cosHI = m.dot(omega_in); + float cosHO = m.dot(omega_out); + float Ht2 = m_eta * cosHI + cosHO; + Ht2 *= Ht2; + float out = (fabsf(cosHI * cosHO) * (m_eta * m_eta) * (G * D)) / (cosNO * Ht2); + // eq. 38 and eq. 17 + pdf = pm * (m_eta * m_eta) * fabsf(cosHI) / Ht2; + eval.setValue(out, out, out); /* disabled for now - gives texture filtering problems */ #if 0 - // Since there is some blur to this refraction, make the - // derivatives a bit bigger. In theory this varies with the - // roughness but the exact relationship is complex and - // requires more ops than are practical. - domega_in_dx *= 10; - domega_in_dy *= 10; + // Since there is some blur to this refraction, make the + // derivatives a bit bigger. In theory this varies with the + // roughness but the exact relationship is complex and + // requires more ops than are practical. + domega_in_dx *= 10; + domega_in_dy *= 10; #endif - } - } - } - return Refractive ? Labels::TRANSMIT : Labels::REFLECT; - } + } + } + } + return Refractive ? Labels::TRANSMIT : Labels::REFLECT; + } }; ClosureParam bsdf_microfacet_ggx_params[] = { - CLOSURE_VECTOR_PARAM(MicrofacetGGXClosure<0>, m_N), - CLOSURE_FLOAT_PARAM (MicrofacetGGXClosure<0>, m_ag), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(MicrofacetGGXClosure<0>) }; + CLOSURE_VECTOR_PARAM(MicrofacetGGXClosure<0>, m_N), + CLOSURE_FLOAT_PARAM(MicrofacetGGXClosure<0>, m_ag), + CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_FINISH_PARAM(MicrofacetGGXClosure<0>) +}; ClosureParam bsdf_microfacet_ggx_refraction_params[] = { - CLOSURE_VECTOR_PARAM(MicrofacetGGXClosure<1>, m_N), - CLOSURE_FLOAT_PARAM (MicrofacetGGXClosure<1>, m_ag), - CLOSURE_FLOAT_PARAM (MicrofacetGGXClosure<1>, m_eta), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(MicrofacetGGXClosure<1>) }; + CLOSURE_VECTOR_PARAM(MicrofacetGGXClosure<1>, m_N), + CLOSURE_FLOAT_PARAM(MicrofacetGGXClosure<1>, m_ag), + CLOSURE_FLOAT_PARAM(MicrofacetGGXClosure<1>, m_eta), + CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_FINISH_PARAM(MicrofacetGGXClosure<1>) +}; ClosureParam bsdf_microfacet_beckmann_params[] = { - CLOSURE_VECTOR_PARAM(MicrofacetBeckmannClosure<0>, m_N), - CLOSURE_FLOAT_PARAM (MicrofacetBeckmannClosure<0>, m_ab), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(MicrofacetBeckmannClosure<0>) }; + CLOSURE_VECTOR_PARAM(MicrofacetBeckmannClosure<0>, m_N), + CLOSURE_FLOAT_PARAM(MicrofacetBeckmannClosure<0>, m_ab), + CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_FINISH_PARAM(MicrofacetBeckmannClosure<0>) +}; ClosureParam bsdf_microfacet_beckmann_refraction_params[] = { - CLOSURE_VECTOR_PARAM(MicrofacetBeckmannClosure<1>, m_N), - CLOSURE_FLOAT_PARAM (MicrofacetBeckmannClosure<1>, m_ab), - CLOSURE_FLOAT_PARAM (MicrofacetBeckmannClosure<1>, m_eta), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(MicrofacetBeckmannClosure<1>) }; + CLOSURE_VECTOR_PARAM(MicrofacetBeckmannClosure<1>, m_N), + CLOSURE_FLOAT_PARAM(MicrofacetBeckmannClosure<1>, m_ab), + CLOSURE_FLOAT_PARAM(MicrofacetBeckmannClosure<1>, m_eta), + CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_FINISH_PARAM(MicrofacetBeckmannClosure<1>) +}; CLOSURE_PREPARE(bsdf_microfacet_ggx_prepare, MicrofacetGGXClosure<0>) CLOSURE_PREPARE(bsdf_microfacet_ggx_refraction_prepare, MicrofacetGGXClosure<1>) diff --git a/intern/cycles/kernel/osl/bsdf_oren_nayar.cpp b/intern/cycles/kernel/osl/bsdf_oren_nayar.cpp index 5d2ca909f93..83d0e583695 100644 --- a/intern/cycles/kernel/osl/bsdf_oren_nayar.cpp +++ b/intern/cycles/kernel/osl/bsdf_oren_nayar.cpp @@ -19,19 +19,20 @@ #include <OpenImageIO/fmath.h> #include <OSL/genclosure.h> #include "osl_closures.h" +#include "util_math.h" CCL_NAMESPACE_BEGIN using namespace OSL; -class OrenNayarClosure: public BSDFClosure { +class OrenNayarClosure : public BSDFClosure { public: Vec3 m_N; float m_sigma; float m_a, m_b; - OrenNayarClosure(): BSDFClosure(Labels::DIFFUSE) {} + OrenNayarClosure() : BSDFClosure(Labels::DIFFUSE) {} void setup() { m_sigma = clamp(m_sigma, 0.0f, 1.0f); @@ -42,19 +43,19 @@ public: m_b = m_sigma * div; } - bool mergeable(const ClosurePrimitive* other) const { - const OrenNayarClosure* comp = static_cast<const OrenNayarClosure*>(other); + bool mergeable(const ClosurePrimitive *other) const { + const OrenNayarClosure *comp = static_cast<const OrenNayarClosure *>(other); return - m_N == comp->m_N && - m_sigma == comp->m_sigma && - BSDFClosure::mergeable(other); + m_N == comp->m_N && + m_sigma == comp->m_sigma && + BSDFClosure::mergeable(other); } size_t memsize() const { return sizeof(*this); } - const char* name() const { + const char *name() const { return "oren_nayar"; } @@ -86,13 +87,13 @@ public: } ustring sample( - const Vec3& Ng, - const Vec3& omega_out, const Vec3& domega_out_dx, const Vec3& domega_out_dy, - float randu, float randv, - Vec3& omega_in, Vec3& domega_in_dx, Vec3& domega_in_dy, - float& pdf, Color3& eval - ) const { - sample_uniform_hemisphere (m_N, omega_out, randu, randv, omega_in, pdf); + const Vec3& Ng, + const Vec3& omega_out, const Vec3& domega_out_dx, const Vec3& domega_out_dy, + float randu, float randv, + Vec3& omega_in, Vec3& domega_in_dx, Vec3& domega_in_dy, + float& pdf, Color3& eval + ) const { + sample_uniform_hemisphere(m_N, omega_out, randu, randv, omega_in, pdf); if (Ng.dot(omega_in) > 0.0f) { float is = get_intensity(m_N, omega_out, omega_in); @@ -117,18 +118,18 @@ private: float nv = max(n.dot(v), 0.0f); float t = l.dot(v) - nl * nv; - if(t > 0.0f) { - t /= max(nl, vl) + 1e-8f; + if (t > 0.0f) { + t /= max(nl, nv) + 1e-8f; } return nl * (m_a + m_b * t); } }; ClosureParam bsdf_oren_nayar_params[] = { - CLOSURE_VECTOR_PARAM (OrenNayarClosure, m_N), - CLOSURE_FLOAT_PARAM (OrenNayarClosure, m_sigma), - CLOSURE_STRING_KEYPARAM ("label"), - CLOSURE_FINISH_PARAM (OrenNayarClosure) + CLOSURE_VECTOR_PARAM(OrenNayarClosure, m_N), + CLOSURE_FLOAT_PARAM(OrenNayarClosure, m_sigma), + CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_FINISH_PARAM(OrenNayarClosure) }; CLOSURE_PREPARE(bsdf_oren_nayar_prepare, OrenNayarClosure) diff --git a/intern/cycles/kernel/osl/bsdf_reflection.cpp b/intern/cycles/kernel/osl/bsdf_reflection.cpp index b0caff6df44..7041b4ced6f 100644 --- a/intern/cycles/kernel/osl/bsdf_reflection.cpp +++ b/intern/cycles/kernel/osl/bsdf_reflection.cpp @@ -42,65 +42,66 @@ using namespace OSL; class ReflectionClosure : public BSDFClosure { public: - Vec3 m_N; // shading normal - ReflectionClosure() : BSDFClosure(Labels::SINGULAR) { } - - void setup() {}; - - bool mergeable (const ClosurePrimitive *other) const { - const ReflectionClosure *comp = (const ReflectionClosure *)other; - return m_N == comp->m_N && BSDFClosure::mergeable(other); - } - - size_t memsize () const { return sizeof(*this); } - - const char *name () const { return "reflection"; } - - void print_on (std::ostream &out) const { - out << name() << " ("; - out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "))"; - } - - float albedo (const Vec3 &omega_out) const - { - return 1.0f; - } - - Color3 eval_reflect (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - return Color3 (0, 0, 0); - } - - Color3 eval_transmit (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - return Color3 (0, 0, 0); - } - - ustring sample (const Vec3 &Ng, - const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, - float randu, float randv, - Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, - float &pdf, Color3 &eval) const - { - // only one direction is possible - float cosNO = m_N.dot(omega_out); - if (cosNO > 0) { - omega_in = (2 * cosNO) * m_N - omega_out; - if (Ng.dot(omega_in) > 0) { - domega_in_dx = 2 * m_N.dot(domega_out_dx) * m_N - domega_out_dx; - domega_in_dy = 2 * m_N.dot(domega_out_dy) * m_N - domega_out_dy; - pdf = 1; - eval.setValue(1, 1, 1); - } - } - return Labels::REFLECT; - } + Vec3 m_N; // shading normal + ReflectionClosure() : BSDFClosure(Labels::SINGULAR) {} + + void setup() {}; + + bool mergeable(const ClosurePrimitive *other) const { + const ReflectionClosure *comp = (const ReflectionClosure *)other; + return m_N == comp->m_N && BSDFClosure::mergeable(other); + } + + size_t memsize() const { return sizeof(*this); } + + const char *name() const { return "reflection"; } + + void print_on(std::ostream &out) const { + out << name() << " ("; + out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "))"; + } + + float albedo(const Vec3 &omega_out) const + { + return 1.0f; + } + + Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const + { + return Color3(0, 0, 0); + } + + Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const + { + return Color3(0, 0, 0); + } + + ustring sample(const Vec3 &Ng, + const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, + float randu, float randv, + Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, + float &pdf, Color3 &eval) const + { + // only one direction is possible + float cosNO = m_N.dot(omega_out); + if (cosNO > 0) { + omega_in = (2 * cosNO) * m_N - omega_out; + if (Ng.dot(omega_in) > 0) { + domega_in_dx = 2 * m_N.dot(domega_out_dx) * m_N - domega_out_dx; + domega_in_dy = 2 * m_N.dot(domega_out_dy) * m_N - domega_out_dy; + pdf = 1; + eval.setValue(1, 1, 1); + } + } + return Labels::REFLECT; + } }; ClosureParam bsdf_reflection_params[] = { - CLOSURE_VECTOR_PARAM(ReflectionClosure, m_N), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(ReflectionClosure) }; + CLOSURE_VECTOR_PARAM(ReflectionClosure, m_N), + CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_FINISH_PARAM(ReflectionClosure) +}; CLOSURE_PREPARE(bsdf_reflection_prepare, ReflectionClosure) diff --git a/intern/cycles/kernel/osl/bsdf_refraction.cpp b/intern/cycles/kernel/osl/bsdf_refraction.cpp index 3ae7a3811b4..f56ad7b127c 100644 --- a/intern/cycles/kernel/osl/bsdf_refraction.cpp +++ b/intern/cycles/kernel/osl/bsdf_refraction.cpp @@ -42,77 +42,78 @@ using namespace OSL; class RefractionClosure : public BSDFClosure { public: - Vec3 m_N; // shading normal - float m_eta; // ratio of indices of refraction (inside / outside) - RefractionClosure() : BSDFClosure(Labels::SINGULAR, Back) { } + Vec3 m_N; // shading normal + float m_eta; // ratio of indices of refraction (inside / outside) + RefractionClosure() : BSDFClosure(Labels::SINGULAR, Back) {} - void setup() {} + void setup() {} - bool mergeable (const ClosurePrimitive *other) const { - const RefractionClosure *comp = (const RefractionClosure *)other; - return m_N == comp->m_N && m_eta == comp->m_eta && - BSDFClosure::mergeable(other); - } + bool mergeable(const ClosurePrimitive *other) const { + const RefractionClosure *comp = (const RefractionClosure *)other; + return m_N == comp->m_N && m_eta == comp->m_eta && + BSDFClosure::mergeable(other); + } - size_t memsize () const { return sizeof(*this); } + size_t memsize() const { return sizeof(*this); } - const char *name () const { return "refraction"; } + const char *name() const { return "refraction"; } - void print_on (std::ostream &out) const { - out << name() << " ("; - out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), "; - out << m_eta; - out << ")"; - } + void print_on(std::ostream &out) const { + out << name() << " ("; + out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), "; + out << m_eta; + out << ")"; + } - Color3 eval_reflect (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - return Color3 (0, 0, 0); - } + Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const + { + return Color3(0, 0, 0); + } - Color3 eval_transmit (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - return Color3 (0, 0, 0); - } + Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const + { + return Color3(0, 0, 0); + } - float albedo (const Vec3 &omega_out) const - { + float albedo(const Vec3 &omega_out) const + { return 1.0f; - } - - ustring sample (const Vec3 &Ng, - const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, - float randu, float randv, - Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, - float &pdf, Color3 &eval) const - { - Vec3 R, dRdx, dRdy; - Vec3 T, dTdx, dTdy; - bool inside; - - fresnel_dielectric(m_eta, m_N, - omega_out, domega_out_dx, domega_out_dy, - R, dRdx, dRdy, - T, dTdx, dTdy, - inside); - - if (!inside) { - pdf = 1; - eval.setValue(1.0f, 1.0f, 1.0f); - omega_in = T; - domega_in_dx = dTdx; - domega_in_dy = dTdy; - } - - return Labels::TRANSMIT; - } + } + + ustring sample(const Vec3 &Ng, + const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, + float randu, float randv, + Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, + float &pdf, Color3 &eval) const + { + Vec3 R, dRdx, dRdy; + Vec3 T, dTdx, dTdy; + bool inside; + + fresnel_dielectric(m_eta, m_N, + omega_out, domega_out_dx, domega_out_dy, + R, dRdx, dRdy, + T, dTdx, dTdy, + inside); + + if (!inside) { + pdf = 1; + eval.setValue(1.0f, 1.0f, 1.0f); + omega_in = T; + domega_in_dx = dTdx; + domega_in_dy = dTdy; + } + + return Labels::TRANSMIT; + } }; ClosureParam bsdf_refraction_params[] = { - CLOSURE_VECTOR_PARAM(RefractionClosure, m_N), - CLOSURE_FLOAT_PARAM (RefractionClosure, m_eta), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(RefractionClosure) }; + CLOSURE_VECTOR_PARAM(RefractionClosure, m_N), + CLOSURE_FLOAT_PARAM(RefractionClosure, m_eta), + CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_FINISH_PARAM(RefractionClosure) +}; CLOSURE_PREPARE(bsdf_refraction_prepare, RefractionClosure) diff --git a/intern/cycles/kernel/osl/bsdf_transparent.cpp b/intern/cycles/kernel/osl/bsdf_transparent.cpp index 941abd6a483..acde92530a2 100644 --- a/intern/cycles/kernel/osl/bsdf_transparent.cpp +++ b/intern/cycles/kernel/osl/bsdf_transparent.cpp @@ -42,54 +42,55 @@ using namespace OSL; class TransparentClosure : public BSDFClosure { public: - TransparentClosure() : BSDFClosure(Labels::STRAIGHT, Back) { } - - void setup() {} - - size_t memsize () const { return sizeof(*this); } - - const char *name () const { return "transparent"; } - - void print_on (std::ostream &out) const { - out << name() << " ()"; - } - - float albedo (const Vec3 &omega_out) const - { - return 1.0f; - } - - Color3 eval_reflect (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - return Color3 (0, 0, 0); - } - - Color3 eval_transmit (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - return Color3 (0, 0, 0); - } - - ustring sample (const Vec3 &Ng, - const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, - float randu, float randv, - Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, - float &pdf, Color3 &eval) const - { - // only one direction is possible - omega_in = -omega_out; - domega_in_dx = -domega_out_dx; - domega_in_dy = -domega_out_dy; - pdf = 1; - eval.setValue(1, 1, 1); - return Labels::TRANSMIT; - } + TransparentClosure() : BSDFClosure(Labels::STRAIGHT, Back) {} + + void setup() {} + + size_t memsize() const { return sizeof(*this); } + + const char *name() const { return "transparent"; } + + void print_on(std::ostream &out) const { + out << name() << " ()"; + } + + float albedo(const Vec3 &omega_out) const + { + return 1.0f; + } + + Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const + { + return Color3(0, 0, 0); + } + + Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const + { + return Color3(0, 0, 0); + } + + ustring sample(const Vec3 &Ng, + const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, + float randu, float randv, + Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, + float &pdf, Color3 &eval) const + { + // only one direction is possible + omega_in = -omega_out; + domega_in_dx = -domega_out_dx; + domega_in_dy = -domega_out_dy; + pdf = 1; + eval.setValue(1, 1, 1); + return Labels::TRANSMIT; + } }; ClosureParam bsdf_transparent_params[] = { - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(TransparentClosure) }; + CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_FINISH_PARAM(TransparentClosure) +}; CLOSURE_PREPARE(bsdf_transparent_prepare, TransparentClosure) diff --git a/intern/cycles/kernel/osl/bsdf_ward.cpp b/intern/cycles/kernel/osl/bsdf_ward.cpp index a7742a04d13..4aacbc4ffc3 100644 --- a/intern/cycles/kernel/osl/bsdf_ward.cpp +++ b/intern/cycles/kernel/osl/bsdf_ward.cpp @@ -46,175 +46,179 @@ using namespace OSL; // see http://www.graphics.cornell.edu/~bjw/wardnotes.pdf class WardClosure : public BSDFClosure { public: - Vec3 m_N; - Vec3 m_T; - float m_ax, m_ay; - WardClosure() : BSDFClosure(Labels::GLOSSY) { } + Vec3 m_N; + Vec3 m_T; + float m_ax, m_ay; + WardClosure() : BSDFClosure(Labels::GLOSSY) {} - void setup() + void setup() { m_ax = clamp(m_ax, 1e-5f, 1.0f); m_ay = clamp(m_ay, 1e-5f, 1.0f); } - bool mergeable (const ClosurePrimitive *other) const { - const WardClosure *comp = (const WardClosure *)other; - return m_N == comp->m_N && m_T == comp->m_T && - m_ax == comp->m_ax && m_ay == comp->m_ay && - BSDFClosure::mergeable(other); - } - - size_t memsize () const { return sizeof(*this); } - - const char *name () const { return "ward"; } - - void print_on (std::ostream &out) const { - out << name() << " (("; - out << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), ("; - out << m_T[0] << ", " << m_T[1] << ", " << m_T[2] << "), "; - out << m_ax << ", " << m_ay << ")"; - } - - float albedo (const Vec3 &omega_out) const - { - return 1.0f; - } - - Color3 eval_reflect (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - float cosNO = m_N.dot(omega_out); - float cosNI = m_N.dot(omega_in); - if (cosNI > 0 && cosNO > 0) { - // get half vector and get x,y basis on the surface for anisotropy - Vec3 H = omega_in + omega_out; - H.normalize(); // normalize needed for pdf - Vec3 X, Y; - make_orthonormals(m_N, m_T, X, Y); - // eq. 4 - float dotx = H.dot(X) / m_ax; - float doty = H.dot(Y) / m_ay; - float dotn = H.dot(m_N); - float exp_arg = (dotx * dotx + doty * doty) / (dotn * dotn); - float denom = (4 * (float) M_PI * m_ax * m_ay * sqrtf(cosNO * cosNI)); - float exp_val = expf(-exp_arg); - float out = cosNI * exp_val / denom; - float oh = H.dot(omega_out); - denom = 4 * (float) M_PI * m_ax * m_ay * oh * dotn * dotn * dotn; - pdf = exp_val / denom; - return Color3 (out, out, out); - } - return Color3 (0, 0, 0); - } - - Color3 eval_transmit (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - return Color3 (0, 0, 0); - } - - ustring sample (const Vec3 &Ng, - const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, - float randu, float randv, - Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, - float &pdf, Color3 &eval) const - { - float cosNO = m_N.dot(omega_out); - if (cosNO > 0) { - // get x,y basis on the surface for anisotropy - Vec3 X, Y; - make_orthonormals(m_N, m_T, X, Y); - // generate random angles for the half vector - // eq. 7 (taking care around discontinuities to keep - // output angle in the right quadrant) - // we take advantage of cos(atan(x)) == 1/sqrt(1+x^2) - // and sin(atan(x)) == x/sqrt(1+x^2) - float alphaRatio = m_ay / m_ax; - float cosPhi, sinPhi; - if (randu < 0.25f) { - float val = 4 * randu; - float tanPhi = alphaRatio * tanf((float) M_PI_2 * val); - cosPhi = 1 / sqrtf(1 + tanPhi * tanPhi); - sinPhi = tanPhi * cosPhi; - } else if (randu < 0.5) { - float val = 1 - 4 * (0.5f - randu); - float tanPhi = alphaRatio * tanf((float) M_PI_2 * val); - // phi = (float) M_PI - phi; - cosPhi = -1 / sqrtf(1 + tanPhi * tanPhi); - sinPhi = -tanPhi * cosPhi; - } else if (randu < 0.75f) { - float val = 4 * (randu - 0.5f); - float tanPhi = alphaRatio * tanf((float) M_PI_2 * val); - //phi = (float) M_PI + phi; - cosPhi = -1 / sqrtf(1 + tanPhi * tanPhi); - sinPhi = tanPhi * cosPhi; - } else { - float val = 1 - 4 * (1 - randu); - float tanPhi = alphaRatio * tanf((float) M_PI_2 * val); - // phi = 2 * (float) M_PI - phi; - cosPhi = 1 / sqrtf(1 + tanPhi * tanPhi); - sinPhi = -tanPhi * cosPhi; - } - // eq. 6 - // we take advantage of cos(atan(x)) == 1/sqrt(1+x^2) - // and sin(atan(x)) == x/sqrt(1+x^2) - float thetaDenom = (cosPhi * cosPhi) / (m_ax * m_ax) + (sinPhi * sinPhi) / (m_ay * m_ay); - float tanTheta2 = -logf(1 - randv) / thetaDenom; - float cosTheta = 1 / sqrtf(1 + tanTheta2); - float sinTheta = cosTheta * sqrtf(tanTheta2); - - Vec3 h; // already normalized becaused expressed from spherical coordinates - h.x = sinTheta * cosPhi; - h.y = sinTheta * sinPhi; - h.z = cosTheta; - // compute terms that are easier in local space - float dotx = h.x / m_ax; - float doty = h.y / m_ay; - float dotn = h.z; - // transform to world space - h = h.x * X + h.y * Y + h.z * m_N; - // generate the final sample - float oh = h.dot(omega_out); - omega_in.x = 2 * oh * h.x - omega_out.x; - omega_in.y = 2 * oh * h.y - omega_out.y; - omega_in.z = 2 * oh * h.z - omega_out.z; - if (Ng.dot(omega_in) > 0) { - float cosNI = m_N.dot(omega_in); - if (cosNI > 0) { - // eq. 9 - float exp_arg = (dotx * dotx + doty * doty) / (dotn * dotn); - float denom = 4 * (float) M_PI * m_ax * m_ay * oh * dotn * dotn * dotn; - pdf = expf(-exp_arg) / denom; - // compiler will reuse expressions already computed - denom = (4 * (float) M_PI * m_ax * m_ay * sqrtf(cosNO * cosNI)); - float power = cosNI * expf(-exp_arg) / denom; - eval.setValue(power, power, power); - domega_in_dx = (2 * m_N.dot(domega_out_dx)) * m_N - domega_out_dx; - domega_in_dy = (2 * m_N.dot(domega_out_dy)) * m_N - domega_out_dy; + bool mergeable(const ClosurePrimitive *other) const { + const WardClosure *comp = (const WardClosure *)other; + return m_N == comp->m_N && m_T == comp->m_T && + m_ax == comp->m_ax && m_ay == comp->m_ay && + BSDFClosure::mergeable(other); + } + + size_t memsize() const { return sizeof(*this); } + + const char *name() const { return "ward"; } + + void print_on(std::ostream &out) const { + out << name() << " (("; + out << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), ("; + out << m_T[0] << ", " << m_T[1] << ", " << m_T[2] << "), "; + out << m_ax << ", " << m_ay << ")"; + } + + float albedo(const Vec3 &omega_out) const + { + return 1.0f; + } + + Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const + { + float cosNO = m_N.dot(omega_out); + float cosNI = m_N.dot(omega_in); + if (cosNI > 0 && cosNO > 0) { + // get half vector and get x,y basis on the surface for anisotropy + Vec3 H = omega_in + omega_out; + H.normalize(); // normalize needed for pdf + Vec3 X, Y; + make_orthonormals(m_N, m_T, X, Y); + // eq. 4 + float dotx = H.dot(X) / m_ax; + float doty = H.dot(Y) / m_ay; + float dotn = H.dot(m_N); + float exp_arg = (dotx * dotx + doty * doty) / (dotn * dotn); + float denom = (4 * (float) M_PI * m_ax * m_ay * sqrtf(cosNO * cosNI)); + float exp_val = expf(-exp_arg); + float out = cosNI * exp_val / denom; + float oh = H.dot(omega_out); + denom = 4 * (float) M_PI * m_ax * m_ay * oh * dotn * dotn * dotn; + pdf = exp_val / denom; + return Color3(out, out, out); + } + return Color3(0, 0, 0); + } + + Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const + { + return Color3(0, 0, 0); + } + + ustring sample(const Vec3 &Ng, + const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, + float randu, float randv, + Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, + float &pdf, Color3 &eval) const + { + float cosNO = m_N.dot(omega_out); + if (cosNO > 0) { + // get x,y basis on the surface for anisotropy + Vec3 X, Y; + make_orthonormals(m_N, m_T, X, Y); + // generate random angles for the half vector + // eq. 7 (taking care around discontinuities to keep + // output angle in the right quadrant) + // we take advantage of cos(atan(x)) == 1/sqrt(1+x^2) + // and sin(atan(x)) == x/sqrt(1+x^2) + float alphaRatio = m_ay / m_ax; + float cosPhi, sinPhi; + if (randu < 0.25f) { + float val = 4 * randu; + float tanPhi = alphaRatio * tanf((float) M_PI_2 * val); + cosPhi = 1 / sqrtf(1 + tanPhi * tanPhi); + sinPhi = tanPhi * cosPhi; + } + else if (randu < 0.5) { + float val = 1 - 4 * (0.5f - randu); + float tanPhi = alphaRatio * tanf((float) M_PI_2 * val); + // phi = (float) M_PI - phi; + cosPhi = -1 / sqrtf(1 + tanPhi * tanPhi); + sinPhi = -tanPhi * cosPhi; + } + else if (randu < 0.75f) { + float val = 4 * (randu - 0.5f); + float tanPhi = alphaRatio * tanf((float) M_PI_2 * val); + //phi = (float) M_PI + phi; + cosPhi = -1 / sqrtf(1 + tanPhi * tanPhi); + sinPhi = tanPhi * cosPhi; + } + else { + float val = 1 - 4 * (1 - randu); + float tanPhi = alphaRatio * tanf((float) M_PI_2 * val); + // phi = 2 * (float) M_PI - phi; + cosPhi = 1 / sqrtf(1 + tanPhi * tanPhi); + sinPhi = -tanPhi * cosPhi; + } + // eq. 6 + // we take advantage of cos(atan(x)) == 1/sqrt(1+x^2) + // and sin(atan(x)) == x/sqrt(1+x^2) + float thetaDenom = (cosPhi * cosPhi) / (m_ax * m_ax) + (sinPhi * sinPhi) / (m_ay * m_ay); + float tanTheta2 = -logf(1 - randv) / thetaDenom; + float cosTheta = 1 / sqrtf(1 + tanTheta2); + float sinTheta = cosTheta * sqrtf(tanTheta2); + + Vec3 h; // already normalized becaused expressed from spherical coordinates + h.x = sinTheta * cosPhi; + h.y = sinTheta * sinPhi; + h.z = cosTheta; + // compute terms that are easier in local space + float dotx = h.x / m_ax; + float doty = h.y / m_ay; + float dotn = h.z; + // transform to world space + h = h.x * X + h.y * Y + h.z * m_N; + // generate the final sample + float oh = h.dot(omega_out); + omega_in.x = 2 * oh * h.x - omega_out.x; + omega_in.y = 2 * oh * h.y - omega_out.y; + omega_in.z = 2 * oh * h.z - omega_out.z; + if (Ng.dot(omega_in) > 0) { + float cosNI = m_N.dot(omega_in); + if (cosNI > 0) { + // eq. 9 + float exp_arg = (dotx * dotx + doty * doty) / (dotn * dotn); + float denom = 4 * (float) M_PI * m_ax * m_ay * oh * dotn * dotn * dotn; + pdf = expf(-exp_arg) / denom; + // compiler will reuse expressions already computed + denom = (4 * (float) M_PI * m_ax * m_ay * sqrtf(cosNO * cosNI)); + float power = cosNI * expf(-exp_arg) / denom; + eval.setValue(power, power, power); + domega_in_dx = (2 * m_N.dot(domega_out_dx)) * m_N - domega_out_dx; + domega_in_dy = (2 * m_N.dot(domega_out_dy)) * m_N - domega_out_dy; /* disabled for now - gives texture filtering problems */ #if 0 - // Since there is some blur to this reflection, make the - // derivatives a bit bigger. In theory this varies with the - // roughness but the exact relationship is complex and - // requires more ops than are practical. - domega_in_dx *= 10; - domega_in_dy *= 10; + // Since there is some blur to this reflection, make the + // derivatives a bit bigger. In theory this varies with the + // roughness but the exact relationship is complex and + // requires more ops than are practical. + domega_in_dx *= 10; + domega_in_dy *= 10; #endif - } - } - } - return Labels::REFLECT; - } + } + } + } + return Labels::REFLECT; + } }; ClosureParam bsdf_ward_params[] = { - CLOSURE_VECTOR_PARAM(WardClosure, m_N), - CLOSURE_VECTOR_PARAM(WardClosure, m_T), - CLOSURE_FLOAT_PARAM (WardClosure, m_ax), - CLOSURE_FLOAT_PARAM (WardClosure, m_ay), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(WardClosure) }; + CLOSURE_VECTOR_PARAM(WardClosure, m_N), + CLOSURE_VECTOR_PARAM(WardClosure, m_T), + CLOSURE_FLOAT_PARAM(WardClosure, m_ax), + CLOSURE_FLOAT_PARAM(WardClosure, m_ay), + CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_FINISH_PARAM(WardClosure) +}; CLOSURE_PREPARE(bsdf_ward_prepare, WardClosure) diff --git a/intern/cycles/kernel/osl/bsdf_westin.cpp b/intern/cycles/kernel/osl/bsdf_westin.cpp index d322f6a7f7e..a476e8045f7 100644 --- a/intern/cycles/kernel/osl/bsdf_westin.cpp +++ b/intern/cycles/kernel/osl/bsdf_westin.cpp @@ -44,193 +44,197 @@ using namespace OSL; class WestinBackscatterClosure : public BSDFClosure { public: - Vec3 m_N; - float m_roughness; - float m_invroughness; - WestinBackscatterClosure() : BSDFClosure(Labels::GLOSSY) { } + Vec3 m_N; + float m_roughness; + float m_invroughness; + WestinBackscatterClosure() : BSDFClosure(Labels::GLOSSY) {} - void setup() - { + void setup() + { m_roughness = clamp(m_roughness, 1e-5f, 1.0f); - m_invroughness = m_roughness > 0 ? 1 / m_roughness : 0; - } - - bool mergeable (const ClosurePrimitive *other) const { - const WestinBackscatterClosure *comp = (const WestinBackscatterClosure *)other; - return m_N == comp->m_N && m_roughness == comp->m_roughness && - BSDFClosure::mergeable(other); - } - - size_t memsize () const { return sizeof(*this); } - - const char *name () const { return "westin_backscatter"; } - - void print_on (std::ostream &out) const - { - out << name() << " ("; - out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), "; - out << m_roughness; - out << ")"; - } - - float albedo (const Vec3 &omega_out) const - { - return 1.0f; - } - - Color3 eval_reflect (const Vec3 &omega_out, const Vec3 &omega_in, float &pdf) const - { - // pdf is implicitly 0 (no indirect sampling) - float cosNO = m_N.dot(omega_out); - float cosNI = m_N.dot(omega_in); - if (cosNO > 0 && cosNI > 0) { - float cosine = omega_out.dot(omega_in); - pdf = cosine > 0 ? (m_invroughness + 1) * powf(cosine, m_invroughness) : 0; - pdf *= 0.5f * float(M_1_PI); - return Color3 (pdf, pdf, pdf); - } - return Color3 (0, 0, 0); - } - - Color3 eval_transmit (const Vec3 &omega_out, const Vec3 &omega_in, float &pdf) const - { - return Color3 (0, 0, 0); - } - - ustring sample (const Vec3 &Ng, - const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, - float randu, float randv, - Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, - float &pdf, Color3 &eval) const - { - float cosNO = m_N.dot(omega_out); - if (cosNO > 0) { - domega_in_dx = domega_out_dx; - domega_in_dy = domega_out_dy; - Vec3 T, B; - make_orthonormals (omega_out, T, B); - float phi = 2 * (float) M_PI * randu; - float cosTheta = powf(randv, 1 / (m_invroughness + 1)); - float sinTheta2 = 1 - cosTheta * cosTheta; - float sinTheta = sinTheta2 > 0 ? sqrtf(sinTheta2) : 0; - omega_in = (cosf(phi) * sinTheta) * T + - (sinf(phi) * sinTheta) * B + - ( cosTheta) * omega_out; - if (Ng.dot(omega_in) > 0) - { - // common terms for pdf and eval - float cosNI = m_N.dot(omega_in); - // make sure the direction we chose is still in the right hemisphere - if (cosNI > 0) - { - pdf = 0.5f * (float) M_1_PI * powf(cosTheta, m_invroughness); - pdf = (m_invroughness + 1) * pdf; - eval.setValue(pdf, pdf, pdf); - // Since there is some blur to this reflection, make the - // derivatives a bit bigger. In theory this varies with the - // exponent but the exact relationship is complex and - // requires more ops than are practical. - domega_in_dx *= 10; - domega_in_dy *= 10; - } - } - } - return Labels::REFLECT; - } + m_invroughness = m_roughness > 0 ? 1 / m_roughness : 0; + } + + bool mergeable(const ClosurePrimitive *other) const { + const WestinBackscatterClosure *comp = (const WestinBackscatterClosure *)other; + return m_N == comp->m_N && m_roughness == comp->m_roughness && + BSDFClosure::mergeable(other); + } + + size_t memsize() const { return sizeof(*this); } + + const char *name() const { return "westin_backscatter"; } + + void print_on(std::ostream &out) const + { + out << name() << " ("; + out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), "; + out << m_roughness; + out << ")"; + } + + float albedo(const Vec3 &omega_out) const + { + return 1.0f; + } + + Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float &pdf) const + { + // pdf is implicitly 0 (no indirect sampling) + float cosNO = m_N.dot(omega_out); + float cosNI = m_N.dot(omega_in); + if (cosNO > 0 && cosNI > 0) { + float cosine = omega_out.dot(omega_in); + pdf = cosine > 0 ? (m_invroughness + 1) * powf(cosine, m_invroughness) : 0; + pdf *= 0.5f * float(M_1_PI); + return Color3(pdf, pdf, pdf); + } + return Color3(0, 0, 0); + } + + Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float &pdf) const + { + return Color3(0, 0, 0); + } + + ustring sample(const Vec3 &Ng, + const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, + float randu, float randv, + Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, + float &pdf, Color3 &eval) const + { + float cosNO = m_N.dot(omega_out); + if (cosNO > 0) { + domega_in_dx = domega_out_dx; + domega_in_dy = domega_out_dy; + Vec3 T, B; + make_orthonormals(omega_out, T, B); + float phi = 2 * (float) M_PI * randu; + float cosTheta = powf(randv, 1 / (m_invroughness + 1)); + float sinTheta2 = 1 - cosTheta * cosTheta; + float sinTheta = sinTheta2 > 0 ? sqrtf(sinTheta2) : 0; + omega_in = (cosf(phi) * sinTheta) * T + + (sinf(phi) * sinTheta) * B + + (cosTheta) * omega_out; + if (Ng.dot(omega_in) > 0) + { + // common terms for pdf and eval + float cosNI = m_N.dot(omega_in); + // make sure the direction we chose is still in the right hemisphere + if (cosNI > 0) + { + pdf = 0.5f * (float) M_1_PI * powf(cosTheta, m_invroughness); + pdf = (m_invroughness + 1) * pdf; + eval.setValue(pdf, pdf, pdf); + // Since there is some blur to this reflection, make the + // derivatives a bit bigger. In theory this varies with the + // exponent but the exact relationship is complex and + // requires more ops than are practical. + domega_in_dx *= 10; + domega_in_dy *= 10; + } + } + } + return Labels::REFLECT; + } }; class WestinSheenClosure : public BSDFClosure { public: - Vec3 m_N; - float m_edginess; + Vec3 m_N; + float m_edginess; // float m_normalization; - WestinSheenClosure() : BSDFClosure(Labels::DIFFUSE) { } - - void setup() {}; - - bool mergeable (const ClosurePrimitive *other) const { - const WestinSheenClosure *comp = (const WestinSheenClosure *)other; - return m_N == comp->m_N && m_edginess == comp->m_edginess && - BSDFClosure::mergeable(other); - } - - size_t memsize () const { return sizeof(*this); } - - const char *name () const { return "westin_sheen"; } - - void print_on (std::ostream &out) const - { - out << name() << " ("; - out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), "; - out << m_edginess; - out << ")"; - } - - float albedo (const Vec3 &omega_out) const - { - return 1.0f; - } - - Color3 eval_reflect (const Vec3 &omega_out, const Vec3 &omega_in, float &pdf) const - { - // pdf is implicitly 0 (no indirect sampling) - float cosNO = m_N.dot(omega_out); - float cosNI = m_N.dot(omega_in); - if (cosNO > 0 && cosNI > 0) { - float sinNO2 = 1 - cosNO * cosNO; - pdf = cosNI * float(M_1_PI); - float westin = sinNO2 > 0 ? powf(sinNO2, 0.5f * m_edginess) * pdf : 0; - return Color3 (westin, westin, westin); - } - return Color3 (0, 0, 0); - } - - Color3 eval_transmit (const Vec3 &omega_out, const Vec3 &omega_in, float &pdf) const - { - return Color3 (0, 0, 0); - } - - ustring sample (const Vec3 &Ng, - const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, - float randu, float randv, - Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, - float &pdf, Color3 &eval) const - { - // we are viewing the surface from the right side - send a ray out with cosine - // distribution over the hemisphere - sample_cos_hemisphere (m_N, omega_out, randu, randv, omega_in, pdf); - if (Ng.dot(omega_in) > 0) { - // TODO: account for sheen when sampling - float cosNO = m_N.dot(omega_out); - float sinNO2 = 1 - cosNO * cosNO; - float westin = sinNO2 > 0 ? powf(sinNO2, 0.5f * m_edginess) * pdf : 0; - eval.setValue(westin, westin, westin); - // TODO: find a better approximation for the diffuse bounce - domega_in_dx = (2 * m_N.dot(domega_out_dx)) * m_N - domega_out_dx; - domega_in_dy = (2 * m_N.dot(domega_out_dy)) * m_N - domega_out_dy; - domega_in_dx *= 125; - domega_in_dy *= 125; - } else - pdf = 0; - return Labels::REFLECT; - } + WestinSheenClosure() : BSDFClosure(Labels::DIFFUSE) {} + + void setup() {}; + + bool mergeable(const ClosurePrimitive *other) const { + const WestinSheenClosure *comp = (const WestinSheenClosure *)other; + return m_N == comp->m_N && m_edginess == comp->m_edginess && + BSDFClosure::mergeable(other); + } + + size_t memsize() const { return sizeof(*this); } + + const char *name() const { return "westin_sheen"; } + + void print_on(std::ostream &out) const + { + out << name() << " ("; + out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), "; + out << m_edginess; + out << ")"; + } + + float albedo(const Vec3 &omega_out) const + { + return 1.0f; + } + + Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float &pdf) const + { + // pdf is implicitly 0 (no indirect sampling) + float cosNO = m_N.dot(omega_out); + float cosNI = m_N.dot(omega_in); + if (cosNO > 0 && cosNI > 0) { + float sinNO2 = 1 - cosNO * cosNO; + pdf = cosNI * float(M_1_PI); + float westin = sinNO2 > 0 ? powf(sinNO2, 0.5f * m_edginess) * pdf : 0; + return Color3(westin, westin, westin); + } + return Color3(0, 0, 0); + } + + Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float &pdf) const + { + return Color3(0, 0, 0); + } + + ustring sample(const Vec3 &Ng, + const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, + float randu, float randv, + Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, + float &pdf, Color3 &eval) const + { + // we are viewing the surface from the right side - send a ray out with cosine + // distribution over the hemisphere + sample_cos_hemisphere(m_N, omega_out, randu, randv, omega_in, pdf); + if (Ng.dot(omega_in) > 0) { + // TODO: account for sheen when sampling + float cosNO = m_N.dot(omega_out); + float sinNO2 = 1 - cosNO * cosNO; + float westin = sinNO2 > 0 ? powf(sinNO2, 0.5f * m_edginess) * pdf : 0; + eval.setValue(westin, westin, westin); + // TODO: find a better approximation for the diffuse bounce + domega_in_dx = (2 * m_N.dot(domega_out_dx)) * m_N - domega_out_dx; + domega_in_dy = (2 * m_N.dot(domega_out_dy)) * m_N - domega_out_dy; + domega_in_dx *= 125; + domega_in_dy *= 125; + } + else { + pdf = 0; + } + return Labels::REFLECT; + } }; ClosureParam bsdf_westin_backscatter_params[] = { - CLOSURE_VECTOR_PARAM(WestinBackscatterClosure, m_N), - CLOSURE_FLOAT_PARAM (WestinBackscatterClosure, m_roughness), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(WestinBackscatterClosure) }; + CLOSURE_VECTOR_PARAM(WestinBackscatterClosure, m_N), + CLOSURE_FLOAT_PARAM(WestinBackscatterClosure, m_roughness), + CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_FINISH_PARAM(WestinBackscatterClosure) +}; ClosureParam bsdf_westin_sheen_params[] = { - CLOSURE_VECTOR_PARAM(WestinSheenClosure, m_N), - CLOSURE_FLOAT_PARAM (WestinSheenClosure, m_edginess), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(WestinSheenClosure) }; + CLOSURE_VECTOR_PARAM(WestinSheenClosure, m_N), + CLOSURE_FLOAT_PARAM(WestinSheenClosure, m_edginess), + CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_FINISH_PARAM(WestinSheenClosure) +}; CLOSURE_PREPARE(bsdf_westin_backscatter_prepare, WestinBackscatterClosure) CLOSURE_PREPARE(bsdf_westin_sheen_prepare, WestinSheenClosure) diff --git a/intern/cycles/kernel/osl/bssrdf.cpp b/intern/cycles/kernel/osl/bssrdf.cpp index 66d7818e677..b195cf513cd 100644 --- a/intern/cycles/kernel/osl/bssrdf.cpp +++ b/intern/cycles/kernel/osl/bssrdf.cpp @@ -42,62 +42,63 @@ using namespace OSL; class BSSRDFCubicClosure : public BSSRDFClosure { public: - Color3 m_radius; - Color3 m_scale; - float m_max_radius; - - template <typename T> - static inline T pow3 (const T &x) { return x * x * x; } - - template <typename T> - static inline T pow5 (const T &x) { T x2 = x * x; return x2 * x2 * x; } - - BSSRDFCubicClosure() { } - - void setup() - { - // pre-compute some terms - m_max_radius = 0; - for (int i = 0; i < 3; i++) { - m_scale[i] = m_radius[i] > 0 ? 4 / pow5 (m_radius[i]) : 0; - m_max_radius = std::max (m_max_radius, m_radius[i]); - } - } - - bool mergeable (const ClosurePrimitive *other) const { - const BSSRDFCubicClosure *comp = (const BSSRDFCubicClosure *)other; - return m_radius == comp->m_radius && BSSRDFClosure::mergeable(other); - } - - size_t memsize () const { return sizeof(*this); } - - const char *name () const { return "bssrdf_cubic"; } - - void print_on (std::ostream &out) const - { - out << name() << " ((" << m_radius[0] << ", " << m_radius[1] << ", " << m_radius[2] << "), (" - << m_scale[0] << ", " << m_scale[1] << ", " << m_scale[2] << "))"; - } - - Color3 eval (float r) const - { - return Color3 ((r < m_radius.x) ? pow3 (m_radius.x - r) * m_scale.x : 0, - (r < m_radius.y) ? pow3 (m_radius.y - r) * m_scale.y : 0, - (r < m_radius.z) ? pow3 (m_radius.z - r) * m_scale.z : 0); - } - - float max_radius() const - { - return m_max_radius; - } + Color3 m_radius; + Color3 m_scale; + float m_max_radius; + + template <typename T> + static inline T pow3(const T &x) { return x * x * x; } + + template <typename T> + static inline T pow5(const T &x) { T x2 = x * x; return x2 * x2 * x; } + + BSSRDFCubicClosure() {} + + void setup() + { + // pre-compute some terms + m_max_radius = 0; + for (int i = 0; i < 3; i++) { + m_scale[i] = m_radius[i] > 0 ? 4 / pow5(m_radius[i]) : 0; + m_max_radius = std::max(m_max_radius, m_radius[i]); + } + } + + bool mergeable(const ClosurePrimitive *other) const { + const BSSRDFCubicClosure *comp = (const BSSRDFCubicClosure *)other; + return m_radius == comp->m_radius && BSSRDFClosure::mergeable(other); + } + + size_t memsize() const { return sizeof(*this); } + + const char *name() const { return "bssrdf_cubic"; } + + void print_on(std::ostream &out) const + { + out << name() << " ((" << m_radius[0] << ", " << m_radius[1] << ", " << m_radius[2] << "), (" + << m_scale[0] << ", " << m_scale[1] << ", " << m_scale[2] << "))"; + } + + Color3 eval(float r) const + { + return Color3((r < m_radius.x) ? pow3(m_radius.x - r) * m_scale.x : 0, + (r < m_radius.y) ? pow3(m_radius.y - r) * m_scale.y : 0, + (r < m_radius.z) ? pow3(m_radius.z - r) * m_scale.z : 0); + } + + float max_radius() const + { + return m_max_radius; + } }; ClosureParam closure_bssrdf_cubic_params[] = { - CLOSURE_COLOR_PARAM (BSSRDFCubicClosure, m_radius), - CLOSURE_STRING_KEYPARAM ("label"), - CLOSURE_FINISH_PARAM(BSSRDFCubicClosure) }; + CLOSURE_COLOR_PARAM(BSSRDFCubicClosure, m_radius), + CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_FINISH_PARAM(BSSRDFCubicClosure) +}; CLOSURE_PREPARE(closure_bssrdf_cubic_prepare, BSSRDFCubicClosure) diff --git a/intern/cycles/kernel/osl/debug.cpp b/intern/cycles/kernel/osl/debug.cpp index 8c3f8b2b323..768a9100e8a 100644 --- a/intern/cycles/kernel/osl/debug.cpp +++ b/intern/cycles/kernel/osl/debug.cpp @@ -49,30 +49,31 @@ using namespace OSL; class DebugClosure : public ClosurePrimitive { public: - ustring m_tag; + ustring m_tag; - DebugClosure () : ClosurePrimitive (Debug) { } + DebugClosure () : ClosurePrimitive(Debug) {} - bool mergeable (const ClosurePrimitive *other) const { - const DebugClosure *comp = (const DebugClosure *)other; - return m_tag == comp->m_tag && - ClosurePrimitive::mergeable(other); - } + bool mergeable(const ClosurePrimitive *other) const { + const DebugClosure *comp = (const DebugClosure *)other; + return m_tag == comp->m_tag && + ClosurePrimitive::mergeable(other); + } - size_t memsize () const { return sizeof(*this); } + size_t memsize() const { return sizeof(*this); } - const char *name () const { return "debug"; } + const char *name() const { return "debug"; } - void print_on (std::ostream &out) const { - out << name() << " (\"" << m_tag.c_str() << "\")"; - } + void print_on(std::ostream &out) const { + out << name() << " (\"" << m_tag.c_str() << "\")"; + } }; ClosureParam closure_debug_params[] = { - CLOSURE_STRING_PARAM(DebugClosure, m_tag), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(DebugClosure) }; + CLOSURE_STRING_PARAM(DebugClosure, m_tag), + CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_FINISH_PARAM(DebugClosure) +}; CLOSURE_PREPARE(closure_debug_prepare, DebugClosure) diff --git a/intern/cycles/kernel/osl/emissive.cpp b/intern/cycles/kernel/osl/emissive.cpp index 2d2d6e1fdde..0a582c3f558 100644 --- a/intern/cycles/kernel/osl/emissive.cpp +++ b/intern/cycles/kernel/osl/emissive.cpp @@ -49,57 +49,58 @@ using namespace OSL; /// class GenericEmissiveClosure : public EmissiveClosure { public: - GenericEmissiveClosure() { } - - void setup() { } - - size_t memsize () const { return sizeof(*this); } - - const char *name () const { return "emission"; } - - void print_on (std::ostream &out) const { - out << name() << "()"; - } - - Color3 eval (const Vec3 &Ng, const Vec3 &omega_out) const - { - float cosNO = fabsf(Ng.dot(omega_out)); - float res = cosNO > 0 ? 1.0f: 0.0f; - return Color3(res, res, res); - } - - void sample (const Vec3 &Ng, float randu, float randv, - Vec3 &omega_out, float &pdf) const - { - // We don't do anything sophisticated here for the step - // We just sample the whole cone uniformly to the cosine - Vec3 T, B; - make_orthonormals(Ng, T, B); - float phi = 2 * (float) M_PI * randu; - float cosTheta = sqrtf(1.0f - 1.0f * randv); - float sinTheta = sqrtf(1.0f - cosTheta * cosTheta); - omega_out = (cosf(phi) * sinTheta) * T + - (sinf(phi) * sinTheta) * B + - cosTheta * Ng; - pdf = 1.0f / float(M_PI); - } - - /// Return the probability distribution function in the direction omega_out, - /// given the parameters and the light's surface normal. This MUST match - /// the PDF computed by sample(). - float pdf (const Vec3 &Ng, - const Vec3 &omega_out) const - { - float cosNO = Ng.dot(omega_out); - return cosNO > 0 ? 1.0f: 0.0f; - } + GenericEmissiveClosure() { } + + void setup() {} + + size_t memsize() const { return sizeof(*this); } + + const char *name() const { return "emission"; } + + void print_on(std::ostream &out) const { + out << name() << "()"; + } + + Color3 eval(const Vec3 &Ng, const Vec3 &omega_out) const + { + float cosNO = fabsf(Ng.dot(omega_out)); + float res = cosNO > 0 ? 1.0f : 0.0f; + return Color3(res, res, res); + } + + void sample(const Vec3 &Ng, float randu, float randv, + Vec3 &omega_out, float &pdf) const + { + // We don't do anything sophisticated here for the step + // We just sample the whole cone uniformly to the cosine + Vec3 T, B; + make_orthonormals(Ng, T, B); + float phi = 2 * (float) M_PI * randu; + float cosTheta = sqrtf(1.0f - 1.0f * randv); + float sinTheta = sqrtf(1.0f - cosTheta * cosTheta); + omega_out = (cosf(phi) * sinTheta) * T + + (sinf(phi) * sinTheta) * B + + cosTheta * Ng; + pdf = 1.0f / float(M_PI); + } + + /// Return the probability distribution function in the direction omega_out, + /// given the parameters and the light's surface normal. This MUST match + /// the PDF computed by sample(). + float pdf(const Vec3 &Ng, + const Vec3 &omega_out) const + { + float cosNO = Ng.dot(omega_out); + return cosNO > 0 ? 1.0f : 0.0f; + } }; ClosureParam closure_emission_params[] = { - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(GenericEmissiveClosure) }; + CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_FINISH_PARAM(GenericEmissiveClosure) +}; CLOSURE_PREPARE(closure_emission_prepare, GenericEmissiveClosure) diff --git a/intern/cycles/kernel/osl/nodes/node_checker_texture.osl b/intern/cycles/kernel/osl/nodes/node_checker_texture.osl index 712d51333ad..306798b645f 100644 --- a/intern/cycles/kernel/osl/nodes/node_checker_texture.osl +++ b/intern/cycles/kernel/osl/nodes/node_checker_texture.osl @@ -23,13 +23,13 @@ float checker(point p) { - p[0] = (p[0] + 0.00001)*0.9999); - p[1] = (p[1] + 0.00001)*0.9999); - p[2] = (p[2] + 0.00001)*0.9999); + p[0] = (p[0] + 0.00001)*0.9999; + p[1] = (p[1] + 0.00001)*0.9999; + p[2] = (p[2] + 0.00001)*0.9999; - int xi = fabs(floor(p[0])); - int yi = fabs(floor(p[1])); - int zi = fabs(floor(p[2])); + int xi = (int)fabs(floor(p[0])); + int yi = (int)fabs(floor(p[1])); + int zi = (int)fabs(floor(p[2])); if((xi % 2 == yi % 2) == (zi % 2)) { return 1.0; @@ -42,9 +42,9 @@ float checker(point p) shader node_checker_texture( float Scale = 5.0, point Vector = P, - color Color1 = color(0.8, 0.8, 0.8); - color Color2 = color(0.2, 0.2, 0.2); - output float Fac = 0.0) + color Color1 = color(0.8, 0.8, 0.8), + color Color2 = color(0.2, 0.2, 0.2), + output float Fac = 0.0, output color Color = color(0.0, 0.0, 0.0)) { Fac = checker(Vector*Scale); diff --git a/intern/cycles/kernel/osl/nodes/node_color.h b/intern/cycles/kernel/osl/nodes/node_color.h index 37d092eae78..80786e4e369 100644 --- a/intern/cycles/kernel/osl/nodes/node_color.h +++ b/intern/cycles/kernel/osl/nodes/node_color.h @@ -18,18 +18,18 @@ float color_srgb_to_scene_linear(float c) { - if(c < 0.04045) - return (c < 0.0)? 0.0: c * (1.0/12.92); + if (c < 0.04045) + return (c < 0.0) ? 0.0 : c * (1.0 / 12.92); else - return pow((c + 0.055)*(1.0/1.055), 2.4); + return pow((c + 0.055) * (1.0 / 1.055), 2.4); } float color_scene_linear_to_srgb(float c) { - if(c < 0.0031308) - return (c < 0.0)? 0.0: c * 12.92; - else - return 1.055 * pow(c, 1.0/2.4) - 0.055; + if (c < 0.0031308) + return (c < 0.0) ? 0.0 : c * 12.92; + else + return 1.055 * pow(c, 1.0 / 2.4) - 0.055; } color color_srgb_to_scene_linear(color c) @@ -61,27 +61,27 @@ color rgb_to_hsv(color rgb) v = cmax; - if(cmax != 0.0) { - s = cdelta/cmax; + if (cmax != 0.0) { + s = cdelta / cmax; } else { s = 0.0; h = 0.0; } - if(s == 0.0) { + if (s == 0.0) { h = 0.0; } else { - c = (color(cmax, cmax, cmax) - rgb)/cdelta; + c = (color(cmax, cmax, cmax) - rgb) / cdelta; - if(rgb[0] == cmax) h = c[2] - c[1]; - else if(rgb[1] == cmax) h = 2.0 + c[0] - c[2]; + if (rgb[0] == cmax) h = c[2] - c[1]; + else if (rgb[1] == cmax) h = 2.0 + c[0] - c[2]; else h = 4.0 + c[1] - c[0]; h /= 6.0; - if(h < 0.0) + if (h < 0.0) h += 1.0; } @@ -97,26 +97,26 @@ color hsv_to_rgb(color hsv) s = hsv[1]; v = hsv[2]; - if(s==0.0) { + if (s == 0.0) { rgb = color(v, v, v); } else { - if(h==1.0) + if (h == 1.0) h = 0.0; h *= 6.0; i = floor(h); f = h - i; rgb = color(f, f, f); - p = v*(1.0-s); - q = v*(1.0-(s*f)); - t = v*(1.0-(s*(1.0-f))); - - if(i == 0.0) rgb = color(v, t, p); - else if(i == 1.0) rgb = color(q, v, p); - else if(i == 2.0) rgb = color(p, v, t); - else if(i == 3.0) rgb = color(p, q, v); - else if(i == 4.0) rgb = color(t, p, v); + p = v * (1.0 - s); + q = v * (1.0 - (s * f)); + t = v * (1.0 - (s * (1.0 - f))); + + if (i == 0.0) rgb = color(v, t, p); + else if (i == 1.0) rgb = color(q, v, p); + else if (i == 2.0) rgb = color(p, v, t); + else if (i == 3.0) rgb = color(p, q, v); + else if (i == 4.0) rgb = color(t, p, v); else rgb = color(v, p, q); } diff --git a/intern/cycles/kernel/osl/nodes/node_fresnel.h b/intern/cycles/kernel/osl/nodes/node_fresnel.h index 0c8a5276ede..dfd0a23fe1e 100644 --- a/intern/cycles/kernel/osl/nodes/node_fresnel.h +++ b/intern/cycles/kernel/osl/nodes/node_fresnel.h @@ -1,17 +1,32 @@ - +/* + * 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. + */ + float fresnel_dielectric(vector Incoming, normal Normal, float eta) { /* compute fresnel reflectance without explicitly computing - the refracted direction */ + * the refracted direction */ float c = fabs(dot(Incoming, Normal)); float g = eta * eta - 1 + c * c; float result; - if(g > 0) { + if (g > 0) { g = sqrt(g); - float A =(g - c)/(g + c); - float B =(c *(g + c)- 1)/(c *(g - c)+ 1); - result = 0.5 * A * A *(1 + B * B); + float A = (g - c) / (g + c); + float B = (c * (g + c) - 1) / (c * (g - c) + 1); + result = 0.5 * A * A * (1 + B * B); } else result = 1.0; /* TIR (no refracted component) */ diff --git a/intern/cycles/kernel/osl/nodes/node_texture.h b/intern/cycles/kernel/osl/nodes/node_texture.h index e0ec8038ee4..d2dbd6db8b3 100644 --- a/intern/cycles/kernel/osl/nodes/node_texture.h +++ b/intern/cycles/kernel/osl/nodes/node_texture.h @@ -20,20 +20,20 @@ float voronoi_distance(string distance_metric, vector d, float e) { float result = 0.0; - if(distance_metric == "Distance Squared") + if (distance_metric == "Distance Squared") result = dot(d, d); - if(distance_metric == "Actual Distance") + if (distance_metric == "Actual Distance") result = length(d); - if(distance_metric == "Manhattan") + if (distance_metric == "Manhattan") result = fabs(d[0]) + fabs(d[1]) + fabs(d[2]); - if(distance_metric == "Chebychev") + if (distance_metric == "Chebychev") result = max(fabs(d[0]), max(fabs(d[1]), fabs(d[2]))); - if(distance_metric == "Minkovsky 1/2") + if (distance_metric == "Minkovsky 1/2") result = sqrt(fabs(d[0])) + sqrt(fabs(d[1])) + sqrt(fabs(d[1])); - if(distance_metric == "Minkovsky 4") - result = sqrt(sqrt(dot(d*d, d*d))); - if(distance_metric == "Minkovsky") - result = pow(pow(fabs(d[0]), e) + pow(fabs(d[1]), e) + pow(fabs(d[2]), e), 1.0/e); + if (distance_metric == "Minkovsky 4") + result = sqrt(sqrt(dot(d * d, d * d))); + if (distance_metric == "Minkovsky") + result = pow(pow(fabs(d[0]), e) + pow(fabs(d[1]), e) + pow(fabs(d[2]), e), 1.0 / e); return result; } @@ -63,9 +63,9 @@ void voronoi(point p, string distance_metric, float e, float da[4], point pa[4]) da[2] = 1e10; da[3] = 1e10; - for(xx = xi-1; xx <= xi+1; xx++) { - for(yy = yi-1; yy <= yi+1; yy++) { - for(zz = zi-1; zz <= zi+1; zz++) { + for (xx = xi - 1; xx <= xi + 1; xx++) { + for (yy = yi - 1; yy <= yi + 1; yy++) { + for (zz = zi - 1; zz <= zi + 1; zz++) { point ip = point(xx, yy, zz); point vp = (point)cellnoise_color(ip); point pd = p - (vp + ip); @@ -73,7 +73,7 @@ void voronoi(point p, string distance_metric, float e, float da[4], point pa[4]) vp += point(xx, yy, zz); - if(d < da[0]) { + if (d < da[0]) { da[3] = da[2]; da[2] = da[1]; da[1] = da[0]; @@ -84,7 +84,7 @@ void voronoi(point p, string distance_metric, float e, float da[4], point pa[4]) pa[1] = pa[0]; pa[0] = vp; } - else if(d < da[1]) { + else if (d < da[1]) { da[3] = da[2]; da[2] = da[1]; da[1] = d; @@ -93,14 +93,14 @@ void voronoi(point p, string distance_metric, float e, float da[4], point pa[4]) pa[2] = pa[1]; pa[1] = vp; } - else if(d < da[2]) { + else if (d < da[2]) { da[3] = da[2]; da[2] = d; pa[3] = pa[2]; pa[2] = vp; } - else if(d < da[3]) { + else if (d < da[3]) { da[3] = d; pa[3] = vp; } @@ -138,16 +138,16 @@ float voronoi_F1F2(point p) { return voronoi_FnFn(p, 0, 1); } float voronoi_Cr(point p) { /* crackle type pattern, just a scale/clamp of F2-F1 */ - float t = 10.0*voronoi_F1F2(p); - return (t > 1.0)? 1.0: t; + float t = 10.0 * voronoi_F1F2(p); + return (t > 1.0) ? 1.0 : t; } -float voronoi_F1S(point p) { return 2.0*voronoi_F1(p) - 1.0; } -float voronoi_F2S(point p) { return 2.0*voronoi_F2(p) - 1.0; } -float voronoi_F3S(point p) { return 2.0*voronoi_F3(p) - 1.0; } -float voronoi_F4S(point p) { return 2.0*voronoi_F4(p) - 1.0; } -float voronoi_F1F2S(point p) { return 2.0*voronoi_F1F2(p) - 1.0; } -float voronoi_CrS(point p) { return 2.0*voronoi_Cr(p) - 1.0; } +float voronoi_F1S(point p) { return 2.0 * voronoi_F1(p) - 1.0; } +float voronoi_F2S(point p) { return 2.0 * voronoi_F2(p) - 1.0; } +float voronoi_F3S(point p) { return 2.0 * voronoi_F3(p) - 1.0; } +float voronoi_F4S(point p) { return 2.0 * voronoi_F4(p) - 1.0; } +float voronoi_F1F2S(point p) { return 2.0 * voronoi_F1F2(p) - 1.0; } +float voronoi_CrS(point p) { return 2.0 * voronoi_Cr(p) - 1.0; } /* Noise Bases */ @@ -155,21 +155,21 @@ float noise_basis(point p, string basis) { float result = 0.0; - if(basis == "Perlin") + if (basis == "Perlin") result = noise(p); - if(basis == "Voronoi F1") + if (basis == "Voronoi F1") result = voronoi_F1S(p); - if(basis == "Voronoi F2") + if (basis == "Voronoi F2") result = voronoi_F2S(p); - if(basis == "Voronoi F3") + if (basis == "Voronoi F3") result = voronoi_F3S(p); - if(basis == "Voronoi F4") + if (basis == "Voronoi F4") result = voronoi_F4S(p); - if(basis == "Voronoi F2-F1") + if (basis == "Voronoi F2-F1") result = voronoi_F1F2S(p); - if(basis == "Voronoi Crackle") + if (basis == "Voronoi Crackle") result = voronoi_CrS(p); - if(basis == "Cell Noise") + if (basis == "Cell Noise") result = cellnoise(p); return result; @@ -180,7 +180,7 @@ float noise_basis(point p, string basis) float noise_basis_hard(point p, string basis, int hard) { float t = noise_basis(p, basis); - return (hard)? fabs(2.0*t - 1.0): t; + return (hard) ? fabs(2.0 * t - 1.0) : t; } /* Waves */ @@ -189,22 +189,22 @@ float noise_wave(string wave, float a) { float result = 0.0; - if(wave == "Sine") { - result = 0.5 + 0.5*sin(a); + if (wave == "Sine") { + result = 0.5 + 0.5 * sin(a); } - else if(wave == "Saw") { - float b = 2*M_PI; + else if (wave == "Saw") { + float b = 2 * M_PI; int n = (int)(a / b); - a -= n*b; - if(a < 0) a += b; + a -= n * b; + if (a < 0) a += b; result = a / b; } - else if(wave == "Tri") { - float b = 2*M_PI; + else if (wave == "Tri") { + float b = 2 * M_PI; float rmax = 1.0; - result = rmax - 2.0*fabs(floor((a*(1.0/b))+0.5) - (a*(1.0/b))); + result = rmax - 2.0 * fabs(floor((a * (1.0 / b)) + 0.5) - (a * (1.0 / b))); } return result; @@ -219,18 +219,18 @@ float noise_turbulence(point p, string basis, int octaves, int hard) float sum = 0.0; int i; - for(i = 0; i <= octaves; i++) { - float t = noise_basis(fscale*p, basis); + for (i = 0; i <= octaves; i++) { + float t = noise_basis(fscale * p, basis); - if(hard) - t = fabs(2.0*t - 1.0); + if (hard) + t = fabs(2.0 * t - 1.0); - sum += t*amp; + sum += t * amp; amp *= 0.5; fscale *= 2.0; } - sum *= ((float)(1 << octaves)/(float)((1 << (octaves+1)) - 1)); + sum *= ((float)(1 << octaves) / (float)((1 << (octaves + 1)) - 1)); return sum; } @@ -241,8 +241,8 @@ float nonzero(float f, float eps) { float r; - if(abs(f) < eps) - r = sign(f)*eps; + if (abs(f) < eps) + r = sign(f) * eps; else r = f; diff --git a/intern/cycles/kernel/osl/nodes/stdosl.h b/intern/cycles/kernel/osl/nodes/stdosl.h index e4a110e737c..0c07c501d69 100644 --- a/intern/cycles/kernel/osl/nodes/stdosl.h +++ b/intern/cycles/kernel/osl/nodes/stdosl.h @@ -163,241 +163,246 @@ vector normalize (vector v) BUILTIN; vector faceforward (vector N, vector I, vector Nref) BUILTIN; vector faceforward (vector N, vector I) BUILTIN; vector reflect (vector I, vector N) { return I - 2*dot(N,I)*N; } -vector refract (vector I, vector N, float eta) { - float IdotN = dot (I, N); - float k = 1 - eta*eta * (1 - IdotN*IdotN); - return (k < 0) ? vector(0,0,0) : (eta*I - N * (eta*IdotN + sqrt(k))); +vector refract(vector I, vector N, float eta) { + float IdotN = dot(I, N); + float k = 1 - eta * eta * (1 - IdotN * IdotN); + return (k < 0) ? vector(0, 0, 0) : (eta * I - N * (eta * IdotN + sqrt(k))); } -void fresnel (vector I, normal N, float eta, - output float Kr, output float Kt, - output vector R, output vector T) +void fresnel(vector I, normal N, float eta, + output float Kr, output float Kt, + output vector R, output vector T) { - float sqr(float x) { return x*x; } - float c = dot(I, N); - if (c < 0) - c = -c; - R = reflect(I, N); - float g = 1.0 / sqr(eta) - 1.0 + c * c; - if (g >= 0.0) { - g = sqrt (g); - float beta = g - c; - float F = (c * (g+c) - 1.0) / (c * beta + 1.0); - F = 0.5 * (1.0 + sqr(F)); - F *= sqr (beta / (g+c)); - Kr = F; - Kt = (1.0 - Kr) * eta*eta; - // OPT: the following recomputes some of the above values, but it - // gives us the same result as if the shader-writer called refract() - T = refract(I, N, eta); - } else { - // total internal reflection - Kr = 1.0; - Kt = 0.0; - T = vector (0,0,0); - } + float sqr(float x) { + return x * x; + } + float c = dot(I, N); + if (c < 0) + c = -c; + R = reflect(I, N); + float g = 1.0 / sqr(eta) - 1.0 + c * c; + if (g >= 0.0) { + g = sqrt(g); + float beta = g - c; + float F = (c * (g + c) - 1.0) / (c * beta + 1.0); + F = 0.5 * (1.0 + sqr(F)); + F *= sqr(beta / (g + c)); + Kr = F; + Kt = (1.0 - Kr) * eta * eta; + // OPT: the following recomputes some of the above values, but it + // gives us the same result as if the shader-writer called refract() + T = refract(I, N, eta); + } + else { + // total internal reflection + Kr = 1.0; + Kt = 0.0; + T = vector(0, 0, 0); + } #undef sqr } -void fresnel (vector I, normal N, float eta, - output float Kr, output float Kt) +void fresnel(vector I, normal N, float eta, + output float Kr, output float Kt) { - vector R, T; - fresnel(I, N, eta, Kr, Kt, R, T); + vector R, T; + fresnel(I, N, eta, Kr, Kt, R, T); } -point rotate (point q, float angle, point a, point b) BUILTIN; +point rotate(point q, float angle, point a, point b) BUILTIN; -normal transform (matrix Mto, normal p) BUILTIN; -vector transform (matrix Mto, vector p) BUILTIN; -point transform (matrix Mto, point p) BUILTIN; +normal transform(matrix Mto, normal p) BUILTIN; +vector transform(matrix Mto, vector p) BUILTIN; +point transform(matrix Mto, point p) BUILTIN; // Implementation of transform-with-named-space in terms of matrices: -point transform (string tospace, point x) +point transform(string tospace, point x) { - return transform (matrix ("common", tospace), x); + return transform(matrix("common", tospace), x); } -point transform (string fromspace, string tospace, point x) +point transform(string fromspace, string tospace, point x) { - return transform (matrix (fromspace, tospace), x); + return transform(matrix(fromspace, tospace), x); } -vector transform (string tospace, vector x) +vector transform(string tospace, vector x) { - return transform (matrix ("common", tospace), x); + return transform(matrix("common", tospace), x); } -vector transform (string fromspace, string tospace, vector x) +vector transform(string fromspace, string tospace, vector x) { - return transform (matrix (fromspace, tospace), x); + return transform(matrix(fromspace, tospace), x); } -normal transform (string tospace, normal x) +normal transform(string tospace, normal x) { - return transform (matrix ("common", tospace), x); + return transform(matrix("common", tospace), x); } -normal transform (string fromspace, string tospace, normal x) +normal transform(string fromspace, string tospace, normal x) { - return transform (matrix (fromspace, tospace), x); + return transform(matrix(fromspace, tospace), x); } -float transformu (string tounits, float x) BUILTIN; -float transformu (string fromunits, string tounits, float x) BUILTIN; +float transformu(string tounits, float x) BUILTIN; +float transformu(string fromunits, string tounits, float x) BUILTIN; // Color functions -float luminance (color c) { - return dot ((vector)c, vector(0.2126, 0.7152, 0.0722)); +float luminance(color c) { + return dot((vector)c, vector(0.2126, 0.7152, 0.0722)); } -color transformc (string to, color x) +color transformc(string to, color x) { - color rgb_to_hsv (color rgb) { // See Foley & van Dam - float r = rgb[0], g = rgb[1], b = rgb[2]; - float mincomp = min (r, min (g, b)); - float maxcomp = max (r, max (g, b)); - float delta = maxcomp - mincomp; // chroma - float h, s, v; - v = maxcomp; - if (maxcomp > 0) - s = delta / maxcomp; - else s = 0; - if (s <= 0) - h = 0; - else { - if (r >= maxcomp) h = (g-b) / delta; - else if (g >= maxcomp) h = 2 + (b-r) / delta; - else h = 4 + (r-g) / delta; - h /= 6; - if (h < 0) - h += 1; - } - return color (h, s, v); - } - - color rgb_to_hsl (color rgb) { // See Foley & van Dam - // First convert rgb to hsv, then to hsl - float minval = min (rgb[0], min (rgb[1], rgb[2])); - color hsv = rgb_to_hsv (rgb); - float maxval = hsv[2]; // v == maxval - float h = hsv[0], s, l = (minval+maxval) / 2; - if (minval == maxval) - s = 0; // special 'achromatic' case, hue is 0 - else if (l <= 0.5) - s = (maxval - minval) / (maxval + minval); - else - s = (maxval - minval) / (2 - maxval - minval); - return color (h, s, l); - } - - color r; - if (to == "rgb" || to == "RGB") - r = x; - else if (to == "hsv") - r = rgb_to_hsv (x); - else if (to == "hsl") - r = rgb_to_hsl (x); - else if (to == "YIQ") - r = color (dot (vector(0.299, 0.587, 0.114), (vector)x), - dot (vector(0.596, -0.275, -0.321), (vector)x), - dot (vector(0.212, -0.523, 0.311), (vector)x)); - else if (to == "xyz") - r = color (dot (vector(0.412453, 0.357580, 0.180423), (vector)x), - dot (vector(0.212671, 0.715160, 0.072169), (vector)x), - dot (vector(0.019334, 0.119193, 0.950227), (vector)x)); - else { - error ("Unknown color space \"%s\"", to); - r = x; - } - return r; + color rgb_to_hsv(color rgb) { // See Foley & van Dam + float r = rgb[0], g = rgb[1], b = rgb[2]; + float mincomp = min(r, min(g, b)); + float maxcomp = max(r, max(g, b)); + float delta = maxcomp - mincomp; // chroma + float h, s, v; + v = maxcomp; + if (maxcomp > 0) + s = delta / maxcomp; + else s = 0; + if (s <= 0) + h = 0; + else { + if (r >= maxcomp) h = (g - b) / delta; + else if (g >= maxcomp) h = 2 + (b - r) / delta; + else h = 4 + (r - g) / delta; + h /= 6; + if (h < 0) + h += 1; + } + return color(h, s, v); + } + + color rgb_to_hsl(color rgb) { // See Foley & van Dam + // First convert rgb to hsv, then to hsl + float minval = min(rgb[0], min(rgb[1], rgb[2])); + color hsv = rgb_to_hsv(rgb); + float maxval = hsv[2]; // v == maxval + float h = hsv[0], s, l = (minval + maxval) / 2; + if (minval == maxval) + s = 0; // special 'achromatic' case, hue is 0 + else if (l <= 0.5) + s = (maxval - minval) / (maxval + minval); + else + s = (maxval - minval) / (2 - maxval - minval); + return color(h, s, l); + } + + color r; + if (to == "rgb" || to == "RGB") + r = x; + else if (to == "hsv") + r = rgb_to_hsv(x); + else if (to == "hsl") + r = rgb_to_hsl(x); + else if (to == "YIQ") + r = color(dot(vector(0.299, 0.587, 0.114), (vector)x), + dot(vector(0.596, -0.275, -0.321), (vector)x), + dot(vector(0.212, -0.523, 0.311), (vector)x)); + else if (to == "xyz") + r = color(dot(vector(0.412453, 0.357580, 0.180423), (vector)x), + dot(vector(0.212671, 0.715160, 0.072169), (vector)x), + dot(vector(0.019334, 0.119193, 0.950227), (vector)x)); + else { + error("Unknown color space \"%s\"", to); + r = x; + } + return r; } -color transformc (string from, string to, color x) +color transformc(string from, string to, color x) { - color hsv_to_rgb (color c) { // Reference: Foley & van Dam - float h = c[0], s = c[1], v = c[2]; - color r; - if (s < 0.0001) { - r = v; - } else { - h = 6 * (h - floor(h)); // expand to [0..6) - int hi = (int)h; - float f = h - hi; - float p = v * (1-s); - float q = v * (1-s*f); - float t = v * (1-s*(1-f)); - if (hi == 0) r = color (v, t, p); - else if (hi == 1) r = color (q, v, p); - else if (hi == 2) r = color (p, v, t); - else if (hi == 3) r = color (p, q, v); - else if (hi == 4) r = color (t, p, v); - else r = color (v, p, q); - } - return r; - } - - color hsl_to_rgb (color c) { - float h = c[0], s = c[1], l = c[2]; - // Easiest to convert hsl -> hsv, then hsv -> RGB (per Foley & van Dam) - float v = (l <= 0.5) ? (l * (1 + s)) : (l * (1 - s) + s); - color r; - if (v <= 0) { - r = 0; - } else { - float min = 2 * l - v; - s = (v - min) / v; - r = hsv_to_rgb (color (h, s, v)); - } - return r; - } - - color r; - if (from == "rgb" || from == "RGB") - r = x; - else if (from == "hsv") - r = hsv_to_rgb (x); - else if (from == "hsl") - r = hsl_to_rgb (x); - else if (from == "YIQ") - r = color (dot (vector(1, 0.9557, 0.6199), (vector)x), - dot (vector(1, -0.2716, -0.6469), (vector)x), - dot (vector(1, -1.1082, 1.7051), (vector)x)); - else if (from == "xyz") - r = color (dot (vector( 3.240479, -1.537150, -0.498535), (vector)x), - dot (vector(-0.969256, 1.875991, 0.041556), (vector)x), - dot (vector( 0.055648, -0.204043, 1.057311), (vector)x)); - else { - error ("Unknown color space \"%s\"", to); - r = x; - } - return transformc (to, r); + color hsv_to_rgb(color c) { // Reference: Foley & van Dam + float h = c[0], s = c[1], v = c[2]; + color r; + if (s < 0.0001) { + r = v; + } + else { + h = 6 * (h - floor(h)); // expand to [0..6) + int hi = (int)h; + float f = h - hi; + float p = v * (1 - s); + float q = v * (1 - s * f); + float t = v * (1 - s * (1 - f)); + if (hi == 0) r = color(v, t, p); + else if (hi == 1) r = color(q, v, p); + else if (hi == 2) r = color(p, v, t); + else if (hi == 3) r = color(p, q, v); + else if (hi == 4) r = color(t, p, v); + else r = color(v, p, q); + } + return r; + } + + color hsl_to_rgb(color c) { + float h = c[0], s = c[1], l = c[2]; + // Easiest to convert hsl -> hsv, then hsv -> RGB (per Foley & van Dam) + float v = (l <= 0.5) ? (l * (1 + s)) : (l * (1 - s) + s); + color r; + if (v <= 0) { + r = 0; + } + else { + float min = 2 * l - v; + s = (v - min) / v; + r = hsv_to_rgb(color(h, s, v)); + } + return r; + } + + color r; + if (from == "rgb" || from == "RGB") + r = x; + else if (from == "hsv") + r = hsv_to_rgb(x); + else if (from == "hsl") + r = hsl_to_rgb(x); + else if (from == "YIQ") + r = color(dot(vector(1, 0.9557, 0.6199), (vector)x), + dot(vector(1, -0.2716, -0.6469), (vector)x), + dot(vector(1, -1.1082, 1.7051), (vector)x)); + else if (from == "xyz") + r = color(dot(vector(3.240479, -1.537150, -0.498535), (vector)x), + dot(vector(-0.969256, 1.875991, 0.041556), (vector)x), + dot(vector(0.055648, -0.204043, 1.057311), (vector)x)); + else { + error("Unknown color space \"%s\"", to); + r = x; + } + return transformc(to, r); } // Matrix functions -float determinant (matrix m) BUILTIN; -matrix transpose (matrix m) BUILTIN; +float determinant(matrix m) BUILTIN; +matrix transpose(matrix m) BUILTIN; // Pattern generation -float step (float edge, float x) BUILTIN; -color step (color edge, color x) BUILTIN; -point step (point edge, point x) BUILTIN; -vector step (vector edge, vector x) BUILTIN; -normal step (normal edge, normal x) BUILTIN; -float smoothstep (float edge0, float edge1, float x) BUILTIN; +float step(float edge, float x) BUILTIN; +color step(color edge, color x) BUILTIN; +point step(point edge, point x) BUILTIN; +vector step(vector edge, vector x) BUILTIN; +normal step(normal edge, normal x) BUILTIN; +float smoothstep(float edge0, float edge1, float x) BUILTIN; // Derivatives and area operators @@ -408,24 +413,26 @@ float smoothstep (float edge0, float edge1, float x) BUILTIN; // String functions -int strlen (string s) BUILTIN; -int startswith (string s, string prefix) BUILTIN; -int endswith (string s, string suffix) BUILTIN; -string substr (string s, int start, int len) BUILTIN; -string substr (string s, int start) { return substr (s, start, strlen(s)); } +int strlen(string s) BUILTIN; +int startswith(string s, string prefix) BUILTIN; +int endswith(string s, string suffix) BUILTIN; +string substr(string s, int start, int len) BUILTIN; +string substr(string s, int start) { + return substr(s, start, strlen(s)); +} // Define concat in terms of shorter concat -string concat (string a, string b, string c) { - return concat(concat(a,b), c); +string concat(string a, string b, string c) { + return concat(concat(a, b), c); } -string concat (string a, string b, string c, string d) { - return concat(concat(a,b,c), d); +string concat(string a, string b, string c, string d) { + return concat(concat(a, b, c), d); } -string concat (string a, string b, string c, string d, string e) { - return concat(concat(a,b,c,d), e); +string concat(string a, string b, string c, string d, string e) { + return concat(concat(a, b, c, d), e); } -string concat (string a, string b, string c, string d, string e, string f) { - return concat(concat(a,b,c,d,e), f); +string concat(string a, string b, string c, string d, string e, string f) { + return concat(concat(a, b, c, d, e), f); } @@ -438,7 +445,7 @@ closure color diffuse(normal N) BUILTIN; closure color oren_nayar(normal N, float sigma) BUILTIN; closure color translucent(normal N) BUILTIN; closure color reflection(normal N, float eta) BUILTIN; -closure color reflection(normal N) { return reflection (N, 0.0); } +closure color reflection(normal N) { return reflection(N, 0.0); } closure color refraction(normal N, float eta) BUILTIN; closure color dielectric(normal N, float eta) BUILTIN; closure color transparent() BUILTIN; @@ -446,7 +453,7 @@ closure color microfacet_ggx(normal N, float ag) BUILTIN; closure color microfacet_ggx_refraction(normal N, float ag, float eta) BUILTIN; closure color microfacet_beckmann(normal N, float ab) BUILTIN; closure color microfacet_beckmann_refraction(normal N, float ab, float eta) BUILTIN; -closure color ward(normal N, vector T,float ax, float ay) BUILTIN; +closure color ward(normal N, vector T, float ax, float ay) BUILTIN; closure color ashikhmin_velvet(normal N, float sigma) BUILTIN; closure color westin_backscatter(normal N, float roughness) BUILTIN; closure color westin_sheen(normal N, float edginess) BUILTIN; @@ -460,7 +467,7 @@ closure color holdout() BUILTIN; closure color subsurface(float eta, float g, float mfp, float albedo) BUILTIN; // Renderer state -int raytype (string typename) BUILTIN; +int raytype(string typename) BUILTIN; #undef BUILTIN #undef BUILTIN_DERIV diff --git a/intern/cycles/kernel/osl/osl_closures.cpp b/intern/cycles/kernel/osl/osl_closures.cpp index b87cdf8af86..0793b29d1ac 100644 --- a/intern/cycles/kernel/osl/osl_closures.cpp +++ b/intern/cycles/kernel/osl/osl_closures.cpp @@ -48,7 +48,7 @@ static void generic_closure_setup(OSL::RendererServices *, int id, void *data) prim->setup(); } -static bool generic_closure_mergeable(int id, const void *dataA, const void *dataB) +static bool generic_closure_compare(int id, const void *dataA, const void *dataB) { assert(dataA && dataB); @@ -59,11 +59,7 @@ static bool generic_closure_mergeable(int id, const void *dataA, const void *dat static void register_closure(OSL::ShadingSystem *ss, const char *name, int id, OSL::ClosureParam *params, OSL::PrepareClosureFunc prepare) { - int j; - for(j = 0; params[j].type != TypeDesc(); ++j) {} - int size = params[j].offset; - - ss->register_closure(name, id, params, size, prepare, generic_closure_setup, generic_closure_mergeable); + ss->register_closure(name, id, params, prepare, generic_closure_setup, generic_closure_compare); } void OSLShader::register_closures(OSL::ShadingSystem *ss) diff --git a/intern/cycles/kernel/osl/osl_services.cpp b/intern/cycles/kernel/osl/osl_services.cpp index 1b52a3e489b..a1574d6e0db 100644 --- a/intern/cycles/kernel/osl/osl_services.cpp +++ b/intern/cycles/kernel/osl/osl_services.cpp @@ -37,7 +37,7 @@ CCL_NAMESPACE_BEGIN /* RenderServices implementation */ -#define TO_MATRIX44(m) (*(OSL::Matrix44*)&(m)) +#define TO_MATRIX44(m) (*(OSL::Matrix44 *)&(m)) /* static ustrings */ ustring OSLRenderServices::u_distance("distance"); @@ -65,14 +65,14 @@ void OSLRenderServices::thread_init(KernelGlobals *kernel_globals_) bool OSLRenderServices::get_matrix(OSL::Matrix44 &result, OSL::TransformationPtr xform, float time) { /* this is only used for shader and object space, we don't really have - a concept of shader space, so we just use object space for both. */ - if(xform) { + * a concept of shader space, so we just use object space for both. */ + if (xform) { KernelGlobals *kg = kernel_globals; - const ShaderData *sd = (const ShaderData*)xform; + const ShaderData *sd = (const ShaderData *)xform; int object = sd->object; - if(object != ~0) { - Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM); + if (object != ~0) { + Transform tfm = object_fetch_transform(kg, object, time, OBJECT_TRANSFORM); tfm = transform_transpose(tfm); result = TO_MATRIX44(tfm); @@ -86,14 +86,14 @@ bool OSLRenderServices::get_matrix(OSL::Matrix44 &result, OSL::TransformationPtr bool OSLRenderServices::get_inverse_matrix(OSL::Matrix44 &result, OSL::TransformationPtr xform, float time) { /* this is only used for shader and object space, we don't really have - a concept of shader space, so we just use object space for both. */ - if(xform) { + * a concept of shader space, so we just use object space for both. */ + if (xform) { KernelGlobals *kg = kernel_globals; - const ShaderData *sd = (const ShaderData*)xform; + const ShaderData *sd = (const ShaderData *)xform; int object = sd->object; - if(object != ~0) { - Transform tfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); + if (object != ~0) { + Transform tfm = object_fetch_transform(kg, object, time, OBJECT_INVERSE_TRANSFORM); tfm = transform_transpose(tfm); result = TO_MATRIX44(tfm); @@ -108,22 +108,22 @@ bool OSLRenderServices::get_matrix(OSL::Matrix44 &result, ustring from, float ti { KernelGlobals *kg = kernel_globals; - if(from == u_ndc) { + if (from == u_ndc) { Transform tfm = transform_transpose(kernel_data.cam.ndctoworld); result = TO_MATRIX44(tfm); return true; } - else if(from == u_raster) { + else if (from == u_raster) { Transform tfm = transform_transpose(kernel_data.cam.rastertoworld); result = TO_MATRIX44(tfm); return true; } - else if(from == u_screen) { + else if (from == u_screen) { Transform tfm = transform_transpose(kernel_data.cam.screentoworld); result = TO_MATRIX44(tfm); return true; } - else if(from == u_camera) { + else if (from == u_camera) { Transform tfm = transform_transpose(kernel_data.cam.cameratoworld); result = TO_MATRIX44(tfm); return true; @@ -136,22 +136,22 @@ bool OSLRenderServices::get_inverse_matrix(OSL::Matrix44 &result, ustring to, fl { KernelGlobals *kg = kernel_globals; - if(to == u_ndc) { + if (to == u_ndc) { Transform tfm = transform_transpose(kernel_data.cam.worldtondc); result = TO_MATRIX44(tfm); return true; } - else if(to == u_raster) { + else if (to == u_raster) { Transform tfm = transform_transpose(kernel_data.cam.worldtoraster); result = TO_MATRIX44(tfm); return true; } - else if(to == u_screen) { + else if (to == u_screen) { Transform tfm = transform_transpose(kernel_data.cam.worldtoscreen); result = TO_MATRIX44(tfm); return true; } - else if(to == u_camera) { + else if (to == u_camera) { Transform tfm = transform_transpose(kernel_data.cam.worldtocamera); result = TO_MATRIX44(tfm); return true; @@ -161,56 +161,57 @@ bool OSLRenderServices::get_inverse_matrix(OSL::Matrix44 &result, ustring to, fl } bool OSLRenderServices::get_array_attribute(void *renderstate, bool derivatives, - ustring object, TypeDesc type, ustring name, - int index, void *val) + ustring object, TypeDesc type, ustring name, + int index, void *val) { return false; } static bool get_mesh_attribute(KernelGlobals *kg, const ShaderData *sd, - const OSLGlobals::Attribute& attr, bool derivatives, void *val) + const OSLGlobals::Attribute& attr, bool derivatives, void *val) { - if(attr.type == TypeDesc::TypeFloat) { - float *fval = (float*)val; + if (attr.type == TypeDesc::TypeFloat) { + float *fval = (float *)val; fval[0] = triangle_attribute_float(kg, sd, attr.elem, attr.offset, - (derivatives)? &fval[1]: NULL, (derivatives)? &fval[2]: NULL); + (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL); } else { /* todo: this won't work when float3 has w component */ - float3 *fval = (float3*)val; + float3 *fval = (float3 *)val; fval[0] = triangle_attribute_float3(kg, sd, attr.elem, attr.offset, - (derivatives)? &fval[1]: NULL, (derivatives)? &fval[2]: NULL); + (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL); } return true; } static bool get_mesh_attribute_convert(KernelGlobals *kg, const ShaderData *sd, - const OSLGlobals::Attribute& attr, const TypeDesc& type, bool derivatives, void *val) + const OSLGlobals::Attribute& attr, const TypeDesc& type, bool derivatives, void *val) { - if(attr.type == TypeDesc::TypeFloat) { + if (attr.type == TypeDesc::TypeFloat) { float tmp[3]; - float3 *fval = (float3*)val; + float3 *fval = (float3 *)val; get_mesh_attribute(kg, sd, attr, derivatives, tmp); fval[0] = make_float3(tmp[0], tmp[0], tmp[0]); - if(derivatives) { + if (derivatives) { fval[1] = make_float3(tmp[1], tmp[1], tmp[1]); fval[2] = make_float3(tmp[2], tmp[2], tmp[2]); } return true; } - else if(attr.type == TypeDesc::TypePoint || attr.type == TypeDesc::TypeVector || - attr.type == TypeDesc::TypeNormal || attr.type == TypeDesc::TypeColor) { + else if (attr.type == TypeDesc::TypePoint || attr.type == TypeDesc::TypeVector || + attr.type == TypeDesc::TypeNormal || attr.type == TypeDesc::TypeColor) + { float3 tmp[3]; - float *fval = (float*)val; + float *fval = (float *)val; get_mesh_attribute(kg, sd, attr, derivatives, tmp); fval[0] = average(tmp[0]); - if(derivatives) { + if (derivatives) { fval[1] = average(tmp[1]); fval[2] = average(tmp[2]); } @@ -226,29 +227,29 @@ static void get_object_attribute(const OSLGlobals::Attribute& attr, bool derivat size_t datasize = attr.value.datasize(); memcpy(val, attr.value.data(), datasize); - if(derivatives) - memset((char*)val + datasize, 0, datasize*2); + if (derivatives) + memset((char *)val + datasize, 0, datasize * 2); } bool OSLRenderServices::get_attribute(void *renderstate, bool derivatives, ustring object_name, - TypeDesc type, ustring name, void *val) + TypeDesc type, ustring name, void *val) { KernelGlobals *kg = kernel_globals; - const ShaderData *sd = (const ShaderData*)renderstate; + const ShaderData *sd = (const ShaderData *)renderstate; int object = sd->object; int tri = sd->prim; /* lookup of attribute on another object */ - if(object_name != u_empty) { + if (object_name != u_empty) { OSLGlobals::ObjectNameMap::iterator it = kg->osl.object_name_map.find(object_name); - if(it == kg->osl.object_name_map.end()) + if (it == kg->osl.object_name_map.end()) return false; object = it->second; tri = ~0; } - else if(object == ~0) { + else if (object == ~0) { /* no background attributes supported */ return false; } @@ -257,20 +258,23 @@ bool OSLRenderServices::get_attribute(void *renderstate, bool derivatives, ustri OSLGlobals::AttributeMap& attribute_map = kg->osl.attribute_map[object]; OSLGlobals::AttributeMap::iterator it = attribute_map.find(name); - if(it == attribute_map.end()) + if (it == attribute_map.end()) return false; /* type mistmatch? */ const OSLGlobals::Attribute& attr = it->second; - if(attr.elem != ATTR_ELEMENT_VALUE) { + if (attr.elem != ATTR_ELEMENT_VALUE) { /* triangle and vertex attributes */ - if(tri != ~0) { - if(attr.type == type || (attr.type == TypeDesc::TypeColor && - (type == TypeDesc::TypePoint || type == TypeDesc::TypeVector || type == TypeDesc::TypeNormal))) + if (tri != ~0) { + if (attr.type == type || (attr.type == TypeDesc::TypeColor && + (type == TypeDesc::TypePoint || type == TypeDesc::TypeVector || type == TypeDesc::TypeNormal))) + { return get_mesh_attribute(kg, sd, attr, derivatives, val); - else + } + else { return get_mesh_attribute_convert(kg, sd, attr, type, derivatives, val); + } } } else { @@ -283,7 +287,7 @@ bool OSLRenderServices::get_attribute(void *renderstate, bool derivatives, ustri } bool OSLRenderServices::get_userdata(bool derivatives, ustring name, TypeDesc type, - void *renderstate, void *val) + void *renderstate, void *val) { return false; /* disabled by lockgeom */ } @@ -294,42 +298,46 @@ bool OSLRenderServices::has_userdata(ustring name, TypeDesc type, void *renderst } void *OSLRenderServices::get_pointcloud_attr_query(ustring *attr_names, - TypeDesc *attr_types, int nattrs) + TypeDesc *attr_types, int nattrs) { #ifdef WITH_PARTIO m_attr_queries.push_back(AttrQuery()); AttrQuery &query = m_attr_queries.back(); /* make space for what we need. the only reason to use - std::vector is to skip the delete */ + * std::vector is to skip the delete */ query.attr_names.resize(nattrs); query.attr_partio_types.resize(nattrs); /* capacity will keep the length of the smallest array passed - to the query. Just to prevent buffer overruns */ + * to the query. Just to prevent buffer overruns */ query.capacity = -1; - for(int i = 0; i < nattrs; ++i) - { + for (int i = 0; i < nattrs; ++i) { query.attr_names[i] = attr_names[i]; - TypeDesc element_type = attr_types[i].elementtype (); + TypeDesc element_type = attr_types[i].elementtype(); - if(query.capacity < 0) - query.capacity = attr_types[i].numelements(); + if (query.capacity < 0) + query.capacity = attr_types[i].numelements(); else - query.capacity = min(query.capacity, (int)attr_types[i].numelements()); + query.capacity = min(query.capacity, (int)attr_types[i].numelements()); /* convert the OSL (OIIO) type to the equivalent Partio type so - we can do a fast check at query time. */ - if(element_type == TypeDesc::TypeFloat) - query.attr_partio_types[i] = Partio::FLOAT; - else if(element_type == TypeDesc::TypeInt) - query.attr_partio_types[i] = Partio::INT; - else if(element_type == TypeDesc::TypeColor || element_type == TypeDesc::TypePoint || - element_type == TypeDesc::TypeVector || element_type == TypeDesc::TypeNormal) - query.attr_partio_types[i] = Partio::VECTOR; - else - return NULL; /* report some error of unknown type */ + * we can do a fast check at query time. */ + if (element_type == TypeDesc::TypeFloat) { + query.attr_partio_types[i] = Partio::FLOAT; + } + else if (element_type == TypeDesc::TypeInt) { + query.attr_partio_types[i] = Partio::INT; + } + else if (element_type == TypeDesc::TypeColor || element_type == TypeDesc::TypePoint || + element_type == TypeDesc::TypeVector || element_type == TypeDesc::TypeNormal) + { + query.attr_partio_types[i] = Partio::VECTOR; + } + else { + return NULL; /* report some error of unknown type */ + } } /* this is valid until the end of RenderServices */ @@ -348,35 +356,35 @@ Partio::ParticlesData *OSLRenderServices::get_pointcloud(ustring filename) #endif int OSLRenderServices::pointcloud(ustring filename, const OSL::Vec3 ¢er, float radius, - int max_points, void *_attr_query, void **attr_outdata) + int max_points, void *_attr_query, void **attr_outdata) { /* todo: this code has never been tested, and most likely does not - work. it's based on the example code in OSL */ + * work. it's based on the example code in OSL */ #ifdef WITH_PARTIO /* query Partio for this pointcloud lookup using cached attr_query */ - if(!_attr_query) + if (!_attr_query) return 0; AttrQuery *attr_query = (AttrQuery *)_attr_query; - if(attr_query->capacity < max_points) + if (attr_query->capacity < max_points) return 0; /* get the pointcloud entry for the given filename */ Partio::ParticlesData *cloud = get_pointcloud(filename); /* now we have to look up all the attributes in the file. we can't do this - before hand cause we never know what we are going to load. */ + * before hand cause we never know what we are going to load. */ int nattrs = attr_query->attr_names.size(); Partio::ParticleAttribute *attr = (Partio::ParticleAttribute *)alloca(sizeof(Partio::ParticleAttribute) * nattrs); - for(int i = 0; i < nattrs; ++i) { + for (int i = 0; i < nattrs; ++i) { /* special case attributes */ - if(attr_query->attr_names[i] == u_distance || attr_query->attr_names[i] == u_index) + if (attr_query->attr_names[i] == u_distance || attr_query->attr_names[i] == u_index) continue; /* lookup the attribute by name*/ - if(!cloud->attributeInfo(attr_query->attr_names[i].c_str(), attr[i])) { + if (!cloud->attributeInfo(attr_query->attr_names[i].c_str(), attr[i])) { /* issue an error here and return, types don't match */ Partio::endCachedAccess(cloud); cloud->release(); @@ -394,20 +402,20 @@ int OSLRenderServices::pointcloud(ustring filename, const OSL::Vec3 ¢er, flo int count = indices.size(); /* retrieve the attributes directly to user space */ - for(int j = 0; j < nattrs; ++j) { + for (int j = 0; j < nattrs; ++j) { /* special cases */ - if(attr_query->attr_names[j] == u_distance) { - for(int i = 0; i < count; ++i) + if (attr_query->attr_names[j] == u_distance) { + for (int i = 0; i < count; ++i) ((float *)attr_outdata[j])[i] = sqrtf(dist2[i]); } - else if(attr_query->attr_names[j] == u_index) { - for(int i = 0; i < count; ++i) + else if (attr_query->attr_names[j] == u_index) { + for (int i = 0; i < count; ++i) ((int *)attr_outdata[j])[i] = indices[i]; } else { /* note we make a single call per attribute, we don't loop over the - points. Partio does it, so it is there that we have to care about - performance */ + * points. Partio does it, so it is there that we have to care about + * performance */ cloud->data(attr[j], count, &indices[0], true, attr_outdata[j]); } } diff --git a/intern/cycles/kernel/osl/osl_services.h b/intern/cycles/kernel/osl/osl_services.h index 85a01e54e5c..e637b53ab78 100644 --- a/intern/cycles/kernel/osl/osl_services.h +++ b/intern/cycles/kernel/osl/osl_services.h @@ -57,34 +57,33 @@ public: bool get_inverse_matrix(OSL::Matrix44 &result, ustring to, float time); bool get_array_attribute(void *renderstate, bool derivatives, - ustring object, TypeDesc type, ustring name, - int index, void *val); + ustring object, TypeDesc type, ustring name, + int index, void *val); bool get_attribute(void *renderstate, bool derivatives, ustring object, - TypeDesc type, ustring name, void *val); + TypeDesc type, ustring name, void *val); bool get_userdata(bool derivatives, ustring name, TypeDesc type, - void *renderstate, void *val); + void *renderstate, void *val); bool has_userdata(ustring name, TypeDesc type, void *renderstate); void *get_pointcloud_attr_query(ustring *attr_names, - TypeDesc *attr_types, int nattrs); + TypeDesc *attr_types, int nattrs); int pointcloud(ustring filename, const OSL::Vec3 ¢er, float radius, - int max_points, void *attr_query, void **attr_outdata); + int max_points, void *attr_query, void **attr_outdata); private: KernelGlobals *kernel_globals; #ifdef WITH_PARTIO /* OSL gets pointers to this but its definition is private. - right now it only caches the types already converted to - Partio constants. this is what get_pointcloud_attr_query - returns */ - struct AttrQuery - { + * right now it only caches the types already converted to + * Partio constants. this is what get_pointcloud_attr_query + * returns */ + struct AttrQuery { /* names of the attributes to query */ std::vector<ustring> attr_names; /* types as (enum Partio::ParticleAttributeType) of the - attributes in the query */ + * attributes in the query */ std::vector<int> attr_partio_types; /* for sanity checks, capacity of the output arrays */ int capacity; diff --git a/intern/cycles/kernel/osl/osl_shader.cpp b/intern/cycles/kernel/osl/osl_shader.cpp index 18a8e974492..d8d510a7c9b 100644 --- a/intern/cycles/kernel/osl/osl_shader.cpp +++ b/intern/cycles/kernel/osl/osl_shader.cpp @@ -27,7 +27,6 @@ #include "util_foreach.h" #include <OSL/oslexec.h> -#include <oslexec_pvt.h> CCL_NAMESPACE_BEGIN @@ -37,7 +36,7 @@ tls_ptr(OSLGlobals::ThreadData, OSLGlobals::thread_data); void OSLShader::thread_init(KernelGlobals *kg) { - OSL::pvt::ShadingSystemImpl *ssi = (OSL::pvt::ShadingSystemImpl*)kg->osl.ss; + OSL::pvt::ShadingSystemImpl *ssi = (OSL::pvt::ShadingSystemImpl *)kg->osl.ss; OSLGlobals::ThreadData *tdata = new OSLGlobals::ThreadData(); @@ -46,12 +45,12 @@ void OSLShader::thread_init(KernelGlobals *kg) tls_set(kg->osl.thread_data, tdata); - ((OSLRenderServices*)ssi->renderer())->thread_init(kg); + ((OSLRenderServices *)ssi->renderer())->thread_init(kg); } void OSLShader::thread_free(KernelGlobals *kg) { - OSL::pvt::ShadingSystemImpl *ssi = (OSL::pvt::ShadingSystemImpl*)kg->osl.ss; + OSL::pvt::ShadingSystemImpl *ssi = (OSL::pvt::ShadingSystemImpl *)kg->osl.ss; OSLGlobals::ThreadData *tdata = tls_get(OSLGlobals::ThreadData, kg->osl.thread_data); @@ -62,12 +61,12 @@ void OSLShader::thread_free(KernelGlobals *kg) /* Globals */ -#define TO_VEC3(v) (*(OSL::Vec3*)&(v)) -#define TO_COLOR3(v) (*(OSL::Color3*)&(v)) +#define TO_VEC3(v) (*(OSL::Vec3 *)&(v)) +#define TO_COLOR3(v) (*(OSL::Color3 *)&(v)) #define TO_FLOAT3(v) make_float3(v[0], v[1], v[2]) static void shaderdata_to_shaderglobals(KernelGlobals *kg, ShaderData *sd, - int path_flag, OSL::ShaderGlobals *globals) + int path_flag, OSL::ShaderGlobals *globals) { /* copy from shader data to shader globals */ globals->P = TO_VEC3(sd->P); @@ -86,7 +85,7 @@ static void shaderdata_to_shaderglobals(KernelGlobals *kg, ShaderData *sd, globals->dvdy = sd->dv.dy; globals->dPdu = TO_VEC3(sd->dPdu); globals->dPdv = TO_VEC3(sd->dPdv); - globals->surfacearea = (sd->object == ~0)? 1.0f: object_surface_area(kg, sd->object); + globals->surfacearea = (sd->object == ~0) ? 1.0f : object_surface_area(kg, sd->object); /* booleans */ globals->raytype = path_flag; /* todo: add our own ray types */ @@ -109,35 +108,35 @@ static void shaderdata_to_shaderglobals(KernelGlobals *kg, ShaderData *sd, /* Surface */ static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy, - const OSL::ClosureColor *closure, float3 weight = make_float3(1.0f, 1.0f, 1.0f)) + const OSL::ClosureColor *closure, float3 weight = make_float3(1.0f, 1.0f, 1.0f)) { - /* OSL gives use a closure tree, we flatten it into arrays per + /* 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; - OSL::ClosurePrimitive *prim = (OSL::ClosurePrimitive*)comp->data(); + if (closure->type == OSL::ClosureColor::COMPONENT) { + OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure; + OSL::ClosurePrimitive *prim = (OSL::ClosurePrimitive *)comp->data(); - if(prim) { + if (prim) { ShaderClosure sc; sc.prim = prim; sc.weight = weight; - switch(prim->category()) { + switch (prim->category()) { case ClosurePrimitive::BSDF: { - if(sd->num_closure == MAX_CLOSURE) + if (sd->num_closure == MAX_CLOSURE) return; - OSL::BSDFClosure *bsdf = (OSL::BSDFClosure*)prim; + OSL::BSDFClosure *bsdf = (OSL::BSDFClosure *)prim; ustring scattering = bsdf->scattering(); /* no caustics option */ - if(no_glossy && scattering == OSL::Labels::GLOSSY) + if (no_glossy && scattering == OSL::Labels::GLOSSY) return; /* sample weight */ float albedo = bsdf->albedo(TO_VEC3(sd->I)); - float sample_weight = fabsf(average(weight))*albedo; + float sample_weight = fabsf(average(weight)) * albedo; float sample_sum = sd->osl_closure.bsdf_sample_sum + sample_weight; sc.sample_weight = sample_weight; @@ -145,10 +144,10 @@ static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy, sd->osl_closure.bsdf_sample_sum = sample_sum; /* scattering flags */ - if(scattering == OSL::Labels::DIFFUSE) - sd->flag |= SD_BSDF|SD_BSDF_HAS_EVAL; - else if(scattering == OSL::Labels::GLOSSY) - sd->flag |= SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY; + if (scattering == OSL::Labels::DIFFUSE) + sd->flag |= SD_BSDF | SD_BSDF_HAS_EVAL; + else if (scattering == OSL::Labels::GLOSSY) + sd->flag |= SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_GLOSSY; else sd->flag |= SD_BSDF; @@ -157,7 +156,7 @@ static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy, break; } case ClosurePrimitive::Emissive: { - if(sd->num_closure == MAX_CLOSURE) + if (sd->num_closure == MAX_CLOSURE) return; /* sample weight */ @@ -175,7 +174,7 @@ static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy, break; } case ClosurePrimitive::Holdout: - if(sd->num_closure == MAX_CLOSURE) + if (sd->num_closure == MAX_CLOSURE) return; sc.sample_weight = 0.0f; @@ -192,12 +191,12 @@ static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy, } } } - else if(closure->type == OSL::ClosureColor::MUL) { - OSL::ClosureMul *mul = (OSL::ClosureMul*)closure; + else if (closure->type == OSL::ClosureColor::MUL) { + OSL::ClosureMul *mul = (OSL::ClosureMul *)closure; flatten_surface_closure_tree(sd, no_glossy, mul->closure, TO_FLOAT3(mul->weight) * weight); } - else if(closure->type == OSL::ClosureColor::ADD) { - OSL::ClosureAdd *add = (OSL::ClosureAdd*)closure; + else if (closure->type == OSL::ClosureColor::ADD) { + OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure; flatten_surface_closure_tree(sd, no_glossy, add->closureA, weight); flatten_surface_closure_tree(sd, no_glossy, add->closureB, weight); } @@ -206,7 +205,7 @@ static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy, void OSLShader::eval_surface(KernelGlobals *kg, ShaderData *sd, float randb, int path_flag) { /* gather pointers */ - OSL::pvt::ShadingSystemImpl *ssi = (OSL::pvt::ShadingSystemImpl*)kg->osl.ss; + OSL::pvt::ShadingSystemImpl *ssi = (OSL::pvt::ShadingSystemImpl *)kg->osl.ss; OSLGlobals::ThreadData *tdata = tls_get(OSLGlobals::ThreadData, kg->osl.thread_data); OSL::ShaderGlobals *globals = &tdata->globals; OSL::pvt::ShadingContext *ctx = ssi->get_context(tdata->thread_info); @@ -218,14 +217,14 @@ void OSLShader::eval_surface(KernelGlobals *kg, ShaderData *sd, float randb, int /* execute shader for this point */ int shader = sd->shader & SHADER_MASK; - if(kg->osl.surface_state[shader]) + if (kg->osl.surface_state[shader]) ctx->execute(OSL::pvt::ShadUseSurface, *(kg->osl.surface_state[shader]), *globals); /* flatten closure tree */ sd->num_closure = 0; sd->randb_closure = randb; - if(globals->Ci) { + if (globals->Ci) { bool no_glossy = (path_flag & PATH_RAY_DIFFUSE) && kernel_data.integrator.no_caustics; flatten_surface_closure_tree(sd, no_glossy, globals->Ci); } @@ -235,27 +234,27 @@ void OSLShader::eval_surface(KernelGlobals *kg, ShaderData *sd, float randb, int static float3 flatten_background_closure_tree(const OSL::ClosureColor *closure) { - /* OSL gives use a closure tree, if we are shading for background there + /* OSL gives us a closure tree, if we are shading for background there * 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; - OSL::ClosurePrimitive *prim = (OSL::ClosurePrimitive*)comp->data(); + if (closure->type == OSL::ClosureColor::COMPONENT) { + OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure; + OSL::ClosurePrimitive *prim = (OSL::ClosurePrimitive *)comp->data(); - if(prim && prim->category() == OSL::ClosurePrimitive::Background) + if (prim && prim->category() == OSL::ClosurePrimitive::Background) return make_float3(1.0f, 1.0f, 1.0f); } - else if(closure->type == OSL::ClosureColor::MUL) { - OSL::ClosureMul *mul = (OSL::ClosureMul*)closure; + else if (closure->type == 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; + else if (closure->type == OSL::ClosureColor::ADD) { + OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure; return flatten_background_closure_tree(add->closureA) + - flatten_background_closure_tree(add->closureB); + flatten_background_closure_tree(add->closureB); } return make_float3(0.0f, 0.0f, 0.0f); @@ -264,7 +263,7 @@ static float3 flatten_background_closure_tree(const OSL::ClosureColor *closure) float3 OSLShader::eval_background(KernelGlobals *kg, ShaderData *sd, int path_flag) { /* gather pointers */ - OSL::pvt::ShadingSystemImpl *ssi = (OSL::pvt::ShadingSystemImpl*)kg->osl.ss; + OSL::pvt::ShadingSystemImpl *ssi = (OSL::pvt::ShadingSystemImpl *)kg->osl.ss; OSLGlobals::ThreadData *tdata = tls_get(OSLGlobals::ThreadData, kg->osl.thread_data); OSL::ShaderGlobals *globals = &tdata->globals; OSL::pvt::ShadingContext *ctx = ssi->get_context(tdata->thread_info); @@ -274,11 +273,11 @@ float3 OSLShader::eval_background(KernelGlobals *kg, ShaderData *sd, int path_fl shaderdata_to_shaderglobals(kg, sd, path_flag, globals); /* execute shader for this point */ - if(kg->osl.background_state) + if (kg->osl.background_state) ctx->execute(OSL::pvt::ShadUseSurface, *kg->osl.background_state, *globals); /* return background color immediately */ - if(globals->Ci) + if (globals->Ci) return flatten_background_closure_tree(globals->Ci); return make_float3(0.0f, 0.0f, 0.0f); @@ -287,23 +286,23 @@ float3 OSLShader::eval_background(KernelGlobals *kg, ShaderData *sd, int path_fl /* Volume */ static void flatten_volume_closure_tree(ShaderData *sd, - const OSL::ClosureColor *closure, float3 weight = make_float3(1.0f, 1.0f, 1.0f)) + const OSL::ClosureColor *closure, float3 weight = make_float3(1.0f, 1.0f, 1.0f)) { - /* OSL gives use a closure tree, we flatten it into arrays per + /* 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; - OSL::ClosurePrimitive *prim = (OSL::ClosurePrimitive*)comp->data(); + if (closure->type == OSL::ClosureColor::COMPONENT) { + OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure; + OSL::ClosurePrimitive *prim = (OSL::ClosurePrimitive *)comp->data(); - if(prim) { + if (prim) { ShaderClosure sc; sc.prim = prim; sc.weight = weight; - switch(prim->category()) { + switch (prim->category()) { case ClosurePrimitive::Volume: { - if(sd->num_closure == MAX_CLOSURE) + if (sd->num_closure == MAX_CLOSURE) return; /* sample weight */ @@ -329,12 +328,12 @@ static void flatten_volume_closure_tree(ShaderData *sd, } } } - else if(closure->type == OSL::ClosureColor::MUL) { - OSL::ClosureMul *mul = (OSL::ClosureMul*)closure; + 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; + 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); } @@ -343,7 +342,7 @@ static void flatten_volume_closure_tree(ShaderData *sd, void OSLShader::eval_volume(KernelGlobals *kg, ShaderData *sd, float randb, int path_flag) { /* gather pointers */ - OSL::pvt::ShadingSystemImpl *ssi = (OSL::pvt::ShadingSystemImpl*)kg->osl.ss; + OSL::pvt::ShadingSystemImpl *ssi = (OSL::pvt::ShadingSystemImpl *)kg->osl.ss; OSLGlobals::ThreadData *tdata = tls_get(OSLGlobals::ThreadData, kg->osl.thread_data); OSL::ShaderGlobals *globals = &tdata->globals; OSL::pvt::ShadingContext *ctx = ssi->get_context(tdata->thread_info); @@ -355,7 +354,7 @@ void OSLShader::eval_volume(KernelGlobals *kg, ShaderData *sd, float randb, int /* execute shader */ int shader = sd->shader & SHADER_MASK; - if(kg->osl.volume_state[shader]) + if (kg->osl.volume_state[shader]) ctx->execute(OSL::pvt::ShadUseSurface, *(kg->osl.volume_state[shader]), *globals); /* retrieve resulting closures */ @@ -363,7 +362,7 @@ void OSLShader::eval_volume(KernelGlobals *kg, ShaderData *sd, float randb, int sd->osl_closure.num_volume = 0; sd->osl_closure.randb = randb; - if(globals->Ci) + if (globals->Ci) flatten_volume_closure_tree(sd, globals->Ci); } @@ -372,7 +371,7 @@ void OSLShader::eval_volume(KernelGlobals *kg, ShaderData *sd, float randb, int void OSLShader::eval_displacement(KernelGlobals *kg, ShaderData *sd) { /* gather pointers */ - OSL::pvt::ShadingSystemImpl *ssi = (OSL::pvt::ShadingSystemImpl*)kg->osl.ss; + OSL::pvt::ShadingSystemImpl *ssi = (OSL::pvt::ShadingSystemImpl *)kg->osl.ss; OSLGlobals::ThreadData *tdata = tls_get(OSLGlobals::ThreadData, kg->osl.thread_data); OSL::ShaderGlobals *globals = &tdata->globals; OSL::pvt::ShadingContext *ctx = ssi->get_context(tdata->thread_info); @@ -384,7 +383,7 @@ void OSLShader::eval_displacement(KernelGlobals *kg, ShaderData *sd) /* execute shader */ int shader = sd->shader & SHADER_MASK; - if(kg->osl.displacement_state[shader]) + if (kg->osl.displacement_state[shader]) ctx->execute(OSL::pvt::ShadUseSurface, *(kg->osl.displacement_state[shader]), *globals); /* get back position */ @@ -393,17 +392,17 @@ void OSLShader::eval_displacement(KernelGlobals *kg, ShaderData *sd) void OSLShader::release(KernelGlobals *kg, const ShaderData *sd) { - OSL::pvt::ShadingSystemImpl *ssi = (OSL::pvt::ShadingSystemImpl*)kg->osl.ss; + OSL::pvt::ShadingSystemImpl *ssi = (OSL::pvt::ShadingSystemImpl *)kg->osl.ss; OSLGlobals::ThreadData *tdata = tls_get(OSLGlobals::ThreadData, kg->osl.thread_data); - ssi->release_context((OSL::pvt::ShadingContext*)sd->osl_ctx, tdata->thread_info); + ssi->release_context((OSL::pvt::ShadingContext *)sd->osl_ctx, tdata->thread_info); } /* BSDF Closure */ int OSLShader::bsdf_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3& eval, float3& omega_in, differential3& domega_in, float& pdf) { - OSL::BSDFClosure *sample_bsdf = (OSL::BSDFClosure*)sc->prim; + OSL::BSDFClosure *sample_bsdf = (OSL::BSDFClosure *)sc->prim; int label = LABEL_NONE; pdf = 0.0f; @@ -412,27 +411,27 @@ int OSLShader::bsdf_sample(const ShaderData *sd, const ShaderClosure *sc, float ustring ulabel; ulabel = sample_bsdf->sample(TO_VEC3(sd->Ng), - TO_VEC3(sd->I), TO_VEC3(sd->dI.dx), TO_VEC3(sd->dI.dy), - randu, randv, - TO_VEC3(omega_in), TO_VEC3(domega_in.dx), TO_VEC3(domega_in.dy), - pdf, TO_COLOR3(eval)); + TO_VEC3(sd->I), TO_VEC3(sd->dI.dx), TO_VEC3(sd->dI.dy), + randu, randv, + TO_VEC3(omega_in), TO_VEC3(domega_in.dx), TO_VEC3(domega_in.dy), + pdf, TO_COLOR3(eval)); /* convert OSL label */ - if(ulabel == OSL::Labels::REFLECT) + if (ulabel == OSL::Labels::REFLECT) label = LABEL_REFLECT; - else if(ulabel == OSL::Labels::TRANSMIT) + else if (ulabel == OSL::Labels::TRANSMIT) label = LABEL_TRANSMIT; else - return LABEL_NONE; /* sampling failed */ + return LABEL_NONE; /* sampling failed */ /* convert scattering to our bitflag label */ ustring uscattering = sample_bsdf->scattering(); - if(uscattering == OSL::Labels::DIFFUSE) + if (uscattering == OSL::Labels::DIFFUSE) label |= LABEL_DIFFUSE; - else if(uscattering == OSL::Labels::GLOSSY) + else if (uscattering == OSL::Labels::GLOSSY) label |= LABEL_GLOSSY; - else if(uscattering == OSL::Labels::SINGULAR) + else if (uscattering == OSL::Labels::SINGULAR) label |= LABEL_SINGULAR; else label |= LABEL_TRANSPARENT; @@ -442,10 +441,10 @@ int OSLShader::bsdf_sample(const ShaderData *sd, const ShaderClosure *sc, float float3 OSLShader::bsdf_eval(const ShaderData *sd, const ShaderClosure *sc, const float3& omega_in, float& pdf) { - OSL::BSDFClosure *bsdf = (OSL::BSDFClosure*)sc->prim; + OSL::BSDFClosure *bsdf = (OSL::BSDFClosure *)sc->prim; OSL::Color3 bsdf_eval; - if(dot(sd->Ng, omega_in) >= 0.0f) + if (dot(sd->Ng, omega_in) >= 0.0f) bsdf_eval = bsdf->eval_reflect(TO_VEC3(sd->I), TO_VEC3(omega_in), pdf); else bsdf_eval = bsdf->eval_transmit(TO_VEC3(sd->I), TO_VEC3(omega_in), pdf); @@ -457,7 +456,7 @@ float3 OSLShader::bsdf_eval(const ShaderData *sd, const ShaderClosure *sc, const float3 OSLShader::emissive_eval(const ShaderData *sd, const ShaderClosure *sc) { - OSL::EmissiveClosure *emissive = (OSL::EmissiveClosure*)sc->prim; + OSL::EmissiveClosure *emissive = (OSL::EmissiveClosure *)sc->prim; OSL::Color3 emissive_eval = emissive->eval(TO_VEC3(sd->Ng), TO_VEC3(sd->I)); eval += TO_FLOAT3(emissive_eval); @@ -468,9 +467,9 @@ float3 OSLShader::emissive_eval(const ShaderData *sd, const ShaderClosure *sc) float3 OSLShader::volume_eval_phase(const ShaderData *sd, const ShaderClosure *sc, const float3 omega_in, const float3 omega_out) { - OSL::VolumeClosure *volume = (OSL::VolumeClosure*)sc->prim; + OSL::VolumeClosure *volume = (OSL::VolumeClosure *)sc->prim; OSL::Color3 volume_eval = volume->eval_phase(TO_VEC3(omega_in), TO_VEC3(omega_out)); - return TO_FLOAT3(volume_eval)*sc->weight; + return TO_FLOAT3(volume_eval) * sc->weight; } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/osl/osl_shader.h b/intern/cycles/kernel/osl/osl_shader.h index 6b1d402989b..815557ed203 100644 --- a/intern/cycles/kernel/osl/osl_shader.h +++ b/intern/cycles/kernel/osl/osl_shader.h @@ -68,15 +68,15 @@ public: /* sample & eval */ static int bsdf_sample(const ShaderData *sd, const ShaderClosure *sc, - float randu, float randv, - float3& eval, float3& omega_in, differential3& domega_in, float& pdf); + float randu, float randv, + float3& eval, float3& omega_in, differential3& domega_in, float& pdf); static float3 bsdf_eval(const ShaderData *sd, const ShaderClosure *sc, - const float3& omega_in, float& pdf); + const float3& omega_in, float& pdf); static float3 emissive_eval(const ShaderData *sd, const ShaderClosure *sc); static float3 volume_eval_phase(const ShaderData *sd, const ShaderClosure *sc, - const float3 omega_in, const float3 omega_out); + const float3 omega_in, const float3 omega_out); /* release */ static void release(KernelGlobals *kg, const ShaderData *sd); diff --git a/intern/cycles/kernel/osl/vol_subsurface.cpp b/intern/cycles/kernel/osl/vol_subsurface.cpp index 0cd3060051b..818a057b6cc 100644 --- a/intern/cycles/kernel/osl/vol_subsurface.cpp +++ b/intern/cycles/kernel/osl/vol_subsurface.cpp @@ -46,88 +46,90 @@ using namespace OSL; class SubsurfaceClosure : public VolumeClosure { public: - float m_g; - float m_eta; - Color3 m_mfp, m_albedo; - static float root_find_Rd(const float Rd0, const float A) { - // quick exit for trivial cases - if (Rd0 <= 0) return 0; - const float A43 = A * 4.0f / 3.0f; - // Find alpha such that f(alpha) = Rd (see eq.15). A simple bisection - // method can be used because this function is monotonicaly increasing. - float lo = 0, hi = 1; - for (int i = 0; i < 20; i++) { // 2^20 divisions should be sufficient - // eval function at midpoint - float alpha = 0.5f * (lo + hi); - float a1 = sqrtf(3 * (1 - alpha)); - float e1 = expf(-a1); - float e2 = expf(-A43 * a1); - float Rd = 0.5f * alpha * (1 + e2) * e1 - Rd0; - if (fabsf(Rd) < 1e-6f) - return alpha; // close enough - else if (Rd > 0) - hi = alpha; // root is on left side - else - lo = alpha; // root is on right side - } - // didn't quite converge, pick result in the middle of remaining interval - return 0.5f * (lo + hi); - } - SubsurfaceClosure() { } - - void setup() - { - ior(m_eta); - - if (m_g >= 0.99f) m_g = 0.99f; - if (m_g <= -0.99f) m_g = -0.99f; - - // eq.10 - float inv_eta = 1 / m_eta; - float Fdr = -1.440f * inv_eta * inv_eta + 0.710 * inv_eta + 0.668f + 0.0636 * m_eta; - float A = (1 + Fdr) / (1 - Fdr); - // compute sigma_s, sigma_a (eq.16) - Color3 alpha_prime = Color3 (root_find_Rd(m_albedo[0], A), - root_find_Rd(m_albedo[1], A), - root_find_Rd(m_albedo[2], A)); - Color3 sigma_t_prime = Color3 (m_mfp.x > 0 ? 1.0f / (m_mfp[0] * sqrtf(3 * (1 - alpha_prime[0]))) : 0.0f, - m_mfp.y > 0 ? 1.0f / (m_mfp[1] * sqrtf(3 * (1 - alpha_prime[1]))) : 0.0f, - m_mfp.z > 0 ? 1.0f / (m_mfp[2] * sqrtf(3 * (1 - alpha_prime[2]))) : 0.0f); - Color3 sigma_s_prime = alpha_prime * sigma_t_prime; - - sigma_s((1.0f / (1 - m_g)) * sigma_s_prime); - sigma_a(sigma_t_prime - sigma_s_prime); - } - - bool mergeable (const ClosurePrimitive *other) const { - const SubsurfaceClosure *comp = (const SubsurfaceClosure *)other; - return m_g == comp->m_g && VolumeClosure::mergeable(other); - } - - size_t memsize () const { return sizeof(*this); } - - const char *name () const { return "subsurface"; } - - void print_on (std::ostream &out) const { - out << name() << " ()"; - } - - virtual Color3 eval_phase(const Vec3 &omega_in, const Vec3 &omega_out) const { - float costheta = omega_in.dot(omega_out); - float ph = 0.25f * float(M_1_PI) * ((1 - m_g * m_g) / powf(1 + m_g * m_g - 2.0f * m_g * costheta, 1.5f)); - return Color3 (ph, ph, ph); - } + float m_g; + float m_eta; + Color3 m_mfp, m_albedo; + static float root_find_Rd(const float Rd0, const float A) { + // quick exit for trivial cases + if (Rd0 <= 0) return 0; + const float A43 = A * 4.0f / 3.0f; + // Find alpha such that f(alpha) = Rd (see eq.15). A simple bisection + // method can be used because this function is monotonicaly increasing. + float lo = 0, hi = 1; + for (int i = 0; i < 20; i++) { // 2^20 divisions should be sufficient + // eval function at midpoint + float alpha = 0.5f * (lo + hi); + float a1 = sqrtf(3 * (1 - alpha)); + float e1 = expf(-a1); + float e2 = expf(-A43 * a1); + float Rd = 0.5f * alpha * (1 + e2) * e1 - Rd0; + if (fabsf(Rd) < 1e-6f) + return alpha; // close enough + else if (Rd > 0) + hi = alpha; // root is on left side + else + lo = alpha; // root is on right side + } + // didn't quite converge, pick result in the middle of remaining interval + return 0.5f * (lo + hi); + } + SubsurfaceClosure() { + } + + void setup() + { + ior(m_eta); + + if (m_g >= 0.99f) m_g = 0.99f; + if (m_g <= -0.99f) m_g = -0.99f; + + // eq.10 + float inv_eta = 1 / m_eta; + float Fdr = -1.440f * inv_eta * inv_eta + 0.710 * inv_eta + 0.668f + 0.0636 * m_eta; + float A = (1 + Fdr) / (1 - Fdr); + // compute sigma_s, sigma_a (eq.16) + Color3 alpha_prime = Color3(root_find_Rd(m_albedo[0], A), + root_find_Rd(m_albedo[1], A), + root_find_Rd(m_albedo[2], A)); + Color3 sigma_t_prime = Color3(m_mfp.x > 0 ? 1.0f / (m_mfp[0] * sqrtf(3 * (1 - alpha_prime[0]))) : 0.0f, + m_mfp.y > 0 ? 1.0f / (m_mfp[1] * sqrtf(3 * (1 - alpha_prime[1]))) : 0.0f, + m_mfp.z > 0 ? 1.0f / (m_mfp[2] * sqrtf(3 * (1 - alpha_prime[2]))) : 0.0f); + Color3 sigma_s_prime = alpha_prime * sigma_t_prime; + + sigma_s((1.0f / (1 - m_g)) * sigma_s_prime); + sigma_a(sigma_t_prime - sigma_s_prime); + } + + bool mergeable(const ClosurePrimitive *other) const { + const SubsurfaceClosure *comp = (const SubsurfaceClosure *)other; + return m_g == comp->m_g && VolumeClosure::mergeable(other); + } + + size_t memsize() const { return sizeof(*this); } + + const char *name() const { return "subsurface"; } + + void print_on(std::ostream &out) const { + out << name() << " ()"; + } + + virtual Color3 eval_phase(const Vec3 &omega_in, const Vec3 &omega_out) const { + float costheta = omega_in.dot(omega_out); + float ph = 0.25f * float(M_1_PI) * ((1 - m_g * m_g) / powf(1 + m_g * m_g - 2.0f * m_g * costheta, 1.5f)); + return Color3(ph, ph, ph); + } }; ClosureParam closure_subsurface_params[] = { - CLOSURE_FLOAT_PARAM (SubsurfaceClosure, m_eta), - CLOSURE_FLOAT_PARAM (SubsurfaceClosure, m_g), - CLOSURE_COLOR_PARAM (SubsurfaceClosure, m_mfp), - CLOSURE_COLOR_PARAM (SubsurfaceClosure, m_albedo), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(SubsurfaceClosure) }; + CLOSURE_FLOAT_PARAM(SubsurfaceClosure, m_eta), + CLOSURE_FLOAT_PARAM(SubsurfaceClosure, m_g), + CLOSURE_COLOR_PARAM(SubsurfaceClosure, m_mfp), + CLOSURE_COLOR_PARAM(SubsurfaceClosure, m_albedo), + CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_FINISH_PARAM(SubsurfaceClosure) +}; CLOSURE_PREPARE(closure_subsurface_prepare, SubsurfaceClosure) diff --git a/intern/cycles/kernel/svm/bsdf.h b/intern/cycles/kernel/svm/bsdf.h index 18c1da73fbd..1a90eab0cd1 100644 --- a/intern/cycles/kernel/svm/bsdf.h +++ b/intern/cycles/kernel/svm/bsdf.h @@ -1,34 +1,34 @@ -/* - * Adapted from Open Shading Language with this license: - * - * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. - * All Rights Reserved. - * - * Modifications Copyright 2011, Blender Foundation. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Sony Pictures Imageworks nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ +/* + * Adapted from Open Shading Language with this license: + * + * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. + * All Rights Reserved. + * + * Modifications Copyright 2011, Blender Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Sony Pictures Imageworks nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ #ifndef __OSL_BSDF_H__ #define __OSL_BSDF_H__ @@ -47,7 +47,7 @@ __device float fresnel_dielectric(float eta, const float3 N, float cos = dot(N, I), neta; float3 Nn; // compute reflection - *R =(2 * cos)* N - I; + *R = (2 * cos)* N - I; #ifdef __RAY_DIFFERENTIALS__ *dRdx = (2 * dot(N, dIdx)) * N - dIdx; *dRdy = (2 * dot(N, dIdy)) * N - dIdy; @@ -65,18 +65,18 @@ __device float fresnel_dielectric(float eta, const float3 N, Nn = -N; *is_inside = true; } - *R =(2 * cos)* Nn - I; + *R = (2 * cos)* Nn - I; float arg = 1 -(neta * neta *(1 -(cos * cos))); if(arg < 0) { - *T= make_float3(0.0f, 0.0f, 0.0f); + *T = make_float3(0.0f, 0.0f, 0.0f); #ifdef __RAY_DIFFERENTIALS__ - *dTdx= make_float3(0.0f, 0.0f, 0.0f); - *dTdy= make_float3(0.0f, 0.0f, 0.0f); + *dTdx = make_float3(0.0f, 0.0f, 0.0f); + *dTdy = make_float3(0.0f, 0.0f, 0.0f); #endif return 1; // total internal reflection } else { float dnp = sqrtf(arg); - float nK =(neta * cos)- dnp; + float nK = (neta * cos)- dnp; *T = -(neta * I)+(nK * Nn); #ifdef __RAY_DIFFERENTIALS__ *dTdx = -(neta * dIdx) + ((neta - neta * neta * cos / dnp) * dot(dIdx, Nn)) * Nn; @@ -85,8 +85,8 @@ __device float fresnel_dielectric(float eta, const float3 N, // compute Fresnel terms float cosTheta1 = cos; // N.R float cosTheta2 = -dot(Nn, *T); - float pPara =(cosTheta1 - eta * cosTheta2)/(cosTheta1 + eta * cosTheta2); - float pPerp =(eta * cosTheta1 - cosTheta2)/(eta * cosTheta1 + cosTheta2); + float pPara = (cosTheta1 - eta * cosTheta2)/(cosTheta1 + eta * cosTheta2); + float pPerp = (eta * cosTheta1 - cosTheta2)/(eta * cosTheta1 + cosTheta2); return 0.5f * (pPara * pPara + pPerp * pPerp); } } @@ -99,8 +99,8 @@ __device float fresnel_dielectric_cos(float cosi, float eta) float g = eta * eta - 1 + c * c; if(g > 0) { g = sqrtf(g); - float A =(g - c)/(g + c); - float B =(c *(g + c)- 1)/(c *(g - c)+ 1); + float A = (g - c)/(g + c); + float B = (c *(g + c)- 1)/(c *(g - c)+ 1); return 0.5f * A * A *(1 + B * B); } return 1.0f; // TIR(no refracted component) @@ -110,10 +110,10 @@ __device float fresnel_conductor(float cosi, float eta, float k) { float tmp_f = eta * eta + k * k; float tmp = tmp_f * cosi * cosi; - float Rparl2 =(tmp -(2.0f * eta * cosi)+ 1)/ - (tmp +(2.0f * eta * cosi)+ 1); - float Rperp2 =(tmp_f -(2.0f * eta * cosi)+ cosi * cosi)/ - (tmp_f +(2.0f * eta * cosi)+ cosi * cosi); + float Rparl2 = (tmp - (2.0f * eta * cosi) + 1)/ + (tmp + (2.0f * eta * cosi) + 1); + float Rperp2 = (tmp_f - (2.0f * eta * cosi) + cosi * cosi)/ + (tmp_f + (2.0f * eta * cosi) + cosi * cosi); return(Rparl2 + Rperp2) * 0.5f; } diff --git a/intern/cycles/kernel/svm/bsdf_ashikhmin_velvet.h b/intern/cycles/kernel/svm/bsdf_ashikhmin_velvet.h index 2e9343647b8..40249dbe9c6 100644 --- a/intern/cycles/kernel/svm/bsdf_ashikhmin_velvet.h +++ b/intern/cycles/kernel/svm/bsdf_ashikhmin_velvet.h @@ -28,7 +28,7 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ + */ #ifndef __BSDF_ASHIKHMIN_VELVET_H__ #define __BSDF_ASHIKHMIN_VELVET_H__ diff --git a/intern/cycles/kernel/svm/bsdf_diffuse.h b/intern/cycles/kernel/svm/bsdf_diffuse.h index e8a002cb84c..45e82a566c0 100644 --- a/intern/cycles/kernel/svm/bsdf_diffuse.h +++ b/intern/cycles/kernel/svm/bsdf_diffuse.h @@ -1,34 +1,34 @@ -/* - * Adapted from Open Shading Language with this license: - * - * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. - * All Rights Reserved. - * - * Modifications Copyright 2011, Blender Foundation. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Sony Pictures Imageworks nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ +/* + * Adapted from Open Shading Language with this license: + * + * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. + * All Rights Reserved. + * + * Modifications Copyright 2011, Blender Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Sony Pictures Imageworks nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ #ifndef __BSDF_DIFFUSE_H__ #define __BSDF_DIFFUSE_H__ diff --git a/intern/cycles/kernel/svm/bsdf_microfacet.h b/intern/cycles/kernel/svm/bsdf_microfacet.h index 8771578a2fd..01e3acb76e8 100644 --- a/intern/cycles/kernel/svm/bsdf_microfacet.h +++ b/intern/cycles/kernel/svm/bsdf_microfacet.h @@ -1,34 +1,34 @@ -/* - * Adapted from Open Shading Language with this license: - * - * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. - * All Rights Reserved. - * - * Modifications Copyright 2011, Blender Foundation. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Sony Pictures Imageworks nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ +/* + * Adapted from Open Shading Language with this license: + * + * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. + * All Rights Reserved. + * + * Modifications Copyright 2011, Blender Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Sony Pictures Imageworks nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ #ifndef __BSDF_MICROFACET_H__ #define __BSDF_MICROFACET_H__ diff --git a/intern/cycles/kernel/svm/bsdf_reflection.h b/intern/cycles/kernel/svm/bsdf_reflection.h index f00b72c4869..09b4e0e48f0 100644 --- a/intern/cycles/kernel/svm/bsdf_reflection.h +++ b/intern/cycles/kernel/svm/bsdf_reflection.h @@ -1,34 +1,34 @@ -/* - * Adapted from Open Shading Language with this license: - * - * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. - * All Rights Reserved. - * - * Modifications Copyright 2011, Blender Foundation. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Sony Pictures Imageworks nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ +/* + * Adapted from Open Shading Language with this license: + * + * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. + * All Rights Reserved. + * + * Modifications Copyright 2011, Blender Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Sony Pictures Imageworks nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ #ifndef __BSDF_REFLECTION_H__ #define __BSDF_REFLECTION_H__ diff --git a/intern/cycles/kernel/svm/bsdf_refraction.h b/intern/cycles/kernel/svm/bsdf_refraction.h index 07ef8633e0d..c9c268999c0 100644 --- a/intern/cycles/kernel/svm/bsdf_refraction.h +++ b/intern/cycles/kernel/svm/bsdf_refraction.h @@ -1,34 +1,34 @@ -/* - * Adapted from Open Shading Language with this license: - * - * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. - * All Rights Reserved. - * - * Modifications Copyright 2011, Blender Foundation. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Sony Pictures Imageworks nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ +/* + * Adapted from Open Shading Language with this license: + * + * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. + * All Rights Reserved. + * + * Modifications Copyright 2011, Blender Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Sony Pictures Imageworks nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ #ifndef __BSDF_REFRACTION_H__ #define __BSDF_REFRACTION_H__ diff --git a/intern/cycles/kernel/svm/bsdf_transparent.h b/intern/cycles/kernel/svm/bsdf_transparent.h index 4425c4bf104..511836cdfa2 100644 --- a/intern/cycles/kernel/svm/bsdf_transparent.h +++ b/intern/cycles/kernel/svm/bsdf_transparent.h @@ -1,34 +1,34 @@ -/* - * Adapted from Open Shading Language with this license: - * - * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. - * All Rights Reserved. - * - * Modifications Copyright 2011, Blender Foundation. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Sony Pictures Imageworks nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ +/* + * Adapted from Open Shading Language with this license: + * + * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. + * All Rights Reserved. + * + * Modifications Copyright 2011, Blender Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Sony Pictures Imageworks nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ #ifndef __BSDF_TRANSPARENT_H__ #define __BSDF_TRANSPARENT_H__ diff --git a/intern/cycles/kernel/svm/bsdf_ward.h b/intern/cycles/kernel/svm/bsdf_ward.h index d46baf099a6..86bca69425d 100644 --- a/intern/cycles/kernel/svm/bsdf_ward.h +++ b/intern/cycles/kernel/svm/bsdf_ward.h @@ -1,34 +1,34 @@ -/* - * Adapted from Open Shading Language with this license: - * - * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. - * All Rights Reserved. - * - * Modifications Copyright 2011, Blender Foundation. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Sony Pictures Imageworks nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ +/* + * Adapted from Open Shading Language with this license: + * + * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. + * All Rights Reserved. + * + * Modifications Copyright 2011, Blender Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Sony Pictures Imageworks nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ #ifndef __BSDF_WARD_H__ #define __BSDF_WARD_H__ diff --git a/intern/cycles/kernel/svm/bsdf_westin.h b/intern/cycles/kernel/svm/bsdf_westin.h index 21e5018c489..6193d81c244 100644 --- a/intern/cycles/kernel/svm/bsdf_westin.h +++ b/intern/cycles/kernel/svm/bsdf_westin.h @@ -1,34 +1,34 @@ -/* - * Adapted from Open Shading Language with this license: - * - * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. - * All Rights Reserved. - * - * Modifications Copyright 2011, Blender Foundation. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Sony Pictures Imageworks nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ +/* + * Adapted from Open Shading Language with this license: + * + * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. + * All Rights Reserved. + * + * Modifications Copyright 2011, Blender Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Sony Pictures Imageworks nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ #ifndef __BSDF_WESTIN_H__ #define __BSDF_WESTIN_H__ diff --git a/intern/cycles/kernel/svm/emissive.h b/intern/cycles/kernel/svm/emissive.h index e3f99e9b729..9a906f82963 100644 --- a/intern/cycles/kernel/svm/emissive.h +++ b/intern/cycles/kernel/svm/emissive.h @@ -1,47 +1,39 @@ -/* - * Adapted from Open Shading Language with this license: - * - * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. - * All Rights Reserved. - * - * Modifications Copyright 2011, Blender Foundation. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Sony Pictures Imageworks nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ +/* + * Adapted from Open Shading Language with this license: + * + * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. + * All Rights Reserved. + * + * Modifications Copyright 2011, Blender Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Sony Pictures Imageworks nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ CCL_NAMESPACE_BEGIN /* EMISSION CLOSURE */ -__device float3 emissive_eval(const float3 Ng, const float3 I) -{ - float cosNO = fabsf(dot(Ng, I)); - float res = (cosNO > 0.0f)? 1.0f: 0.0f; - - return make_float3(res, res, res); -} - /// Return the probability distribution function in the direction I, /// given the parameters and the light's surface normal. This MUST match /// the PDF computed by sample(). @@ -51,6 +43,13 @@ __device float emissive_pdf(const float3 Ng, const float3 I) return (cosNO > 0.0f)? 1.0f: 0.0f; } +__device float3 emissive_eval(const float3 Ng, const float3 I) +{ + float res = emissive_pdf(Ng, I); + + return make_float3(res, res, res); +} + __device float3 svm_emissive_eval(ShaderData *sd, ShaderClosure *sc) { return emissive_eval(sd->Ng, sd->I); diff --git a/intern/cycles/kernel/svm/svm.h b/intern/cycles/kernel/svm/svm.h index 6a05639beb9..8901e5e9628 100644 --- a/intern/cycles/kernel/svm/svm.h +++ b/intern/cycles/kernel/svm/svm.h @@ -269,6 +269,9 @@ __device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ShaderT case NODE_OBJECT_INFO: svm_node_object_info(kg, sd, stack, node.y, node.z); break; + case NODE_PARTICLE_INFO: + svm_node_particle_info(kg, sd, stack, node.y, node.z); + break; #endif case NODE_CONVERT: svm_node_convert(sd, stack, node.y, node.z, node.w); diff --git a/intern/cycles/kernel/svm/svm_closure.h b/intern/cycles/kernel/svm/svm_closure.h index 8409e83d94e..935504026ef 100644 --- a/intern/cycles/kernel/svm/svm_closure.h +++ b/intern/cycles/kernel/svm/svm_closure.h @@ -374,7 +374,7 @@ __device void svm_node_mix_closure(ShaderData *sd, float *stack, { #ifdef __MULTI_CLOSURE__ /* fetch weight from blend input, previous mix closures, - and write to stack to be used by closure nodes later */ + * and write to stack to be used by closure nodes later */ uint weight_offset, in_weight_offset, weight1_offset, weight2_offset; decode_node_uchar4(node.y, &weight_offset, &in_weight_offset, &weight1_offset, &weight2_offset); @@ -387,8 +387,8 @@ __device void svm_node_mix_closure(ShaderData *sd, float *stack, stack_store_float(stack, weight2_offset, in_weight*weight); #else /* pick a closure and make the random number uniform over 0..1 again. - closure 1 starts on the next node, for closure 2 the start is at an - offset from the current node, so we jump */ + * closure 1 starts on the next node, for closure 2 the start is at an + * offset from the current node, so we jump */ uint weight_offset = node.y; uint node_jump = node.z; float weight = stack_load_float(stack, weight_offset); @@ -410,8 +410,8 @@ __device void svm_node_add_closure(ShaderData *sd, float *stack, uint unused, /* nothing to do, handled in compiler */ #else /* pick one of the two closures with probability 0.5. sampling quality - is not going to be great, for that we'd need to evaluate the weights - of the two closures being added */ + * is not going to be great, for that we'd need to evaluate the weights + * of the two closures being added */ float weight = 0.5f; if(*randb < weight) { diff --git a/intern/cycles/kernel/svm/svm_geometry.h b/intern/cycles/kernel/svm/svm_geometry.h index dab19983946..88127b56474 100644 --- a/intern/cycles/kernel/svm/svm_geometry.h +++ b/intern/cycles/kernel/svm/svm_geometry.h @@ -94,5 +94,27 @@ __device void svm_node_object_info(KernelGlobals *kg, ShaderData *sd, float *sta stack_store_float(stack, out_offset, data); } +/* Particle Info */ + +__device void svm_node_particle_info(KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset) +{ + float data; + + switch(type) { + case NODE_INFO_PAR_AGE: { + uint particle_id = object_particle_id(kg, sd->object); + data = particle_age(kg, particle_id); + stack_store_float(stack, out_offset, data); + break; + } + case NODE_INFO_PAR_LIFETIME: { + uint particle_id = object_particle_id(kg, sd->object); + data = particle_lifetime(kg, particle_id); + stack_store_float(stack, out_offset, data); + break; + } + } +} + CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/svm/svm_gradient.h b/intern/cycles/kernel/svm/svm_gradient.h index c7013800d6b..7fad1175c49 100644 --- a/intern/cycles/kernel/svm/svm_gradient.h +++ b/intern/cycles/kernel/svm/svm_gradient.h @@ -20,13 +20,13 @@ CCL_NAMESPACE_BEGIN /* Gradient */ -__device float svm_gradient(float3 p, NodeBlendType type) +__device float svm_gradient(float3 p, NodeGradientType type) { float x, y, z; - x= p.x; - y= p.y; - z= p.z; + x = p.x; + y = p.y; + z = p.z; if(type == NODE_BLEND_LINEAR) { return x; @@ -45,7 +45,7 @@ __device float svm_gradient(float3 p, NodeBlendType type) return (x + y)/2.0f; } else if(type == NODE_BLEND_RADIAL) { - return atan2(y, x)/(2.0f*M_PI_F) + 0.5f; + return atan2f(y, x) / (2.0f * M_PI_F) + 0.5f; } else { float r = fmaxf(1.0f - sqrtf(x*x + y*y + z*z), 0.0f); @@ -67,7 +67,7 @@ __device void svm_node_tex_gradient(ShaderData *sd, float *stack, uint4 node) float3 co = stack_load_float3(stack, co_offset); - float f = svm_gradient(co, (NodeBlendType)type); + float f = svm_gradient(co, (NodeGradientType)type); f = clamp(f, 0.0f, 1.0f); if(stack_valid(fac_offset)) diff --git a/intern/cycles/kernel/svm/svm_image.h b/intern/cycles/kernel/svm/svm_image.h index 388f006c40f..3b2b9204d86 100644 --- a/intern/cycles/kernel/svm/svm_image.h +++ b/intern/cycles/kernel/svm/svm_image.h @@ -92,13 +92,13 @@ __device float4 svm_image_texture(KernelGlobals *kg, int id, float x, float y) float4 r; /* not particularly proud of this massive switch, what are the - alternatives? - - use a single big 1D texture, and do our own lookup/filtering - - group by size and use a 3d texture, performance impact - - group into larger texture with some padding for correct lerp - - also note that cuda has 128 textures limit, we use 100 now, since - we still need some for other storage */ + * alternatives? + * - use a single big 1D texture, and do our own lookup/filtering + * - group by size and use a 3d texture, performance impact + * - group into larger texture with some padding for correct lerp + * + * also note that cuda has 128 textures limit, we use 100 now, since + * we still need some for other storage */ switch(id) { case 0: r = kernel_tex_image_interp(__tex_image_000, x, y); break; diff --git a/intern/cycles/kernel/svm/svm_magic.h b/intern/cycles/kernel/svm/svm_magic.h index 65d37937e1e..fdded813784 100644 --- a/intern/cycles/kernel/svm/svm_magic.h +++ b/intern/cycles/kernel/svm/svm_magic.h @@ -34,39 +34,39 @@ __device_noinline float3 svm_magic(float3 p, int n, float distortion) y *= distortion; if(n > 1) { - x= cosf(x-y-z); + x = cosf(x-y-z); x *= distortion; if(n > 2) { - z= sinf(-x-y-z); + z = sinf(-x-y-z); z *= distortion; if(n > 3) { - x= -cosf(-x+y-z); + x = -cosf(-x+y-z); x *= distortion; if(n > 4) { - y= -sinf(-x+y+z); + y = -sinf(-x+y+z); y *= distortion; if(n > 5) { - y= -cosf(-x+y+z); + y = -cosf(-x+y+z); y *= distortion; if(n > 6) { - x= cosf(x+y+z); + x = cosf(x+y+z); x *= distortion; if(n > 7) { - z= sinf(x+y-z); + z = sinf(x+y-z); z *= distortion; if(n > 8) { - x= -cosf(-x-y+z); + x = -cosf(-x-y+z); x *= distortion; if(n > 9) { - y= -sinf(x-y+z); + y = -sinf(x-y+z); y *= distortion; } } diff --git a/intern/cycles/kernel/svm/svm_mix.h b/intern/cycles/kernel/svm/svm_mix.h index e2274a2e691..6b455e713c2 100644 --- a/intern/cycles/kernel/svm/svm_mix.h +++ b/intern/cycles/kernel/svm/svm_mix.h @@ -248,8 +248,8 @@ __device float3 svm_mix_soft(float t, float3 col1, float3 col2) { float tm = 1.0f - t; - float3 one= make_float3(1.0f, 1.0f, 1.0f); - float3 scr= one - (one - col2)*(one - col1); + float3 one = make_float3(1.0f, 1.0f, 1.0f); + float3 scr = one - (one - col2)*(one - col1); return tm*col1 + t*((one - col1)*col2*col1 + col1*scr); } @@ -259,19 +259,19 @@ __device float3 svm_mix_linear(float t, float3 col1, float3 col2) float3 outcol = col1; if(col2.x > 0.5f) - outcol.x= col1.x + t*(2.0f*(col2.x - 0.5f)); + outcol.x = col1.x + t*(2.0f*(col2.x - 0.5f)); else - outcol.x= col1.x + t*(2.0f*(col2.x) - 1.0f); + outcol.x = col1.x + t*(2.0f*(col2.x) - 1.0f); if(col2.y > 0.5f) - outcol.y= col1.y + t*(2.0f*(col2.y - 0.5f)); + outcol.y = col1.y + t*(2.0f*(col2.y - 0.5f)); else - outcol.y= col1.y + t*(2.0f*(col2.y) - 1.0f); + outcol.y = col1.y + t*(2.0f*(col2.y) - 1.0f); if(col2.z > 0.5f) - outcol.z= col1.z + t*(2.0f*(col2.z - 0.5f)); + outcol.z = col1.z + t*(2.0f*(col2.z - 0.5f)); else - outcol.z= col1.z + t*(2.0f*(col2.z) - 1.0f); + outcol.z = col1.z + t*(2.0f*(col2.z) - 1.0f); return outcol; } diff --git a/intern/cycles/kernel/svm/svm_musgrave.h b/intern/cycles/kernel/svm/svm_musgrave.h index 9444dc20e6e..425909e59f1 100644 --- a/intern/cycles/kernel/svm/svm_musgrave.h +++ b/intern/cycles/kernel/svm/svm_musgrave.h @@ -41,7 +41,7 @@ __device_noinline float noise_musgrave_fBm(float3 p, NodeNoiseBasis basis, float p *= lacunarity; } - rmd = octaves - floor(octaves); + rmd = octaves - floorf(octaves); if(rmd != 0.0f) value += rmd * snoise(p) * pwr; @@ -69,7 +69,7 @@ __device_noinline float noise_musgrave_multi_fractal(float3 p, NodeNoiseBasis ba p *= lacunarity; } - rmd = octaves - floor(octaves); + rmd = octaves - floorf(octaves); if(rmd != 0.0f) value *= (rmd * pwr * snoise(p) + 1.0f); /* correct? */ @@ -102,7 +102,7 @@ __device_noinline float noise_musgrave_hetero_terrain(float3 p, NodeNoiseBasis b p *= lacunarity; } - rmd = octaves - floor(octaves); + rmd = octaves - floorf(octaves); if(rmd != 0.0f) { increment = (snoise(p) + offset) * pwr * value; value += rmd * increment; @@ -141,7 +141,7 @@ __device_noinline float noise_musgrave_hybrid_multi_fractal(float3 p, NodeNoiseB p *= lacunarity; } - rmd = octaves - floor(octaves); + rmd = octaves - floorf(octaves); if(rmd != 0.0f) result += rmd * ((snoise(p) + offset) * pwr); diff --git a/intern/cycles/kernel/svm/svm_noise.h b/intern/cycles/kernel/svm/svm_noise.h index 1d3ace061ab..dfaf43acbd4 100644 --- a/intern/cycles/kernel/svm/svm_noise.h +++ b/intern/cycles/kernel/svm/svm_noise.h @@ -28,7 +28,7 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ + */ CCL_NAMESPACE_BEGIN @@ -84,9 +84,9 @@ __device uint phash(int kx, int ky, int kz, int3 p) __device float floorfrac(float x, int* i) { - float f = floorf(x); - *i = (int)f; - return x - f; + float f = floorf(x); + *i = (int)f; + return x - f; } __device float fade(float t) @@ -96,7 +96,7 @@ __device float fade(float t) __device float nerp(float t, float a, float b) { - return (1.0f - t) * a + t * b; + return (1.0f - t) * a + t * b; } __device float grad(int hash, float x, float y, float z) diff --git a/intern/cycles/kernel/svm/svm_texture.h b/intern/cycles/kernel/svm/svm_texture.h index 448132bff46..6c22d98e0df 100644 --- a/intern/cycles/kernel/svm/svm_texture.h +++ b/intern/cycles/kernel/svm/svm_texture.h @@ -152,7 +152,7 @@ __device float voronoi_CrS(float3 p) { return 2.0f*voronoi_Cr(p) - 1.0f; } __device float noise_basis(float3 p, NodeNoiseBasis basis) { /* Only Perlin enabled for now, others break CUDA compile by making kernel - too big, with compile using > 4GB, due to everything being inlined. */ + * too big, with compile using > 4GB, due to everything being inlined. */ #if 0 if(basis == NODE_NOISE_PERLIN) @@ -188,10 +188,10 @@ __device float noise_basis_hard(float3 p, NodeNoiseBasis basis, int hard) /* Waves */ -__device float noise_wave(NodeWaveType wave, float a) +__device float noise_wave(NodeWaveBasis wave, float a) { if(wave == NODE_WAVE_SINE) { - return 0.5f + 0.5f*sin(a); + return 0.5f + 0.5f * sinf(a); } else if(wave == NODE_WAVE_SAW) { float b = 2.0f*M_PI_F; @@ -221,7 +221,7 @@ __device_noinline float noise_turbulence(float3 p, NodeNoiseBasis basis, float o int i, n; octaves = clamp(octaves, 0.0f, 16.0f); - n= (int)octaves; + n = (int)octaves; for(i = 0; i <= n; i++) { float t = noise_basis(fscale*p, basis); @@ -234,7 +234,7 @@ __device_noinline float noise_turbulence(float3 p, NodeNoiseBasis basis, float o fscale *= 2.0f; } - float rmd = octaves - floor(octaves); + float rmd = octaves - floorf(octaves); if(rmd != 0.0f) { float t = noise_basis(fscale*p, basis); diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h index 97849736ef6..c1eeeb55268 100644 --- a/intern/cycles/kernel/svm/svm_types.h +++ b/intern/cycles/kernel/svm/svm_types.h @@ -30,70 +30,66 @@ CCL_NAMESPACE_BEGIN /* Nodes */ -/* note that we do not simply use 0, 1, 2, .. as values for these. this works - * around an obscure CUDA bug that happens when compiling for fermi. why it - * happens i have no idea, but consecutive values are problematic, maybe it - * generates an incorrect jump table. */ - typedef enum NodeType { NODE_END = 0, - NODE_CLOSURE_BSDF = 100, - NODE_CLOSURE_EMISSION = 200, - NODE_CLOSURE_BACKGROUND = 300, - NODE_CLOSURE_SET_WEIGHT = 400, - NODE_CLOSURE_WEIGHT = 500, - NODE_MIX_CLOSURE = 600, - NODE_JUMP = 700, - NODE_TEX_IMAGE = 1000, - NODE_TEX_SKY = 1100, - NODE_GEOMETRY = 1200, - NODE_LIGHT_PATH = 1300, - NODE_VALUE_F = 1400, - NODE_VALUE_V = 1500, - NODE_MIX = 1600, - NODE_ATTR = 1700, - NODE_CONVERT = 1900, - NODE_FRESNEL = 2000, - NODE_EMISSION_WEIGHT = 2100, - NODE_TEX_GRADIENT = 2200, - NODE_TEX_VORONOI = 2300, - NODE_TEX_MUSGRAVE = 2400, - NODE_TEX_WAVE = 2500, - NODE_TEX_MAGIC = 2600, - NODE_TEX_NOISE = 3000, - NODE_SHADER_JUMP = 3100, - NODE_SET_DISPLACEMENT = 3200, - NODE_GEOMETRY_BUMP_DX = 3300, - NODE_GEOMETRY_BUMP_DY = 3400, - NODE_SET_BUMP = 3500, - NODE_MATH = 3600, - NODE_VECTOR_MATH = 3700, - NODE_MAPPING = 3800, - NODE_TEX_COORD = 3900, - NODE_TEX_COORD_BUMP_DX = 4000, - NODE_TEX_COORD_BUMP_DY = 4100, - NODE_ADD_CLOSURE = 4200, - NODE_EMISSION_SET_WEIGHT_TOTAL = 4300, - NODE_ATTR_BUMP_DX = 4400, - NODE_ATTR_BUMP_DY = 4500, - NODE_TEX_ENVIRONMENT = 4600, - NODE_CLOSURE_HOLDOUT = 4700, - NODE_LAYER_WEIGHT = 4800, - NODE_CLOSURE_VOLUME = 4900, - NODE_SEPARATE_RGB = 5000, - NODE_COMBINE_RGB = 5100, - NODE_HSV = 5200, - NODE_CAMERA = 5300, - NODE_INVERT = 5400, - NODE_NORMAL = 5500, - NODE_GAMMA = 5600, - NODE_TEX_CHECKER = 5700, - NODE_BRIGHTCONTRAST = 5800, - NODE_RGB_RAMP = 5900, - NODE_RGB_CURVES = 6000, - NODE_MIN_MAX = 6100, - NODE_LIGHT_FALLOFF = 6200, - NODE_OBJECT_INFO = 6300 + NODE_CLOSURE_BSDF, + NODE_CLOSURE_EMISSION, + NODE_CLOSURE_BACKGROUND, + NODE_CLOSURE_SET_WEIGHT, + NODE_CLOSURE_WEIGHT, + NODE_MIX_CLOSURE, + NODE_JUMP, + NODE_TEX_IMAGE, + NODE_TEX_SKY, + NODE_GEOMETRY, + NODE_LIGHT_PATH, + NODE_VALUE_F, + NODE_VALUE_V, + NODE_MIX, + NODE_ATTR, + NODE_CONVERT, + NODE_FRESNEL, + NODE_EMISSION_WEIGHT, + NODE_TEX_GRADIENT, + NODE_TEX_VORONOI, + NODE_TEX_MUSGRAVE, + NODE_TEX_WAVE, + NODE_TEX_MAGIC, + NODE_TEX_NOISE, + NODE_SHADER_JUMP, + NODE_SET_DISPLACEMENT, + NODE_GEOMETRY_BUMP_DX, + NODE_GEOMETRY_BUMP_DY, + NODE_SET_BUMP, + NODE_MATH, + NODE_VECTOR_MATH, + NODE_MAPPING, + NODE_TEX_COORD, + NODE_TEX_COORD_BUMP_DX, + NODE_TEX_COORD_BUMP_DY, + NODE_ADD_CLOSURE, + NODE_EMISSION_SET_WEIGHT_TOTAL, + NODE_ATTR_BUMP_DX, + NODE_ATTR_BUMP_DY, + NODE_TEX_ENVIRONMENT, + NODE_CLOSURE_HOLDOUT, + NODE_LAYER_WEIGHT, + NODE_CLOSURE_VOLUME, + NODE_SEPARATE_RGB, + NODE_COMBINE_RGB, + NODE_HSV, + NODE_CAMERA, + NODE_INVERT, + NODE_NORMAL, + NODE_GAMMA, + NODE_TEX_CHECKER, + NODE_BRIGHTCONTRAST, + NODE_RGB_RAMP, + NODE_RGB_CURVES, + NODE_MIN_MAX, + NODE_LIGHT_FALLOFF, + NODE_OBJECT_INFO, + NODE_PARTICLE_INFO } NodeType; typedef enum NodeAttributeType { @@ -117,6 +113,11 @@ typedef enum NodeObjectInfo { NODE_INFO_OB_RANDOM } NodeObjectInfo; +typedef enum NodeParticleInfo { + NODE_INFO_PAR_AGE, + NODE_INFO_PAR_LIFETIME +} NodeParticleInfo; + typedef enum NodeLightPath { NODE_LP_camera = 0, NODE_LP_shadow, @@ -220,11 +221,11 @@ typedef enum NodeNoiseBasis { NODE_NOISE_CELL_NOISE } NodeNoiseBasis; -typedef enum NodeWaveType { +typedef enum NodeWaveBasis { NODE_WAVE_SINE, NODE_WAVE_SAW, NODE_WAVE_TRI -} NodeWaveType; +} NodeWaveBasis; typedef enum NodeMusgraveType { NODE_MUSGRAVE_MULTIFRACTAL, @@ -234,12 +235,12 @@ typedef enum NodeMusgraveType { NODE_MUSGRAVE_HETERO_TERRAIN } NodeMusgraveType; -typedef enum NodeWoodType { +typedef enum NodeWaveType { NODE_WAVE_BANDS, NODE_WAVE_RINGS -} NodeWoodType; +} NodeWaveType; -typedef enum NodeBlendType { +typedef enum NodeGradientType { NODE_BLEND_LINEAR, NODE_BLEND_QUADRATIC, NODE_BLEND_EASING, @@ -247,24 +248,7 @@ typedef enum NodeBlendType { NODE_BLEND_RADIAL, NODE_BLEND_QUADRATIC_SPHERE, NODE_BLEND_SPHERICAL -} NodeBlendType; - -typedef enum NodeBlendAxis { - NODE_BLEND_HORIZONTAL, - NODE_BLEND_VERTICAL -} NodeBlendAxis; - -typedef enum NodeMarbleType { - NODE_MARBLE_SOFT, - NODE_MARBLE_SHARP, - NODE_MARBLE_SHARPER -} NodeMarbleType; - -typedef enum NodeStucciType { - NODE_STUCCI_PLASTIC, - NODE_STUCCI_WALL_IN, - NODE_STUCCI_WALL_OUT -} NodeStucciType; +} NodeGradientType; typedef enum NodeVoronoiColoring { NODE_VORONOI_INTENSITY, diff --git a/intern/cycles/kernel/svm/svm_voronoi.h b/intern/cycles/kernel/svm/svm_voronoi.h index f5ee7851a51..7e7bd970320 100644 --- a/intern/cycles/kernel/svm/svm_voronoi.h +++ b/intern/cycles/kernel/svm/svm_voronoi.h @@ -38,7 +38,7 @@ __device_noinline float4 svm_voronoi(NodeVoronoiColoring coloring, float scale, } else { color = cellnoise_color(pa[0]); - fac= average(color); + fac = average(color); } return make_float4(color.x, color.y, color.z, fac); diff --git a/intern/cycles/kernel/svm/svm_wave.h b/intern/cycles/kernel/svm/svm_wave.h index 39edd7d9fff..d2d808e4063 100644 --- a/intern/cycles/kernel/svm/svm_wave.h +++ b/intern/cycles/kernel/svm/svm_wave.h @@ -18,18 +18,18 @@ CCL_NAMESPACE_BEGIN -/* Marble */ +/* Wave */ -__device_noinline float svm_wave(NodeWoodType type, float3 p, float scale, float detail, float distortion, float dscale) +__device_noinline float svm_wave(NodeWaveType type, float3 p, float scale, float detail, float distortion, float dscale) { float w, n; p *= scale; if(type == NODE_WAVE_BANDS) - n= (p.x + p.y + p.z)*10.0f; + n = (p.x + p.y + p.z) * 10.0f; else /* if(type == NODE_WAVE_RINGS) */ - n= len(p)*20.0f; + n = len(p) * 20.0f; if(distortion != 0.0f) n += distortion * noise_turbulence(p*dscale, NODE_NOISE_PERLIN, detail, 0); @@ -55,7 +55,7 @@ __device void svm_node_tex_wave(KernelGlobals *kg, ShaderData *sd, float *stack, float distortion = stack_load_float_default(stack, distortion_offset, node2.z); float dscale = stack_load_float_default(stack, dscale_offset, node2.w); - float f = svm_wave((NodeWoodType)type, co, scale, detail, distortion, dscale); + float f = svm_wave((NodeWaveType)type, co, scale, detail, distortion, dscale); if(stack_valid(fac_offset)) stack_store_float(stack, fac_offset, f); if(stack_valid(color_offset)) stack_store_float3(stack, color_offset, make_float3(f, f, f)); diff --git a/intern/cycles/kernel/svm/volume.h b/intern/cycles/kernel/svm/volume.h index 86cb2dcc24e..10e9c5de352 100644 --- a/intern/cycles/kernel/svm/volume.h +++ b/intern/cycles/kernel/svm/volume.h @@ -19,7 +19,7 @@ CCL_NAMESPACE_BEGIN /* note: the interfaces here are just as an example, need to figure - out the right functions and parameters to use */ + * out the right functions and parameters to use */ /* ISOTROPIC VOLUME CLOSURE */ diff --git a/intern/cycles/render/attribute.cpp b/intern/cycles/render/attribute.cpp index c1a089cc872..5c7966d6d96 100644 --- a/intern/cycles/render/attribute.cpp +++ b/intern/cycles/render/attribute.cpp @@ -74,10 +74,13 @@ bool Attribute::same_storage(TypeDesc a, TypeDesc b) if(a == TypeDesc::TypeColor || a == TypeDesc::TypePoint || a == TypeDesc::TypeVector || a == TypeDesc::TypeNormal) + { if(b == TypeDesc::TypeColor || b == TypeDesc::TypePoint || b == TypeDesc::TypeVector || b == TypeDesc::TypeNormal) + { return true; - + } + } return false; } @@ -286,10 +289,13 @@ bool AttributeRequestSet::modified(const AttributeRequestSet& other) for(size_t j = 0; j < requests.size() && !found; j++) if(requests[i].name == other.requests[j].name && requests[i].std == other.requests[j].std) + { found = true; + } - if(!found) + if(!found) { return true; + } } return false; diff --git a/intern/cycles/render/buffers.cpp b/intern/cycles/render/buffers.cpp index a80851b945a..a79a3591e0f 100644 --- a/intern/cycles/render/buffers.cpp +++ b/intern/cycles/render/buffers.cpp @@ -117,8 +117,8 @@ void RenderBuffers::reset(Device *device, BufferParams& params_) uint *init_state = rng_state.resize(params.width, params.height); int x, y, width = params.width, height = params.height; - for(x=0; x<width; x++) - for(y=0; y<height; y++) + for(x = 0; x < width; x++) + for(y = 0; y < height; y++) init_state[x + y*width] = hash_int_2d(params.full_x+x, params.full_y+y); device->mem_alloc(rng_state, MEM_READ_WRITE); @@ -311,8 +311,14 @@ void DisplayBuffer::draw_set(int width, int height) void DisplayBuffer::draw(Device *device) { - if(draw_width != 0 && draw_height != 0) + if(draw_width != 0 && draw_height != 0) { + glPushMatrix(); + glTranslatef(params.full_x, params.full_y, 0.0f); + device->draw_pixels(rgba, 0, draw_width, draw_height, 0, params.width, params.height, transparent); + + glPopMatrix(); + } } bool DisplayBuffer::draw_ready() diff --git a/intern/cycles/render/buffers.h b/intern/cycles/render/buffers.h index 77ad4a5a4b0..78712ed89ef 100644 --- a/intern/cycles/render/buffers.h +++ b/intern/cycles/render/buffers.h @@ -35,7 +35,7 @@ class Device; struct float4; /* Buffer Parameters - Size of render buffer and how it fits in the full image (border render). */ + * Size of render buffer and how it fits in the full image (border render). */ class BufferParams { public: @@ -98,8 +98,8 @@ public: /* buffer parameters */ BufferParams params; /* dimensions for how much of the buffer is actually ready for display. - with progressive render we can be using only a subset of the buffer. - if these are zero, it means nothing can be drawn yet */ + * with progressive render we can be using only a subset of the buffer. + * if these are zero, it means nothing can be drawn yet */ int draw_width, draw_height; /* draw alpha channel? */ bool transparent; diff --git a/intern/cycles/render/camera.cpp b/intern/cycles/render/camera.cpp index 3ecffab7cbc..55a0f23f8d0 100644 --- a/intern/cycles/render/camera.cpp +++ b/intern/cycles/render/camera.cpp @@ -58,6 +58,11 @@ Camera::Camera() bottom = -1.0f; top = 1.0f; + border_left = 0.0f; + border_right = 1.0f; + border_bottom = 0.0f; + border_top = 1.0f; + screentoworld = transform_identity(); rastertoworld = transform_identity(); ndctoworld = transform_identity(); @@ -194,7 +199,7 @@ void Camera::device_update(Device *device, DeviceScene *dscene, Scene *scene) kcam->bladesrotation = bladesrotation; /* motion blur */ - kcam->shuttertime= (need_motion == Scene::MOTION_BLUR)? shuttertime: 0.0f; + kcam->shuttertime = (need_motion == Scene::MOTION_BLUR) ? shuttertime: 0.0f; /* type */ kcam->type = type; @@ -248,6 +253,10 @@ bool Camera::modified(const Camera& cam) (right == cam.right) && (bottom == cam.bottom) && (top == cam.top) && + (border_left == cam.border_left) && + (border_right == cam.border_right) && + (border_bottom == cam.border_bottom) && + (border_top == cam.border_top) && (matrix == cam.matrix) && (motion == cam.motion) && (use_motion == cam.use_motion) && diff --git a/intern/cycles/render/camera.h b/intern/cycles/render/camera.h index 7a09b5981e4..d2a3cce1817 100644 --- a/intern/cycles/render/camera.h +++ b/intern/cycles/render/camera.h @@ -67,6 +67,9 @@ public: int width, height; float left, right, bottom, top; + /* border */ + float border_left, border_right, border_bottom, border_top; + /* transformation */ Transform matrix; @@ -75,7 +78,7 @@ public: bool use_motion; /* computed camera parameters */ - Transform screentoworld; + Transform screentoworld; Transform rastertoworld; Transform ndctoworld; Transform rastertocamera; diff --git a/intern/cycles/render/film.cpp b/intern/cycles/render/film.cpp index 878aa87510e..035821fadde 100644 --- a/intern/cycles/render/film.cpp +++ b/intern/cycles/render/film.cpp @@ -142,7 +142,7 @@ void Pass::add(PassType type, vector<Pass>& passes) passes.push_back(pass); /* order from by components, to ensure alignment so passes with size 4 - come first and then passes with size 1 */ + * come first and then passes with size 1 */ sort(passes.begin(), passes.end(), compare_pass_order); if(pass.divide_type != PASS_NONE) diff --git a/intern/cycles/render/filter.cpp b/intern/cycles/render/filter.cpp index 9bcf57b5a27..0bd4fb4d579 100644 --- a/intern/cycles/render/filter.cpp +++ b/intern/cycles/render/filter.cpp @@ -73,17 +73,17 @@ static vector<float> filter_table(FilterType type, float width) /* compute cumulative distribution function */ filter_table_cdf[0] = 0.0f; - for(i=0; i<filter_table_size; i++) { + for(i = 0; i < filter_table_size; i++) { float x = i*width*0.5f/(filter_table_size-1); float y = filter_func(x, width); filter_table_cdf[i+1] += filter_table_cdf[i] + fabsf(y); } - for(i=0; i<=filter_table_size; i++) + for(i = 0; i <= filter_table_size; i++) filter_table_cdf[i] /= filter_table_cdf[filter_table_size]; /* create importance sampling table */ - for(i=0; i<=half_size; i++) { + for(i = 0; i <= half_size; i++) { float x = i/(float)half_size; int index = upper_bound(filter_table_cdf.begin(), filter_table_cdf.end(), x) - filter_table_cdf.begin(); float t; diff --git a/intern/cycles/render/graph.cpp b/intern/cycles/render/graph.cpp index a0e7af66100..34c8879aa1f 100644 --- a/intern/cycles/render/graph.cpp +++ b/intern/cycles/render/graph.cpp @@ -375,8 +375,8 @@ void ShaderGraph::break_cycles(ShaderNode *node, vector<bool>& visited, vector<b void ShaderGraph::clean() { /* we do two things here: find cycles and break them, and remove unused - nodes that don't feed into the output. how cycles are broken is - undefined, they are invalid input, the important thing is to not crash */ + * nodes that don't feed into the output. how cycles are broken is + * undefined, they are invalid input, the important thing is to not crash */ vector<bool> removed(nodes.size(), false); vector<bool> visited(nodes.size(), false); @@ -495,7 +495,7 @@ void ShaderGraph::bump_from_displacement() copy_nodes(nodes_displace, nodes_dy); /* mark nodes to indicate they are use for bump computation, so - that any texture coordinates are shifted by dx/dy when sampling */ + * that any texture coordinates are shifted by dx/dy when sampling */ foreach(NodePair& pair, nodes_center) pair.second->bump = SHADER_BUMP_CENTER; foreach(NodePair& pair, nodes_dx) @@ -516,15 +516,15 @@ void ShaderGraph::bump_from_displacement() connect(out_dy, bump->input("SampleY")); /* connect bump output to normal input nodes that aren't set yet. actually - this will only set the normal input to the geometry node that we created - and connected to all other normal inputs already. */ + * this will only set the normal input to the geometry node that we created + * and connected to all other normal inputs already. */ foreach(ShaderNode *node, nodes) foreach(ShaderInput *input, node->inputs) if(!input->link && input->default_value == ShaderInput::NORMAL) connect(bump->output("Normal"), input); /* finally, add the copied nodes to the graph. we can't do this earlier - because we would create dependency cycles in the above loop */ + * because we would create dependency cycles in the above loop */ foreach(NodePair& pair, nodes_center) add(pair.second); foreach(NodePair& pair, nodes_dx) diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp index 6417d0e2103..dc20dbdbea2 100644 --- a/intern/cycles/render/image.cpp +++ b/intern/cycles/render/image.cpp @@ -66,7 +66,7 @@ static bool is_float_image(const string& filename) if(in->open(filename, spec)) { /* check the main format, and channel formats; - if any take up more than one byte, we'll need a float texture slot */ + * if any take up more than one byte, we'll need a float texture slot */ if(spec.format.basesize() > 1) is_float = true; @@ -171,8 +171,8 @@ void ImageManager::remove_image(const string& filename) assert(images[slot]->users >= 0); /* don't remove immediately, rather do it all together later on. one of - the reasons for this is that on shader changes we add and remove nodes - that use them, but we do not want to reload the image all the time. */ + * the reasons for this is that on shader changes we add and remove nodes + * that use them, but we do not want to reload the image all the time. */ if(images[slot]->users == 0) need_update = true; @@ -189,8 +189,8 @@ void ImageManager::remove_image(const string& filename) assert(float_images[slot]->users >= 0); /* don't remove immediately, rather do it all together later on. one of - the reasons for this is that on shader changes we add and remove nodes - that use them, but we do not want to reload the image all the time. */ + * the reasons for this is that on shader changes we add and remove nodes + * that use them, but we do not want to reload the image all the time. */ if(float_images[slot]->users == 0) need_update = true; @@ -483,7 +483,7 @@ void ImageManager::device_update(Device *device, DeviceScene *dscene, Progress& void ImageManager::device_pack_images(Device *device, DeviceScene *dscene, Progress& progess) { /* for OpenCL, we pack all image textures inside a single big texture, and - will do our own interpolation in the kernel */ + * will do our own interpolation in the kernel */ size_t size = 0; for(size_t slot = 0; slot < images.size(); slot++) { diff --git a/intern/cycles/render/light.cpp b/intern/cycles/render/light.cpp index 267cb8e6d3a..e918de990c2 100644 --- a/intern/cycles/render/light.cpp +++ b/intern/cycles/render/light.cpp @@ -109,6 +109,9 @@ Light::Light() map_resolution = 512; + spot_angle = M_PI_F/4.0f; + spot_smooth = 0.0f; + cast_shadow = true; shader = 0; } @@ -359,7 +362,7 @@ void LightManager::device_update_background(Device *device, DeviceScene *dscene, float cdf_total = cond_cdf[i * cdf_count + res - 1].y + cond_cdf[i * cdf_count + res - 1].x / res; /* stuff the total into the brightness value for the last entry, because - we are going to normalize the CDFs to 0.0 to 1.0 afterwards */ + * we are going to normalize the CDFs to 0.0 to 1.0 afterwards */ cond_cdf[i * cdf_count + res].x = cdf_total; if(cdf_total > 0.0f) @@ -451,6 +454,17 @@ void LightManager::device_update_points(Device *device, DeviceScene *dscene, Sce light_data[i*LIGHT_SIZE + 2] = make_float4(0.0f, axisv.x, axisv.y, axisv.z); light_data[i*LIGHT_SIZE + 3] = make_float4(0.0f, dir.x, dir.y, dir.z); } + else if(light->type == LIGHT_SPOT) { + shader_id &= ~SHADER_AREA_LIGHT; + + float spot_angle = cosf(light->spot_angle*0.5f); + float spot_smooth = (1.0f - spot_angle)*light->spot_smooth; + + light_data[i*LIGHT_SIZE + 0] = make_float4(__int_as_float(light->type), co.x, co.y, co.z); + light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), light->size, dir.x, dir.y); + light_data[i*LIGHT_SIZE + 2] = make_float4(dir.z, spot_angle, spot_smooth, 0.0f); + light_data[i*LIGHT_SIZE + 3] = make_float4(0.0f, 0.0f, 0.0f, 0.0f); + } } device->tex_alloc("__light_data", dscene->light_data); diff --git a/intern/cycles/render/light.h b/intern/cycles/render/light.h index 0ed143f5ad1..fb8684fa59b 100644 --- a/intern/cycles/render/light.h +++ b/intern/cycles/render/light.h @@ -48,6 +48,9 @@ public: int map_resolution; + float spot_angle; + float spot_smooth; + bool cast_shadow; int shader; diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp index cabbd5760c2..8f5f2647ebf 100644 --- a/intern/cycles/render/mesh.cpp +++ b/intern/cycles/render/mesh.cpp @@ -474,7 +474,7 @@ void MeshManager::device_update_attributes(Device *device, DeviceScene *dscene, AttributeRequestSet& attributes = mesh_attributes[i]; /* todo: we now store std and name attributes from requests even if - they actually refer to the same mesh attributes, optimize */ + * they actually refer to the same mesh attributes, optimize */ foreach(AttributeRequest& req, attributes.requests) { Attribute *mattr = mesh->attributes.find(req); @@ -493,7 +493,7 @@ void MeshManager::device_update_attributes(Device *device, DeviceScene *dscene, } /* we abuse AttributeRequest to pass on info like element and - offset, it doesn't really make sense but is convenient */ + * offset, it doesn't really make sense but is convenient */ /* store element and type */ if(mattr->element == Attribute::VERTEX) @@ -528,7 +528,7 @@ void MeshManager::device_update_attributes(Device *device, DeviceScene *dscene, } /* mesh vertex/triangle index is global, not per object, so we sneak - a correction for that in here */ + * a correction for that in here */ if(req.element == ATTR_ELEMENT_VERTEX) req.offset -= mesh->vert_offset; else if(mattr->element == Attribute::FACE) diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index 16c6b07261a..0f64d858de0 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -332,7 +332,7 @@ static void sky_texture_precompute(KernelSunSky *ksunsky, float3 dir, float turb float T2 = T * T; float chi = (4.0f / 9.0f - T / 120.0f) * (M_PI_F - 2.0f * theta); - ksunsky->zenith_Y = (4.0453f * T - 4.9710f) * tan(chi) - 0.2155f * T + 2.4192f; + ksunsky->zenith_Y = (4.0453f * T - 4.9710f) * tanf(chi) - 0.2155f * T + 2.4192f; ksunsky->zenith_Y *= 0.06f; ksunsky->zenith_x = @@ -695,7 +695,7 @@ static ShaderEnum wave_type_init() ShaderEnum WaveTextureNode::type_enum = wave_type_init(); WaveTextureNode::WaveTextureNode() -: TextureNode("marble_texture") +: TextureNode("wave_texture") { type = ustring("Bands"); @@ -1789,6 +1789,47 @@ void ObjectInfoNode::compile(OSLCompiler& compiler) compiler.add(this, "node_object_info"); } +/* Particle Info */ + +ParticleInfoNode::ParticleInfoNode() +: ShaderNode("particle_info") +{ + add_output("Age", SHADER_SOCKET_FLOAT); + add_output("Lifetime", SHADER_SOCKET_FLOAT); +} + +void ParticleInfoNode::attributes(AttributeRequestSet *attributes) +{ + if(!output("Age")->links.empty()) + attributes->add(ATTR_STD_PARTICLE); + if(!output("Lifetime")->links.empty()) + attributes->add(ATTR_STD_PARTICLE); + + ShaderNode::attributes(attributes); +} + +void ParticleInfoNode::compile(SVMCompiler& compiler) +{ + ShaderOutput *out; + + out = output("Age"); + if(!out->links.empty()) { + compiler.stack_assign(out); + compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_AGE, out->stack_offset); + } + + out = output("Lifetime"); + if(!out->links.empty()) { + compiler.stack_assign(out); + compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_LIFETIME, out->stack_offset); + } +} + +void ParticleInfoNode::compile(OSLCompiler& compiler) +{ + compiler.add(this, "node_particle_info"); +} + /* Value */ ValueNode::ValueNode() diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h index 2d0d58d1e94..efd814e4ae6 100644 --- a/intern/cycles/render/nodes.h +++ b/intern/cycles/render/nodes.h @@ -44,7 +44,7 @@ public: float3 min, max; bool use_minmax; - enum Mapping { NONE=0, X=1, Y=2, Z=3 }; + enum Mapping { NONE = 0, X = 1, Y = 2, Z = 3 }; Mapping x_mapping, y_mapping, z_mapping; enum Projection { FLAT, CUBE, TUBE, SPHERE }; @@ -55,7 +55,7 @@ public: class TextureNode : public ShaderNode { public: - TextureNode(const char *name) : ShaderNode(name) {} + TextureNode(const char *name_) : ShaderNode(name_) {} TextureMapping tex_mapping; }; @@ -290,6 +290,12 @@ public: SHADER_NODE_CLASS(ObjectInfoNode) }; +class ParticleInfoNode : public ShaderNode { +public: + SHADER_NODE_CLASS(ParticleInfoNode) + void attributes(AttributeRequestSet *attributes); +}; + class ValueNode : public ShaderNode { public: SHADER_NODE_CLASS(ValueNode) diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp index 5c7e48a38eb..376a7911fc9 100644 --- a/intern/cycles/render/object.cpp +++ b/intern/cycles/render/object.cpp @@ -25,6 +25,7 @@ #include "util_foreach.h" #include "util_map.h" #include "util_progress.h" +#include "util_vector.h" CCL_NAMESPACE_BEGIN @@ -38,6 +39,7 @@ Object::Object() visibility = ~0; random_id = 0; pass_id = 0; + particle_id = 0; bounds = BoundBox::empty; motion.pre = transform_identity(); motion.post = transform_identity(); @@ -87,7 +89,7 @@ void Object::apply_transform() Transform ntfm = transform_transpose(transform_inverse(tfm)); /* we keep normals pointing in same direction on negative scale, notify - mesh about this in it (re)calculates normals */ + * mesh about this in it (re)calculates normals */ if(transform_negative_scale(tfm)) mesh->transform_negative_scaled = true; @@ -159,7 +161,7 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene Transform itfm = transform_inverse(tfm); /* compute surface area. for uniform scale we can do avoid the many - transform calls and share computation for instances */ + * transform calls and share computation for instances */ /* todo: correct for displacement, and move to a better place */ float uniform_scale; float surface_area = 0.0f; @@ -200,12 +202,12 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene memcpy(&objects[offset], &tfm, sizeof(float4)*3); memcpy(&objects[offset+3], &itfm, sizeof(float4)*3); - objects[offset+6] = make_float4(surface_area, pass_id, random_number, 0.0f); + objects[offset+6] = make_float4(surface_area, pass_id, random_number, __int_as_float(ob->particle_id)); if(need_motion == Scene::MOTION_PASS) { /* motion transformations, is world/object space depending if mesh - comes with deformed position in object space, or if we transform - the shading point in world space */ + * comes with deformed position in object space, or if we transform + * the shading point in world space */ Transform mtfm_pre = ob->motion.pre; Transform mtfm_post = ob->motion.post; @@ -246,6 +248,38 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene device->tex_alloc("__object_flag", dscene->object_flag); } +void ObjectManager::device_update_particles(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress) +{ + /* count particles. + * adds one dummy particle at the beginning to avoid invalid lookups, + * in case a shader uses particle info without actual particle data. + */ + int num_particles = 1; + foreach(Object *ob, scene->objects) + num_particles += ob->particles.size(); + + float4 *particles = dscene->particles.resize(PARTICLE_SIZE*num_particles); + + /* dummy particle */ + particles[0] = make_float4(0.0f, 0.0f, 0.0f, 0.0f); + + int i = 1; + foreach(Object *ob, scene->objects) { + foreach(Particle &pa, ob->particles) { + /* pack in texture */ + int offset = i*PARTICLE_SIZE; + + particles[offset] = make_float4(pa.age, pa.lifetime, 0.0f, 0.0f); + + i++; + + if(progress.get_cancel()) return; + } + } + + device->tex_alloc("__particles", dscene->particles); +} + void ObjectManager::device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress) { if(!need_update) @@ -271,6 +305,11 @@ void ObjectManager::device_update(Device *device, DeviceScene *dscene, Scene *sc if(progress.get_cancel()) return; + progress.set_status("Updating Objects", "Copying Particles to device"); + device_update_particles(device, dscene, scene, progress); + + if(progress.get_cancel()) return; + need_update = false; } @@ -281,6 +320,9 @@ void ObjectManager::device_free(Device *device, DeviceScene *dscene) device->tex_free(dscene->object_flag); dscene->object_flag.clear(); + + device->tex_free(dscene->particles); + dscene->particles.clear(); } void ObjectManager::apply_static_transforms(Scene *scene, Progress& progress) diff --git a/intern/cycles/render/object.h b/intern/cycles/render/object.h index a3bd748a8a4..6d674731b07 100644 --- a/intern/cycles/render/object.h +++ b/intern/cycles/render/object.h @@ -35,6 +35,11 @@ struct Transform; /* Object */ +struct Particle { + float age; + float lifetime; +}; + class Object { public: Mesh *mesh; @@ -49,6 +54,9 @@ public: bool use_motion; bool use_holdout; + int particle_id; + vector<Particle> particles; + Object(); ~Object(); @@ -69,6 +77,7 @@ public: void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress); void device_update_transforms(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress); + void device_update_particles(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress); void device_free(Device *device, DeviceScene *dscene); void tag_update(Scene *scene); diff --git a/intern/cycles/render/osl.cpp b/intern/cycles/render/osl.cpp index b0173334c76..04af9b48280 100644 --- a/intern/cycles/render/osl.cpp +++ b/intern/cycles/render/osl.cpp @@ -167,7 +167,7 @@ string OSLCompiler::compatible_name(const char *name) bool OSLCompiler::node_skip_input(ShaderNode *node, ShaderInput *input) { /* exception for output node, only one input is actually used - depending on the current shader type */ + * depending on the current shader type */ if(node->name == ustring("output")) { if(strcmp(input->name, "Surface") == 0 && current_type != SHADER_TYPE_SURFACE) diff --git a/intern/cycles/render/scene.h b/intern/cycles/render/scene.h index 90bc47d5c8e..8b9944cb76e 100644 --- a/intern/cycles/render/scene.h +++ b/intern/cycles/render/scene.h @@ -82,6 +82,9 @@ public: device_vector<float2> light_background_marginal_cdf; device_vector<float2> light_background_conditional_cdf; + /* particles */ + device_vector<float4> particles; + /* shaders */ device_vector<uint4> svm_nodes; device_vector<uint> shader_flag; diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp index 34a0c0ff877..a9f7e5beb56 100644 --- a/intern/cycles/render/session.cpp +++ b/intern/cycles/render/session.cpp @@ -27,6 +27,7 @@ #include "util_foreach.h" #include "util_function.h" +#include "util_opengl.h" #include "util_task.h" #include "util_time.h" @@ -115,8 +116,8 @@ bool Session::ready_to_reset() void Session::reset_gpu(BufferParams& buffer_params, int samples) { /* block for buffer acces and reset immediately. we can't do this - in the thread, because we need to allocate an OpenGL buffer, and - that only works in the main thread */ + * in the thread, because we need to allocate an OpenGL buffer, and + * that only works in the main thread */ thread_scoped_lock display_lock(display->mutex); thread_scoped_lock buffers_lock(buffers->mutex); @@ -139,10 +140,10 @@ bool Session::draw_gpu(BufferParams& buffer_params) /* first check we already rendered something */ if(gpu_draw_ready) { /* then verify the buffers have the expected size, so we don't - draw previous results in a resized window */ + * draw previous results in a resized window */ if(!buffer_params.modified(display->params)) { /* for CUDA we need to do tonemapping still, since we can - only access GL buffers from the main thread */ + * only access GL buffers from the main thread */ if(gpu_need_tonemap) { thread_scoped_lock buffers_lock(buffers->mutex); tonemap(); @@ -184,7 +185,7 @@ void Session::run_gpu() } else { /* if in interactive mode, and we are either paused or done for now, - wait for pause condition notify to wake up again */ + * wait for pause condition notify to wake up again */ thread_scoped_lock pause_lock(pause_mutex); if(pause || no_tiles) { @@ -223,8 +224,8 @@ void Session::run_gpu() if(!no_tiles) { /* buffers mutex is locked entirely while rendering each - sample, and released/reacquired on each iteration to allow - reset and draw in between */ + * sample, and released/reacquired on each iteration to allow + * reset and draw in between */ thread_scoped_lock buffers_lock(buffers->mutex); /* update status and timing */ @@ -293,7 +294,7 @@ bool Session::draw_cpu(BufferParams& buffer_params) /* first check we already rendered something */ if(display->draw_ready()) { /* then verify the buffers have the expected size, so we don't - draw previous results in a resized window */ + * draw previous results in a resized window */ if(!buffer_params.modified(display->params)) { display->draw(device); @@ -333,7 +334,7 @@ void Session::run_cpu() } else { /* if in interactive mode, and we are either paused or done for now, - wait for pause condition notify to wake up again */ + * wait for pause condition notify to wake up again */ thread_scoped_lock pause_lock(pause_mutex); if(pause || no_tiles) { @@ -361,8 +362,8 @@ void Session::run_cpu() if(!no_tiles) { /* buffers mutex is locked entirely while rendering each - sample, and released/reacquired on each iteration to allow - reset and draw in between */ + * sample, and released/reacquired on each iteration to allow + * reset and draw in between */ thread_scoped_lock buffers_lock(buffers->mutex); /* update scene */ @@ -405,7 +406,7 @@ void Session::run_cpu() } else if(need_tonemap) { /* tonemap only if we do not reset, we don't we don't - want to show the result of an incomplete sample*/ + * wan't to show the result of an incomplete sample*/ tonemap(); } @@ -534,8 +535,8 @@ void Session::update_scene() progress.set_status("Updating Scene"); /* update camera if dimensions changed for progressive render. the camera - knows nothing about progressive or cropped rendering, it just gets the - image dimensions passed in */ + * knows nothing about progressive or cropped rendering, it just gets the + * image dimensions passed in */ Camera *cam = scene->camera; int width = tile_manager.state.buffer.full_width; int height = tile_manager.state.buffer.full_height; diff --git a/intern/cycles/render/shader.cpp b/intern/cycles/render/shader.cpp index f50709146ef..fae1d6bd81c 100644 --- a/intern/cycles/render/shader.cpp +++ b/intern/cycles/render/shader.cpp @@ -81,9 +81,9 @@ void Shader::tag_update(Scene *scene) scene->light_manager->need_update = true; /* get requested attributes. this could be optimized by pruning unused - nodes here already, but that's the job of the shader manager currently, - and may not be so great for interactive rendering where you temporarily - disconnect a node */ + * nodes here already, but that's the job of the shader manager currently, + * and may not be so great for interactive rendering where you temporarily + * disconnect a node */ AttributeRequestSet prev_attributes = attributes; attributes.clear(); @@ -91,7 +91,7 @@ void Shader::tag_update(Scene *scene) node->attributes(&attributes); /* compare if the attributes changed, mesh manager will check - need_update_attributes, update the relevant meshes and clear it. */ + * need_update_attributes, update the relevant meshes and clear it. */ if(attributes.modified(prev_attributes)) { need_update_attributes = true; scene->mesh_manager->need_update = true; diff --git a/intern/cycles/render/shader.h b/intern/cycles/render/shader.h index 48d517ce21a..02788008060 100644 --- a/intern/cycles/render/shader.h +++ b/intern/cycles/render/shader.h @@ -53,8 +53,8 @@ public: ShaderGraph *graph; /* shader graph with auto bump mapping included, we compile two shaders, - with and without bump, because the displacement method is a mesh - level setting, so we need to handle both */ + * with and without bump, because the displacement method is a mesh + * level setting, so we need to handle both */ ShaderGraph *graph_bump; /* sampling */ @@ -109,7 +109,7 @@ public: int get_shader_id(uint shader, Mesh *mesh = NULL, bool smooth = false); /* add default shaders to scene, to use as default for things that don't - have any shader assigned explicitly */ + * have any shader assigned explicitly */ static void add_default(Scene *scene); protected: diff --git a/intern/cycles/render/svm.cpp b/intern/cycles/render/svm.cpp index 1ff3ac20d50..844ce01569f 100644 --- a/intern/cycles/render/svm.cpp +++ b/intern/cycles/render/svm.cpp @@ -251,11 +251,11 @@ void SVMCompiler::stack_link(ShaderInput *input, ShaderOutput *output) void SVMCompiler::stack_clear_users(ShaderNode *node, set<ShaderNode*>& done) { /* optimization we should add: - find and lower user counts for outputs for which all inputs are done. - this is done before the node is compiled, under the assumption that the - node will first load all inputs from the stack and then writes its - outputs. this used to work, but was disabled because it gave trouble - with inputs getting stack positions assigned */ + * find and lower user counts for outputs for which all inputs are done. + * this is done before the node is compiled, under the assumption that the + * node will first load all inputs from the stack and then writes its + * outputs. this used to work, but was disabled because it gave trouble + * with inputs getting stack positions assigned */ foreach(ShaderInput *input, node->inputs) { ShaderOutput *output = input->link; @@ -418,8 +418,8 @@ void SVMCompiler::generate_closure(ShaderNode *node, set<ShaderNode*>& done) add_node(NODE_ADD_CLOSURE, 0, 0, 0); /* generate code for closure 1 - note we backup all compiler state and restore it afterwards, so one - closure choice doesn't influence the other*/ + * note we backup all compiler state and restore it afterwards, so one + * closure choice doesn't influence the other*/ if(cl1in->link) { StackBackup backup; stack_backup(backup, done); @@ -448,7 +448,7 @@ void SVMCompiler::generate_closure(ShaderNode *node, set<ShaderNode*>& done) add_node(NODE_END, 0, 0, 0); /* set jump for mix node, -1 because offset is already - incremented when this jump is added to it */ + * incremented when this jump is added to it */ svm_nodes[mix_offset].z = cl2_offset - mix_offset - 1; done.insert(node); @@ -482,9 +482,9 @@ void SVMCompiler::generate_closure(ShaderNode *node, set<ShaderNode*>& done) void SVMCompiler::generate_multi_closure(ShaderNode *node, set<ShaderNode*>& done, uint in_offset) { /* todo: the weaks point here is that unlike the single closure sampling - we will evaluate all nodes even if they are used as input for closures - that are unused. it's not clear what would be the best way to skip such - nodes at runtime, especially if they are tangled up */ + * we will evaluate all nodes even if they are used as input for closures + * that are unused. it's not clear what would be the best way to skip such + * nodes at runtime, especially if they are tangled up */ if(node->name == ustring("mix_closure") || node->name == ustring("add_closure")) { ShaderInput *fin = node->input("Fac"); @@ -597,10 +597,10 @@ void SVMCompiler::compile_type(Shader *shader, ShaderGraph *graph, ShaderType ty memset(&active_stack, 0, sizeof(active_stack)); svm_nodes.clear(); - foreach(ShaderNode *node, graph->nodes) { - foreach(ShaderInput *input, node->inputs) + foreach(ShaderNode *node_iter, graph->nodes) { + foreach(ShaderInput *input, node_iter->inputs) input->stack_offset = SVM_STACK_INVALID; - foreach(ShaderOutput *output, node->outputs) + foreach(ShaderOutput *output, node_iter->outputs) output->stack_offset = SVM_STACK_INVALID; } diff --git a/intern/cycles/subd/subd_build.cpp b/intern/cycles/subd/subd_build.cpp index 640c30eba9d..c8181838ec3 100644 --- a/intern/cycles/subd/subd_build.cpp +++ b/intern/cycles/subd/subd_build.cpp @@ -82,7 +82,7 @@ static float pseudoValence(SubdVert *vert) if(vert->is_boundary()) { /* we treat boundary verts as being half a closed mesh. corners are - special case. n = 4 for corners and n = 2*(n-1) for boundaries. */ + * special case. n = 4 for corners and n = 2*(n-1) for boundaries. */ if(valence == 2) return 4; return (valence - 1)*2; } @@ -314,7 +314,7 @@ void SubdAccBuilder::computeEdgeStencil(SubdFaceRing *ring, GregoryAccStencil *s stencil->get(eid1) = stencil->get(cid); stencil->get(eid2) = stencil->get(cid); - int j = 0; + j = 0; for(SubdVert::EdgeIterator eit(vert->edges()); !eit.isDone(); eit.advance(), j++) { SubdEdge *edge = eit.current(); assert(vert->co == edge->from()->co); @@ -402,8 +402,8 @@ void SubdAccBuilder::computeInteriorStencil(SubdFaceRing *ring, GregoryAccStenci int idx2 = interior2Indices[primitiveOffset+v]; int i = 0; - for(SubdFace::EdgeIterator it(face->edges(edge)); !it.isDone(); it.advance(), i++) { - SubdVert *vert = it.current()->from(); + for(SubdFace::EdgeIterator it_sub(face->edges(edge)); !it_sub.isDone(); it_sub.advance(), i++) { + SubdVert *vert = it_sub.current()->from(); stencil->get(idx1, vert) += weights1[i]; stencil->get(idx2, vert) += weights2[i]; } @@ -481,10 +481,11 @@ void SubdAccBuilder::computeInteriorStencil(SubdFaceRing *ring, GregoryAccStenci } /* this change makes the triangle boundaries smoother, but distorts the quads next to them */ - /*if(ring->is_triangle() || SubdFaceRing::is_triangle(edge->pair->face)) - { +#if 0 + if(ring->is_triangle() || SubdFaceRing::is_triangle(edge->pair->face)) { y *= 4.0f / 3.0f; - }*/ + } +#endif stencil->get(interior1Indices[primitiveOffset+v]) = stencil->get(edge1Indices[primitiveOffset+v]); stencil->get(interior1Indices[primitiveOffset+v]) += x; @@ -539,8 +540,10 @@ void SubdAccBuilder::computeInteriorStencil(SubdFaceRing *ring, GregoryAccStenci } /* this change makes the triangle boundaries smoother, but distorts the quads next to them. */ - /*if(ring->is_triangle() || SubdFaceRing::is_triangle(edge->pair->face)) - y *= 4.0f / 3.0f;*/ +#if 0 + if(ring->is_triangle() || SubdFaceRing::is_triangle(edge->pair->face)) + y *= 4.0f / 3.0f; +#endif stencil->get(interior2Indices[primitiveOffset+v]) = stencil->get(edge2Indices[primitiveOffset+v]); stencil->get(interior2Indices[primitiveOffset+v]) += x; diff --git a/intern/cycles/subd/subd_dice.cpp b/intern/cycles/subd/subd_dice.cpp index 6e24bb410b5..6920df9954c 100644 --- a/intern/cycles/subd/subd_dice.cpp +++ b/intern/cycles/subd/subd_dice.cpp @@ -81,9 +81,9 @@ void EdgeDice::stitch_triangles(vector<int>& outer, vector<int>& inner) return; // XXX avoid crashes for Mu or Mv == 1, missing polygons /* stitch together two arrays of verts with triangles. at each step, - we compare using the next verts on both sides, to find the split - direction with the smallest diagonal, and use that in order to keep - the triangle shape reasonable. */ + * we compare using the next verts on both sides, to find the split + * direction with the smallest diagonal, and use that in order to keep + * the triangle shape reasonable. */ for(size_t i = 0, j = 0; i+1 < inner.size() || j+1 < outer.size();) { int v0, v1, v2; @@ -354,8 +354,8 @@ void TriangleDice::add_grid(SubPatch& sub, EdgeFactors& ef, int M) // XXX normals are flipped, why? /* grid is constructed starting from the outside edges, and adding - progressively smaller inner triangles that connected to the outer - one, until M = 1 or 2, the we fill up the last part. */ + * progressively smaller inner triangles that connected to the outer + * one, until M = 1 or 2, the we fill up the last part. */ vector<int> outer_u, outer_v, outer_w; int m; @@ -388,13 +388,13 @@ void TriangleDice::add_grid(SubPatch& sub, EdgeFactors& ef, int M) for(m = M-2; m > 0; m -= 2) { vector<int> inner_u, inner_v, inner_w; - float t = m/(float)M; + const float t0 = m / (float)M; float2 center = make_float2(1.0f/3.0f, 1.0f/3.0f); /* 3 corner vertices */ - float2 p_u = interp(center, make_float2(1.0f, 0.0f), t); - float2 p_v = interp(center, make_float2(0.0f, 1.0f), t); - float2 p_w = interp(center, make_float2(0.0f, 0.0f), t); + float2 p_u = interp(center, make_float2(1.0f, 0.0f), t0); + float2 p_v = interp(center, make_float2(0.0f, 1.0f), t0); + float2 p_w = interp(center, make_float2(0.0f, 0.0f), t0); int corner_u = add_vert(sub, p_u); int corner_v = add_vert(sub, p_v); @@ -407,11 +407,11 @@ void TriangleDice::add_grid(SubPatch& sub, EdgeFactors& ef, int M) for(int i = 1; i < m; i++) { /* add vertices between corners */ - float t = i/(float)m; + const float t1 = i / (float)m; - inner_u.push_back(add_vert(sub, interp(p_v, p_w, t))); - inner_v.push_back(add_vert(sub, interp(p_w, p_u, t))); - inner_w.push_back(add_vert(sub, interp(p_u, p_v, t))); + inner_u.push_back(add_vert(sub, interp(p_v, p_w, t1))); + inner_v.push_back(add_vert(sub, interp(p_w, p_u, t1))); + inner_w.push_back(add_vert(sub, interp(p_u, p_v, t1))); } inner_u.push_back(corner_w); diff --git a/intern/cycles/subd/subd_ring.cpp b/intern/cycles/subd/subd_ring.cpp index cbd12e60da0..66eab02231c 100644 --- a/intern/cycles/subd/subd_ring.cpp +++ b/intern/cycles/subd/subd_ring.cpp @@ -82,8 +82,8 @@ int SubdFaceRing::vert_index(SubdVert *vertex) void SubdFaceRing::evaluate_stencils(float3 *P, StencilMask *mask, int num) { /* first we sort verts by id. this way verts will always be added - in the same order to ensure the exact same float ops happen for control - points of other patches, so we get water-tight patches */ + * in the same order to ensure the exact same float ops happen for control + * points of other patches, so we get water-tight patches */ int num_verts = m_verts.size(); vector<int> vmap(num_verts); @@ -161,8 +161,8 @@ bool SubdFaceRing::is_quad(SubdFace *face) bool SubdFaceRing::is_boundary(SubdFace *face) { /* note that face->is_boundary() returns a different result. That function - returns true when any of the *edges* are on the boundary. however, this - function returns true if any of the face *verts* are on the boundary. */ + * returns true when any of the *edges* are on the boundary. however, this + * function returns true if any of the face *verts* are on the boundary. */ for(SubdFace::EdgeIterator it(face->edges()); !it.isDone(); it.advance()) { SubdEdge *edge = it.current(); diff --git a/intern/cycles/subd/subd_split.cpp b/intern/cycles/subd/subd_split.cpp index f0b87200f08..074c82a2348 100644 --- a/intern/cycles/subd/subd_split.cpp +++ b/intern/cycles/subd/subd_split.cpp @@ -248,19 +248,19 @@ void DiagSplit::split(QuadDice::SubPatch& sub, QuadDice::EdgeFactors& ef, int de void DiagSplit::split_triangle(Mesh *mesh, Patch *patch, int shader, bool smooth) { - TriangleDice::SubPatch sub; - TriangleDice::EdgeFactors ef; + TriangleDice::SubPatch sub_split; + TriangleDice::EdgeFactors ef_split; - sub.patch = patch; - sub.Pu = make_float2(1.0f, 0.0f); - sub.Pv = make_float2(0.0f, 1.0f); - sub.Pw = make_float2(0.0f, 0.0f); + sub_split.patch = patch; + sub_split.Pu = make_float2(1.0f, 0.0f); + sub_split.Pv = make_float2(0.0f, 1.0f); + sub_split.Pw = make_float2(0.0f, 0.0f); - ef.tu = T(patch, sub.Pv, sub.Pw); - ef.tv = T(patch, sub.Pw, sub.Pu); - ef.tw = T(patch, sub.Pu, sub.Pv); + ef_split.tu = T(patch, sub_split.Pv, sub_split.Pw); + ef_split.tv = T(patch, sub_split.Pw, sub_split.Pu); + ef_split.tw = T(patch, sub_split.Pu, sub_split.Pv); - split(sub, ef); + split(sub_split, ef_split); TriangleDice dice(mesh, shader, smooth, dicing_rate); dice.camera = camera; @@ -286,21 +286,21 @@ void DiagSplit::split_triangle(Mesh *mesh, Patch *patch, int shader, bool smooth void DiagSplit::split_quad(Mesh *mesh, Patch *patch, int shader, bool smooth) { - QuadDice::SubPatch sub; - QuadDice::EdgeFactors ef; + QuadDice::SubPatch sub_split; + QuadDice::EdgeFactors ef_split; - sub.patch = patch; - sub.P00 = make_float2(0.0f, 0.0f); - sub.P10 = make_float2(1.0f, 0.0f); - sub.P01 = make_float2(0.0f, 1.0f); - sub.P11 = make_float2(1.0f, 1.0f); + sub_split.patch = patch; + sub_split.P00 = make_float2(0.0f, 0.0f); + sub_split.P10 = make_float2(1.0f, 0.0f); + sub_split.P01 = make_float2(0.0f, 1.0f); + sub_split.P11 = make_float2(1.0f, 1.0f); - ef.tu0 = T(patch, sub.P00, sub.P10); - ef.tu1 = T(patch, sub.P01, sub.P11); - ef.tv0 = T(patch, sub.P00, sub.P01); - ef.tv1 = T(patch, sub.P10, sub.P11); + ef_split.tu0 = T(patch, sub_split.P00, sub_split.P10); + ef_split.tu1 = T(patch, sub_split.P01, sub_split.P11); + ef_split.tv0 = T(patch, sub_split.P00, sub_split.P01); + ef_split.tv1 = T(patch, sub_split.P10, sub_split.P11); - split(sub, ef); + split(sub_split, ef_split); QuadDice dice(mesh, shader, smooth, dicing_rate); dice.camera = camera; diff --git a/intern/cycles/util/util_color.h b/intern/cycles/util/util_color.h index 8b4a175f498..5136ea5c5db 100644 --- a/intern/cycles/util/util_color.h +++ b/intern/cycles/util/util_color.h @@ -29,15 +29,15 @@ __device float color_srgb_to_scene_linear(float c) if(c < 0.04045f) return (c < 0.0f)? 0.0f: c * (1.0f/12.92f); else - return pow((c + 0.055f)*(1.0f/1.055f), 2.4f); + return powf((c + 0.055f) * (1.0f / 1.055f), 2.4f); } __device float color_scene_linear_to_srgb(float c) { if(c < 0.0031308f) return (c < 0.0f)? 0.0f: c * 12.92f; - else - return 1.055f * pow(c, 1.0f/2.4f) - 0.055f; + else + return 1.055f * powf(c, 1.0f / 2.4f) - 0.055f; } #ifndef __KERNEL_OPENCL__ diff --git a/intern/cycles/util/util_cuda.cpp b/intern/cycles/util/util_cuda.cpp index f81a11ba9da..2960022fd8d 100644 --- a/intern/cycles/util/util_cuda.cpp +++ b/intern/cycles/util/util_cuda.cpp @@ -326,8 +326,8 @@ bool cuLibraryInit() CUDA_LIBRARY_FIND(cuCtxGetLimit); /* functions which changed 3.1 -> 3.2 for 64 bit stuff, the cuda library - has both the old ones for compatibility and new ones with _v2 postfix, - we load the _v2 ones here. */ + * has both the old ones for compatibility and new ones with _v2 postfix, + * we load the _v2 ones here. */ CUDA_LIBRARY_FIND_V2(cuDeviceTotalMem); CUDA_LIBRARY_FIND_V2(cuCtxCreate); CUDA_LIBRARY_FIND_V2(cuModuleGetGlobal); diff --git a/intern/cycles/util/util_cuda.h b/intern/cycles/util/util_cuda.h index ffc71b8864e..d9d956b7bd9 100644 --- a/intern/cycles/util/util_cuda.h +++ b/intern/cycles/util/util_cuda.h @@ -56,225 +56,225 @@ typedef struct CUstream_st *CUstream; typedef struct CUgraphicsResource_st *CUgraphicsResource; typedef struct CUuuid_st { - char bytes[16]; + char bytes[16]; } CUuuid; typedef enum CUctx_flags_enum { - CU_CTX_SCHED_AUTO = 0, - CU_CTX_SCHED_SPIN = 1, - CU_CTX_SCHED_YIELD = 2, - CU_CTX_SCHED_MASK = 0x3, - CU_CTX_BLOCKING_SYNC = 4, - CU_CTX_MAP_HOST = 8, - CU_CTX_LMEM_RESIZE_TO_MAX = 16, - CU_CTX_FLAGS_MASK = 0x1f + CU_CTX_SCHED_AUTO = 0, + CU_CTX_SCHED_SPIN = 1, + CU_CTX_SCHED_YIELD = 2, + CU_CTX_SCHED_MASK = 0x3, + CU_CTX_BLOCKING_SYNC = 4, + CU_CTX_MAP_HOST = 8, + CU_CTX_LMEM_RESIZE_TO_MAX = 16, + CU_CTX_FLAGS_MASK = 0x1f } CUctx_flags; typedef enum CUevent_flags_enum { - CU_EVENT_DEFAULT = 0, - CU_EVENT_BLOCKING_SYNC = 1, - CU_EVENT_DISABLE_TIMING = 2 + CU_EVENT_DEFAULT = 0, + CU_EVENT_BLOCKING_SYNC = 1, + CU_EVENT_DISABLE_TIMING = 2 } CUevent_flags; typedef enum CUarray_format_enum { - CU_AD_FORMAT_UNSIGNED_INT8 = 0x01, - CU_AD_FORMAT_UNSIGNED_INT16 = 0x02, - CU_AD_FORMAT_UNSIGNED_INT32 = 0x03, - CU_AD_FORMAT_SIGNED_INT8 = 0x08, - CU_AD_FORMAT_SIGNED_INT16 = 0x09, - CU_AD_FORMAT_SIGNED_INT32 = 0x0a, - CU_AD_FORMAT_HALF = 0x10, - CU_AD_FORMAT_FLOAT = 0x20 + CU_AD_FORMAT_UNSIGNED_INT8 = 0x01, + CU_AD_FORMAT_UNSIGNED_INT16 = 0x02, + CU_AD_FORMAT_UNSIGNED_INT32 = 0x03, + CU_AD_FORMAT_SIGNED_INT8 = 0x08, + CU_AD_FORMAT_SIGNED_INT16 = 0x09, + CU_AD_FORMAT_SIGNED_INT32 = 0x0a, + CU_AD_FORMAT_HALF = 0x10, + CU_AD_FORMAT_FLOAT = 0x20 } CUarray_format; typedef enum CUaddress_mode_enum { - CU_TR_ADDRESS_MODE_WRAP = 0, - CU_TR_ADDRESS_MODE_CLAMP = 1, - CU_TR_ADDRESS_MODE_MIRROR = 2, - CU_TR_ADDRESS_MODE_BORDER = 3 + CU_TR_ADDRESS_MODE_WRAP = 0, + CU_TR_ADDRESS_MODE_CLAMP = 1, + CU_TR_ADDRESS_MODE_MIRROR = 2, + CU_TR_ADDRESS_MODE_BORDER = 3 } CUaddress_mode; typedef enum CUfilter_mode_enum { - CU_TR_FILTER_MODE_POINT = 0, - CU_TR_FILTER_MODE_LINEAR = 1 + CU_TR_FILTER_MODE_POINT = 0, + CU_TR_FILTER_MODE_LINEAR = 1 } CUfilter_mode; typedef enum CUdevice_attribute_enum { - CU_DEVICE_ATTRIBUTE_MAX_THREADS_PER_BLOCK = 1, - CU_DEVICE_ATTRIBUTE_MAX_BLOCK_DIM_X = 2, - CU_DEVICE_ATTRIBUTE_MAX_BLOCK_DIM_Y = 3, - CU_DEVICE_ATTRIBUTE_MAX_BLOCK_DIM_Z = 4, - CU_DEVICE_ATTRIBUTE_MAX_GRID_DIM_X = 5, - CU_DEVICE_ATTRIBUTE_MAX_GRID_DIM_Y = 6, - CU_DEVICE_ATTRIBUTE_MAX_GRID_DIM_Z = 7, - CU_DEVICE_ATTRIBUTE_MAX_SHARED_MEMORY_PER_BLOCK = 8, - CU_DEVICE_ATTRIBUTE_SHARED_MEMORY_PER_BLOCK = 8, - CU_DEVICE_ATTRIBUTE_TOTAL_CONSTANT_MEMORY = 9, - CU_DEVICE_ATTRIBUTE_WARP_SIZE = 10, - CU_DEVICE_ATTRIBUTE_MAX_PITCH = 11, - CU_DEVICE_ATTRIBUTE_MAX_REGISTERS_PER_BLOCK = 12, - CU_DEVICE_ATTRIBUTE_REGISTERS_PER_BLOCK = 12, - CU_DEVICE_ATTRIBUTE_CLOCK_RATE = 13, - CU_DEVICE_ATTRIBUTE_TEXTURE_ALIGNMENT = 14, - CU_DEVICE_ATTRIBUTE_GPU_OVERLAP = 15, - CU_DEVICE_ATTRIBUTE_MULTIPROCESSOR_COUNT = 16, - CU_DEVICE_ATTRIBUTE_KERNEL_EXEC_TIMEOUT = 17, - CU_DEVICE_ATTRIBUTE_INTEGRATED = 18, - CU_DEVICE_ATTRIBUTE_CAN_MAP_HOST_MEMORY = 19, - CU_DEVICE_ATTRIBUTE_COMPUTE_MODE = 20, - CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE1D_WIDTH = 21, - CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE2D_WIDTH = 22, - CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE2D_HEIGHT = 23, - CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE3D_WIDTH = 24, - CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE3D_HEIGHT = 25, - CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE3D_DEPTH = 26, - CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE2D_ARRAY_WIDTH = 27, - CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE2D_ARRAY_HEIGHT = 28, - CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE2D_ARRAY_NUMSLICES = 29, - CU_DEVICE_ATTRIBUTE_SURFACE_ALIGNMENT = 30, - CU_DEVICE_ATTRIBUTE_CONCURRENT_KERNELS = 31, - CU_DEVICE_ATTRIBUTE_ECC_ENABLED = 32, - CU_DEVICE_ATTRIBUTE_PCI_BUS_ID = 33, - CU_DEVICE_ATTRIBUTE_PCI_DEVICE_ID = 34, - CU_DEVICE_ATTRIBUTE_TCC_DRIVER = 35 + CU_DEVICE_ATTRIBUTE_MAX_THREADS_PER_BLOCK = 1, + CU_DEVICE_ATTRIBUTE_MAX_BLOCK_DIM_X = 2, + CU_DEVICE_ATTRIBUTE_MAX_BLOCK_DIM_Y = 3, + CU_DEVICE_ATTRIBUTE_MAX_BLOCK_DIM_Z = 4, + CU_DEVICE_ATTRIBUTE_MAX_GRID_DIM_X = 5, + CU_DEVICE_ATTRIBUTE_MAX_GRID_DIM_Y = 6, + CU_DEVICE_ATTRIBUTE_MAX_GRID_DIM_Z = 7, + CU_DEVICE_ATTRIBUTE_MAX_SHARED_MEMORY_PER_BLOCK = 8, + CU_DEVICE_ATTRIBUTE_SHARED_MEMORY_PER_BLOCK = 8, + CU_DEVICE_ATTRIBUTE_TOTAL_CONSTANT_MEMORY = 9, + CU_DEVICE_ATTRIBUTE_WARP_SIZE = 10, + CU_DEVICE_ATTRIBUTE_MAX_PITCH = 11, + CU_DEVICE_ATTRIBUTE_MAX_REGISTERS_PER_BLOCK = 12, + CU_DEVICE_ATTRIBUTE_REGISTERS_PER_BLOCK = 12, + CU_DEVICE_ATTRIBUTE_CLOCK_RATE = 13, + CU_DEVICE_ATTRIBUTE_TEXTURE_ALIGNMENT = 14, + CU_DEVICE_ATTRIBUTE_GPU_OVERLAP = 15, + CU_DEVICE_ATTRIBUTE_MULTIPROCESSOR_COUNT = 16, + CU_DEVICE_ATTRIBUTE_KERNEL_EXEC_TIMEOUT = 17, + CU_DEVICE_ATTRIBUTE_INTEGRATED = 18, + CU_DEVICE_ATTRIBUTE_CAN_MAP_HOST_MEMORY = 19, + CU_DEVICE_ATTRIBUTE_COMPUTE_MODE = 20, + CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE1D_WIDTH = 21, + CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE2D_WIDTH = 22, + CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE2D_HEIGHT = 23, + CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE3D_WIDTH = 24, + CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE3D_HEIGHT = 25, + CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE3D_DEPTH = 26, + CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE2D_ARRAY_WIDTH = 27, + CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE2D_ARRAY_HEIGHT = 28, + CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE2D_ARRAY_NUMSLICES = 29, + CU_DEVICE_ATTRIBUTE_SURFACE_ALIGNMENT = 30, + CU_DEVICE_ATTRIBUTE_CONCURRENT_KERNELS = 31, + CU_DEVICE_ATTRIBUTE_ECC_ENABLED = 32, + CU_DEVICE_ATTRIBUTE_PCI_BUS_ID = 33, + CU_DEVICE_ATTRIBUTE_PCI_DEVICE_ID = 34, + CU_DEVICE_ATTRIBUTE_TCC_DRIVER = 35 } CUdevice_attribute; typedef struct CUdevprop_st { - int maxThreadsPerBlock; - int maxThreadsDim[3]; - int maxGridSize[3]; - int sharedMemPerBlock; - int totalConstantMemory; - int SIMDWidth; - int memPitch; - int regsPerBlock; - int clockRate; - int textureAlign; + int maxThreadsPerBlock; + int maxThreadsDim[3]; + int maxGridSize[3]; + int sharedMemPerBlock; + int totalConstantMemory; + int SIMDWidth; + int memPitch; + int regsPerBlock; + int clockRate; + int textureAlign; } CUdevprop; typedef enum CUfunction_attribute_enum { - CU_FUNC_ATTRIBUTE_MAX_THREADS_PER_BLOCK = 0, - CU_FUNC_ATTRIBUTE_SHARED_SIZE_BYTES = 1, - CU_FUNC_ATTRIBUTE_CONST_SIZE_BYTES = 2, - CU_FUNC_ATTRIBUTE_LOCAL_SIZE_BYTES = 3, - CU_FUNC_ATTRIBUTE_NUM_REGS = 4, - CU_FUNC_ATTRIBUTE_PTX_VERSION = 5, - CU_FUNC_ATTRIBUTE_BINARY_VERSION = 6, - CU_FUNC_ATTRIBUTE_MAX + CU_FUNC_ATTRIBUTE_MAX_THREADS_PER_BLOCK = 0, + CU_FUNC_ATTRIBUTE_SHARED_SIZE_BYTES = 1, + CU_FUNC_ATTRIBUTE_CONST_SIZE_BYTES = 2, + CU_FUNC_ATTRIBUTE_LOCAL_SIZE_BYTES = 3, + CU_FUNC_ATTRIBUTE_NUM_REGS = 4, + CU_FUNC_ATTRIBUTE_PTX_VERSION = 5, + CU_FUNC_ATTRIBUTE_BINARY_VERSION = 6, + CU_FUNC_ATTRIBUTE_MAX } CUfunction_attribute; typedef enum CUfunc_cache_enum { - CU_FUNC_CACHE_PREFER_NONE = 0x00, - CU_FUNC_CACHE_PREFER_SHARED = 0x01, - CU_FUNC_CACHE_PREFER_L1 = 0x02 + CU_FUNC_CACHE_PREFER_NONE = 0x00, + CU_FUNC_CACHE_PREFER_SHARED = 0x01, + CU_FUNC_CACHE_PREFER_L1 = 0x02 } CUfunc_cache; typedef enum CUmemorytype_enum { - CU_MEMORYTYPE_HOST = 0x01, - CU_MEMORYTYPE_DEVICE = 0x02, - CU_MEMORYTYPE_ARRAY = 0x03 + CU_MEMORYTYPE_HOST = 0x01, + CU_MEMORYTYPE_DEVICE = 0x02, + CU_MEMORYTYPE_ARRAY = 0x03 } CUmemorytype; typedef enum CUcomputemode_enum { - CU_COMPUTEMODE_DEFAULT = 0, - CU_COMPUTEMODE_EXCLUSIVE = 1, - CU_COMPUTEMODE_PROHIBITED = 2 + CU_COMPUTEMODE_DEFAULT = 0, + CU_COMPUTEMODE_EXCLUSIVE = 1, + CU_COMPUTEMODE_PROHIBITED = 2 } CUcomputemode; typedef enum CUjit_option_enum { - CU_JIT_MAX_REGISTERS = 0, - CU_JIT_THREADS_PER_BLOCK, - CU_JIT_WALL_TIME, - CU_JIT_INFO_LOG_BUFFER, - CU_JIT_INFO_LOG_BUFFER_SIZE_BYTES, - CU_JIT_ERROR_LOG_BUFFER, - CU_JIT_ERROR_LOG_BUFFER_SIZE_BYTES, - CU_JIT_OPTIMIZATION_LEVEL, - CU_JIT_TARGET_FROM_CUCONTEXT, - CU_JIT_TARGET, - CU_JIT_FALLBACK_STRATEGY + CU_JIT_MAX_REGISTERS = 0, + CU_JIT_THREADS_PER_BLOCK, + CU_JIT_WALL_TIME, + CU_JIT_INFO_LOG_BUFFER, + CU_JIT_INFO_LOG_BUFFER_SIZE_BYTES, + CU_JIT_ERROR_LOG_BUFFER, + CU_JIT_ERROR_LOG_BUFFER_SIZE_BYTES, + CU_JIT_OPTIMIZATION_LEVEL, + CU_JIT_TARGET_FROM_CUCONTEXT, + CU_JIT_TARGET, + CU_JIT_FALLBACK_STRATEGY } CUjit_option; typedef enum CUjit_target_enum { - CU_TARGET_COMPUTE_10 = 0, - CU_TARGET_COMPUTE_11, - CU_TARGET_COMPUTE_12, - CU_TARGET_COMPUTE_13, - CU_TARGET_COMPUTE_20, - CU_TARGET_COMPUTE_21, - CU_TARGET_COMPUTE_30 + CU_TARGET_COMPUTE_10 = 0, + CU_TARGET_COMPUTE_11, + CU_TARGET_COMPUTE_12, + CU_TARGET_COMPUTE_13, + CU_TARGET_COMPUTE_20, + CU_TARGET_COMPUTE_21, + CU_TARGET_COMPUTE_30 } CUjit_target; typedef enum CUjit_fallback_enum { - CU_PREFER_PTX = 0, - CU_PREFER_BINARY + CU_PREFER_PTX = 0, + CU_PREFER_BINARY } CUjit_fallback; typedef enum CUgraphicsRegisterFlags_enum { - CU_GRAPHICS_REGISTER_FLAGS_NONE = 0x00 + CU_GRAPHICS_REGISTER_FLAGS_NONE = 0x00 } CUgraphicsRegisterFlags; typedef enum CUgraphicsMapResourceFlags_enum { - CU_GRAPHICS_MAP_RESOURCE_FLAGS_NONE = 0x00, - CU_GRAPHICS_MAP_RESOURCE_FLAGS_READ_ONLY = 0x01, - CU_GRAPHICS_MAP_RESOURCE_FLAGS_WRITE_DISCARD = 0x02 + CU_GRAPHICS_MAP_RESOURCE_FLAGS_NONE = 0x00, + CU_GRAPHICS_MAP_RESOURCE_FLAGS_READ_ONLY = 0x01, + CU_GRAPHICS_MAP_RESOURCE_FLAGS_WRITE_DISCARD = 0x02 } CUgraphicsMapResourceFlags; typedef enum CUarray_cubemap_face_enum { - CU_CUBEMAP_FACE_POSITIVE_X = 0x00, - CU_CUBEMAP_FACE_NEGATIVE_X = 0x01, - CU_CUBEMAP_FACE_POSITIVE_Y = 0x02, - CU_CUBEMAP_FACE_NEGATIVE_Y = 0x03, - CU_CUBEMAP_FACE_POSITIVE_Z = 0x04, - CU_CUBEMAP_FACE_NEGATIVE_Z = 0x05 + CU_CUBEMAP_FACE_POSITIVE_X = 0x00, + CU_CUBEMAP_FACE_NEGATIVE_X = 0x01, + CU_CUBEMAP_FACE_POSITIVE_Y = 0x02, + CU_CUBEMAP_FACE_NEGATIVE_Y = 0x03, + CU_CUBEMAP_FACE_POSITIVE_Z = 0x04, + CU_CUBEMAP_FACE_NEGATIVE_Z = 0x05 } CUarray_cubemap_face; typedef enum CUlimit_enum { - CU_LIMIT_STACK_SIZE = 0x00, - CU_LIMIT_PRINTF_FIFO_SIZE = 0x01, - CU_LIMIT_MALLOC_HEAP_SIZE = 0x02 + CU_LIMIT_STACK_SIZE = 0x00, + CU_LIMIT_PRINTF_FIFO_SIZE = 0x01, + CU_LIMIT_MALLOC_HEAP_SIZE = 0x02 } CUlimit; typedef enum cudaError_enum { - CUDA_SUCCESS = 0, - CUDA_ERROR_INVALID_VALUE = 1, - CUDA_ERROR_OUT_OF_MEMORY = 2, - CUDA_ERROR_NOT_INITIALIZED = 3, - CUDA_ERROR_DEINITIALIZED = 4, - CUDA_ERROR_NO_DEVICE = 100, - CUDA_ERROR_INVALID_DEVICE = 101, - CUDA_ERROR_INVALID_IMAGE = 200, - CUDA_ERROR_INVALID_CONTEXT = 201, - CUDA_ERROR_CONTEXT_ALREADY_CURRENT = 202, - CUDA_ERROR_MAP_FAILED = 205, - CUDA_ERROR_UNMAP_FAILED = 206, - CUDA_ERROR_ARRAY_IS_MAPPED = 207, - CUDA_ERROR_ALREADY_MAPPED = 208, - CUDA_ERROR_NO_BINARY_FOR_GPU = 209, - CUDA_ERROR_ALREADY_ACQUIRED = 210, - CUDA_ERROR_NOT_MAPPED = 211, - CUDA_ERROR_NOT_MAPPED_AS_ARRAY = 212, - CUDA_ERROR_NOT_MAPPED_AS_POINTER = 213, - CUDA_ERROR_ECC_UNCORRECTABLE = 214, - CUDA_ERROR_UNSUPPORTED_LIMIT = 215, - CUDA_ERROR_INVALID_SOURCE = 300, - CUDA_ERROR_FILE_NOT_FOUND = 301, - CUDA_ERROR_SHARED_OBJECT_SYMBOL_NOT_FOUND = 302, - CUDA_ERROR_SHARED_OBJECT_INIT_FAILED = 303, - CUDA_ERROR_OPERATING_SYSTEM = 304, - CUDA_ERROR_INVALID_HANDLE = 400, - CUDA_ERROR_NOT_FOUND = 500, - CUDA_ERROR_NOT_READY = 600, - CUDA_ERROR_LAUNCH_FAILED = 700, - CUDA_ERROR_LAUNCH_OUT_OF_RESOURCES = 701, - CUDA_ERROR_LAUNCH_TIMEOUT = 702, - CUDA_ERROR_LAUNCH_INCOMPATIBLE_TEXTURING = 703, - CUDA_ERROR_UNKNOWN = 999 + CUDA_SUCCESS = 0, + CUDA_ERROR_INVALID_VALUE = 1, + CUDA_ERROR_OUT_OF_MEMORY = 2, + CUDA_ERROR_NOT_INITIALIZED = 3, + CUDA_ERROR_DEINITIALIZED = 4, + CUDA_ERROR_NO_DEVICE = 100, + CUDA_ERROR_INVALID_DEVICE = 101, + CUDA_ERROR_INVALID_IMAGE = 200, + CUDA_ERROR_INVALID_CONTEXT = 201, + CUDA_ERROR_CONTEXT_ALREADY_CURRENT = 202, + CUDA_ERROR_MAP_FAILED = 205, + CUDA_ERROR_UNMAP_FAILED = 206, + CUDA_ERROR_ARRAY_IS_MAPPED = 207, + CUDA_ERROR_ALREADY_MAPPED = 208, + CUDA_ERROR_NO_BINARY_FOR_GPU = 209, + CUDA_ERROR_ALREADY_ACQUIRED = 210, + CUDA_ERROR_NOT_MAPPED = 211, + CUDA_ERROR_NOT_MAPPED_AS_ARRAY = 212, + CUDA_ERROR_NOT_MAPPED_AS_POINTER = 213, + CUDA_ERROR_ECC_UNCORRECTABLE = 214, + CUDA_ERROR_UNSUPPORTED_LIMIT = 215, + CUDA_ERROR_INVALID_SOURCE = 300, + CUDA_ERROR_FILE_NOT_FOUND = 301, + CUDA_ERROR_SHARED_OBJECT_SYMBOL_NOT_FOUND = 302, + CUDA_ERROR_SHARED_OBJECT_INIT_FAILED = 303, + CUDA_ERROR_OPERATING_SYSTEM = 304, + CUDA_ERROR_INVALID_HANDLE = 400, + CUDA_ERROR_NOT_FOUND = 500, + CUDA_ERROR_NOT_READY = 600, + CUDA_ERROR_LAUNCH_FAILED = 700, + CUDA_ERROR_LAUNCH_OUT_OF_RESOURCES = 701, + CUDA_ERROR_LAUNCH_TIMEOUT = 702, + CUDA_ERROR_LAUNCH_INCOMPATIBLE_TEXTURING = 703, + CUDA_ERROR_UNKNOWN = 999 } CUresult; #define CU_MEMHOSTALLOC_PORTABLE 0x01 @@ -282,76 +282,76 @@ typedef enum cudaError_enum { #define CU_MEMHOSTALLOC_WRITECOMBINED 0x04 typedef struct CUDA_MEMCPY2D_st { - size_t srcXInBytes; - size_t srcY; - - CUmemorytype srcMemoryType; - const void *srcHost; - CUdeviceptr srcDevice; - CUarray srcArray; - size_t srcPitch; - - size_t dstXInBytes; - size_t dstY; - - CUmemorytype dstMemoryType; - void *dstHost; - CUdeviceptr dstDevice; - CUarray dstArray; - size_t dstPitch; - - size_t WidthInBytes; - size_t Height; + size_t srcXInBytes; + size_t srcY; + + CUmemorytype srcMemoryType; + const void *srcHost; + CUdeviceptr srcDevice; + CUarray srcArray; + size_t srcPitch; + + size_t dstXInBytes; + size_t dstY; + + CUmemorytype dstMemoryType; + void *dstHost; + CUdeviceptr dstDevice; + CUarray dstArray; + size_t dstPitch; + + size_t WidthInBytes; + size_t Height; } CUDA_MEMCPY2D; typedef struct CUDA_MEMCPY3D_st { - size_t srcXInBytes; - size_t srcY; - size_t srcZ; - size_t srcLOD; - CUmemorytype srcMemoryType; - const void *srcHost; - CUdeviceptr srcDevice; - CUarray srcArray; - void *reserved0; - size_t srcPitch; - size_t srcHeight; - - size_t dstXInBytes; - size_t dstY; - size_t dstZ; - size_t dstLOD; - CUmemorytype dstMemoryType; - void *dstHost; - CUdeviceptr dstDevice; - CUarray dstArray; - void *reserved1; - size_t dstPitch; - size_t dstHeight; - - size_t WidthInBytes; - size_t Height; - size_t Depth; + size_t srcXInBytes; + size_t srcY; + size_t srcZ; + size_t srcLOD; + CUmemorytype srcMemoryType; + const void *srcHost; + CUdeviceptr srcDevice; + CUarray srcArray; + void *reserved0; + size_t srcPitch; + size_t srcHeight; + + size_t dstXInBytes; + size_t dstY; + size_t dstZ; + size_t dstLOD; + CUmemorytype dstMemoryType; + void *dstHost; + CUdeviceptr dstDevice; + CUarray dstArray; + void *reserved1; + size_t dstPitch; + size_t dstHeight; + + size_t WidthInBytes; + size_t Height; + size_t Depth; } CUDA_MEMCPY3D; typedef struct CUDA_ARRAY_DESCRIPTOR_st { - size_t Width; - size_t Height; + size_t Width; + size_t Height; - CUarray_format Format; - unsigned int NumChannels; + CUarray_format Format; + unsigned int NumChannels; } CUDA_ARRAY_DESCRIPTOR; typedef struct CUDA_ARRAY3D_DESCRIPTOR_st { - size_t Width; - size_t Height; - size_t Depth; + size_t Width; + size_t Height; + size_t Depth; - CUarray_format Format; - unsigned int NumChannels; - unsigned int Flags; + CUarray_format Format; + unsigned int NumChannels; + unsigned int Flags; } CUDA_ARRAY3D_DESCRIPTOR; #define CUDA_ARRAY3D_2DARRAY 0x01 diff --git a/intern/cycles/util/util_hash.h b/intern/cycles/util/util_hash.h index c31b46e1580..5b3ff76af7f 100644 --- a/intern/cycles/util/util_hash.h +++ b/intern/cycles/util/util_hash.h @@ -34,14 +34,14 @@ static inline uint hash_int_2d(uint kx, uint ky) b += ky; c ^= b; c -= rot(b,14); - a ^= c; a -= rot(c,11); - b ^= a; b -= rot(a,25); - c ^= b; c -= rot(b,16); - a ^= c; a -= rot(c,4); - b ^= a; b -= rot(a,14); - c ^= b; c -= rot(b,24); - - return c; + a ^= c; a -= rot(c,11); + b ^= a; b -= rot(a,25); + c ^= b; c -= rot(b,16); + a ^= c; a -= rot(c,4); + b ^= a; b -= rot(a,14); + c ^= b; c -= rot(b,24); + + return c; #undef rot } diff --git a/intern/cycles/util/util_math.h b/intern/cycles/util/util_math.h index fee2f10085b..a6bc478ee64 100644 --- a/intern/cycles/util/util_math.h +++ b/intern/cycles/util/util_math.h @@ -162,6 +162,12 @@ __device_inline float nonzerof(float f, float eps) return f; } +__device_inline float smoothstepf(float f) +{ + float ff = f*f; + return (3.0f*ff - 2.0f*ff*f); +} + /* Float2 Vector */ #ifndef __KERNEL_OPENCL__ @@ -328,7 +334,7 @@ __device_inline float2 as_float2(const float4 a) __device_inline void print_float2(const char *label, const float2& a) { - printf("%s: %.8f %.8f\n", label, a.x, a.y); + printf("%s: %.8f %.8f\n", label, (double)a.x, (double)a.y); } #endif @@ -526,7 +532,7 @@ __device_inline float4 float3_to_float4(const float3 a) __device_inline void print_float3(const char *label, const float3& a) { - printf("%s: %.8f %.8f %.8f\n", label, a.x, a.y, a.z); + printf("%s: %.8f %.8f %.8f\n", label, (double)a.x, (double)a.y, (double)a.z); } __device_inline float3 rcp(const float3& a) @@ -838,7 +844,7 @@ __device_inline float4 reduce_add(const float4& a) __device_inline void print_float4(const char *label, const float4& a) { - printf("%s: %.8f %.8f %.8f %.8f\n", label, a.x, a.y, a.z, a.w); + printf("%s: %.8f %.8f %.8f %.8f\n", label, (double)a.x, (double)a.y, (double)a.z, (double)a.w); } #endif diff --git a/intern/cycles/util/util_md5.cpp b/intern/cycles/util/util_md5.cpp index 25a77f18d02..9dcd69cec99 100644 --- a/intern/cycles/util/util_md5.cpp +++ b/intern/cycles/util/util_md5.cpp @@ -148,7 +148,7 @@ void MD5Hash::process(const uint8_t *data /*[64]*/) /* Round 1. */ /* Let [abcd k s i] denote the operation - a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */ + * a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */ #define F(x, y, z) (((x) & (y)) | (~(x) & (z))) #define SET(a, b, c, d, k, s, Ti)\ t = a + F(b,c,d) + X[k] + Ti;\ @@ -172,9 +172,9 @@ void MD5Hash::process(const uint8_t *data /*[64]*/) SET(b, c, d, a, 15, 22, T16); #undef SET - /* Round 2. */ - /* Let [abcd k s i] denote the operation - a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */ + /* Round 2. */ + /* Let [abcd k s i] denote the operation + * a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */ #define G(x, y, z) (((x) & (z)) | ((y) & ~(z))) #define SET(a, b, c, d, k, s, Ti)\ t = a + G(b,c,d) + X[k] + Ti;\ @@ -198,9 +198,9 @@ void MD5Hash::process(const uint8_t *data /*[64]*/) SET(b, c, d, a, 12, 20, T32); #undef SET - /* Round 3. */ - /* Let [abcd k s t] denote the operation - a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */ + /* Round 3. */ + /* Let [abcd k s t] denote the operation + * a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */ #define H(x, y, z) ((x) ^ (y) ^ (z)) #define SET(a, b, c, d, k, s, Ti)\ t = a + H(b,c,d) + X[k] + Ti;\ @@ -224,9 +224,9 @@ void MD5Hash::process(const uint8_t *data /*[64]*/) SET(b, c, d, a, 2, 23, T48); #undef SET - /* Round 4. */ - /* Let [abcd k s t] denote the operation - a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */ + /* Round 4. */ + /* Let [abcd k s t] denote the operation + * a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */ #define I(x, y, z) ((y) ^ ((x) | ~(z))) #define SET(a, b, c, d, k, s, Ti)\ t = a + I(b,c,d) + X[k] + Ti;\ @@ -250,9 +250,9 @@ void MD5Hash::process(const uint8_t *data /*[64]*/) SET(b, c, d, a, 9, 21, T64); #undef SET - /* Then perform the following additions. (That is increment each - of the four registers by the value it had before this block - was started.) */ + /* Then perform the following additions. (That is increment each + * of the four registers by the value it had before this block + * was started.) */ abcd[0] += a; abcd[1] += b; abcd[2] += c; @@ -365,7 +365,7 @@ string MD5Hash::get_hex() finish(digest); - for(int i=0; i<16; i++) + for(int i = 0; i < 16; i++) sprintf(buf + i*2, "%02X", digest[i]); buf[sizeof(buf)-1] = '\0'; diff --git a/intern/cycles/util/util_md5.h b/intern/cycles/util/util_md5.h index 5e7e604c4cf..43e08e64f39 100644 --- a/intern/cycles/util/util_md5.h +++ b/intern/cycles/util/util_md5.h @@ -44,13 +44,13 @@ public: bool append_file(const string& filepath); string get_hex(); -protected: + protected: void process(const uint8_t *data); void finish(uint8_t digest[16]); - uint32_t count[2]; /* message length in bits, lsw first */ - uint32_t abcd[4]; /* digest buffer */ - uint8_t buf[64]; /* accumulate block */ + uint32_t count[2]; /* message length in bits, lsw first */ + uint32_t abcd[4]; /* digest buffer */ + uint8_t buf[64]; /* accumulate block */ }; CCL_NAMESPACE_END diff --git a/intern/cycles/util/util_opencl.cpp b/intern/cycles/util/util_opencl.cpp index 4087c2c3823..c9df9c2ff5c 100644 --- a/intern/cycles/util/util_opencl.cpp +++ b/intern/cycles/util/util_opencl.cpp @@ -13,29 +13,29 @@ #ifndef CLCC_GENERATE_DOCUMENTATION #ifdef _WIN32 - #define WIN32_LEAN_AND_MEAN - #define VC_EXTRALEAN - #include <windows.h> +# define WIN32_LEAN_AND_MEAN +# define VC_EXTRALEAN +# include <windows.h> - typedef HMODULE CLCC_DYNLIB_HANDLE; + typedef HMODULE CLCC_DYNLIB_HANDLE; - #define CLCC_DYNLIB_OPEN LoadLibrary - #define CLCC_DYNLIB_CLOSE FreeLibrary - #define CLCC_DYNLIB_IMPORT GetProcAddress +# define CLCC_DYNLIB_OPEN LoadLibrary +# define CLCC_DYNLIB_CLOSE FreeLibrary +# define CLCC_DYNLIB_IMPORT GetProcAddress #else - #include <dlfcn.h> - - typedef void* CLCC_DYNLIB_HANDLE; +# include <dlfcn.h> - #define CLCC_DYNLIB_OPEN(path) dlopen(path, RTLD_NOW | RTLD_GLOBAL) - #define CLCC_DYNLIB_CLOSE dlclose - #define CLCC_DYNLIB_IMPORT dlsym + typedef void* CLCC_DYNLIB_HANDLE; + +# define CLCC_DYNLIB_OPEN(path) dlopen(path, RTLD_NOW | RTLD_GLOBAL) +# define CLCC_DYNLIB_CLOSE dlclose +# define CLCC_DYNLIB_IMPORT dlsym #endif #else - //typedef implementation_defined CLCC_DYNLIB_HANDLE; - //#define CLCC_DYNLIB_OPEN(path) implementation_defined - //#define CLCC_DYNLIB_CLOSE implementation_defined - //#define CLCC_DYNLIB_IMPORT implementation_defined +// typedef implementation_defined CLCC_DYNLIB_HANDLE; +//# define CLCC_DYNLIB_OPEN(path) implementation_defined +//# define CLCC_DYNLIB_CLOSE implementation_defined +//# define CLCC_DYNLIB_IMPORT implementation_defined #endif CCL_NAMESPACE_BEGIN @@ -117,12 +117,12 @@ PFNCLGETEXTENSIONFUNCTIONADDRESS __clewGetExtensionFunctionAddress = NULL; //! \brief Unloads OpenCL dynamic library, should not be called directly static void clewExit(void) { - if (module != NULL) - { - // Ignore errors - CLCC_DYNLIB_CLOSE(module); - module = NULL; - } + if (module != NULL) + { + // Ignore errors + CLCC_DYNLIB_CLOSE(module); + module = NULL; + } } //! \param path path to dynamic library to load @@ -138,186 +138,186 @@ int clLibraryInit() #else const char *path = "libOpenCL.so"; #endif - int error = 0; + int error = 0; - // Check if already initialized - if (module != NULL) - { - return 1; - } + // Check if already initialized + if (module != NULL) + { + return 1; + } - // Load library - module = CLCC_DYNLIB_OPEN(path); + // Load library + module = CLCC_DYNLIB_OPEN(path); - // Check for errors - if (module == NULL) - { - return 0; - } + // Check for errors + if (module == NULL) + { + return 0; + } - // Set unloading - error = atexit(clewExit); + // Set unloading + error = atexit(clewExit); - if (error) - { - // Failure queing atexit, shutdown with error - CLCC_DYNLIB_CLOSE(module); - module = NULL; + if (error) + { + // Failure queing atexit, shutdown with error + CLCC_DYNLIB_CLOSE(module); + module = NULL; - return 0; - } + return 0; + } - // Determine function entry-points - __clewGetPlatformIDs = (PFNCLGETPLATFORMIDS )CLCC_DYNLIB_IMPORT(module, "clGetPlatformIDs"); - __clewGetPlatformInfo = (PFNCLGETPLATFORMINFO )CLCC_DYNLIB_IMPORT(module, "clGetPlatformInfo"); - __clewGetDeviceIDs = (PFNCLGETDEVICEIDS )CLCC_DYNLIB_IMPORT(module, "clGetDeviceIDs"); - __clewGetDeviceInfo = (PFNCLGETDEVICEINFO )CLCC_DYNLIB_IMPORT(module, "clGetDeviceInfo"); - __clewCreateContext = (PFNCLCREATECONTEXT )CLCC_DYNLIB_IMPORT(module, "clCreateContext"); - __clewCreateContextFromType = (PFNCLCREATECONTEXTFROMTYPE )CLCC_DYNLIB_IMPORT(module, "clCreateContextFromType"); - __clewRetainContext = (PFNCLRETAINCONTEXT )CLCC_DYNLIB_IMPORT(module, "clRetainContext"); - __clewReleaseContext = (PFNCLRELEASECONTEXT )CLCC_DYNLIB_IMPORT(module, "clReleaseContext"); - __clewGetContextInfo = (PFNCLGETCONTEXTINFO )CLCC_DYNLIB_IMPORT(module, "clGetContextInfo"); - __clewCreateCommandQueue = (PFNCLCREATECOMMANDQUEUE )CLCC_DYNLIB_IMPORT(module, "clCreateCommandQueue"); - __clewRetainCommandQueue = (PFNCLRETAINCOMMANDQUEUE )CLCC_DYNLIB_IMPORT(module, "clRetainCommandQueue"); - __clewReleaseCommandQueue = (PFNCLRELEASECOMMANDQUEUE )CLCC_DYNLIB_IMPORT(module, "clReleaseCommandQueue"); - __clewGetCommandQueueInfo = (PFNCLGETCOMMANDQUEUEINFO )CLCC_DYNLIB_IMPORT(module, "clGetCommandQueueInfo"); - __clewSetCommandQueueProperty = (PFNCLSETCOMMANDQUEUEPROPERTY )CLCC_DYNLIB_IMPORT(module, "clSetCommandQueueProperty"); - __clewCreateBuffer = (PFNCLCREATEBUFFER )CLCC_DYNLIB_IMPORT(module, "clCreateBuffer"); - __clewCreateImage2D = (PFNCLCREATEIMAGE2D )CLCC_DYNLIB_IMPORT(module, "clCreateImage2D"); - __clewCreateImage3D = (PFNCLCREATEIMAGE3D )CLCC_DYNLIB_IMPORT(module, "clCreateImage3D"); - __clewRetainMemObject = (PFNCLRETAINMEMOBJECT )CLCC_DYNLIB_IMPORT(module, "clRetainMemObject"); - __clewReleaseMemObject = (PFNCLRELEASEMEMOBJECT )CLCC_DYNLIB_IMPORT(module, "clReleaseMemObject"); - __clewGetSupportedImageFormats = (PFNCLGETSUPPORTEDIMAGEFORMATS )CLCC_DYNLIB_IMPORT(module, "clGetSupportedImageFormats"); - __clewGetMemObjectInfo = (PFNCLGETMEMOBJECTINFO )CLCC_DYNLIB_IMPORT(module, "clGetMemObjectInfo"); - __clewGetImageInfo = (PFNCLGETIMAGEINFO )CLCC_DYNLIB_IMPORT(module, "clGetImageInfo"); - __clewCreateSampler = (PFNCLCREATESAMPLER )CLCC_DYNLIB_IMPORT(module, "clCreateSampler"); - __clewRetainSampler = (PFNCLRETAINSAMPLER )CLCC_DYNLIB_IMPORT(module, "clRetainSampler"); - __clewReleaseSampler = (PFNCLRELEASESAMPLER )CLCC_DYNLIB_IMPORT(module, "clReleaseSampler"); - __clewGetSamplerInfo = (PFNCLGETSAMPLERINFO )CLCC_DYNLIB_IMPORT(module, "clGetSamplerInfo"); - __clewCreateProgramWithSource = (PFNCLCREATEPROGRAMWITHSOURCE )CLCC_DYNLIB_IMPORT(module, "clCreateProgramWithSource"); - __clewCreateProgramWithBinary = (PFNCLCREATEPROGRAMWITHBINARY )CLCC_DYNLIB_IMPORT(module, "clCreateProgramWithBinary"); - __clewRetainProgram = (PFNCLRETAINPROGRAM )CLCC_DYNLIB_IMPORT(module, "clRetainProgram"); - __clewReleaseProgram = (PFNCLRELEASEPROGRAM )CLCC_DYNLIB_IMPORT(module, "clReleaseProgram"); - __clewBuildProgram = (PFNCLBUILDPROGRAM )CLCC_DYNLIB_IMPORT(module, "clBuildProgram"); - __clewUnloadCompiler = (PFNCLUNLOADCOMPILER )CLCC_DYNLIB_IMPORT(module, "clUnloadCompiler"); - __clewGetProgramInfo = (PFNCLGETPROGRAMINFO )CLCC_DYNLIB_IMPORT(module, "clGetProgramInfo"); - __clewGetProgramBuildInfo = (PFNCLGETPROGRAMBUILDINFO )CLCC_DYNLIB_IMPORT(module, "clGetProgramBuildInfo"); - __clewCreateKernel = (PFNCLCREATEKERNEL )CLCC_DYNLIB_IMPORT(module, "clCreateKernel"); - __clewCreateKernelsInProgram = (PFNCLCREATEKERNELSINPROGRAM )CLCC_DYNLIB_IMPORT(module, "clCreateKernelsInProgram"); - __clewRetainKernel = (PFNCLRETAINKERNEL )CLCC_DYNLIB_IMPORT(module, "clRetainKernel"); - __clewReleaseKernel = (PFNCLRELEASEKERNEL )CLCC_DYNLIB_IMPORT(module, "clReleaseKernel"); - __clewSetKernelArg = (PFNCLSETKERNELARG )CLCC_DYNLIB_IMPORT(module, "clSetKernelArg"); - __clewGetKernelInfo = (PFNCLGETKERNELINFO )CLCC_DYNLIB_IMPORT(module, "clGetKernelInfo"); - __clewGetKernelWorkGroupInfo = (PFNCLGETKERNELWORKGROUPINFO )CLCC_DYNLIB_IMPORT(module, "clGetKernelWorkGroupInfo"); - __clewWaitForEvents = (PFNCLWAITFOREVENTS )CLCC_DYNLIB_IMPORT(module, "clWaitForEvents"); - __clewGetEventInfo = (PFNCLGETEVENTINFO )CLCC_DYNLIB_IMPORT(module, "clGetEventInfo"); - __clewRetainEvent = (PFNCLRETAINEVENT )CLCC_DYNLIB_IMPORT(module, "clRetainEvent"); - __clewReleaseEvent = (PFNCLRELEASEEVENT )CLCC_DYNLIB_IMPORT(module, "clReleaseEvent"); - __clewGetEventProfilingInfo = (PFNCLGETEVENTPROFILINGINFO )CLCC_DYNLIB_IMPORT(module, "clGetEventProfilingInfo"); - __clewFlush = (PFNCLFLUSH )CLCC_DYNLIB_IMPORT(module, "clFlush"); - __clewFinish = (PFNCLFINISH )CLCC_DYNLIB_IMPORT(module, "clFinish"); - __clewEnqueueReadBuffer = (PFNCLENQUEUEREADBUFFER )CLCC_DYNLIB_IMPORT(module, "clEnqueueReadBuffer"); - __clewEnqueueWriteBuffer = (PFNCLENQUEUEWRITEBUFFER )CLCC_DYNLIB_IMPORT(module, "clEnqueueWriteBuffer"); - __clewEnqueueCopyBuffer = (PFNCLENQUEUECOPYBUFFER )CLCC_DYNLIB_IMPORT(module, "clEnqueueCopyBuffer"); - __clewEnqueueReadImage = (PFNCLENQUEUEREADIMAGE )CLCC_DYNLIB_IMPORT(module, "clEnqueueReadImage"); - __clewEnqueueWriteImage = (PFNCLENQUEUEWRITEIMAGE )CLCC_DYNLIB_IMPORT(module, "clEnqueueWriteImage"); - __clewEnqueueCopyImage = (PFNCLENQUEUECOPYIMAGE )CLCC_DYNLIB_IMPORT(module, "clEnqueueCopyImage"); - __clewEnqueueCopyImageToBuffer = (PFNCLENQUEUECOPYIMAGETOBUFFER )CLCC_DYNLIB_IMPORT(module, "clEnqueueCopyImageToBuffer"); - __clewEnqueueCopyBufferToImage = (PFNCLENQUEUECOPYBUFFERTOIMAGE )CLCC_DYNLIB_IMPORT(module, "clEnqueueCopyBufferToImage"); - __clewEnqueueMapBuffer = (PFNCLENQUEUEMAPBUFFER )CLCC_DYNLIB_IMPORT(module, "clEnqueueMapBuffer"); - __clewEnqueueMapImage = (PFNCLENQUEUEMAPIMAGE )CLCC_DYNLIB_IMPORT(module, "clEnqueueMapImage"); - __clewEnqueueUnmapMemObject = (PFNCLENQUEUEUNMAPMEMOBJECT )CLCC_DYNLIB_IMPORT(module, "clEnqueueUnmapMemObject"); - __clewEnqueueNDRangeKernel = (PFNCLENQUEUENDRANGEKERNEL )CLCC_DYNLIB_IMPORT(module, "clEnqueueNDRangeKernel"); - __clewEnqueueTask = (PFNCLENQUEUETASK )CLCC_DYNLIB_IMPORT(module, "clEnqueueTask"); - __clewEnqueueNativeKernel = (PFNCLENQUEUENATIVEKERNEL )CLCC_DYNLIB_IMPORT(module, "clEnqueueNativeKernel"); - __clewEnqueueMarker = (PFNCLENQUEUEMARKER )CLCC_DYNLIB_IMPORT(module, "clEnqueueMarker"); - __clewEnqueueWaitForEvents = (PFNCLENQUEUEWAITFOREVENTS )CLCC_DYNLIB_IMPORT(module, "clEnqueueWaitForEvents"); - __clewEnqueueBarrier = (PFNCLENQUEUEBARRIER )CLCC_DYNLIB_IMPORT(module, "clEnqueueBarrier"); - __clewGetExtensionFunctionAddress = (PFNCLGETEXTENSIONFUNCTIONADDRESS )CLCC_DYNLIB_IMPORT(module, "clGetExtensionFunctionAddress"); + // Determine function entry-points + __clewGetPlatformIDs = (PFNCLGETPLATFORMIDS )CLCC_DYNLIB_IMPORT(module, "clGetPlatformIDs"); + __clewGetPlatformInfo = (PFNCLGETPLATFORMINFO )CLCC_DYNLIB_IMPORT(module, "clGetPlatformInfo"); + __clewGetDeviceIDs = (PFNCLGETDEVICEIDS )CLCC_DYNLIB_IMPORT(module, "clGetDeviceIDs"); + __clewGetDeviceInfo = (PFNCLGETDEVICEINFO )CLCC_DYNLIB_IMPORT(module, "clGetDeviceInfo"); + __clewCreateContext = (PFNCLCREATECONTEXT )CLCC_DYNLIB_IMPORT(module, "clCreateContext"); + __clewCreateContextFromType = (PFNCLCREATECONTEXTFROMTYPE )CLCC_DYNLIB_IMPORT(module, "clCreateContextFromType"); + __clewRetainContext = (PFNCLRETAINCONTEXT )CLCC_DYNLIB_IMPORT(module, "clRetainContext"); + __clewReleaseContext = (PFNCLRELEASECONTEXT )CLCC_DYNLIB_IMPORT(module, "clReleaseContext"); + __clewGetContextInfo = (PFNCLGETCONTEXTINFO )CLCC_DYNLIB_IMPORT(module, "clGetContextInfo"); + __clewCreateCommandQueue = (PFNCLCREATECOMMANDQUEUE )CLCC_DYNLIB_IMPORT(module, "clCreateCommandQueue"); + __clewRetainCommandQueue = (PFNCLRETAINCOMMANDQUEUE )CLCC_DYNLIB_IMPORT(module, "clRetainCommandQueue"); + __clewReleaseCommandQueue = (PFNCLRELEASECOMMANDQUEUE )CLCC_DYNLIB_IMPORT(module, "clReleaseCommandQueue"); + __clewGetCommandQueueInfo = (PFNCLGETCOMMANDQUEUEINFO )CLCC_DYNLIB_IMPORT(module, "clGetCommandQueueInfo"); + __clewSetCommandQueueProperty = (PFNCLSETCOMMANDQUEUEPROPERTY )CLCC_DYNLIB_IMPORT(module, "clSetCommandQueueProperty"); + __clewCreateBuffer = (PFNCLCREATEBUFFER )CLCC_DYNLIB_IMPORT(module, "clCreateBuffer"); + __clewCreateImage2D = (PFNCLCREATEIMAGE2D )CLCC_DYNLIB_IMPORT(module, "clCreateImage2D"); + __clewCreateImage3D = (PFNCLCREATEIMAGE3D )CLCC_DYNLIB_IMPORT(module, "clCreateImage3D"); + __clewRetainMemObject = (PFNCLRETAINMEMOBJECT )CLCC_DYNLIB_IMPORT(module, "clRetainMemObject"); + __clewReleaseMemObject = (PFNCLRELEASEMEMOBJECT )CLCC_DYNLIB_IMPORT(module, "clReleaseMemObject"); + __clewGetSupportedImageFormats = (PFNCLGETSUPPORTEDIMAGEFORMATS )CLCC_DYNLIB_IMPORT(module, "clGetSupportedImageFormats"); + __clewGetMemObjectInfo = (PFNCLGETMEMOBJECTINFO )CLCC_DYNLIB_IMPORT(module, "clGetMemObjectInfo"); + __clewGetImageInfo = (PFNCLGETIMAGEINFO )CLCC_DYNLIB_IMPORT(module, "clGetImageInfo"); + __clewCreateSampler = (PFNCLCREATESAMPLER )CLCC_DYNLIB_IMPORT(module, "clCreateSampler"); + __clewRetainSampler = (PFNCLRETAINSAMPLER )CLCC_DYNLIB_IMPORT(module, "clRetainSampler"); + __clewReleaseSampler = (PFNCLRELEASESAMPLER )CLCC_DYNLIB_IMPORT(module, "clReleaseSampler"); + __clewGetSamplerInfo = (PFNCLGETSAMPLERINFO )CLCC_DYNLIB_IMPORT(module, "clGetSamplerInfo"); + __clewCreateProgramWithSource = (PFNCLCREATEPROGRAMWITHSOURCE )CLCC_DYNLIB_IMPORT(module, "clCreateProgramWithSource"); + __clewCreateProgramWithBinary = (PFNCLCREATEPROGRAMWITHBINARY )CLCC_DYNLIB_IMPORT(module, "clCreateProgramWithBinary"); + __clewRetainProgram = (PFNCLRETAINPROGRAM )CLCC_DYNLIB_IMPORT(module, "clRetainProgram"); + __clewReleaseProgram = (PFNCLRELEASEPROGRAM )CLCC_DYNLIB_IMPORT(module, "clReleaseProgram"); + __clewBuildProgram = (PFNCLBUILDPROGRAM )CLCC_DYNLIB_IMPORT(module, "clBuildProgram"); + __clewUnloadCompiler = (PFNCLUNLOADCOMPILER )CLCC_DYNLIB_IMPORT(module, "clUnloadCompiler"); + __clewGetProgramInfo = (PFNCLGETPROGRAMINFO )CLCC_DYNLIB_IMPORT(module, "clGetProgramInfo"); + __clewGetProgramBuildInfo = (PFNCLGETPROGRAMBUILDINFO )CLCC_DYNLIB_IMPORT(module, "clGetProgramBuildInfo"); + __clewCreateKernel = (PFNCLCREATEKERNEL )CLCC_DYNLIB_IMPORT(module, "clCreateKernel"); + __clewCreateKernelsInProgram = (PFNCLCREATEKERNELSINPROGRAM )CLCC_DYNLIB_IMPORT(module, "clCreateKernelsInProgram"); + __clewRetainKernel = (PFNCLRETAINKERNEL )CLCC_DYNLIB_IMPORT(module, "clRetainKernel"); + __clewReleaseKernel = (PFNCLRELEASEKERNEL )CLCC_DYNLIB_IMPORT(module, "clReleaseKernel"); + __clewSetKernelArg = (PFNCLSETKERNELARG )CLCC_DYNLIB_IMPORT(module, "clSetKernelArg"); + __clewGetKernelInfo = (PFNCLGETKERNELINFO )CLCC_DYNLIB_IMPORT(module, "clGetKernelInfo"); + __clewGetKernelWorkGroupInfo = (PFNCLGETKERNELWORKGROUPINFO )CLCC_DYNLIB_IMPORT(module, "clGetKernelWorkGroupInfo"); + __clewWaitForEvents = (PFNCLWAITFOREVENTS )CLCC_DYNLIB_IMPORT(module, "clWaitForEvents"); + __clewGetEventInfo = (PFNCLGETEVENTINFO )CLCC_DYNLIB_IMPORT(module, "clGetEventInfo"); + __clewRetainEvent = (PFNCLRETAINEVENT )CLCC_DYNLIB_IMPORT(module, "clRetainEvent"); + __clewReleaseEvent = (PFNCLRELEASEEVENT )CLCC_DYNLIB_IMPORT(module, "clReleaseEvent"); + __clewGetEventProfilingInfo = (PFNCLGETEVENTPROFILINGINFO )CLCC_DYNLIB_IMPORT(module, "clGetEventProfilingInfo"); + __clewFlush = (PFNCLFLUSH )CLCC_DYNLIB_IMPORT(module, "clFlush"); + __clewFinish = (PFNCLFINISH )CLCC_DYNLIB_IMPORT(module, "clFinish"); + __clewEnqueueReadBuffer = (PFNCLENQUEUEREADBUFFER )CLCC_DYNLIB_IMPORT(module, "clEnqueueReadBuffer"); + __clewEnqueueWriteBuffer = (PFNCLENQUEUEWRITEBUFFER )CLCC_DYNLIB_IMPORT(module, "clEnqueueWriteBuffer"); + __clewEnqueueCopyBuffer = (PFNCLENQUEUECOPYBUFFER )CLCC_DYNLIB_IMPORT(module, "clEnqueueCopyBuffer"); + __clewEnqueueReadImage = (PFNCLENQUEUEREADIMAGE )CLCC_DYNLIB_IMPORT(module, "clEnqueueReadImage"); + __clewEnqueueWriteImage = (PFNCLENQUEUEWRITEIMAGE )CLCC_DYNLIB_IMPORT(module, "clEnqueueWriteImage"); + __clewEnqueueCopyImage = (PFNCLENQUEUECOPYIMAGE )CLCC_DYNLIB_IMPORT(module, "clEnqueueCopyImage"); + __clewEnqueueCopyImageToBuffer = (PFNCLENQUEUECOPYIMAGETOBUFFER )CLCC_DYNLIB_IMPORT(module, "clEnqueueCopyImageToBuffer"); + __clewEnqueueCopyBufferToImage = (PFNCLENQUEUECOPYBUFFERTOIMAGE )CLCC_DYNLIB_IMPORT(module, "clEnqueueCopyBufferToImage"); + __clewEnqueueMapBuffer = (PFNCLENQUEUEMAPBUFFER )CLCC_DYNLIB_IMPORT(module, "clEnqueueMapBuffer"); + __clewEnqueueMapImage = (PFNCLENQUEUEMAPIMAGE )CLCC_DYNLIB_IMPORT(module, "clEnqueueMapImage"); + __clewEnqueueUnmapMemObject = (PFNCLENQUEUEUNMAPMEMOBJECT )CLCC_DYNLIB_IMPORT(module, "clEnqueueUnmapMemObject"); + __clewEnqueueNDRangeKernel = (PFNCLENQUEUENDRANGEKERNEL )CLCC_DYNLIB_IMPORT(module, "clEnqueueNDRangeKernel"); + __clewEnqueueTask = (PFNCLENQUEUETASK )CLCC_DYNLIB_IMPORT(module, "clEnqueueTask"); + __clewEnqueueNativeKernel = (PFNCLENQUEUENATIVEKERNEL )CLCC_DYNLIB_IMPORT(module, "clEnqueueNativeKernel"); + __clewEnqueueMarker = (PFNCLENQUEUEMARKER )CLCC_DYNLIB_IMPORT(module, "clEnqueueMarker"); + __clewEnqueueWaitForEvents = (PFNCLENQUEUEWAITFOREVENTS )CLCC_DYNLIB_IMPORT(module, "clEnqueueWaitForEvents"); + __clewEnqueueBarrier = (PFNCLENQUEUEBARRIER )CLCC_DYNLIB_IMPORT(module, "clEnqueueBarrier"); + __clewGetExtensionFunctionAddress = (PFNCLGETEXTENSIONFUNCTIONADDRESS )CLCC_DYNLIB_IMPORT(module, "clGetExtensionFunctionAddress"); if(__clewGetPlatformIDs == NULL) return 0; - return 1; + return 1; } //! \param error CL error code //! \return a string representation of the error code const char *clErrorString(cl_int error) { - static const char* strings[] = - { - // Error Codes - "CL_SUCCESS" // 0 - , "CL_DEVICE_NOT_FOUND" // -1 - , "CL_DEVICE_NOT_AVAILABLE" // -2 - , "CL_COMPILER_NOT_AVAILABLE" // -3 - , "CL_MEM_OBJECT_ALLOCATION_FAILURE" // -4 - , "CL_OUT_OF_RESOURCES" // -5 - , "CL_OUT_OF_HOST_MEMORY" // -6 - , "CL_PROFILING_INFO_NOT_AVAILABLE" // -7 - , "CL_MEM_COPY_OVERLAP" // -8 - , "CL_IMAGE_FORMAT_MISMATCH" // -9 - , "CL_IMAGE_FORMAT_NOT_SUPPORTED" // -10 - , "CL_BUILD_PROGRAM_FAILURE" // -11 - , "CL_MAP_FAILURE" // -12 + static const char* strings[] = + { + // Error Codes + "CL_SUCCESS" // 0 + , "CL_DEVICE_NOT_FOUND" // -1 + , "CL_DEVICE_NOT_AVAILABLE" // -2 + , "CL_COMPILER_NOT_AVAILABLE" // -3 + , "CL_MEM_OBJECT_ALLOCATION_FAILURE" // -4 + , "CL_OUT_OF_RESOURCES" // -5 + , "CL_OUT_OF_HOST_MEMORY" // -6 + , "CL_PROFILING_INFO_NOT_AVAILABLE" // -7 + , "CL_MEM_COPY_OVERLAP" // -8 + , "CL_IMAGE_FORMAT_MISMATCH" // -9 + , "CL_IMAGE_FORMAT_NOT_SUPPORTED" // -10 + , "CL_BUILD_PROGRAM_FAILURE" // -11 + , "CL_MAP_FAILURE" // -12 - , "" // -13 - , "" // -14 - , "" // -15 - , "" // -16 - , "" // -17 - , "" // -18 - , "" // -19 + , "" // -13 + , "" // -14 + , "" // -15 + , "" // -16 + , "" // -17 + , "" // -18 + , "" // -19 - , "" // -20 - , "" // -21 - , "" // -22 - , "" // -23 - , "" // -24 - , "" // -25 - , "" // -26 - , "" // -27 - , "" // -28 - , "" // -29 + , "" // -20 + , "" // -21 + , "" // -22 + , "" // -23 + , "" // -24 + , "" // -25 + , "" // -26 + , "" // -27 + , "" // -28 + , "" // -29 - , "CL_INVALID_VALUE" // -30 - , "CL_INVALID_DEVICE_TYPE" // -31 - , "CL_INVALID_PLATFORM" // -32 - , "CL_INVALID_DEVICE" // -33 - , "CL_INVALID_CONTEXT" // -34 - , "CL_INVALID_QUEUE_PROPERTIES" // -35 - , "CL_INVALID_COMMAND_QUEUE" // -36 - , "CL_INVALID_HOST_PTR" // -37 - , "CL_INVALID_MEM_OBJECT" // -38 - , "CL_INVALID_IMAGE_FORMAT_DESCRIPTOR" // -39 - , "CL_INVALID_IMAGE_SIZE" // -40 - , "CL_INVALID_SAMPLER" // -41 - , "CL_INVALID_BINARY" // -42 - , "CL_INVALID_BUILD_OPTIONS" // -43 - , "CL_INVALID_PROGRAM" // -44 - , "CL_INVALID_PROGRAM_EXECUTABLE" // -45 - , "CL_INVALID_KERNEL_NAME" // -46 - , "CL_INVALID_KERNEL_DEFINITION" // -47 - , "CL_INVALID_KERNEL" // -48 - , "CL_INVALID_ARG_INDEX" // -49 - , "CL_INVALID_ARG_VALUE" // -50 - , "CL_INVALID_ARG_SIZE" // -51 - , "CL_INVALID_KERNEL_ARGS" // -52 - , "CL_INVALID_WORK_DIMENSION" // -53 - , "CL_INVALID_WORK_GROUP_SIZE" // -54 - , "CL_INVALID_WORK_ITEM_SIZE" // -55 - , "CL_INVALID_GLOBAL_OFFSET" // -56 - , "CL_INVALID_EVENT_WAIT_LIST" // -57 - , "CL_INVALID_EVENT" // -58 - , "CL_INVALID_OPERATION" // -59 - , "CL_INVALID_GL_OBJECT" // -60 - , "CL_INVALID_BUFFER_SIZE" // -61 - , "CL_INVALID_MIP_LEVEL" // -62 - , "CL_INVALID_GLOBAL_WORK_SIZE" // -63 - }; + , "CL_INVALID_VALUE" // -30 + , "CL_INVALID_DEVICE_TYPE" // -31 + , "CL_INVALID_PLATFORM" // -32 + , "CL_INVALID_DEVICE" // -33 + , "CL_INVALID_CONTEXT" // -34 + , "CL_INVALID_QUEUE_PROPERTIES" // -35 + , "CL_INVALID_COMMAND_QUEUE" // -36 + , "CL_INVALID_HOST_PTR" // -37 + , "CL_INVALID_MEM_OBJECT" // -38 + , "CL_INVALID_IMAGE_FORMAT_DESCRIPTOR" // -39 + , "CL_INVALID_IMAGE_SIZE" // -40 + , "CL_INVALID_SAMPLER" // -41 + , "CL_INVALID_BINARY" // -42 + , "CL_INVALID_BUILD_OPTIONS" // -43 + , "CL_INVALID_PROGRAM" // -44 + , "CL_INVALID_PROGRAM_EXECUTABLE" // -45 + , "CL_INVALID_KERNEL_NAME" // -46 + , "CL_INVALID_KERNEL_DEFINITION" // -47 + , "CL_INVALID_KERNEL" // -48 + , "CL_INVALID_ARG_INDEX" // -49 + , "CL_INVALID_ARG_VALUE" // -50 + , "CL_INVALID_ARG_SIZE" // -51 + , "CL_INVALID_KERNEL_ARGS" // -52 + , "CL_INVALID_WORK_DIMENSION" // -53 + , "CL_INVALID_WORK_GROUP_SIZE" // -54 + , "CL_INVALID_WORK_ITEM_SIZE" // -55 + , "CL_INVALID_GLOBAL_OFFSET" // -56 + , "CL_INVALID_EVENT_WAIT_LIST" // -57 + , "CL_INVALID_EVENT" // -58 + , "CL_INVALID_OPERATION" // -59 + , "CL_INVALID_GL_OBJECT" // -60 + , "CL_INVALID_BUFFER_SIZE" // -61 + , "CL_INVALID_MIP_LEVEL" // -62 + , "CL_INVALID_GLOBAL_WORK_SIZE" // -63 + }; - return strings[-error]; + return strings[-error]; } CCL_NAMESPACE_END diff --git a/intern/cycles/util/util_opencl.h b/intern/cycles/util/util_opencl.h index 2e97097ef36..5f3f1667bcc 100644 --- a/intern/cycles/util/util_opencl.h +++ b/intern/cycles/util/util_opencl.h @@ -36,27 +36,27 @@ CCL_NAMESPACE_BEGIN #endif // CLCC_GENERATE_DOCUMENTATION /******************************************************************************* -* Copyright (c) 2008-2009 The Khronos Group Inc. -* -* Permission is hereby granted, free of charge, to any person obtaining a -* copy of this software and/or associated documentation files (the -* "Materials"), to deal in the Materials without restriction, including -* without limitation the rights to use, copy, modify, merge, publish, -* distribute, sublicense, and/or sell copies of the Materials, and to -* permit persons to whom the Materials are furnished to do so, subject to -* the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Materials. -* -* THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. -******************************************************************************/ + * Copyright (c) 2008-2009 The Khronos Group Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and/or associated documentation files (the + * "Materials"), to deal in the Materials without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Materials, and to + * permit persons to whom the Materials are furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Materials. + * + * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. + ******************************************************************************/ #ifndef CLCC_GENERATE_DOCUMENTATION @@ -88,20 +88,20 @@ typedef double cl_double; /* -* Vector types -* -* Note: OpenCL requires that all types be naturally aligned. -* This means that vector types must be naturally aligned. -* For example, a vector of four floats must be aligned to -* a 16 byte boundary (calculated as 4 * the natural 4-byte -* alignment of the float). The alignment qualifiers here -* will only function properly if your compiler supports them -* and if you don't actively work to defeat them. For example, -* in order for a cl_float4 to be 16 byte aligned in a struct, -* the start of the struct must itself be 16-byte aligned. -* -* Maintaining proper alignment is the user's responsibility. -*/ + * Vector types + * + * Note: OpenCL requires that all types be naturally aligned. + * This means that vector types must be naturally aligned. + * For example, a vector of four floats must be aligned to + * a 16 byte boundary (calculated as 4 * the natural 4-byte + * alignment of the float). The alignment qualifiers here + * will only function properly if your compiler supports them + * and if you don't actively work to defeat them. For example, + * in order for a cl_float4 to be 16 byte aligned in a struct, + * the start of the struct must itself be 16-byte aligned. + * + * Maintaining proper alignment is the user's responsibility. + */ typedef signed __int8 cl_char2[2]; typedef signed __int8 cl_char4[4]; typedef signed __int8 cl_char8[8]; @@ -168,20 +168,20 @@ typedef float cl_float __attribute__((aligned(4))); typedef double cl_double __attribute__((aligned(8))); /* -* Vector types -* -* Note: OpenCL requires that all types be naturally aligned. -* This means that vector types must be naturally aligned. -* For example, a vector of four floats must be aligned to -* a 16 byte boundary (calculated as 4 * the natural 4-byte -* alignment of the float). The alignment qualifiers here -* will only function properly if your compiler supports them -* and if you don't actively work to defeat them. For example, -* in order for a cl_float4 to be 16 byte aligned in a struct, -* the start of the struct must itself be 16-byte aligned. -* -* Maintaining proper alignment is the user's responsibility. -*/ + * Vector types + * + * Note: OpenCL requires that all types be naturally aligned. + * This means that vector types must be naturally aligned. + * For example, a vector of four floats must be aligned to + * a 16 byte boundary (calculated as 4 * the natural 4-byte + * alignment of the float). The alignment qualifiers here + * will only function properly if your compiler supports them + * and if you don't actively work to defeat them. For example, + * in order for a cl_float4 to be 16 byte aligned in a struct, + * the start of the struct must itself be 16-byte aligned. + * + * Maintaining proper alignment is the user's responsibility. + */ typedef int8_t cl_char2[2] __attribute__((aligned(2))); typedef int8_t cl_char4[4] __attribute__((aligned(4))); typedef int8_t cl_char8[8] __attribute__((aligned(8))); @@ -339,8 +339,8 @@ typedef cl_uint cl_command_type; typedef cl_uint cl_profiling_info; typedef struct _cl_image_format { - cl_channel_order image_channel_order; - cl_channel_type image_channel_data_type; + cl_channel_order image_channel_order; + cl_channel_type image_channel_data_type; } cl_image_format; diff --git a/intern/cycles/util/util_path.cpp b/intern/cycles/util/util_path.cpp index 69069a3bbce..717aa34c426 100644 --- a/intern/cycles/util/util_path.cpp +++ b/intern/cycles/util/util_path.cpp @@ -179,8 +179,8 @@ static bool path_read_text(const string& path, string& text) string path_source_replace_includes(const string& source_, const string& path) { /* our own little c preprocessor that replaces #includes with the file - contents, to work around issue of opencl drivers not supporting - include paths with spaces in them */ + * contents, to work around issue of opencl drivers not supporting + * include paths with spaces in them */ string source = source_; const string include = "#include \""; size_t n, pos = 0; diff --git a/intern/cycles/util/util_system.cpp b/intern/cycles/util/util_system.cpp index e8c81e57654..2d9f0fffae6 100644 --- a/intern/cycles/util/util_system.cpp +++ b/intern/cycles/util/util_system.cpp @@ -149,10 +149,12 @@ bool system_cpu_support_optimized() __cpuid(result, 0); num = result[0]; - /*__cpuid(result, 0x80000000); - num_ex = result[0];*/ +#if 0 + __cpuid(result, 0x80000000); + num_ex = result[0]; +#endif - if(num >= 1){ + if(num >= 1) { __cpuid(result, 0x00000001); caps.mmx = (result[3] & ((int)1 << 23)) != 0; caps.sse = (result[3] & ((int)1 << 25)) != 0; @@ -167,13 +169,15 @@ bool system_cpu_support_optimized() caps.fma3 = (result[2] & ((int)1 << 12)) != 0; } - /*if(num_ex >= 0x80000001){ +#if 0 + if(num_ex >= 0x80000001) { __cpuid(result, 0x80000001); caps.x64 = (result[3] & ((int)1 << 29)) != 0; caps.sse4a = (result[2] & ((int)1 << 6)) != 0; caps.fma4 = (result[2] & ((int)1 << 16)) != 0; caps.xop = (result[2] & ((int)1 << 11)) != 0; - }*/ + } +#endif caps_init = true; } diff --git a/intern/cycles/util/util_task.cpp b/intern/cycles/util/util_task.cpp index 023630e8fae..ea0abd6f54f 100644 --- a/intern/cycles/util/util_task.cpp +++ b/intern/cycles/util/util_task.cpp @@ -164,7 +164,7 @@ void TaskScheduler::init(int num_threads) thread_scoped_lock lock(mutex); /* multiple cycles instances can use this task scheduler, sharing the same - threads, so we keep track of the number of users. */ + * threads, so we keep track of the number of users. */ if(users == 0) { do_exit = false; diff --git a/intern/cycles/util/util_thread.h b/intern/cycles/util/util_thread.h index 008f68e69e8..9bea4e7808a 100644 --- a/intern/cycles/util/util_thread.h +++ b/intern/cycles/util/util_thread.h @@ -34,7 +34,7 @@ typedef boost::mutex::scoped_lock thread_scoped_lock; typedef boost::condition_variable thread_condition_variable; /* own pthread based implementation, to avoid boost version conflicts with - dynamically loaded blender plugins */ + * dynamically loaded blender plugins */ class thread { public: diff --git a/intern/cycles/util/util_transform.cpp b/intern/cycles/util/util_transform.cpp index 1780994da27..b3c6506dfa0 100644 --- a/intern/cycles/util/util_transform.cpp +++ b/intern/cycles/util/util_transform.cpp @@ -139,7 +139,7 @@ Transform transform_inverse(const Transform& tfm) if(!transform_matrix4_gj_inverse(R, M)) { /* matrix is degenerate (e.g. 0 scale on some axis), ideally we should - never be in this situation, but try to invert it anyway with tweak */ + * never be in this situation, but try to invert it anyway with tweak */ M[0][0] += 1e-8f; M[1][1] += 1e-8f; M[2][2] += 1e-8f; @@ -160,15 +160,15 @@ static float4 transform_to_quat(const Transform& tfm) double trace = tfm[0][0] + tfm[1][1] + tfm[2][2]; float4 qt; - if(trace > 0.0f) { + if(trace > 0.0) { double s = sqrt(trace + 1.0); qt.w = (float)(s/2.0); s = 0.5/s; - qt.x = (float)((tfm[2][1] - tfm[1][2]) * s); - qt.y = (float)((tfm[0][2] - tfm[2][0]) * s); - qt.z = (float)((tfm[1][0] - tfm[0][1]) * s); + qt.x = (float)((double)(tfm[2][1] - tfm[1][2]) * s); + qt.y = (float)((double)(tfm[0][2] - tfm[2][0]) * s); + qt.z = (float)((double)(tfm[1][0] - tfm[0][1]) * s); } else { int i = 0; @@ -181,16 +181,16 @@ static float4 transform_to_quat(const Transform& tfm) int j = (i + 1)%3; int k = (j + 1)%3; - double s = sqrt((tfm[i][i] - (tfm[j][j] + tfm[k][k])) + 1.0); + double s = sqrt((double)(tfm[i][i] - (tfm[j][j] + tfm[k][k])) + 1.0); double q[3]; q[i] = s * 0.5; if(s != 0.0) s = 0.5/s; - double w = (tfm[k][j] - tfm[j][k]) * s; - q[j] = (tfm[j][i] + tfm[i][j]) * s; - q[k] = (tfm[k][i] + tfm[i][k]) * s; + double w = (double)(tfm[k][j] - tfm[j][k]) * s; + q[j] = (double)(tfm[j][i] + tfm[i][j]) * s; + q[k] = (double)(tfm[k][i] + tfm[i][k]) * s; qt.x = (float)q[0]; qt.y = (float)q[1]; diff --git a/intern/cycles/util/util_transform.h b/intern/cycles/util/util_transform.h index b460c4c87a2..d93bbff5415 100644 --- a/intern/cycles/util/util_transform.h +++ b/intern/cycles/util/util_transform.h @@ -255,7 +255,7 @@ Transform transform_inverse(const Transform& a); __device_inline bool transform_uniform_scale(const Transform& tfm, float& scale) { /* the epsilon here is quite arbitrary, but this function is only used for - surface area and bump, where we except it to not be so sensitive */ + * surface area and bump, where we except it to not be so sensitive */ Transform ttfm = transform_transpose(tfm); float eps = 1e-6f; diff --git a/intern/cycles/util/util_view.cpp b/intern/cycles/util/util_view.cpp index 0b311b0331a..328c0c97391 100644 --- a/intern/cycles/util/util_view.cpp +++ b/intern/cycles/util/util_view.cpp @@ -55,7 +55,7 @@ static void view_display_text(int x, int y, const char *text) glRasterPos3f(x, y, 0); - for(c=text; *c != '\0'; c++) + for(c = text; *c != '\0'; c++) glutBitmapCharacter(GLUT_BITMAP_HELVETICA_10, *c); } diff --git a/intern/ghost/GHOST_Types.h b/intern/ghost/GHOST_Types.h index 7614cb80e00..8454f338645 100644 --- a/intern/ghost/GHOST_Types.h +++ b/intern/ghost/GHOST_Types.h @@ -56,8 +56,7 @@ typedef unsigned long long GHOST_TUns64; typedef void *GHOST_TUserDataPtr; -typedef enum -{ +typedef enum { GHOST_kFailure = 0, GHOST_kSuccess } GHOST_TSuccess; diff --git a/intern/ghost/intern/GHOST_DisplayManagerNULL.h b/intern/ghost/intern/GHOST_DisplayManagerNULL.h index eb116e30d2d..4d5a0b008dc 100644 --- a/intern/ghost/intern/GHOST_DisplayManagerNULL.h +++ b/intern/ghost/intern/GHOST_DisplayManagerNULL.h @@ -41,7 +41,7 @@ public: GHOST_TSuccess getNumDisplaySettings( GHOST_TUns8 display, GHOST_TInt32& numSettings ) const{ return GHOST_kFailure; } GHOST_TSuccess getDisplaySetting( GHOST_TUns8 display, GHOST_TInt32 index, GHOST_DisplaySetting& setting ) const { return GHOST_kFailure; } GHOST_TSuccess getCurrentDisplaySetting( GHOST_TUns8 display, GHOST_DisplaySetting& setting ) const { return getDisplaySetting(display,GHOST_TInt32(0),setting); } - GHOST_TSuccess setCurrentDisplaySetting( GHOST_TUns8 display, const GHOST_DisplaySetting& setting ){ return GHOST_kSuccess; } + GHOST_TSuccess setCurrentDisplaySetting( GHOST_TUns8 display, const GHOST_DisplaySetting& setting ) { return GHOST_kSuccess; } private: GHOST_SystemNULL * m_system; diff --git a/intern/ghost/intern/GHOST_WindowNULL.h b/intern/ghost/intern/GHOST_WindowNULL.h index cde2cb0ba76..dcbb7d2b346 100644 --- a/intern/ghost/intern/GHOST_WindowNULL.h +++ b/intern/ghost/intern/GHOST_WindowNULL.h @@ -60,27 +60,27 @@ public: } protected: - GHOST_TSuccess installDrawingContext( GHOST_TDrawingContextType type ){ return GHOST_kSuccess; } - GHOST_TSuccess removeDrawingContext( ){ return GHOST_kSuccess; } - GHOST_TSuccess setWindowCursorGrab( GHOST_TGrabCursorMode mode ){ return GHOST_kSuccess; } - GHOST_TSuccess setWindowCursorShape( GHOST_TStandardCursor shape ){ return GHOST_kSuccess; } + GHOST_TSuccess installDrawingContext( GHOST_TDrawingContextType type ) { return GHOST_kSuccess; } + GHOST_TSuccess removeDrawingContext( ) { return GHOST_kSuccess; } + GHOST_TSuccess setWindowCursorGrab( GHOST_TGrabCursorMode mode ) { return GHOST_kSuccess; } + GHOST_TSuccess setWindowCursorShape( GHOST_TStandardCursor shape ) { return GHOST_kSuccess; } GHOST_TSuccess setWindowCustomCursorShape( GHOST_TUns8 bitmap[16][2], GHOST_TUns8 mask[16][2], int hotX, int hotY ) { return GHOST_kSuccess; } - GHOST_TSuccess setWindowCustomCursorShape( GHOST_TUns8 *bitmap, GHOST_TUns8 *mask, int sizex, int sizey, int hotX, int hotY, int fg_color, int bg_color ){ return GHOST_kSuccess; } + GHOST_TSuccess setWindowCustomCursorShape( GHOST_TUns8 *bitmap, GHOST_TUns8 *mask, int sizex, int sizey, int hotX, int hotY, int fg_color, int bg_color ) { return GHOST_kSuccess; } bool getValid( ) const { return true; } - void setTitle( const STR_String& title ){ /* nothing */ } + void setTitle( const STR_String& title ) { /* nothing */ } void getTitle( STR_String& title ) const { title= "untitled"; } void getWindowBounds( GHOST_Rect& bounds ) const { getClientBounds(bounds); } void getClientBounds( GHOST_Rect& bounds ) const { /* nothing */ } - GHOST_TSuccess setClientWidth( GHOST_TUns32 width ){ return GHOST_kFailure; } - GHOST_TSuccess setClientHeight( GHOST_TUns32 height ){ return GHOST_kFailure; } - GHOST_TSuccess setClientSize( GHOST_TUns32 width, GHOST_TUns32 height ){ return GHOST_kFailure; } + GHOST_TSuccess setClientWidth( GHOST_TUns32 width ) { return GHOST_kFailure; } + GHOST_TSuccess setClientHeight( GHOST_TUns32 height ) { return GHOST_kFailure; } + GHOST_TSuccess setClientSize( GHOST_TUns32 width, GHOST_TUns32 height ) { return GHOST_kFailure; } void screenToClient( GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY ) const { outX = inX; outY = inY; } void clientToScreen( GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY ) const { outX = inX; outY = inY; } - GHOST_TSuccess swapBuffers( ){ return GHOST_kFailure; } - GHOST_TSuccess activateDrawingContext( ){ return GHOST_kFailure; } - ~GHOST_WindowNULL( ){ /* nothing */ } - GHOST_TSuccess setWindowCursorVisibility( bool visible ){ return GHOST_kSuccess; } + GHOST_TSuccess swapBuffers( ) { return GHOST_kFailure; } + GHOST_TSuccess activateDrawingContext( ) { return GHOST_kFailure; } + ~GHOST_WindowNULL( ) { /* nothing */ } + GHOST_TSuccess setWindowCursorVisibility( bool visible ) { return GHOST_kSuccess; } GHOST_TSuccess setState(GHOST_TWindowState state) { return GHOST_kSuccess; } GHOST_TWindowState getState() const { return GHOST_kWindowStateNormal; } GHOST_TSuccess invalidate() { return GHOST_kSuccess; } diff --git a/intern/ghost/test/multitest/EventToBuf.c b/intern/ghost/test/multitest/EventToBuf.c index f988f0fb86a..034fbe04447 100644 --- a/intern/ghost/test/multitest/EventToBuf.c +++ b/intern/ghost/test/multitest/EventToBuf.c @@ -36,7 +36,7 @@ char *eventtype_to_string(GHOST_TEventType type) { - switch(type) { + switch (type) { case GHOST_kEventCursorMove: return "CursorMove"; case GHOST_kEventButtonDown: return "ButtonDown"; case GHOST_kEventButtonUp: return "ButtonUp"; diff --git a/intern/guardedalloc/intern/mallocn.c b/intern/guardedalloc/intern/mallocn.c index cad0e549060..f1a83583715 100644 --- a/intern/guardedalloc/intern/mallocn.c +++ b/intern/guardedalloc/intern/mallocn.c @@ -290,7 +290,9 @@ static void make_memhead_header(MemHead *memh, size_t len, const char *str) memt->tag3 = MEMTAG3; addtail(membase, &memh->next); - if (memh->next) memh->nextname = MEMNEXT(memh->next)->name; + if (memh->next) { + memh->nextname = MEMNEXT(memh->next)->name; + } totblock++; mem_in_use += len; @@ -681,8 +683,12 @@ static void addtail(volatile localListBase *listbase, void *vlink) { struct localLink *link = vlink; + /* for a generic API error checks here is fine but + * the limited use here they will never be NULL */ +#if 0 if (link == NULL) return; if (listbase == NULL) return; +#endif link->next = NULL; link->prev = listbase->last; @@ -696,8 +702,12 @@ static void remlink(volatile localListBase *listbase, void *vlink) { struct localLink *link = vlink; + /* for a generic API error checks here is fine but + * the limited use here they will never be NULL */ +#if 0 if (link == NULL) return; if (listbase == NULL) return; +#endif if (link->next) link->next->prev = link->prev; if (link->prev) link->prev->next = link->next; diff --git a/intern/itasc/Armature.cpp b/intern/itasc/Armature.cpp index 916b0bc7bf3..1dacb8bc184 100644 --- a/intern/itasc/Armature.cpp +++ b/intern/itasc/Armature.cpp @@ -158,7 +158,7 @@ void Armature::pushQ(CacheTS timestamp) { if (m_qCCh >= 0) { // try to keep the cache if the joints are the same - m_cache->addCacheVectorIfDifferent(this, m_qCCh, timestamp, &m_qKdl(0), m_qKdl.rows(), KDL::epsilon); + m_cache->addCacheVectorIfDifferent(this, m_qCCh, timestamp, m_qKdl(0), m_qKdl.rows(), KDL::epsilon); m_qCTs = timestamp; } } @@ -170,8 +170,8 @@ bool Armature::popQ(CacheTS timestamp) double* item; item = (double*)m_cache->getPreviousCacheItem(this, m_qCCh, ×tamp); if (item && m_qCTs != timestamp) { - double& q = m_qKdl(0); - memcpy(&q, item, m_qKdl.rows()*sizeof(q)); + double* q = m_qKdl(0); + memcpy(q, item, m_qKdl.rows()*sizeof(double)); m_qCTs = timestamp; // changing the joint => recompute the jacobian updateJacobian(); @@ -255,7 +255,7 @@ bool Armature::getSegment(const std::string& name, const unsigned int q_size, co p_tip = &sit->second.segment.getFrameToTip(); for (unsigned int dof=0; dof<p_joint->getNDof(); dof++) { (&q_rest)[dof] = m_joints[sit->second.q_nr+dof].rest; - (&q)[dof] = m_qKdl(sit->second.q_nr+dof); + (&q)[dof] = m_qKdl[sit->second.q_nr+dof]; } return true; } @@ -267,7 +267,7 @@ double Armature::getMaxJointChange() double maxJoint = 0.0; for (unsigned int i=0; i<m_njoint; i++) { // this is a very rough calculation, it doesn't work well for spherical joint - double joint = fabs(m_oldqKdl(i)-m_qKdl(i)); + double joint = fabs(m_oldqKdl[i]-m_qKdl[i]); if (maxJoint < joint) maxJoint = joint; } @@ -369,11 +369,13 @@ int Armature::addEndEffector(const std::string& name) return m_neffector++; } -void Armature::finalize() +bool Armature::finalize() { unsigned int i, j, c; if (m_finalized) - return; + return true; + if (m_njoint == 0) + return false; initialize(m_njoint, m_noutput, m_neffector); for (i=c=0; i<m_nconstraint; i++) { JointConstraint_struct* pConstraint = m_constraints[i]; @@ -390,7 +392,7 @@ void Armature::finalize() m_newqKdl.resize(m_njoint); m_qdotKdl.resize(m_njoint); for (i=0; i<m_njoint; i++) { - m_newqKdl(i) = m_oldqKdl(i) = m_qKdl(i) = m_joints[i].rest; + m_newqKdl[i] = m_oldqKdl[i] = m_qKdl[i] = m_joints[i].rest; } updateJacobian(); // estimate the maximum size of the robot arms @@ -410,6 +412,7 @@ void Armature::finalize() if (m_armlength < KDL::epsilon) m_armlength = KDL::epsilon; m_finalized = true; + return true; } void Armature::pushCache(const Timestamp& timestamp) @@ -444,15 +447,15 @@ bool Armature::updateJoint(const Timestamp& timestamp, JointLockCallback& callba // integration and joint limit // for spherical joint we must use a more sophisticated method unsigned int q_nr; - double* qdot=&m_qdotKdl(0); - double* q=&m_qKdl(0); - double* newq=&m_newqKdl(0); + double* qdot=m_qdotKdl(0); + double* q=m_qKdl(0); + double* newq=m_newqKdl(0); double norm, qx, qz, CX, CZ, sx, sz; bool locked = false; int unlocked = 0; for (q_nr=0; q_nr<m_nq; ++q_nr) - m_qdotKdl(q_nr)=m_qdot(q_nr); + qdot[q_nr]=m_qdot[q_nr]; for (q_nr=0; q_nr<m_nq; ) { Joint_struct* joint = &m_joints[q_nr]; @@ -621,7 +624,7 @@ void Armature::updateKinematics(const Timestamp& timestamp){ return; // the new joint value have been computed already, just copy - memcpy(&m_qKdl(0), &m_newqKdl(0), sizeof(double)*m_qKdl.rows()); + memcpy(m_qKdl(0), m_newqKdl(0), sizeof(double)*m_qKdl.rows()); pushCache(timestamp); updateJacobian(); // here update the desired output. @@ -674,7 +677,7 @@ void Armature::updateControlOutput(const Timestamp& timestamp) if (!timestamp.substep) { // save previous joint state for getMaxJointChange() - memcpy(&m_oldqKdl(0), &m_qKdl(0), sizeof(double)*m_qKdl.rows()); + memcpy(m_oldqKdl(0), m_qKdl(0), sizeof(double)*m_qKdl.rows()); for (unsigned int i=0; i<m_neffector; i++) { m_effectors[i].oldpose = m_effectors[i].pose; } @@ -693,8 +696,8 @@ void Armature::updateControlOutput(const Timestamp& timestamp) JointConstraint_struct* pConstraint = *it; unsigned int nr, i; for (i=0, nr = pConstraint->segment->second.q_nr; i<pConstraint->v_nr; i++, nr++) { - *(double*)&pConstraint->value[i].y = m_qKdl(nr); - *(double*)&pConstraint->value[i].ydot = m_qdotKdl(nr); + *(double*)&pConstraint->value[i].y = m_qKdl[nr]; + *(double*)&pConstraint->value[i].ydot = m_qdotKdl[nr]; } if (pConstraint->function && (pConstraint->substep || (!timestamp.reiterate && !timestamp.substep))) { (*pConstraint->function)(timestamp, pConstraint->values, pConstraint->v_nr, pConstraint->param); diff --git a/intern/itasc/Armature.hpp b/intern/itasc/Armature.hpp index 0f4abeab4f0..63d1899f4e9 100644 --- a/intern/itasc/Armature.hpp +++ b/intern/itasc/Armature.hpp @@ -31,7 +31,7 @@ public: bool getSegment(const std::string& segment_name, const unsigned int q_size, const Joint* &p_joint, double &q_rest, double &q, const Frame* &p_tip); bool getRelativeFrame(Frame& result, const std::string& segment_name, const std::string& base_name=m_root); - virtual void finalize(); + virtual bool finalize(); virtual int addEndEffector(const std::string& name); virtual const Frame& getPose(const unsigned int end_effector); diff --git a/intern/itasc/CMakeLists.txt b/intern/itasc/CMakeLists.txt index 3d24a0cb8c6..f4bc0326ea1 100644 --- a/intern/itasc/CMakeLists.txt +++ b/intern/itasc/CMakeLists.txt @@ -318,8 +318,5 @@ set(SRC ../../extern/Eigen3/Eigen/src/Cholesky/LLT.h ) -if(WIN32) - add_definitions(-DEIGEN_DONT_ALIGN_STATICALLY) -endif() blender_add_lib(bf_intern_itasc "${SRC}" "${INC}" "${INC_SYS}") diff --git a/intern/itasc/Distance.cpp b/intern/itasc/Distance.cpp index 7cf04367a4e..c9efca101e3 100644 --- a/intern/itasc/Distance.cpp +++ b/intern/itasc/Distance.cpp @@ -189,7 +189,7 @@ void Distance::updateKinematics(const Timestamp& timestamp) void Distance::updateJacobian() { for(unsigned int i=0;i<6;i++) - m_chiKdl(i)=m_chi(i); + m_chiKdl[i]=m_chi[i]; m_fksolver->JntToCart(m_chiKdl,m_internalPose); m_jacsolver->JntToJac(m_chiKdl,m_jac); diff --git a/intern/itasc/FixedObject.cpp b/intern/itasc/FixedObject.cpp index 9dc4d69878a..2a1e66f9c6f 100644 --- a/intern/itasc/FixedObject.cpp +++ b/intern/itasc/FixedObject.cpp @@ -53,12 +53,13 @@ int FixedObject::addEndEffector(const std::string& name) return -1; } -void FixedObject::finalize() +bool FixedObject::finalize() { if (m_finalized) - return; + return true; initialize(0, m_nframe); m_finalized = true; + return true; } const Frame& FixedObject::getPose(const unsigned int frameIndex) diff --git a/intern/itasc/FixedObject.hpp b/intern/itasc/FixedObject.hpp index b4279d9adcb..ad26e7cb2d6 100644 --- a/intern/itasc/FixedObject.hpp +++ b/intern/itasc/FixedObject.hpp @@ -23,7 +23,7 @@ public: virtual void updateCoordinates(const Timestamp& timestamp) {}; virtual int addEndEffector(const std::string& name); - virtual void finalize(); + virtual bool finalize(); virtual const Frame& getPose(const unsigned int frameIndex); virtual void updateKinematics(const Timestamp& timestamp) {}; virtual void pushCache(const Timestamp& timestamp) {}; diff --git a/intern/itasc/MovingFrame.cpp b/intern/itasc/MovingFrame.cpp index 3b0ee7842ca..90ebe091eb5 100644 --- a/intern/itasc/MovingFrame.cpp +++ b/intern/itasc/MovingFrame.cpp @@ -27,9 +27,10 @@ MovingFrame::~MovingFrame() { } -void MovingFrame::finalize() +bool MovingFrame::finalize() { updateJacobian(); + return true; } void MovingFrame::initCache(Cache *_cache) diff --git a/intern/itasc/MovingFrame.hpp b/intern/itasc/MovingFrame.hpp index 21cb344980a..d2a956d7312 100644 --- a/intern/itasc/MovingFrame.hpp +++ b/intern/itasc/MovingFrame.hpp @@ -28,7 +28,7 @@ public: virtual void updateKinematics(const Timestamp& timestamp); virtual void pushCache(const Timestamp& timestamp); virtual void initCache(Cache *_cache); - virtual void finalize(); + virtual bool finalize(); protected: virtual void updateJacobian(); diff --git a/intern/itasc/Object.hpp b/intern/itasc/Object.hpp index 5aa4346fc4b..bf80d83e5aa 100644 --- a/intern/itasc/Object.hpp +++ b/intern/itasc/Object.hpp @@ -33,7 +33,7 @@ public: virtual ~Object(){}; virtual int addEndEffector(const std::string& name){return 0;}; - virtual void finalize(){}; + virtual bool finalize(){return true;}; virtual const KDL::Frame& getPose(const unsigned int end_effector=0){return m_internalPose;}; virtual const ObjectType getType(){return m_type;}; virtual const unsigned int getNrOfCoordinates(){return 0;}; diff --git a/intern/itasc/SConscript b/intern/itasc/SConscript index 69dddf40228..c1ad931c665 100644 --- a/intern/itasc/SConscript +++ b/intern/itasc/SConscript @@ -9,8 +9,5 @@ incs = '. ../../extern/Eigen3' defs = [] -if env['PLATFORM'] == 'win32': - defs.append('EIGEN_DONT_ALIGN_STATICALLY') - env.BlenderLib ('bf_intern_itasc', sources, Split(incs), defs, libtype=['intern','player'], priority=[20,100] ) diff --git a/intern/itasc/Scene.cpp b/intern/itasc/Scene.cpp index 16f8551bfc7..877cd883208 100644 --- a/intern/itasc/Scene.cpp +++ b/intern/itasc/Scene.cpp @@ -91,7 +91,8 @@ bool Scene::setParam(SceneParam paramId, double value) bool Scene::addObject(const std::string& name, Object* object, UncontrolledObject* base, const std::string& baseFrame) { // finalize the object before adding - object->finalize(); + if (!object->finalize()) + return false; //Check if Object is controlled or uncontrolled. if(object->getType()==Object::Controlled){ int baseFrameIndex = base->addEndEffector(baseFrame); diff --git a/intern/itasc/kdl/jntarray.cpp b/intern/itasc/kdl/jntarray.cpp index 77c75e6af6c..db2c913a532 100644 --- a/intern/itasc/kdl/jntarray.cpp +++ b/intern/itasc/kdl/jntarray.cpp @@ -71,20 +71,25 @@ namespace KDL SetToZero(*this); } - double JntArray::operator()(unsigned int i,unsigned int j)const + double JntArray::operator[](unsigned int i)const { - assert(i<size&&j==0); - assert(0 != size); // found JntArray containing no data + assert(i<size); return data[i]; } - double& JntArray::operator()(unsigned int i,unsigned int j) + double& JntArray::operator[](unsigned int i) { - assert(i<size&&j==0); - assert(0 != size); // found JntArray containing no data + assert(i<size); return data[i]; } + double* JntArray::operator()(unsigned int i) + { + if (i>=size) + return NULL; + return &data[i]; + } + unsigned int JntArray::rows()const { return size; diff --git a/intern/itasc/kdl/jntarray.hpp b/intern/itasc/kdl/jntarray.hpp index 8db4cd6f2b3..ece6b0bdb6b 100644 --- a/intern/itasc/kdl/jntarray.hpp +++ b/intern/itasc/kdl/jntarray.hpp @@ -107,24 +107,30 @@ class MyTask : public RTT::TaskContext JntArray& operator = ( const JntArray& arg); /** - * get_item operator for the joint array, if a second value is - * given it should be zero, since a JntArray resembles a column. + * get_item operator for the joint array * * * @return the joint value at position i, starting from 0 * @pre 0 != size (ie non-default constructor or resize() called) */ - double operator()(unsigned int i,unsigned int j=0)const; + double operator[](unsigned int i) const; /** - * set_item operator, again if a second value is given it - *should be zero. + * set_item operator * * @return reference to the joint value at position i,starting *from zero. * @pre 0 != size (ie non-default constructor or resize() called) */ - double& operator()(unsigned int i,unsigned int j=0); + double& operator[](unsigned int i); /** + * access operator for the joint array. Use pointer here to allow + * access to sequential joint angles (required for ndof joints) + * + * + * @return the joint value at position i, NULL if i is outside the valid range + */ + double* operator()(unsigned int i); + /** * Returns the number of rows (size) of the array * */ diff --git a/intern/itasc/kdl/joint.cpp b/intern/itasc/kdl/joint.cpp index 5458efc4fcf..161794ddd72 100644 --- a/intern/itasc/kdl/joint.cpp +++ b/intern/itasc/kdl/joint.cpp @@ -55,37 +55,45 @@ namespace KDL { { } - Frame Joint::pose(const double& q)const + Frame Joint::pose(const double* q)const { switch(type){ case RotX: - return Frame(Rotation::RotX(scale*q+offset)); + assert(q); + return Frame(Rotation::RotX(scale*q[0]+offset)); break; case RotY: - return Frame(Rotation::RotY(scale*q+offset)); + assert(q); + return Frame(Rotation::RotY(scale*q[0]+offset)); break; case RotZ: - return Frame(Rotation::RotZ(scale*q+offset)); + assert(q); + return Frame(Rotation::RotZ(scale*q[0]+offset)); break; case TransX: - return Frame(Vector(scale*q+offset,0.0,0.0)); + assert(q); + return Frame(Vector(scale*q[0]+offset,0.0,0.0)); break; case TransY: - return Frame(Vector(0.0,scale*q+offset,0.0)); + assert(q); + return Frame(Vector(0.0,scale*q[0]+offset,0.0)); break; case TransZ: - return Frame(Vector(0.0,0.0,scale*q+offset)); + assert(q); + return Frame(Vector(0.0,0.0,scale*q[0]+offset)); break; case Sphere: // the joint angles represent a rotation vector expressed in the base frame of the joint // (= the frame you get when there is no offset nor rotation) - return Frame(Rot(Vector((&q)[0], (&q)[1], (&q)[2]))); + assert(q); + return Frame(Rot(Vector(q[0], q[1], q[2]))); break; case Swing: // the joint angles represent a 2D rotation vector in the XZ planee of the base frame of the joint // (= the frame you get when there is no offset nor rotation) - return Frame(Rot(Vector((&q)[0], 0.0, (&q)[1]))); + assert(q); + return Frame(Rot(Vector(q[0], 0.0, q[1]))); break; default: return Frame::Identity(); diff --git a/intern/itasc/kdl/joint.hpp b/intern/itasc/kdl/joint.hpp index a1291509f0f..9d25b427499 100644 --- a/intern/itasc/kdl/joint.hpp +++ b/intern/itasc/kdl/joint.hpp @@ -70,7 +70,7 @@ namespace KDL { * * @return the resulting 6D-pose */ - Frame pose(const double& q)const; + Frame pose(const double* q)const; /** * Request the resulting 6D-velocity with a joint velocity qdot * diff --git a/intern/itasc/kdl/kinfam_io.cpp b/intern/itasc/kdl/kinfam_io.cpp index 15557ab5f05..ff4cab862ce 100644 --- a/intern/itasc/kdl/kinfam_io.cpp +++ b/intern/itasc/kdl/kinfam_io.cpp @@ -76,7 +76,7 @@ std::istream& operator >>(std::istream& is, Tree& tree) { std::ostream& operator <<(std::ostream& os, const JntArray& array) { os << "["; for (unsigned int i = 0; i < array.rows(); i++) - os << std::setw(KDL_FRAME_WIDTH) << array(i); + os << std::setw(KDL_FRAME_WIDTH) << array[i]; os << "]"; return os; } diff --git a/intern/itasc/kdl/segment.cpp b/intern/itasc/kdl/segment.cpp index cba797899e1..f963559c4c8 100644 --- a/intern/itasc/kdl/segment.cpp +++ b/intern/itasc/kdl/segment.cpp @@ -48,12 +48,12 @@ namespace KDL { { } - Frame Segment::pose(const double& q)const + Frame Segment::pose(const double* q)const { return joint.pose(q)*f_tip; } - Twist Segment::twist(const double& q, const double& qdot, int dof)const + Twist Segment::twist(const double* q, const double& qdot, int dof)const { return joint.twist(qdot, dof).RefPoint(pose(q).p); } diff --git a/intern/itasc/kdl/segment.hpp b/intern/itasc/kdl/segment.hpp index 87d972ead70..130bfb13f8b 100644 --- a/intern/itasc/kdl/segment.hpp +++ b/intern/itasc/kdl/segment.hpp @@ -73,7 +73,7 @@ namespace KDL { * * @return pose from the root to the tip of the segment */ - Frame pose(const double& q)const; + Frame pose(const double* q)const; /** * Request the 6D-velocity of the tip of the segment, given * the joint position q and the joint velocity qdot. @@ -85,7 +85,7 @@ namespace KDL { *in the base-frame of the segment(root) and with the tip of *the segment as reference point. */ - Twist twist(const double& q,const double& qdot, int dof=0)const; + Twist twist(const double* q,const double& qdot, int dof=0)const; /** * Request the 6D-velocity at a given point p, relative to base frame of the segment diff --git a/intern/itasc/kdl/utilities/utility.h b/intern/itasc/kdl/utilities/utility.h index fbf9982665a..892b375d442 100644 --- a/intern/itasc/kdl/utilities/utility.h +++ b/intern/itasc/kdl/utilities/utility.h @@ -27,6 +27,10 @@ #include <cassert> #include <cmath> +#ifdef NDEBUG +#undef assert +#define assert(e) ((void)0) +#endif ///////////////////////////////////////////////////////////// // configurable options for the frames library. diff --git a/intern/memutil/MEM_Allocator.h b/intern/memutil/MEM_Allocator.h index 9541604b680..0020094ebbb 100644 --- a/intern/memutil/MEM_Allocator.h +++ b/intern/memutil/MEM_Allocator.h @@ -72,7 +72,7 @@ struct MEM_Allocator } // __p is not permitted to be a null pointer. - void deallocate(pointer __p, size_type){ + void deallocate(pointer __p, size_type) { MEM_freeN(__p); } diff --git a/intern/memutil/MEM_RefCountPtr.h b/intern/memutil/MEM_RefCountPtr.h index 4f475345076..ffdf927b551 100644 --- a/intern/memutil/MEM_RefCountPtr.h +++ b/intern/memutil/MEM_RefCountPtr.h @@ -98,7 +98,7 @@ * * static * MEM_RefCountPtr<RcUsefullClass> - * New(...){ + * New(...) { * return MEM_RefCountPtr<RcUsefullClass> output( * new UsefullClass(...) * ); diff --git a/intern/memutil/MEM_SmartPtr.h b/intern/memutil/MEM_SmartPtr.h index 6a0dc1723c4..722a0a8fd3b 100644 --- a/intern/memutil/MEM_SmartPtr.h +++ b/intern/memutil/MEM_SmartPtr.h @@ -119,7 +119,7 @@ public : MEM_SmartPtr( const MEM_SmartPtr &rhs - ){ + ) { m_val = rhs.Release(); } diff --git a/intern/mikktspace/mikktspace.c b/intern/mikktspace/mikktspace.c index 24c77c439a7..0a3141d6782 100644 --- a/intern/mikktspace/mikktspace.c +++ b/intern/mikktspace/mikktspace.c @@ -40,8 +40,7 @@ #define INTERNAL_RND_SORT_SEED 39871946 // internal structure -typedef struct -{ +typedef struct { float x, y, z; } SVec3; @@ -119,14 +118,12 @@ static tbool VNotZero(const SVec3 v) -typedef struct -{ +typedef struct { int iNrFaces; int * pTriMembers; } SSubGroup; -typedef struct -{ +typedef struct { int iNrFaces; int * pFaceIndices; int iVertexRepresentitive; @@ -141,8 +138,7 @@ typedef struct -typedef struct -{ +typedef struct { int FaceNeighbors[3]; SGroup * AssignedGroup[3]; @@ -156,8 +152,7 @@ typedef struct unsigned char vert_num[4]; } STriInfo; -typedef struct -{ +typedef struct { SVec3 vOs; float fMagS; SVec3 vOt; @@ -258,7 +253,7 @@ tbool genTangSpace(const SMikkTSpaceContext * pContext, const float fAngularThre { const int verts = pContext->m_pInterface->m_getNumVerticesOfFace(pContext, f); if (verts==3) ++iNrTrianglesIn; - else if(verts==4) iNrTrianglesIn += 2; + else if (verts==4) iNrTrianglesIn += 2; } if (iNrTrianglesIn<=0) return TFALSE; @@ -426,8 +421,7 @@ tbool genTangSpace(const SMikkTSpaceContext * pContext, const float fAngularThre /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -typedef struct -{ +typedef struct { float vert[3]; int index; } STmpVert; @@ -470,11 +464,11 @@ static void GenerateSharedVerticesIndexList(int piTriList_in_and_out[], const SM const SVec3 vP = GetPosition(pContext, index); if (vMin.x > vP.x) vMin.x = vP.x; - else if(vMax.x < vP.x) vMax.x = vP.x; + else if (vMax.x < vP.x) vMax.x = vP.x; if (vMin.y > vP.y) vMin.y = vP.y; - else if(vMax.y < vP.y) vMax.y = vP.y; + else if (vMax.y < vP.y) vMax.y = vP.y; if (vMin.z > vP.z) vMin.z = vP.z; - else if(vMax.z < vP.z) vMax.z = vP.z; + else if (vMax.z < vP.z) vMax.z = vP.z; } vDim = vsub(vMax,vMin); @@ -485,7 +479,7 @@ static void GenerateSharedVerticesIndexList(int piTriList_in_and_out[], const SM iChannel=1; fMin = vMin.y, fMax=vMax.y; } - else if(vDim.z>vDim.x) + else if (vDim.z>vDim.x) { iChannel=2; fMin = vMin.z, fMax=vMax.z; @@ -590,7 +584,7 @@ static void MergeVertsFast(int piTriList_in_and_out[], STmpVert pTmpVert[], cons for (l=(iL_in+1); l<=iR_in; l++) for (c=0; c<3; c++) if (fvMin[c]>pTmpVert[l].vert[c]) fvMin[c]=pTmpVert[l].vert[c]; - else if(fvMax[c]<pTmpVert[l].vert[c]) fvMax[c]=pTmpVert[l].vert[c]; + else if (fvMax[c]<pTmpVert[l].vert[c]) fvMax[c]=pTmpVert[l].vert[c]; dx = fvMax[0]-fvMin[0]; dy = fvMax[1]-fvMin[1]; @@ -598,7 +592,7 @@ static void MergeVertsFast(int piTriList_in_and_out[], STmpVert pTmpVert[], cons channel = 0; if (dy>dx && dy>dz) channel=1; - else if(dz>dx) channel=2; + else if (dz>dx) channel=2; fSep = 0.5f*(fvMax[channel]+fvMin[channel]); @@ -626,7 +620,7 @@ static void MergeVertsFast(int piTriList_in_and_out[], STmpVert pTmpVert[], cons const SVec3 vT2 = GetTexCoord(pContext, index2); i2rec=i2; - //if(vP==vP2 && vN==vN2 && vT==vT2) + //if (vP==vP2 && vN==vN2 && vT==vT2) if (vP.x==vP2.x && vP.y==vP2.y && vP.z==vP2.z && vN.x==vN2.x && vN.y==vN2.y && vN.z==vN2.z && vT.x==vT2.x && vT.y==vT2.y && vT.z==vT2.z) @@ -812,7 +806,7 @@ static int GenerateInitialVerticesIndexList(STriInfo pTriInfos[], int piTriList_ tbool bQuadDiagIs_02; if (distSQ_02<distSQ_13) bQuadDiagIs_02 = TTRUE; - else if(distSQ_13<distSQ_02) + else if (distSQ_13<distSQ_02) bQuadDiagIs_02 = TFALSE; else { @@ -911,8 +905,7 @@ static SVec3 GetTexCoord(const SMikkTSpaceContext * pContext, const int index) ///////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////// -typedef union -{ +typedef union { struct { int i0, i1, f; @@ -1027,7 +1020,7 @@ static void InitTriInfo(STriInfo pTriInfos[], const int piTriListIn[], const SMi //printf("found quad with bad mapping\n"); tbool bChooseOrientFirstTri = TFALSE; if ((pTriInfos[t+1].iFlag&GROUP_WITH_ANY)!=0) bChooseOrientFirstTri = TTRUE; - else if( CalcTexArea(pContext, &piTriListIn[t*3+0]) >= CalcTexArea(pContext, &piTriListIn[(t+1)*3+0]) ) + else if ( CalcTexArea(pContext, &piTriListIn[t*3+0]) >= CalcTexArea(pContext, &piTriListIn[(t+1)*3+0]) ) bChooseOrientFirstTri = TTRUE; // force match @@ -1142,13 +1135,13 @@ static tbool AssignRecur(const int piTriListIn[], STriInfo psTriInfos[], const int * pVerts = &piTriListIn[3*iMyTriIndex+0]; int i=-1; if (pVerts[0]==iVertRep) i=0; - else if(pVerts[1]==iVertRep) i=1; - else if(pVerts[2]==iVertRep) i=2; + else if (pVerts[1]==iVertRep) i=1; + else if (pVerts[2]==iVertRep) i=2; assert(i>=0 && i<3); // early out if (pMyTriInfo->AssignedGroup[i] == pGroup) return TTRUE; - else if(pMyTriInfo->AssignedGroup[i]!=NULL) return TFALSE; + else if (pMyTriInfo->AssignedGroup[i]!=NULL) return TFALSE; if ((pMyTriInfo->iFlag&GROUP_WITH_ANY)!=0) { // first to group with a group-with-anything triangle @@ -1232,8 +1225,8 @@ static tbool GenerateTSpaces(STSpace psTspace[], const STriInfo pTriInfos[], con tbool bFound; SVec3 n, vOs, vOt; if (pTriInfos[f].AssignedGroup[0]==pGroup) index=0; - else if(pTriInfos[f].AssignedGroup[1]==pGroup) index=1; - else if(pTriInfos[f].AssignedGroup[2]==pGroup) index=2; + else if (pTriInfos[f].AssignedGroup[1]==pGroup) index=1; + else if (pTriInfos[f].AssignedGroup[2]==pGroup) index=2; assert(index>=0 && index<3); iVertIndex = piTriListIn[f*3+index]; @@ -1381,8 +1374,8 @@ static STSpace EvalTspace(int face_indices[], const int iFaces, const int piTriL float fCos, fAngle, fMagS, fMagT; int i=-1, index=-1, i0=-1, i1=-1, i2=-1; if (piTriListIn[3*f+0]==iVertexRepresentitive) i=0; - else if(piTriListIn[3*f+1]==iVertexRepresentitive) i=1; - else if(piTriListIn[3*f+2]==iVertexRepresentitive) i=2; + else if (piTriListIn[3*f+1]==iVertexRepresentitive) i=1; + else if (piTriListIn[3*f+2]==iVertexRepresentitive) i=2; assert(i>=0 && i<3); // project @@ -1404,8 +1397,8 @@ static STSpace EvalTspace(int face_indices[], const int iFaces, const int piTriL v2 = vsub(p2,p1); // project - v1 = vsub(v1, vscale(vdot(n,v1),n)); if( VNotZero(v1) ) v1 = Normalize(v1); - v2 = vsub(v2, vscale(vdot(n,v2),n)); if( VNotZero(v2) ) v2 = Normalize(v2); + v1 = vsub(v1, vscale(vdot(n,v1),n)); if ( VNotZero(v1) ) v1 = Normalize(v1); + v2 = vsub(v2, vscale(vdot(n,v2),n)); if ( VNotZero(v2) ) v2 = Normalize(v2); // weight contribution by the angle // between the two edge vectors @@ -1647,7 +1640,7 @@ static void QuickSortEdges(SEdge * pSortBuffer, int iLeft, int iRight, const int SEdge sTmp; const int iElems = iRight-iLeft+1; if (iElems<2) return; - else if(iElems==2) + else if (iElems==2) { if (pSortBuffer[iLeft].array[channel] > pSortBuffer[iRight].array[channel]) { @@ -1868,8 +1861,8 @@ static void DegenEpilogue(STSpace psTspace[], STriInfo pTriInfos[], int piTriLis int iFlag = (1<<pV[0]) | (1<<pV[1]) | (1<<pV[2]); int iMissingIndex = 0; if ((iFlag&2)==0) iMissingIndex=1; - else if((iFlag&4)==0) iMissingIndex=2; - else if((iFlag&8)==0) iMissingIndex=3; + else if ((iFlag&4)==0) iMissingIndex=2; + else if ((iFlag&8)==0) iMissingIndex=3; iOrgF = pTriInfos[t].iOrgFaceNumber; vDstP = GetPosition(pContext, MakeIndex(iOrgF, iMissingIndex)); diff --git a/intern/mikktspace/mikktspace.h b/intern/mikktspace/mikktspace.h index dc2308f6116..52c44a713c6 100644 --- a/intern/mikktspace/mikktspace.h +++ b/intern/mikktspace/mikktspace.h @@ -62,8 +62,7 @@ extern "C" { typedef int tbool; typedef struct SMikkTSpaceContext SMikkTSpaceContext; -typedef struct -{ +typedef struct { // Returns the number of faces (triangles/quads) on the mesh to be processed. int (*m_getNumFaces)(const SMikkTSpaceContext * pContext); diff --git a/intern/raskter/CMakeLists.txt b/intern/raskter/CMakeLists.txt new file mode 100644 index 00000000000..3e1368d8eb0 --- /dev/null +++ b/intern/raskter/CMakeLists.txt @@ -0,0 +1,40 @@ +# ***** 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) 2012, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Peter Larabell +# +# ***** END GPL LICENSE BLOCK ***** + +set(INC + . +) + +set(INC_SYS + +) + +set(SRC + raskter.c + + raskter.h +) + +blender_add_lib(bf_intern_raskter "${SRC}" "${INC}" "${INC_SYS}") diff --git a/intern/raskter/SConscript b/intern/raskter/SConscript new file mode 100644 index 00000000000..7ad505d70e4 --- /dev/null +++ b/intern/raskter/SConscript @@ -0,0 +1,10 @@ +#!/usr/bin/python + +Import ('env') + +sources = ['raskter.c'] + +incs = '' +defs = '' + +env.BlenderLib ('bf_intern_raskter', sources, Split(incs), Split(defs), libtype=['intern'], priority=[100] ) diff --git a/intern/raskter/raskter.c b/intern/raskter/raskter.c new file mode 100644 index 00000000000..081a7c6bdbd --- /dev/null +++ b/intern/raskter/raskter.c @@ -0,0 +1,753 @@ +/* + * ***** 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) 2012 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Peter Larabell. + * + * ***** END GPL LICENSE BLOCK ***** + */ +/** \file raskter.c + * \ingroup RASKTER + */ + +#include <stdlib.h> +#include "raskter.h" + +/* from BLI_utildefines.h */ +#define MIN2(x, y) ( (x) < (y) ? (x) : (y) ) +#define MAX2(x, y) ( (x) > (y) ? (x) : (y) ) + + +struct e_status { + int x; + int ybeg; + int xshift; + int xdir; + int drift; + int drift_inc; + int drift_dec; + int num; + struct e_status *e_next; +}; + +struct r_buffer_stats { + float *buf; + int sizex; + int sizey; +}; + +struct r_fill_context { + struct e_status *all_edges, *possible_edges; + struct r_buffer_stats rb; +}; + +/* + * Sort all the edges of the input polygon by Y, then by X, of the "first" vertex encountered. + * This will ensure we can scan convert the entire poly in one pass. + * + * Really the poly should be clipped to the frame buffer's dimensions here for speed of drawing + * just the poly. Since the DEM code could end up being coupled with this, we'll keep it separate + * for now. + */ +static void preprocess_all_edges(struct r_fill_context *ctx, struct poly_vert *verts, int num_verts, struct e_status *open_edge) +{ + int i; + int xbeg; + int ybeg; + int xend; + int yend; + int dx; + int dy; + int temp_pos; + int xdist; + struct e_status *e_new; + struct e_status *next_edge; + struct e_status **next_edge_ref; + struct poly_vert *v; + /* set up pointers */ + v = verts; + ctx->all_edges = NULL; + /* loop all verts */ + for (i = 0; i < num_verts; i++) { + /* determine beginnings and endings of edges, linking last vertex to first vertex */ + xbeg = v[i].x; + ybeg = v[i].y; + if (i) { + /* we're not at the last vert, so end of the edge is the previous vertex */ + xend = v[i - 1].x; + yend = v[i - 1].y; + } + else { + /* we're at the first vertex, so the "end" of this edge is the last vertex */ + xend = v[num_verts - 1].x; + yend = v[num_verts - 1].y; + } + /* make sure our edges are facing the correct direction */ + if (ybeg > yend) { + /* flip the Xs */ + temp_pos = xbeg; + xbeg = xend; + xend = temp_pos; + /* flip the Ys */ + temp_pos = ybeg; + ybeg = yend; + yend = temp_pos; + } + + /* calculate y delta */ + dy = yend - ybeg; + /* dont draw horizontal lines directly, they are scanned as part of the edges they connect, so skip em. :) */ + if (dy) { + /* create the edge and determine it's slope (for incremental line drawing) */ + e_new = open_edge++; + + /* calculate x delta */ + dx = xend - xbeg; + if (dx > 0) { + e_new->xdir = 1; + xdist = dx; + } + else { + e_new->xdir = -1; + xdist = -dx; + } + + e_new->x = xbeg; + e_new->ybeg = ybeg; + e_new->num = dy; + e_new->drift_dec = dy; + + /* calculate deltas for incremental drawing */ + if (dx >= 0) { + e_new->drift = 0; + } + else { + e_new->drift = -dy + 1; + } + if (dy >= xdist) { + e_new->drift_inc = xdist; + e_new->xshift = 0; + } + else { + e_new->drift_inc = xdist % dy; + e_new->xshift = (xdist / dy) * e_new->xdir; + } + next_edge_ref = &ctx->all_edges; + /* link in all the edges, in sorted order */ + for (;; ) { + next_edge = *next_edge_ref; + if (!next_edge || (next_edge->ybeg > ybeg) || ((next_edge->ybeg == ybeg) && (next_edge->x >= xbeg))) { + e_new->e_next = next_edge; + *next_edge_ref = e_new; + break; + } + next_edge_ref = &next_edge->e_next; + } + } + } +} + +/* + * This function clips drawing to the frame buffer. That clipping will likely be moved into the preprocessor + * for speed, but waiting on final design choices for curve-data before eliminating data the DEM code will need + * if it ends up being coupled with this function. + */ +static int rast_scan_fill(struct r_fill_context *ctx, struct poly_vert *verts, int num_verts) +{ + int x_curr; /* current pixel position in X */ + int y_curr; /* current scan line being drawn */ + int yp; /* y-pixel's position in frame buffer */ + int swixd = 0; /* whether or not edges switched position in X */ + float *cpxl; /* pixel pointers... */ + float *mpxl; + float *spxl; + struct e_status *e_curr; /* edge pointers... */ + struct e_status *e_temp; + struct e_status *edgbuf; + struct e_status **edgec; + + + /* + * If the number of verts specified to render as a polygon is less than 3, + * return immediately. Obviously we cant render a poly with sides < 3. The + * return for this we set to 1, simply so it can be distinguished from the + * next place we could return, /home/guest/blender-svn/soc-2011-tomato/intern/raskter/raskter. + * which is a failure to allocate memory. + */ + if (num_verts < 3) { + return(1); + } + + /* + * Try to allocate an edge buffer in memory. needs to be the size of the edge tracking data + * multiplied by the number of edges, which is always equal to the number of verts in + * a 2D polygon. Here we return 0 to indicate a memory allocation failure, as opposed to a 1 for + * the preceeding error, which was a rasterization request on a 2D poly with less than + * 3 sides. + */ + if ((edgbuf = (struct e_status *)(malloc(sizeof(struct e_status) * num_verts))) == NULL) { + return(0); + } + + /* + * Do some preprocessing on all edges. This constructs a table structure in memory of all + * the edge properties and can "flip" some edges so sorting works correctly. + */ + preprocess_all_edges(ctx, verts, num_verts, edgbuf); + + /* + * Set the pointer for tracking the edges currently in processing to NULL to make sure + * we don't get some crazy value after initialization. + */ + ctx->possible_edges = NULL; + + /* + * Loop through all scan lines to be drawn. Since we sorted by Y values during + * preprocess_all_edges(), we can already exact values for the lowest and + * highest Y values we could possibly need by induction. The preprocessing sorted + * out edges by Y position, we can cycle the current edge being processed once + * it runs out of Y pixels. When we have no more edges, meaning the current edge + * is NULL after setting the "current" edge to be the previous current edge's + * "next" edge in the Y sorted edge connection chain, we can stop looping Y values, + * since we can't possibly have more scan lines if we ran out of edges. :) + * + * TODO: This clips Y to the frame buffer, which should be done in the preprocessor, but for now is done here. + * Will get changed once DEM code gets in. + */ + for (y_curr = ctx->all_edges->ybeg; (ctx->all_edges || ctx->possible_edges); y_curr++) { + + /* + * Link any edges that start on the current scan line into the list of + * edges currently needed to draw at least this, if not several, scan lines. + */ + + /* + * Set the current edge to the beginning of the list of edges to be rasterized + * into this scan line. + * + * We could have lots of edge here, so iterate over all the edges needed. The + * preprocess_all_edges() function sorted edges by X within each chunk of Y sorting + * so we safely cycle edges to thier own "next" edges in order. + * + * At each iteration, make sure we still have a non-NULL edge. + */ + for (edgec = &ctx->possible_edges; ctx->all_edges && (ctx->all_edges->ybeg == y_curr); ) { + x_curr = ctx->all_edges->x; /* Set current X position. */ + for (;; ) { /* Start looping edges. Will break when edges run out. */ + e_curr = *edgec; /* Set up a current edge pointer. */ + if (!e_curr || (e_curr->x >= x_curr)) { /* If we have an no edge, or we need to skip some X-span, */ + e_temp = ctx->all_edges->e_next; /* set a temp "next" edge to test. */ + *edgec = ctx->all_edges; /* Add this edge to the list to be scanned. */ + ctx->all_edges->e_next = e_curr; /* Set up the next edge. */ + edgec = &ctx->all_edges->e_next; /* Set our list to the next edge's location in memory. */ + ctx->all_edges = e_temp; /* Skip the NULL or bad X edge, set pointer to next edge. */ + break; /* Stop looping edges (since we ran out or hit empty X span. */ + } + else { + edgec = &e_curr->e_next; /* Set the pointer to the edge list the "next" edge. */ + } + } + } + + /* + * Determine the current scan line's offset in the pixel buffer based on its Y position. + * Basically we just multiply the current scan line's Y value by the number of pixels in each line. + */ + yp = y_curr * ctx->rb.sizex; + /* + * Set a "scan line pointer" in memory. The location of the buffer plus the row offset. + */ + spxl = ctx->rb.buf + (yp); + /* + * Set up the current edge to the first (in X) edge. The edges which could possibly be in this + * list were determined in the preceeding edge loop above. They were already sorted in X by the + * initial processing function. + * + * At each iteration, test for a NULL edge. Since we'll keep cycling edge's to their own "next" edge + * we will eventually hit a NULL when the list runs out. + */ + for (e_curr = ctx->possible_edges; e_curr; e_curr = e_curr->e_next) { + /* + * Calculate a span of pixels to fill on the current scan line. + * + * Set the current pixel pointer by adding the X offset to the scan line's start offset. + * Cycle the current edge the next edge. + * Set the max X value to draw to be one less than the next edge's first pixel. This way we are + * sure not to ever get into a situation where we have overdraw. (drawing the same pixel more than + * one time because it's on a vertex connecting two edges) + * + * Then blast through all the pixels in the span, advancing the pointer and setting the color to white. + * + * TODO: Here we clip to the scan line, this is not efficient, and should be done in the preprocessor, + * but for now it is done here until the DEM code comes in. + */ + + /* set up xmin and xmax bounds on this scan line */ + cpxl = spxl + MAX2(e_curr->x, 0); + e_curr = e_curr->e_next; + mpxl = spxl + MIN2(e_curr->x, ctx->rb.sizex) - 1; + + if ((y_curr >= 0) && (y_curr < ctx->rb.sizey)) { + /* draw the pixels. */ + for (; cpxl <= mpxl; *cpxl++ = 1.0f); + } + } + + /* + * Loop through all edges of polygon that could be hit by this scan line, + * and figure out their x-intersections with the next scan line. + * + * Either A.) we wont have any more edges to test, or B.) we just add on the + * slope delta computed in preprocessing step. Since this draws non-antialiased + * polygons, we dont have fractional positions, so we only move in x-direction + * when needed to get all the way to the next pixel over... + */ + for (edgec = &ctx->possible_edges; (e_curr = *edgec); ) { + if (!(--(e_curr->num))) { + *edgec = e_curr->e_next; + } + else { + e_curr->x += e_curr->xshift; + if ((e_curr->drift += e_curr->drift_inc) > 0) { + e_curr->x += e_curr->xdir; + e_curr->drift -= e_curr->drift_dec; + } + edgec = &e_curr->e_next; + } + } + /* + * It's possible that some edges may have crossed during the last step, so we'll be sure + * that we ALWAYS intersect scan lines in order by shuffling if needed to make all edges + * sorted by x-intersection coordinate. We'll always scan through at least once to see if + * edges crossed, and if so, we set the 'swixd' flag. If 'swixd' gets set on the initial + * pass, then we know we need to sort by x, so then cycle through edges again and perform + * the sort.- + */ + if (ctx->possible_edges) { + for (edgec = &ctx->possible_edges; (e_curr = *edgec)->e_next; edgec = &(*edgec)->e_next) { + /* if the current edge hits scan line at greater X than the next edge, we need to exchange the edges */ + if (e_curr->x > e_curr->e_next->x) { + *edgec = e_curr->e_next; + /* exchange the pointers */ + e_temp = e_curr->e_next->e_next; + e_curr->e_next->e_next = e_curr; + e_curr->e_next = e_temp; + /* set flag that we had at least one switch */ + swixd = 1; + } + } + /* if we did have a switch, look for more (there will more if there was one) */ + for (;; ) { + /* reset exchange flag so it's only set if we encounter another one */ + swixd = 0; + for (edgec = &ctx->possible_edges; (e_curr = *edgec)->e_next; edgec = &(*edgec)->e_next) { + /* again, if current edge hits scan line at higher X than next edge, exchange the edges and set flag */ + if (e_curr->x > e_curr->e_next->x) { + *edgec = e_curr->e_next; + /* exchange the pointers */ + e_temp = e_curr->e_next->e_next; + e_curr->e_next->e_next = e_curr; + e_curr->e_next = e_temp; + /* flip the exchanged flag */ + swixd = 1; + } + } + /* if we had no exchanges, we're done reshuffling the pointers */ + if (!swixd) { + break; + } + } + } + } + + free(edgbuf); + return 1; +} + +int PLX_raskterize(float (*base_verts)[2], int num_base_verts, + float *buf, int buf_x, int buf_y) +{ + int i; /* i: Loop counter. */ + struct poly_vert *ply; /* ply: Pointer to a list of integer buffer-space vertex coordinates. */ + struct r_fill_context ctx = {0}; + + /* + * Allocate enough memory for our poly_vert list. It'll be the size of the poly_vert + * data structure multiplied by the number of base_verts. + * + * In the event of a failure to allocate the memory, return 0, so this error can + * be distinguished as a memory allocation error. + */ + if ((ply = (struct poly_vert *)(malloc(sizeof(struct poly_vert) * num_base_verts))) == NULL) { + return(0); + } + + /* + * Loop over all verts passed in to be rasterized. Each vertex's X and Y coordinates are + * then converted from normalized screen space (0.0 <= POS <= 1.0) to integer coordinates + * in the buffer-space coordinates passed in inside buf_x and buf_y. + * + * It's worth noting that this function ONLY outputs fully white pixels in a mask. Every pixel + * drawn will be 1.0f in value, there is no anti-aliasing. + */ + for (i = 0; i < num_base_verts; i++) { /* Loop over all base_verts. */ + ply[i].x = (base_verts[i][0] * buf_x) + 0.5f; /* Range expand normalized X to integer buffer-space X. */ + ply[i].y = (base_verts[i][1] * buf_y) + 0.5f; /* Range expand normalized Y to integer buffer-space Y. */ + } + + ctx.rb.buf = buf; /* Set the output buffer pointer. */ + ctx.rb.sizex = buf_x; /* Set the output buffer size in X. (width) */ + ctx.rb.sizey = buf_y; /* Set the output buffer size in Y. (height) */ + + i = rast_scan_fill(&ctx, ply, num_base_verts); /* Call our rasterizer, passing in the integer coords for each vert. */ + free(ply); /* Free the memory allocated for the integer coordinate table. */ + return(i); /* Return the value returned by the rasterizer. */ +} + +/* + * This function clips drawing to the frame buffer. That clipping will likely be moved into the preprocessor + * for speed, but waiting on final design choices for curve-data before eliminating data the DEM code will need + * if it ends up being coupled with this function. + */ +static int rast_scan_feather(struct r_fill_context *ctx, + float (*base_verts_f)[2], int num_base_verts, + struct poly_vert *feather_verts, float (*feather_verts_f)[2], int num_feather_verts) +{ + int x_curr; /* current pixel position in X */ + int y_curr; /* current scan line being drawn */ + int yp; /* y-pixel's position in frame buffer */ + int swixd = 0; /* whether or not edges switched position in X */ + float *cpxl; /* pixel pointers... */ + float *mpxl; + float *spxl; + struct e_status *e_curr; /* edge pointers... */ + struct e_status *e_temp; + struct e_status *edgbuf; + struct e_status **edgec; + + /* from dem */ + int a; // a = temporary pixel index buffer loop counter + float fsz; // size of the frame + unsigned int rsl; // long used for finding fast 1.0/sqrt + float rsf; // float used for finding fast 1.0/sqrt + const float rsopf = 1.5f; // constant float used for finding fast 1.0/sqrt + + //unsigned int gradientFillOffset; + float t; + float ud; // ud = unscaled edge distance + float dmin; // dmin = minimun edge distance + float odist; // odist = current outer edge distance + float idist; // idist = current inner edge distance + float dx; // dx = X-delta (used for distance proportion calculation) + float dy; // dy = Y-delta (used for distance proportion calculation) + float xpxw = (1.0f / (float)(ctx->rb.sizex)); // xpxw = normalized pixel width + float ypxh = (1.0f / (float)(ctx->rb.sizey)); // ypxh = normalized pixel height + + /* + * If the number of verts specified to render as a polygon is less than 3, + * return immediately. Obviously we cant render a poly with sides < 3. The + * return for this we set to 1, simply so it can be distinguished from the + * next place we could return, /home/guest/blender-svn/soc-2011-tomato/intern/raskter/raskter + * which is a failure to allocate memory. + */ + if (num_feather_verts < 3) { + return(1); + } + + /* + * Try to allocate an edge buffer in memory. needs to be the size of the edge tracking data + * multiplied by the number of edges, which is always equal to the number of verts in + * a 2D polygon. Here we return 0 to indicate a memory allocation failure, as opposed to a 1 for + * the preceeding error, which was a rasterization request on a 2D poly with less than + * 3 sides. + */ + if ((edgbuf = (struct e_status *)(malloc(sizeof(struct e_status) * num_feather_verts))) == NULL) { + return(0); + } + + /* + * Do some preprocessing on all edges. This constructs a table structure in memory of all + * the edge properties and can "flip" some edges so sorting works correctly. + */ + preprocess_all_edges(ctx, feather_verts, num_feather_verts, edgbuf); + + /* + * Set the pointer for tracking the edges currently in processing to NULL to make sure + * we don't get some crazy value after initialization. + */ + ctx->possible_edges = NULL; + + /* + * Loop through all scan lines to be drawn. Since we sorted by Y values during + * preprocess_all_edges(), we can already exact values for the lowest and + * highest Y values we could possibly need by induction. The preprocessing sorted + * out edges by Y position, we can cycle the current edge being processed once + * it runs out of Y pixels. When we have no more edges, meaning the current edge + * is NULL after setting the "current" edge to be the previous current edge's + * "next" edge in the Y sorted edge connection chain, we can stop looping Y values, + * since we can't possibly have more scan lines if we ran out of edges. :) + * + * TODO: This clips Y to the frame buffer, which should be done in the preprocessor, but for now is done here. + * Will get changed once DEM code gets in. + */ + for (y_curr = ctx->all_edges->ybeg; (ctx->all_edges || ctx->possible_edges); y_curr++) { + + /* + * Link any edges that start on the current scan line into the list of + * edges currently needed to draw at least this, if not several, scan lines. + */ + + /* + * Set the current edge to the beginning of the list of edges to be rasterized + * into this scan line. + * + * We could have lots of edge here, so iterate over all the edges needed. The + * preprocess_all_edges() function sorted edges by X within each chunk of Y sorting + * so we safely cycle edges to thier own "next" edges in order. + * + * At each iteration, make sure we still have a non-NULL edge. + */ + for (edgec = &ctx->possible_edges; ctx->all_edges && (ctx->all_edges->ybeg == y_curr); ) { + x_curr = ctx->all_edges->x; /* Set current X position. */ + for (;; ) { /* Start looping edges. Will break when edges run out. */ + e_curr = *edgec; /* Set up a current edge pointer. */ + if (!e_curr || (e_curr->x >= x_curr)) { /* If we have an no edge, or we need to skip some X-span, */ + e_temp = ctx->all_edges->e_next; /* set a temp "next" edge to test. */ + *edgec = ctx->all_edges; /* Add this edge to the list to be scanned. */ + ctx->all_edges->e_next = e_curr; /* Set up the next edge. */ + edgec = &ctx->all_edges->e_next; /* Set our list to the next edge's location in memory. */ + ctx->all_edges = e_temp; /* Skip the NULL or bad X edge, set pointer to next edge. */ + break; /* Stop looping edges (since we ran out or hit empty X span. */ + } + else { + edgec = &e_curr->e_next; /* Set the pointer to the edge list the "next" edge. */ + } + } + } + + /* + * Determine the current scan line's offset in the pixel buffer based on its Y position. + * Basically we just multiply the current scan line's Y value by the number of pixels in each line. + */ + yp = y_curr * ctx->rb.sizex; + /* + * Set a "scan line pointer" in memory. The location of the buffer plus the row offset. + */ + spxl = ctx->rb.buf + (yp); + /* + * Set up the current edge to the first (in X) edge. The edges which could possibly be in this + * list were determined in the preceeding edge loop above. They were already sorted in X by the + * initial processing function. + * + * At each iteration, test for a NULL edge. Since we'll keep cycling edge's to their own "next" edge + * we will eventually hit a NULL when the list runs out. + */ + for (e_curr = ctx->possible_edges; e_curr; e_curr = e_curr->e_next) { + /* + * Calculate a span of pixels to fill on the current scan line. + * + * Set the current pixel pointer by adding the X offset to the scan line's start offset. + * Cycle the current edge the next edge. + * Set the max X value to draw to be one less than the next edge's first pixel. This way we are + * sure not to ever get into a situation where we have overdraw. (drawing the same pixel more than + * one time because it's on a vertex connecting two edges) + * + * Then blast through all the pixels in the span, advancing the pointer and setting the color to white. + * + * TODO: Here we clip to the scan line, this is not efficient, and should be done in the preprocessor, + * but for now it is done here until the DEM code comes in. + */ + + /* set up xmin and xmax bounds on this scan line */ + cpxl = spxl + MAX2(e_curr->x, 0); + e_curr = e_curr->e_next; + mpxl = spxl + MIN2(e_curr->x, ctx->rb.sizex) - 1; + + if ((y_curr >= 0) && (y_curr < ctx->rb.sizey)) { + t = ((float)((cpxl - spxl) % ctx->rb.sizex) + 0.5f) * xpxw; + fsz = ((float)(y_curr) + 0.5f) * ypxh; + /* draw the pixels. */ + for (; cpxl <= mpxl; cpxl++, t += xpxw) { + //do feather check + // first check that pixel isn't already full, and only operate if it is not + if (*cpxl < 0.9999f) { + + dmin = 2.0f; // reset min distance to edge pixel + for (a = 0; a < num_feather_verts; a++) { // loop through all outer edge buffer pixels + dy = t - feather_verts_f[a][0]; // set dx to gradient pixel column - outer edge pixel row + dx = fsz - feather_verts_f[a][1]; // set dy to gradient pixel row - outer edge pixel column + ud = dx * dx + dy * dy; // compute sum of squares + if (ud < dmin) { // if our new sum of squares is less than the current minimum + dmin = ud; // set a new minimum equal to the new lower value + } + } + odist = dmin; // cast outer min to a float + rsf = odist * 0.5f; // + rsl = *(unsigned int *)&odist; // use some peculiar properties of the way bits are stored + rsl = 0x5f3759df - (rsl >> 1); // in floats vs. unsigned ints to compute an approximate + odist = *(float *)&rsl; // reciprocal square root + odist = odist * (rsopf - (rsf * odist * odist)); // -- ** this line can be iterated for more accuracy ** -- + odist = odist * (rsopf - (rsf * odist * odist)); + dmin = 2.0f; // reset min distance to edge pixel + for (a = 0; a < num_base_verts; a++) { // loop through all inside edge pixels + dy = t - base_verts_f[a][0]; // compute delta in Y from gradient pixel to inside edge pixel + dx = fsz - base_verts_f[a][1]; // compute delta in X from gradient pixel to inside edge pixel + ud = dx * dx + dy * dy; // compute sum of squares + if (ud < dmin) { // if our new sum of squares is less than the current minimum we've found + dmin = ud; // set a new minimum equal to the new lower value + } + } + idist = dmin; // cast inner min to a float + rsf = idist * 0.5f; // + rsl = *(unsigned int *)&idist; // + rsl = 0x5f3759df - (rsl >> 1); // see notes above + idist = *(float *)&rsl; // + idist = idist * (rsopf - (rsf * idist * idist)); // + idist = idist * (rsopf - (rsf * idist * idist)); + /* + * Note once again that since we are using reciprocals of distance values our + * proportion is already the correct intensity, and does not need to be + * subracted from 1.0 like it would have if we used real distances. + */ + + /* set intensity, do the += so overlapping gradients are additive */ + *cpxl = (idist / (idist + odist)); + } + } + } + } + + /* + * Loop through all edges of polygon that could be hit by this scan line, + * and figure out their x-intersections with the next scan line. + * + * Either A.) we wont have any more edges to test, or B.) we just add on the + * slope delta computed in preprocessing step. Since this draws non-antialiased + * polygons, we dont have fractional positions, so we only move in x-direction + * when needed to get all the way to the next pixel over... + */ + for (edgec = &ctx->possible_edges; (e_curr = *edgec); ) { + if (!(--(e_curr->num))) { + *edgec = e_curr->e_next; + } + else { + e_curr->x += e_curr->xshift; + if ((e_curr->drift += e_curr->drift_inc) > 0) { + e_curr->x += e_curr->xdir; + e_curr->drift -= e_curr->drift_dec; + } + edgec = &e_curr->e_next; + } + } + /* + * It's possible that some edges may have crossed during the last step, so we'll be sure + * that we ALWAYS intersect scan lines in order by shuffling if needed to make all edges + * sorted by x-intersection coordinate. We'll always scan through at least once to see if + * edges crossed, and if so, we set the 'swixd' flag. If 'swixd' gets set on the initial + * pass, then we know we need to sort by x, so then cycle through edges again and perform + * the sort.- + */ + if (ctx->possible_edges) { + for (edgec = &ctx->possible_edges; (e_curr = *edgec)->e_next; edgec = &(*edgec)->e_next) { + /* if the current edge hits scan line at greater X than the next edge, we need to exchange the edges */ + if (e_curr->x > e_curr->e_next->x) { + *edgec = e_curr->e_next; + /* exchange the pointers */ + e_temp = e_curr->e_next->e_next; + e_curr->e_next->e_next = e_curr; + e_curr->e_next = e_temp; + /* set flag that we had at least one switch */ + swixd = 1; + } + } + /* if we did have a switch, look for more (there will more if there was one) */ + for (;; ) { + /* reset exchange flag so it's only set if we encounter another one */ + swixd = 0; + for (edgec = &ctx->possible_edges; (e_curr = *edgec)->e_next; edgec = &(*edgec)->e_next) { + /* again, if current edge hits scan line at higher X than next edge, + * exchange the edges and set flag */ + if (e_curr->x > e_curr->e_next->x) { + *edgec = e_curr->e_next; + /* exchange the pointers */ + e_temp = e_curr->e_next->e_next; + e_curr->e_next->e_next = e_curr; + e_curr->e_next = e_temp; + /* flip the exchanged flag */ + swixd = 1; + } + } + /* if we had no exchanges, we're done reshuffling the pointers */ + if (!swixd) { + break; + } + } + } + } + + free(edgbuf); + return 1; +} + +int PLX_raskterize_feather(float (*base_verts)[2], int num_base_verts, float (*feather_verts)[2], int num_feather_verts, + float *buf, int buf_x, int buf_y) +{ + int i; /* i: Loop counter. */ + struct poly_vert *fe; /* fe: Pointer to a list of integer buffer-space feather vertex coords. */ + struct r_fill_context ctx = {0}; + + /* for faster multiply */ + const float buf_x_f = (float)buf_x; + const float buf_y_f = (float)buf_y; + + /* + * Allocate enough memory for our poly_vert list. It'll be the size of the poly_vert + * data structure multiplied by the number of verts. + * + * In the event of a failure to allocate the memory, return 0, so this error can + * be distinguished as a memory allocation error. + */ + if ((fe = (struct poly_vert *)(malloc(sizeof(struct poly_vert) * num_feather_verts))) == NULL) { + return(0); + } + + /* + * Loop over all verts passed in to be rasterized. Each vertex's X and Y coordinates are + * then converted from normalized screen space (0.0 <= POS <= 1.0) to integer coordinates + * in the buffer-space coordinates passed in inside buf_x and buf_y. + * + * It's worth noting that this function ONLY outputs fully white pixels in a mask. Every pixel + * drawn will be 1.0f in value, there is no anti-aliasing. + */ + for (i = 0; i < num_feather_verts; i++) { /* Loop over all verts. */ + fe[i].x = (int)((feather_verts[i][0] * buf_x_f) + 0.5f); /* Range expand normalized X to integer buffer-space X. */ + fe[i].y = (int)((feather_verts[i][1] * buf_y_f) + 0.5f); /* Range expand normalized Y to integer buffer-space Y. */ + } + + ctx.rb.buf = buf; /* Set the output buffer pointer. */ + ctx.rb.sizex = buf_x; /* Set the output buffer size in X. (width) */ + ctx.rb.sizey = buf_y; /* Set the output buffer size in Y. (height) */ + + /* Call our rasterizer, passing in the integer coords for each vert. */ + i = rast_scan_feather(&ctx, base_verts, num_base_verts, fe, feather_verts, num_feather_verts); + free(fe); + return i; /* Return the value returned by the rasterizer. */ +} diff --git a/intern/raskter/raskter.h b/intern/raskter/raskter.h new file mode 100644 index 00000000000..e80ca1d41c4 --- /dev/null +++ b/intern/raskter/raskter.h @@ -0,0 +1,59 @@ +/* + * ***** 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) 2012 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Peter Larabell. + * + * ***** END GPL LICENSE BLOCK ***** + */ +/** \file raskter.h + * \ingroup RASKTER + */ + +struct poly_vert { + int x; + int y; +}; + +struct scan_line { + int xstart; + int xend; +}; + +struct scan_line_batch { + int num; + int ystart; + struct scan_line *slines; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +int PLX_raskterize(float (*base_verts)[2], int num_base_verts, + float *buf, int buf_x, int buf_y); +int PLX_raskterize_feather(float (*base_verts)[2], int num_base_verts, + float (*feather_verts)[2], int num_feather_verts, + float *buf, int buf_x, int buf_y); + +#ifdef __cplusplus +} +#endif diff --git a/intern/utfconv/utfconv.c b/intern/utfconv/utfconv.c index 189141e487d..a9b2920111d 100644 --- a/intern/utfconv/utfconv.c +++ b/intern/utfconv/utfconv.c @@ -34,7 +34,7 @@ size_t count_utf_8_from_16(const wchar_t *string16) return 0; } - for (i = 0; (u = string16[i]); i++) { + for (i = 0; (u = string16[i]); i++) { if (u < 0x0080) { count += 1; } |