Пример #1
0
void collideObjectRoom(physicalPoint_s* pp, room_s* r)
{
	if(!pp || !r)return;
	vect3Df_s oldPosition = pp->position;

	// float length=vmagf(pp->speed);
	
	bool ret=false;
	
	pp->position = vaddf(pp->position,pp->speed);
	ret = checkObjectCollision(pp, r);
	
	pp->contact=ret;
	
	vect3Df_s os=pp->speed;
	pp->speed=vect3Df(pp->position.x-oldPosition.x, pp->position.y-oldPosition.y, pp->position.z-oldPosition.z);
	pp->speed=vect3Df((os.x*pp->speed.x>0)?(pp->speed.x):(0),(os.y*pp->speed.y>0)?(pp->speed.y):(0),(os.z*pp->speed.z>0)?(pp->speed.z):(0));

	if(pp->contact)
	{
		 //floor friction
		vect3Df_s s=vsubf(pp->speed,vmulf(normGravityVector,vdotf(normGravityVector,pp->speed)));
		pp->speed=vsubf(pp->speed,vdivf(s,2));
	}else{
		//air friction
		vect3Df_s s=vsubf(pp->speed,vmulf(normGravityVector,vdotf(normGravityVector,pp->speed)));
		pp->speed=vsubf(pp->speed,vdivf(s,32));
	}

	if(fabs(pp->speed.x)<0.01f)pp->speed.x=0;
	if(fabs(pp->speed.z)<0.01f)pp->speed.z=0;
}
Пример #2
0
bool collideRectangle(physicalPoint_s* o, vect3Df_s p, vect3Df_s s)
{
	if(!o)return false;

	vect3Df_s o2 = getClosestPointRectangle(p, s, o->position);

	int i;
	for(i=0; i < NUM_PORTALS; i++)
	{
		if(portals[i].target && portals[i].open && portals[i].target->open)collidePortal(p, s, &portals[i], &o2);
	}

	vect3Df_s v = vsubf(o2, o->position);

	float gval = vdotf(v, normGravityVector);
	vect3Df_s v2 = vsubf(v, vmulf(normGravityVector, gval));
	float sqd = (v2.x*v2.x)+(v2.y*v2.y)+(v2.z*v2.z)+((gval*gval)/ transY);

	if(sqd < o->sqRadius)
	{
		float sqd = (v2.x*v2.x)+(v2.y*v2.y)+(v2.z*v2.z)+(gval*gval)/transY;
		float d = sqrtf(sqd);
		v = vdivf(vmulf(vect3Df(v.x, v.y, v.z), -(o->radius-d)), d);
		o->position = vaddf(o->position, v);
		return true;
	}
	return false;
}
Пример #3
0
void updatePlatform(platform_s* pf, player_s* p)
{
	if(!pf)return;

	if(pf->ao.active)
	{
		if(pf->touched && p->object.position.y>pf->position.y+p->object.radius)
		{
			p->object.position=vaddf(p->object.position,pf->velocity);
		}else if(pf->oldTouched){
			p->object.speed=vaddf(p->object.speed,pf->velocity);
		}

		if(pf->direction)
		{
			if(vdotf(vsubf(pf->position,pf->destination),pf->velocity)>0)
			{
				if(pf->backandforth)
				{
					pf->velocity=vmulf(pf->velocity,-1);
					pf->direction=false;
				}else{
					pf->velocity=vect3Df(0,0,0);
					pf->ao.active=false;
				}
			}
		}else{
			if(vdotf(vsubf(pf->position,pf->origin),pf->velocity)>0)
			{
				pf->velocity=vmulf(pf->velocity,-1);
				pf->direction=true;
			}
		}

		int i;
		for(i=0; i<NUMOBJECTS; i++)
		{
			if(objects[i].used && intersectOBBPlatform(pf, &objects[i]))
			{
				objects[i].position = vaddf(objects[i].position, pf->velocity);
			}
		}

		pf->position=vaddf(pf->position,pf->velocity);
	}

	if(pf->aar)
	{
		pf->aar->position = vaddf(pf->position, vect3Df(-PLATFORMSIZE, PLATFORMHEIGHT, -PLATFORMSIZE));
	}
	
	pf->ao.oldActive=pf->ao.active;
	pf->oldTouched=pf->touched;
	pf->touched=false;
}
Пример #4
0
void collidePortal(vect3Df_s pr, vect3Df_s sr, portal_s* p, vect3Df_s* point)
{
	vect3Df_s o;
	if(!isPortalInRectangle(pr,sr,p,&o))return;
	vect3Df_s v=vsubf(*point,p->position);

	const vect3Df_s u1=p->plane[0], u2=p->plane[1];

	float xp=vdotf(v,u1)+PORTAL_WIDTH;
	float yp=vdotf(v,u2)+PORTAL_HEIGHT;

	// printf("IN PORTAL ? %f %f\n", xp, yp);
	if(xp<0 || yp<0 || xp>=PORTAL_WIDTH*2 || yp>=PORTAL_HEIGHT*2)return;
	float d1=(xp), d2=(yp), d3=PORTAL_WIDTH*2-(xp), d4=PORTAL_HEIGHT*2-(yp);

	if(d1<d2 && d1<d3 && d1<d4)
	{
		*point=vaddf(*point,vmulf(u1,-d1));
	}else if(d2<d1 && d2<d3 && d2<d4)
	{
		*point=vaddf(*point,vmulf(u2,-d2));
	}else if(d3<d1 && d3<d2 && d3<d4)
	{
		*point=vaddf(*point,vmulf(u1,d3));
	}else{
		*point=vaddf(*point,vmulf(u2,d4));
	}
	// printf("YES %f %f %f %f\n",d1,d2,d3,d4);
}
Пример #5
0
void initPlatform(platform_s* pf, room_s* r, vect3Di_s orig, vect3Di_s dest, u8 id, bool BAF)
{
	if(!pf || !r)return;
	
	// orig=vect3Df(orig.x+r->position.x, orig.y, orig.z+r->position.y);
	// dest=vect3Df(dest.x+r->position.x, dest.y, dest.z+r->position.y);

	pf->id=id;
	pf->origin=convertRectangleVector(orig);
	pf->destination=convertRectangleVector(dest);

	pf->position=pf->origin;
	pf->velocity=vdivf(vnormf(vsubf(pf->destination,pf->origin)),16);
	
	pf->direction=true;
	pf->touched=false;
	pf->backandforth=true;
	
	initActivatableObject(&pf->ao);
	pf->ao.active=true;

	pf->aar=createAAR(vaddf(pf->position, vect3Df(-PLATFORMSIZE, PLATFORMHEIGHT, -PLATFORMSIZE)), vect3Df(2*PLATFORMSIZE, 0.0f, 2*PLATFORMSIZE), vect3Df(0.0f, 1.0f, 0.0f));
	
	// addPlatform(id,vmulf(pf->origin,4),vmulf(pf->destination,4),BAF); //TEMP
	
	pf->used=true;
}
Пример #6
0
bool isPortalInRectangle(vect3Df_s pr, vect3Df_s sr, portal_s* p, vect3Df_s* o)
{
	*o=vsubf(pr,p->position);

	if(!sr.x)return fabs(o->x) < 0.1f;
	else if(!sr.y)return fabs(o->y) < 0.1f;
	else return fabs(o->z) < 0.1f;
}
Пример #7
0
bool collideLineRectangle(rectangle_s* rec, vect3Df_s o, vect3Df_s v, float d, float* kk, vect3Df_s* ip)
{
	if(!rec)return false;
	vect3Df_s n=vect3Df(fabs(rec->normal.x),fabs(rec->normal.y),fabs(rec->normal.z));
	float p1=vdotf(v,n);
	if(fabs(p1)>0.001f)
	{
		vect3Df_s p = convertRectangleVector(rec->position);
		vect3Df_s s = convertRectangleVector(rec->size);
		
		float p2=vdotf(vsubf(p,o),n);

		float k=p2/p1;
		s8 sign=((s.x>0)^(s.y<0)^(s.z>0)^(p1<0))?(-1):(1);
		if(kk)
		{
			*kk=k+sign;
		}
		if(k<0 || k>d){return false;}
		vect3Df_s i=vaddf(o,vmulf(v,k));
		if(ip)*ip=i;
		i=vsubf(i,p);
		
		bool r=true;
		if(s.x)
		{
			if(s.x>0)r=r&&i.x<s.x&&i.x>=0;
			else r=r&&i.x>s.x&&i.x<=0;
		}
		if(s.y)
		{
			if(s.y>0)r=r&&i.y<s.y&&i.y>=0;
			else r=r&&i.y>s.y&&i.y<=0;
		}
		if(s.z)
		{
			if(s.z>0)r=r&&i.z<s.z&&i.z>=0;
			else r=r&&i.z>s.z&&i.z<=0;
		}
		return r;
	}
	return false;
}
Пример #8
0
bool isPointInPortal(portal_s* p, vect3Df_s o, vect3Df_s *v, float* x, float* y, float* z)
{
	if(!x || !y || !z || !v || !p)return false;
	*v=vsubf(o,p->position);
	const vect3Df_s u1=p->plane[0], u2=p->plane[1];
	*x=vdotf(*v,u1);
	*y=vdotf(*v,u2);
	*z=vdotf(*v,p->normal);
	return !(*x<-PORTAL_WIDTH || *y<-PORTAL_HEIGHT || *x>=PORTAL_WIDTH || *y>=PORTAL_HEIGHT || *z>3.0f);
}
Пример #9
0
void updateEnergyBall(room_s* r, energyBall_s* eb)
{
	if(!eb)return;
	
	vect3Df_s l=eb->position;
	
	vect3Df_s ip=l, normal;
	rectangle_s* col=collideGridCell(getCurrentCell(r,eb->position), eb->launcher?eb->launcher->surface:NULL, l, eb->direction, eb->speed, &ip, &normal);
	if(!col)col=collideGridCell(getCurrentCell(r,vaddf(eb->position,vmulf(eb->direction,eb->speed))), eb->launcher?eb->launcher->surface:NULL, l, eb->direction, eb->speed, &ip, &normal);
	if(col)
	{
		// printf("COL COL COL %d\n",col->collides);
		energyDevice_s* ed=isEnergyCatcherSurface(col);
		if(ed && !ed->active)
		{
			//caught
			md2InstanceChangeAnimation(&ed->modelInstance,2,false);
			md2InstanceChangeAnimation(&ed->modelInstance,1,true);
			killEnergyBall(eb);
			if(eb->launcher)eb->launcher->active=false;
			ed->active=true;
			return;
		}

		vect3Df_s v=vect3Df(0,0,0);
		float x, y, z;
		portal_s* portal=NULL;
		int i;
		for(i=0; i<NUM_PORTALS && !portal; i++)
		{
			if(isPointInPortal(&portals[i],ip,&v,&x,&y,&z))portal=&portals[i];
			if(portal && fabs(z)>=0.1f)portal=NULL;
		}
		if(portal && !portal->target)portal=NULL;
		if(!portal)
		{
			eb->position=ip;
			eb->direction=vsubf(eb->direction,vmulf(normal,2*vdotf(eb->direction,normal)));
			eb->position=vaddf(eb->position,vmulf(eb->direction,ENERGYBALLSIZE));
		}else if(portal->target && portal->open && portal->target->open){
			eb->position=vaddf(eb->position,vmulf(eb->direction,eb->speed));
			warpEnergyBall(portal,eb);
			eb->position=vaddf(eb->position,vmulf(eb->direction,eb->speed));
		}

	}else{
		eb->position=vaddf(eb->position,vmulf(eb->direction,eb->speed));
	}
	
	md2InstanceUpdate(&eb->modelInstance);
	
	if(!eb->life)killEnergyBall(eb);
	else eb->life--;
}
Пример #10
0
gridCell_s* getCurrentCell(room_s* r, vect3Df_s o)
{
	if(!r)return NULL;
	
	o=vsubf(o,convertRectangleVector(vect3Di(r->rectangleGridOrigin.x,0,r->rectangleGridOrigin.y)));
	o=vdivf(o,CELLSIZE*TILESIZE*2);

	int x = (int)o.x;
	int z = (int)o.z;
	
	if(x>=0 && x<r->rectangleGridSize.x && z>=0 && z<r->rectangleGridSize.z)return &r->rectangleGrid[x+z*r->rectangleGridSize.x];
	return NULL;
}
Пример #11
0
vect3Df_s getClosestPointRectangle(vect3Df_s rectOrigin, vect3Df_s rectSize, vect3Df_s o)
{
	vect3Df_s u1, u2;
	float x,y,sx,sy;
	
	if(rectSize.x){sx=fabs(rectSize.x);u1=vect3Df((rectSize.x>0)?(1.0f):(-(1.0f)),0,0);}
	else{sx=fabs(rectSize.y);u1=vect3Df(0,(rectSize.y>0)?(1.0f):(-(1.0f)),0);}
	
	if(rectSize.z){sy=fabs(rectSize.z);u2=vect3Df(0,0,(rectSize.z>0)?(1.0f):(-(1.0f)));}
	else{sy=fabs(rectSize.y);u2=vect3Df(0,(rectSize.y>0)?(1.0f):(-(1.0f)),0);}
	
	o=vsubf(o, rectOrigin);
	
	x=vdotf(o, u1);
	y=vdotf(o, u2);
	
	bool r=true;

	r=r && x<sx && x>=0;
	r=r && y<sy && y>=0;
	
	if(r)return vaddf(rectOrigin, vect3Df((x*u1.x)+(y*u2.x), (x*u1.y)+(y*u2.y), (x*u1.z)+(y*u2.z)));
	
	if(x<0)
	{
		x=0;
		if(y<0)y=0;
		else if(y>sy)y=sy;
	}else if(x>sx)
	{
		x=sx;
		if(y<0)y=0;
		else if(y>sy)y=sy;
	}else if(y<0)
	{
		y=0;
		if(x<0)x=0;
		else if(x>sx)y=sx;
	}else if(y>sy)
	{
		y=sy;
		if(x<0)x=0;
		else if(x>sx)x=sx;
	}
	
	return vaddf(rectOrigin, vect3Df((x*u1.x)+(y*u2.x), (x*u1.y)+(y*u2.y), (x*u1.z)+(y*u2.z)));
}
Пример #12
0
void warpPlayer(portal_s* p, player_s* pl)
{
	if(!p || !pl)return;
	camera_s* c = &pl->camera;

	camera_s new_camera = *c;

	if(gravityGunObject)gravityGunObject = NULL; // TEMP : TODO better solution

	float tmp1[4*4], tmp2[4*4];
	transposeMatrix44(p->target->matrix, tmp1);
	new_camera.position = vaddf(p->target->position, warpPortalVector(p, vsubf(c->position, p->position)));
	multMatrix44((float*)new_camera.orientation, p->matrix, tmp2);
	rotateMatrixY(tmp1, M_PI, true);
	multMatrix44(tmp2, tmp1, (float*)new_camera.orientation);

	memcpy(new_camera.modelview, new_camera.orientation, sizeof(mtx44));
	translateMatrix((float*)new_camera.modelview, -new_camera.position.x, -new_camera.position.y, -new_camera.position.z);

	pl->object.position = new_camera.position;
	pl->object.speed = warpPortalVector(p, pl->object.speed);
	*c = new_camera;
}
Пример #13
0
void shootPlayerGun(player_s* p, room_s* r, portal_s* portal)
{
	if(!p)return;
	if(p->gunInstance.currentAnim == PORTALGUN_SHOOT)return;

	md2InstanceChangeAnimation(&p->gunInstance, PORTALGUN_IDLE, false);
	md2InstanceChangeAnimation(&p->gunInstance, PORTALGUN_SHOOT, true);

	vect3Df_s position;
	rectangle_s* rec = collideLineMapClosest(r, NULL, p->camera.position, vect3Df(-p->camera.orientation[2][0], -p->camera.orientation[2][1], -p->camera.orientation[2][2]), 1000.0f, &position, NULL);
	if(rec && rec->portalable)
	{
		portal_s oldPortal = *portal;
		vect3Df_s normal = rec->normal;
		vect3Df_s plane0 = vect3Df(p->camera.orientation[0][0], p->camera.orientation[0][1], p->camera.orientation[0][2]);
		plane0 = vnormf(vsubf(plane0, vmulf(normal, vdotf(normal, plane0))));

		position = vaddf(position, vmulf(normal, -0.05f));

		portal->position = position;

		updatePortalOrientation(portal, plane0, normal);
		isPortalOnWall(r, portal, true);

		portal->draw = true;
		portal->open = true;

		if(isPortalOnWall(r, portal, false))
		{
			ejectPortalOBBs(portal);
			ejectPortalOBBs(portal->target);
		}else{
			*portal = oldPortal;
		}
	}
}
Пример #14
0
void warpEnergyBall(portal_s* p, energyBall_s* eb)
{
	if(!p->target)return;
	eb->position=vaddf(warpPortalVector(p,vsubf(eb->position,p->position)),p->target->position);
	eb->direction=warpPortalVector(p,eb->direction);
}
Пример #15
0
void updateControls(player_s* p)
{
	circlePosition cpad;
	circlePosition cstick;
	
	hidCircleRead(&cpad);
	irrstCstickRead(&cstick);

	rotatePlayer(p, vect3Df((abs(cstick.dy)<5)?0:(-cstick.dy*0.001f), (abs(cstick.dx)<5)?0:(cstick.dx*0.001f), 0.0f));

	if(abs(cpad.dx) > 15 || abs(cpad.dy) > 15) //dead zone
	{
		float factor = 0.0015f;

		if(p->flying)factor*=2;
		else if(!p->object.contact)factor*=0.06f;
		else updatePlayerWalk(p, cpad.dy*factor*2, cpad.dx*factor);

		movePlayer(p, vect3Df(cpad.dx*factor, 0.0f, -cpad.dy*factor));
	}

	if(keysDown()&KEY_ZL)
	{
		// "USE" key
		vect3Df_s u = moveCameraVector(&p->camera, vect3Df(0.0f, 0.0f, -1.0f), true);
		timedButton_s* tb = collideRayTimedButtons(p->object.position, u, TILESIZE_FLOAT*2);
		if(tb)
		{
			activateTimedButton(tb);
		}else{
			OBB_s* o = collideRayBoxes(p->object.position, u, TILESIZE_FLOAT*4);
			if(o)
			{
				gravityGunObject = o;
			}
		}
	}

	if(keysDown()&KEY_ZR)
	{
		// JUMP key
		if(p->object.contact)
		{
			p->object.speed.y += 0.6f;			
		}
	}

	if(gravityGunObject)
	{
		if(!(keysHeld()&KEY_ZL))
		{
			gravityGunObject = NULL;
			md2InstanceChangeAnimation(&p->gunInstance, 0, false);
			md2InstanceChangeAnimation(&p->gunInstance, 1, true);
		}else{
			const vect3Df_s u = moveCameraVector(&p->camera, vect3Df(0.0f, 0.0f, -5.0f), true);
			const vect3Df_s t = vaddf(u, p->object.position);
			const vect3Df_s v = vmulf(vsubf(t, gravityGunObject->position), 1.75f);
			setObbVelocity(gravityGunObject, v);
			md2InstanceChangeAnimation(&p->gunInstance, 2, false);
		}
	}else if(p->gunInstance.currentAnim == 2){
		md2InstanceChangeAnimation(&p->gunInstance, 0, false);
		md2InstanceChangeAnimation(&p->gunInstance, 1, true);
	}
}