スクリプト SimpleObject プラグイン

SimpleObject は、ボックス、球、円錐などのトライメッシュによって定義されたジオメトリ プリミティブの一種です。つまり、simpleObject プラグインは、3ds Max のすべての標準および拡張プリミティブに類似しています。

SimpleObject プラグインのスクリプトでは、このメッシュを構築するためのハンドラを指定する必要があり、3ds Max によってシーンの表示、ヒット テスト、レイの交差、レンダリング、モディファイヤの適用性などが自動的に処理されます。

スクリプト SimpleObject プラグインを宣言するには、<superclass> simpleObject として指定します。

スクリプト SimpleObject プラグインには create ツールが必要です。

シーン ノードの作成やモディファイヤ スタックの構築などのシーン関連のアクションを、SimpleObject プラグインによって実行しないでください。このプラグインではマウス ツール ハンドラにおけるパラメータの調節および buildMesh ハンドラにおけるメッシュの構築だけを行います。SimpleObject プラグインでシーン ノードを作成しようとしたりモディファイヤを適用したりすると、進行中のシーン ノード作成ですべての種類の未知の相互作用が発生します。

SimpleObject プラグインには、定義済みのローカル変数 mesh があります。この変数には、作成されたオブジェクトの元になるメッシュが含まれています。 mesh ローカル変数はどのプラグイン ハンドラでもアクセス可能ですが、一般に buildMesh ハンドラ内にだけ構築されます。TriMesh メソッドを使って、既存の TriMesh 値を適切に修正するか、または新しい TriMesh 値を作成し、それを mesh プラグイン ローカル変数に代入できます。TriMesh メソッドとプロパティについては、「Editable_Mesh: GeometryClass および TriMesh: Value」を参照してください。

スクリプト:

plugin simpleObject tower_plugin_def
name:"Tower"
classID:#(145345,543211)
category:"Scripted Primitives"
(
  parameters main rollout:params
  (
    height type:#worldUnits ui:height default:0
    width type:#worldUnits ui:width default:0
    depth type:#worldUnits ui:depth default:0
  )
  rollout params "Two Faces Parameters"
  (
    spinner height "Height" type:#worldunits range:[-1000,1000,0]
    spinner width "Width" type:#worldunits range:[-1000,1000,0]
    spinner depth "Depth" type:#worldunits range:[-1000,1000,0]
  )
  on buildMesh do
  (
    setMesh mesh \
    verts:#([0,0,0],[width,0,0],[width,depth,0],[0,depth,0]) \
    faces:#([3,2,1], [1,4,3])
    extrudeFace mesh #(1,2) (height * 0.5) 40 dir:#common
    extrudeFace mesh #(1,2) (height * 0.5) 50 dir:#common
  )
  tool create
  (
    on mousePoint click do
      case click of
      (
        1: nodeTM.translation = gridPoint
        3: #stop
       )
    on mouseMove click do
      case click of
      (
        2: (width = gridDist.x; depth = gridDist.y)
        3: height = gridDist.z
      )
  )
)

このスクリプトでは、Tower という新しいプリミティブが定義されています。これにより、ごく簡単なタワー フォームが作成されます。最初のドラッグでベースが設定され、次のドラッグで高さが設定されます。これには、3 つのアニメート可能なロールアウト パラメータ height width 、および depth が含まれており、オブジェクトの基本的な範囲が設定されます。ここでのキー コンポーネントは create ツールと on buildMesh ハンドラで、これらは一緒に単純な動作をします。 create ツールによってパラメータの値が設定され、 on buildMesh ハンドラによってこのパラメータ値に基づいたメッシュが構築されます。

create ツールでは、定義済みマウス ツールのローカル変数 nodeTM 内の Matrix3 値を使って、新しいオブジェクトを含むように作成されるノードの位置にアクセスし、設定することもできます。この場合、ノードの TM の位置は、初めてマウスをクリックしたときのワールド位置に設定されます。 on mouseMove ハンドラでは、2 度目のクリックで幅と長さを、3 度目のクリックで高さを設定します。

