Gamestudio Links
Zorro Links
Newest Posts
M1 Oversampling
by Petra. 04/24/24 10:34
Zorro FIX plugin - Experimental
by flink. 04/21/24 07:12
Data from CSV not parsed correctly
by EternallyCurious. 04/20/24 21:39
Scripts not found
by juergen_wue. 04/20/24 18:51
zorro 64bit command line support
by 7th_zorro. 04/20/24 10:06
StartWeek not working as it should
by jcl. 04/20/24 08:38
folder management functions
by VoroneTZ. 04/17/24 06:52
AUM Magazine
Latest Screens
The Bible Game
A psychological thriller game
SHADOW (2014)
DEAD TASTE
Who's Online Now
4 registered members (AndrewAMD, Ayumi, Quad, PeWi), 488 guests, and 6 spiders.
Key: Admin, Global Mod, Mod
Newest Members
Mega_Rod, EternallyCurious, howardR, 11honza11, ccorrea
19048 Registered Users
Previous Thread
Next Thread
Print Thread
Rate Thread
Page 2 of 2 1 2
Re: Walking Up Steps [Re: Valdsator] #385048
10/12/11 02:59
10/12/11 02:59
Joined: Oct 2005
Posts: 4,771
Bay City, MI
lostclimate Offline
Expert
lostclimate  Offline
Expert

Joined: Oct 2005
Posts: 4,771
Bay City, MI
you could make a bb struct and have a scheduler go through a list of bb dependant on its relativity to any possible collisions. i am far from an expert on physics or collision but thats where i would start if i were doing it.

Re: Walking Up Steps [Re: lostclimate] #385057
10/12/11 09:58
10/12/11 09:58
Joined: Aug 2009
Posts: 1,438
Spain
painkiller Offline
Serious User
painkiller  Offline
Serious User

Joined: Aug 2009
Posts: 1,438
Spain
maybe you can adapt c_intersect function


3D Gamestudio A8 Pro
AMD FX 8350 4.00 Ghz
16GB RAM
Gigabyte GeForce GTX 960 4GB
Re: Walking Up Steps [Re: painkiller] #385077
10/12/11 13:26
10/12/11 13:26
Joined: Dec 2008
Posts: 1,660
North America
Redeemer Offline
Serious User
Redeemer  Offline
Serious User

Joined: Dec 2008
Posts: 1,660
North America
Originally Posted By: Valdsator
Each entity would set it's bounding box (a rectangular prism) via a function I make, or just changing some skills, and then I would make a function for movement. The move function would use the bounding box to check if it's intersecting with another bounding box, or the level (not sure how I would do this, as c_intersect wouldn't work with the level, and c_trace only makes a line).
If it's intersecting, it would try fixing the problem, which could be done several ways (a simple solution would be moving to the previous position). I think I know how I would do gliding, but that's irrelevant at this point. I really just need help creating the bounding box. Is it possible for the engine to check if anything is inside a rectangular prism shaped area? I don't think c_scan would work.

That's a fine plan, but it's sort of like planning the construction of a robot when you have no idea how they work. "First, I make the robot's body. Then I program the robot and give it power."

Don't take that the wrong way, I'm just trying to put what you said into perspective for you. laugh To "make" a bounding box for an object, you have to define a new data structure with the information you'll need (or reuse an existing one, like an entity's min/max variables) and then setup some complicated logical and mathematical constructs that can be used to "trace" a volume across your movement distance. Said tracing involves checking the volume's path against the world's raw geometry data, which is simply a list of polygon definitions... and simply put, it's really really hard to check cube volumes against polygons.

Basically, this is a very complicated kind of programming and you're in for a massive headache if you try to begin learning it by writing your own 3D AABB movement system. And trust me when I say there's no easy way to do this right. My own 2D collision code was 350 lines of commented code - and while that may seem like only a little bit, for such a "simple" task of moving a box over a 2D landscape, it's quite a lot of mathematical/logical construction, and none of it's obvious!

