2017年01月

2017年01月31日

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

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

今回も「PainterInterface」について調べてみたい。

「ポイント収集」モードはストローク中にブラシにヒットしたポイントを収集するモードだ。

「ポイント収集」モードを有効にするには「pointGatherEnable」をtrueにする。このプロパティは読み書き出来るので値を調べることでモードが有効か無効かもわかる。

thePainterInterface.pointGatherEnable : boolean : Read|Write 

「ポイント収集」モードでストロークして特定のノード上でヒットしたポイントのリストは「getPointGatherHits」で取得する事が出来る。

<bitArray>thePainterInterface.getPointGatherHits <node>node 

例えば下のプログラムはこれを使ってポイントを選択するものだ。「getPointGatherHits()」で得たポイントのリストを「polyop.setVertSelection()」で選択している。

(
  local theObj = undefined
  local pghba
  thePainterInterface.pointGatherEnable = true

  rollout TestPinterIterfaceRollout "MicroPaint"
  (
    fn startStroke = print "Handle start stroke here"
    fn paintStroke = (
		print "--- paintStroke ---"
    )  
    fn endStroke = (
		print "--- endStroke ---"
		pghba=thePainterInterface.getPointGatherHits theObj
		polyop.setVertSelection theObj pghba
	  )
    fn cancelStroke = print "Handle cancel stroke here"
    fn systemEnd = print "Handle system end here"

    pickbutton pickMesh "Pick Mesh" autodisplay:true
    checkbutton paint3D "3D PAINT"
    button btnOptions "Option"
  
    on TestPinterIterfaceRollout open do (
		if thePainterInterface.InPaintMode() then
        (
          thePainterInterface.EndPaintSession()
	    )
    )
	
	  on TestPinterIterfaceRollout close do (
		if thePainterInterface.InPaintMode() then
        (
          thePainterInterface.EndPaintSession()
	    )
    )
  
    on pickMesh picked obj do
    (
      if obj != undefined do
      (
        theObj = Obj
      ) 
    ) 
  
    on paint3D changed state do 
    (
      if thePainterInterface.InPaintMode() or theObj == undefined then
      (
        thePainterInterface.EndPaintSession()
        paint3D.checked = false
      )
      else
      (
        paint3D.checked = true
        thePainterInterface.initializeNodes 0 #(theObj)
        thePainterInterface.ScriptFunctions startStroke paintStroke endStroke cancelStroke SystemEndPaintSession
        thePainterInterface.startPaintSession()
      )
    )
    on btnOptions pressed do (
      thePainterInterface.paintOptions() 
    )
  )
  createDialog TestPinterIterfaceRollout 
)

下のGIFアニメはこのプログラムを実行して、編集可能ポリゴンにペイントしてみているところだ。「Pick Mesh」ボタンを押して頂点サブオブジェクトモードにしたメッシュオブジェクトを選んで、「3D PAINT」ボタンを押してメッシュをブラシでストロークすると、下のように頂点が選択状態になる。

fig02

続きはまた来週。

maxまとめページ



take_z_ultima at 11:30|この記事のURLComments(0)TrackBack(0)3ds Max | CG

2017年01月30日

modo10のスクリプトについて調べてみた その52

「UVMap」クラスを調べていたらバグと思えるものを見つけたので書いておくね。

それは「continuousVertices()」メソッドだ。これは連続UVマップ値を持つ頂点のタプルを取得するためのものなんだけど、ソースを見ると以下のようになっている。

    def continuousVertices(self):
        return tuple(self.iterDisContinuousVertices())

    def iterContinuousVertices(self):
        for i in range(len(self._geometry.vertices)):
            if self.__get(i, listContinuous=True, listNonContinuous=False):
                yield MeshVertex(i, self._geometry)

見ての通りこれじゃあ非連続UVマップの頂点のタプルを出力しちゃうよね。

実際にやってみると下のように「continuousVertices()」メソッドも「disContinuousVertices()」メソッドも出力が同じになってしまった。

import modo
mesh = modo.Mesh('Mesh')
geo=mesh.geometry
t=geo.vmaps.uvMaps[0]
print "-- continuousVertices --"
print t.continuousVertices()
print "-- disContinuousVertices --"
print t.disContinuousVertices()

