今回はマテリアルのサブ要素(マテリアル、テクスチャ)の取得について。
マテリアルは要素の下に別の要素がツリー状に接続される、いわゆる階層構造を持っています。
こういった構造では、再帰処理による取得が強力です。
以下は指定マテリアル下の全てのサブ要素を取得する関数です。
オプション引数のsubsは内部使用専用なので、基本的には何も指定しないでください。
内部的な処理を簡単に説明すると、マテリアルのサブマテリアルとサブテクスチャを全て検索し、それらの要素に対してgetAllSubMtlAndMapsを再帰的に実行しています。
ただし、この時サブ要素がループ接続されている可能性を考慮し(実際にそういう状況になるのかは知りません…)、appendIfUniqueで要素がまだ追加されていない時だけ再帰しています。
よって、subsに最初から要素を追加しておいた場合、そのマテリアル以下は検索されない事になります。
ただし、取得されるサブ要素は、マテリアルとテクスチャマップが混ざってしまっているので、個別に必要な場合は自力で分類する必要があります。
余談ですが、自分が初めて再帰関数を使ったとき、再帰内でループする事に気付かず、処理がフリーズする原因を見つけられずに3日くらい悩んだ思い出があります。
再帰処理は非常に強力ではありますが、度々バグの原因になったりして扱いの難しさを時々実感します。
マテリアルは要素の下に別の要素がツリー状に接続される、いわゆる階層構造を持っています。
こういった構造では、再帰処理による取得が強力です。
以下は指定マテリアル下の全てのサブ要素を取得する関数です。
fn getAllSubMtlAndMaps mtl subs:#() =
(
if mtl != undefined and (appendIfUnique subs mtl) do
(
if (superclassof mtl) == material do
(
for i = 1 to (getNumSubMtls mtl) do
getAllSubMtlAndMaps (getSubMtl mtl i) subs:subs
)
for i = 1 to (getNumSubTexmaps mtl) do
getAllSubMtlAndMaps (getSubTexmap mtl i) subs:subs
)
subs
)
引数のmtlにはマテリアルオブジェクトを指定してください。
例えば・・・
getAllSubMtlAndMaps $.material -- 選択オブジェクトのマテリアル
や
getAllSubMtlAndMaps meditMaterials[1] -- マテリアルスロット1のマテリアル
といった感じです。
オプション引数のsubsは内部使用専用なので、基本的には何も指定しないでください。
内部的な処理を簡単に説明すると、マテリアルのサブマテリアルとサブテクスチャを全て検索し、それらの要素に対してgetAllSubMtlAndMapsを再帰的に実行しています。
ただし、この時サブ要素がループ接続されている可能性を考慮し(実際にそういう状況になるのかは知りません…)、appendIfUniqueで要素がまだ追加されていない時だけ再帰しています。
よって、subsに最初から要素を追加しておいた場合、そのマテリアル以下は検索されない事になります。
ただし、取得されるサブ要素は、マテリアルとテクスチャマップが混ざってしまっているので、個別に必要な場合は自力で分類する必要があります。
local subs = getAllSubMtlAndMaps $.material
local mtls = #()
local maps = #()
for s in subs do
(
if (superclassof s) == material then
append mtls s
else
append maps s
)
こんな感じです。余談ですが、自分が初めて再帰関数を使ったとき、再帰内でループする事に気付かず、処理がフリーズする原因を見つけられずに3日くらい悩んだ思い出があります。
再帰処理は非常に強力ではありますが、度々バグの原因になったりして扱いの難しさを時々実感します。