「オブジェクトがカメラに写っているかどうかを取得したい!」ということでICEで組んでみました。
今回は分かりやすいようにカメラの範囲外になると表示が消えるようにしています。(⑅╸▵╺⑅)
実際のコンパウンドは以下のリンクからダウンロードしてください
(ダウンロードは 右クリック>対象をファイルに保存 で出来るかと。)
ダウンロード
使い方
1.判別したいポリゴンメッシュオブジェクトのICETreeにコンパウンドを読み込む
2.任意のカメラをコンパウンドに接続
ICEツリーをエンベロープより上位のコンストラクションモードに差し込んでやることでエンベロープオブジェクトにも対応できます。
分かってるバグ
エンベロープ済みのオブジェクト自身に回転値を加えるなどすると判定がおかしくなります。
(デフォーマーとエンベロープオブジェクトをまとめた上位(親)ノードを回転・移動させることは問題なし)
ICEコンパウンドの簡単な説明
Softimageに最初から用意されていた
『Test Visibility From Camera(カメラからの可視性のテスト)』
『
Get Bounding Box(バウンディング ボックスの取得)』
を拝借して使っています。
『
Get Bounding Box(バウンディング ボックスの取得)』で自分自身のPointPositionからバウンディングボックスの情報を取得。
上辺・下辺8か所、さらにY軸の中心位置の4か所を加えた12ポイントについて『Test Visibility From Camera(カメラからの可視性のテスト)』を流用して作ったコンパウンドでカメラ内に収まっているかどうかを判別しています。
12ポイントの1つでも画面内に収まっていたらそのオブジェクトは画面内に収まっていると判断されます。
『Test Visibility From Camera(カメラからの可視性のテスト)』についてはカメラの視野タイプが「水平」の場合のみを考慮していたようで「垂直」にすると正常に動作していなかったです。
ということで、その点も修正してみました。
(詳しくはTest Visibility From Camera2コンパウンドの中を参照)
その結果をもとにオブジェクトの表示・非表示を切り替えています。
ICE適用スクリプト例
選択オブジェクトに対して今回のICEコンパウンドを適用するスクリプトはこんなかんじ。
自動的にビューポートB
var oObj = Selection
for(var i = 0; i < oObj.count; i++)ICE_VisibilityTest( oObj(i) )
function ICE_VisibilityTest( oObj ){
//既存のICETreeを削除する。
var oICETrees = oObj.ActivePrimitive.ICETrees
if( oICETrees.count > 0 ){
DeleteObj( oICETrees );
}
//ICETreeを作成。
var oPrim =oObj.ActivePrimitive;
oICETree = ApplyOp("ICETree", oPrim , "", "", "", 3 );
//コンパウンドをロードしてICETreeに接続
var oNODE = AddICECompoundNode( "Test Polymsh Visibility From Camera" , oICETree );
ConnectICENodes( oICETree(0).InputPorts(0) , oNODE.OutputPorts(0) );
//カメラを取得してコンパウンドに接続
var oGet = AddICENode("$XSI_DSPRESETS\\ICENodes\\GetDataNode.Preset" , oICETree );
ConnectICENodes( oNODE.InputPorts("Camera") , oGet.OutputPorts("outname") );
var ActiveCamera = GetViewCamera(1);
oGet.reference.value = ActiveCamera.Fullname;
}
赤字の部分はICEコンパウンドがSIに読み込まれている場合の記述なので、適当な場所に置いておく場合はファイルのフルパスになります。
一応複数選択でも処理してますが、オブジェクトが多すぎるとSIさんがお亡くなりになられる可能性が高いですw
自己責任でどうぞ。。(*∀*;)