最近案子遇到要將max的建築物在houdini碎完做好動態再輸出回去,整個流程有幾個需要注意的點是:
- 建築物本身自帶多種材質,也就是在max裡有上多個material ID
- 物件只有進行碎裂跟位移,面數、頂點數跟其他屬性都是固定無動態基於第一點,要在max->houdini->max的流程下保持材質,FBX可以說是最方便的格式之一,連材質名稱都可以保留(對應primitive的shop_materialpath),要對回去很方便。
而第二點可以判定說,我們只要一個有完整資訊的物件,再讓houdini輸出point cache去移動頂點可以做到最有效率跟節省空間的方法。
houdini在原先選單輸出帶point cache的FBX會有許多問題,normal有時會跑掉,而且point cache的容量跟輸出速度都異常的大跟久,甚至在max匯入會有後續影格讀不到的問題,完全沒有point cache該有的優勢。
後來解決的方法是利用原先FBX輸出單一無動態物件,再另外以script輸出給max吃純帶位置資訊的point cache,PC2檔案。
本來還想說研究PC2的格式自己去寫,沒想到已經有大神研究好了,如果有興趣可以參閱這篇文章。
在這邊直接引用 glassman3d 大的script:
import sys import struct def doCache(): sf = hou.evalParm("startframe") ef = hou.evalParm("endframe") sr = 1 ns = (ef - sf) + 1 geo = hou.pwd().geometry() points = geo.points() np = len(points) pc2File = open(hou.evalParm("file"), "wb") with hou.InterruptableOperation("PC2 Cache",open_interrupt_dialog=True) as operation: with hou.InterruptableOperation("Exporting %s" % hou.pwd().name(),open_interrupt_dialog=True) as export: # Write header headerFormat='<12siiffi' #headerStr = struct.pack(headerFormat, 'P','O','I','N','T','C','A','C','H','E','2','\0', 1, np, sf, sr, ns) headerStr = struct.pack(headerFormat, "POINTCACHE2\0", 1, np, sf, sr, ns) pc2File.write(headerStr) for f in range(sf, sf+ns, sr): hou.setFrame(f) pos = geo.pointFloatAttribValuesAsString("P") pc2File.write(pos) export.updateProgress( f/ns ) operation.updateLongProgress(0.5 * (f/ns) ) with hou.InterruptableOperation("Finishing",open_interrupt_dialog=True) as finish: pc2File.flush() pc2File.close() finish.updateProgress(1) operation.updateLongProgress(1)