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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/intern
diff options
context:
space:
mode:
authorLukas Toenne <lukas.toenne@googlemail.com>2012-09-14 22:10:54 +0400
committerLukas Toenne <lukas.toenne@googlemail.com>2012-09-14 22:10:54 +0400
commitdf79ab5a778e877ff371ac571afcc55f2558b6f6 (patch)
tree222169846c5c7ce73c3c4c8924ba33b66e155d68 /intern
parentb48398c96aa91fec0f5a5f34c36b9d2dae61718f (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.txt1
-rw-r--r--intern/cycles/kernel/osl/nodes/node_object_info.osl33
-rw-r--r--intern/cycles/kernel/osl/osl_services.cpp149
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;