on buildMesh ハンドラは、TriMesh 値の任意のメッシュを、定義済みプラグインのローカル変数 mesh に作成します。通常は、ハンドラが呼び出されるたびにメッシュをゼロから作成します。上記の例では、メッシュは初め単純な 2 面矩形の平面に( setMesh() を使用して)設定され、次に 2 面が上に押し出されて、2 回スケールダウンし単純なタワーになります。

mesh プラグイン ローカル変数はどのプラグイン ハンドラでもアクセス可能ですが、一般に on buildMesh ハンドラ内にだけ構築されます。TriMesh メソッドを使って、既存の TriMesh 値を適切に修正するか、または新しい TriMesh 値を作成し、それを mesh プラグイン ローカル変数に代入できます。作成した TriMesh は有効でなければなりません。無効な場合は 3ds Max がクラッシュすることがあります。割り当てられたすべての面、頂点、マテリアル ID、およびテクスチャ頂点配列は、ハンドラで入力される必要があります。

スクリプト化された SimpleObject に実装できる追加イベント ハンドラには、以下の 3 つがあります。

on OKtoDisplay do <boolean_expr>

OKtoDisplay イベント ハンドラが実装されている場合、 <boolean_expr> は、現在のメッシュを表示してもよいかどうかによって true または false を返します。これは、メッシュが特定のパラメータ設定で縮退状態にあり、ビューポートに表示されてない場合に使用すると便利です。既定値は true です。空のメッシュを表示してもよいことに注意してください。

on hasUVW do <boolean_expr>

hasUVW イベント ハンドラが実装されている場合、 <boolean_expr> は、UVW 座標がメッシュに表示されるかどうかによって true または false を返す必要があります。プリミティブ オブジェクトの多くには、ユーザが UVW 座標の生成をコントロールするための[マッピング座標を生成](Generate Mapping Coords)チェックボックスが備わっています。 hasUVW ハンドラ式によって、このチェックボックスの状態が返されます。既定の実装では、メッシュにテクスチャ頂点があるかどうかによって、 true または false が返されます。現在のところ、1 つのマップ チャネルのみがサポートされています。

on setGenUVW <onOff> do <expr>

setGenUVW イベント ハンドラは、3ds Max がプラグインで自動的にマッピング座標を生成するときに呼び出されます。この状況は、マッピング座標ではなくマテリアルを適用したオブジェクトを最初にレンダリングする場合に発生します。これは、スイッチ引数 <onOff> とともに呼び出され、このスイッチ引数が true または false になることによって、マッピング座標がオンまたはオフになります。使用するプラグインによってマッピング座標が管理されている場合は、このハンドラを実装し、 true 引数で呼び出してマッピング座標を作成する必要があります。

例:

