MCG積み上げグラフ

Max Creation Graphで積み上げグラフ(Stacked Bar Chart)の作成。

入力できるデータは5つまでのなんとも融通の利かないものになってしまっています。「Parameter: IArray<Single>」を用いて可変長の配列を入力出来ますがそれだとアニメーションができなくなってしまうので不採用。

半年ほど前に作成したので中身を今見返すとなんのこっちゃな状態。

あらかじめ用意されているオペレータノードが豊富でどれを使用するか、または希望の機能を持つノードがあるのかを把握するだけでも結構大変ですね。

パッケージしていない状態ですので改変はご自由に。Max2016 Extention2 SP3 v2 で動作確認済み。htS5BChart.zip


V-Ray Physical Camera’s Fov

Focal lengthで画角を指定したV-Ray Physical Cameraからfovを取得するテストスクリプト。

VRayCameraFOV

Mayaのカメラなら以下のようにfilmWidthとfocalLengthから計算できますが、MaxのV-Ray Cameraでは被写体までの距離が必要です。

def angleOfView(filmWidth,focalLength):
    angle = 2 * math.atan(float(filmWidth) / (2*float(focalLength)))
    angle = math.degrees(angle)
    return angle

Angle of viewの「Derivation of the angle-of-view formula」が参考になります。

import MaxPlus
import math
 
def angleOfView(filmWidth,focalLength):
    angle = 2 * math.atan(float(filmWidth) / (2*float(focalLength)))
    angle = math.degrees(angle)
    return angle
 
def angleOfViewVrayCamera(filmWidth,focalLength,distance):
	focalLengthWithMagFactor = distance * focalLength / (distance - focalLength)
	angle = angleOfView(filmWidth,focalLengthWithMagFactor)
	return angle
 
def getVRayCameraFocusDistance(node):
	objPBlock = node.Object.ParameterBlock
	distance = 0.0
	if objPBlock.targeted.Value and (not objPBlock.specify_focus.Value):
		targetNode = node.GetTarget()
		vec = targetNode.GetWorldPosition() - node.GetWorldPosition()
		distance = vec.GetLength()
	elif (not objPBlock.targeted.Value) and (not objPBlock.specify_focus.Value):
		distance = objPBlock.target_distance.Value
	elif (not objPBlock.targeted.Value) and objPBlock.specify_focus.Value:
		distance = objPBlock.focus_distance.Value
	return distance
 
def getVRayCameraFOV(node):
	objPBlock = node.Object.ParameterBlock
	fov = 0.0
	if objPBlock.specify_fov.Value == True:
		fov = objPBlock.fov.Value
	else:
		fov = angleOfViewVrayCamera(
			objPBlock.film_width.Value,
			objPBlock.focal_length.Value,
			getVRayCameraFocusDistance(node))
	return fov
	
if __name__ == '__main__':
	if MaxPlus.SelectionManager.GetCount() != 0:
		selNode = MaxPlus.SelectionManager.GetNode(0)
		if selNode.Object.GetClassName() == 'VRayPhysicalCamera':
			print getVRayCameraFOV(selNode)
		else:
			print "Selection is not V-Ray Camera."
	else:
		print "Select V-Ray Camera."

はじめてPythonAPIを使ってみました、Maxの中にPythonエディタが搭載されてるわけでは無いんですね。APIリファレンスの情報量も少ないなー。


4つトバシて、3ds Max 2012!

3ds Max Ver.9からバージョン4つとばしてver.2012です。max9を使うこと約5年、ようやく新しいバージョン使えます。

サブスクリプション契約の必要なかったやろ…4バージョンもとばしたのにたいして変わってない無いのもビックリです。使ってくうちに良くなったトコロ分かってくるんでしょうけど。

War Machine by Grant Warwick

制作用のPCには難なくインストールできましたが、問題はネットワークレンダリングまわり。

あまり参考にはならないと思いますが、お役に立てば。
続きを読む “4つトバシて、3ds Max 2012!”


MAX2AE

一段落したと思ったらすぐに次のお仕事。大忙しっ!

さて、欲しいな〜と思ったけど$250もするんですね、MAX2AE。高すぎってことで、自分で作る準備です。探せばどなたかが公開されてるんでしょうけどね。

まずは基本的なところから位置の取得、例えば15フレーム目のpoint01の位置を知りたければ、

at time 15 in coordsys world $point01.pos

これをスタートからエンドまでループさせれば、ノードのワールド座標は簡単に取得できますね。

for i=animationRange.start to (animationRange.end - animationRange.start) do (
	print ("frame " + (i as string)+ ":" + (at time i in coordsys world $point01.pos) as string)
)

カメラの書き出しですが、AfterEffectsのカメラはターゲット付きなので、maxのフリーカメラを書き出したい場合、カメラのZ方向と「ターゲットまでの距離」を使って適当なターゲット位置を計算します。

if superClassOf selection[1] == camera do
(
	case classOf selection[1] of
	(
		Freecamera:
			(
				td = selection[1].baseObject.targetDistance
				tartgetPos = [selection[1].dir.x * -1 * td + selection[1].pos.x , selection[1].dir.y* -1 * td + selection[1].pos.y, selection[1].dir.z * -1 * td + selection[1].pos.z ]
			)

		Targetcamera:
			(
				tartgetPos = selection[1].target.pos
			)
	)
)

あとはカメラのFOVやロール角を書き出せばOKかな。

ちなみに、レンズフレアエフェクト等の位置参照用に、スクリーン座標を知りたい場合は、

p = selection[1].pos * viewport.getTM()
screen_topLeft = mapScreenToView [0,0] (p.z) [RenderWidth,RenderHeight]
screen_bottomRight = mapScreenToView [RenderWidth,RenderHeight] (p.z) [RenderWidth,RenderHeight]
world_size = screen_topLeft - screen_bottomRight
x_aspect = RenderWidth/(abs world_size.x)
y_aspect = RenderHeight/(abs world_size.y)
screenPos = point2 (x_aspect*(p.x - screen_topLeft.x)) (-(y_aspect*(p.y - screen_topLeft.y)))

です。アクティブビューポートとレンダリングサイズを元にピクセルで結果(screenPos)を取得できます。