Procedural Tree


  //Scatter on branch
int seed = chi("../info/seed")+7854;
int steps = chi("steps");
int branches_per_step = chi("branches_per_step");
float min_u = ch("min_u");
float max_u = ch("max_u");
float random_offset = ch("random_offset");
float skip_chance = ch("skip_chance");

int current_pt;
vector current_pos;
float current_grad, current_width;
vector current_side, current_up, current_forward;

int branches = steps * branches_per_step;

float step =(max_u - min_u)/steps;
float current_step = min_u + step/2;

for(int i =0; i < branches; i++){
    if(i!= 0 && i%branches_per_step == 0)
        current_step += step;
    if(rand(@primnum+i+212121+seed) < skip_chance)
        continue;
        
    float u = current_step + fit01(rand(@primnum+i+seed+21321),-random_offset,random_offset);
    
    prim_attribute(@OpInput1,current_pos,"P",@primnum,u,0.0);
    prim_attribute(@OpInput1,current_grad,"grad",@primnum,u,0.0);
    prim_attribute(@OpInput1,current_width,"width",@primnum,u,0.0);
    prim_attribute(@OpInput1,current_side,"side",@primnum,u,0.0);
    prim_attribute(@OpInput1,current_up,"up",@primnum,u,0.0);
    prim_attribute(@OpInput1,current_forward,"forward",@primnum,u,0.0);
    
    current_pt = addpoint(geoself(),current_pos);
    setpointattrib(geoself(),"grad",current_pt,current_grad);
    setpointattrib(geoself(),"width",current_pt,current_width);
    setpointattrib(geoself(),"side",current_pt,current_side);
    setpointattrib(geoself(),"up",current_pt,current_up);
    setpointattrib(geoself(),"forward",current_pt,current_forward);
}

  //Randomize Direction
int seed = chi("../info/seed")+928781;
float angle = radians(ch("angle"));
float rand_angle = radians(ch("rand_angle"));

int level = chi("../info/i");
string path = sprintf("../angle_ramp%d",level);
float ramp = chramp(path,f@grad);

float phi = fit01(random(@ptnum+seed+272112),0,2*$PI);
float a = angle + fit01(rand(@ptnum+seed+238129),-rand_angle,rand_angle);
float theta = ramp*a;

v@N = set(cos(phi)*cos(theta),sin(theta),sin(phi)*cos(theta)); 

  //Gravity
vector dir = chv("direction");
float mag = length(dir);
dir = normalize(dir);

int prim = pointprims(@OpInput1,@ptnum)[0];
vector base = prim(@OpInput1,"base_pos",prim);
vector delta = @P - base;
float delta_length = length(delta);
float dist2 = length2(delta-dir*dot(delta,dir));
vector new_pos = @P+0.025*dist2*mag*dir;
vector new_delta = normalize(new_pos - base);
new_pos = base + new_delta * delta_length;
@P = new_pos;