Simplified camera code somewhat, added support for final-camera, and made reverse
faster. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@4306 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
f6b4197b7d
commit
de0e948c9a
@ -38,8 +38,6 @@ Camera::Camera(int camera_index, const Kart* kart)
|
|||||||
setupCamera();
|
setupCamera();
|
||||||
m_distance = kart->getKartProperties()->getCameraDistance() * 0.5f;
|
m_distance = kart->getKartProperties()->getCameraDistance() * 0.5f;
|
||||||
m_kart = kart;
|
m_kart = kart;
|
||||||
m_angle_up = 0.0f;
|
|
||||||
m_angle_around = 0.0f;
|
|
||||||
m_ambient_light = RaceManager::getTrack()->getDefaultAmbientColor();
|
m_ambient_light = RaceManager::getTrack()->getDefaultAmbientColor();
|
||||||
|
|
||||||
// TODO: Put these values into a config file
|
// TODO: Put these values into a config file
|
||||||
@ -136,12 +134,49 @@ void Camera::setupCamera()
|
|||||||
} // setupCamera
|
} // setupCamera
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
/** Sets the mode of the camera.
|
||||||
|
* \param mode Mode the camera should be switched to.
|
||||||
|
*/
|
||||||
void Camera::setMode(Mode mode)
|
void Camera::setMode(Mode mode)
|
||||||
{
|
{
|
||||||
m_mode = mode;
|
// If we switch from reverse view, move the camera immediately to the
|
||||||
|
// correct position.
|
||||||
|
if(m_mode==CM_REVERSE && mode==CM_NORMAL)
|
||||||
|
{
|
||||||
|
Vec3 wanted_position, wanted_target;
|
||||||
|
computeNormalCameraPosition(&wanted_position, &wanted_target);
|
||||||
|
m_camera->setPosition(wanted_position.toIrrVector());
|
||||||
|
m_camera->setTarget(wanted_target.toIrrVector());
|
||||||
|
}
|
||||||
|
if(mode==CM_FINAL)
|
||||||
|
{
|
||||||
|
const Track* track = RaceManager::getTrack();
|
||||||
|
core::vector3df wanted_position(track->getCameraPosition().toIrrVector());
|
||||||
|
core::vector3df curr_position(m_camera->getPosition());
|
||||||
|
m_lin_velocity = (wanted_position-curr_position)
|
||||||
|
/ stk_config->m_final_camera_time;
|
||||||
|
float distance = (m_kart->getXYZ() - curr_position).length();
|
||||||
|
core::vector3df hpr = track->getCameraHPR().toIrrHPR();
|
||||||
|
core::vector3df target = hpr.rotationToDirection(core::vector3df(0, 0, 1)*distance)
|
||||||
|
+ wanted_position;
|
||||||
|
core::vector3df curr_hpr = m_camera->getRotation();
|
||||||
|
m_target_velocity = (target - m_camera->getTarget())
|
||||||
|
/ stk_config->m_final_camera_time;
|
||||||
|
m_final_time = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the camera is set to final mode but there is no camera
|
||||||
|
// end position defined, ignore this request and leave the camera
|
||||||
|
// in normal mode.
|
||||||
|
if(mode!=CM_FINAL || RaceManager::getTrack()->hasFinalCamera())
|
||||||
|
{
|
||||||
|
m_mode = mode;
|
||||||
|
}
|
||||||
} // setMode
|
} // setMode
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
/** Returns the current mode of the camera.
|
||||||
|
*/
|
||||||
Camera::Mode Camera::getMode()
|
Camera::Mode Camera::getMode()
|
||||||
{
|
{
|
||||||
return m_mode;
|
return m_mode;
|
||||||
@ -154,9 +189,6 @@ Camera::Mode Camera::getMode()
|
|||||||
void Camera::reset()
|
void Camera::reset()
|
||||||
{
|
{
|
||||||
setMode(CM_NORMAL);
|
setMode(CM_NORMAL);
|
||||||
// m_position, m_target etc. are set when the worlds has computed the right starting
|
|
||||||
// position of all karts and calls setInitialTransform for each camera.
|
|
||||||
|
|
||||||
} // reset
|
} // reset
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -165,107 +197,30 @@ void Camera::reset()
|
|||||||
*/
|
*/
|
||||||
void Camera::setInitialTransform()
|
void Camera::setInitialTransform()
|
||||||
{
|
{
|
||||||
m_target = m_kart->getXYZ();
|
m_camera->setPosition( m_kart->getXYZ().toIrrVector() - core::vector3df(0, -25, 50) );
|
||||||
m_position = m_target - Vec3(0,50,-25);
|
} // setInitialTransform
|
||||||
m_temp_position = m_position;
|
|
||||||
m_temp_target = m_target;
|
|
||||||
} // updateKartPosition
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void Camera::update(float dt)
|
/** 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, const Vec3 &wanted_position,
|
||||||
|
const Vec3 &wanted_target)
|
||||||
{
|
{
|
||||||
const Track* track=RaceManager::getTrack();
|
|
||||||
float steering;
|
|
||||||
float dampened_steer;
|
|
||||||
|
|
||||||
// Each case should set m_target and m_position according to what is needed for that mode.
|
|
||||||
// Yes, there is a lot of duplicate code but it is (IMHO) much easier to follow this way.
|
|
||||||
switch(m_mode)
|
|
||||||
{
|
|
||||||
case CM_NORMAL:
|
|
||||||
// This first line moves the camera around behind the kart, pointing it
|
|
||||||
// towards where the kart is turning (and turning even more while skidding).
|
|
||||||
steering = m_kart->getSteerPercent() * (1.0f + (m_kart->getSkidding() - 1.0f)/2.3f ); // dampen skidding effect
|
|
||||||
dampened_steer = fabsf(steering) * steering; // quadratically to dampen small variations (but keep sign)
|
|
||||||
m_angle_around = m_kart->getHPR().getX() + m_rotation_range * dampened_steer * 0.5f;
|
|
||||||
m_angle_up = m_kart->getHPR().getY() - 30.0f*DEGREE_TO_RAD;
|
|
||||||
|
|
||||||
m_target = m_kart->getXYZ();
|
|
||||||
m_target.setZ(m_target.getZ()+0.75f);
|
|
||||||
|
|
||||||
m_position.setX( sin(m_angle_around));
|
|
||||||
m_position.setY(-cos(m_angle_around));
|
|
||||||
m_position.setZ(-sin(m_angle_up));
|
|
||||||
m_position *= m_distance;
|
|
||||||
m_position += m_target;
|
|
||||||
|
|
||||||
break;
|
|
||||||
case CM_REVERSE: // Same as CM_NORMAL except it looks backwards
|
|
||||||
m_angle_around = m_kart->getHPR().getX() - m_rotation_range * m_kart->getSteerPercent() * m_kart->getSkidding();
|
|
||||||
m_angle_up = m_kart->getHPR().getY() + 30.0f*DEGREE_TO_RAD;
|
|
||||||
|
|
||||||
m_target = m_kart->getXYZ();
|
|
||||||
m_target.setZ(m_target.getZ()+0.75f);
|
|
||||||
|
|
||||||
m_position.setX(-sin(m_angle_around));
|
|
||||||
m_position.setY( cos(m_angle_around));
|
|
||||||
m_position.setZ( sin(m_angle_up));
|
|
||||||
m_position *= m_distance * 2.0f;
|
|
||||||
m_position += m_target;
|
|
||||||
|
|
||||||
break;
|
|
||||||
case CM_CLOSEUP: // Lower to the ground and closer to the kart
|
|
||||||
m_angle_around = m_kart->getHPR().getX() + m_rotation_range * m_kart->getSteerPercent() * m_kart->getSkidding();
|
|
||||||
m_angle_up = m_kart->getHPR().getY() - 20.0f*DEGREE_TO_RAD;
|
|
||||||
|
|
||||||
m_target = m_kart->getXYZ();
|
|
||||||
m_target.setZ(m_target.getZ()+0.75f);
|
|
||||||
|
|
||||||
m_position.setX( sin(m_angle_around));
|
|
||||||
m_position.setY(-cos(m_angle_around));
|
|
||||||
m_position.setZ(-sin(m_angle_up));
|
|
||||||
m_position *= m_distance * 0.5f;
|
|
||||||
m_position += m_target;
|
|
||||||
|
|
||||||
break;
|
|
||||||
case CM_LEADER_MODE: // Follows the leader kart, higher off of the ground, further from the kart,
|
|
||||||
// and turns in the opposite direction from the kart for a nice effect. :)
|
|
||||||
m_angle_around = RaceManager::getKart(0)->getHPR().getX();
|
|
||||||
m_angle_up = RaceManager::getKart(0)->getHPR().getY() + 40.0f*DEGREE_TO_RAD;
|
|
||||||
|
|
||||||
m_target = RaceManager::getKart(0)->getXYZ();
|
|
||||||
|
|
||||||
m_position.setX(sin(m_angle_around));
|
|
||||||
m_position.setY(cos(m_angle_around));
|
|
||||||
m_position.setZ(sin(m_angle_up));
|
|
||||||
m_position *= m_distance * 2.0f;
|
|
||||||
m_position += m_target;
|
|
||||||
|
|
||||||
break;
|
|
||||||
case CM_FINAL:
|
|
||||||
if(!track->hasFinalCamera())
|
|
||||||
{
|
|
||||||
m_mode = CM_NORMAL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
m_position = track->getCameraPosition();
|
|
||||||
m_target.setX(-sin( track->getCameraHPR().getX() ) );
|
|
||||||
m_target.setY( cos( track->getCameraHPR().getX() ) );
|
|
||||||
m_target.setZ( sin( track->getCameraHPR().getY() ) );
|
|
||||||
m_target *= 10.0f;
|
|
||||||
m_target += m_position;
|
|
||||||
break;
|
|
||||||
case CM_SIMPLE_REPLAY:
|
|
||||||
// TODO: Implement
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Smoothly interpolate towards the position and target
|
// Smoothly interpolate towards the position and target
|
||||||
m_temp_target += ((m_target - m_temp_target) * m_target_speed) * dt;
|
core::vector3df current_position = m_camera->getPosition();
|
||||||
m_temp_position += ((m_position - m_temp_position) * m_position_speed) * dt;
|
core::vector3df current_target = m_camera->getTarget();
|
||||||
|
current_target += ((wanted_target.toIrrVector() - current_target ) * m_target_speed ) * dt;
|
||||||
|
current_position += ((wanted_position.toIrrVector() - current_position) * m_position_speed) * dt;
|
||||||
|
m_camera->setPosition(current_position);
|
||||||
|
m_camera->setTarget(current_target);
|
||||||
|
|
||||||
|
if(race_manager->getNumLocalPlayers() < 2)
|
||||||
|
sound_manager->positionListener(current_position,
|
||||||
|
current_target - current_position);
|
||||||
|
|
||||||
m_camera->setPosition(m_temp_position.toIrrVector());
|
|
||||||
m_camera->setTarget(m_temp_target.toIrrVector());
|
|
||||||
// The following settings give a debug camera which shows the track from
|
// The following settings give a debug camera which shows the track from
|
||||||
// high above the kart straight down.
|
// high above the kart straight down.
|
||||||
#undef DEBUG_CAMERA
|
#undef DEBUG_CAMERA
|
||||||
@ -275,9 +230,120 @@ void Camera::update(float dt)
|
|||||||
xyz.Y = xyz.Y+30;
|
xyz.Y = xyz.Y+30;
|
||||||
m_camera->setPosition(xyz);
|
m_camera->setPosition(xyz);
|
||||||
#endif
|
#endif
|
||||||
|
} // smoothMoveCamera
|
||||||
|
|
||||||
if(race_manager->getNumLocalPlayers() < 2)
|
//-----------------------------------------------------------------------------
|
||||||
sound_manager->positionListener(m_temp_position, m_temp_target - m_temp_position);
|
/** Computes the wanted camera position and target for normal camera mode.
|
||||||
|
* Besides being used in update(dt), it is also used when switching the
|
||||||
|
* camera from reverse mode to normal mode - in which case we don't want
|
||||||
|
* to have a smooth camera.
|
||||||
|
* \param wanted_position The position the camera should be.
|
||||||
|
* \param wanted_target The target position the camera should target.
|
||||||
|
*/
|
||||||
|
void Camera::computeNormalCameraPosition(Vec3 *wanted_position,
|
||||||
|
Vec3 *wanted_target)
|
||||||
|
{
|
||||||
|
*wanted_target = m_kart->getXYZ();
|
||||||
|
wanted_target->setZ(wanted_target->getZ()+ 0.75f);
|
||||||
|
// This first line moves the camera around behind the kart, pointing it
|
||||||
|
// towards where the kart is turning (and turning even more while skidding).
|
||||||
|
float steering = m_kart->getSteerPercent() * (1.0f + (m_kart->getSkidding() - 1.0f)/2.3f ); // dampen skidding effect
|
||||||
|
float dampened_steer = fabsf(steering) * steering; // quadratically to dampen small variations (but keep sign)
|
||||||
|
float angle_around = m_kart->getHPR().getX() + m_rotation_range * dampened_steer * 0.5f;
|
||||||
|
float angle_up = m_kart->getHPR().getY() - 30.0f*DEGREE_TO_RAD;
|
||||||
|
wanted_position->setX( sin(angle_around));
|
||||||
|
wanted_position->setY(-cos(angle_around));
|
||||||
|
wanted_position->setZ(-sin(angle_up) );
|
||||||
|
*wanted_position *= m_distance;
|
||||||
|
*wanted_position += *wanted_target;
|
||||||
|
} // computeNormalCameraPosition
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/** Called once per time frame to move the camera to the right position.
|
||||||
|
* \param dt Time step.
|
||||||
|
*/
|
||||||
|
void Camera::update(float dt)
|
||||||
|
{
|
||||||
|
printf("cam: %f %f %f\n",
|
||||||
|
m_camera->getRotation().X,
|
||||||
|
m_camera->getRotation().Y,
|
||||||
|
m_camera->getRotation().Z);
|
||||||
|
|
||||||
|
Vec3 wanted_position;
|
||||||
|
Vec3 wanted_target = m_kart->getXYZ();
|
||||||
|
|
||||||
|
// Each case should set wanted_position and wanted_target according to
|
||||||
|
// what is needed for that mode. Yes, there is a lot of duplicate code
|
||||||
|
// but it is (IMHO) much easier to follow this way.
|
||||||
|
switch(m_mode)
|
||||||
|
{
|
||||||
|
case CM_NORMAL:
|
||||||
|
{
|
||||||
|
computeNormalCameraPosition(&wanted_position, &wanted_target);
|
||||||
|
smoothMoveCamera(dt, wanted_position, wanted_target);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CM_REVERSE: // Same as CM_NORMAL except it looks backwards
|
||||||
|
{
|
||||||
|
wanted_target.setZ(wanted_target.getZ()+ 0.75f);
|
||||||
|
float angle_around = m_kart->getHPR().getX() - m_rotation_range * m_kart->getSteerPercent() * m_kart->getSkidding();
|
||||||
|
float angle_up = m_kart->getHPR().getY() + 30.0f*DEGREE_TO_RAD;
|
||||||
|
wanted_position.setX(-sin(angle_around));
|
||||||
|
wanted_position.setY( cos(angle_around));
|
||||||
|
wanted_position.setZ( sin(angle_up) );
|
||||||
|
wanted_position *= m_distance * 2.0f;
|
||||||
|
wanted_position += wanted_target;
|
||||||
|
smoothMoveCamera(dt, wanted_position, wanted_target);
|
||||||
|
m_camera->setPosition(wanted_position.toIrrVector());
|
||||||
|
m_camera->setTarget(wanted_target.toIrrVector());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CM_CLOSEUP: // Lower to the ground and closer to the kart
|
||||||
|
{
|
||||||
|
wanted_target.setZ(wanted_target.getZ()+0.75f);
|
||||||
|
float angle_around = m_kart->getHPR().getX() + m_rotation_range * m_kart->getSteerPercent() * m_kart->getSkidding();
|
||||||
|
float angle_up = m_kart->getHPR().getY() - 20.0f*DEGREE_TO_RAD;
|
||||||
|
wanted_position.setX( sin(angle_around));
|
||||||
|
wanted_position.setY(-cos(angle_around));
|
||||||
|
wanted_position.setZ(-sin(angle_up) );
|
||||||
|
wanted_position *= m_distance * 0.5f;
|
||||||
|
wanted_position += wanted_target;
|
||||||
|
smoothMoveCamera(dt, wanted_position, wanted_target);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CM_LEADER_MODE:
|
||||||
|
{
|
||||||
|
wanted_target = RaceManager::getKart(0)->getXYZ().toIrrVector();
|
||||||
|
// Follows the leader kart, higher off of the ground, further from the kart,
|
||||||
|
// and turns in the opposite direction from the kart for a nice effect. :)
|
||||||
|
float angle_around = RaceManager::getKart(0)->getHPR().getX();
|
||||||
|
float angle_up = RaceManager::getKart(0)->getHPR().getY() + 40.0f*DEGREE_TO_RAD;
|
||||||
|
wanted_position.setX(sin(angle_around));
|
||||||
|
wanted_position.setY(cos(angle_around));
|
||||||
|
wanted_position.setZ(sin(angle_up) );
|
||||||
|
wanted_position *= m_distance * 2.0f;
|
||||||
|
wanted_position += wanted_target;
|
||||||
|
smoothMoveCamera(dt, wanted_position, wanted_target);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CM_FINAL:
|
||||||
|
{
|
||||||
|
m_final_time +=dt;
|
||||||
|
if(m_final_time < stk_config->m_final_camera_time)
|
||||||
|
{
|
||||||
|
const Track* track=RaceManager::getTrack();
|
||||||
|
core::vector3df new_pos = m_camera->getPosition()+m_lin_velocity*dt;
|
||||||
|
m_camera->setPosition(new_pos);
|
||||||
|
core::vector3df new_target = m_camera->getTarget()+m_target_velocity*dt;
|
||||||
|
m_camera->setTarget(new_target);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CM_SIMPLE_REPLAY:
|
||||||
|
// TODO: Implement
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
} // update
|
} // update
|
||||||
|
|
||||||
|
@ -51,35 +51,16 @@ private:
|
|||||||
* attached to. */
|
* attached to. */
|
||||||
unsigned int m_index;
|
unsigned int m_index;
|
||||||
|
|
||||||
/** The ultimate position which the camera wants to obtain. */
|
|
||||||
Vec3 m_position;
|
|
||||||
|
|
||||||
/** The position the camera currently has. */
|
|
||||||
Vec3 m_temp_position;
|
|
||||||
|
|
||||||
/** The ultimate target which the camera wants to obtain. */
|
|
||||||
Vec3 m_target;
|
|
||||||
|
|
||||||
/** The target the camera currently has. */
|
|
||||||
Vec3 m_temp_target;
|
|
||||||
|
|
||||||
/** Current ambient light for this camera. */
|
/** Current ambient light for this camera. */
|
||||||
video::SColor m_ambient_light;
|
video::SColor m_ambient_light;
|
||||||
|
|
||||||
/** Distance between the camera and the kart. */
|
/** Distance between the camera and the kart. */
|
||||||
float m_distance;
|
float m_distance;
|
||||||
|
|
||||||
/** Angle between the ground and the camera (with the kart as the
|
|
||||||
* vertex of the angle). */
|
|
||||||
float m_angle_up;
|
|
||||||
|
|
||||||
/** Angle around the kart (should actually match the rotation of the kart). */
|
|
||||||
float m_angle_around;
|
|
||||||
|
|
||||||
/** The speed at which the camera changes position. */
|
/** The speed at which the camera changes position. */
|
||||||
float m_position_speed;
|
float m_position_speed;
|
||||||
|
|
||||||
/** The speed at which the camera changes targets. */
|
/** The speed at which the camera target changes position. */
|
||||||
float m_target_speed;
|
float m_target_speed;
|
||||||
|
|
||||||
/** Factor of the effects of steering in camera aim. */
|
/** Factor of the effects of steering in camera aim. */
|
||||||
@ -100,8 +81,21 @@ private:
|
|||||||
/** Aspect ratio for camera. */
|
/** Aspect ratio for camera. */
|
||||||
float m_aspect;
|
float m_aspect;
|
||||||
|
|
||||||
void setupCamera();
|
/** Linear velocity of the camera, only used for end camera. */
|
||||||
|
core::vector3df m_lin_velocity;
|
||||||
|
|
||||||
|
/** Velocity of the target of the camera, only used for end camera. */
|
||||||
|
core::vector3df m_target_velocity;
|
||||||
|
|
||||||
|
/** Counts the time for the end camera only, to indicate when
|
||||||
|
* the end camera should stop moving. */
|
||||||
|
float m_final_time;
|
||||||
|
|
||||||
|
void setupCamera();
|
||||||
|
void smoothMoveCamera(float dt, const Vec3 &wanted_position,
|
||||||
|
const Vec3 &wanted_target);
|
||||||
|
void computeNormalCameraPosition(Vec3 *wanted_position,
|
||||||
|
Vec3 *wanted_target);
|
||||||
public:
|
public:
|
||||||
Camera (int camera_index, const Kart* kart);
|
Camera (int camera_index, const Kart* kart);
|
||||||
~Camera ();
|
~Camera ();
|
||||||
|
@ -278,9 +278,9 @@ void PlayerKart::update(float dt)
|
|||||||
if (m_powerup.getType()==POWERUP_NOTHING)
|
if (m_powerup.getType()==POWERUP_NOTHING)
|
||||||
Kart::beep();
|
Kart::beep();
|
||||||
}
|
}
|
||||||
|
if(m_camera->getMode()!=Camera::CM_FINAL)
|
||||||
m_camera->setMode(m_controls.m_look_back ? Camera::CM_REVERSE
|
m_camera->setMode(m_controls.m_look_back ? Camera::CM_REVERSE
|
||||||
: Camera::CM_NORMAL);
|
: Camera::CM_NORMAL);
|
||||||
|
|
||||||
// We can't restrict rescue to fulfil isOnGround() (which would be more like
|
// We can't restrict rescue to fulfil isOnGround() (which would be more like
|
||||||
// MK), since e.g. in the City track it is possible for the kart to end
|
// MK), since e.g. in the City track it is possible for the kart to end
|
||||||
|
@ -237,14 +237,6 @@ void Track::loadTrackInfo(const std::string &filename)
|
|||||||
|
|
||||||
if(m_groups.size()==0)
|
if(m_groups.size()==0)
|
||||||
m_groups.push_back("standard");
|
m_groups.push_back("standard");
|
||||||
// if both camera position and rotation are defined,
|
|
||||||
// set the flag that the track has final camera position
|
|
||||||
m_has_final_camera = root->get("camera-final-position",
|
|
||||||
&m_camera_final_position)!=1;
|
|
||||||
m_has_final_camera &= root->get("camera-final-hpr",
|
|
||||||
&m_camera_final_hpr) !=1;
|
|
||||||
m_camera_final_hpr.degreeToRad();
|
|
||||||
|
|
||||||
const XMLNode *xml_node = root->getNode("curves");
|
const XMLNode *xml_node = root->getNode("curves");
|
||||||
if(xml_node)
|
if(xml_node)
|
||||||
loadCurves(*xml_node);
|
loadCurves(*xml_node);
|
||||||
@ -614,9 +606,13 @@ void Track::createWater(const XMLNode &node)
|
|||||||
* animations, items, ... It is called from world during initialisation.
|
* animations, items, ... It is called from world during initialisation.
|
||||||
* Track is the first model to be loaded, so at this stage the root scene node
|
* Track is the first model to be loaded, so at this stage the root scene node
|
||||||
* is empty.
|
* is empty.
|
||||||
|
* \param mode_id Which of the modes of a track to use. This determines which
|
||||||
|
* scene, quad, and graph file to load.
|
||||||
*/
|
*/
|
||||||
void Track::loadTrackModel(unsigned int mode_id)
|
void Track::loadTrackModel(unsigned int mode_id)
|
||||||
{
|
{
|
||||||
|
m_has_final_camera = false;
|
||||||
|
m_is_arena = false;
|
||||||
item_manager->setStyle();
|
item_manager->setStyle();
|
||||||
|
|
||||||
// Load the graph only now: this function is called from world, after
|
// Load the graph only now: this function is called from world, after
|
||||||
@ -740,6 +736,10 @@ void Track::loadTrackModel(unsigned int mode_id)
|
|||||||
{
|
{
|
||||||
handleSky(*node, path);
|
handleSky(*node, path);
|
||||||
}
|
}
|
||||||
|
else if (name=="camera")
|
||||||
|
{
|
||||||
|
handleCamera(*node);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Warning: element '%s' not found.\n",
|
fprintf(stderr, "Warning: element '%s' not found.\n",
|
||||||
@ -862,8 +862,26 @@ void Track::handleSky(const XMLNode &xml_node, const std::string &filename)
|
|||||||
} // handleSky
|
} // handleSky
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
/** Reads the final camera position.
|
||||||
|
* \param root The XML node with the camera node.
|
||||||
|
*/
|
||||||
|
void Track::handleCamera(const XMLNode &root)
|
||||||
|
{
|
||||||
|
m_has_final_camera = true;
|
||||||
|
root.get("final-position", &m_camera_final_position);
|
||||||
|
root.get("final-hpr", &m_camera_final_hpr );
|
||||||
|
m_camera_final_hpr.degreeToRad();
|
||||||
|
} // handleCamera
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/** Handle creation and placement of an item.
|
||||||
|
* \param xyz The position of the item.
|
||||||
|
* \param type The item type.
|
||||||
|
* \param need_height True if the item Z position should be determined based on
|
||||||
|
* the track topology.
|
||||||
|
*/
|
||||||
void Track::itemCommand(const Vec3 &xyz, Item::ItemType type,
|
void Track::itemCommand(const Vec3 &xyz, Item::ItemType type,
|
||||||
int bNeedHeight)
|
int need_height)
|
||||||
{
|
{
|
||||||
// Some modes (e.g. time trial) don't have any bonus boxes
|
// Some modes (e.g. time trial) don't have any bonus boxes
|
||||||
if(type==Item::ITEM_BONUS_BOX &&
|
if(type==Item::ITEM_BONUS_BOX &&
|
||||||
@ -872,7 +890,7 @@ void Track::itemCommand(const Vec3 &xyz, Item::ItemType type,
|
|||||||
|
|
||||||
Vec3 loc(xyz);
|
Vec3 loc(xyz);
|
||||||
// if only 2d coordinates are given, let the item fall from very high
|
// if only 2d coordinates are given, let the item fall from very high
|
||||||
if(bNeedHeight)
|
if(need_height)
|
||||||
{
|
{
|
||||||
loc.setZ(1000);
|
loc.setZ(1000);
|
||||||
loc.setZ(getTerrainHeight(loc));
|
loc.setZ(getTerrainHeight(loc));
|
||||||
|
@ -73,14 +73,20 @@ private:
|
|||||||
scene::ILightSceneNode *m_sun;
|
scene::ILightSceneNode *m_sun;
|
||||||
TriangleMesh* m_track_mesh;
|
TriangleMesh* m_track_mesh;
|
||||||
TriangleMesh* m_non_collision_mesh;
|
TriangleMesh* m_non_collision_mesh;
|
||||||
|
/** True if the track/scene has a final camera position. */
|
||||||
bool m_has_final_camera;
|
bool m_has_final_camera;
|
||||||
|
/** The final xyz coordinates of the camera. */
|
||||||
Vec3 m_camera_final_position;
|
Vec3 m_camera_final_position;
|
||||||
|
/** The final hpr rotation of the camera. */
|
||||||
Vec3 m_camera_final_hpr;
|
Vec3 m_camera_final_hpr;
|
||||||
/** Minimum coordinates of this track. */
|
/** Minimum coordinates of this track. */
|
||||||
Vec3 m_aabb_min;
|
Vec3 m_aabb_min;
|
||||||
/** Maximum coordinates of this track. */
|
/** Maximum coordinates of this track. */
|
||||||
Vec3 m_aabb_max;
|
Vec3 m_aabb_max;
|
||||||
|
/** True if this track is an arena. */
|
||||||
bool m_is_arena;
|
bool m_is_arena;
|
||||||
|
/** The version of this track. A certain STK version will only support
|
||||||
|
* certain track versions. */
|
||||||
int m_version;
|
int m_version;
|
||||||
|
|
||||||
/** The graph used to connect the quads. */
|
/** The graph used to connect the quads. */
|
||||||
@ -166,6 +172,7 @@ private:
|
|||||||
void loadCurves(const XMLNode &node);
|
void loadCurves(const XMLNode &node);
|
||||||
void handleAnimatedTextures(scene::ISceneNode *node, const XMLNode &xml);
|
void handleAnimatedTextures(scene::ISceneNode *node, const XMLNode &xml);
|
||||||
void handleSky(const XMLNode &root, const std::string &filename);
|
void handleSky(const XMLNode &root, const std::string &filename);
|
||||||
|
void handleCamera(const XMLNode &root);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user