# Result: 
-- continuousVertices --
(modo.MeshVertex(0, 'mesh002'), modo.MeshVertex(1, 'mesh002'), modo.MeshVertex(4, 'mesh002'), modo.MeshVertex(5, 'mesh002'), modo.MeshVertex(8, 'mesh002'), modo.MeshVertex(9, 'mesh002'), modo.MeshVertex(11, 'mesh002'), modo.MeshVertex(13, 'mesh002'), modo.MeshVertex(15, 'mesh002'), modo.MeshVertex(17, 'mesh002'), modo.MeshVertex(23, 'mesh002'))
-- disContinuousVertices --
(modo.MeshVertex(0, 'mesh002'), modo.MeshVertex(1, 'mesh002'), modo.MeshVertex(4, 'mesh002'), modo.MeshVertex(5, 'mesh002'), modo.MeshVertex(8, 'mesh002'), modo.MeshVertex(9, 'mesh002'), modo.MeshVertex(11, 'mesh002'), modo.MeshVertex(13, 'mesh002'), modo.MeshVertex(15, 'mesh002'), modo.MeshVertex(17, 'mesh002'), modo.MeshVertex(23, 'mesh002'))

連続UVマップの頂点のタプルを得るには「meshgeometry.py」の「continuousVertices()」の定義を下のように直すか、「continuousVertices()」は使わないで、「tuple(UVマップのオブジェクト.iterContinuousVertices())」とするかする必要がある。

    def continuousVertices(self):
        return tuple(self.iterContinuousVertices())

    def iterContinuousVertices(self):
        for i in range(len(self._geometry.vertices)):
            if self.__get(i, listContinuous=True, listNonContinuous=False):
                yield MeshVertex(i, self._geometry)

下のプログラムは「meshgeometry.py」は修正しないで使い方を変更したもの。今度は連続UVを持つ頂点のタプルが得られた。

import modo
mesh = modo.Mesh('Mesh')
geo=mesh.geometry
t=geo.vmaps.uvMaps[0]
print "-- continuousVertices --"
print tuple(t.iterContinuousVertices())
print "-- disContinuousVertices --"
print t.disContinuousVertices()

# Result: 
-- continuousVertices --
(modo.MeshVertex(2, 'mesh002'), modo.MeshVertex(3, 'mesh002'), modo.MeshVertex(6, 'mesh002'), modo.MeshVertex(7, 'mesh002'), modo.MeshVertex(10, 'mesh002'), modo.MeshVertex(12, 'mesh002'), modo.MeshVertex(14, 'mesh002'), modo.MeshVertex(16, 'mesh002'), modo.MeshVertex(18, 'mesh002'), modo.MeshVertex(19, 'mesh002'), modo.MeshVertex(20, 'mesh002'), modo.MeshVertex(21, 'mesh002'), modo.MeshVertex(22, 'mesh002'), modo.MeshVertex(24, 'mesh002'), modo.MeshVertex(25, 'mesh002'))
-- disContinuousVertices --
(modo.MeshVertex(0, 'mesh002'), modo.MeshVertex(1, 'mesh002'), modo.MeshVertex(4, 'mesh002'), modo.MeshVertex(5, 'mesh002'), modo.MeshVertex(8, 'mesh002'), modo.MeshVertex(9, 'mesh002'), modo.MeshVertex(11, 'mesh002'), modo.MeshVertex(13, 'mesh002'), modo.MeshVertex(15, 'mesh002'), modo.MeshVertex(17, 'mesh002'), modo.MeshVertex(23, 'mesh002'))

それではまた次回。

modo10ブログ目次



take_z_ultima at 11:30|この記事のURLComments(0)TrackBack(0)modo | CG

2017年01月27日

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

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

前回、重心座標系からUV座標値を求める事をやったのでついでに三次元座標から重心座標値を求める方もやってみたい。

変換する座標値は三角ポリゴンABCの平面上にあると仮定すれば得られる重心座標値の要素の合計が1になると言う拘束条件は省略できるので、重心座標(α,β,γ)とポリゴン上の点P(xp,yp,zp)、ポリゴンの3頂点A(xa,ya,za)、B(xb,yb,zb)、C(xc,yc,zc)の関係式は以下のようになるから、

