2019年05月14日

ビットマップペイントツールのチュートリアルをやってみた その222 3dsmax 2019

引き続きMAXScriptマニュアルに載っている「チュートリアル-ビットマップペイントツールを9つの簡単なステップで作成する」 の続きを考えて見たい。

前回までの変更で「offpoint」配列にアクセスすれば頂点番号からその頂点を移動してUV境界を膨らませた輪郭の頂点にアクセス出来るようになった。ただしその頂点はブラシ立方体でトリミングした多角形ではなくて3角形の面の頂点に対応したものだ。3角形の面をブラシ立方体でトリミングするのは「crossFaceMaps()」で頂点座標リストを生成して、それを「clipface()」に渡して行っている。そして返ってきた頂点座標リストを「meshop.getBaryCoords()」で重心座標に変換して、それに重心座標からビットマップ座標に変換するマトリクスをかけてビットマップ座標に変換している。

fn crossFaceMaps theMesh theChannel mt2b =
(
  invBrushTransform = inverse( brushtransform)
  crossfaces = selectcrossface()
  for faceIndex in crossfaces do (
    vlist = #()
    sufFace = getFace theMesh  faceIndex
    append vlist (getVert theMesh sufFace.x)
    append vlist (getVert theMesh sufFace.y)
    append vlist (getVert theMesh sufFace.z)
    mg2w=(matrix3 [vlist[1].x,vlist[1].y,vlist[1].z] [vlist[2].x,vlist[2].y,vlist[2].z] [vlist[3].x,vlist[3].y,vlist[3].z] [0,0,0])
    texFace = meshop.getMapFace theMesh theChannel faceIndex
    tv1= meshop.getMapVert theMesh theChannel texFace.x
    tv2= meshop.getMapVert theMesh theChannel texFace.y
    tv3= meshop.getMapVert theMesh theChannel texFace.z
    mg2t=(matrix3 [tv1.x,tv1.y,1] [tv2.x,tv2.y,1] [tv3.x,tv3.y,1] [0,0,0])

    mg2b = mg2t * mt2b
    mb2g = inverse mg2b
    mb2w = mb2g * mg2w
    
    clipface &vlist invBrushTransform 

    if vlist.count == 0 then continue
    maplist =  #()

    for v in vlist do (
      mp = (meshop.getBaryCoords theMesh faceIndex v) * mg2b
      append maplist mp
    )
    append maps #(maplist , mb2w)      )
),

この時に扱われる三角形の面の3つの頂点番号は「texFace」に入っているので、その番号から「offpoint」を調べれば、2つの頂点であらわされるエッジがUVマップの輪郭のエッジなのかどうかが判別できる。あとはそのエッジが「clipface()」でどうクリッピングされたかがわかれば、そのエッジのクリッピングポイントの内分比率を使ってオフセットされたエッジをクリッピングしてはみ出し部分の輪郭を生成出来そうだ。

下が「clipface()」の中身で、引数「w2b」はワールド座標系をブラシ立方体のローカル座標に変換するマトリクスだ。ブラシ立方体のローカル座標ならクリッピングの判定が簡単になるからね。

fn clipface &vlist w2b = ( 
  for i = 0 to 5 do (
    vtmp = #()
    for j = 1 to (vlist.count - 1) do (
      st = chckClip vlist[j] vlist[j+1] w2b i
      if st[1] == 0 then (
        append vtmp vlist[j] 
      ) else if st[1] == 2 then (
        append vtmp vlist[j] 
        append vtmp (innerpoint vlist[j] vlist[j+1] st[2])
      ) else if st[1] == 1 then (
        append vtmp (innerpoint vlist[j] vlist[j+1] st[2])
      )
    )
    if vlist.count == 0 then exit
    st = chckClip vlist[vlist.count] vlist[1] w2b i
    if st[1] == 0 then (
        append vtmp vlist[vlist.count]
    ) else if st[1] == 2 then (
      append vtmp vlist[vlist.count]
      append vtmp (innerpoint vlist[vlist.count] vlist[1] st[2])
    ) else if st[1] == 1 then (
      append vtmp (innerpoint vlist[vlist.count] vlist[1] st[2])
    )
    vlist = vtmp
  )
),

このファンクションの中では「vlist」で与えられた面の頂点リストから2点ずつ取り出して、2点間を繋ぐ直線とブラシ立方体の6つの面との関係を「chckClip()」で調べて、全部立方体の内側か、内から外に出るエッジか、外から内に入るエッジか、完全に外かを判定し「st[1]」、交点があるならその内分点を全長に対する比率「st[2]」から求めてもとの頂点と置き換えて行く。このクリッピングの時に同じ比率でオフセットされたエッジもトリムできれば良さそうな感じだ。

続きはまた次回。

maxまとめページ



take_z_ultima at 11:30│Comments(0)3ds Max | CG

この記事にコメントする

名前:
URL:
  情報を記憶: 評価: 顔   
 
 
 

Archives