【令和最新版】Mayaのノードの話

（某通販サイトで商品名の先頭が令和最新版ってついてるだけで　あっ（察し）ってなるよね。ちなみにメーカー名やブランド名が先頭にきてないのは規約違反らしいよ。）

***エクスプレッションの件は25年に回します。がんばれ次の12月の俺。***

***Maya2026でプラグの型に対して変更が色々ありました！＾＾＃***
変更点、注意点は[公式のhelp](https://help.autodesk.com/view/MAYAUL/2026/JPN/?guid=GUID-BAF59B47-E24F-4F87-9B77-ABE78D3F8268#:~:text=%E3%81%AA%E3%82%8A%E3%81%BE%E3%81%97%E3%81%9F%E3%80%82-,%E5%8D%98%E4%BD%8D%E3%81%AA%E3%81%97%E3%81%AE%E8%A8%88%E7%AE%97%E3%83%8E%E3%83%BC%E3%83%89,-DoubleLinear%20(%E8%B7%9D%E9%9B%A2)%E3%82%A2%E3%83%88%E3%83%AA%E3%83%93%E3%83%A5%E3%83%BC%E3%83%88)見てください！！＾＾＃＃


## 前置きと言う名の何かアレ

クリスマスっぽいことは最早何年もやってないおっさんTA　M_M_M_M_M_M_Mです。なんか名前が冗長ですね。そのうちなんかナイスな名前にします。

さて皆さん仕事でシバいてるMayaのバージョンはいくつですか？
昨今ではゲーム開発が長期化しすぎて最早公式サポートの切れているバージョンを未だに業務でメインにしてたり、Python2の頃のツール資産を3に置き換え出来ていなくて新しいバージョンに出来ていなかったり、そもそもめんどくさくて安定してる2020あたりでいいやと新しいバージョンに移行してない人もまぁまぁ多いというのが筆者の肌感です。
（昔と違いせっかくサブスクで新バージョン使う事に対して追加コストかからないんだからみんな新しいバージョンもっとシバこう？）

ほとんどの人が注目するのはMayaの表向きの新機能ですが、筆者は開発者向け資料や追加されたノード見る事のほうが興奮するちょっとアレなTAなので、普段めったに注目されないけど縁の下で支えているノードの話を今回はしたいと思います。（派手な新機能より裏側の仕様変更のほうが観察してて面白いよマジで。）

なお今回の記事はMaya2024.2時点の話になります。


## ノードの話

初歩的なノードの話はそもそもこんなノードの話見に来てる人には不要だと思うのですっ飛ばします。
ノードわからない人がもし間違ってこの記事に来ちゃってたら、まずはノードとは何かの基礎を何らかのソフトベースで学習してからもう一度戻ってきたほうがいいですが、端的に説明するなら入力した値を色々処理して結果を出力する小さな関数のようなプログラムの塊がノードです。上流から下流にバケツリレーします。（プロキシアトリビュート等一部このルールを超越した存在もありますが割愛します。興味あれば調べて下さい。）

## なんかしらんけどここ数バージョン、ノードの追加が活発なんだよMayaって！

表向きな派手目な機能とは裏腹に、ノード関係は本当に地味に、しれっと追加されます。
2020でMatrix系のノードがバッと増えたときは公式で動画が作るくらいに珍しくアピールしていましたが、基本的に新機能情報の端っこか、下手するとサイレント追加されたりします。
ArnoldやBifrostのようなプラグインとして実装されているものは含んでいませんが、Mayaを構成するヴァニラノードとでも言うべき一般的な汎用ノード(以下ヴァニラノード)のリストは毎バージョンMaya公式ドキュメントのテクニカルドキュメントカテゴリー内にMELやPythonのコマンドリファレンスとともにちゃんとページがあります。
※コマンドリファレンスと違い英語のページのみですが、高校英語くらいの知識で問題なく読解できるので英語はやだなぁとか思わずに読んでみましょう。勉強になりますよ！

さて、Mayaのヴァニラノード数の推移を見てみると、

注:ノードリファレンスに掲載されている項目数から抽出してカウントしているためプラグイン系ノードは含んでいません。プラグイン系含め全てのノード列挙してカウントする方法はありますが、今回プラグイン系が混ざると話がややこしくなるのでヴァニラノードのみでカウントしています。

カウントの方法自体はノードリファレンス内のindex_all.htmlからの各ページリンク数から抽出しています。雑です。すんません。（本稿はこの数字の正確性自体は大した問題にならないので仕事の片手間で書いてる雑ネタ記事みたいなモンだし超雑なカウント方法を取っています。）

---

**Maya2018:714
Maya2019:715 (前バージョン+1)
Maya2020:724 (前バージョン+9)
Maya2022:840 (前バージョン+116) ←！？
Maya2023:843 (前バージョン+3)
Maya2024:892 (前バージョン+49)　←！？**

---

なんとカウントしてみると6バージョンで178ものノードが増えてるんですね。
（こんなに増えてるとカウントするまでまったく予想してなかったのでカウントした本人が一番たまげてます。カウントのしかたが若干雑なので何か間違いがあったらツッコミコメントください。）

余談ですが、このノードリファレンス、前述の通りプラグインとしてMayaに実装されているノードは筆者が知る限りは載ってないのですが、実は標準のMatrixノードもリガーが嫌ってほどお世話になるmultMatrixやdecomposeMatrixは直接Maya本体に実装されているけどinverseMatrixノードはmatrixNodes.mllで実装されているためノードリファレンスに載っていません！！クォータニオン系ノードは全てquatNodes.mllで実装されているので一切載っていません！！！

本稿で紹介しているノード以外にも実は2024でもひっそりmatrix系ノードも追加されていますが、新機能紹介からハブられてる上あまりおもしろいネタにならなそう（活用する人マジで一部だけになりそう）なので省きました。

あとノードリファレンスには表向きアトリビュートエディタやチャンネルボックスに出てこない裏方のアトリビュートも原則全部載ってるので読んでみると面白いです。型も既定値もプラグの動作種別も全部載ってます。

## ここから本題。2024で追加されたノード達

さてここからは本稿の1番のメインである2024で追加されたノード達にフォーカスします。
時を遡る事2023年、Maya2024がリリースされた日、毎度のバージョンのお決まりルーチンである端から端までドキュメント全て読むというイベントが当時の筆者には降りかかりました(好きでやってるんで別にいいんですが)
まず[2024の新機能に目を通していくと・・・](https://help.autodesk.com/view/MAYAUL/2024/JPN/?guid=GUID-E48ECBA5-2BC2-45B5-AFD6-7B3B10214CEE)

ほうほう、色々新機能が増えていますな。へぇー、ウェイトの数値がビューポート上で可視化されるように これはナイスですねー。(文字に縁取りかドロップシャドウ機能があれば100点満点でしたが・・・ウェイトカラー表示にすると必然的にレインボー設定と文字色がかぶる！！グラデをウェイトのカラーの補色になるように色相ズラしたグラデにするとか一応ある程度は緩和できるけども・・・)

・・・んん？！なんでアニメーション機能の新機能欄に追加ノードが？！(それ言い出したらウェイトペイントツールの紹介がこのカテゴリでしかも先頭なのもおかしいが)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3950033/70cea738-31d5-b441-3fdb-a7954c91fe61.png)

追加ノード、、、うおおおお！！数学系ノードがすごく増えてる！！
[advent calendar2018のchiyamaさんの記事](https://philosy.com/blog/2018/12/21/maya%E3%81%AE%E3%83%8E%E3%83%BC%E3%83%89%E3%81%A7%E6%95%B0%E5%AD%A6%E3%81%AE%E6%BC%94%E7%AE%97%E3%82%92%E5%AE%9F%E7%8F%BE%E3%81%99%E3%82%8B/)で言及されてるような数学ノードがめっちゃ増えてんじゃん！！

マジで今までなんでこんな超基本的な数学系が無かったのかMayaの不思議の一つでしたが、ついにそれが解消されました！正直Mayaのバージョンのナンバリングが年号表記になる前のバージョンあたりでとっくに実装されてるべきなノードだと思うけど！
(昔はMELコマンドとしては大体必要なコマンドがあるからエクスプレッションで組めよって意向だったんだろうなと邪推。今はむしろExpression使ってほしくない感じをヒシヒシと感じる・・・


余談だがGitには大昔からこの手のノードのリポジトリがある。剛を煮やしたどこかのエンジニアさんかTAさんなんだろうなぁ、、、
https://github.com/serguei-k/maya-math-nodes
https://github.com/cyrillef/MayaMathNode

## ざっと全ノード紹介　数学ノード系
せっかく実装してくれたんやからしばき倒さんと無作法という物、、、
#### absolute
doubleLinear型(以下dl型、特記が無い限り単体型のアトリビュートとする)の入力に対してdl型で入力値の絶対値が出力される。

数学的には$|x|$

input(dl型):入力値
output(dl型):入力値を絶対値にした値

#### sin

doubleAngle型(以下da型)の入力(角度$\theta$)に対してdl型で$sinθ$の値（$θ$のときの辺の比率）が出力される。

$sinθ$ = 対辺／斜辺

input(da型):角度$θ$
output(dl型):Sin$θ$

#### cos
da型の入力に対してdl型で$cos\theta$の値が出力される。

$cosθ$ = 底辺／斜辺

input(da型):角度$θ$
output(dl型):Cos$θ$


#### tan

da型の入力に対してdl型で$tan\theta$の値が出力される。

$tanθ$ = 対辺／底辺

input(da型):角度$θ$
output(dl型):tan$θ$

ちなみに解無し（もしくは無限）である90度、270度をいれると

90:16331239353195370
180:5443746451065123

が出力されます。infとかNaNとかゼロ除算警告とかワンチャン出てくるかな？という予想もありましたが、普通にMathモジュールで計算させた時のような結果になりました。

#### asin

dl型の入力(辺の比率)に対してda型で角度が出力される。

input(dl型):比率
output(da型):$θ$

注意点として、asin関数に値を放り込むとRadで結果を返すMathモジュール等と違い、このノードから出力される **”アトリビュート表示上の値”** はMayaの角度設定に依存します。

Mayaのプリファレンスの単位設定でわざわざDeg（度数法）ではなくRad（弧度法）使うような案件に出会うことは多分一生無いと思いますが、既定値のDegの場合、出力値は見かけ上Degになります。（内部的にはどっちのモードでもRadで計算されています。）
ノードのプラグがdl型やDouble型かつDegで出力されてたら数学ガチ勢がキレるところでしたが、流石にちゃんとda型で出力されてるのはナイスです。

#### acos

dl型の入力に対してda型で角度が出力される。

input(dl型):比率
output(da型):$θ$

#### atan

dl型の入力に対してda型で角度が出力される。

input(dl型):比率
output(da型):$θ$

tanノードの時と逆で、16331239353195370とかを放り込むと90度を返します。

#### atan2

dl型の2つの入力（座標）に対してda型で角度が出力される。

atan2(y,x)

input1(dl型):y
input2(dl型):x
output(da型):$θ$

atan2に馴染みのない人にはxy逆じゃね？って思われるかもしれないが、引数順番はyxであってます。ちなみに多分これただの記述ミスですが、[ノードリファレンスのatan2のページ](https://help.autodesk.com/cloudhelp/2024/JPN/Maya-Tech-Docs/Nodes/atan2.html)ではinput1はX,input2はYとなっています・・・

ええ？？天下のAutodesk様が記述ミスゥ？そんな馬鹿な！って方は以下のコードで比較してみてください。
(記述ミスなはず・・・なんか筆者の根本的な認識違いでしたらAutodesk社の方角に2024年中は毎朝土下座するんでご指摘下さい。記述ミスであればしれっと直しておいて下さいこの記事みたA社の中の人！！！！)
```python
import math
import maya.cmds as cmds


def patternTest():
    # 座標を指定
    xPos = 1
    yPos = 2

    angle_radiansYX = math.atan2(yPos, xPos)
    angle_radiansXY = math.atan2(xPos, yPos)

    atan2Node_YX = cmds.createNode("atan2", name="atan2_YX")
    cmds.setAttr(atan2Node_YX+".input1", yPos)
    cmds.setAttr(atan2Node_YX+".input2", xPos)
    atan2Node_YX_outVal = cmds.getAttr(atan2Node_YX+".output")

    atan2Node_XY = cmds.createNode("atan2", name="atan2_XY")
    cmds.setAttr(atan2Node_XY+".input1", xPos)
    cmds.setAttr(atan2Node_XY+".input2", yPos)
    atan2Node_XY_outVal = cmds.getAttr(atan2Node_XY+".output")

    print("\n\natan2ノードのOutput値(YX):{}".format(atan2Node_YX_outVal))

    print("mathモジュールatan2のYX順の結果:{}\n".format(math.degrees(angle_radiansYX)))

    print("atan2ノードのOutput値(XY):{}".format(atan2Node_XY_outVal))

    print("mathモジュールatan2のXY順の結果:{}\n\n".format(math.degrees(angle_radiansXY)))


patternTest()
```


余談：XY順番とYX順番については[この記事](https://qiita.com/tsubolabo/items/fbc1f156b7c6aa352f58#:~:text=%E3%81%AB%E3%81%AA%E3%82%8A%E3%81%BE%E3%81%99%E3%80%82-,atan2(y%2Cx)%E6%96%B9%E5%BC%8F,-Java%2C%E3%80%80C%2C%E3%80%80Python)見てもらえるとよいかと・・・

余談2:atanだけじゃなくatan2も実装マジ感謝。色々役に立つんスよ。

#### power

べき乗を求めます。
パワー！とか言いながらマッチョは出てきません。

$a^x=b$
での$a$(底)を$x$乗したときの$b$を求めます。

input(dl型):底（上の式での$a$）
exponent(dl型):乗数（上の式での$x$）
output(dl型):inputのexponent乗の解

（数学ではべき乗はexponentで表現するのに日常会話等ではpowerを使うという英語のややこしさ！ああややこしい。）

#### log

底に対する真数の対数を求めます。

$a^x = b$
でのaが底,bを真数としたときのaに対する指数を求めます。
底だの真数だの数学苦手ﾏﾝにはわけわからん言葉が出てきてますが、要するにpowerの逆やって乗数求めてるだけです。

base(dl型):底（上の式での$a$）
input(dl型):真数（上の式での$b$）
output(dl型):底を真数にするための乗数（上の式での$x$）

#### pi
小学校で円周率はみなさん習いましたね？中学から円周率を$π$と表記するようになりましたね？はいその$π$です。$π$を出力するだけのノードです。

***これいる・・・・？？？***


強いて言えば何らかpiをダミーノードのアトリビュートに仕込まなくても明示的にpiだよとノードで示せる事くらいか・・・？（処理負荷的には特段優位性があるとも思えない・・・



何らかの計算をするノードではないので入力無し！（cachingやfrozenはある）

output(da型):deg表記で180,rad表記で3.14.....(円周率)


#### determinant
行列式の計算をするノード。式と言ってますがこいつは入力を1つしか持ちません。
なぜなら式を示す数学概念じゃないから（超絶語弊のある言い方・・・・）
行列式ってなんぞや？って人は行列式について解説してるサイトや動画を見て下さい。筆者は全然業務で必要になったことがないのであんまナイスな説明が出来ません！

input(matrix型):行列式を実行させるmatrix入力 
output(dl型):行列式を実行した結果のスカラー値

(ちなみにここでのmatrix型は4x4行列のみっぽい。というかMayaのヴァニラノード系はMatrix=4x4行列しか概念として存在しない・・・？MayaでのMatrixはTransformを扱うためだけに存在しているようなものだから別にノードとして2x2や3x3がなくてもいいですが・・・が、が！！！！！Bifrost Graphはすごく柔軟にここら扱えるんだよなぁぁぁぁ・・・・・Bifrostにも行列式ノードはありまぁす！)


#### max

入力された値のリストの中で一番大きな値を出力する
地味にこれリグでは使い所ちょいちょいあるので嬉しい。

input(dl配列型):入力値をセットするor繋ぐ
output(dl型):入力値のリストの中で一番大きな値を出力する

#### min

maxの逆で一番小さな値を出力する。これも地味にうれしい。

input(dl配列型):入力値をセットするor繋ぐ
output(dl型):入力値のリストの中で一番小さな値を出力する

#### round

入力値の浮動小数点部分の四捨五入
（Python3のRoundのように銀行丸めじゃなくて純粋にRound処理なので注意。むしろPython3の銀行丸めの方に注意だが・・・）

input(dl型):四捨五入したい値
output(dl型):入力値の浮動小数点が四捨五入された値


#### modulo

モジュロ演算つまり剰余計算です。
・・・分かりづらいですね。割り算のあまり部分を出す計算です！

$6/4=1余り2$

の2部分！

```python
6 % 4
```
したときの値！

input(dl型):割られる数
modulus(dl型):割る数
output(dl型):input / modulusの余り

moduloに関しての余談[^1]

[^1]: 超余談：昔々、人生で初めてモジュロ演算という単語を聞いたのは映画サマーウォーズの中で主人公がヒロインの生年月日を聞いて曜日を即答（マジで即答すぎて笑える）するシーンにて
ヒロインちゃん「ひょっとして全部覚えてるの？」
主人公「いえ、モジュロ演算ってのを使って・・・」
というセリフがあり、当時全くプログラミングのプの字も知らないピュアな学生だった筆者は、はぇー世の中にはけったいな演算方法があるんやなぁと信じてしまったのですが、時は流れてプログラミングをするように成ったあと、moduloの概念（%記号）を知り、え・・・？moduloって曜日出すやつでは？　えぇ・・・曜日出すのはツェラーの公式であってmodulo演算そのものではないやん！！細田守に騙された！！！ともんどりうったりうたなかったりしました。（ツェラーの公式で剰余を利用するのでModulo演算で算出するというのは完全な嘘ではないが・・・・）

#### floor

小数点以下の端数切り捨て。負の数の場合はマイナス方向に下がった数になる。

input(dl型):小数点以下を消したい数
output(dl型):小数点以下を消した数


#### ceil

floorの逆で小数点以下の端数切り上げ。負の数の場合はプラス方向に上がった数になる。

input(dl型):小数点以下を消したい数
output(dl型):小数点以下を消した数

#### truncate

入力された値の整数部分だけを出力します。

floorとceilに似てますが、純粋に整数部分だけを抽出するような動作なので微妙に挙動が違います。

input(dl型):小数点以下を消したい数
output(dl型):小数点以下を消した数

#### rotateVector

入力したベクトルを入力した回転で回した結果のベクトルを求める。

input(dl型):回転させたいベクトル
rotate(da型):回転（回転順序指定アトリビュート）
output(dl型):回転されたベクトル


#### sum

入力した値のリストを加算します。足し算

input(dl配列型):加算したい値のリスト
output(dl型):足し算結果


え？plusMinusAverageがあるだろって？まぁ落ち着いて、ちゃんとそこらも後述します。

#### subtract

入力したinput1からinput2を減算します。引き算

input1(dl型):引かれる数
input2(dl型):引く数
output(dl型):引き算結果


え？plusMinusAverageが(ry

ちなみにsubtractは載せ忘れなのか何なのか、新機能紹介ページの追加ノード一覧には載ってなく、ノードリファレンスにはしれっと載ってるし普通にノードとして呼び出せます。

#### multiply

入力したリスト同士を乗法（掛け算）する。

input(dl配列型):掛け算したい値のリスト
output(dl型):掛け算結果


え？multiplyDivideがあるだr(ry

#### divide

入力したinput1をinput2で除算（割り算）する

input1(dl型):割られる数
input2(dl型):割る数
output(dl型):割り算結果

moduloとかもそうですが、0除算になったときはメッセージとして0除算になってることを通知し0が出力されます。変にwarningとか出たりinfとか値が出力される方が色々と面倒事（warningにビックリした作業者がなにかやらかす系ヒューマンエラー的なものや、infがアトリビュートに入ることによるデータエラー的なものや）が発生するのでこの仕様が一番丸いと思います。ええ。

え？mul(ry

subtractと同じく新機能紹介ページで乗せ忘れられてる悲しきノードの一つ・・・

#### lerp

線形補間を計算します。

input1(dl型):A
input2(dl型):B
weight(dl型):AB間線上を0-1にしたときの位置の割合 (lerpでよく出てくるtの扱い)
output(dl型):AB線上をWeightで指定した位置の値



#### inverseLerp

lerpの逆で、線形補間結果からweight(t)を求める計算をします。
input1(dl型):A
input2(dl型):B
interpolation(dl型):lerpの結果
output(dl型):weight

#### negate

入力値の符号反転をします。つまり$x*-1$してるだけです。

input(dl型):値
output(dl型):input*-1の値

#### clampRange

下限と上限範囲外をクランプします。範囲内はそのままの値で出力されます。

input(dl型):値
maximum(dl型):上限値
minimum(dl型):下限値


#### smoothStep



入力値が下限の値と上限の値の範囲外であればそれぞれのリミットとなる値にクランプされ、範囲内の場合はエルミート補間された値が出力されます。

input(dl型):値
leftEdge(dl型):補間のスタート
rightEdge(dl型)補間のゴール


エルミート補間をぐぐってもなんのこっちゃ？となると思いますが、早い話がイージー・イーズアウトとインのようなグラフを描く結果になります。
テキトーに何かに繋いでキーベイクするとわかりやすいですが以下のような曲線を描きます。

![smoothstep.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3950033/afde09dc-d596-00c8-2ff7-a6f64311c5ca.jpeg)



Leapは線形補間なので動きが等速直線運動のような直線のグラフになるのと違って曲線を描くグラフになります。

値が下限と上限を超過した場合はそれぞれでクランプされます。

#### average

入力したリストの平均値を求めます。

input(dl配列型):値
output:リストの平均値

え？plusMinusAv(ry

#### length

入力したベクトルの長さを求めます。

input(dl3型):ベクトル
output(dl型):長さ




#### normalize

入力したベクトルを正規化します。

input(dl3型):ベクトル
output(dl3型):正規化されたベクトル

え？vectorProduct(ry

#### dotProduct
せっかく実装されたのに新機能紹介に載ってない重要ノード！
2つの入力ベクトルの内積値を出力します。

$\vec{a} \cdot \vec{b}$

input1(dl3型):ベクトル
input2(dl3型):ベクトル
output(dl型):内積値


え？vectorProduct(ry

#### crossProduct

せっかく実装されたのに新機能紹介に載ってない重要ノード２！
2つの入力ベクトルの外積ベクトルを出力します。

$\vec{a} \times \vec{b}$

input1(dl3型):ベクトル
input2(dl3型):ベクトル
output(dl3型):外積ベクトル

え？vectorProduct(ry

## 論理演算系ノード

#### equal

入力1と2が等価ならばBool型でTrueを出力し、等価でなければFalseが出力されます。
epsilonで許容誤差を設定できます。（便利）

$a=b$


input1(dl型):値a
input2(dl型):値b
epsilon(dl型):許容誤差
output(bool型):判定

#### and

論理積

入力1と2がTrueならばTrue、どちらかが1つでもFalseならばFalseがbool型で出力されます

$a \land b$

input1(bool型):bool
input2(bool型):bool
output(bool型):判定

#### or

論理和

入力1か2いずれか１つがTrueならばTrue、両方がTrueならTrue、全てFalseならFalseがbool型で出力されます。

$a \lor b$

input1(bool型):bool
input2(bool型):bool
output(bool型):判定

#### not
入力がTrueならFalseが、FalseならTrueが出力されます。
（2値の比較ではなく単純に入力されたbool値を反転するという実装。まぁequalで2値比較で外れていればFalse出せるのであまり出番がない感じがする。）

$a≠b$

input(bool型):bool
output(bool型):inputの逆bool

#### greaterThan
入力値1$>$入力値2が真ならばTrueを出力します。

$a$ $>$ $b$

input1(bool型):値a
input2(bool型):値b
output(bool型):判定

#### lessThan	
入力値1$<$入力値2が真ならばTrueを出力します。

$a < b$

input1(bool型):値a
input2(bool型):値b
output(bool型):判定

## 良い所

プラグの型が基本的にDouble型（DoubleLiner,DoubleAngle）なのが非常に良いですね。
既存のノードと比較したときの最大のウリと言っても良いと思います。今までFloat型のノードでうーん・・・って思ってた人はまぁまぁいると思いますがコレである程度払拭された形になります。

※Double型とFloat型の違いや浮動小数点数値の精度誤差の話はわざわざここで書かなくてもゴマンと世の中に記事があるんでそっち見て下さい。

例えばvectorProductノードでは地味に入出力がfloat型ですが、dotProductノード、crossProductノードでDouble型で扱えるようになりました。（ただし後述の通り正規化オプションがないんで使いづらいです。）


## ダメな所

もしかして、もしかして・・・・このノードって新人研修の一環で若い子に作らせたのでは？(全くもって完全な邪推でソース無し)
というような部分があったりする部分があるのがやや残念。

例えば前述のvectorProductノードでは出力値を正規化するオプションがついていますがdotProductにもvectorProductにもそんなオプションが無いので、dotProductを使う場合は正規化したベクトルを入力するか、出力結果を-1~1の範囲に正規化する必要があり、crossProductも出力結果をnormalizeノードで正規化する必要があるためDGの処理的に接続とノードが増えてるのでむしろvectorProductノードのほうが効率的では？という疑念があります。（ここらの考慮が出来ていないのが新人研修でやらせたのでは？という邪推の原因。繰り返しになりますがソースは一切無いです。）

lerpはdouble3型やXYZでの入力がないので3次元座標でのlerpしたい場合は次元分のlerpノードを作らにゃいけないのでやや面倒です。（pointConstraintで代用できますが・・・）


また他のノードに目を向けると最大にめんどくさいのが、論理演算で判定を1ノード内で複数判定させることが出来ないためまるで論理回路を組んでるが如くノードを組まねばならぬこと・・・
いやまぁ複数条件設定できるようなノードにしたら使って無くても重いノードになりかねないので最小単位としてはこれでいいとは思います・・・ですが・・・電子回路のFPGAチップのような、LUTで指定したら1ノードだけでいろんな条件式を実装できるようなノード作ってほしかった・・・・今からでも遅くないんでお願いします・・・！
(え？そのためにエクスプレッションがあるじゃんって？いやそのエクスプレッションに問題がありましてぇ・・・後述。)


あとこれはどういう条件で発動している不具合なのかまだ原因究明できていませんが、ノードエディタでtabショートカットから一部新規実装ノード呼ぼうとすると別のノードが呼ばれるの何故・・・・（and呼ぼうとするとaiRandom呼ばれたり・・・まぁcreateNodeコマンドは正常なんで別に大した話じゃないですが・・・）



## 既存のヴァニラノードとの比較

しつこいくらいに　え？　～　と記述していた部分のノードに関して既存のノードと比較してみましょう。

#### sum,subtract,average vs plusMinusAverage
float型からdouble型になったのは良いんですが、plusMinusAverageでは出来た2,3次元入力が無くなってます。劣化しとるがな！！！

#### multiply,divide,power vs multiplyDivide

float型から（略）、3次元入力ではなく1次元になってます。これも劣化しとるがな！！！

#### dotProduct,crossProduct vs vectorProduct

既に指摘しているdotProductとcrossProductはvectorProductノードのプラグDoubleLinear版として使えるかと思いきや正規化部分のお膳立てを別ノードで行わなければならないのでぶっちゃけ使いづらいですね。
vectorProductは内積外積以外にベクトル行列積、ポイント行列積も搭載してる上、operationアトリビュートを0(操作無し)にしてnormalizeOutput(出力の正規化)すると、input1に繋いだベクトルを正規化したベクトルとしてoutputに出せるという小技が使えたりするのでnormalizeノード使わなくても正規化ベクトルをvecrtorProductノードで得ることが出来ます（ただしもちろんFloat型）

#### lengh vs distanceDimension

・・・・distanceDimensionっていう完全上位互換ノードが昔からあるので存在意義がよくわかりません。（シンプルな分すこし計算処理はlengthの方に軍配あるかもしれないが、入力ベクトルが1つだけなのがめんどくさい。原点以外の2点間ベクトルのときに原点に持っていく処理挟まんといかんやんけ！！distanceDimensionノードが入出力Float型だったらまだわかるがdoubleLinear型やし・・・強いて言えば出力部分がdoubleLinearじゃなくてDouble型だけど、ほぼ困るような場面は無かろうなぁ・・・）

### 論理演算系ノード vs condition

conditionノードなら1つのノードで

```
==
!=
>
>=
<
<=
```

が扱えるのに、Greater or Equals（≧、以上）とLess or Equals（≦、以下）が無く（実装忘れ・・・？他のノードと組み合わせて相当するノードツリーを組め？スマートじゃない！）、条件毎に個別のノードにわけられてるせいでコネクションはそのままで条件を切り替えたいときに、conditionノードならoperationアトリビュートを切り替えればよかったのに別のノードツリーを組む必要があるのが非常に非常にめんどくさいです。

（ただ、conditionノードに不満が全く無いわけではなく、型がfloatであること以外に既定値でtrueがRGB 000が出力されてfalseが111出力されるのが実に美しくない・・・（setAttrで逆にするのが1手間でめんどくさい・・・））





## そもそもなんで古いノードはプラグがFloatなん？
答えは明白で、元々マテリアルとかシェーダー用のノードとして実装されたから。（if判定で今まで使っていたconditionノードを見れば明白。アトリビュート名がRGBです。）bump等のノードや、ai~で始まるArnold系ノードは概ね筆者が知る限りどれもこれもプラグがfloatです。
なんでDoubleじゃないのか？は、倍精度ほどの浮動小数点値はレンダリング関連では（90年代や00年代当時としては）オーバースペック過ぎるので単精度のFloatで実装するのは当然ですね。
Double型の汎用計算ノードを実装しないまま2024まで放置されたという事はオイオイオイという点ですが・・・



## エクスプレッションじゃだめなん？

ぶっちゃけエクスプレッションでも問題ない場面ではまったく問題ないです。
というか複雑に入り組んだ条件分岐の論理回路みたいな処理を手でノード組んだら頭がパンクします。
ただし、エクスプレッションにはいくつか問題がありまして・・・
筆者が知りうる限り3つ
#### 1.デフォの評価モードがAlways
リグとかノードの勉強するときに高確率でたどり着くSquareEnix社の佐々木氏の2019年の講演資料で[DGとパラレル評価についての内容のスライド内 p.96](http://www.jp.square-enix.com/tech/library/pdf/BDSeminar20190711.pdf#page=96)でも言及されていますが、Expressionノードの評価モードの既定値がAlwaysなため毎フレーム評価されるので意味がない評価＝無駄にシーンのPlayback負荷を上げてるだけの存在になります。onDemandにすればいいだけなのでこれは別に大した問題ではありません。

#### 2.Expressionノード同士はパラレル評価されない
はい。Expressionノードは（スレッドセーフなノードじゃないので）Expressionノード同士はパラレル評価されません。
（1で提示したPDF内でパラレル評価モードでは動かない。と説明がありますが、Mayaのパラレル評価モード設定だとExpressionが動か無いのかと誤解してしまうかもしれませんが、パラレル評価をEvaluationManagerがしないだけであって、パラレル評価モードでExpressionノードが動かないわけではありません。）
[他のノードとのパラレル評価は行われます。](https://download.autodesk.com/us/company/files/UsingParallelMaya/2022/UsingParallelMaya.html#:~:text=The%20expression%20engine,expression%20is%20evaluated.)
>The expression engine is not thread-safe so only one expression can run at a time, but it can run in parallel with any other nodes. However, if the expression uses unsafe commands (expressions could use any command to access any part of the scene), the node is marked as untrusted because nothing can run while the expression is evaluated.

スレッドセーフなノードじゃないというか、中の記述次第でいくらでもスレッドセーフじゃない設計なんて出来てしまうため、スレッドセーフが保証出来ないのでそもそもパラレル評価しないようになっている　という認識のほうがより正確かと思います。

#### 3.ある機能使うと特定条件下でMayaがとんでもなく不安定になる
まだこれ完全に解明できていないので伏線として一旦放り投げたいと思いますが、とあるMayaの機能との相性が特定条件下で非常に悪い事に最近気づきまして、超高確率でMayaがｽﾝｯと落ちるため泣く泣くExpressionノードで記述していた制御を全て計算ノードで組み直すという回避方法をしました。（その時に2024の論理演算ノードがあまりに最低限の機能実装と気付き完全に論理回路を組んでるのと同等の事をする羽目に・・・）
[まぁAutodeskも汎用ノードでこういうの組むこと推奨してるしなぁ](https://download.autodesk.com/us/company/files/UsingParallelMaya/2022/UsingParallelMaya.html#:~:text=using%20utility%20nodes.)

## 次回予告？

エクスプレッションじゃだめなん？の部分で触れたエクスプレッションを使った場合の致命的な問題が来週までに解けたらそれに関しての解説記事を~~アドカレのシリーズ2のどこか空いてる日に書きます。解けなかったら25年のアドカレ時期の自分に投げておきます。~~ 解けなかったんで25年に回します。 本当はこっちのほうがメインのつもりでしたが解析終わってないのと、そもそもの前提知識である2024での追加ノードの知名度が絶対低いのでまずはノードの方から紹介した次第。

んじゃまた。