fig01

式を行列の式にまとめて変形してやると、

fig05

となる。3X3の行列の逆行列を求めて式を書いてるとうっかりミスも出易いので、ここからの式の処理はMaximaを使って行う。Maximaについてはこのブログでも何度かやってるフリーで使える数式処理ソフトだ。

まず2つの行列を入力する。

fig01

次にa行列の逆行列にb行列をかけてgp行列を作った。

fig02

最後にgp行列を「rat」で単純化して整理した。

fig03

これを選択してコピーして、

fig04

ペーストしたのが下のコードだ。

matrix([((xb*yc-xc*yb)*zp+(-xb*yp+xp*yb)*zc+(xc*yp-xp*yc)*zb)/((xa*yb-xb*ya)*zc+(-xa*yc+xc*ya)*zb+(xb*yc-xc*yb)*za)],[-((xa*yc-xc*ya)*zp+(-xa*yp+xp*ya)*zc+(xc*yp-xp*yc)*za)/((xa*yb-xb*ya)*zc+(-xa*yc+xc*ya)*zb+(xb*yc-xc*yb)*za)],[((xa*yb-xb*ya)*zp+(-xa*yp+xp*ya)*zb+(xb*yp-xp*yb)*za)/((xa*yb-xb*ya)*zc+(-xa*yc+xc*ya)*zb+(xb*yc-xc*yb)*za)])

分母は共通なので変数dに計算しておいて、残りの式の分母の部分をdで置き換えて式を書き直したのが下の式だ。

これで3頂点A(xa,ya,za)、B(xb,yb,zb)、C(xc,yc,zc)を持つ三角形上の点P(xp,yp,zp)を重心座標G(a,b,c)に変換できる。

d=((xa*yb-xb*ya)*zc+(-xa*yc+xc*ya)*zb+(xb*yc-xc*yb)*za)
a=((xb*yc-xc*yb)*zp+(-xb*yp+xp*yb)*zc+(xc*yp-xp*yc)*zb)/d
b=-((xa*yc-xc*ya)*zp+(-xa*yp+xp*ya)*zc+(xc*yp-xp*yc)*za)/d
c=((xa*yb-xb*ya)*zp+(-xa*yp+xp*ya)*zb+(xb*yp-xp*yb)*za)/d
g=[a,b,c]

これをテストプログラムに組み込んでペイントでヒットした位置から重心座標値を求めたものと「thePainterInterface.getHitFaceData()」から得た重心座標を表示させて比較すると値が揃った。

