~jesterking/blender/win32libs

« back to all changes in this revision

Viewing changes to osl/include/OSL/dual_vec.h

  • Committer: dingto
  • Date: 2013-12-06 17:01:28 UTC
  • Revision ID: svn-v4:954f8c5b-7b00-dc11-b283-0030488c597c:trunk/lib/windows:61249
MSVC 2008 x86
* Update OSL to 1.4.0 and OIIO to 1.3.9.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
3
 
All Rights Reserved.
4
 
 
5
 
Redistribution and use in source and binary forms, with or without
6
 
modification, are permitted provided that the following conditions are
7
 
met:
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.
27
 
*/
28
 
 
29
 
#ifndef OSL_DUAL_VEC_H
30
 
#define OSL_DUAL_VEC_H
31
 
 
32
 
#include "oslconfig.h"
33
 
#include "dual.h"
34
 
 
35
 
OSL_NAMESPACE_ENTER
36
 
 
37
 
 
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; };
43
 
 
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; };
51
 
 
52
 
 
53
 
 
54
 
/// A uniform way to assemble a Vec3 from float and a Dual2<Vec3>
55
 
/// from Dual2<float>.
56
 
inline Vec3
57
 
make_Vec3 (float x, float y, float z)
58
 
{
59
 
    return Vec3 (x, y, z);
60
 
}
61
 
 
62
 
inline Dual2<Vec3>
63
 
make_Vec3 (const Dual2<float> &x, const Dual2<float> &y, const Dual2<float> &z)
64
 
{
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()));
68
 
}
69
 
 
70
 
 
71
 
/// Make a Dual2<Vec3> from a single Dual2<Float> x coordinate, and 0
72
 
/// for the other components.
73
 
inline Dual2<Vec3>
74
 
make_Vec3 (const Dual2<Float> &x)
75
 
{
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));
79
 
}
80
 
 
81
 
 
82
 
inline Dual2<Vec3>
83
 
make_Vec3 (const Dual2<Float> &x, const Dual2<Float> &y)
84
 
{
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));
88
 
}
89
 
 
90
 
 
91
 
 
92
 
 
93
 
/// A uniform way to assemble a Vec2 from float and a Dual2<Vec2>
94
 
/// from Dual2<float>.
95
 
inline Vec2
96
 
make_Vec2 (float x, float y)
97
 
{
98
 
    return Vec2 (x, y);
99
 
}
100
 
 
101
 
inline Dual2<Vec2>
102
 
make_Vec2 (const Dual2<float> &x, const Dual2<float> &y)
103
 
{
104
 
    return Dual2<Vec2> (Vec2 (x.val(), y.val()),
105
 
                        Vec2 (x.dx(),  y.dx()),
106
 
                        Vec2 (x.dy(),  y.dy()));
107
 
}
108
 
 
109
 
 
110
 
 
111
 
/// A uniform way to extract a single component from a Vec3 or Dual2<Vec3>
112
 
inline float
113
 
comp (const Vec3 &v, int c)
114
 
{
115
 
    return v[c];
116
 
}
117
 
 
118
 
 
119
 
inline Dual2<float>
120
 
comp (const Dual2<Vec3> &v, int c)
121
 
{
122
 
    return Dual2<float> (v.val()[c], v.dx()[c], v.dy()[c]);
123
 
}
124
 
 
125
 
 
126
 
 
127
 
/// Multiply a 3x3 matrix by a 3-vector, with derivs.
128
 
///
129
 
template <class S, class T>
130
 
inline void
131
 
multMatrix (const Imath::Matrix33<T> &M, const Dual2<Imath::Vec3<S> > &src,
132
 
            Dual2<Imath::Vec3<S> > &dst)
133
 
{
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);
139
 
}
140
 
 
141
 
 
142
 
 
143
 
/// Multiply a matrix times a vector with derivatives to obtain
144
 
/// a transformed vector with derivatives.
145
 
inline void
146
 
multVecMatrix (const Matrix44 &M, Dual2<Vec3> &in, Dual2<Vec3> &out)
147
 
{
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]);
152
 
 
153
 
    // N.B. the following function has a divide by 'w'
154
 
    M.multVecMatrix (din, dout);
155
 
 
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()));
160
 
}
161
 
 
162
 
/// Multiply a matrix times a direction with derivatives to obtain
163
 
/// a transformed direction with derivatives.
164
 
inline void
165
 
multDirMatrix (const Matrix44 &M, Dual2<Vec3> &in, Dual2<Vec3> &out)
166
 
