1 registered members (SBGuy),
712
guests, and 3
spiders. |
Key:
Admin,
Global Mod,
Mod
|
|
|
maze-like generator with auto model fitting capability
#411019
11/12/12 10:40
11/12/12 10:40
|
Joined: Mar 2012
Posts: 927 cyberspace
Wjbender
OP
User
|
OP
User
Joined: Mar 2012
Posts: 927
cyberspace
|
download here a small maze-like generator ,i will use mine to generate dungeons but with further developement .... take a look at the code to understand it ,its pretty easy and non complicated someone may find it usefull so i uploaded it .. there is a small demo wich produces some roads .. ps. models may be caves/roads/hallway sections or whatever auto model fitting capability may not be as you want it but it does have it to the degree of fitting 3 sections per cell wall
Compulsive compiler
|
|
|
Re: maze-like generator with auto model fitting capability
[Re: 3run]
#411022
11/12/12 10:56
11/12/12 10:56
|
Joined: Mar 2012
Posts: 927 cyberspace
Wjbender
OP
User
|
OP
User
Joined: Mar 2012
Posts: 927
cyberspace
|
the walls that are left over already forms a path like structure like wed paths that can be converted to paths if you like ,my main idea was to use this along with navmesh and opensteer to generate a city for a cop chase/arrest game for the serious game competision but abandoned that game idea due to time ,someone may add it if they want to though,would be cool
Compulsive compiler
|
|
|
Re: maze-like generator with auto model fitting capability
[Re: PriNova]
#411026
11/12/12 11:29
11/12/12 11:29
|
Joined: Mar 2012
Posts: 927 cyberspace
Wjbender
OP
User
|
OP
User
Joined: Mar 2012
Posts: 927
cyberspace
|
i left out the borders in this contribution for people maby wanting to capp the dead ends or link rooms up to them or perhaps link entire seperate cell grid to it(if possible) or to branch out into something else , if i closed them there would have been a border around the whole maze-like structure in the form of a square which would be kinda crappy ,its easy to scann through the cell array and find those unused areas to use for anything alse you want placed there you will see the generator has some cell finding/wall lookup functions that simplify the process... p.s I JUST SAW SOME CODE I FORGOT TO DELETE LOOK IN BUILDER.C LINES 203-207 theres som code of level load fps_min or something and max entities to be deleted...(forgot it there when i seperated into functions)
THE LINES WERE JUST DEBUG DRAWN FOR ME WHILE DEVELOPING YOU MAY REMOVE THE LOOP IN MAIN WHERE ITS DRAWN
Compulsive compiler
|
|
|
Re: maze-like generator with auto model fitting capability
[Re: sivan]
#417898
02/19/13 11:55
02/19/13 11:55
|
Joined: Mar 2012
Posts: 927 cyberspace
Wjbender
OP
User
|
OP
User
Joined: Mar 2012
Posts: 927
cyberspace
|
updated builder.c code functions to add_walls/make solvable maze
//updated file builder.c
//cell structure
//each cell has 4 walls
//each wall is divided into 3 for 3 model sections
//p.s check for doubled walls
typedef struct
{
VECTOR right_walls;//right wall start vector
VECTOR right_walle;//right wall end vector
VECTOR left_walls;//left wall start vector
VECTOR left_walle;//left wall end vector
VECTOR lower_walls;//lower wall start vector
VECTOR lower_walle;//lower wall end vector
VECTOR upper_walls;//upper wall start vector
VECTOR upper_walle;//upper wall end vector
VECTOR pos;//center of cell
int index;//cell index
}cell;
int totcells=0;//total cells
var spc=0;//space between cell centers
cell *cells;//cell array
var w;//width of grid
var h;//height of grid
/*
typedef struct
{
ENTITY* section_ent;
}section;
section* T_sections;//T shaped intersections
section* cross_sections;//+ shaped intersections;
section* corner_sections;//corner shaped intersections
section* hallway_section;//hallway sections
*/
void on_t_intersection_topleft(int cell_index,VECTOR *pos);
void on_t_intersection_bottomleft(int cell_index,VECTOR* pos);
void on_t_intersection_topleftside(int cell_index,VECTOR* pos);
void on_t_intersection_toprightside(int cell_index,VECTOR* pos);
void on_cross_intersection(int cell_index,VECTOR* pos);
void on_corner_topleft(int cell_index,VECTOR* pos);
void on_corner_topright(int cell_index,VECTOR* pos);
void on_corner_bottomleft(int cell_index,VECTOR* pos);
void on_corner_bottomright(int cell_index,VECTOR* pos);
void on_upward_straight_leftmiddle(int cell_index,VECTOR* pos);
void on_upward_straight_lefttop(int cell_index,VECTOR* pos);
void on_upward_straight_leftbottom(int cell_index,VECTOR* pos);
void on_sideways_straight_topmiddle(int cell_index,VECTOR* pos);
void on_sideways_straight_topright(int cell_index,VECTOR* pos);
void on_sideways_straight_bottomleft(int cell_index,VECTOR* pos);
////////////////////////////////////////////////////////check walls
//cur_cell has upper wall?
int has_upper_wall(int cur_cell)
{
if((cells[cur_cell].upper_walls.x!=0 && cells[cur_cell].upper_walle.x!=0)&&(cells[cur_cell].upper_walls.y!=0 && cells[cur_cell].upper_walle.y!=0))
return 1;
else return 0;
}
//cur_cell has lower wall?
int has_lower_wall(int cur_cell)
{
if((cells[cur_cell].lower_walls.x!=0 && cells[cur_cell].lower_walle.x!=0)&&(cells[cur_cell].lower_walls.y!=0 && cells[cur_cell].lower_walle.y!=0))
return 1;
else return 0;
}
//cur_cell has right wall?
int has_right_wall(int cur_cell)
{
if((cells[cur_cell].right_walls.x!=0 && cells[cur_cell].right_walle.x!=0)&&(cells[cur_cell].right_walls.y!=0 && cells[cur_cell].right_walle.y!=0))
return 1;
else return 0;
}
//cur_cell has left wall?
int has_left_wall(int cur_cell)
{
if((cells[cur_cell].left_walls.x!=0 && cells[cur_cell].left_walle.x!=0)&&(cells[cur_cell].left_walls.y!=0 && cells[cur_cell].left_walle.y!=0))
return 1;
else return 0;
}
////////////////////////////////////////////////////////neigbours
//cur_cell is on right of targetcell?
int is_on_right(int targetcell,int cur_cell)
{
if(cells[targetcell].pos.y<cells[cur_cell].pos.y)// &&(cells[targetcell].pos.x==cells[curcell].pos.x))//right of curcell
return 1;
else return 0;
}
//cur_cell is on left of targetcell?
int is_on_left(int targetcell,int cur_cell)
{
if(cells[targetcell].pos.y>cells[cur_cell].pos.y)//&& (cells[targetcell].pos.x==cells[curcell].pos.x))//left of curcell
return 1;
else return 0;
}
//cur_cell is on top of targetcell?
int is_on_top(int targetcell,int cur_cell)
{
if(cells[targetcell].pos.x>cells[cur_cell].pos.x)//&& (cells[targetcell].pos.y==cells[curcell].pos.y))//top of curcell
return 1;
else return 0;
}
//cur_cell is on bottom of targetcell?
int is_on_bottom(int targetcell,int cur_cell)
{
if(cells[targetcell].pos.x<cells[cur_cell].pos.x)//&& (cells[targetcell].pos.y==cells[curcell].pos.y))//bottom of curcell
return 1;
else return 0;
}
//return the index of the cell ontop of curcell
int get_upper_cell(int cur_cell)
{
int i;
for(i=0;i<totcells;i++)
{
if(vec_dist(cells[cur_cell].pos,cells[i].pos)==spc)//in neighbour range?
{
if(is_on_top(i,cur_cell))return i;//cells[i].index;//cell index ontop of current cell
}
}
return -1;//no cell found
}
//return the index of the cell below curcell
int get_lower_cell(int cur_cell)
{
int i;
for(i=0;i<totcells;i++)
{
if(vec_dist(cells[cur_cell].pos,cells[i].pos)==spc)//in neighbour range?
{
if(is_on_bottom(i,cur_cell))return i;//cells[i].index;//cell index bellow of current cell
}
}
return -1;//no cell found
}
//return the index of the cell left of curcell
int get_left_cell(int cur_cell)
{
int i;
for(i=0;i<totcells;i++)
{
if(vec_dist(cells[cur_cell].pos,cells[i].pos)==spc)//in neighbour range?
{
if(is_on_left(i,cur_cell))return i;//cells[i].index;//cell index left of current cell
}
}
return -1;//no cell found
}
//return the index of the cell right of curcell
int get_right_cell(int cur_cell)
{
int i;
for(i=0;i<totcells;i++)
{
if(vec_dist(cells[cur_cell].pos,cells[i].pos)==spc)//in neighbour range?
{
if(is_on_right(i,cur_cell))return i;//cells[i].index;//cell index right of current cell
}
}
return -1;//no cell found
}
////////////////////////////////////////////////////////remove walls
//remove curcell left wall
void remove_left_wall(int cur_cell)
{
vec_set(cells[cur_cell].left_walls,nullvector);
vec_set(cells[cur_cell].left_walle,nullvector);
}
//remove curcell right wall
void remove_right_wall(int cur_cell)
{
vec_set(cells[cur_cell].right_walls,nullvector);
vec_set(cells[cur_cell].right_walle,nullvector);
}
//remove curcell upper wall
void remove_upper_wall(int cur_cell)
{
vec_set(cells[cur_cell].upper_walls,nullvector);
vec_set(cells[cur_cell].upper_walle,nullvector);
}
//remove curcell lower wall
void remove_lower_wall(int cur_cell)
{
vec_set(cells[cur_cell].lower_walls,nullvector);
vec_set(cells[cur_cell].lower_walle,nullvector);
}
////////////////////////////////////////////////////////add walls
var d=2;
void add_left_wall(int cur_cell)
{
if(!has_left_wall(cur_cell))
{
vec_set(cells[cur_cell].left_walls,vector(cells[cur_cell].pos.x-spc/d,cells[cur_cell].pos.y+spc/d,0));
vec_set(cells[cur_cell].left_walle,vector(cells[cur_cell].pos.x+spc/d,cells[cur_cell].pos.y+spc/d,0));
}
}
void add_right_wall(int cur_cell)
{
if(!has_right_wall(cur_cell))
{
vec_set(cells[cur_cell].right_walls,vector(cells[cur_cell].pos.x-spc/d,cells[cur_cell].pos.y-spc/d,0));
vec_set(cells[cur_cell].right_walle,vector(cells[cur_cell].pos.x+spc/d,cells[cur_cell].pos.y-spc/d,0));
}
}
void add_upper_wall(int cur_cell)
{
if(!has_upper_wall(cur_cell))
{
vec_set(cells[cur_cell].upper_walls,vector(cells[cur_cell].pos.x+spc/d,cells[cur_cell].pos.y-spc/d,0));
vec_set(cells[cur_cell].upper_walle,vector(cells[cur_cell].pos.x+spc/d,cells[cur_cell].pos.y+spc/d,0));
}
}
void add_lower_wall(int cur_cell)
{
if(!has_lower_wall(cur_cell))
{
vec_set(cells[cur_cell].lower_walls,vector(cells[cur_cell].pos.x-spc/d,cells[cur_cell].pos.y-spc/d,0));
vec_set(cells[cur_cell].lower_walle,vector(cells[cur_cell].pos.x-spc/d,cells[cur_cell].pos.y+spc/d,0));
}
}
////////////////////////////////////////////////////////make grid
//void generate_grid(length of a straight section,amount of cells eg. 10x10 3x3)
//creates a grid of cells of value NxN
void generate_grid(var l,int tot)
{
var segment_length=l; //segment length of a straight segment model
int amount=tot;//amount of cells =amount x amount eg.3x3 grid
w=(segment_length*3)*amount;//width
h=(segment_length*3)*amount;//height
spc=segment_length*3;//space between cells centers
totcells=(int)(amount*amount);
cells=malloc(sizeof(cell)*totcells);
//create cells in grid
int i=0;
var d=2;
var xx=0,yy=0;
for(xx=0;xx<w;xx+=spc)
{
for(yy=0;yy<h;yy+=spc)
{
vec_set(cells[i].pos,vector(xx,yy,0));//cell pos
vec_set(cells[i].right_walls,vector(xx-spc/d,yy-spc/d,0));//r wall start
vec_set(cells[i].right_walle,vector(xx+spc/d,yy-spc/d,0));//r wall end
vec_set(cells[i].left_walls,vector(xx-spc/d,yy+spc/d,0));//l wall start
vec_set(cells[i].left_walle,vector(xx+spc/d,yy+spc/d,0));//l wall end
vec_set(cells[i].lower_walls,vector(xx-spc/d,yy-spc/d,0));//lower wall start
vec_set(cells[i].lower_walle,vector(xx-spc/d,yy+spc/d,0));//lower wall end
vec_set(cells[i].upper_walls,vector(xx+spc/d,yy-spc/d,0));//upper wall start
vec_set(cells[i].upper_walle,vector(xx+spc/d,yy+spc/d,0));//upper wall end
cells[i].index=i;
i+=1;
}
}
}
////////////////////////////////////////////////////////make maze
///////////////////////////
//create non-solvable maze
//by removing random cell walls
void do_maze()
{
int curcell=0;
for(curcell=0;curcell<totcells;curcell++)
{
int pick=random(4);//to remove a wall at random position(left/right/up/down walls)
if(pick==0)
{
//if not on border
//if has cell left of it
int neigbour=get_left_cell(curcell);
if(neigbour!=-1)
{
//if unvisited
if(has_right_wall(curcell) && has_upper_wall(curcell) && has_lower_wall(curcell))
{
//remove wall between
if(has_left_wall(curcell))remove_left_wall(curcell);
if(has_right_wall(neigbour))remove_right_wall(neigbour);
}
}
}
//picked neigbour right of curcell
if(pick==1)
{
//if not on border
//if has cell right of it
int neigbour=get_right_cell(curcell);
if(neigbour!=-1)
{
//if unvisited
if(has_left_wall(curcell) && has_upper_wall(curcell) && has_lower_wall(curcell))
{
//remove wall between
if(has_right_wall(curcell))remove_right_wall(curcell);
if(has_left_wall(neigbour))remove_left_wall(neigbour);
}
}
}
//picked neigbour ontop of curcell
if(pick==2)
{
//if not on border
//if has cell ontop of it
int neigbour=get_upper_cell(curcell);
if(neigbour!=-1)
{
//if unvisited
if(has_left_wall(curcell) && has_right_wall(curcell) && has_lower_wall(curcell))
{
//remove wall between
if(has_upper_wall(curcell))remove_upper_wall(curcell);
if(has_lower_wall(neigbour))remove_lower_wall(neigbour);
}
}
}
//picked neigbour below of curcell
if(pick==3)
{
//if not on border
//if has cell below it
int neigbour=get_lower_cell(curcell);
if(neigbour!=-1)
{
//if unvisited
if(has_left_wall(curcell) && has_right_wall(curcell) && has_upper_wall(curcell))
{
//remove wall between
if(has_lower_wall(curcell))remove_lower_wall(curcell);
if(has_upper_wall(neigbour))remove_upper_wall(neigbour);
}
}
}
}
////////////////////////////////////////////////////////make solvable
//if theres cells with less than min_walls add walls to it
//to prevent non-solvable mazes
for(curcell=0;curcell<totcells;curcell++)
{
int min_walls=2;
int total_cell_walls=0;
if(has_left_wall(curcell)) total_cell_walls+=1;
if(has_right_wall(curcell)) total_cell_walls+=1;
if(has_upper_wall(curcell)) total_cell_walls+=1;
if(has_lower_wall(curcell)) total_cell_walls+=1;
if(total_cell_walls<=min_walls)
{
if(total_cell_walls<=min_walls && !has_left_wall(curcell))
{
int neighbour=get_left_cell(curcell);
if(neighbour!=-1)
{
add_left_wall(curcell);
add_right_wall(neighbour);
total_cell_walls+=1;
}
}
if(total_cell_walls<=min_walls && !has_right_wall(curcell))
{
int neighbour=get_right_cell(curcell);
if(neighbour!=-1)
{
add_right_wall(curcell);
add_left_wall(neighbour);
total_cell_walls+=1;
}
}
if(total_cell_walls<=min_walls && !has_upper_wall(curcell))
{
int neighbour=get_upper_cell(curcell);
if(neighbour!=-1)
{
add_upper_wall(curcell);
add_lower_wall(neighbour);
total_cell_walls+=1;
}
}
if(total_cell_walls<=min_walls && !has_lower_wall(curcell))
{
int neighbour=get_lower_cell(curcell);
if(neighbour!=-1)
{
add_lower_wall(curcell);
add_upper_wall(neighbour);
total_cell_walls+=1;
}
}
}
}
}
////////////////////////
//create intersections and corners entities
void find_sections()
{
int curcell;
int pick=0;
for(curcell=0;curcell<totcells;curcell++)
{
//upperwallend -leftt top of cell
//upperwallstart -right top of cell
//lowerwallend -left bottom of cell
//lowerwallstart -right bottom of cell
//leftwallstart - bottom left of cell
//leftwallend - top left of cell
//rightwallstart - bottom right of cell
//rightwallend - top right of cell
//all shapes to build the maze-like structure are ceated and placed inside these functions
//iterate through neigbours
pick=get_left_cell(curcell);
if(pick!=-1)
{
//check for intersection T shaped at top left of cell
if(has_left_wall(curcell))
{
if(has_upper_wall(curcell)&& has_upper_wall(pick))
{
int a=get_upper_cell(curcell);
if(a!=-1)
{
if(!has_left_wall(a))//topleft T intersection
{
on_t_intersection_topleft(curcell,cells[curcell].upper_walle);
}
if(has_left_wall(a))//+ intersection
{
on_cross_intersection(curcell,cells[curcell].upper_walle);
}
}
}
}
//check for intersection T shaped at bottom left of cell
if(has_left_wall(curcell))
{
if(has_lower_wall(curcell)&& has_lower_wall(pick))
{
int a=get_lower_cell(curcell);
if(a!=-1)
{
if(!has_left_wall(a))//bottomleft inverted T _|_ intersection
{
on_t_intersection_bottomleft(curcell,cells[curcell].lower_walle);
}
}
}
}
}
pick=get_upper_cell(curcell);
if(pick!=-1)
{
//check for intersection T |-- shaped at top left of cell
if(has_left_wall(curcell)&& has_left_wall(pick))
{
if(has_upper_wall(curcell))
{
int a=get_left_cell(curcell);
if(a!=-1)
{
if(!has_upper_wall(a))//topleft on side |-- intersection
{
on_t_intersection_topleftside(curcell,cells[curcell].upper_walle);
}
}
}
}
//check for intersection T --| shaped at top right of cell
if(has_right_wall(curcell)&& has_right_wall(pick))
{
if(has_upper_wall(curcell))
{
int a=get_right_cell(curcell);
if(a!=-1)
{
if(!has_upper_wall(a))//topright on side --| intersection
{
on_t_intersection_toprightside(curcell,cells[curcell].right_walle);
}
}
}
}
}
//find corners
pick=get_left_cell(curcell);
if(pick!=-1)
{
if(has_left_wall(curcell))
{
if(has_upper_wall(curcell)&& !has_upper_wall(pick))
{
int a=get_upper_cell(curcell);
if(a!=-1)
{
if(!has_left_wall(a))//topleft corner
{
on_corner_topleft(curcell,cells[curcell].upper_walle);
}
}
}
}
}
pick=get_right_cell(curcell);
if(pick!=-1)
{
if(has_right_wall(curcell))
{
if(has_upper_wall(curcell)&& !has_upper_wall(pick))
{
int a=get_upper_cell(curcell);
if(a!=-1)
{
if(!has_right_wall(a))//topright corner intersection
{
on_corner_topright(curcell,cells[curcell].right_walle);
}
}
}
}
}
pick=get_left_cell(curcell);
if(pick!=-1)
{
if(has_left_wall(curcell))
{
if(has_lower_wall(curcell)&& !has_lower_wall(pick))
{
int a=get_lower_cell(curcell);
if(a!=-1)
{
if(!has_left_wall(a))//bottomleft corner intersection
{
on_corner_bottomleft(curcell,cells[curcell].left_walls);
}
}
}
}
}
pick=get_right_cell(curcell);
if(pick!=-1)
{
if(has_right_wall(curcell))
{
if(has_lower_wall(curcell)&& !has_lower_wall(pick))
{
int a=get_lower_cell(curcell);
if(a!=-1)
{
if(!has_right_wall(a))//bottomright corner intersection
{
on_corner_bottomright(curcell,cells[curcell].right_walls);
}
}
}
}
}
//x axis hallway sections
pick=get_left_cell(curcell);
if(pick!=-1)
{
if(has_left_wall(curcell)&& has_right_wall(pick))
{
on_upward_straight_leftmiddle(curcell,vector(cells[curcell].pos.x,cells[curcell].pos.y+spc/2,cells[curcell].pos.z));
if(!has_upper_wall(curcell) && !has_upper_wall(pick))
{
on_upward_straight_lefttop(curcell,vector(cells[curcell].pos.x+spc/3,cells[curcell].pos.y+spc/2,cells[curcell].pos.z));
}
if(!has_lower_wall(curcell) && !has_lower_wall(pick))
{
on_upward_straight_leftbottom(curcell,vector(cells[curcell].pos.x-spc/3,cells[curcell].pos.y+spc/2,cells[curcell].pos.z));
}
}
}
//y axis hallway sections
pick=get_upper_cell(curcell);
if(pick!=-1)
{
if(has_upper_wall(curcell)&& has_lower_wall(pick))
{
on_sideways_straight_topmiddle(curcell,vector(cells[curcell].pos.x+spc/2,cells[curcell].pos.y,cells[curcell].pos.z));
if(!has_right_wall(curcell) && !has_right_wall(pick))
{
on_sideways_straight_topright(curcell,vector(cells[curcell].pos.x+spc/2,cells[curcell].pos.y-spc/3,cells[curcell].pos.z));
}
if(!has_left_wall(curcell) && !has_left_wall(pick))
{
on_sideways_straight_bottomleft(curcell,vector(cells[curcell].pos.x+spc/2,cells[curcell].pos.y+spc/3,cells[curcell].pos.z));
}
}
}
}
}
Last edited by Wjbender; 02/19/13 12:18.
Compulsive compiler
|
|
|
|