Thread: Recast / Detour
View Single Post
Re: Recast / Detour
Old
  (#41)
Neoptolemus
Member
 
Status: Offline
Posts: 93
Join Date: Apr 2012
Default Re: Recast / Detour - 01-09-2015

Quote:
Originally Posted by Immortal_BLG View Post
I think this is because RunPlayerMove receives view angles instead of move angles, which should be oriented same as red line (upwards)...

To traverse ladder:
1) pEdict->v.movetype == MOVETYPE_FLY
2) bot move angles which receives to RunPlayerMove should direct at top of ladder
3) bot forwardSpeed != 0.0
So from this point I think that you have missed something from this...

Sorry for bad english...

Hi Immortal_BLG, thanks for jumping in.

I believe I have met these requirements, however I'll detail the code I'm using to see if you can spot the mistake (don't worry, it's not much code).

My BotThink function looks like this:

Code:
void BotThink(bot_t *pBot)
{
	edict_t *pEdict = pBot->pEdict;


	pEdict->v.flags |= FL_THIRDPARTYBOT;
	pEdict->v.button = 0;

	if (pBot->name[0] == 0)  // name filled in yet?
		strcpy(pBot->name, STRING(pBot->pEdict->v.netname));

	if (pBot->not_started) {
		BotStartGame(pBot);
	}

	// If the bot does not have a path size
	if (pBot->pathSize == 0) {
		// Pick a random point on the navmesh as a destination
		GetRandomPoint(pBot->targetDest);
		// Create the path
		FindPathToPoint(pBot, pBot->targetDest, pBot->currentPath, &pBot->pathSize);
		// Point 0 is usually right at the bot's current position, so jump ahead
		pBot->currentPathPoint = 1;
	}
	else {
		// Determines the bot's forward and side speed
		NextMove(pBot);
	}

	// Updates the bot's view frustum, updates the list of currently visible players and makes the bot look at their current waypoint
	UpdateView(pBot);

	// Adjust msec to command time interval
	byte adjustedmsec = ThrottledMsec(pBot);

	// save the command time
	pBot->f_previous_command_time = gpGlobals->time;

	// This is the ONLY call to pfnRunPlayerMove
	g_engfuncs.pfnRunPlayerMove(pEdict, pEdict->v.v_angle, pBot->y_move_speed,
		pBot->x_move_speed, 0, pEdict->v.button, 0, adjustedmsec);

}
The NextMove function is pretty big as it does a lot of checking of the path and whether the bot is stuck or not, but its ONLY function is to populate pBot->y_move_speed and pBot->x_move_speed. It basically takes the direction the bot needs to move in, uses VecToAngles to work out the orientation in relation to the bot's current rotation and then has an if statement that says "if the bot needs to move diagonally-right then set y_move_speed to maxspeed and x_move_speed to maxspeed", or "if the bot needs to move backwards then set y_move_speed to -maxspeed and x_move_speed to 0" and so on.

The UpdateView function does a bunch of stuff related to the bot's vision, and also makes the bot look its current waypoint:

Code:
void UpdateView(bot_t* pBot) {
	int visibleCount = 0;

	// Updates the view frustum based on the bot's position and v_angle
	UpdateViewFrustrum(pBot);

	memset(pBot->visiblePlayers, 0, sizeof(float) * 32);

	// nextDest is the waypoint the bot is currently moving to
	Vector lookDest = pBot->nextDest.location;

	// Make the bot rotate instantly to look at lookDest
	LookAt(pBot, lookDest);

	// Update list of currently visible players
	for (int i = 0; i < 32; i++) {
		if (clients[i] != NULL) {
			if (CheckPlayerVisiblity(pBot, clients[i])) {
				pBot->visiblePlayers[visibleCount++] = clients[i];
			}
		}
	}

	// Call BotSeePlayer for every visible player each frame. Currently does nothing
	for (int i = 0; i < visibleCount; i++) {
		BotSeePlayer(pBot, pBot->visiblePlayers[i]);
	}
}

and finally the LookAt code is listed here:

Code:
void LookAt(bot_t* pBot, Vector target) {
	edict_t *pEdict = pBot->pEdict;

	Vector viewPos = pBot->pEdict->v.origin + pBot->pEdict->v.view_ofs;
	Vector dir = target - viewPos;
	Vector bot_angles = UTIL_VecToAngles(dir) -pEdict->v.punchangle;

	pEdict->v.idealpitch = bot_angles.x;
	pEdict->v.ideal_yaw = bot_angles.y;
	ClampAngle(pEdict->v.idealpitch);
	ClampAngle(pEdict->v.ideal_yaw);

	pEdict->v.v_angle.x = pEdict->v.idealpitch;
	pEdict->v.v_angle.y = pEdict->v.ideal_yaw;


	pEdict->v.angles.x = pEdict->v.v_angle.x * (1.f / 3.f);
	pEdict->v.angles.y = pEdict->v.v_angle.y;
	pEdict->v.angles.z = pEdict->v.v_angle.z = 0;
}

So every frame, the bot determines which direction it is heading in (i.e. whether it is moving forwards/backwards and strafing left/right) and updates the v_angle and angles to face its current waypoint.

If I view the bot in first person mode as spectator, I can see its looking at the top of the ladder, and I have traces to confirm it is definitely MOVETYPE_FLY, and that it is currently trying to move forwards (the yellow line in the earlier screenshot indicates that y_movement_speed is maxspeed and x_movement_speed is 0 basically).

Not sure what I'm missing here.

Last edited by Neoptolemus; 01-09-2015 at 19:54..
  
Reply With Quote