1 // Copyright Contributors to the Open Shading Language project.
2 // SPDX-License-Identifier: BSD-3-Clause
3 // https://github.com/AcademySoftwareFoundation/OpenShadingLanguage
4
5 /////////////////////////////////////////////////////////////////////////
6 /// \file
7 ///
8 /// Shader interpreter implementation of spline
9 /// operator
10 ///
11 /////////////////////////////////////////////////////////////////////////
12
13
14
15 // If enabled, derivatives associated with the knot vectors are
16 // ignored
17 //#define SKIP_KNOT_DERIVS 1
18
19
20 #include "oslexec_pvt.h"
21 #include <OSL/dual_vec.h>
22 #include <OSL/Imathx/Imathx.h>
23 #include <OSL/device_string.h>
24
25 #include <OpenImageIO/fmath.h>
26 #include "splineimpl.h"
27
28 OSL_NAMESPACE_ENTER
29
30 namespace pvt {
31
32
osl_spline_fff(void * out,const char * spline_,void * x,void * knots,int knot_count,int knot_arraylen)33 OSL_SHADEOP OSL_HOSTDEVICE void osl_spline_fff(void *out, const char *spline_, void *x,
34 void* knots, int knot_count, int knot_arraylen)
35 {
36 Spline::SplineInterp::create(HDSTR(spline_)).evaluate<float, float, float, float, false>
37 (*(float *)out, *(float *)x, (float *)knots, knot_count, knot_arraylen);
38 }
39
osl_spline_dfdfdf(void * out,const char * spline_,void * x,void * knots,int knot_count,int knot_arraylen)40 OSL_SHADEOP OSL_HOSTDEVICE void osl_spline_dfdfdf(void *out, const char *spline_, void *x,
41 void* knots, int knot_count, int knot_arraylen)
42 {
43 Spline::SplineInterp::create(HDSTR(spline_)).evaluate<Dual2<float>, Dual2<float>, Dual2<float>, float, true>
44 (DFLOAT(out), DFLOAT(x), (float *) knots, knot_count, knot_arraylen);
45 }
46
osl_spline_dffdf(void * out,const char * spline_,void * x,void * knots,int knot_count,int knot_arraylen)47 OSL_SHADEOP OSL_HOSTDEVICE void osl_spline_dffdf(void *out, const char *spline_, void *x,
48 void* knots, int knot_count, int knot_arraylen)
49 {
50 Spline::SplineInterp::create(HDSTR(spline_)).evaluate<Dual2<float>, float, Dual2<float>, float, true>
51 (DFLOAT(out), *(float *)x, (float *) knots, knot_count, knot_arraylen);
52 }
53
osl_spline_dfdff(void * out,const char * spline_,void * x,void * knots,int knot_count,int knot_arraylen)54 OSL_SHADEOP OSL_HOSTDEVICE void osl_spline_dfdff(void *out, const char *spline_, void *x,
55 void* knots, int knot_count, int knot_arraylen)
56 {
57 Spline::SplineInterp::create(HDSTR(spline_)).evaluate<Dual2<float>, Dual2<float>, float, float, false>
58 (DFLOAT(out), DFLOAT(x), (float *) knots, knot_count, knot_arraylen);
59 }
60
osl_spline_vfv(void * out,const char * spline_,void * x,void * knots,int knot_count,int knot_arraylen)61 OSL_SHADEOP OSL_HOSTDEVICE void osl_spline_vfv(void *out, const char *spline_, void *x,
62 void *knots, int knot_count, int knot_arraylen)
63 {
64 Spline::SplineInterp::create(HDSTR(spline_)).evaluate<Vec3, float, Vec3, Vec3, false>
65 (*(Vec3 *)out, *(float *)x, (Vec3 *) knots, knot_count, knot_arraylen);
66 }
67
osl_spline_dvdfv(void * out,const char * spline_,void * x,void * knots,int knot_count,int knot_arraylen)68 OSL_SHADEOP OSL_HOSTDEVICE void osl_spline_dvdfv(void *out, const char *spline_, void *x,
69 void *knots, int knot_count, int knot_arraylen)
70 {
71 Spline::SplineInterp::create(HDSTR(spline_)).evaluate<Dual2<Vec3>, Dual2<float>, Vec3, Vec3, false>
72 (DVEC(out), DFLOAT(x), (Vec3 *) knots, knot_count, knot_arraylen);
73 }
74
osl_spline_dvfdv(void * out,const char * spline_,void * x,void * knots,int knot_count,int knot_arraylen)75 OSL_SHADEOP OSL_HOSTDEVICE void osl_spline_dvfdv(void *out, const char *spline_, void *x,
76 void *knots, int knot_count, int knot_arraylen)
77 {
78 Spline::SplineInterp::create(HDSTR(spline_)).evaluate<Dual2<Vec3>, float, Dual2<Vec3>, Vec3, true>
79 (DVEC(out), *(float *)x, (Vec3 *) knots, knot_count, knot_arraylen);
80 }
81
osl_spline_dvdfdv(void * out,const char * spline_,void * x,void * knots,int knot_count,int knot_arraylen)82 OSL_SHADEOP OSL_HOSTDEVICE void osl_spline_dvdfdv(void *out, const char *spline_, void *x,
83 void *knots, int knot_count, int knot_arraylen)
84 {
85 Spline::SplineInterp::create(HDSTR(spline_)).evaluate<Dual2<Vec3>, Dual2<float>, Dual2<Vec3>, Vec3, true>
86 (DVEC(out), DFLOAT(x), (Vec3 *) knots, knot_count, knot_arraylen);
87 }
88
osl_splineinverse_fff(void * out,const char * spline_,void * x,void * knots,int knot_count,int knot_arraylen)89 OSL_SHADEOP OSL_HOSTDEVICE void osl_splineinverse_fff(void *out, const char *spline_, void *x,
90 void* knots, int knot_count, int knot_arraylen)
91 {
92 // Version with no derivs
93 Spline::SplineInterp::create(HDSTR(spline_)).inverse<float>
94 (*(float *)out, *(float *)x, (float *) knots, knot_count, knot_arraylen);
95 }
96
osl_splineinverse_dfdff(void * out,const char * spline_,void * x,void * knots,int knot_count,int knot_arraylen)97 OSL_SHADEOP OSL_HOSTDEVICE void osl_splineinverse_dfdff(void *out, const char *spline_, void *x,
98 void* knots, int knot_count, int knot_arraylen)
99 {
100 // x has derivs, so return derivs as well
101 Spline::SplineInterp::create(HDSTR(spline_)).inverse<Dual2<float> >
102 (DFLOAT(out), DFLOAT(x), (float *) knots, knot_count, knot_arraylen);
103 }
104
osl_splineinverse_dfdfdf(void * out,const char * spline_,void * x,void * knots,int knot_count,int knot_arraylen)105 OSL_SHADEOP OSL_HOSTDEVICE void osl_splineinverse_dfdfdf(void *out, const char *spline_, void *x,
106 void* knots, int knot_count, int knot_arraylen)
107 {
108 // Ignore knot derivatives
109 osl_splineinverse_dfdff (out, spline_, x, (float *) knots, knot_count, knot_arraylen);
110 }
111
osl_splineinverse_dffdf(void * out,const char * spline_,void * x,void * knots,int knot_count,int knot_arraylen)112 OSL_SHADEOP OSL_HOSTDEVICE void osl_splineinverse_dffdf(void *out, const char *spline_, void *x,
113 void* knots, int knot_count, int knot_arraylen)
114 {
115 // Ignore knot derivs
116 float outtmp = 0;
117 osl_splineinverse_fff (&outtmp, spline_, x, (float *) knots, knot_count, knot_arraylen);
118 DFLOAT(out) = outtmp;
119 }
120
121
122
123 } // namespace pvt
124 OSL_NAMESPACE_EXIT
125