4变形物体_Houdini基础(二)曲线变形物体
設想:
先從二維上來看直角坐標系。物體是由x,y兩個軸向的數據組成的。少了其中一組數據物體就只能是分布在單一軸向上的點。
單獨保留物體x、y情況下的點分布情況現在將x、y加起來,可見在三維空間中形成了一個平面。
僅有x、y坐標的物體從目前的情況上來看我們已經知道了后續再添加上z軸信息的物體情況。
因為坐標系是三個完全交叉相互垂直的平面,所以當只有兩個軸向信息時物體只能組成一個平面。當我們添加第三個軸向時,物體開始突破平面變成三維物體。
物體從二維變為三維以上,我們還原了物體的三維構建。
由此可以得到,三維物體組成的公式為:
P = ( P.x , 0, 0)+ ( 0, P.y, 0) + ( 0, 0, P.z);
在最后的動圖中我們可以看到,物體加上z軸的向量的時候時筆直的朝著Z軸方向進行增加。
前面講述過三個軸是相互垂直的,現在P.z上面儲存的值是小數,且位于向量第三個位置,所以相對于是加上了(0,0,z),物體不會在x、y上面出現變化。
這就是這篇文章的重點,既然因為坐標系是直角,所以還原物體數據時只會相互垂直的相加形成,那我們把第三個軸向變形擾亂會怎樣呢?物體是否就會因此而變形?
一、重映射曲線位置到模型。
想單獨給物體的z軸添加信息首先需要保存一個物體的bound box局部的相對位置關系來記錄物體的點排布順序。
計算出物體的0到1的bound boxvector max, min; getbbox(min, max);vector transZero = {0,0,0} - min; vector localP = @P + transZero; //Translate Object to coordinate origin.vector boundSize = max - min; vector bbox = localP / boundSize;@Cd = bbox; v@bbox = bbox;曲線是有uv的,曲線上uv一般為(u,0.5),v向是沒有數值的,這個u值記錄了類似物體boundbox一樣的0-1參數。
曲線的uv參數可視化使用Geo的boundBox.z的0-1去匹配上曲線uv.u的0-1得到新的物體Z軸向量。
獲取曲線pos代替原有z軸位置操作效果vector newP = @P; newP.z = 0;vector curvePos=primuv(1,"P",0,v@bbox.z);@P = newP.xyz + curvePos.xyz;二、效果修正
上述基本上已經完成了曲線變形的制作思路,但是還會涉及比較具體的一些問題沒有講到:
1.物體沒有匹配到曲線上。
2.物體沒有讀取變形的旋轉信息值讀取了Position,沒有rotate矩陣。
3.物體變形拉伸。
4.物體位移。
1.物體現在離曲線有一定的差距
因為不光在z軸加了curvePos,在xy軸也加上了curvePos,物體變形后的位置是本身對于original的位置再機上curvePos對于original的位置。
現物體變形pos的組成解決方法很簡單,把物體歸零就好,然后物體的朝向一直設定為旋轉到z軸(自己想想怎么做)。
物體回歸坐標原點2.曲線的旋轉信息
在編輯曲線使其彎曲后,發現物體對于彎曲的曲線只是在x軸向上進行了變化,是直直的向其他方向位移過去的,并沒有彎曲變形的感覺。
比較直線和曲線效果因此需要用到上一篇文章說得那樣,給點定義一個自身的矩陣記錄旋轉信息。
這里我們用lookat函數來制作。
int npoints = primvertexcount( geoself(), int(@primnum)); vector up = normalize( chv("upVector")); matrix3 localCoor = -1;for(int i = 0; i <= int(npoints-1); i++) {if( i == int(npoints-1)){setpointattrib( geoself(), "localCoor", i, localCoor, "set");break;}localCoor = lookat( point(geoself(),"P",i+1), point(geoself(),"P",i), up); setpointattrib( geoself(), "localCoor", i, localCoor, "set"); }有相對于曲線的旋轉與沒有旋轉的對比加上了旋轉后,整個物體的變形才是正確的。
3.物體拉伸
因為直接用boundBox的0-1去適配長度不相同的曲線的uv0-1所以必然會出現拉伸。其實解決方法也很簡單,用物體變形軸(Z Axis)的長度 / 曲線長度得到他們的縮放因子,乘以 boundBox.z。
newBbox = bbox * ( boundSize.z / curveLength);
物體現在保持原有的大小變形到曲線上//---computer boundBox----- vector max, min; getbbox(min, max);vector transZero = {0,0,0} - min;vector localP = @P + transZero;vector boundSize = max - min; vector bbox = localP / boundSize;@Cd = bbox; //----deforme------- //remap bbox. float curveLength= prim( 1, "length", 0); float newBbox = bbox.z * (boundSize.z / curveLength); // computer reduction scale factor.vector newP = @P; newP.z = 0;vector curvePos = primuv( 1, "P", 0, newBbox); matrix3 rot = primuv( 1, "localCoor", 0, newBbox);@P = newP.xyz * rot + curvePos.xyz;4.物體位移
通過上面的縮放操作我們已經可以明白,想要控制物體在曲線上的縮放、位移,其實就是對于bbox值的一個重映射,縮放是*一個factor進行保持原物體0-1整個范圍值內關系的映射。位移則是+上一個數值,進行整體的位移(這些都可以也可以使用在去曲線上不同的值去進行計算)。
位移的代碼最終效果最終代碼
//---computer boundBox----- vector max, min; getbbox(min, max);vector transZero = {0,0,0} - min;vector localP = @P + transZero;vector boundSize = max - min; vector bbox = localP / boundSize;@Cd = bbox; //----deforme------- //remap bbox. float curveLength= prim( 1, "length", 0); float newBbox = bbox.z * (boundSize.z / curveLength); // computer reduction scale factor.newBbox += chf("offset");vector newP = @P; newP.z = 0;vector curvePos = primuv( 1, "P", 0, newBbox); matrix3 rot = primuv( 1, "localCoor", 0, newBbox);@P = newP.xyz * rot + curvePos.xyz;總結:
以上基本實現了這個功能,其余的拓展功能(超過曲線的部分如何保持啊,怎么每個地方旋轉不一樣啊etc....)可以自己想想如何添加,基本上就是很簡單的矩陣操作和邏輯問題。
Reference:
https://vimeo.com/247900360?vimeo.com總結
以上是生活随笔為你收集整理的4变形物体_Houdini基础(二)曲线变形物体的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java中包装类介绍
- 下一篇: web api、获取DOM元素的方式、事