int
detect_collision (struct pt *oldpos, struct pt *newpos,
		      struct groundtri *gt)
{
	double dist, t;
	struct vect v;
	struct pt p;

	dist = dist_pt_to_plane (newpos, &gt->pl);

	//THINK THROUGH IF NORMAL WILL ALWAYS BE POINTING IN CORRECT DIRECTION
	//AND IF A WALL MATTERS IF YOU GO THROUGH IT IN THE WRONG DIRECTION

	//DO OTHER GAMES CARE IF YOU GO THROUGH A WALL THE WRONG WAY? I DON'T
	//REMEMBER, HAVE TO CHECK

	if (dist >= 0) {
		return (0);
	} else {
		psub (&v, newpos, oldpos);

		t = -(gt->pl.a * oldpos->x + gt->pl.b * oldpos->y + gt->pl.c * oldpos->z + gt->pl.d) / (gt->pl.a * v.x + gt->pl.b * v.y + gt->pl.c * v.z);

		p.x = oldpos->x + v.x * t;
		p.y = oldpos->x + v.y * t;
		p.z = oldpos->x + v.z * t;
		
		return (pt_in_gt (&p, gt));
	}

	return (0);
}
int
pt_in_gt (struct pt *p, struct groundtri *gt)
{
	double theta;
	struct vect v1, v2;

	theta = 0;

	psub (&v1, &gt->p1, p);
	vnorm (&v1, &v1);

	psub (&v2, &gt->p2, p);
	vnorm (&v2, &v2);

	theta += acos (vdot (&v1, &v2));


	psub (&v1, &gt->p2, p);
	vnorm (&v1, &v1);

	psub (&v2, &gt->p3, p);
	vnorm (&v2, &v2);

	theta += acos (vdot (&v1, &v2));

		
	psub (&v1, &gt->p3, p);
	vnorm (&v1, &v1);

	psub (&v2, &gt->p1, p);
	vnorm (&v2, &v2);

	theta += acos (vdot (&v1, &v2));

	if (theta >= DTOR ((360 - 1e-7))) {
		return (1);
	}

	return (0);
}
Exemple #3
0
int main(){



int gd = DETECT,gm;

initgraph(&gd,&gm,NULL);
point p1,p2;
point l1,l2;

p1.x=100;
p1.y=100;
p2.x=300;
p2.y=300;

l1.x=80;
l1.y=130;
l2.x=330;
l2.y=150;

rectangle(p1.x, p1.y,p2.x,p2.y);
//line(l1.x,l1.y, l2.x,l2.y);

point n[4];
point p[4];
point w[4];
point d[4];

n[0].x=-1;n[0].y=0;
n[1].x=-1;n[1].y=0;
n[2].x=0;n[2].y=1;
n[3].x=0;n[3].y=-1;

p[0].x=p1.x;p[0].y=p1.y;
p[1].x=p2.x;p[1].y=p2.y;
p[2].x=p1.x;p[2].y=p1.y;
p[3].x=p2.x;p[3].y=p2.y;

psub(l1,p[0],w[0]);
psub(l1,p[1],w[1]);
psub(l1,p[2],w[2]);
psub(l1,p[3],w[3]);

for(int i=0;i<4;i++)
	 {
	 	 d[i].x=l2.x-l1.x; 
	 	 d[i].y=l2.y-l1.y;
	 }



int nw[4];
int nd[4];

for(int i=0;i<4;i++){

	nw[i]=mul(n[i],w[i]);
	nd[i]=mul(n[i],d[i]);

 }


 float tl=-10000;
 float tu=10000;


 for(int i=0;i<4;i++)
 {
   
   if(nd[i]>0)
     {
     	float tm=nw[i]/nd[i];
     	  
     	  if(tm>tl) tl=tm;
     }
     else
     {
        
       float tm=nw[i]/nd[i];
       
       if(tm<tu) tu=tm;

     }


 }

point rp1;
point rp2;

rp1.x=l1.x+d[0].x*tl;
rp1.y=l1.y+d[0].y*tl;

rp2.x=l1.x+d[0].x*tu;
rp2.y=l1.y+d[0].y*tu;


line(rp1.x,rp1.y, rp2.x,rp2.y);

delay(10000);
closegraph();

return 0;
}
void
old_grounded_moving (void)
{
	double now, dt;
	struct pt newpos;
	struct groundtri *gt;
	struct vect v1, v2, ctrl_vel;

	now = get_secs ();
	dt = now - player.lasttime;

	ctrl_vel.x = 0;
	ctrl_vel.y = 0;
	ctrl_vel.z = 0;

	if (player.p.z <= ground_height (&player.p)) {
		switch (player.moving) {
		case BACK:
			ctrl_vel.x = -.3 * player.speed * cos (player.theta);
			ctrl_vel.y = -.3 * player.speed * sin (player.theta);
			break;
		case FORW:
			ctrl_vel.x = player.speed * cos (player.theta);
			ctrl_vel.y = player.speed * sin (player.theta);
			break;
		case SIDE_Q:
			ctrl_vel.x = player.speed
				* cos (player.theta + DTOR (90));
			ctrl_vel.y = player.speed
				* sin (player.theta + DTOR (90));
			break;
		case SIDE_E:
			ctrl_vel.x = player.speed
				* cos (player.theta - DTOR (90));
			ctrl_vel.y = player.speed
				* sin (player.theta - DTOR (90));
			break;
		case FORW_Q:
			ctrl_vel.x = player.speed
				* cos (player.theta + DTOR (45));
			ctrl_vel.y = player.speed
				* sin (player.theta + DTOR (45));
			break;
		case FORW_E:
			ctrl_vel.x = player.speed
				* cos (player.theta - DTOR (45));
			ctrl_vel.y = player.speed
				* sin (player.theta - DTOR (45));
			break;
		case BACK_Q:
			ctrl_vel.x = -.3 * player.speed
				* cos (player.theta - DTOR (45));
			ctrl_vel.y = -.3 * player.speed
				* sin (player.theta - DTOR (45));
			break;
		case BACK_E:
			ctrl_vel.x = -.3 * player.speed
				* cos (player.theta + DTOR (45));
			ctrl_vel.y = -.3 * player.speed
				* sin (player.theta + DTOR (45));
			break;
		}
	}

	newpos.x = player.p.x + ctrl_vel.x * dt;
	newpos.y = player.p.y + ctrl_vel.y * dt;
	newpos.z = player.p.z + ctrl_vel.z * dt;

	psub (&player.vel, &newpos, &player.p);
	vscal (&player.vel, &player.vel, 1 / dt);

	if ((gt = detect_plane (&newpos)) == NULL) {
		printf ("Can't find ground, moving player to start position "
			"to avoid seg fault\n");
		player.p.x = 0;
		player.p.y = 0;
		player.p.z = ground_height (&player.p);
		player.movtype = GROUNDED;
		player.loc = detect_plane (&player.p);
		return;
	}

	if (gt->theta < DTOR (50)) {
		newpos.z = ground_height (&newpos);
		psub (&player.vel, &newpos, &player.p);
		vscal (&player.vel, &player.vel, 1 / dt);
		player.p = newpos;
	} else if (newpos.z > gt->pl.middle.z) {
		player.p = newpos;
		player.movtype = FALLING;
		printf ("switching to falling\n");
	} else if (newpos.z <= gt->pl.middle.z) {
		if (gt == player.loc) {
			printf ("line %d: some sort of bug caused"
				" player to be in grounded mode while"
				" on steep plane\n", __LINE__);
			pt_on_z_plane (&newpos, &newpos, &player.loc->pl);
			player.p = newpos;
			printf ("shifting player to nearest point on"
				" plane with same z\n");
			vset (&player.vel, 0, 0, 0);
			printf ("killing player velocity\n");
			player.movtype = FALLING;
			printf ("switching to falling\n");
			paused = YES;
			printf ("paused game\n");
			return;
		}

		vnorm (&v2, &ctrl_vel);
		vcross (&v1, &player.loc->normv, &gt->normv);
		vnorm (&v1, &v1);
		if (vdot (&v1, &v2) < 0)
			vscal (&v1, &v1, -1);
		vscal (&ctrl_vel, &v1, vdot (&ctrl_vel, &v1));
			
		newpos.x = player.p.x + ctrl_vel.x * dt;
		newpos.y = player.p.y + ctrl_vel.y * dt;
		newpos.z = player.p.z + ctrl_vel.z * dt;
			
		if ((gt = detect_plane (&newpos)) == NULL) {
			printf ("can't detect plane, exiting\n");
			exit (1);
		}
			
		if (gt->theta < DTOR (50)) {
			newpos.z = ground_height (&newpos);
			psub (&player.vel, &newpos, &player.p);
			vscal (&player.vel, &player.vel, 1 / dt);
				
			printf ("bar\n");

			player.p = newpos;
		} else {
//			struct groundtri *first_col, *last_col, *gt2;
//			int i;

			//PLAYER STARTS MOVING INTO GROUND BEFORE THIS EVER
			//HAPPENS

			printf ("pausing\n");
			paused = YES;

			/* i = 0; */
			/* first_col = NULL; */
			/* last_col = NULL; */

			/* for (gt2 = first_groundtri; gt2; gt2 = gt2->next) { */
			/* 	if (detect_collision (&player.p, */
			/* 			      &newpos, gt2)) { */
			/* 		if (first_col == NULL) { */
			/* 			first_col = gt2; */
			/* 		} else { */
			/* 			last_col->next = gt2; */
			/* 		} */
			/* 		last_col = gt2; */

			/* 		i++; */
			/* 	} */
			/* } */

			/* if (first_col == NULL) { */
			/* 	printf ("%s: %s: %d: something weird\n", */
			/* 		__FILE__, __FUNCTION__, __LINE__); */
			/* } */
			
			/* printf ("number of collisions: %d\n", i); */



			//TRY PROJECTING PLAYER TO LINE OF INTERSECTION
			//BETWEEN OLD & NEW PLANES. IF PLAYER IS STILL
			//INSIDE ANY PLANES, GRAB THREE PLANES AND GO
			//TO INTERSECTION POINT OF THOSE. MIGHT WANT
			//TO CHECK FOR OVER THREE PLANES JUST IN CASE

/* 			printf ("player.z: %g\n", player.p.z); */
/* 			newpos = player.p; */
/* 			rnd_escape (&newpos, gt); */
/* 			printf ("ran rnd_escape\n"); */
/* 			gt = detect_plane (&newpos); */


/* 			double b2; */
/* 			b2 = newpos.y - (gt->pl.b / gt->pl.a) * newpos.x; */
/* 			newpos.x = -(b2 * gt->pl.a * gt->pl.b */
/* 				     + gt->pl.c * newpos.z * gt->pl.a */
/* 				     + gt->pl.d * gt->pl.a) */
/* 				/ (square (gt->pl.a) + square (gt->pl.b)); */
/* 			newpos.y = (gt->pl.b / gt->pl.a) * newpos.x + b2; */
/* 			player.p = newpos; */
/* 			printf ("shifting player to nearest point on" */
/* 				" plane with same z\n"); */


/* 			gt = detect_plane (&player.p); */
/* 			printf ("re detected plane\n"); */
/* 			if (gt->theta >= DTOR (50)) { */
/* 				printf ("rnd_escape put player on slope," */
/* 					" changing player to falling\n"); */
/* 				player.movtype = FALLING; */
/* 				printf ("killing velocity\n"); */
/* 				vset (&player.vel, 0, 0, 0); */
/* 			} */
/* 			printf ("player.z: %g\n", player.p.z); */
		}
	} else {
		printf ("this should never be printed\n");
	}
}
void
grounded_moving (void)
{
	double now, dt;
	struct pt newpos;
	struct groundtri *gt;
	struct vect ctrl_vel;

	now = get_secs ();
	dt = now - player.lasttime;

	ctrl_vel.x = 0;
	ctrl_vel.y = 0;
	ctrl_vel.z = 0;

	if (fabs (player.p.z - ground_height (&player.p)) <= 1e6) {
		switch (player.moving) {
		case BACK:
			ctrl_vel.x = -.3 * player.speed * cos (player.theta);
			ctrl_vel.y = -.3 * player.speed * sin (player.theta);
			break;
		case FORW:
			ctrl_vel.x = player.speed * cos (player.theta);
			ctrl_vel.y = player.speed * sin (player.theta);
			break;
		case SIDE_Q:
			ctrl_vel.x = player.speed
				* cos (player.theta + DTOR (90));
			ctrl_vel.y = player.speed
				* sin (player.theta + DTOR (90));
			break;
		case SIDE_E:
			ctrl_vel.x = player.speed
				* cos (player.theta - DTOR (90));
			ctrl_vel.y = player.speed
				* sin (player.theta - DTOR (90));
			break;
		case FORW_Q:
			ctrl_vel.x = player.speed
				* cos (player.theta + DTOR (45));
			ctrl_vel.y = player.speed
				* sin (player.theta + DTOR (45));
			break;
		case FORW_E:
			ctrl_vel.x = player.speed
				* cos (player.theta - DTOR (45));
			ctrl_vel.y = player.speed
				* sin (player.theta - DTOR (45));
			break;
		case BACK_Q:
			ctrl_vel.x = -.3 * player.speed
				* cos (player.theta - DTOR (45));
			ctrl_vel.y = -.3 * player.speed
				* sin (player.theta - DTOR (45));
			break;
		case BACK_E:
			ctrl_vel.x = -.3 * player.speed
				* cos (player.theta + DTOR (45));
			ctrl_vel.y = -.3 * player.speed
				* sin (player.theta + DTOR (45));
			break;
		}
	}

	newpos.x = player.p.x + ctrl_vel.x * dt;
	newpos.y = player.p.y + ctrl_vel.y * dt;
	newpos.z = player.p.z + ctrl_vel.z * dt;

	psub (&player.vel, &newpos, &player.p);
	vscal (&player.vel, &player.vel, 1 / dt);

	if ((gt = detect_plane (&newpos)) == NULL) {
		printf ("Can't find ground, moving player to start position "
			"to avoid seg fault\n");
		player.p.x = 0;
		player.p.y = 0;
		player.p.z = ground_height (&player.p);
		player.movtype = GROUNDED;
		player.loc = detect_plane (&player.p);
		return;
	}

	if (gt->theta < DTOR (50)) {
		newpos.z = ground_height (&newpos);
		psub (&player.vel, &newpos, &player.p);
		vscal (&player.vel, &player.vel, 1 / dt);
		player.p = newpos;
	} else if (newpos.z > gt->pl.middle.z) {
		//imperfect detection of cliffs but tolerable for now
		player.p = newpos;
		player.movtype = FALLING;
		printf ("switching to falling\n");
	} else {
		if (gt == player.loc) {
			printf ("line %d: HORRIBLE MESSINESS\n", __LINE__);
			paused = YES;
			printf ("paused game\n");
			return;
		}

		struct vect v1, v2;

		vnorm (&v2, &ctrl_vel);
		vcross (&v1, &player.loc->normv, &gt->normv);
		vnorm (&v1, &v1);
		if (vdot (&v1, &v2) < 0)
			vscal (&v1, &v1, -1);
		vscal (&ctrl_vel, &v1, vdot (&ctrl_vel, &v1));
			
		newpos.x = player.p.x + ctrl_vel.x * dt;
		newpos.y = player.p.y + ctrl_vel.y * dt;
		newpos.z = player.p.z + ctrl_vel.z * dt;

		newpos.z = ground_height (&newpos);
		psub (&player.vel, &newpos, &player.p);
		vscal (&player.vel, &player.vel, 1 / dt);
				
		player.p = newpos;
	}
}