diff options
author | Lukas Toenne <lukas.toenne@googlemail.com> | 2012-09-14 22:10:54 +0400 |
---|---|---|
committer | Lukas Toenne <lukas.toenne@googlemail.com> | 2012-09-14 22:10:54 +0400 |
commit | df79ab5a778e877ff371ac571afcc55f2558b6f6 (patch) | |
tree | 222169846c5c7ce73c3c4c8924ba33b66e155d68 /intern | |
parent | b48398c96aa91fec0f5a5f34c36b9d2dae61718f (diff) |
Added Object Info node implementation for OSL. This uses an additional attribute check in the osl_services callback for special attribute names related to objects:
* std::object_location
* std::object_index
* std::material_index
* std::object_random
Other object-based attributes can be added for particle info in the same way.
Diffstat (limited to 'intern')
-rw-r--r-- | intern/cycles/kernel/osl/nodes/CMakeLists.txt | 1 | ||||
-rw-r--r-- | intern/cycles/kernel/osl/nodes/node_object_info.osl | 33 | ||||
-rw-r--r-- | intern/cycles/kernel/osl/osl_services.cpp | 149 |
3 files changed, 128 insertions, 55 deletions
diff --git a/intern/cycles/kernel/osl/nodes/CMakeLists.txt b/intern/cycles/kernel/osl/nodes/CMakeLists.txt index 08e9b9ee726..48039fcc243 100644 --- a/intern/cycles/kernel/osl/nodes/CMakeLists.txt +++ b/intern/cycles/kernel/osl/nodes/CMakeLists.txt @@ -38,6 +38,7 @@ set(SRC_OSL node_musgrave_texture.osl node_normal.osl node_noise_texture.osl + node_object_info.osl node_output_displacement.osl node_output_surface.osl node_output_volume.osl diff --git a/intern/cycles/kernel/osl/nodes/node_object_info.osl b/intern/cycles/kernel/osl/nodes/node_object_info.osl new file mode 100644 index 00000000000..21e50d8a43e --- /dev/null +++ b/intern/cycles/kernel/osl/nodes/node_object_info.osl @@ -0,0 +1,33 @@ +/* + * 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 "stdosl.h" + +shader node_object_info( + output point Location = point(0.0, 0.0, 0.0), + output float ObjectIndex = 0.0, + output float MaterialIndex = 0.0, + output float Random = 0.0 + ) +{ + getattribute("std::object_location", Location); + getattribute("std::object_index", ObjectIndex); + getattribute("std::material_index", MaterialIndex); + getattribute("std::object_random", Random); +} + diff --git a/intern/cycles/kernel/osl/osl_services.cpp b/intern/cycles/kernel/osl/osl_services.cpp index a3f2c2ea369..41176456e84 100644 --- a/intern/cycles/kernel/osl/osl_services.cpp +++ b/intern/cycles/kernel/osl/osl_services.cpp @@ -179,55 +179,65 @@ bool OSLRenderServices::get_array_attribute(void *renderstate, bool derivatives, return false; } -static bool get_mesh_attribute(KernelGlobals *kg, const ShaderData *sd, - const OSLGlobals::Attribute& attr, bool derivatives, void *val) +static void set_attribute_float3(float3 f[3], TypeDesc type, bool derivatives, void *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); + if (type == TypeDesc::TypePoint || type == TypeDesc::TypeVector || + type == TypeDesc::TypeNormal || type == TypeDesc::TypeColor) { + float3 *fval = (float3 *)val; + fval[0] = f[0]; + if (derivatives) { + fval[1] = f[1]; + fval[2] = f[2]; + } } else { - /* todo: this won't work when float3 has w component */ - float3 *fval = (float3 *)val; - fval[0] = triangle_attribute_float3(kg, sd, attr.elem, attr.offset, - (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL); + float *fval = (float *)val; + fval[0] = average(f[0]); + if (derivatives) { + fval[1] = average(f[1]); + fval[2] = average(f[2]); + } } - - return true; } -static bool get_mesh_attribute_convert(KernelGlobals *kg, const ShaderData *sd, - const OSLGlobals::Attribute& attr, const TypeDesc& type, bool derivatives, void *val) +static void set_attribute_float(float f[3], TypeDesc type, bool derivatives, void *val) { - if (attr.type == TypeDesc::TypeFloat) { - float tmp[3]; + if (type == TypeDesc::TypePoint || type == TypeDesc::TypeVector || + type == TypeDesc::TypeNormal || type == TypeDesc::TypeColor) { float3 *fval = (float3 *)val; - - get_mesh_attribute(kg, sd, attr, derivatives, tmp); - - fval[0] = make_float3(tmp[0], tmp[0], tmp[0]); + fval[0] = make_float3(f[0], f[0], f[0]); if (derivatives) { - fval[1] = make_float3(tmp[1], tmp[1], tmp[1]); - fval[2] = make_float3(tmp[2], tmp[2], tmp[2]); + fval[1] = make_float3(f[1], f[2], f[1]); + fval[2] = make_float3(f[2], f[2], f[2]); } - - return true; } - else if (attr.type == TypeDesc::TypePoint || attr.type == TypeDesc::TypeVector || - attr.type == TypeDesc::TypeNormal || attr.type == TypeDesc::TypeColor) - { - float3 tmp[3]; + else { float *fval = (float *)val; - - get_mesh_attribute(kg, sd, attr, derivatives, tmp); - - fval[0] = average(tmp[0]); + fval[0] = f[0]; if (derivatives) { - fval[1] = average(tmp[1]); - fval[2] = average(tmp[2]); + fval[1] = f[1]; + fval[2] = f[2]; } + } +} +static bool get_mesh_attribute(KernelGlobals *kg, const ShaderData *sd, const OSLGlobals::Attribute& attr, + const TypeDesc& type, bool derivatives, void *val) +{ + if (attr.type == TypeDesc::TypeFloat) { + float fval[3]; + fval[0] = triangle_attribute_float(kg, sd, attr.elem, attr.offset, + (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL); + set_attribute_float(fval, type, derivatives, val); + return true; + } + else if (attr.type == TypeDesc::TypePoint || attr.type == TypeDesc::TypeVector || + attr.type == TypeDesc::TypeNormal || attr.type == TypeDesc::TypeColor) { + /* todo: this won't work when float3 has w component */ + float3 fval[3]; + fval[0] = triangle_attribute_float3(kg, sd, attr.elem, attr.offset, + (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL); + set_attribute_float3(fval, type, derivatives, val); return true; } else @@ -243,11 +253,46 @@ static void get_object_attribute(const OSLGlobals::Attribute& attr, bool derivat memset((char *)val + datasize, 0, datasize * 2); } +static bool get_object_standard_attribute(KernelGlobals *kg, ShaderData *sd, ustring name, + TypeDesc type, bool derivatives, void *val) +{ + if (name == "std::object_location") { + float3 loc[3]; + loc[0] = object_location(kg, sd); + loc[1] = loc[2] = make_float3(0.0, 0.0, 0.0); /* derivates set to 0 */ + set_attribute_float3(loc, type, derivatives, val); + return true; + } + else if (name == "std::object_index") { + float loc[3]; + loc[0] = object_pass_id(kg, sd->object); + loc[1] = loc[2] = 0.0; /* derivates set to 0 */ + set_attribute_float(loc, type, derivatives, val); + return true; + } + else if (name == "std::material_index") { + float loc[3]; + loc[0] = shader_pass_id(kg, sd); + loc[1] = loc[2] = 0.0; /* derivates set to 0 */ + set_attribute_float(loc, type, derivatives, val); + return true; + } + else if (name == "std::object_random") { + float loc[3]; + loc[0] = object_random_number(kg, sd->object); + loc[1] = loc[2] = 0.0; /* derivates set to 0 */ + set_attribute_float(loc, type, derivatives, val); + return true; + } + else + return false; +} + bool OSLRenderServices::get_attribute(void *renderstate, bool derivatives, ustring object_name, TypeDesc type, ustring name, void *val) { KernelGlobals *kg = kernel_globals; - const ShaderData *sd = (const ShaderData *)renderstate; + ShaderData *sd = (ShaderData *)renderstate; int object = sd->object; int tri = sd->prim; @@ -270,29 +315,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()) - return false; - - /* type mistmatch? */ - const OSLGlobals::Attribute& attr = it->second; - - 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))) - { - return get_mesh_attribute(kg, sd, attr, derivatives, val); - } - else { - return get_mesh_attribute_convert(kg, sd, attr, type, derivatives, val); - } + if (it != attribute_map.end()) { + const OSLGlobals::Attribute& attr = it->second; + + if (attr.elem != ATTR_ELEMENT_VALUE) { + /* triangle and vertex attributes */ + if (tri != ~0) + return get_mesh_attribute(kg, sd, attr, type, derivatives, val); + } + else { + /* object attribute */ + get_object_attribute(attr, derivatives, val); + return true; } } else { - /* object attribute */ - get_object_attribute(attr, derivatives, val); - return true; + /* not found in attribute, check standard object info */ + return get_object_standard_attribute(kg, sd, name, type, derivatives, val); } return false; |