Procedural Castle HDA

This project is to realize a HDA that can procedurally generate castles with different appearances in batches, and at the same time, based on the random point information set by the user, the castles can be generated in batches on the point cloud

Control Pannel

All of the control parameter are placed at NULL OBJECT which is named CONTROL PANNEL.

Global Control

Z direction length - control the whole model’s size in Z direction

X direction length - control the whole model’s size in X direction

 

Stone Base Control

Height - control the height of the stone base

Pillar -

Pillar num - control the amount of pillars in each direction

Y Axis Position - control the height of the pillars’ position relative to the stone base

Offset -control how long the pillars are

Stone -

Stone Separation - control the separation of the stone generating point,higher amount will getsmaller stone

 

Stone Shrink - Control how wide is the gap between the stones

 

Do Geo Level Noise - Check the toggle will remesh the stone and add point noise to the stone surface (WARNING - This feature requires higher computer performance and longer computing time)

Remesh size - Control the precision of the remesh result, lower amount will get more subdivision mesh

 

First Level Noise - Control the Noise parameter of the Surface displacement, in default it’s a lower frequency noise to get the basic surface shape

 

Second Level Noise - Control the Noise parameter of the surface displacement, in default it’s a higher frequency noise to get further detail  

 

Third Level Noise - Control the Noise parameter of the erosion displacement, it’s a different type noise compared to the First and Second Level noise, this fuction need Extremely high amount of mesh point.

Wooden Platform Control

Platform Size Multiply -Control the relative size multiple to the stone base

 

Platform Ground - 

Board Length - Control the the length of each board that makes up the platform

 

Board Width - Control the the width of each board that makes up the platform

 

Shrink Offset - Control how wide is the gap between the boards

Platform steps -

Steps Amount - Control the number of upper steps, The lower steps will be automatically adjusted according to the number of upper steps

 

Steps Height - Control the height of each steps

 

Steps Width - Control the width of each steps

 

Steps Overlap - Control the width of the overlap between each step

Fence -

Open Width - The width of the fence opening at the entrance and the length of the upper step will also be automatically adjusted according to the opening width

Main Building - 

First Floor - 

Beam Offset Mutiply - This parameter will multiply the offset value calculated by the subsequent ramp

 

Beam Offset -This ramp visually controls the curve trend of the beam as shown in the red dot

eaves Offset Mutiply - This parameter will multiply the offset value calculated by the subsequent ramp

eaves Offset - This ramp visually controls the downward offset of the curve of the beam as shown in the red dot

Second Floor - Same parameters as the First Floor, but it control the second floor roof

 

Third Floor - Same parameters as the First Floor, but it control the second floor roof

Groud Floor attic -

Roof up mutiply - This parameter will multiply the offset value calculated by the subsequent ramp

Roof up offset - This ramp visually controls the upward offset of the curve of the beam as shown in the red dot

Top Floor attic - Same parameter as Ground floor attic

First of all, a basic geometry is the beginning of everything. Then using the point from volume node to create points with equal distance in each layer. Later, these points will be used to make stone bricks of similar specifications

Technical Breakdown

01 | Build A Stone Base

By connecting the generated points with the basic geometry to the Voronoi fracture node, we can get regular shaped bricks. In order to improve the shape of the stone brick, we need to make it random. Therefore, getting the foundation of the stone brick by using point jitter to make the distance between each point and the surrounding point change

In order to make the stone wear in the corner, we use the poly bevel node to bevel at the point class. At the same time, in order to ensure the randomness of the edge level, we use the point wrangle node to generate random values for each point according to the @ ptnum attribute in advance

In addition, in order to make the brick have more details, and make the brick shape can be better controlled, the project remesh the brick, so that we can get a more average mesh. Then point VOP node is applied to the subdivided grid, and the displacement effect based on location information is created in VOP.

There are three layers of such nodes. The first two layers are low-frequency and high noise. These two layers create the appearance of stone texture, and the third layer adds additional ramp to make the VOP produce the effect similar to erosion.

02 | Build A Adaptive Platform

Same start as 01, the project need a grid as a basic geometry so we can get the size from the grid later.

By reading the data of the four points in the grid, according to the set length and width of the board, we can generate a point from 0, each time the length distance, and copy the generated point down according to the odd and even number sequence


vector pt0 = point(1,"P",0);
vector pt1 = point(1,"P",1);
vector pt2 = point(1,"P",2);
vector pt3 = point(1,"P",3);
float width_x = ch("length");
float width_z = ch("width");

float x_dist = pt1.x - pt0.x;
float z_dist = pt2.z - pt0.z;
float num_x = floor(x_dist/width_x)+1;
float num_z = floor(z_dist/width_z)+1;

