/** Actually sets the camera based on the given parameter. * \param above_kart How far above the camera should aim at. * \param cam_angle Angle above the kart plane for the camera. * \param sideway Sideway movement of the camera. * \param distance Distance from kart. */ void Camera::positionCamera(float dt, float above_kart, float cam_angle, float side_way, float distance, float smoothing) { Vec3 wanted_position; Vec3 wanted_target = m_kart->getXYZ(); if(UserConfigParams::m_camera_debug==2) wanted_target.setY(m_kart->getVehicle()->getWheelInfo(2).m_raycastInfo.m_contactPointWS.getY()); else wanted_target.setY(wanted_target.getY()+above_kart); float tan_up = tan(cam_angle); Vec3 relative_position(side_way, fabsf(distance)*tan_up+above_kart, distance); btTransform t=m_kart->getTrans(); if(stk_config->m_camera_follow_skid && m_kart->getSkidding()->getVisualSkidRotation()!=0) { // If the camera should follow the graphical skid, add the // visual rotation to the relative vector: btQuaternion q(m_kart->getSkidding()->getVisualSkidRotation(), 0, 0); t.setBasis(t.getBasis() * btMatrix3x3(q)); } wanted_position = t(relative_position); if (smoothing) { smoothMoveCamera(dt, wanted_position, wanted_target); } else { if (m_mode!=CM_FALLING) m_camera->setPosition(wanted_position.toIrrVector()); m_camera->setTarget(wanted_target.toIrrVector()); if (race_manager->getNumLocalPlayers() < 2) { sfx_manager->positionListener(m_camera->getPosition(), wanted_target - m_camera->getPosition()); } } Kart *kart = dynamic_cast<Kart*>(m_kart); if (kart && !kart->isFlying()) { // Rotate the up vector (0,1,0) by the rotation ... which is just column 1 Vec3 up = m_kart->getTrans().getBasis().getColumn(1); float f = 0.04f; // weight for new up vector to reduce shaking f = 0; m_camera->setUpVector(f * up.toIrrVector() + (1.0f - f) * m_camera->getUpVector()); } // kart && !flying else m_camera->setUpVector(core::vector3df(0, 1, 0)); } // positionCamera
/** Actually sets the camera based on the given parameter. * \param above_kart How far above the camera should aim at. * \param cam_angle Angle above the kart plane for the camera. * \param sideway Sideway movement of the camera. * \param distance Distance from kart. */ void CameraDebug::positionCamera(float dt, float above_kart, float cam_angle, float side_way, float distance ) { Vec3 wanted_position; Vec3 wanted_target = m_kart->getXYZ(); if(m_default_debug_Type==CM_DEBUG_GROUND) { const btWheelInfo &w = m_kart->getVehicle()->getWheelInfo(2); wanted_target.setY(w.m_raycastInfo.m_contactPointWS.getY()); } else wanted_target.setY(wanted_target.getY()+above_kart); float tan_up = tan(cam_angle); Vec3 relative_position(side_way, fabsf(distance)*tan_up+above_kart, distance); btTransform t=m_kart->getTrans(); if(stk_config->m_camera_follow_skid && m_kart->getSkidding()->getVisualSkidRotation()!=0) { // If the camera should follow the graphical skid, add the // visual rotation to the relative vector: btQuaternion q(m_kart->getSkidding()->getVisualSkidRotation(), 0, 0); t.setBasis(t.getBasis() * btMatrix3x3(q)); } if (m_default_debug_Type == CM_DEBUG_GROUND) { wanted_position = t(relative_position); // Make sure that the Y position is a the same height as the wheel. wanted_position.setY(wanted_target.getY()); } else wanted_position = t(relative_position); if (getMode() != CM_FALLING) m_camera->setPosition(wanted_position.toIrrVector()); m_camera->setTarget(wanted_target.toIrrVector()); Kart *kart = dynamic_cast<Kart*>(m_kart); if (kart && !kart->isFlying()) { // Rotate the up vector (0,1,0) by the rotation ... which is just column 1 Vec3 up = m_kart->getTrans().getBasis().getColumn(1); float f = 0.04f; // weight for new up vector to reduce shaking m_camera->setUpVector( f * up.toIrrVector() + (1.0f - f) * m_camera->getUpVector()); } // kart && !flying else m_camera->setUpVector(core::vector3df(0, 1, 0)); } // positionCamera
/** Moves the camera smoothly from the current camera position (and target) * to the new position and target. * \param wanted_position The position the camera wanted to reach. * \param wanted_target The point the camera wants to point to. */ void Camera::smoothMoveCamera(float dt) { Kart *kart = dynamic_cast<Kart*>(m_kart); if (kart->isFlying()) { Vec3 vec3 = m_kart->getXYZ() + Vec3(sin(m_kart->getHeading()) * -4.0f, 0.5f, cos(m_kart->getHeading()) * -4.0f); m_camera->setTarget(m_kart->getXYZ().toIrrVector()); m_camera->setPosition(vec3.toIrrVector()); return; } core::vector3df current_position = m_camera->getPosition(); // Smoothly interpolate towards the position and target const KartProperties *kp = m_kart->getKartProperties(); float max_increase_with_zipper = kp->getZipperMaxSpeedIncrease(); float max_speed_without_zipper = kp->getMaxSpeed(); float current_speed = m_kart->getSpeed(); const Skidding *ks = m_kart->getSkidding(); float skid_factor = ks->getVisualSkidRotation(); float skid_angle = asin(skid_factor); float ratio = (current_speed - max_speed_without_zipper) / max_increase_with_zipper; ratio = ratio > -0.12f ? ratio : -0.12f; float camera_distance = -3 * (0.5f + ratio);// distance of camera from kart in x and z plane if (camera_distance > -2.0f) camera_distance = -2.0f; Vec3 camera_offset(camera_distance * sin(skid_angle / 2), 1.1f * (1 + ratio / 2), camera_distance * cos(skid_angle / 2));// defines how far camera should be from player kart. Vec3 m_kart_camera_position_with_offset = m_kart->getTrans()(camera_offset); core::vector3df current_target = m_kart->getXYZ().toIrrVector();// next target current_target.Y += 0.5f; core::vector3df wanted_position = m_kart_camera_position_with_offset.toIrrVector();// new required position of camera if ((m_kart->getSpeed() > 5 ) || (m_kart->getSpeed() < 0 )) { current_position += ((wanted_position - current_position) * dt * (m_kart->getSpeed()>0 ? m_kart->getSpeed()/3 + 1.0f : -1.5f * m_kart->getSpeed() + 2.0f)); } else { current_position += (wanted_position - current_position) * dt * 5; } if(m_mode!=CM_FALLING) m_camera->setPosition(current_position); m_camera->setTarget(current_target);//set new target assert(!isnan(m_camera->getPosition().X)); assert(!isnan(m_camera->getPosition().Y)); assert(!isnan(m_camera->getPosition().Z)); if (race_manager->getNumLocalPlayers() < 2) { sfx_manager->positionListener(current_position, current_target - current_position); } } // smoothMoveCamera