//VOP
//Wrangle
1 vector min; 2 vector max; 3 getbbox(min,max); 4 float thetamax = 4; 5 matrix3 matrix_ini = {{1,0,0},{0,1,0},{0,0,1}}; 6 float rotAngel = fit(@P.y,min.y,max.y,0,1); 7 8 rotate(matrix_ini,rotAngel*thetamax,{0,1,0}); 9 @P = @P * matrix_ini ;
//Define a label deftype , a tab Bend , deftype is a menulist
1 #pragma label deftype "Operation" 2 #pragma label offset "Offset Value" 3 #pragma group XFORM offset deftype 4 5 #pragma choice deftype “0” “Bend" 6 #pragma choice deftype "1" "Twist" 7 #pragma choice deftype "2" "Taper"
// houdinivex 中的一个小片段,比较有用,摘抄下来
//会以当前点为基准,查找最近的10个点的速度,最后更新加速度
1 float max_radius = 99999; 2 int max_neighbours = 10; 3 int handle = pcopen(@OpInput1,"P",@P,max_radius,max_neighbours+1); //因为我们查找的是第一输入端(@OpInput1),所以会把自己算进去。因此需要11个点 4 5 int near_pt; 6 int near_count = 0; 7 vector near_v; 8 vector accum_v = {0,0,0}; 9 while( pciterate(handle)) 10 { 11 pcimport(handle,"point.number",near_pt); //如果是自己,就跳过 12 if( near_pt == @ptnum ) 13 continue; 14 15 pcimport(handle,"v",near_v); 16 accum_v += near_v; 17 near_count++; 18 } 19 if(near_count != 0) 20 { 21 accum_v /= (float)near_count; 22 v@accel += (accum_v - @v) * 0.4 ; 23 }
// houdini 中使用copy节点进行模型替代粒子时,会遇到这样的问题,可以设置N为速度的方向,但是up方向不好确定(不能一直是{0,1,0}),下面是一个简单的方法
1 v@N = normalize(@v); 2 v@up = {0,1,0}; 3 v@side = normalize(cross(@N,@up)); 4 v@up = normalize(cross(@N,@side)); //side跟N是正交的,可以求出side后,利用它得到新的up
//如何求出两个向量a,b之间的夹角,并且判断b是在a的左边,还是右边,下面摘抄的代码简单的实现了这一个效果
// a = {0,1,0} b = {1,2,0} b可以随机,只要在xy平面上
1 // 返回 a b 之间的夹角, 0 到 pi 2 float angle_between(vector a; vector b) { 3 return acos(dot(normalize(a), normalize(b))); 4 } 5 // 2d xy 平面 6 // b在a左边,返回 -1 ; b在a右边,返回1。观察方向是从Z轴负方向。 7 int left_or_right(vector a; vector b) { 8 vector cp = normalize(cross(normalize(a), normalize(b))); 9 if (cp.z < 0) 10 return 1; 11 else 12 return -1; 13 } 14 vector a = point(0, "P", 1) - point(0, "P", 0); 15 vector b = point(1, "P", 1) - point(1, "P", 0); 16 float ang = angle_between(a, b); 17 int d = left_or_right(a, b); 18 if (d == -1) { 19 printf("direction: left\n"); 20 printf("degrees : %d\n", degrees(ang)); 21 }else { 22 printf("direction: right\n"); 23 printf("degrees: %d\n", degrees(ang)); 24 }
// 学习VEX时整理的一个snippet, 代码实现了Noise的全部功能
1 float turb_noise(vector sample_point; //采样点 2 vector frequency; // 频率 3 vector offset; // 偏移 4 float roughness; // 当前这一层noise的值的倍数,用于加到累积和中。 5 float lacunarity; // 每加一层noise,在计算下一层noise时会把频率乘lacunarity 6 int octaves; // 多少层noise 7 float exponent) // 倍增,可以平滑曲线(把直线平滑成曲线) 8 { 9 float sum = 0; 10 float weight = 1.0; 11 vector samp_p = sample_point * frequency + offset; 12 13 for(int i = 0; i<octaves+1; i++) 14 { 15 sum += pow(noise(samp_p),exponent) * weight *4; 16 samp_p *= lacunarity; 17 weight *= roughness; 18 } 19 return sum; 20 } 21 vector frequency = chv("frequence"); 22 vector offset = chv("offset"); 23 float roughness = chf("roughness"); 24 float lacunarity= chf("lacunarity"); 25 int octaves = chi("octaves"); 26 float exponent = chf("exponent"); 27 float scale = chf("scale"); 28 float value = turb_noise(@P,frequency,offset,roughness,lacunarity,octaves,exponent); 29 @P.y += value;
在Houdini中得到的效果如下:
在vex中没有函数pointgroupmask,注:某一个指定组时可用inpointgroup,这里讨论的是多个组。可以在wrangle中新建一个string 类型,利用表达式函数pointgroupmask函数表达式选出组,wrangle中代码如下:
1 int result = 0; 2 string chosengroups[] = split( chs("maskparm") ); 3 foreach(string group;chosengroups) 4 { 5 result = inpointgroup(0,group,@ptnum); 6 }