for(int k = 0; k<=num_z; k++ ){
    if(k%2 == 0){
        for(int i = 0; i<=num_x; i++){
            vector pt = set(pt0.x+i*width_x,pt0.y,pt0.z+k*width_z+0.5*width_z);
            addpoint(0,pt);
             }
         }
    else{
         for(int i = 0; i<=num_x+1; i++){
            vector pt = set(pt0.x+i*width_x-ch("offset"),pt0.y,pt0.z+k*width_z+0.5*width_z);
            addpoint(0,pt);
            }
         }
}

After the dot matrix is generated, the project reads the length and width of the board from the channel in vex, applies the data to the size of the box, and finally copies the box to the point

In order to make the final shape consistent with the initial basic geometry, four clip nodes are used to cut the platform geometry, and poly fil node is used to repair the gap

After getting the floor of the platform, the next step of the project is to generate the points needed to copy the fence. The project uses the basic geo grid and carve node to transform primitive into polyline. At the same time, according to the U of polyline in the positive direction of x-axis, the gap of line segment is generated. But at this time, the two points of the gap are coincident.

In order to get the vacancy at the entrance, we need to offset the z-axis of the two points.The clamp function is used in vex to ensure that the offset of the point at the notch is limited to the grid, At the same time, the polygon is re sampled according to the polygon edge.This allows the project to get the points needed to replicate the fence

Finally, we need to make stairs that can be adjusted automatically according to the height and width of the platform.The project continue to use vex in the project, read the length of x-axis and the height of Y-axis of the grid, and combined with the set length, width and height of the step to generate the copy point of the first step.Then, according to the length, width and height of the step, the offset iteration is based on the point of the first step. Overlap fuction simply multiplies the initial calculated offset by a value, so that the offset value is less than the set width.


float ini_y = ch("../transform1/ty");
float ini_x = 0.5*ch("../grid1/sizex");
float floor_height = ch("../box1/sizey");
float hold_width = ch("../box7/sizez");

float stage_height = ch("stage_height");
float stage_length = 1.05*2*ch("../pointwrangle1/open_width");
float stage_width = ch("stage_width");
float stage_overlap = 1-ch("stage_overlap");

for(int i=0; i < ch("stage_amount");i++){
    vector ini_pos = set(ini_x+0.5*stage_width,ini_y-0.5*floor_height-0.5*stage_height,0);
    vector offset = set(i*stage_width*stage_overlap,-i*stage_height,0);
    vector pos = ini_pos+offset;
    addpoint(0,pos);
    if(i%4 == 0 && i!=0){
        vector hold = pos+set(0,0.5*stage_height,0.5*(stage_length/1.05)-0.5*hold_width);
        vector hold2 = pos+set(0,0.5*stage_height,-0.5*(stage_length/1.05)+0.5*hold_width);
        int pt = addpoint(0,hold);
        int pt2 = addpoint(0,hold2);
        setpointattrib(0,"group_hold",pt,1,"set");
        setpointattrib(0,"group_hold",pt2,1,"set");
        }
    }

float iter = ch("stage_amount")-1;
vector final_offset = set((iter+0.5)*stage_width*stage_overlap,-(iter+0.5)*stage_height,0);
vector ini_pos = set(ini_x+0.5*stage_width,ini_y-0.5*floor_height-0.5*stage_height,0);
vector pos2 = ini_pos +final_offset;
@pos_x = pos2.x;
@pos_y = pos2.y;

vector p = point(0,"P",@numpt-1);
vector p2 = point(0,"P",@numpt-2);

float max = `chs("../grid1/sizey")`;
float dist = clamp(ch("open_width"),0,0.5*max);

vector value = set(p.x,p.y,-dist);
vector value2 = set(p.x,p.y,dist);

setpointattrib(0,"P",@numpt-1,value,"set");
setpointattrib(0,"P",@numpt-2,value2,"set");

03 | Build A Ramp Control Roof

First of all, according to the direction of the roof tiles in the reference figure, a complete curved roof should be divided into four triangles. So again, the project needs to prepare a triangular foundation model.

After that, the project used more than ten grids to cut the grid on the x-axis to generate additional control points. Since Boolean shatter will generate coincident points, we need an extra fuse to make each corner point unique.

In order to obtain regular point number, sort node is used in the project, and the point number is redistributed according to the z-axis information of the point. However, because the two points formed by gird cutting are consistent in the z-axis information, we will get some random point number, which disturbs the point number rule we need

Therefore, a simple way is to rotate the grid by 0.0001 degrees, so that the z-axis information is changed, and the upper layer is full of even numbers, and the lower layer is full of odd numbers

By using this law, different curves can be formed between the upper and lower points.After that, in vex, we can substitute ptnum into ramp to calculate the offset of each point on the y-axis.

Finally, in order to obtain the copy point of tile. The project needs to retain the polyline as shown below.

The solution in the project is to group each of these points and give different group names.And use the function in add node to connect the points in the same group

So far, the project can resample the roof and copy the tiles to the point.