Houdini VEX Note ( 一)

Houdini VEX Note ( 一)_第1张图片

//VOP

Houdini VEX Note ( 一)_第2张图片

 

//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 中利用通配符判断点在多个组内

在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 }

 

你可能感兴趣的:(Houdini VEX Note ( 一))