« クラスタの名前をクラスタマテリアルの名前にしてみる。 | トップページ | The Backwater Gospel。 »

2011年2月17日 (木)

悲しみのローカルシンメトリ。

またもや唐突にスクリプトが発生します。






var rtn = GetKeyboardState( );
ModKey = rtn(1);

var oObjects = FilterX3D( Selection );
if ( oObjects.count != 0 )
{
    var oSyms = DupSymLocalFuckOff( oObjects );
    SelectObj( oSyms, ModKey );
}

function DupSymLocalFuckOff( oObjects, ModKey )
{
    var oSyms = XSIFactory.CreateObject( "XSI.Collection" );
    for ( var i=0; i<oObjects.count; i++ )
    {
        //    恥ずかしながら、tmp な null を降臨させる
        var oNull = ActiveSceneRoot.AddNull( "Fucker" );

        //    はばかりながら、tmp な null の SRT を、元オブジェクトの親と一致させる
        oNull.Kinematics.Global.Transform = oObjects(i).Parent.Kinematics.Global.Transform;

        //    人目を忍んで、まずはそのまんま複製する → 複製されたブツは oDup に
        if ( ModKey == 0 )
        {
            var oDup = SIDuplicate( oObjects(i) )(0);
        }
        else
        {
            var oDup = Clone( oObjects(i) )(0); // 残念なことに、Shift とか押しながらだと Clone
        }

        //    恥をしのんで、複製された oDup を、tmp な null の子供にする
        oNull.AddChild( oDup );

        //    こともあろうに、oDup を子供にした null をワールド原点に戻す
        oNull.Kinematics.Global.Transform = ActiveSceneRoot.Kinematics.Global.Transform;

       //    やけくそで、標準の DuplicateSymmetry コマンドで YZ プレーンなシンメトリ複製をする
        var oSym = DuplicateSymmetry( oDup, null, true, 1, 0, 0, 0, null)(0);
        oSyms.Add( oSym );

        //    泣きながら、シンメトリ複製後のブツを元の SRT に戻す
        oNull.Kinematics.Global.Transform = oObjects(i).Parent.Kinematics.Global.Transform;

       //    情けないことに、複製後のブツを元の親の子供に戻しておく
        oObjects(i).Parent.AddChild( oSym );

        //    誰にも気付かれないように、tmp なブツたちを消しておく
        DeleteObj( oDup );
        DeleteObj( oNull );
    }
    return oSyms;    //    何事もなかったように、複製されたブツを戻す
}

function FilterX3D( in_Objs )
{
    var oCol = XSIFactory.CreateObject( "XSI.Collection" );
    for ( var i=0; i<in_Objs.count; i++ )
    {
        if ( in_Objs(i).IsClassOf( siX3DObjectID ) )
        {
            oCol.Add( in_Objs(i) );
        }
    }
    return oCol;
}


ブツを選んで(複数可)実行します。
ローカル座標なシンメトリ複製が実行されます。X反転のみです。
ローカル=つまり自分の親に対しての X 反転になります。


XSI の Duplicate Symmetry コマンドはワールド原点を中心にしたシンメトリ複製しかしてくれないので、あまりにも悲しくて書きました。 しかし座標の変換というか計算というか、俺そういうの全くわからないので、手作業でやったことをただスクリプトにしただけというものであります。 つまり、こちらは手順を指定するだけであり、計算アルゴリズムはブラックボックスのまま XSI の機能に委ねているわけです。 これはこれでツール開発の正しいアプローチだとは思いますが、冗長なスクリプトになるし、実行遅くなりがちだし、何よりも、ちゃんとしたアルゴリズムの考察を忌避するためにやっていることなので、やはり悲しくなります。



最近このアプローチばかりで、ダメっす俺。
XSI の機能をスクリプトでどう動かすか、という所を知っているというだけであり、そもそものアルゴリズムは全くわかってないし、考えようともしない傾向にある。 刹那的であり、飛躍がありません。 光と影の挙動を理解しないまま、ともかくライトの Intensity 上げれば明るくなるんでしょー みたいな、そういうアプローチです。




まあいいんですが。

詳しい方、添削して下さい。

よろしくお願い致します。




.

|

« クラスタの名前をクラスタマテリアルの名前にしてみる。 | トップページ | The Backwater Gospel。 »

コメント

どもです、解決になってないですが
DuplicateSymmetryの引数の
SymmetryPlaneA
SymmetryPlaneB
SymmetryPlaneC
SymmetryPlaneD
がシンメトリするプレーンの指定ぽいです
ax+by+cz+d=0てのが平面の式でそれぞれに入るっぽいです
(a,b,c)が向きで(x,y,z)が位置みたいなんですが
axってa掛けるxじゃないの?ってところで分からなくなってしまいましたw
teraさんの記事http://tera256.exblog.jp/12129460/とリンクしてる気が

