2017年03月21日

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

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

正方形までは描けるようになったので、今度は円形に塗りつぶしたい。オリジナルではピクセルを塗る時にそれがヒットポイントを中心とした円内なのかどうかを判定して円内ならピクセルを塗るような処理をする必要がある。チュートリアルのプログラムでは「paintBrush()」ファンクションの下の部分がそれだ。

 case BrushShape.selection of
 (
    1: (
      if distance pos currentPos <= BrushSize.value/2 do
        setPixels theCanvasBitmap pos #(thePaintColor)
    )
    2: setPixels theCanvasBitmap pos #(thePaintColor)
    3: (
      theFactor = (distance pos currentPos) / (BrushSize.value/2.0)
      if theFactor <= 1.0 do
      (
        theFactor = sin ( 90.0 * theFactor)
        thePixels = getPixels theCanvasBitmap pos 1
        if thePixels[1] != undefined do
        (
          thePixels[1] = (thePixels[1] * theFactor) + (thePaintColor * (1.0 - theFactor))
          setPixels theCanvasBitmap pos thePixels
        )
      )
    )--end case 3
 )--end case

「currentPos」がペイントブラシの中心位置で、「pos」が塗るかどうかの判定位置だ。どちらもキャンバス座標系の座標値だ。

今回はメッシュサーフェス上で正方形になるようにしたので、円もメッシュサーフェス上で考えなきゃならない。だから「pos」が示す座標に対応したメッシュサーフェス上の座標を求めて、2点間の距離を求めてそれがブラシサイズより小さいかどうかを調べる事になる。

それなら最初からメッシュサーフェス上で処理をして、最後にテクスチャ座標に変換すれば良さそうだけど、それだとピクセル単位で処理出来ないから塗りつぶした時に隙間が出来たり重複して塗ったりって事になりかねない。

そこで今度はキャンバス座標系からワールド座標系へ変換する変換が必要になる。

また、オリジナルのプログラムでは正方形の中を塗っていたけどそれもキャンバス上では歪んだものになるので塗りつぶしのためのピクセル位置の生成方法も変更する必要がある。オリジナルのプログラムでは「drawStroke()」の下の太字の部分がその部分だ。

  fn drawStroke lastPos pos drawIt: =
  (
    currentPos = lastPos
    deltaX = pos.x - lastPos.x
    deltaY = pos.y - lastPos.y
    maxSteps = amax #(abs(deltaX),abs(deltaY))
    deltaStepX = deltaX / maxSteps
    deltaStepY = deltaY / maxSteps
    for i = 0 to maxSteps do
    (
      if airBrush.checked then
        for b = 1 to (BrushSize.value / AirBrushSpeed.value) do
          paintBrush (currentPos + (random [-BrushSize.value/2,-BrushSize.value/2] [BrushSize.value/2,BrushSize.value/2] ))
      else
        for b = -BrushSize.value/2 to BrushSize.value/2 do
          for c = -BrushSize.value/2 to BrushSize.value/2 do
            paintBrush (currentPos + [c,b])
      currentPos += [deltaStepX, deltaStepY]
    )
    if drawIt== true or drawIt == unsupplied do theCanvas.bitmap = theCanvasBitmap
  )

エアブラシにした場合は単純にメッシュサーフェス上にランダムな位置を生成して、それをキャンバス座標に変換して点を打てば良さそうだ。それ以外の時はキャンバス座標上に生成した塗りつぶしたい四角形をY軸方向に1ピクセルごとスライスしてX軸に平行な線分に分解して、その線分を1ピクセルごとに分解して1つの描画点にする必要がある。

fig01

次回はこれらを実現するためのプログラムを作ってみたい。

それではまた次回。

maxまとめページ



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

トラックバックURL

この記事にコメントする

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

Archives