{
167
 
    M.multDirMatrix (in.val(), out.val());
168
 
    M.multDirMatrix (in.dx(), out.dx());
169
 
    M.multDirMatrix (in.dy(), out.dy());
170
 
}
171
 
 
172
 
 
173
 
 
174
 
 
175
 
 
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; };
181
 
 
182
 
 
183
 
/// A uniform way to assemble a Color3 from float and a Dual2<Color3>
184
 
/// from Dual2<float>.
185
 
inline Color3
186
 
make_Color3 (float x, float y, float z)
187
 
{
188
 
    return Color3 (x, y, z);
189
 
}
190
 
 
191
 
inline Dual2<Color3>
192
 
make_Color3 (const Dual2<float> &x, const Dual2<float> &y, const Dual2<float> &z)
193
 
{
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()));
197
 
}
198
 
 
199
 
 
200
 
 
201
 
/// Various operator* permuations between Dual2<float> and Dual2<Vec3> 
202
 
// datatypes.
203
 
inline Dual2<Vec3> 
204
 
operator* (float a, const Dual2<Vec3> &b)
205
 
{
206
 
    return Dual2<Vec3>(a*b.val(), a*b.dx(), a*b.dy());
207
 
}
208
 
 
209
 
inline Dual2<Vec3> 
210
 
operator* (const Dual2<Vec3> &a, float b)
211
 
{
212
 
    return Dual2<Vec3>(a.val()*b, a.dx()*b, a.dy()*b);
213
 
}
214
 
 
215
 
inline Dual2<Vec3> 
216
 
operator* (const Vec3 &a, const Dual2<float> &b)
217
 
{
218
 
    return Dual2<Vec3>(a*b.val(), a*b.dx(), a*b.dy());
219
 
}
220
 
 
221
 
inline Dual2<Vec3> 
222
 
operator* (const Dual2<Vec3> &a, const Dual2<float> &b)
223
 
{
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());
227
 
}
228
 
 
229
 
 
230
 
inline Dual2<float>
231
 
dot (const Dual2<Vec3> &a, const Dual2<Vec3> &b)
232
 
{
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;
240
 
}
241
 
 
242
 
 
243
 
 
244
 
inline Dual2<float>
245
 
dot (const Dual2<Vec3> &a, const Vec3 &b)
246
 
{
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;
251
 
}
252
 
 
253
 
 
254
 
 
255
 
inline Dual2<float>
256
 
dot (const Vec3 &a, const Dual2<Vec3> &b)
257
 
{
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;
262
 
}
263
 
 
264
 
 
265
 
 
266
 
inline Dual2<float>
267
 
dot (const Dual2<Vec2> &a, const Dual2<Vec2> &b)
268
 
{
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;
274
 
}
275
 
 
276
 
 
277
 
 
278
 
inline Dual2<float>
279
 
dot (const Dual2<Vec2> &a, const Vec2 &b)
280
 
{
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;
284
 
}
285
 
 
286
 
 
287
 
 
288
 
inline Dual2<float>
289
 
dot (const Vec2 &a, const Dual2<Vec2> &b)
290
 
{
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;
294
 
}
295
 
 
296
 
 
297
 
 
298
 
inline Dual2<Vec3>
299
 
cross (const Dual2<Vec3> &a, const Dual2<Vec3> &b)
300
 
{
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);
307
 
 
308
 
    Dual2<float> nx = ay*bz - az*by;
309
 
    Dual2<float> ny = az*bx - ax*bz;
310
 
    Dual2<float> nz = ax*by - ay*bx;
311
 
 
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()  ));
315
 
}
316
 
 
317
 
 
318
 
 
319
 
inline Dual2<float>
320
 
length (const Dual2<Vec3> &a)
321
 
{
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);
326
 
}
327
 
 
328
 
 
329
 
 
330
 
inline Dual2<Vec3>
331
 
normalize (const Dual2<Vec3> &a)
332
 
{
333
 
    if (a.val().x == 0 && a.val().y == 0 && a.val().z == 0) {
334
 
        return Dual2<Vec3> (Vec3(0, 0, 0),
335
 
                            Vec3(0, 0, 0),
336
 
                            Vec3(0, 0, 0));
337
 
    } else {
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);
342
 
        ax = ax*inv_length;
343
 
        ay = ay*inv_length;
344
 
        az = az*inv_length;
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() ));
348
 
    }
349
 
}
350
 
 
351
 
 
352
 
 
353
 
inline Dual2<float>
354
 
distance (const Dual2<Vec3> &a, const Dual2<Vec3> &b)
355
 
{
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);
362
 
 
363
 
    Dual2<float> dx = bx - ax;
364
 
    Dual2<float> dy = by - ay;
365
 
    Dual2<float> dz = bz - az;
