Ejemplo n.º 1
0
void cCritterViewer::setViewpoint(cVector toviewer, cVector lookatpoint, 
	BOOL trytoseewholeworld)
{
//First do some default setup stuff
	_fieldofviewangle = cCritterViewer::STARTFIELDOFVIEWANGLE;
	setSpeed(0.0);
#ifndef THREEDVECTORS //not THREEDVECTORS means the 2D case.
	_attitude = cMatrix(cVector2(1.0, 0.0), cVector2(0.0, 1.0), _position);
#else //THREEDVECTORS
	_attitude = cMatrix(-cVector::ZAXIS, -cVector::XAXIS, cVector::YAXIS, cVector::ZEROVECTOR);
		/* To get a reasonable default orientation, we arrange the viewer axes so that:  
		viewer x axis = world -z axis, viewer y axis = world -x axis, viewer z axis = world y axis.
		We pick this orientation so that if the viewer moves "forward" (along its tangent vector)
		it moves towards the world.  (We correct the mismatch between the coordinate systems in the 
		cCritterViewer::loadViewMatrix method, which has a long comment about this.)
		 Note that we will adjust _position (fourth column) later in this  call
		 with a moveTo, also we may rotate the _attitude a bit. */
	if (!_perspective) //Ortho view, simply move up.
	{
		_proportionofworldtoshow = 1.0; //Show all of a flat world.
		moveTo(lookatpoint + cCritterViewer::ORTHOZOFFSET * cVector::ZAXIS); // Get above the world
		_maxspeed = _maxspeedstandard = 0.5 * cCritterViewer::ORTHOZOFFSET; //Mimic perspective case.
	}
	else //_perspective
	{
		if (toviewer.isPracticallyZero()) //Not usable, so pick a real direction.
			toviewer = cVector::ZAXIS; //Default is straight up.
		if (trytoseewholeworld) /* Treat toviewer as a direction, and back off in that direction
			enough to see the whole world */
		{
			toviewer.normalize(); //Make it a unit vector.
			_proportionofworldtoshow = cCritterViewer::PROPORTIONOFWORLDTOSHOW;
			//Trying to show all of a world when flying around it, often leaves too big a space around it.
			Real furthestcornerdistance = pgame()->border().maxDistanceToCorner(lookatpoint); 
			Real tanangle = tan(_fieldofviewangle/2.0); /* We work with half the fov in this calculation, 
				the tanangle will be the ratio of visible distance to distance above the world,
				that is, tanangle = dr/dz, where
				Our dr is _proportionofworldtoshow * furthestcornerdistance, and
				our dz is the unknown seeallz height we need to back off to. 
				Swap tangangle and dz to get the next formula. */
			ASSERT(tanangle);
			Real seeallz = _proportionofworldtoshow * furthestcornerdistance / tanangle; 
			moveTo(lookatpoint + seeallz * toviewer);
		}
		else /*Not trytoseewholeworld.  In this case we don't normalize toviewer, instead	
			we treat it as a displacment from the lookatpoint. */
			moveTo(lookatpoint + toviewer);
		lookAt(lookatpoint);
		_maxspeed = _maxspeedstandard = 0.5 * (position()-lookatpoint).magnitude(); 
			/* Define the speed like this so it typically takes two seconds (1/0.5)
			to fly in to lookatpoint. */
		_lastgoodplayeroffset = position() - pgame()->pplayer()->position();
	}
#endif //THREEDVECTORS case
}
Ejemplo n.º 2
0
cRealBox2 cCritterViewer::orthoViewRect() const
{
	Real dx = _proportionofworldtoshow * pgame()->border().xsize();
	Real dy = _proportionofworldtoshow * pgame()->border().ysize();
	ASSERT(dy);
	Real tempaspect = dx/dy;
	if (tempaspect > _aspect) //dy is too small, make it bigger.
		dy = dx / _aspect;
	if (tempaspect < _aspect) //dx is too small, make it bigger.
		dx = _aspect * dy;
	return cRealBox2(dx, dy); 
/* This constructor makes a box centred at the origin.
		We don't center at positon, because once we do
		the loadViewMatrix translation, the origin is effectively at the critter
		location. Earlier I mistakenly had return cRealBox2(_position, dx, dy), 
		and my ortho images were always off by a factor of two. */
}
Ejemplo n.º 3
0
int		load_all_games()
{
	all_games.clear();
	std::string sql = "SELECT `id`,`tech_type`,\
		`dir`,	`exe`,	`update_url`,	`help_url`,\
		`game_name`,	`thumbnail`,	`solution`, `no_embed`, `catalog` \
		FROM `setting_game_list`";
	Query q(*db_);
	if (!q.get_result(sql))
		return error_sql_execute_error;

	while (q.fetch_row())
	{
		gamei_ptr pgame(new game_info);
		pgame->id_ = q.getval();
		pgame->type_ = q.getval();
		COPY_STR(pgame->dir_, q.getstr());
		COPY_STR(pgame->exe_, q.getstr());
		COPY_STR(pgame->update_url_, q.getstr());
		COPY_STR(pgame->help_url_, q.getstr());
		COPY_STR(pgame->game_name_, q.getstr());
		COPY_STR(pgame->thumbnail_, q.getstr());
		COPY_STR(pgame->solution_, q.getstr());
		pgame->no_embed_ = q.getval();
		COPY_STR(pgame->catalog_, q.getstr());
		all_games.insert(std::make_pair(pgame->id_, pgame));
	}
	q.free_result();

	sql = "SELECT `gameid`,	`roomid`,	`room_name`,\
		`room_desc`,	`thumbnail`,	`srvip`,		`srvport`, `require` \
		FROM `setting_game_room_info`";

	if (!q.get_result(sql))
		return error_sql_execute_error;

	while (q.fetch_row())
	{
		game_room_inf inf;
		inf.game_id_ = q.getval();
		inf.room_id_ = q.getval();
		COPY_STR(inf.room_name_, q.getstr());
		COPY_STR(inf.room_desc_, q.getstr());
		COPY_STR(inf.thumbnail_, q.getstr());
		COPY_STR(inf.ip_, q.getstr());
		inf.port_ = q.getval();
		COPY_STR(inf.require_, q.getstr());
		if (all_games.find(inf.game_id_) != all_games.end()){
			all_games[inf.game_id_]->rooms_.push_back(inf);
		}
	}
	q.free_result();

	return error_success;
}
Ejemplo n.º 4
0
cCritterViewer::cCritterViewer(CPopView *pview):
_pownerview(pview), 
_proportionofworldtoshow(cCritterViewer::PROPORTIONOFWORLDTOSHOW),
_aspect(4.0/3.0), //Start with standard screen aspect.
_fieldofviewangle(cCritterViewer::STARTFIELDOFVIEWANGLE),
_trackplayer(FALSE), /* Depending on the game, you might want to start with either FALSE 
	or TRUE for _trackplayer. In general the place where your game can make adjustments 
	to the critterviewer is in the cGame::initializeView method. */