(
  local theObj = undefined
  local localHit = [0,0,0]
  local localNormal = [0,0,0]
  local worldHit=[0,0,0]
  local worldNormal=[0,0,0]
  local radius=1
  local str=1
  local tabIndex = 0
  local offmeshhittype = 0
  local offMeshHitLocator = undefined
  local bary=[0,0,0]
  local faceIndex=0

  rollout TestPinterIterfaceRollout "MicroPaint"
  (
    fn startStroke = print "Handle start stroke here"
    fn paintStroke = (
      hits = thePainterInterface.getHitCount() 
      thePainterInterface.getHitPointData &localHit &localNormal &worldHit &worldNormal &radius &str tabIndex
	    thePainterInterface.getHitFaceData &bary &faceIndex theObj tabIndex
	    mesh = theObj.mesh
	    face = getFace mesh faceIndex	
	    va = (getVert mesh face.x) *  theObj.transform
	    vb = (getVert mesh face.y) *  theObj.transform
	    vc = (getVert mesh face.z) *  theObj.transform
		
	    d=((va.x*vb.y-vb.x*va.y)*vc.z+(-va.x*vc.y+vc.x*va.y)*vb.z+(vb.x*vc.y-vc.x*vb.y)*va.z)
	    a=((vb.x*vc.y-vc.x*vb.y)*worldHit.z+(-vb.x*worldHit.y+worldHit.x*vb.y)*vc.z+(vc.x*worldHit.y-worldHit.x*vc.y)*vb.z) /d
	    b=-((va.x*vc.y-vc.x*va.y)*worldHit.z+(-va.x*worldHit.y+worldHit.x*va.y)*vc.z+(vc.x*worldHit.y-worldHit.x*vc.y)*va.z)/d
	    c=((va.x*vb.y-vb.x*va.y)*worldHit.z+(-va.x*worldHit.y+worldHit.x*va.y)*vb.z+(vb.x*worldHit.y-worldHit.x*vb.y)*va.z) /d
	    print bary
	    print [a,b,c]
    )  
    fn endStroke = (
		print "--- endStroke ---"
	  )
    fn cancelStroke = print "Handle cancel stroke here"
    fn systemEnd = print "Handle system end here"

    pickbutton pickMesh "Pick Mesh" autodisplay:true
    checkbutton paint3D "3D PAINT"
    dropdownlist hitType "Off Mesh Hit Type" items:#("0", "1", "2") fieldwidth:40
    spinner  offMeshHitZDepth "offMeshHitZDepth" range:[-9999,999,100] type:#float fieldwidth:40
    pickbutton pickLocator "Pick Hit Position Locator" autodisplay:true
    button btnOptions "Option"
  
    on TestPinterIterfaceRollout open do (
		if thePainterInterface.InPaintMode() then
        (
          thePainterInterface.EndPaintSession()
	    )
        thePainterInterface.offMeshHitZDepth = offMeshHitZDepth.value
    )
	
	 on TestPinterIterfaceRollout close do (
		if thePainterInterface.InPaintMode() then
        (
          thePainterInterface.EndPaintSession()
	    )
    )
  
    on hitType selected i do
    (
      offmeshhittype = i - 1
      if thePainterInterface.InPaintMode() then
      (
        thePainterInterface.EndPaintSession()
        paint3D.checked = false
      )
    )
  
    on pickMesh picked obj do
    (
      if obj != undefined do
      (
        theObj = Obj
      ) 
    ) 
  
    on offMeshHitZDepth changed val do
    (
      if thePainterInterface.InPaintMode() then
      (
        thePainterInterface.EndPaintSession()
        paint3D.checked = false
      )
      thePainterInterface.offMeshHitZDepth = offMeshHitZDepth.value
    )
  
    on pickLocator picked obj do
    (
      if obj != undefined do
      (
        thePainterInterface.EndPaintSession()
        paint3D.checked = false
        offMeshHitLocator = Obj
        thePainterInterface.offMeshHitPos = offMeshHitLocator.pos
      ) 
    )

    on paint3D changed state do 
    (
      if thePainterInterface.InPaintMode() or theObj == undefined  or (offmeshhittype==2 and offMeshHitLocator == undefined ) then
      (
        thePainterInterface.EndPaintSession()
        paint3D.checked = false
      )
      else
      (
        paint3D.checked = true
        thePainterInterface.initializeNodes 0 #(theObj)
        thePainterInterface.offMeshHitType = offmeshhittype
        thePainterInterface.ScriptFunctions startStroke paintStroke endStroke cancelStroke SystemEndPaintSession
        thePainterInterface.startPaintSession()
      )
    )
    on btnOptions pressed do (
      thePainterInterface.paintOptions() 
    )
  )
  createDialog TestPinterIterfaceRollout 
)

続きはまた来週。

maxまとめページ



take_z_ultima at 11:30|この記事のURLComments(0)TrackBack(0)3ds Max | CG

2017年01月26日

modo10のスクリプトについて調べてみた その51

前回に引き続き「TD SDK」の「MeshGeometry」と関連クラスについて調べてみたい。

今回はUVマップについて調べてみたい。UVマップは「UVMap」クラスで扱えるようになっている。

メッシュオブジェクトのUVマップはメッシュオブジェクトの持つ「MeshGeometry」の「MeshMaps」オブジェクト「vmaps」プロパティのuvMapsプロパティにUVマップのコレクションとして入っている。下のプログラムはその0番目のUVマップを変数「texture」に取り出すものだ。

import modo
mesh=modo.Mesh('Mesh')
geo=mesh.geometry
texture=geo.vmaps.uvMaps[0]

新規にUVマップを追加するのは「addUVMap()」メソッドを使う。

method of modo.meshgeometry.MeshMaps
 
 addUVMap(self, name='UVMap')

UVマップの値は連続と非連続があって、データの形が異なる。例えば下のメッシュで、

fig01