366
 
 
367
 
    return sqrt(dx*dx + dy*dy + dz*dz);
368
 
}
369
 
 
370
 
 
371
 
 
372
 
OSL_NAMESPACE_EXIT
373
 
 
374
 
#endif /* OSL_DUAL_VEC_H */
 
1
/*
 
2
Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
 
3
All Rights Reserved.
 
4
 
 
5
Redistribution and use in source and binary forms, with or without
 
6
modification, are permitted provided that the following conditions are
 
7
met:
 
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.
 
27
*/
 
28
 
 
29
#ifndef OSL_DUAL_VEC_H
 
30
#define OSL_DUAL_VEC_H
 
31
 
 
32
#include "oslconfig.h"
 
33
#include "dual.h"
 
34
 
 
35
OSL_NAMESPACE_ENTER
 
36
 
 
37
 
 
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; };
 
43
 
 
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; };
 
51
 
 
52
 
 
53
 
 
54
/// A uniform way to assemble a Vec3 from float and a Dual2<Vec3>
 
55
/// from Dual2<float>.
 
56
inline Vec3
 
57
make_Vec3 (float x, float y, float z)
 
58
{
 
59
    return Vec3 (x, y, z);
 
60
}
 
61
 
 
62
inline Dual2<Vec3>
 
63
make_Vec3 (const Dual2<float> &x, const Dual2<float> &y, const Dual2<float> &z)
 
64
{
 
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()));
 
68
}
 
69
 
 
70
 
 
71
/// Make a Dual2<Vec3> from a single Dual2<Float> x coordinate, and 0
 
72
/// for the other components.
 
73
inline Dual2<Vec3>
 
74
make_Vec3 (const Dual2<Float> &x)
 
75
{
 
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));
 
79
}
 
80
 
 
81
 
 
82
inline Dual2<Vec3>
 
83
make_Vec3 (const Dual2<Float> &x, const Dual2<Float> &y)
 
84
{
 
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));
 
88
}
 
89
 
 
90
 
 
91
 
 
92
 
 
93
/// A uniform way to assemble a Vec2 from float and a Dual2<Vec2>
 
94
/// from Dual2<float>.
 
95
inline Vec2
 
96
make_Vec2 (float x, float y)
 
97
{
 
98
    return Vec2 (x, y);
 
99
}
 
100
 
 
101
inline Dual2<Vec2>
 
102
make_Vec2 (const Dual2<float> &x, const Dual2<float> &y)
 
103
{
 
104
    return Dual2<Vec2> (Vec2 (x.val(), y.val()),
 
105
                        Vec2 (x.dx(),  y.dx()),
 
106
                        Vec2 (x.dy(),  y.dy()));
 
107
}
 
108
 
 
109
 
 
110
 
 
111
/// A uniform way to extract a single component from a Vec3 or Dual2<Vec3>
 
112
inline float
 
113
comp (const Vec3 &v, int c)
 
114
{
 
115
    return v[c];
 
116
}
 
117
 
 
118
 
 
119
inline Dual2<float>
 
120
comp (const Dual2<Vec3> &v, int c)
 
121
{
 
122
    return Dual2<float> (v.val()[c], v.dx()[c], v.dy()[c]);
 
123
}
 
124
 
 
125
 
 
126
 
 
127
/// Multiply a 3x3 matrix by a 3-vector, with derivs.
 
128
///
 
129
template <class S, class T>
 
130
inline void
 
131
multMatrix (const Imath::Matrix33<T> &M, const Dual2<Imath::Vec3<S> > &src,
 
132
            Dual2<Imath::Vec3<S> > &dst)
 
133
{
 
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);
 
139
}
 
140
 
 
141
 
 
142
 
 
143
/// Multiply a matrix times a vector with derivatives to obtain
 
144
/// a transformed vector with derivatives.
 
145
inline void
 
146
multVecMatrix (const Matrix44 &M, Dual2<Vec3> &in, Dual2<Vec3> &out)
 
147
{
 
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]);
 
152
 
 
153
    // N.B. the following function has a divide by 'w'
 
154
    M.multVecMatrix (din, dout);
 
155
 
 
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()));
 
160
}
 
161
 
 
162
/// Multiply a matrix times a direction with derivatives to obtain
 
163
/// a transformed direction with derivatives.
 
164
inline void
 
165
multDirMatrix (const Matrix44 &M, Dual2<Vec3> &in, Dual2<Vec3> &out)
 
166
{
 
167
    M.multDirMatrix (in.val(), out.val());
 
168
    M.multDirMatrix (in.dx(), out.dx());
 
169
    M.multDirMatrix (in.dy(), out.dy());
 
170
}
 