plugin simpleObject TexturePlane
name:"TexturePlane"
classID:#(0x19a75166, 0x83e3a1c7)
category:"MAXScript Examples"
(
parameters main rollout:params
(
  Size type:#worldUnits ui:size default:0
  genMapCoords type:#boolean ui:gen_Map_Coords default:false animatable:false
  u_tile type:#float default:1.0 ui:u_step
  v_tile type:#float default:1.0 ui:v_step
)
rollout params "TexturePlane"
(
  group "Geometry"
  (
    spinner size "Size:" type:#worldunits range:[0,1000,1]
  )
  group "Mapping"
  (
    spinner u_step "U Tiling" scale:0.01
    spinner v_step "V Tiling" scale:0.01
    checkbox gen_Map_Coords "Generate Mapping Coords."
  )
) --end roll

--When Max wants to know whether the object has UV coords,
--return the value stored in genMapCoords to inform it of
--the current UV sate of the plug-in.

on hasUVW do genMapCoords 

--When 3ds Max tells the plug-in to turn on UV coordinates 
--(for example when applying a texture 
--with "Show Map In Viewport" checked), 
--this handler will automagically check the checkbutton 
--connected to our parameter called genMapCoords. 
--Also, when the user changes the checkbox, 
--the variable will tell the builMesh to generate coordinates. 
--Note that the handler will override the manual settings, 
--for example if a texture has "Show Map In Viewport" enabled, 
--you cannot actually uncheck the "Generate Mapping Coords." 
--checkbox with the mouse! 
					 
on setGenUVW bool do genMapCoords = bool 

on buildMesh do ( 
  --Generate a simple Quad 
  local vertex_array = #() 
  append vertex_array [-size/2,-size/2,0] 
  append vertex_array [size/2,-size/2,0] 
  append vertex_array [size/2,size/2,0] 
  append vertex_array [-size/2,size/2,0] 
  face_array = #( [1,2,3], [1,3,4] ) 
  setMesh mesh verts:vertex_array faces:face_array 
  --If the checkbox was enabled and we want 
  --coordinates to be generated... 
					 
  if genMapCoords then ( --define the texture vertices 
    local uvw_array = #() append uvw_array [0.0,0.0,0.0] append uvw_array [u_tile ,0.0,0.0] append uvw_array [u_tile ,v_tile ,0.0] append uvw_array [0.0,v_tile ,0.0] 
    --set the number of vertices 
    setNumTVerts mesh uvw_array.count 
    --set all vertices 
    for v = 1 to uvw_array.count do setTVert mesh v uvw_array[v] 
    --build texture faces 
    buildTVFaces mesh false 
    --set all texture faces (in this case using the mesh faces 
    --since we happen to have a one-to-one correspondence 
    --between vertices and texture vertices.) 
    --This is not always the case though... 
    for f = 1 to face_array.count do setTVFace mesh f face_array[f] ) 
)--end on buildMesh 
tool create 
( 
  on mousePoint click do 
  case click of 
  ( 
    1: ( nodeTM.translation = gridPoint ) 
    2: ( #stop) 
  ) 
  on mouseMove click do 
  case click of 
  ( 
    2: (Size= abs gridDist.x) 
  ) 
  ) 
)--end plugin 

ここでは、まず別のテンポラリのオブジェクトを作成し、メッシュのブール値を使って最終的なメッシュを作成するもう 1 つの例を示します。

スクリプト:

plugin simpleObject squareTube
name:"SquareTube"
classID:#(63445,55332)
category:"Scripted Primitives"
(
local box1, box2
parameters main rollout:params
(
  length type:#worldUnits ui:length default:1E-3
  width type:#worldUnits ui:width default:1E-3
  height type:#worldUnits ui:height default:1E-3
)
rollout params "SquareTube"
(
  spinner height "Height" type:#worldUnits range:[1E-3,1E9,1E-3]
  spinner width "Width" type:#worldUnits range:[1E-3,1E9,1E-3]
  spinner length "Length" type:#worldUnits range:[-1E9,1E9,1E-3]
)
on buildMesh do
(
  if box1 == undefined do
    (box1 = createInstance box; box2 = createInstance box)
  box1.height = height; box2.height = height
  box1.width = width; box2.width = width * 2
  box1.length = length; box2.length = length * 2
  mesh = box2.mesh - box1.mesh
)
tool create
(
  on mousePoint click do
    case click of
    (
      1: nodeTM.translation = gridPoint
      3: #stop
    )
  on mouseMove click do
    case click of
    (
      2: (width = abs gridDist.x; length = abs gridDist.y)
      3: height = gridDist.z
    )
  )
)

この例で、パラメータとロールアウトは最初の例と同じように処理されていますが、 buildMesh ハンドラはメッシュを間接的な方法で生成します。最終的なオブジェクトは、矩形パイプのフォームで、中心に穴の空いたボックスで表します。2 つのプラグイン ローカル( box1 および box2 )には、プラグイン パラメータに従ってサイズ パラメータが設定される Box 基本オブジェクトが入っています( box2 は外側のボックスで、 box1 は穴です)。最後のメッシュは、 box1 box2 からの論理減算によって作成されます。この場合、独立した新しいメッシュが作成され、 mesh プラグイン ローカル変数に代入されます。これは、オブジェクトの元のメッシュを直接修正した最初の例とは対照的です。どちらの方法でもかまいません。

createInstance() メソッドは、Box 基本オブジェクトを直接作成するために使用します。このメソッドは、指定されたオブジェクトに関連するジオメトリを作成しますが、ノードは作成しません。シーン ノードの作成やモディファイヤ スタックの作成などのシーンに関連するアクションは、SimpleObject プラグインで実行できないため、このメソッドを使用します。

関連事項