UVマップが下のようになっている場合、メッシュ形状ではポリゴンに切れ目が無いけど、UVマップは平面に開くためにどこかに切れ目が入る。この場合切れ目が入ったエッジの頂点は3Dメッシュ上では1つでもUVマップ上では2箇所に存在することになる。UVマップの値は頂点マップなので1つの頂点に対して複数のUVマップ値が割り当てられることになる。

fig02

下のプログラムは上の画像の連続ポイント(22)と非連続ポイント(17)のUVマップ値を取得するものだ。

import modo
mesh = modo.Mesh('Mesh')
geo = mesh.geometry
v=geo.vertices[22]
print "--- 22 ---"
print v.getUVs()
v=geo.vertices[17]
print "--- 17 ---"
print v.getUVs()

これがその結果。連続UVの値は(U,V)の2値なのに対して非連続のUV値はポリゴンオブジェクトとUV値がセットになった値4つのタプルになっているのがわかる。

# Result:
--- 22 ---
(0.375, 0.5)
--- 17 ---
((modo.MeshPolygon(8, 'mesh002'), (0.625, 0.6666666865348816)), (modo.MeshPolygon(9, 'mesh002'), (0.625, 0.6666666865348816)), (modo.MeshPolygon(22, 'mesh002'), (0.5, 0.8333333730697632)), (modo.MeshPolygon(23, 'mesh002'), (0.5, 0.8333333730697632)))

「MeshVertex」クラスのオブジェクトからUV値を取得するのが「getUVs()」メソッドだ。

getUVs(self, uvmap=None)

以下がその定義で、引数「uvmap」を省力した場合、インデックス0番のUVマップが使われる事がわかる。

    def getUVs(self, uvmap=None):
        if uvmap is None and self._geometry.vmaps.uvMaps:
            uvmap = self._geometry.vmaps.uvMaps[0]

        if uvmap:
            return uvmap[self.index]
        return None

他のUVマップの値を調べたいなら上のプログラムに従って、「uvMaps」から必要なUVマップのオブジェクトを取得して「getUVs()」に渡してやればいい。

import modo
mesh = modo.Mesh('Mesh')
geo = mesh.geometry
uvm = geo.vmaps.uvMaps[1]
v=geo.vertices[22]
print v.getUVs(uvm)

以上のように連続でも非連続でもUV値は「getUVs()」で取得出来るけど、設定の方はそうもいかないようだ。

頂点にUV値をセットするのは「setUVs()」メソッドを使う。

setUVs(self, values, uvmap=None)

例えば非連続のUVマップ値を持つ17番の頂点の値を「getUVs()」で取得して、そのまま「setUVs()」でセットしようとしてもエラーになる。

import modo
mesh = modo.Mesh('Mesh')
geo = mesh.geometry
v=geo.vertices[22]
uv = v.getUVs()
v.setUVs(uv)
v=geo.vertices[17]
uv = v.getUVs()
v.setUVs(uv)

連続UVの22番のUV値はそのままセットできるけど、17番の非連続のUV値をセットすると下のようにエラーが出る。受け付けるのは連続UVマップの値だけのようだ。

_setValue
    raise ValueError("Value is not a UV pair")
ValueError: Value is not a UV pair

非連続UVについては「MeshPolygon」クラスの「setUV()」メソッドを使う。

setUV(self, values, vertex, uvmap=None)
    Set a UV value pair for a vertex specific to this polygon.
    Splitting UVs off their surrounding connections can be done this way.
     
    :param tuple values: A tuple containing the two uv floats to be set
    :vertex int or MeshVertex: Vertex to write the uv value pair for. Can be a vertex index or a MeshVertex object.
    :param UVMap uvmap: The UVMap to write the value to. Will look for the first found UV map if None

例えば「Mesh」アイテムのポリゴンと頂点のインデックスが以下のようになっている時に、

fig03

以下のプログラムを実行すると、

import modo
mesh = modo.Mesh('Mesh')
geo = mesh.geometry
v=geo.vertices[22]
p=geo.polygons[12]
p.setUV((0.6,0.7),v)
geo.setMeshEdits()

このように不連続UVを作成できる。 修正後に「setMeshEdit()」を実行して表示を更新するのを忘れずに。

fig04