171
 
 
172
 
 
173
 
 
174
 
 
175
 
 
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; };
 
181
 
 
182
 
 
183
/// A uniform way to assemble a Color3 from float and a Dual2<Color3>
 
184
/// from Dual2<float>.
 
185
inline Color3
 
186
make_Color3 (float x, float y, float z)
 
187
{
 
188
    return Color3 (x, y, z);
 
189
}
 
190
 
 
191
inline Dual2<Color3>
 
192
make_Color3 (const Dual2<float> &x, const Dual2<float> &y, const Dual2<float> &z)
 
193
{
 
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()));
 
197
}
 
198
 
 
199
 
 
200
 
 
201
/// Various operator* permuations between Dual2<float> and Dual2<Vec3> 
 
202
// datatypes.
 
203
inline Dual2<Vec3> 
 
204
operator* (float a, const Dual2<Vec3> &b)
 
205
{
 
206
    return Dual2<Vec3>(a*b.val(), a*b.dx(), a*b.dy());
 
207
}
 
208
 
 
209
inline Dual2<Vec3> 
 
210
operator* (const Dual2<Vec3> &a, float b)
 
211
{
 
212
    return Dual2<Vec3>(a.val()*b, a.dx()*b, a.dy()*b);
 
213
}
 
214
 
 
215
inline Dual2<Vec3> 
 
216
operator* (const Vec3 &a, const Dual2<float> &b)
 
217
{
 
218
    return Dual2<Vec3>(a*b.val(), a*b.dx(), a*b.dy());
 
219
}
 
220
 
 
221
inline Dual2<Vec3> 
 
222
operator* (const Dual2<Vec3> &a, const Dual2<float> &b)
 
223
{
 
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());
 
227
}
 
228
 
 
229
 
 
230
inline Dual2<float>
 
231
dot (const Dual2<Vec3> &a, const Dual2<Vec3> &b)
 
232
{
 
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;
 
240
}
 
241
 
 
242
 
 
243
 
 
244
inline Dual2<float>
 
245
dot (const Dual2<Vec3> &a, const Vec3 &b)
 
246
{
 
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;
 
251
}
 
252
 
 
253
 
 
254
 
 
255
inline Dual2<float>
 
256
dot (const Vec3 &a, const Dual2<Vec3> &b)
 
257
{
 
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;
 
262
}
 
263
 
 
264
 
 
265
 
 
266
inline Dual2<float>
 
267
dot (const Dual2<Vec2> &a, const Dual2<Vec2> &b)
 
268
{
 
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;
 
274
}
 
275
 
 
276
 
 
277
 
 
278
inline Dual2<float>
 
279
dot (const Dual2<Vec2> &a, const Vec2 &b)
 
280
{
 
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;
 
284
}
 
285
 
 
286
 
 
287
 
 
288
inline Dual2<float>
 
289
dot (const Vec2 &a, const Dual2<Vec2> &b)
 
290
{
 
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;
 
294
}
 
295
 
 
296
 
 
297
 
 
298
inline Dual2<Vec3>
 
299
cross (const Dual2<Vec3> &a, const Dual2<Vec3> &b)
 
300
{
 
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);
 
307
 
 
308
    Dual2<float> nx = ay*bz - az*by;
 
309
    Dual2<float> ny = az*bx - ax*bz;
 
310
    Dual2<float> nz = ax*by - ay*bx;
 
311
 
 
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()  ));
 
315
}
 
316
 
 
317
 
 
318
 
 
319
inline Dual2<float>
 
320
length (const Dual2<Vec3> &a)
 
321
{
 
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);
 
326
}
 
327
 
 
328
 
 
329
 
 
330
inline Dual2<Vec3>
 
331
normalize (const Dual2<Vec3> &a)
 
332
{
 
333
    if (a.val().x == 0 && a.val().y == 0 && a.val().z == 0) {
 
334
        return Dual2<Vec3> (Vec3(0, 0, 0),
 
335
                            Vec3(0, 0, 0),
 
336
                            Vec3(0, 0, 0));
 
337
    } else {
 
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);
 
342
        ax = ax*inv_length;
 
343
        ay = ay*inv_length;
 
344
        az = az*inv_length;
 
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() ));
 
348
    }
 
349
}
 
350
 
 
351
 
 
352
 
 
353
inline Dual2<float>
 
354
distance (const Dual2<Vec3> &a, const Dual2<Vec3> &b)
 
355
{
 
356
    return length (a - b);
 
357
}
 
358
 
 
359
 
 
360
 
 
361
OSL_NAMESPACE_EXIT
 
362
 
 
363
#endif /* OSL_DUAL_VEC_H */