2011-04-27 11:58:34 +00:00
|
|
|
/*
|
|
|
|
* 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 <string.h>
|
|
|
|
|
|
|
|
#include "mesh.h"
|
|
|
|
#include "object.h"
|
|
|
|
#include "scene.h"
|
|
|
|
|
|
|
|
#include "osl_services.h"
|
|
|
|
#include "osl_shader.h"
|
|
|
|
|
|
|
|
#include "util_foreach.h"
|
|
|
|
#include "util_string.h"
|
|
|
|
|
|
|
|
#include "kernel_compat_cpu.h"
|
|
|
|
#include "kernel_globals.h"
|
|
|
|
#include "kernel_object.h"
|
|
|
|
#include "kernel_triangle.h"
|
|
|
|
|
|
|
|
CCL_NAMESPACE_BEGIN
|
|
|
|
|
|
|
|
/* RenderServices implementation */
|
|
|
|
|
2012-06-04 22:44:58 +00:00
|
|
|
#define TO_MATRIX44(m) (*(OSL::Matrix44 *)&(m))
|
2011-04-27 11:58:34 +00:00
|
|
|
|
|
|
|
/* static ustrings */
|
|
|
|
ustring OSLRenderServices::u_distance("distance");
|
|
|
|
ustring OSLRenderServices::u_index("index");
|
|
|
|
ustring OSLRenderServices::u_camera("camera");
|
|
|
|
ustring OSLRenderServices::u_screen("screen");
|
|
|
|
ustring OSLRenderServices::u_raster("raster");
|
|
|
|
ustring OSLRenderServices::u_ndc("NDC");
|
|
|
|
ustring OSLRenderServices::u_empty;
|
|
|
|
|
|
|
|
OSLRenderServices::OSLRenderServices()
|
|
|
|
{
|
|
|
|
kernel_globals = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
OSLRenderServices::~OSLRenderServices()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void OSLRenderServices::thread_init(KernelGlobals *kernel_globals_)
|
|
|
|
{
|
|
|
|
kernel_globals = 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
|
2012-06-09 17:22:52 +00:00
|
|
|
* a concept of shader space, so we just use object space for both. */
|
2012-06-04 22:44:58 +00:00
|
|
|
if (xform) {
|
2011-04-27 11:58:34 +00:00
|
|
|
KernelGlobals *kg = kernel_globals;
|
2012-06-04 22:44:58 +00:00
|
|
|
const ShaderData *sd = (const ShaderData *)xform;
|
2011-04-27 11:58:34 +00:00
|
|
|
int object = sd->object;
|
|
|
|
|
2012-06-04 22:44:58 +00:00
|
|
|
if (object != ~0) {
|
2012-06-05 15:40:02 +00:00
|
|
|
Transform tfm = object_fetch_transform(kg, object, time, OBJECT_TRANSFORM);
|
2011-04-27 11:58:34 +00:00
|
|
|
tfm = transform_transpose(tfm);
|
|
|
|
result = TO_MATRIX44(tfm);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
2012-06-09 17:22:52 +00:00
|
|
|
* a concept of shader space, so we just use object space for both. */
|
2012-06-04 22:44:58 +00:00
|
|
|
if (xform) {
|
2011-04-27 11:58:34 +00:00
|
|
|
KernelGlobals *kg = kernel_globals;
|
2012-06-04 22:44:58 +00:00
|
|
|
const ShaderData *sd = (const ShaderData *)xform;
|
2011-04-27 11:58:34 +00:00
|
|
|
int object = sd->object;
|
|
|
|
|
2012-06-04 22:44:58 +00:00
|
|
|
if (object != ~0) {
|
2012-06-05 15:40:02 +00:00
|
|
|
Transform tfm = object_fetch_transform(kg, object, time, OBJECT_INVERSE_TRANSFORM);
|
2011-04-27 11:58:34 +00:00
|
|
|
tfm = transform_transpose(tfm);
|
|
|
|
result = TO_MATRIX44(tfm);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool OSLRenderServices::get_matrix(OSL::Matrix44 &result, ustring from, float time)
|
|
|
|
{
|
|
|
|
KernelGlobals *kg = kernel_globals;
|
|
|
|
|
2012-06-04 22:44:58 +00:00
|
|
|
if (from == u_ndc) {
|
2011-04-27 11:58:34 +00:00
|
|
|
Transform tfm = transform_transpose(kernel_data.cam.ndctoworld);
|
|
|
|
result = TO_MATRIX44(tfm);
|
|
|
|
return true;
|
|
|
|
}
|
2012-06-04 22:44:58 +00:00
|
|
|
else if (from == u_raster) {
|
2011-04-27 11:58:34 +00:00
|
|
|
Transform tfm = transform_transpose(kernel_data.cam.rastertoworld);
|
|
|
|
result = TO_MATRIX44(tfm);
|
|
|
|
return true;
|
|
|
|
}
|
2012-06-04 22:44:58 +00:00
|
|
|
else if (from == u_screen) {
|
2011-04-27 11:58:34 +00:00
|
|
|
Transform tfm = transform_transpose(kernel_data.cam.screentoworld);
|
|
|
|
result = TO_MATRIX44(tfm);
|
|
|
|
return true;
|
|
|
|
}
|
2012-06-04 22:44:58 +00:00
|
|
|
else if (from == u_camera) {
|
2011-04-27 11:58:34 +00:00
|
|
|
Transform tfm = transform_transpose(kernel_data.cam.cameratoworld);
|
|
|
|
result = TO_MATRIX44(tfm);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool OSLRenderServices::get_inverse_matrix(OSL::Matrix44 &result, ustring to, float time)
|
|
|
|
{
|
|
|
|
KernelGlobals *kg = kernel_globals;
|
|
|
|
|
2012-06-04 22:44:58 +00:00
|
|
|
if (to == u_ndc) {
|
2011-04-27 11:58:34 +00:00
|
|
|
Transform tfm = transform_transpose(kernel_data.cam.worldtondc);
|
|
|
|
result = TO_MATRIX44(tfm);
|
|
|
|
return true;
|
|
|
|
}
|
2012-06-04 22:44:58 +00:00
|
|
|
else if (to == u_raster) {
|
2011-04-27 11:58:34 +00:00
|
|
|
Transform tfm = transform_transpose(kernel_data.cam.worldtoraster);
|
|
|
|
result = TO_MATRIX44(tfm);
|
|
|
|
return true;
|
|
|
|
}
|
2012-06-04 22:44:58 +00:00
|
|
|
else if (to == u_screen) {
|
2011-04-27 11:58:34 +00:00
|
|
|
Transform tfm = transform_transpose(kernel_data.cam.worldtoscreen);
|
|
|
|
result = TO_MATRIX44(tfm);
|
|
|
|
return true;
|
|
|
|
}
|
2012-06-04 22:44:58 +00:00
|
|
|
else if (to == u_camera) {
|
2011-04-27 11:58:34 +00:00
|
|
|
Transform tfm = transform_transpose(kernel_data.cam.worldtocamera);
|
|
|
|
result = TO_MATRIX44(tfm);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2012-09-02 01:10:31 +00:00
|
|
|
bool OSLRenderServices::get_matrix(OSL::Matrix44 &result, OSL::TransformationPtr xform)
|
|
|
|
{
|
|
|
|
// XXX implementation
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool OSLRenderServices::get_matrix(OSL::Matrix44 &result, ustring from)
|
|
|
|
{
|
|
|
|
// XXX implementation
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
bool OSLRenderServices::get_array_attribute(void *renderstate, bool derivatives,
|
2012-06-04 22:44:58 +00:00
|
|
|
ustring object, TypeDesc type, ustring name,
|
|
|
|
int index, void *val)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool get_mesh_attribute(KernelGlobals *kg, const ShaderData *sd,
|
2012-06-04 22:44:58 +00:00
|
|
|
const OSLGlobals::Attribute& attr, bool derivatives, void *val)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
2012-06-04 22:44:58 +00:00
|
|
|
if (attr.type == TypeDesc::TypeFloat) {
|
|
|
|
float *fval = (float *)val;
|
2011-04-27 11:58:34 +00:00
|
|
|
fval[0] = triangle_attribute_float(kg, sd, attr.elem, attr.offset,
|
2012-06-04 22:44:58 +00:00
|
|
|
(derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
|
|
|
else {
|
2011-05-31 16:21:30 +00:00
|
|
|
/* todo: this won't work when float3 has w component */
|
2012-06-04 22:44:58 +00:00
|
|
|
float3 *fval = (float3 *)val;
|
2011-04-27 11:58:34 +00:00
|
|
|
fval[0] = triangle_attribute_float3(kg, sd, attr.elem, attr.offset,
|
2012-06-04 22:44:58 +00:00
|
|
|
(derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool get_mesh_attribute_convert(KernelGlobals *kg, const ShaderData *sd,
|
2012-06-04 22:44:58 +00:00
|
|
|
const OSLGlobals::Attribute& attr, const TypeDesc& type, bool derivatives, void *val)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
2012-06-04 22:44:58 +00:00
|
|
|
if (attr.type == TypeDesc::TypeFloat) {
|
2011-04-27 11:58:34 +00:00
|
|
|
float tmp[3];
|
2012-06-04 22:44:58 +00:00
|
|
|
float3 *fval = (float3 *)val;
|
2011-04-27 11:58:34 +00:00
|
|
|
|
|
|
|
get_mesh_attribute(kg, sd, attr, derivatives, tmp);
|
|
|
|
|
|
|
|
fval[0] = make_float3(tmp[0], tmp[0], tmp[0]);
|
2012-06-04 22:44:58 +00:00
|
|
|
if (derivatives) {
|
2011-04-27 11:58:34 +00:00
|
|
|
fval[1] = make_float3(tmp[1], tmp[1], tmp[1]);
|
|
|
|
fval[2] = make_float3(tmp[2], tmp[2], tmp[2]);
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2012-06-04 22:44:58 +00:00
|
|
|
else if (attr.type == TypeDesc::TypePoint || attr.type == TypeDesc::TypeVector ||
|
|
|
|
attr.type == TypeDesc::TypeNormal || attr.type == TypeDesc::TypeColor)
|
|
|
|
{
|
2011-04-27 11:58:34 +00:00
|
|
|
float3 tmp[3];
|
2012-06-04 22:44:58 +00:00
|
|
|
float *fval = (float *)val;
|
2011-04-27 11:58:34 +00:00
|
|
|
|
|
|
|
get_mesh_attribute(kg, sd, attr, derivatives, tmp);
|
|
|
|
|
|
|
|
fval[0] = average(tmp[0]);
|
2012-06-04 22:44:58 +00:00
|
|
|
if (derivatives) {
|
2011-04-27 11:58:34 +00:00
|
|
|
fval[1] = average(tmp[1]);
|
|
|
|
fval[2] = average(tmp[2]);
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void get_object_attribute(const OSLGlobals::Attribute& attr, bool derivatives, void *val)
|
|
|
|
{
|
|
|
|
size_t datasize = attr.value.datasize();
|
|
|
|
|
|
|
|
memcpy(val, attr.value.data(), datasize);
|
2012-06-04 22:44:58 +00:00
|
|
|
if (derivatives)
|
|
|
|
memset((char *)val + datasize, 0, datasize * 2);
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool OSLRenderServices::get_attribute(void *renderstate, bool derivatives, ustring object_name,
|
2012-06-04 22:44:58 +00:00
|
|
|
TypeDesc type, ustring name, void *val)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
|
|
|
KernelGlobals *kg = kernel_globals;
|
2012-06-04 22:44:58 +00:00
|
|
|
const ShaderData *sd = (const ShaderData *)renderstate;
|
2011-04-27 11:58:34 +00:00
|
|
|
int object = sd->object;
|
|
|
|
int tri = sd->prim;
|
|
|
|
|
|
|
|
/* lookup of attribute on another object */
|
2012-06-04 22:44:58 +00:00
|
|
|
if (object_name != u_empty) {
|
2011-04-27 11:58:34 +00:00
|
|
|
OSLGlobals::ObjectNameMap::iterator it = kg->osl.object_name_map.find(object_name);
|
|
|
|
|
2012-06-04 22:44:58 +00:00
|
|
|
if (it == kg->osl.object_name_map.end())
|
2011-04-27 11:58:34 +00:00
|
|
|
return false;
|
|
|
|
|
|
|
|
object = it->second;
|
|
|
|
tri = ~0;
|
|
|
|
}
|
2012-06-04 22:44:58 +00:00
|
|
|
else if (object == ~0) {
|
2011-04-27 11:58:34 +00:00
|
|
|
/* no background attributes supported */
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* find attribute on object */
|
|
|
|
OSLGlobals::AttributeMap& attribute_map = kg->osl.attribute_map[object];
|
|
|
|
OSLGlobals::AttributeMap::iterator it = attribute_map.find(name);
|
|
|
|
|
2012-06-04 22:44:58 +00:00
|
|
|
if (it == attribute_map.end())
|
2011-04-27 11:58:34 +00:00
|
|
|
return false;
|
|
|
|
|
|
|
|
/* type mistmatch? */
|
|
|
|
const OSLGlobals::Attribute& attr = it->second;
|
|
|
|
|
2012-06-04 22:44:58 +00:00
|
|
|
if (attr.elem != ATTR_ELEMENT_VALUE) {
|
2011-04-27 11:58:34 +00:00
|
|
|
/* triangle and vertex attributes */
|
2012-06-04 22:44:58 +00:00
|
|
|
if (tri != ~0) {
|
|
|
|
if (attr.type == type || (attr.type == TypeDesc::TypeColor &&
|
|
|
|
(type == TypeDesc::TypePoint || type == TypeDesc::TypeVector || type == TypeDesc::TypeNormal)))
|
|
|
|
{
|
2011-04-27 11:58:34 +00:00
|
|
|
return get_mesh_attribute(kg, sd, attr, derivatives, val);
|
2012-06-04 22:44:58 +00:00
|
|
|
}
|
|
|
|
else {
|
2011-04-27 11:58:34 +00:00
|
|
|
return get_mesh_attribute_convert(kg, sd, attr, type, derivatives, val);
|
2012-06-04 22:44:58 +00:00
|
|
|
}
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* object attribute */
|
|
|
|
get_object_attribute(attr, derivatives, val);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool OSLRenderServices::get_userdata(bool derivatives, ustring name, TypeDesc type,
|
2012-06-04 22:44:58 +00:00
|
|
|
void *renderstate, void *val)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
|
|
|
return false; /* disabled by lockgeom */
|
|
|
|
}
|
|
|
|
|
|
|
|
bool OSLRenderServices::has_userdata(ustring name, TypeDesc type, void *renderstate)
|
|
|
|
{
|
|
|
|
return false; /* never called by OSL */
|
|
|
|
}
|
|
|
|
|
2012-09-02 01:10:31 +00:00
|
|
|
int OSLRenderServices::pointcloud_search(OSL::ShaderGlobals *sg, ustring filename, const OSL::Vec3 ¢er,
|
|
|
|
float radius, int max_points, bool sort, size_t *out_indices, float *out_distances, int derivs_offset)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
2012-09-02 01:10:31 +00:00
|
|
|
return 0;
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
|
|
|
|
2012-09-02 01:10:31 +00:00
|
|
|
int OSLRenderServices::pointcloud_get(ustring filename, size_t *indices, int count,
|
|
|
|
ustring attr_name, TypeDesc attr_type, void *out_data)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
2012-09-02 01:10:31 +00:00
|
|
|
return 0;
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
CCL_NAMESPACE_END
|