Here's my code just so you can get a small idea of what you'd be up against (note that it's long, and (being experimental) a bit messy):
Click to reveal..
Code:
/*-------------------------------------------------------------------------------

	e_CheckCells

	Tests all four cells surrounding the position (tx, ty, tz) and returns
	a 1 if the position intersects with a cell.

-------------------------------------------------------------------------------*/

int e_CheckCells( double tx, double ty, int tz, entity_t* me )
{
	float sx, sy;
	float ffx, ffy;
	long fx, fy;
	long fh, ch;
	entity_t* entity;

	for( sy=-me->sizey; sy<=me->sizey; sy+=me->sizey )
	{
		for( sx=-me->sizex; sx<=me->sizex; sx+=me->sizex )
		{
			fx = floor(tx+sx); fy = floor(ty+sy); // int coordinates
			ffx = tx+sx; ffy = ty+sy; // float coordinates
			
			fh = map.floors[fx+fy*map.width] + (me->sizez*.5) - 1; // get the initial floor/ceiling heights
			ch = map.ceilings[fx+fy*map.width] - (me->sizez*.5) - 1;
			if( firstentity != NULL ) // check against entities
			{
				for( entity=firstentity; entity!=NULL; entity=entity->next )
				{
					if( !(entity->flags&FLAG_PASSABLE) && entity != me ) // if the entity is neither passable nor myself
					{
						if( ffx >= entity->x-entity->sizex && ffx <= entity->x+entity->sizex ) // if this horizontal position intersects with the entity
						{
							if( ffy >= entity->y-entity->sizey && ffy <= entity->y+entity->sizey ) // if this vertical position intersects with the entity
							{
								if( me->z+me->sizez > entity->z+entity->sizez && fh < entity->z+entity->sizez )
									fh=entity->z+entity->sizez; // adjust the floor height to include me!
								if( me->z-me->sizez < entity->z-entity->sizez && ch > entity->z-entity->sizez )
									ch=entity->z-entity->sizez; // adjust the ceiling height to include me!
								else if( me->z == entity->z )
									return(1); // you're level with the entity. stop that ship!
							}
						}
					}
				}
			}
			
			if( fh >= ch ) return(1); // the floor is in the ceiling
			if( (fh-tz) > STEPHEI ) return(1); // this floor is too high
			else if( fh+1 >= tz ) me->onground=1; // I fell to the floor
			if( (tz-ch) > STEPHEI ) return(1); // the ceiling is too low
			
			gfh = max(fh+1,gfh); // remember the highest position of the floor for this collision pass
			gch = min(ch+1,gch); // remember the lowest position of the ceiling for this collision pass
		}
	}
	return(0);
}

/*-------------------------------------------------------------------------------

	e_ClipVelocity

	Takes a velocity (vx, vy, vz) and clips it against the cells
	surrounding the position (*x, *y, *z)

-------------------------------------------------------------------------------*/

int e_ClipVelocity( double *x, double *y, int *z, double vx, double vy, double vz, entity_t* me )
{
	double tx, ty; int tz;
	long fx, fy;
	//long fh, ch;
	int exitcode = 1;

	if( *x+vx < .36 ) vx -= *x+vx-.36;
	if( *y+vy < .36 ) vy -= *y+vy-.36;
	if( *x+vx > map.width-.36 ) vx -= *x+vx-map.width+.36;
	if( *y+vy > map.height-.36 ) vy -= *y+vy-map.height+.36;
	
	fx=floor(*x); fy=floor(*y);
	gfh = map.floors[fx+fy*map.width] + (me->sizez*.5);
	gch = map.ceilings[fx+fy*map.width] - (me->sizez*.5);

	if(me->onground == 0) me->onground2 = 0;
	else me->onground = 0;
	tx=*x+vx;
	ty=*y+vy;
	tz=*z;
	if( !e_CheckCells(tx,ty,tz,me) )
	{
		*x=tx;
		*y=ty;
		exitcode=0;
	}
	else
	{
		tx=*x+vx;
		ty=*y;
		tz=*z;
		if( !e_CheckCells(tx,ty,tz,me) )
		{
			*x=tx;
			*y=ty;
		}
		else
		{
			tx=*x;
			ty=*y+vy;
			tz=*z;
			if( !e_CheckCells(tx,ty,tz,me) )
			{
				*x=tx;
				*y=ty;
			}
		}
	}

	tx=*x; ty=*y; tz=*z;
	/*fx=floor(tx); fy=floor(ty);

	fh = map.floors[fx+fy*map.width] + PLAYER_EYES;
	ch = map.ceilings[fx+fy*map.width] - (PLAYER_HEIGHT-PLAYER_EYES);*/

	*z=min(max((tz+vz),gfh-me->sizez),gch);
	if(*z <= gfh)
	{
		if( !me->onground2 ) // landing from a fall?
		{
			*z=gfh;
			me->onground2=1;
		}
		else if(*z < gfh) // climbing a step?
		{
			*z+=timesync*.3;
			if(*z>gfh) *z=gfh;
		}
	}

	return(exitcode);
}

/*-------------------------------------------------------------------------------

	e_MoveTrace

	Traces from *x1, *y1, *z1 to x2, y2, z2 performing collision detection along the
	way. If an impassable obstacle or the destination is reached, set the
	given pointers *x1, *y1, and *z1 to end position.

-------------------------------------------------------------------------------*/

void e_MoveTrace( double *x1, double *y1, int *z1, double x2, double y2, int z2, entity_t* me )
{
	double tracex, tracey, tracex2, tracey2;
	int tracez, tracez2;
	double dx, dy, dxabs, dyabs, x, y;
	int sdx, sdy, i;

	dx=x2-*x1;		// the horizontal distance of the line
	dy=y2-*y1;		// the vertical distance of the line
	dxabs=abs(dx);
	dyabs=abs(dy);
	sdx=sgn(dx);
	sdy=sgn(dy);
	x=dyabs*.5;
	y=dxabs*.5;
	tracex=*x1;
	tracey=*y1;
	tracez=*z1;
	tracex2=x2;
	tracey2=y2;
	tracez2=z2-tracez;

	if( sdx >= 0 && sdy >= 0 )
	{
		if( e_ClipVelocity(&tracex,&tracey,&tracez,min(1,tracex2-tracex),min(1,tracey2-tracey),tracez2,me) )
		{
			*x1 = tracex;
			*y1 = tracey;
			*z1 = tracez;
			return;
		}
	}
	else if( sdx < 0 && sdy >= 0 )
	{
		if( e_ClipVelocity(&tracex,&tracey,&tracez,min(1,tracex2-tracex),min(1,tracey2-tracey),tracez2,me) )
		{
			*x1 = tracex;
			*y1 = tracey;
			*z1 = tracez;
			return;
		}
	}
	else if( sdx >= 0 && sdy < 0 )
	{
		if( e_ClipVelocity(&tracex,&tracey,&tracez,min(1,tracex2-tracex),min(1,tracey2-tracey),tracez2,me) )
		{
			*x1 = tracex;
			*y1 = tracey;
			*z1 = tracez;
			return;
		}
	}
	else if( sdx < 0 && sdy < 0 )
	{
		if( e_ClipVelocity(&tracex,&tracey,&tracez,min(1,tracex2-tracex),min(1,tracey2-tracey),tracez2,me) )
		{
			*x1 = tracex;
			*y1 = tracey;
			*z1 = tracez;
			return;
		}
	}
	if( dxabs >= dyabs ) // the line is more horizontal than vertical
	{
		for( i=0; i<dxabs; i++ )
		{
			y+=dyabs;
			if( y >= dxabs )
			{
				y -= dxabs;
				tracey += sdy;
			}
			tracex += sdx;

			if( sdx >= 0 && sdy >= 0 )
			{
				if( e_ClipVelocity(&tracex,&tracey,&tracez,min(1,tracex2-tracex),min(1,tracey2-tracey),tracez2,me) )
				{
					*x1 = tracex;
					*y1 = tracey;
					*z1 = tracez;
					return;
				}
			}
			else if( sdx < 0 && sdy >= 0 )
			{
				if( e_ClipVelocity(&tracex,&tracey,&tracez,min(1,tracex2-tracex),min(1,tracey2-tracey),tracez2,me) )
				{
					*x1 = tracex;
					*y1 = tracey;
					*z1 = tracez;
					return;
				}
			}
			else if( sdx >= 0 && sdy < 0 )
			{
				if( e_ClipVelocity(&tracex,&tracey,&tracez,min(1,tracex2-tracex),min(1,tracey2-tracey),tracez2,me) )
				{
					*x1 = tracex;
					*y1 = tracey;
					*z1 = tracez;
					return;
				}
			}
			else if( sdx < 0 && sdy < 0 )
			{
				if( e_ClipVelocity(&tracex,&tracey,&tracez,min(1,tracex2-tracex),min(1,tracey2-tracey),tracez2,me) )
				{
					*x1 = tracex;
					*y1 = tracey;
					*z1 = tracez;
					return;
				}
			}
		}
	}
	else // the line is more vertical than horizontal
	{
		for( i=0; i<dyabs; i++ )
		{
			x += dxabs;
			if( x >= dyabs )
			{
				x -= dyabs;
				tracex += sdx;
			}
			tracey += sdy;

			if( sdx >= 0 && sdy >= 0 )
			{
				if( e_ClipVelocity(&tracex,&tracey,&tracez,min(1,tracex2-tracex),min(1,tracey2-tracey),tracez2,me) )
				{
					*x1 = tracex;
					*y1 = tracey;
					*z1 = tracez;
					return;
				}
			}
			else if( sdx < 0 && sdy >= 0 )
			{
				if( e_ClipVelocity(&tracex,&tracey,&tracez,min(1,tracex2-tracex),min(1,tracey2-tracey),tracez2,me) )
				{
					*x1 = tracex;
					*y1 = tracey;
					*z1 = tracez;
					return;
				}
			}
			else if( sdx >= 0 && sdy < 0 )
			{
				if( e_ClipVelocity(&tracex,&tracey,&tracez,min(1,tracex2-tracex),min(1,tracey2-tracey),tracez2,me) )
				{
					*x1 = tracex;
					*y1 = tracey;
					*z1 = tracez;
					return;
				}
			}
			else if( sdx < 0 && sdy < 0 )
			{
				if( e_ClipVelocity(&tracex,&tracey,&tracez,min(1,tracex2-tracex),min(1,tracey2-tracey),tracez2,me) )
				{
					*x1 = tracex;
					*y1 = tracey;
					*z1 = tracez;
					return;
				}
			}
		}
	}
	*x1 = tracex;
	*y1 = tracey;
	*z1 = tracez;
}


I execute this movement system by calling e_MoveTrace and passing an entity's information. e_MoveTrace in turn calls e_CheckVelocity multiple times while it traces a path through the level, which in turn calls e_CheckCells multiple times to check whether or not the volume has hit an obstacle so far.
(note that in my code I'm also moving z variables around... that's because technically this is collision code for a doom-like engine)

Last edited by Redeemer; 10/12/11 13:42.

Eats commas for breakfast.

Play Barony: Cursed Edition!
Re: Walking Up Steps [Re: Redeemer] #385094
10/12/11 21:16
10/12/11 21:16
Joined: Mar 2009
Posts: 186
V
Valdsator Offline OP
Member
Valdsator  Offline OP
Member
V

Joined: Mar 2009
Posts: 186
Originally Posted By: Redeemer
That's a fine plan, but it's sort of like planning the construction of a robot when you have no idea how they work. "First, I make the robot's body. Then I program the robot and give it power."
Haha, that's exactly how I feel.

Originally Posted By: Redeemer
Basically, this is a very complicated kind of programming and you're in for a massive headache if you try to begin learning it by writing your own 3D AABB movement system. And trust me when I say there's no easy way to do this right. My own 2D collision code was 350 lines of commented code - and while that may seem like only a little bit, for such a "simple" task of moving a box over a 2D landscape, it's quite a lot of mathematical/logical construction, and none of it's obvious!
Heh, I knew it wasn't quite as simple as I thought. Since I'm really interested in this, I'll search around the internet for more information, and do some experiments. Thanks for the code, I'll definitely have a look at that, and thanks for explaining the basics as well. laugh

Re: Walking Up Steps [Re: Valdsator] #385107
10/13/11 04:13
10/13/11 04:13
Joined: Aug 2008
Posts: 482
B
bart_the_13th Offline
Senior Member
bart_the_13th  Offline
Senior Member
B

Joined: Aug 2008
Posts: 482
Maybe you can check jiglib's collision for start. I guess the best way to check collision actually is during the vertex computing/processing, at least when you actually have access to the process.

Re: Walking Up Steps [Re: bart_the_13th] #385136
10/13/11 12:16
10/13/11 12:16
Joined: May 2009
Posts: 5,370
Caucasus
3run Offline
Senior Expert
3run  Offline
Senior Expert

Joined: May 2009
Posts: 5,370
Caucasus
Bart, where can I find those jiglib's collusions?


Looking for free stuff?? Take a look here: http://badcom.at.ua
Support me on: https://boosty.to/3rung
Re: Walking Up Steps [Re: Valdsator] #385266
10/15/11 15:46
10/15/11 15:46
Joined: Mar 2009
Posts: 186
V
Valdsator Offline OP
Member
Valdsator  Offline OP
Member
V

Joined: Mar 2009
Posts: 186
Alright, I've begun experimenting on some collision detection stuff, but obviously it's going to take a while to make anything that would be flexible and usable in a game. I guess I'll have to just deal with the 3DGS collision detection for now, but one thing that would really help is the ability for the bounding box to be... well an actual box. It's an ellipsoid when it's colliding against the level, and it would be great if it was just a rectangular prism. Surely there's a way to do this? :|

Re: Walking Up Steps [Re: Valdsator] #385274
10/15/11 17:45
10/15/11 17:45
Joined: May 2009
Posts: 5,370
Caucasus
3run Offline
Senior Expert
3run  Offline
Senior Expert

Joined: May 2009
Posts: 5,370
Caucasus
No mate, there is no way to change ellipsoid shape for collusions... But sure, there are some ways to workaround problems which you faced, but without changing bbox's shape. A lot of users on this community requested different shapes for bbox, but noone really cares...


Looking for free stuff?? Take a look here: http://badcom.at.ua
Support me on: https://boosty.to/3rung
Re: Walking Up Steps [Re: 3run] #385275
10/15/11 18:31
10/15/11 18:31
Joined: Sep 2003
Posts: 6,861
Kiel (Germany)
Superku Offline
Senior Expert
Superku  Offline
Senior Expert

Joined: Sep 2003
Posts: 6,861
Kiel (Germany)
I'm currently working on a simple AABB implementation (blocks/ entities):
http://www.opserver.de/ubb7/ubbthreads.php?ubb=showflat&Number=385150#Post385150
I will continue to work on it after I've written my last exam on the 21st and publish the source code (if I get it done).


"Falls das Resultat nicht einfach nur dermassen gut aussieht, sollten Sie nochmal von vorn anfangen..." - Manual

Check out my new game: Pogostuck: Rage With Your Friends
Re: Walking Up Steps [Re: Superku] #385282
10/15/11 21:37
10/15/11 21:37
Joined: Mar 2009
Posts: 186
V
Valdsator Offline OP
Member
Valdsator  Offline OP
Member
V

Joined: Mar 2009
Posts: 186
Nice! Good luck with that. I don't like using other people's code, so I'd probably just look at it to see how it's done. tongue

Anyway, good news. I finally got the walking up steps thingy to work properly, while not screwing up the slopes. First I set move_min_z to 0.1, because the default 3dgs collision detection is going to take care of sliding down slopes. Next, I made a c_trace that goes from the bottom of the bounding box of the player, to a bit lower (5 unit) than his model's feet. Then it checks if there was a hit, and if the normal.z is more than 0.9.

It instantly sets the entity's z to hit.z + 60 (standing on the ground) if normal.z is less than 1. So if the player is walking on a slope, he will stick to the ground. Then it checks if my.z is lower than hit.z + 60 (the feet of the player is 60 units below the origin), and if normal.z = 1. If so, it increases z_move to 10 (a variable c_move uses). This allows for the player to walk up steps.

If the player is now perfectly standing on the ground, z_move is set to 0. Finally, if the c_trace does not hit, or if the player walks on to a slope too steep, gravity pulls the player down.

Code:
move_min_z = 0.1;

[irrelevant code]

c_trace(vector(my.x,my.y,my.z + my.min_z),vector(my.x,my.y,(my.z - 65)),IGNORE_ME|IGNORE_PASSABLE);
	if(trace_hit && normal.z > 0.9){
		if(normal.z < 1){my.z = hit.z + 60;} //if on slope
		if(my.z < hit.z + 60){ //if too low
			if(normal.z == 1){z_move = 10;} //and if on flat ground
		}else{ //if standing perfectly on ground
			z_move = 0;
		}
	}else{ //if not on ground
		z_move -= grav * time_step;
	}
c_move(me,nullvector,vector(0,0,z_move * time_step),GLIDE|IGNORE_PASSABLE);

Woot.

Page 2 of 2 1 2

Gamestudio download | chip programmers | Zorro platform | shop | Data Protection Policy

oP group Germany GmbH | Birkenstr. 25-27 | 63549 Ronneburg / Germany | info (at) opgroup.de

Powered by UBB.threads™ PHP Forum Software 7.7.1