_perspective(FALSE), //Will be reset by setViewer,
_foveaproportion(cCritterViewer::FOVEAPROPORTION)
{
	resetAndMatchMoveBox(pgame());
}
Ejemplo n.º 5
0
void cCritterViewer::update(CPopView *pactiveview, Real dt)
{		
	cCritter::update(pactiveview, dt);
	setZClipPlanes((cRealBox3(pgame()->border())).outerBox(cSprite::MAXPRISMDZ)); 
		/* This call updates _znear and _zfar.  It explicity requires a
		cRealBox3 input, and we do cast of pgame()->border() BEFORE we compute
		the outer box. */
	if (_trackplayer && pgame()->visibleplayer() &&
		 !(plistener() && plistener()->GetRuntimeClass() == RUNTIME_CLASS(cListenerViewerRide)))
		/* The meaning of the visibleplayer() condition is that it doesn't make sense
		to track the player if it's not an onscreen player. The reason for the
		listener condition is that you don't want to stare at the player when
		riding it. */
/*  I should  explain that the goal here is to not bother turning when the player 
is  moving around in the middle of the veiw area, and only to turn when he's near
the edge, but to have the turning when he's near the edge be smoooth.
	The use of the 0.85 foveaproportion parameter means that you react before the player
gets right up to the edge.  The reactproportion factor in lookAtProportional and
moveToProportional is delicate and should probably be adjusted according to the
current player speed relative to the visible window.  The issue is that (a) if I make
reactproportion too small, like 0.01, then the viewer doesn't turn (or move) fast
enough to catch up with the player and keep it in view, but (b) if I make reactpropotion
too big, like 0.5, then the turning or moving is such an abrupt jump that the visual
effect is jerky.  The goal is to do turns that are just big enough to not look jerky,
but to have the turns be big enough so you aren't turning more often than you really
have to.  Another downside of a toosmall reactproportion, by the way, is that it can be
computationally expensive to react. 
	The way we finally solved this is to do a while loop to turn just
far enough, moving just a little at a time so as to not overshoot. */
	{
		if (isVisible(pgame()->pplayer()->position()))// Uses _foveaproportion
			_lastgoodplayeroffset = position() - pgame()->pplayer()->position();
			/*I'm not sure about constantly changing _lastgoodplayeroffset.  On the
			one hand, the offset I set in setViewpoint was a standard good one, so why
			not keep it.  On the other, if I want to move my viewpoint around then I
			do want to be able to get a new value here. It seems ok for now.*/
		else //not visible, so do somehting about it. 
		{
			int loopcount = 0; /* Never have a while loop without a loopcount
				to make sure you don't spin inside the while forever under some
				unexpected situation like at startup. */
			cVector lookat = pgame()->pplayer()->position();
			cVector viewerpos = lookat + _lastgoodplayeroffset;
			if (pgame()->worldShape() == cGame::SHAPE_XSCROLLER)
			{
				lookat = cVector(pgame()->pplayer()->position().x(),
					pgame()->border().midy(), pgame()->pplayer()->position().z());
				viewerpos = cVector(lookat.x(), position().y(), position().z()); 
			}
			if (pgame()->worldShape() == cGame::SHAPE_YSCROLLER)
			{
				lookat = cVector(pgame()->border().midx(),
					pgame()->pplayer()->position().y(), pgame()->pplayer()->position().z());
				viewerpos = cVector(position().x(), lookat.y(), position().z()); 
			} 
			if (_perspective)
				while (!isVisible(lookat) && loopcount < 100)// Uses _foveaproportion
				{
#ifdef TURNMYHEADTOTRACKPLAYER
					lookAtProportional(lookat, cCritterViewer::TURNPROPORTION);
#else //Don't TURNMYHEADTOTRACKPLAYER, instead move with the player.
					moveToProportional(viewerpos, cCritterViewer::TURNPROPORTION);
#endif //TURNMYHEADTOTRACKPLAYER
					loopcount++;
				}
			else //ortho case
				while( !isVisible(lookat) && loopcount < 100)// Uses _foveaproportion
				{
					moveToProportional(lookat +	10.0*pgame()->pplayer()->binormal(),
						cCritterViewer::TURNPROPORTION);
					loopcount++;
				}
		}
	}
//Possibly ride the player. 
	if (plistener()->IsKindOf(RUNTIME_CLASS(cListenerViewerRide)))
	{
		cCritter *pplayer = pgame()->pplayer();
		cVector offset = ((cListenerViewerRide*)plistener())->offset();
		moveTo(pplayer->position() + 
			offset.x()*pplayer->attitudeTangent() +
			offset.y()*pplayer->attitudeNormal() +
			offset.z()*pplayer->attitudeBinormal());
#ifdef COLLIDEVIEWER
		cRealBox skeleton = pplayer->moveBox();
		if (skeleton.zsize()<0.5)
			skeleton.setZRange(0.0, offset.z());
		if (skeleton.ysize()<0.5)
			skeleton.setYRange(0.0, offset.z());
		skeleton.clamp(_position);
		for (int i=0; i<pgame()->pbiota()->count(); i++)
		{
			cCritter* pother = pgame()->pbiota()->GetAt(i);
			if (pother->IsKindOf(RUNTIME_CLASS(cCritterWall)))
				pother->collide(this);
		}
		/* colliding with the wall may have twisted the viwer's orientation,
		so align it once again. */
#endif //COLLIDEVIEWER
		setAttitude(pplayer->attitude()); /* Before we call lookAt, 
			make sure your attitude matches the player.  For one thing,
			you may have gotten twisted around in the COLLIDEVIEWER code. */
		lookAt(pplayer->position() +
			cListenerViewerRide::PLAYERLOOKAHEAD * pplayer->radius() * 
			pplayer->attitudeTangent());
			 /* This has the effect that as offset gets large you change your
			looking direction see right in front of the player. The multiplier
			cCritterViewer::PLAYERLOOKAHEAD is tweaked to work well
			with the default cCritterViewer::OFFSET. */
	}
}
Ejemplo n.º 6
0
void cCritterViewer::setDefaultView()
{
	pgame()->initializeViewpoint(this);
}