もうすぐ冬なので雪を作りたい。
だがなかなかわかりやすいCyclesのノード構成図が見当たらない。
この絵の床は
https://www.packtpub.com/books/content/creating-ice-and-snow-materials
のiceを途中までやったのだがテクスチャが必要と言われ断念。
ゆきだるまのほうは自前で何かしらやった結果。
てか、iceこれで十分じゃね?(ちょっと変えてある)
template<typename T> struct coord { T x; T y; T z; coord() {} coord(const T _x, const T _y, const T _z) { x = _x; y = _y; z = _z; } template<typename U> coord<T>& operator=(const coord<U>& src) { x = src.x; y = src.y; z = src.z; return *this; } };
このような構造体があったとして、こいつにoperatorを定義するときにいつも悩むのが戻り値の型である。
template<typename T, typename U> double operator-(const coord<T>& s, U v) { typedef decltype(s.x - v) Type; return coord< Type >( static_cast<Type>(s.x - v), static_cast<Type>(s.y - v), static_cast<Type>(s.z - v) ); }
このように型を決め打ちしてしまうと、TもUもintなのにdoubleが返ってくることになったり、long doubleが入ってきたりすると潰れてしまう。
BoostにはBOOST::TYPEOFなるものがあるらしいが、このためにBoostを使うのは論外だ。
Boostにあるということはメタメタすればいけるんだろうが、これもやりたくない。
ここで思い出したのだが、今は仕事でもVC++2015を使っている。こいつのC++11対応はMicrosoftにしては良い線行っている。
autoとdecltypeを使えば、以下のように書ける。
template<typename T, typename U> auto operator-(const coord<T>& s, U v) { typedef decltype(s.x - v) Type; return coord< Type >( static_cast<Type>( s.x-v ), static_cast<Type>( s.y-v ), static_cast<Type>( s.z-v ) ); }
やはり、ターゲットプラットフォームに問題がないなら、Visual C++のバージョンは2015以降を使うことを人類の義務にすべきだ。トランプよ法律作れ。