以下途中まで作った奴です、対象が回転してると変な角度で複製されます
set oObj = selection(0)

set oTrans= oObj.kinematics.Global.Transform'選択オブジェクトのトランフォームげっと

set vT = XSIMath.CreateVector3
set vR = XSIMath.CreateVector3
set vN = XSIMath.CreateVector3( 1.0, 0.0, 0.0)
set rA = XSIMath.CreateRotation

oTrans.GetTranslation vT'選択オブジェクトの位置げっと
oTrans.GetRotationXYZAngles vR'選択オブジェクトの回転げっと

rA.SetFromXYZAngles vR
vN.MulByRotationInPlace rA'プレーンをげっとした回転で回す

ax = vN.x*vT.x
by = vN.y*vT.y
cz = vN.z*vT.z
d = vT.dot(vN) * -1
set obj = DuplicateSymmetry(, True, False, ax, by, cz, -d, True)

投稿: ringpull(りんぷる | 2011年2月17日 (木) 22時41分

さすが 287cm。

俺、そのマスだかベクタだかようわからんのです Orz
っていうか俺も SDK ガイドで Duplicate Symmetry のページを見たらその ax だか by だかを発見して、でもマトモな説明がひとことも書かれてなくて、モニタ2個投げたところでした。

ということでりんぷるさんが完成させて下さい。結果分かったことを教えて下さい。
ご査収の程よろしくお願い申し上げます。

投稿: junki | 2011年2月18日 (金) 00時51分

でけました
axうんぬんのところに、ただの方向をいれたらなんかうまくいったような気がします
jsにしときました

var oObj = selection(0);

var oTrans = oObj.kinematics.Global.Transform;//選択オブジェクトのトランフォームげっと

var vT = XSIMath.CreateVector3();
var vR = XSIMath.CreateVector3();
var vN = XSIMath.CreateVector3( 1.0, 0.0, 0.0);
var rA = XSIMath.CreateRotation();

oTrans.GetTranslation(vT);//選択オブジェクトの位置げっと
oTrans.GetRotationXYZAngles(vR);//選択オブジェクトの回転げっと

rA.SetFromXYZAngles( vR);
vN.MulByRotationInPlace( rA);//プレーンをげっとした回転で回す

vN.NormalizeInPlace();
d = vT.dot(vN) * -1;
var oDup = DuplicateSymmetry(oObj, true, false, vN.x, vN.y, vN.z, -d, true)(0);

投稿: ringpull(りんぷる | 2011年2月18日 (金) 08時49分

りんぷるさん、ありがとう。後で試してみる。問題なかったら、りんぷるクレジットを入れてプラグインにします。 とりあえず自分で作ったバージョンでもやりたいことはできていて、今の作業的にかなり便利(゚∀゚)

投稿: junki | 2011年2月19日 (土) 12時40分

りんぷるさん


あれれ?

今さら試してみたんだけど、シンメトリ複製されませんね? 複製はされるんだけど、その場に居座ったまま、対象になってくれませぬ。

御査収よろしくお願い致します。

投稿: junki | 2011年2月22日 (火) 13時56分

あっ

親に対してではなく、自分自身のセンターを軸にして対象複製するんですねっ
今気付きました。

すいません、ってことで正常作動してます。
ええと、親に対して対象複製にするにはどこをいじれば・・・・

投稿: junki | 2011年2月22日 (火) 14時08分

ママンの位置と回転を取ってくればいいんでしょうかね。


var oTrans = oObj.Parent.kinematics.Global.Transform;//選択オブジェクトのママントランフォームげっと


こう書き換えたら、親に対しての対象複製になったように見える。

投稿: junki | 2011年2月22日 (火) 14時17分

そうですね
oTransに基準になるトランフォームを入れるとそれに従う感じでしょうか

以下余談ですが
var vN = XSIMath.CreateVector3( 1.0, 0.0, 0.0);
のところを
var vN = XSIMath.CreateVector3( 0.0, 1.0, 0.0);
にするとY反転に
var vN = XSIMath.CreateVector3( 0.0, 0.0, 1.0);
とするとZ反転になります

あと最後の
d = vT.dot(vN) * -1;
var oDup = DuplicateSymmetry(oObj, true, false, vN.x, vN.y, vN.z, -d, true)(0);

d = vT.dot(vN);
var oDup = DuplicateSymmetry(oObj, true, false, vN.x, vN.y, vN.z, d, true)(0);
でいいです、dに-1を2回掛けてましたw

投稿: ringpull(りんぷる | 2011年2月22日 (火) 14時22分

イエイ。了解です。 今俺様用に改造中。

投稿: junki | 2011年2月22日 (火) 14時28分

コメントを書く



(ウェブ上には掲載しません)




トラックバック


この記事へのトラックバック一覧です: 悲しみのローカルシンメトリ。:

« クラスタの名前をクラスタマテリアルの名前にしてみる。 | トップページ | The Backwater Gospel。 »