「setUV()」の「vertex」パラメータは上のプログラムのように「MeshVertex」オブジェクト以外に「int」でもOKと書いてあるので、頂点のインデックス番号22で試してみたらうまくいかなかった。この番号はポリゴン内のローカルな頂点インデックス番号のことらしい。下のプログラムは12番のポリゴンの「vertices」配列に入っている頂点を全て表示するものだ。これを見るとインデックス番号22の頂点は2番のローカルインデックスになっているのがわかる。

import modo
mesh = modo.Mesh('Mesh')
geo = mesh.geometry
p=geo.polygons[12]
for i,v in enumerate(p.vertices):
	print i,v

# Result: 
0 modo.MeshVertex(6, 'mesh002')
1 modo.MeshVertex(20, 'mesh002')
2 modo.MeshVertex(22, 'mesh002')
3 modo.MeshVertex(18, 'mesh002')

以下のようにして実行してみたら確かに22番の頂点のUVマップが変更された。

import modo
mesh = modo.Mesh('Mesh')
geo = mesh.geometry
p=geo.polygons[12]
p.setUV((0.7,0.8),2)
geo.setMeshEdits()
fig05

それではまた次回。

modo10ブログ目次



take_z_ultima at 11:30|この記事のURLComments(0)TrackBack(0)modo | CG

2017年01月25日

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

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

今回は「getHitFaceData()」メソッドについて調べてみたい。

<void>thePainterInterface.getHitFaceData <&point3>bary <&integer>faceIndex <node>node <integer>tabIndex 

このメソッドも前回調べた「getHitPointData()」メソッド同様に「tabIndex」でストローク中の指定した番号のヒットポイントデータを取得するためのものだ。最大の違いは「getHitPointData()」メソッドがワールドまたはローカルの直交座標系での出力だったのに対して、「getHitFaceData()」メソッドはヒットポイントを含むポリゴンと、ポリゴン上での重心座標系での座標値を出力するところにある。

重心座標系は三角形の各頂点の位置ベクトルを合成して三角形内の位置を表すもので、下のベクトル式で表される。3つの座標値の合計が1であれば点Pは三角形を含む平面上に来る。

fig01

この座標系を使うメリットは、なんと言ってもUVマップとの対応だ。3D上の三角ポリゴンとそれに対応するUVマップ上の三角ポリゴンで、対応する点の位置を同じ座標値であらわす事が出来る。そして点Pを求める式も変らない。異なるのは三角ポリゴンの三頂点の位置ベクトルがXYZの座標系からUVの座標系になる事だ。

「getHitFaceData()」メソッドで指定ノード「node」のヒットポイントのポリゴンインデックス「faceIndex」とヒットポイントの重心座標値「bary」が取得できる。

そこからこのメッシュアイテム上のヒットポイントに対応するUVマップ上のポイントを求めるには、まずオブジェクトのノード「node」からメッシュデータ「theMesh」を取得する。

mesh = node.mesh

次に「meshop.getMapFace()」で、上で取得したメッシュデータ「mesh」とUVマップのマップチャンネル「mapChannel」、ヒットポイントを含むポリゴンの番号「faceIndex」から、UVマップ上の三角ポリゴンの3つの頂点の頂点番号を<point3>値として取得する。

mapFace = meshop.getMapFace mesh mapChannel faceIndex

これで各頂点の番号は「x」「y」「z」プロパティとして参照できるようになる。

この頂点番号「mapFace」と、メッシュデータ「mesh」、UVマップのチャンネル番号から「meshop.getMapVert」で3頂点のUV座標値が取得できる。

mapV1 = meshop.getMapVert mesh mapChannel mapFace.x
mapV2 = meshop.getMapVert mesh mapChannel mapFace.y
mapV3 = meshop.getMapVert mesh mapChannel mapFace.z

ここで得られたUVマップ上の3頂点の座標値に重心座標値「bary」をかけてやればUVマップ上のヒットポイントが得られる。

mapPoint = bary.x * mapV1 + bary.y * mapV2 + bary.z * mapV3

このポイントを使ってテクスチャにペイントすれば、メッシュペイントが出来るってわけだ。

続きはまた次回。

maxまとめページ



take_z_ultima at 11:30|この記事のURLComments(0)TrackBack(0)
Archives