[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [50603] trunk/blender/intern/cycles/kernel /osl: Added Object Info node implementation for OSL.

Lukas Toenne lukas.toenne at googlemail.com
Fri Sep 14 20:10:54 CEST 2012


Revision: 50603
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=50603
Author:   lukastoenne
Date:     2012-09-14 18:10:54 +0000 (Fri, 14 Sep 2012)
Log Message:
-----------
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.

Modified Paths:
--------------
    trunk/blender/intern/cycles/kernel/osl/nodes/CMakeLists.txt
    trunk/blender/intern/cycles/kernel/osl/osl_services.cpp

Added Paths:
-----------
    trunk/blender/intern/cycles/kernel/osl/nodes/node_object_info.osl

Modified: trunk/blender/intern/cycles/kernel/osl/nodes/CMakeLists.txt
===================================================================
--- trunk/blender/intern/cycles/kernel/osl/nodes/CMakeLists.txt	2012-09-14 16:43:07 UTC (rev 50602)
+++ trunk/blender/intern/cycles/kernel/osl/nodes/CMakeLists.txt	2012-09-14 18:10:54 UTC (rev 50603)
@@ -38,6 +38,7 @@
 	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

Added: trunk/blender/intern/cycles/kernel/osl/nodes/node_object_info.osl
===================================================================
--- trunk/blender/intern/cycles/kernel/osl/nodes/node_object_info.osl	                        (rev 0)
+++ trunk/blender/intern/cycles/kernel/osl/nodes/node_object_info.osl	2012-09-14 18:10:54 UTC (rev 50603)
@@ -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);
+}
+

Modified: trunk/blender/intern/cycles/kernel/osl/osl_services.cpp
===================================================================
--- trunk/blender/intern/cycles/kernel/osl/osl_services.cpp	2012-09-14 16:43:07 UTC (rev 50602)
+++ trunk/blender/intern/cycles/kernel/osl/osl_services.cpp	2012-09-14 18:10:54 UTC (rev 50603)
@@ -179,57 +179,67 @@
 	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
 		return false;
 }
@@ -243,11 +253,46 @@
 		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 @@
 	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;




More information about the Bf-blender-cvs mailing list