/* Updates the viewpoint according to the object being tracked */ BOOL camTrackCamera( void ) { PROPULSION_STATS *psPropStats; DROID *psDroid; BOOL bFlying; bFlying = false; /* Most importantly - see if the target we're tracking is dead! */ if(trackingCamera.target->died) { setFindNewTarget(); return(false); } /* Cancel tracking if it's no longer selected. This may not be desirable? */ if(trackingCamera.target->type == OBJ_DROID) { // if(!trackingCamera.target->selected) // { // return(false); // } } /* Update the acceleration,velocity and position of the camera for movement */ updateCameraAcceleration(CAM_ALL); updateCameraVelocity(CAM_ALL); updateCameraPosition(CAM_ALL); /* Update the acceleration,velocity and rotation of the camera for rotation */ /* You can track roll as well (z axis) but it makes you ill and looks like a flight sim, so for now just pitch and orientation */ if(trackingCamera.target->type == OBJ_DROID) { psDroid = (DROID*)trackingCamera.target; psPropStats = asPropulsionStats + psDroid->asBits[COMP_PROPULSION].nStat; if (psPropStats->propulsionType == PROPULSION_TYPE_LIFT) { bFlying = true; } } /* bIsBuilding = false; if(trackingCamera.target->type == OBJ_DROID) { psDroid= (DROID*)trackingCamera.target; if(DroidIsBuilding(psDroid)) { bIsBuilding = true; } } */ if(bRadarAllign || trackingCamera.target->type == OBJ_DROID) { if(bFlying) { updateCameraRotationAcceleration(CAM_ALL); } else { updateCameraRotationAcceleration(CAM_X_AND_Y); } } if(bFlying) { updateCameraRotationVelocity(CAM_ALL); updateCameraRotationPosition(CAM_ALL); } /* else if(bIsBuilding) { updateCameraRotationVelocity(CAM_X_ONLY); } */ else { updateCameraRotationVelocity(CAM_X_AND_Y); updateCameraRotationPosition(CAM_X_AND_Y); } /* Record the old positions for comparison */ oldPosition.x = player.p.x; oldPosition.y = player.p.y; oldPosition.z = player.p.z; /* Update the position that's now stored in trackingCamera.position */ player.p.x = trackingCamera.position.x; player.p.y = trackingCamera.position.y; player.p.z = trackingCamera.position.z; /* Record the old positions for comparison */ oldRotation.x = player.r.x; oldRotation.y = player.r.y; oldRotation.z = player.r.z; /* Update the rotations that're now stored in trackingCamera.rotation */ player.r.x = trackingCamera.rotation.x; /*if(!bIsBuilding)*/ player.r.y = trackingCamera.rotation.y; player.r.z = trackingCamera.rotation.z; /* There's a minimum for this - especially when John's VTOL code lets them land vertically on cliffs */ if(player.r.x>DEG(360+MAX_PLAYER_X_ANGLE)) { player.r.x = DEG(360+MAX_PLAYER_X_ANGLE); } /* if(bIsBuilding) { player.r.y+=DEG(1); } */ /* Clip the position to the edge of the map */ CheckScrollLimits(); /* Store away our last update as acceleration and velocity are all fn()/dt */ trackingCamera.lastUpdate = gameTime2; if(bFullInfo) { flushConsoleMessages(); if(trackingCamera.target->type == OBJ_DROID) { printDroidInfo((DROID*)trackingCamera.target); } } /* Switch off if we're jumping to a new location and we've got there */ if(getRadarTrackingStatus()) { /* This will ensure we come to a rest and terminate the tracking routine once we're close enough */ if(getRotationMagnitude()<10000) { if(getPositionMagnitude() < 60) { setWarCamActive(false); } } } return(true); }
/* Updates the viewpoint according to the object being tracked */ static bool camTrackCamera() { PROPULSION_STATS *psPropStats; DROID *psDroid; bool bFlying = false; /* Most importantly - see if the target we're tracking is dead! */ if(trackingCamera.target->died) { return(false); } /* Update the acceleration,velocity and position of the camera for movement */ updateCameraAcceleration(CAM_ALL); updateCameraVelocity(CAM_ALL); updateCameraPosition(CAM_ALL); /* Update the acceleration,velocity and rotation of the camera for rotation */ /* You can track roll as well (z axis) but it makes you ill and looks like a flight sim, so for now just pitch and orientation */ if(trackingCamera.target->type == OBJ_DROID) { psDroid = (DROID*)trackingCamera.target; psPropStats = asPropulsionStats + psDroid->asBits[COMP_PROPULSION].nStat; if (psPropStats->propulsionType == PROPULSION_TYPE_LIFT) { bFlying = true; } } if(bRadarAllign || trackingCamera.target->type == OBJ_DROID) { if(bFlying) { updateCameraRotationAcceleration(CAM_ALL); } else { updateCameraRotationAcceleration(CAM_X_AND_Y); } } if(bFlying) { updateCameraRotationVelocity(CAM_ALL); updateCameraRotationPosition(CAM_ALL); } else { updateCameraRotationVelocity(CAM_X_AND_Y); updateCameraRotationPosition(CAM_X_AND_Y); } /* Update the position that's now stored in trackingCamera.position */ player.p.x = trackingCamera.position.x; player.p.y = trackingCamera.position.y; player.p.z = trackingCamera.position.z; /* Update the rotations that're now stored in trackingCamera.rotation */ player.r.x = trackingCamera.rotation.x; player.r.y = trackingCamera.rotation.y; player.r.z = trackingCamera.rotation.z; /* There's a minimum for this - especially when John's VTOL code lets them land vertically on cliffs */ if(player.r.x>DEG(360+MAX_PLAYER_X_ANGLE)) { player.r.x = DEG(360+MAX_PLAYER_X_ANGLE); } /* Clip the position to the edge of the map */ CheckScrollLimits(); /* Store away our last update as acceleration and velocity are all fn()/dt */ trackingCamera.lastUpdate = realTime; if(bFullInfo) { flushConsoleMessages(); if(trackingCamera.target->type == OBJ_DROID) { printDroidInfo((DROID*)trackingCamera.target); } } /* Switch off if we're jumping to a new location and we've got there */ if(getRadarTrackingStatus()) { /* This will ensure we come to a rest and terminate the tracking routine once we're close enough */ if (trackingCamera.velocity*trackingCamera.velocity + trackingCamera.acceleration*trackingCamera.acceleration < 1.f && trackingCamera.rotVel*trackingCamera.rotVel + trackingCamera.rotAccel*trackingCamera.rotAccel < 1.f) { setWarCamActive(false); } } return(true); }
bool Visualization::update() { if (!m_initialized) { printf("Visualization has not been yet initialized."); return false; } // Compute the time since last update (in seconds). Uint32 time = SDL_GetTicks(); float dt = (time - m_lastTickCount) / 1000.0f; m_lastTickCount = time; bool singleSimulationStep = false; bool scrollForward = false; bool scrollBackward = false; int mscroll = 0; SDL_Event event; while (SDL_PollEvent(&event)) { switch (event.type) { case SDL_KEYDOWN: // Handle any key presses here. if (event.key.keysym.sym == SDLK_ESCAPE) //Escape. { m_stopRequested = true; } else if (event.key.keysym.sym == SDLK_SPACE) { m_paused = !m_paused; } else if (event.key.keysym.sym == SDLK_TAB) { singleSimulationStep = true; } else if (event.key.keysym.sym == SDLK_r) { float pos[3] = {-15, 0, 15}; m_crowd->pushAgentPosition(0, pos); } else if (event.key.keysym.sym == SDLK_KP7) { float pos[3] = {-19, 0, -19}; dtVnormalize(pos); dtVscale(pos, pos, 2.f); dtCrowdAgent ag; m_crowd->fetchAgent(ag, 0); dtVcopy(ag.velocity, pos); m_crowd->pushAgent(ag); } else if (event.key.keysym.sym == SDLK_KP9) { float pos[] = {19, 0, -19}; dtVnormalize(pos); dtVscale(pos, pos, 2.f); dtCrowdAgent ag; m_crowd->fetchAgent(ag, 0); dtVcopy(ag.velocity, pos); m_crowd->pushAgent(ag); } else if (event.key.keysym.sym == SDLK_KP3) { float pos[3] = {19, 0, 19}; dtVnormalize(pos); dtVscale(pos, pos, 2.f); dtCrowdAgent ag; m_crowd->fetchAgent(ag, 0); dtVcopy(ag.velocity, pos); m_crowd->pushAgent(ag); } else if (event.key.keysym.sym == SDLK_KP1) { float pos[3] = {-19, 0, 19}; dtVnormalize(pos); dtVscale(pos, pos, 2.f); dtCrowdAgent ag; m_crowd->fetchAgent(ag, 0); dtVcopy(ag.velocity, pos); m_crowd->pushAgent(ag); } else if (event.key.keysym.sym == SDLK_KP5) { float pos[3] = {0, 0, 0}; dtVnormalize(pos); dtVscale(pos, pos, 2.f); dtCrowdAgent ag; m_crowd->fetchAgent(ag, 0); dtVcopy(ag.velocity, pos); m_crowd->pushAgent(ag); } break; case SDL_MOUSEBUTTONDOWN: if (event.button.button == SDL_BUTTON_RIGHT) { // Rotate view m_rotating = true; m_initialMousePosition[0] = m_mousePosition[0]; m_initialMousePosition[1] = m_mousePosition[1]; m_intialCameraOrientation[0] = m_cameraOrientation[0]; m_intialCameraOrientation[1] = m_cameraOrientation[1]; m_intialCameraOrientation[2] = m_cameraOrientation[2]; } else if (event.button.button == SDL_BUTTON_WHEELUP) { scrollForward = true; } else if (event.button.button == SDL_BUTTON_WHEELDOWN) { scrollBackward = true; } break; case SDL_MOUSEBUTTONUP: if (event.button.button == SDL_BUTTON_RIGHT) { m_rotating = false; } else if (event.button.button == SDL_BUTTON_LEFT) { float pickedPosition[3]; int index = 0; pick(pickedPosition, &index); } break; case SDL_MOUSEMOTION: m_mousePosition[0] = event.motion.x; m_mousePosition[1] = m_winHeight-1 - event.motion.y; if (m_rotating) { int dx = m_mousePosition[0] - m_initialMousePosition[0]; int dy = m_mousePosition[1] - m_initialMousePosition[1]; m_cameraOrientation[0] = m_intialCameraOrientation[0] - dy*0.25f; m_cameraOrientation[1] = m_intialCameraOrientation[1] + dx*0.25f; } break; case SDL_QUIT: m_stopRequested = true; break; default: break; } } unsigned char mbut = 0; if (SDL_GetMouseState(0,0) & SDL_BUTTON_LMASK) mbut |= IMGUI_MBUT_LEFT; if (SDL_GetMouseState(0,0) & SDL_BUTTON_RMASK) mbut |= IMGUI_MBUT_RIGHT; // Update the camera velocity from keyboard state. Uint8* keystate = SDL_GetKeyState(NULL); #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable:4800) #endif updateCameraVelocity( dt, keystate[SDLK_w] || keystate[SDLK_UP] || scrollForward, keystate[SDLK_s] || keystate[SDLK_DOWN] || scrollBackward, keystate[SDLK_a] || keystate[SDLK_LEFT], keystate[SDLK_d] || keystate[SDLK_RIGHT], SDL_GetModState() & KMOD_SHIFT); #ifdef _MSC_VER #pragma warning(pop) #endif //Update the camera position updateCameraPosition(dt); //Update the crowd if (m_crowd) { if (singleSimulationStep) { m_paused = true; m_debugInfo->startUpdate(); m_crowd->update(m_crowdDt); m_debugInfo->endUpdate(m_crowdDt); m_crowdAvailableDt = 0.f; } else if (!m_paused) { m_crowdAvailableDt += dt; while(m_crowdAvailableDt > m_crowdDt) { m_debugInfo->startUpdate(); m_crowd->update(m_crowdDt); m_debugInfo->endUpdate(m_crowdDt); m_crowdAvailableDt -= m_crowdDt; } } else { m_crowdAvailableDt = 0.f; } } // Set rendering context glViewport(0, 0, m_winWidth, m_winHeight); glClearColor(0.3f, 0.3f, 0.32f, 1.0f); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDisable(GL_TEXTURE_2D); // Render 3D glEnable(GL_DEPTH_TEST); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(50.0f, (float)m_winWidth/(float)m_winHeight, m_zNear, m_zFar); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glRotatef(m_cameraOrientation[0],1,0,0); glRotatef(m_cameraOrientation[1],0,1,0); glRotatef(m_cameraOrientation[2],0,0,1); glTranslatef(-m_cameraPosition[0], -m_cameraPosition[1], -m_cameraPosition[2]); // Extract OpenGL view properties glGetDoublev(GL_PROJECTION_MATRIX, m_projection); glGetDoublev(GL_MODELVIEW_MATRIX, m_modelView); glGetIntegerv(GL_VIEWPORT, m_viewport); renderScene(); renderCrowd(); // Render 2D Overlay glDisable(GL_DEPTH_TEST); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0, m_winWidth, 0, m_winHeight); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); imguiBeginFrame(m_mousePosition[0], m_mousePosition[1], mbut,mscroll); renderDebugInfoOverlay(); imguiEndFrame(); imguiRenderGLDraw(); glEnable(GL_DEPTH_TEST); SDL_GL_SwapBuffers(); return true; }