2
Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
5
Redistribution and use in source and binary forms, with or without
6
modification, are permitted provided that the following conditions are
8
* Redistributions of source code must retain the above copyright
9
notice, this list of conditions and the following disclaimer.
10
* Redistributions in binary form must reproduce the above copyright
11
notice, this list of conditions and the following disclaimer in the
12
documentation and/or other materials provided with the distribution.
13
* Neither the name of Sony Pictures Imageworks nor the names of its
14
contributors may be used to endorse or promote products derived from
15
this software without specific prior written permission.
16
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
#ifndef OSL_DUAL_VEC_H
30
#define OSL_DUAL_VEC_H
32
#include "oslconfig.h"
38
/// Templated trick to be able to derive what type we use to represent
39
/// a vector, given a scalar, automatically using the right kind of Dual2.
40
template<typename T> struct Vec3FromScalar {};
41
template<> struct Vec3FromScalar<float> { typedef Vec3 type; };
42
template<> struct Vec3FromScalar<Dual2<float> > { typedef Dual2<Vec3> type; };
44
/// Templated trick to be able to derive the scalar component type of
45
/// a vector, whether a VecN or a Dual2<VecN>.
46
template<typename T> struct ScalarFromVec {};
47
template<> struct ScalarFromVec<Vec3> { typedef Float type; };
48
template<> struct ScalarFromVec<Vec2> { typedef Float type; };
49
template<> struct ScalarFromVec<Dual2<Vec3> > { typedef Dual2<Float> type; };
50
template<> struct ScalarFromVec<Dual2<Vec2> > { typedef Dual2<Float> type; };
54
/// A uniform way to assemble a Vec3 from float and a Dual2<Vec3>
55
/// from Dual2<float>.
57
make_Vec3 (float x, float y, float z)
59
return Vec3 (x, y, z);
63
make_Vec3 (const Dual2<float> &x, const Dual2<float> &y, const Dual2<float> &z)
65
return Dual2<Vec3> (Vec3 (x.val(), y.val(), z.val()),
66
Vec3 (x.dx(), y.dx(), z.dx()),
67
Vec3 (x.dy(), y.dy(), z.dy()));
71
/// Make a Dual2<Vec3> from a single Dual2<Float> x coordinate, and 0
72
/// for the other components.
74
make_Vec3 (const Dual2<Float> &x)
76
return Dual2<Vec3> (Vec3 (x.val(), 0.0f, 0.0f),
77
Vec3 (x.dx(), 0.0f, 0.0f),
78
Vec3 (x.dy(), 0.0f, 0.0f));
83
make_Vec3 (const Dual2<Float> &x, const Dual2<Float> &y)
85
return Dual2<Vec3> (Vec3 (x.val(), y.val(), 0.0f),
86
Vec3 (x.dx(), y.dx(), 0.0f),
87
Vec3 (x.dy(), y.dy(), 0.0f));
93
/// A uniform way to assemble a Vec2 from float and a Dual2<Vec2>
94
/// from Dual2<float>.
96
make_Vec2 (float x, float y)
102
make_Vec2 (const Dual2<float> &x, const Dual2<float> &y)
104
return Dual2<Vec2> (Vec2 (x.val(), y.val()),
105
Vec2 (x.dx(), y.dx()),
106
Vec2 (x.dy(), y.dy()));
111
/// A uniform way to extract a single component from a Vec3 or Dual2<Vec3>
113
comp (const Vec3 &v, int c)
120
comp (const Dual2<Vec3> &v, int c)
122
return Dual2<float> (v.val()[c], v.dx()[c], v.dy()[c]);
127
/// Multiply a 3x3 matrix by a 3-vector, with derivs.
129
template <class S, class T>
131
multMatrix (const Imath::Matrix33<T> &M, const Dual2<Imath::Vec3<S> > &src,
132
Dual2<Imath::Vec3<S> > &dst)
134
Dual2<float> src0 = comp(src,0), src1 = comp(src,1), src2 = comp(src,2);
135
Dual2<S> a = src0 * M[0][0] + src1 * M[1][0] + src2 * M[2][0];
136
Dual2<S> b = src0 * M[0][1] + src1 * M[1][1] + src2 * M[2][1];
137
Dual2<S> c = src0 * M[0][2] + src1 * M[1][2] + src2 * M[2][2];
138
dst = make_Vec3 (a, b, c);
143
/// Multiply a matrix times a vector with derivatives to obtain
144
/// a transformed vector with derivatives.
146
multVecMatrix (const Matrix44 &M, Dual2<Vec3> &in, Dual2<Vec3> &out)
148
// Rearrange into a Vec3<Dual2<float> >
149
Imath::Vec3<Dual2<float> > din, dout;
150
for (int i = 0; i < 3; ++i)
151
din[i].set (in.val()[i], in.dx()[i], in.dy()[i]);
153
// N.B. the following function has a divide by 'w'
154
M.multVecMatrix (din, dout);
156
// Rearrange back into Dual2<Vec3>
157
out.set (Vec3 (dout[0].val(), dout[1].val(), dout[2].val()),
158
Vec3 (dout[0].dx(), dout[1].dx(), dout[2].dx()),
159
Vec3 (dout[0].dy(), dout[1].dy(), dout[2].dy()));
162
/// Multiply a matrix times a direction with derivatives to obtain
163
/// a transformed direction with derivatives.
165
multDirMatrix (const Matrix44 &M, Dual2<Vec3> &in, Dual2<Vec3> &out)
167
M.multDirMatrix (in.val(), out.val());
168
M.multDirMatrix (in.dx(), out.dx());
169
M.multDirMatrix (in.dy(), out.dy());
176
/// Templated trick to be able to derive what type we use to represent
177
/// a color, given a scalar, automatically using the right kind of Dual2.
178
template<typename T> struct Color3FromScalar {};
179
template<> struct Color3FromScalar<float> { typedef Color3 type; };
180
template<> struct Color3FromScalar<Dual2<float> > { typedef Dual2<Color3> type; };
183
/// A uniform way to assemble a Color3 from float and a Dual2<Color3>
184
/// from Dual2<float>.
186
make_Color3 (float x, float y, float z)
188
return Color3 (x, y, z);
192
make_Color3 (const Dual2<float> &x, const Dual2<float> &y, const Dual2<float> &z)
194
return Dual2<Color3> (Color3 (x.val(), y.val(), z.val()),
195
Color3 (x.dx(), y.dx(), z.dx()),
196
Color3 (x.dy(), y.dy(), z.dy()));
201
/// Various operator* permuations between Dual2<float> and Dual2<Vec3>
204
operator* (float a, const Dual2<Vec3> &b)
206
return Dual2<Vec3>(a*b.val(), a*b.dx(), a*b.dy());
210
operator* (const Dual2<Vec3> &a, float b)
212
return Dual2<Vec3>(a.val()*b, a.dx()*b, a.dy()*b);
216
operator* (const Vec3 &a, const Dual2<float> &b)
218
return Dual2<Vec3>(a*b.val(), a*b.dx(), a*b.dy());
222
operator* (const Dual2<Vec3> &a, const Dual2<float> &b)
224
return Dual2<Vec3>(a.val()*b.val(),
225
a.val()*b.dx() + a.dx()*b.val(),
226
a.val()*b.dy() + a.dy()*b.val());
231
dot (const Dual2<Vec3> &a, const Dual2<Vec3> &b)
233
Dual2<float> ax (a.val().x, a.dx().x, a.dy().x);
234
Dual2<float> ay (a.val().y, a.dx().y, a.dy().y);
235
Dual2<float> az (a.val().z, a.dx().z, a.dy().z);
236
Dual2<float> bx (b.val().x, b.dx().x, b.dy().x);
237
Dual2<float> by (b.val().y, b.dx().y, b.dy().y);
238
Dual2<float> bz (b.val().z, b.dx().z, b.dy().z);
239
return ax*bx + ay*by + az*bz;
245
dot (const Dual2<Vec3> &a, const Vec3 &b)
247
Dual2<float> ax (a.val().x, a.dx().x, a.dy().x);
248
Dual2<float> ay (a.val().y, a.dx().y, a.dy().y);
249
Dual2<float> az (a.val().z, a.dx().z, a.dy().z);
250
return ax*b.x + ay*b.y + az*b.z;
256
dot (const Vec3 &a, const Dual2<Vec3> &b)
258
Dual2<float> bx (b.val().x, b.dx().x, b.dy().x);
259
Dual2<float> by (b.val().y, b.dx().y, b.dy().y);
260
Dual2<float> bz (b.val().z, b.dx().z, b.dy().z);
261
return a.x*bx + a.y*by + a.z*bz;
267
dot (const Dual2<Vec2> &a, const Dual2<Vec2> &b)
269
Dual2<float> ax (a.val().x, a.dx().x, a.dy().x);
270
Dual2<float> ay (a.val().y, a.dx().y, a.dy().y);
271
Dual2<float> bx (b.val().x, b.dx().x, b.dy().x);
272
Dual2<float> by (b.val().y, b.dx().y, b.dy().y);
273
return ax*bx + ay*by;
279
dot (const Dual2<Vec2> &a, const Vec2 &b)
281
Dual2<float> ax (a.val().x, a.dx().x, a.dy().x);
282
Dual2<float> ay (a.val().y, a.dx().y, a.dy().y);
283
return ax*b.x + ay*b.y;
289
dot (const Vec2 &a, const Dual2<Vec2> &b)
291
Dual2<float> bx (b.val().x, b.dx().x, b.dy().x);
292
Dual2<float> by (b.val().y, b.dx().y, b.dy().y);
293
return a.x*bx + a.y*by;
299
cross (const Dual2<Vec3> &a, const Dual2<Vec3> &b)
301
Dual2<float> ax (a.val().x, a.dx().x, a.dy().x);
302
Dual2<float> ay (a.val().y, a.dx().y, a.dy().y);
303
Dual2<float> az (a.val().z, a.dx().z, a.dy().z);
304
Dual2<float> bx (b.val().x, b.dx().x, b.dy().x);
305
Dual2<float> by (b.val().y, b.dx().y, b.dy().y);
306
Dual2<float> bz (b.val().z, b.dx().z, b.dy().z);
308
Dual2<float> nx = ay*bz - az*by;
309
Dual2<float> ny = az*bx - ax*bz;
310
Dual2<float> nz = ax*by - ay*bx;
312
return Dual2<Vec3> (Vec3(nx.val(), ny.val(), nz.val()),
313
Vec3(nx.dx(), ny.dx(), nz.dx() ),
314
Vec3(nx.dy(), ny.dy(), nz.dy() ));
320
length (const Dual2<Vec3> &a)
322
Dual2<float> ax (a.val().x, a.dx().x, a.dy().x);
323
Dual2<float> ay (a.val().y, a.dx().y, a.dy().y);
324
Dual2<float> az (a.val().z, a.dx().z, a.dy().z);
325
return sqrt(ax*ax + ay*ay + az*az);
331
normalize (const Dual2<Vec3> &a)
333
if (a.val().x == 0 && a.val().y == 0 && a.val().z == 0) {
334
return Dual2<Vec3> (Vec3(0, 0, 0),
338
Dual2<float> ax (a.val().x, a.dx().x, a.dy().x);
339
Dual2<float> ay (a.val().y, a.dx().y, a.dy().y);
340
Dual2<float> az (a.val().z, a.dx().z, a.dy().z);
341
Dual2<float> inv_length = 1.0f / sqrt(ax*ax + ay*ay + az*az);
345
return Dual2<Vec3> (Vec3(ax.val(), ay.val(), az.val()),
346
Vec3(ax.dx(), ay.dx(), az.dx() ),
347
Vec3(ax.dy(), ay.dy(), az.dy() ));
354
distance (const Dual2<Vec3> &a, const Dual2<Vec3> &b)
356
Dual2<float> ax (a.val().x, a.dx().x, a.dy().x);
357
Dual2<float> ay (a.val().y, a.dx().y, a.dy().y);
358
Dual2<float> az (a.val().z, a.dx().z, a.dy().z);
359
Dual2<float> bx (b.val().x, b.dx().x, b.dy().x);
360
Dual2<float> by (b.val().y, b.dx().y, b.dy().y);
361
Dual2<float> bz (b.val().z, b.dx().z, b.dy().z);
363
Dual2<float> dx = bx - ax;
364
Dual2<float> dy = by - ay;
365
Dual2<float> dz = bz - az;
367
return sqrt(dx*dx + dy*dy + dz*dz);
374
#endif /* OSL_DUAL_VEC_H */
2
Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
5
Redistribution and use in source and binary forms, with or without
6
modification, are permitted provided that the following conditions are
8
* Redistributions of source code must retain the above copyright
9
notice, this list of conditions and the following disclaimer.
10
* Redistributions in binary form must reproduce the above copyright
11
notice, this list of conditions and the following disclaimer in the
12
documentation and/or other materials provided with the distribution.
13
* Neither the name of Sony Pictures Imageworks nor the names of its
14
contributors may be used to endorse or promote products derived from
15
this software without specific prior written permission.
16
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
#ifndef OSL_DUAL_VEC_H
30
#define OSL_DUAL_VEC_H
32
#include "oslconfig.h"
38
/// Templated trick to be able to derive what type we use to represent
39
/// a vector, given a scalar, automatically using the right kind of Dual2.
40
template<typename T> struct Vec3FromScalar {};
41
template<> struct Vec3FromScalar<float> { typedef Vec3 type; };
42
template<> struct Vec3FromScalar<Dual2<float> > { typedef Dual2<Vec3> type; };
44
/// Templated trick to be able to derive the scalar component type of
45
/// a vector, whether a VecN or a Dual2<VecN>.
46
template<typename T> struct ScalarFromVec {};
47
template<> struct ScalarFromVec<Vec3> { typedef Float type; };
48
template<> struct ScalarFromVec<Vec2> { typedef Float type; };
49
template<> struct ScalarFromVec<Dual2<Vec3> > { typedef Dual2<Float> type; };
50
template<> struct ScalarFromVec<Dual2<Vec2> > { typedef Dual2<Float> type; };
54
/// A uniform way to assemble a Vec3 from float and a Dual2<Vec3>
55
/// from Dual2<float>.
57
make_Vec3 (float x, float y, float z)
59
return Vec3 (x, y, z);
63
make_Vec3 (const Dual2<float> &x, const Dual2<float> &y, const Dual2<float> &z)
65
return Dual2<Vec3> (Vec3 (x.val(), y.val(), z.val()),
66
Vec3 (x.dx(), y.dx(), z.dx()),
67
Vec3 (x.dy(), y.dy(), z.dy()));
71
/// Make a Dual2<Vec3> from a single Dual2<Float> x coordinate, and 0
72
/// for the other components.
74
make_Vec3 (const Dual2<Float> &x)
76
return Dual2<Vec3> (Vec3 (x.val(), 0.0f, 0.0f),
77
Vec3 (x.dx(), 0.0f, 0.0f),
78
Vec3 (x.dy(), 0.0f, 0.0f));
83
make_Vec3 (const Dual2<Float> &x, const Dual2<Float> &y)
85
return Dual2<Vec3> (Vec3 (x.val(), y.val(), 0.0f),
86
Vec3 (x.dx(), y.dx(), 0.0f),
87
Vec3 (x.dy(), y.dy(), 0.0f));
93
/// A uniform way to assemble a Vec2 from float and a Dual2<Vec2>
94
/// from Dual2<float>.
96
make_Vec2 (float x, float y)
102
make_Vec2 (const Dual2<float> &x, const Dual2<float> &y)
104
return Dual2<Vec2> (Vec2 (x.val(), y.val()),
105
Vec2 (x.dx(), y.dx()),
106
Vec2 (x.dy(), y.dy()));
111
/// A uniform way to extract a single component from a Vec3 or Dual2<Vec3>
113
comp (const Vec3 &v, int c)
120
comp (const Dual2<Vec3> &v, int c)
122
return Dual2<float> (v.val()[c], v.dx()[c], v.dy()[c]);
127
/// Multiply a 3x3 matrix by a 3-vector, with derivs.
129
template <class S, class T>
131
multMatrix (const Imath::Matrix33<T> &M, const Dual2<Imath::Vec3<S> > &src,
132
Dual2<Imath::Vec3<S> > &dst)
134
Dual2<float> src0 = comp(src,0), src1 = comp(src,1), src2 = comp(src,2);
135
Dual2<S> a = src0 * M[0][0] + src1 * M[1][0] + src2 * M[2][0];
136
Dual2<S> b = src0 * M[0][1] + src1 * M[1][1] + src2 * M[2][1];
137
Dual2<S> c = src0 * M[0][2] + src1 * M[1][2] + src2 * M[2][2];
138
dst = make_Vec3 (a, b, c);
143
/// Multiply a matrix times a vector with derivatives to obtain
144
/// a transformed vector with derivatives.
146
multVecMatrix (const Matrix44 &M, Dual2<Vec3> &in, Dual2<Vec3> &out)
148
// Rearrange into a Vec3<Dual2<float> >
149
Imath::Vec3<Dual2<float> > din, dout;
150
for (int i = 0; i < 3; ++i)
151
din[i].set (in.val()[i], in.dx()[i], in.dy()[i]);
153
// N.B. the following function has a divide by 'w'
154
M.multVecMatrix (din, dout);
156
// Rearrange back into Dual2<Vec3>
157
out.set (Vec3 (dout[0].val(), dout[1].val(), dout[2].val()),
158
Vec3 (dout[0].dx(), dout[1].dx(), dout[2].dx()),
159
Vec3 (dout[0].dy(), dout[1].dy(), dout[2].dy()));
162
/// Multiply a matrix times a direction with derivatives to obtain
163
/// a transformed direction with derivatives.
165
multDirMatrix (const Matrix44 &M, Dual2<Vec3> &in, Dual2<Vec3> &out)
167
M.multDirMatrix (in.val(), out.val());
168
M.multDirMatrix (in.dx(), out.dx());
169
M.multDirMatrix (in.dy(), out.dy());
176
/// Templated trick to be able to derive what type we use to represent
177
/// a color, given a scalar, automatically using the right kind of Dual2.
178
template<typename T> struct Color3FromScalar {};
179
template<> struct Color3FromScalar<float> { typedef Color3 type; };
180
template<> struct Color3FromScalar<Dual2<float> > { typedef Dual2<Color3> type; };
183
/// A uniform way to assemble a Color3 from float and a Dual2<Color3>
184
/// from Dual2<float>.
186
make_Color3 (float x, float y, float z)
188
return Color3 (x, y, z);
192
make_Color3 (const Dual2<float> &x, const Dual2<float> &y, const Dual2<float> &z)
194
return Dual2<Color3> (Color3 (x.val(), y.val(), z.val()),
195
Color3 (x.dx(), y.dx(), z.dx()),
196
Color3 (x.dy(), y.dy(), z.dy()));
201
/// Various operator* permuations between Dual2<float> and Dual2<Vec3>
204
operator* (float a, const Dual2<Vec3> &b)
206
return Dual2<Vec3>(a*b.val(), a*b.dx(), a*b.dy());
210
operator* (const Dual2<Vec3> &a, float b)
212
return Dual2<Vec3>(a.val()*b, a.dx()*b, a.dy()*b);
216
operator* (const Vec3 &a, const Dual2<float> &b)
218
return Dual2<Vec3>(a*b.val(), a*b.dx(), a*b.dy());
222
operator* (const Dual2<Vec3> &a, const Dual2<float> &b)
224
return Dual2<Vec3>(a.val()*b.val(),
225
a.val()*b.dx() + a.dx()*b.val(),
226
a.val()*b.dy() + a.dy()*b.val());
231
dot (const Dual2<Vec3> &a, const Dual2<Vec3> &b)
233
Dual2<float> ax (a.val().x, a.dx().x, a.dy().x);
234
Dual2<float> ay (a.val().y, a.dx().y, a.dy().y);
235
Dual2<float> az (a.val().z, a.dx().z, a.dy().z);
236
Dual2<float> bx (b.val().x, b.dx().x, b.dy().x);
237
Dual2<float> by (b.val().y, b.dx().y, b.dy().y);
238
Dual2<float> bz (b.val().z, b.dx().z, b.dy().z);
239
return ax*bx + ay*by + az*bz;
245
dot (const Dual2<Vec3> &a, const Vec3 &b)
247
Dual2<float> ax (a.val().x, a.dx().x, a.dy().x);
248
Dual2<float> ay (a.val().y, a.dx().y, a.dy().y);
249
Dual2<float> az (a.val().z, a.dx().z, a.dy().z);
250
return ax*b.x + ay*b.y + az*b.z;
256
dot (const Vec3 &a, const Dual2<Vec3> &b)
258
Dual2<float> bx (b.val().x, b.dx().x, b.dy().x);
259
Dual2<float> by (b.val().y, b.dx().y, b.dy().y);
260
Dual2<float> bz (b.val().z, b.dx().z, b.dy().z);
261
return a.x*bx + a.y*by + a.z*bz;
267
dot (const Dual2<Vec2> &a, const Dual2<Vec2> &b)
269
Dual2<float> ax (a.val().x, a.dx().x, a.dy().x);
270
Dual2<float> ay (a.val().y, a.dx().y, a.dy().y);
271
Dual2<float> bx (b.val().x, b.dx().x, b.dy().x);
272
Dual2<float> by (b.val().y, b.dx().y, b.dy().y);
273
return ax*bx + ay*by;
279
dot (const Dual2<Vec2> &a, const Vec2 &b)
281
Dual2<float> ax (a.val().x, a.dx().x, a.dy().x);
282
Dual2<float> ay (a.val().y, a.dx().y, a.dy().y);
283
return ax*b.x + ay*b.y;
289
dot (const Vec2 &a, const Dual2<Vec2> &b)
291
Dual2<float> bx (b.val().x, b.dx().x, b.dy().x);
292
Dual2<float> by (b.val().y, b.dx().y, b.dy().y);
293
return a.x*bx + a.y*by;
299
cross (const Dual2<Vec3> &a, const Dual2<Vec3> &b)
301
Dual2<float> ax (a.val().x, a.dx().x, a.dy().x);
302
Dual2<float> ay (a.val().y, a.dx().y, a.dy().y);
303
Dual2<float> az (a.val().z, a.dx().z, a.dy().z);
304
Dual2<float> bx (b.val().x, b.dx().x, b.dy().x);
305
Dual2<float> by (b.val().y, b.dx().y, b.dy().y);
306
Dual2<float> bz (b.val().z, b.dx().z, b.dy().z);
308
Dual2<float> nx = ay*bz - az*by;
309
Dual2<float> ny = az*bx - ax*bz;
310
Dual2<float> nz = ax*by - ay*bx;
312
return Dual2<Vec3> (Vec3(nx.val(), ny.val(), nz.val()),
313
Vec3(nx.dx(), ny.dx(), nz.dx() ),
314
Vec3(nx.dy(), ny.dy(), nz.dy() ));
320
length (const Dual2<Vec3> &a)
322
Dual2<float> ax (a.val().x, a.dx().x, a.dy().x);
323
Dual2<float> ay (a.val().y, a.dx().y, a.dy().y);
324
Dual2<float> az (a.val().z, a.dx().z, a.dy().z);
325
return sqrt(ax*ax + ay*ay + az*az);
331
normalize (const Dual2<Vec3> &a)
333
if (a.val().x == 0 && a.val().y == 0 && a.val().z == 0) {
334
return Dual2<Vec3> (Vec3(0, 0, 0),
338
Dual2<float> ax (a.val().x, a.dx().x, a.dy().x);
339
Dual2<float> ay (a.val().y, a.dx().y, a.dy().y);
340
Dual2<float> az (a.val().z, a.dx().z, a.dy().z);
341
Dual2<float> inv_length = 1.0f / sqrt(ax*ax + ay*ay + az*az);
345
return Dual2<Vec3> (Vec3(ax.val(), ay.val(), az.val()),
346
Vec3(ax.dx(), ay.dx(), az.dx() ),
347
Vec3(ax.dy(), ay.dy(), az.dy() ));
354
distance (const Dual2<Vec3> &a, const Dual2<Vec3> &b)
356
return length (a - b);
363
#endif /* OSL_DUAL_VEC_H */