Merged the switch_coordinate_system branch with trunk. This means
that now all coordinate systems are y up, z forwards - including the file format. For now only one track has been ported, the rest will follow shortly. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@4985 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
commit
d50bd9dbe6
@ -2,11 +2,32 @@
|
|||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
|
|
||||||
<config>
|
<config>
|
||||||
|
<!-- Minimum and maximum kart versions that can be used by this binary.
|
||||||
|
Older version will be ignored. -->
|
||||||
|
<kart-version min="2" max="2"/>
|
||||||
|
<!-- Minimum and maxium track versions that be be read by this binary.
|
||||||
|
Older versions will be ignored. -->
|
||||||
|
<track-version min="2" max="2"/>
|
||||||
|
<!-- Maximum number of karts to be used at the same time. This limit
|
||||||
|
can easily be increased, but some tracks might not have valid start
|
||||||
|
positions for those additional karts. -->
|
||||||
|
<max-karts value="8"/>
|
||||||
|
<!--
|
||||||
|
<Scores =point="10 8 6 5 4 3 2 1"''>
|
||||||
|
grid-order="1"
|
||||||
|
title-music="main_theme.music"
|
||||||
|
mainmenu-background="st_title_screen.rgb st_title_screen2.rgb"
|
||||||
|
menu-background="menu_background.rgb menu_background2.rgb"
|
||||||
|
max-history="10000"
|
||||||
|
max-skidmarks="100"
|
||||||
|
skid-fadeout-time="60"
|
||||||
|
near-ground="2"
|
||||||
|
delay-finish-time="4"
|
||||||
|
music-credit-time="10"
|
||||||
|
final-camera-time="1.5"
|
||||||
|
-->
|
||||||
<!-- STK PARAMETERS
|
<!-- STK PARAMETERS
|
||||||
|
|
||||||
min-kart-version and max-kart-version are the the minimum and maximum .kart
|
|
||||||
files supported. Older/newer files are ignored.
|
|
||||||
|
|
||||||
min-track-version and max-track-version are the minimum and maximum .track
|
min-track-version and max-track-version are the minimum and maximum .track
|
||||||
files supported, older/newer files are ignored.
|
files supported, older/newer files are ignored.
|
||||||
@ -34,10 +55,10 @@ final-camera-time is the time for the final camera to reach it's destination
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<stk-parameters
|
<stk-parameters
|
||||||
min-kart-version="1"
|
min-kart-version="2"
|
||||||
max-kart-version="1"
|
max-kart-version="2"
|
||||||
min-track-version="1"
|
min-track-version="2"
|
||||||
max-track-version="1"
|
max-track-version="2"
|
||||||
max-karts="8"
|
max-karts="8"
|
||||||
scores="10 8 6 5 4 3 2 1"
|
scores="10 8 6 5 4 3 2 1"
|
||||||
grid-order="1"
|
grid-order="1"
|
||||||
@ -158,7 +179,7 @@ a hit kart receives depends on the orientation - if a kart is pushed
|
|||||||
in the direction it is driving, it will be more (no friction from tires),
|
in the direction it is driving, it will be more (no friction from tires),
|
||||||
while when pushed to the side, hardly anything happens.
|
while when pushed to the side, hardly anything happens.
|
||||||
|
|
||||||
z-rescue-offset is the z-axis offset when kart is being put back on track
|
vert-rescue-offset is the z-axis offset when kart is being put back on track
|
||||||
after being rescued, it's a fraction of kart height
|
after being rescued, it's a fraction of kart height
|
||||||
|
|
||||||
gear-switch-ratio defines at what ratio of the maximum speed what gear is
|
gear-switch-ratio defines at what ratio of the maximum speed what gear is
|
||||||
@ -189,7 +210,7 @@ rubber-band-duration is the duration a rubber band acts.
|
|||||||
time-full-steer-ai="0.1"
|
time-full-steer-ai="0.1"
|
||||||
corn-f ="4"
|
corn-f ="4"
|
||||||
corn-r="4"
|
corn-r="4"
|
||||||
gravity-center-shift="0 0 0.3"
|
gravity-center-shift="0 0.3 0"
|
||||||
nitro-power-boost="3"
|
nitro-power-boost="3"
|
||||||
|
|
||||||
skid-increase="1.05"
|
skid-increase="1.05"
|
||||||
@ -223,11 +244,11 @@ rubber-band-duration is the duration a rubber band acts.
|
|||||||
suspension-travel-cm="19"
|
suspension-travel-cm="19"
|
||||||
jump-velocity="3.0"
|
jump-velocity="3.0"
|
||||||
collision-side-impulse="0"
|
collision-side-impulse="0"
|
||||||
z-rescue-offset="0.0"
|
vert-rescue-offset="0.0"
|
||||||
wheel-front-right="0.38 0.6 0"
|
wheel-front-right="0.38 0 0.6"
|
||||||
wheel-front-left="-0.38 0.6 0"
|
wheel-front-left="-0.38 0 0.6"
|
||||||
wheel-rear-right="0.38 -0.6 0"
|
wheel-rear-right="0.38 0 -0.6"
|
||||||
wheel-rear-left="-0.38 -0.6 0"
|
wheel-rear-left="-0.38 0 -0.6"
|
||||||
gear-switch-ratio="0.25 0.7 1.0"
|
gear-switch-ratio="0.25 0.7 1.0"
|
||||||
gear-power-increase="2.2 1.7 1.3"
|
gear-power-increase="2.2 1.7 1.3"
|
||||||
upright-tolerance="0.2"
|
upright-tolerance="0.2"
|
||||||
|
@ -25,3 +25,28 @@ cp $LOCATION/src/BulletDynamics/Vehicle/*.cpp src/BulletDynamics/Vehicl
|
|||||||
cp $LOCATION/Demos/OpenGL/*.h Demos/OpenGL
|
cp $LOCATION/Demos/OpenGL/*.h Demos/OpenGL
|
||||||
cp $LOCATION/Demos/OpenGL/*.cpp Demos/OpenGL
|
cp $LOCATION/Demos/OpenGL/*.cpp Demos/OpenGL
|
||||||
|
|
||||||
|
echo "REMEMBER to patch this new bullet version:"
|
||||||
|
echo "1) btDiscreteDynamicsWorld.cpp:
|
||||||
|
--- BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp (revision 4812)
|
||||||
|
+++ BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp (working copy)
|
||||||
|
@@ -262,7 +262,12 @@
|
||||||
|
for (int v=0;v<m_vehicles[i]->getNumWheels();v++)
|
||||||
|
{
|
||||||
|
//synchronize the wheels with the (interpolated) chassis worldtransform
|
||||||
|
+ // updateWheelTransform resets m_isInContact to false. Since
|
||||||
|
+ // this field is needed in STK, we save it here and restore
|
||||||
|
+ // its value after the call to updateWheelTransform.
|
||||||
|
+ bool contact = m_vehicles[i]->getWheelInfo(v).m_raycastInfo.m_isInContact;
|
||||||
|
m_vehicles[i]->updateWheelTransform(v,true);
|
||||||
|
+ m_vehicles[i]->getWheelInfo(v).m_raycastInfo.m_isInContact = contact;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"
|
||||||
|
|
||||||
|
echo "2) btRaycastVehicle.cpp
|
||||||
|
From:
|
||||||
|
rel_pos[2] *= wheelInfo.m_rollInfluence;
|
||||||
|
to
|
||||||
|
rel_pos[m_indexUpAxis] *= wheelInfo.m_rollInfluence;
|
||||||
|
"
|
||||||
|
@ -262,7 +262,12 @@ void btDiscreteDynamicsWorld::synchronizeMotionStates()
|
|||||||
for (int v=0;v<m_vehicles[i]->getNumWheels();v++)
|
for (int v=0;v<m_vehicles[i]->getNumWheels();v++)
|
||||||
{
|
{
|
||||||
//synchronize the wheels with the (interpolated) chassis worldtransform
|
//synchronize the wheels with the (interpolated) chassis worldtransform
|
||||||
|
// updateWheelTransform resets m_isInContact to false. Since
|
||||||
|
// this field is needed in STK, we save it here and restore
|
||||||
|
// its value after the call to updateWheelTransform.
|
||||||
|
bool contact = m_vehicles[i]->getWheelInfo(v).m_raycastInfo.m_isInContact;
|
||||||
m_vehicles[i]->updateWheelTransform(v,true);
|
m_vehicles[i]->updateWheelTransform(v,true);
|
||||||
|
m_vehicles[i]->getWheelInfo(v).m_raycastInfo.m_isInContact = contact;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -690,7 +690,7 @@ void btRaycastVehicle::updateFriction(btScalar timeStep)
|
|||||||
|
|
||||||
btVector3 sideImp = m_axle[wheel] * m_sideImpulse[wheel];
|
btVector3 sideImp = m_axle[wheel] * m_sideImpulse[wheel];
|
||||||
|
|
||||||
rel_pos[2] *= wheelInfo.m_rollInfluence;
|
rel_pos[m_indexUpAxis] *= wheelInfo.m_rollInfluence;
|
||||||
m_chassisBody->applyImpulse(sideImp,rel_pos);
|
m_chassisBody->applyImpulse(sideImp,rel_pos);
|
||||||
|
|
||||||
//apply friction impulse on the ground
|
//apply friction impulse on the ground
|
||||||
|
@ -232,7 +232,6 @@ namespace UserConfigParams
|
|||||||
// ---- Debug
|
// ---- Debug
|
||||||
PARAM_PREFIX BoolUserConfigParam m_gamepad_debug PARAM_DEFAULT( BoolUserConfigParam(false, "gamepad_debug") );
|
PARAM_PREFIX BoolUserConfigParam m_gamepad_debug PARAM_DEFAULT( BoolUserConfigParam(false, "gamepad_debug") );
|
||||||
PARAM_PREFIX IntUserConfigParam m_track_debug PARAM_DEFAULT( IntUserConfigParam(false, "track_debug") );
|
PARAM_PREFIX IntUserConfigParam m_track_debug PARAM_DEFAULT( IntUserConfigParam(false, "track_debug") );
|
||||||
PARAM_PREFIX bool m_bullet_debug PARAM_DEFAULT( false );
|
|
||||||
PARAM_PREFIX bool m_print_kart_sizes PARAM_DEFAULT( false );
|
PARAM_PREFIX bool m_print_kart_sizes PARAM_DEFAULT( false );
|
||||||
|
|
||||||
// ---- Networking
|
// ---- Networking
|
||||||
|
@ -20,6 +20,8 @@
|
|||||||
|
|
||||||
#include "graphics/camera.hpp"
|
#include "graphics/camera.hpp"
|
||||||
|
|
||||||
|
#include "math.h"
|
||||||
|
|
||||||
#include "audio/sound_manager.hpp"
|
#include "audio/sound_manager.hpp"
|
||||||
#include "config/user_config.hpp"
|
#include "config/user_config.hpp"
|
||||||
#include "graphics/irr_driver.hpp"
|
#include "graphics/irr_driver.hpp"
|
||||||
@ -48,7 +50,7 @@ Camera::Camera(int camera_index, const Kart* kart)
|
|||||||
m_position_speed = 8.0f;
|
m_position_speed = 8.0f;
|
||||||
m_target_speed = 10.0f;
|
m_target_speed = 10.0f;
|
||||||
m_rotation_range = 0.4f;
|
m_rotation_range = 0.4f;
|
||||||
|
reset();
|
||||||
} // Camera
|
} // Camera
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@ -169,6 +171,7 @@ Camera::Mode Camera::getMode()
|
|||||||
void Camera::reset()
|
void Camera::reset()
|
||||||
{
|
{
|
||||||
setMode(CM_NORMAL);
|
setMode(CM_NORMAL);
|
||||||
|
setInitialTransform();
|
||||||
} // reset
|
} // reset
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -177,7 +180,9 @@ void Camera::reset()
|
|||||||
*/
|
*/
|
||||||
void Camera::setInitialTransform()
|
void Camera::setInitialTransform()
|
||||||
{
|
{
|
||||||
m_camera->setPosition( m_kart->getXYZ().toIrrVector() - core::vector3df(0, -25, 50) );
|
m_camera->setPosition( m_kart->getXYZ().toIrrVector()
|
||||||
|
+ core::vector3df(0, 25, -50) );
|
||||||
|
m_camera->setRotation(core::vector3df(0, 0, 0));
|
||||||
m_camera->setRotation( core::vector3df( 0.0f, 0.0f, 0.0f ) );
|
m_camera->setRotation( core::vector3df( 0.0f, 0.0f, 0.0f ) );
|
||||||
} // setInitialTransform
|
} // setInitialTransform
|
||||||
|
|
||||||
@ -206,7 +211,7 @@ void Camera::smoothMoveCamera(float dt, const Vec3 &wanted_position,
|
|||||||
// high above the kart straight down.
|
// high above the kart straight down.
|
||||||
#undef DEBUG_CAMERA
|
#undef DEBUG_CAMERA
|
||||||
#ifdef DEBUG_CAMERA
|
#ifdef DEBUG_CAMERA
|
||||||
core::vector3df xyz = RaceManager::getKart(0)->getXYZ().toIrrVector();
|
core::vector3df xyz = m_kart->getXYZ().toIrrVector();
|
||||||
m_camera->setTarget(xyz);
|
m_camera->setTarget(xyz);
|
||||||
xyz.Y = xyz.Y+30;
|
xyz.Y = xyz.Y+30;
|
||||||
m_camera->setPosition(xyz);
|
m_camera->setPosition(xyz);
|
||||||
@ -225,16 +230,21 @@ void Camera::computeNormalCameraPosition(Vec3 *wanted_position,
|
|||||||
Vec3 *wanted_target)
|
Vec3 *wanted_target)
|
||||||
{
|
{
|
||||||
*wanted_target = m_kart->getXYZ();
|
*wanted_target = m_kart->getXYZ();
|
||||||
wanted_target->setZ(wanted_target->getZ()+ 0.75f);
|
wanted_target->setY(wanted_target->getY()+ 0.75f);
|
||||||
// This first line moves the camera around behind the kart, pointing it
|
// This first line moves the camera around behind the kart, pointing it
|
||||||
// towards where the kart is turning (and turning even more while skidding).
|
// 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
|
// The skidding effect is dampened.
|
||||||
float dampened_steer = fabsf(steering) * steering; // quadratically to dampen small variations (but keep sign)
|
float steering = m_kart->getSteerPercent()
|
||||||
float angle_around = m_kart->getHPR().getX() + m_rotation_range * dampened_steer * 0.5f;
|
* (1.0f + (m_kart->getSkidding() - 1.0f)/2.3f );
|
||||||
float angle_up = m_kart->getHPR().getY() - 30.0f*DEGREE_TO_RAD;
|
// quadratically to dampen small variations (but keep sign)
|
||||||
wanted_position->setX( sin(angle_around));
|
float dampened_steer = fabsf(steering) * steering;
|
||||||
wanted_position->setY(-cos(angle_around));
|
float angle_around = m_kart->getHeading()
|
||||||
wanted_position->setZ(-sin(angle_up) );
|
+ m_rotation_range * dampened_steer * 0.5f;
|
||||||
|
float angle_up = m_kart->getPitch() + 30.0f*DEGREE_TO_RAD;
|
||||||
|
|
||||||
|
wanted_position->setX(-sin(angle_around));
|
||||||
|
wanted_position->setY( sin(angle_up) );
|
||||||
|
wanted_position->setZ(-cos(angle_around));
|
||||||
*wanted_position *= m_distance;
|
*wanted_position *= m_distance;
|
||||||
*wanted_position += *wanted_target;
|
*wanted_position += *wanted_target;
|
||||||
} // computeNormalCameraPosition
|
} // computeNormalCameraPosition
|
||||||
@ -247,7 +257,6 @@ void Camera::update(float dt)
|
|||||||
{
|
{
|
||||||
Vec3 wanted_position;
|
Vec3 wanted_position;
|
||||||
Vec3 wanted_target = m_kart->getXYZ();
|
Vec3 wanted_target = m_kart->getXYZ();
|
||||||
|
|
||||||
// Each case should set wanted_position and wanted_target according to
|
// 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
|
// what is needed for that mode. Yes, there is a lot of duplicate code
|
||||||
// but it is (IMHO) much easier to follow this way.
|
// but it is (IMHO) much easier to follow this way.
|
||||||
@ -261,12 +270,14 @@ void Camera::update(float dt)
|
|||||||
}
|
}
|
||||||
case CM_REVERSE: // Same as CM_NORMAL except it looks backwards
|
case CM_REVERSE: // Same as CM_NORMAL except it looks backwards
|
||||||
{
|
{
|
||||||
wanted_target.setZ(wanted_target.getZ()+ 0.75f);
|
wanted_target.setY(wanted_target.getY()+ 0.75f);
|
||||||
float angle_around = m_kart->getHPR().getX() - m_rotation_range * m_kart->getSteerPercent() * m_kart->getSkidding();
|
float angle_around = m_kart->getHeading()
|
||||||
float angle_up = m_kart->getHPR().getY() + 30.0f*DEGREE_TO_RAD;
|
+ m_rotation_range * m_kart->getSteerPercent()
|
||||||
wanted_position.setX(-sin(angle_around));
|
* m_kart->getSkidding();
|
||||||
wanted_position.setY( cos(angle_around));
|
float angle_up = m_kart->getPitch() + 30.0f*DEGREE_TO_RAD;
|
||||||
wanted_position.setZ( sin(angle_up) );
|
wanted_position.setX( sin(angle_around));
|
||||||
|
wanted_position.setY( sin(angle_up) );
|
||||||
|
wanted_position.setZ( cos(angle_around));
|
||||||
wanted_position *= m_distance * 2.0f;
|
wanted_position *= m_distance * 2.0f;
|
||||||
wanted_position += wanted_target;
|
wanted_position += wanted_target;
|
||||||
smoothMoveCamera(dt, wanted_position, wanted_target);
|
smoothMoveCamera(dt, wanted_position, wanted_target);
|
||||||
@ -276,12 +287,15 @@ void Camera::update(float dt)
|
|||||||
}
|
}
|
||||||
case CM_CLOSEUP: // Lower to the ground and closer to the kart
|
case CM_CLOSEUP: // Lower to the ground and closer to the kart
|
||||||
{
|
{
|
||||||
wanted_target.setZ(wanted_target.getZ()+0.75f);
|
wanted_target.setY(wanted_target.getY()+0.75f);
|
||||||
float angle_around = m_kart->getHPR().getX() + m_rotation_range * m_kart->getSteerPercent() * m_kart->getSkidding();
|
float angle_around = m_kart->getHeading()
|
||||||
float angle_up = m_kart->getHPR().getY() - 20.0f*DEGREE_TO_RAD;
|
+ m_rotation_range * m_kart->getSteerPercent()
|
||||||
|
* m_kart->getSkidding();
|
||||||
|
float angle_up = m_kart->getPitch()
|
||||||
|
- 20.0f*DEGREE_TO_RAD;
|
||||||
wanted_position.setX( sin(angle_around));
|
wanted_position.setX( sin(angle_around));
|
||||||
wanted_position.setY(-cos(angle_around));
|
wanted_position.setY(-sin(angle_up) );
|
||||||
wanted_position.setZ(-sin(angle_up) );
|
wanted_position.setZ(-cos(angle_around));
|
||||||
wanted_position *= m_distance * 0.5f;
|
wanted_position *= m_distance * 0.5f;
|
||||||
wanted_position += wanted_target;
|
wanted_position += wanted_target;
|
||||||
smoothMoveCamera(dt, wanted_position, wanted_target);
|
smoothMoveCamera(dt, wanted_position, wanted_target);
|
||||||
@ -294,11 +308,11 @@ void Camera::update(float dt)
|
|||||||
wanted_target = kart->getXYZ().toIrrVector();
|
wanted_target = kart->getXYZ().toIrrVector();
|
||||||
// Follows the leader kart, higher off of the ground, further from the kart,
|
// 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. :)
|
// and turns in the opposite direction from the kart for a nice effect. :)
|
||||||
float angle_around = kart->getHPR().getX();
|
float angle_around = kart->getHeading();
|
||||||
float angle_up = kart->getHPR().getY() + 40.0f*DEGREE_TO_RAD;
|
float angle_up = kart->getPitch() + 40.0f*DEGREE_TO_RAD;
|
||||||
wanted_position.setX(sin(angle_around));
|
wanted_position.setX(sin(angle_around));
|
||||||
wanted_position.setY(cos(angle_around));
|
wanted_position.setY(sin(angle_up) );
|
||||||
wanted_position.setZ(sin(angle_up) );
|
wanted_position.setZ(cos(angle_around));
|
||||||
wanted_position *= m_distance * 2.0f;
|
wanted_position *= m_distance * 2.0f;
|
||||||
wanted_position += wanted_target;
|
wanted_position += wanted_target;
|
||||||
smoothMoveCamera(dt, wanted_position, wanted_target);
|
smoothMoveCamera(dt, wanted_position, wanted_target);
|
||||||
|
@ -411,8 +411,9 @@ void IrrDriver::setAllMaterialFlags(scene::IAnimatedMesh *mesh) const
|
|||||||
for(unsigned int j=0; j<video::MATERIAL_MAX_TEXTURES; j++)
|
for(unsigned int j=0; j<video::MATERIAL_MAX_TEXTURES; j++)
|
||||||
{
|
{
|
||||||
video::ITexture* t=irr_material.getTexture(j);
|
video::ITexture* t=irr_material.getTexture(j);
|
||||||
if (!t) material_manager->setAllFlatMaterialFlags(mb);
|
//if (!t) material_manager->setAllFlatMaterialFlags(mb);
|
||||||
else material_manager->setAllMaterialFlags(t, mb);
|
//else material_manager->setAllMaterialFlags(t, mb);
|
||||||
|
if(t) material_manager->setAllMaterialFlags(t, mb);
|
||||||
|
|
||||||
} // for j<MATERIAL_MAX_TEXTURES
|
} // for j<MATERIAL_MAX_TEXTURES
|
||||||
material_manager->setAllUntexturedMaterialFlags(mb);
|
material_manager->setAllUntexturedMaterialFlags(mb);
|
||||||
@ -766,7 +767,7 @@ void IrrDriver::update(float dt)
|
|||||||
const bool inRace = world!=NULL;
|
const bool inRace = world!=NULL;
|
||||||
// With bullet debug view we have to clear the back buffer, but
|
// With bullet debug view we have to clear the back buffer, but
|
||||||
// that's not necessary for non-debug
|
// that's not necessary for non-debug
|
||||||
bool back_buffer_clear = inRace && UserConfigParams::m_bullet_debug;
|
bool back_buffer_clear = inRace && world->getPhysics()->isDebug();
|
||||||
m_device->getVideoDriver()->beginScene(back_buffer_clear,
|
m_device->getVideoDriver()->beginScene(back_buffer_clear,
|
||||||
true, video::SColor(255,100,101,140));
|
true, video::SColor(255,100,101,140));
|
||||||
|
|
||||||
@ -795,9 +796,11 @@ void IrrDriver::update(float dt)
|
|||||||
m_scene_manager->drawAll();
|
m_scene_manager->drawAll();
|
||||||
// Note that drawAll must be called before rendering
|
// Note that drawAll must be called before rendering
|
||||||
// the bullet debug view, since otherwise the camera
|
// the bullet debug view, since otherwise the camera
|
||||||
// is not set up properly.
|
// is not set up properly. This is only used for
|
||||||
if (UserConfigParams::m_bullet_debug)
|
// the bullet debug view.
|
||||||
|
#ifdef DEBUG
|
||||||
World::getWorld()->getPhysics()->draw();
|
World::getWorld()->getPhysics()->draw();
|
||||||
|
#endif
|
||||||
} // if kart->Camera
|
} // if kart->Camera
|
||||||
} // for i<world->getNumKarts()
|
} // for i<world->getNumKarts()
|
||||||
// To draw the race gui we set the viewport back to the full
|
// To draw the race gui we set the viewport back to the full
|
||||||
|
@ -36,8 +36,8 @@ void MeshTools::minMax3D(scene::IMesh* mesh, Vec3 *min, Vec3 *max) {
|
|||||||
for(unsigned int j=0; j<mb->getIndexCount(); j+=1) {
|
for(unsigned int j=0; j<mb->getIndexCount(); j+=1) {
|
||||||
int indx=mbIndices[j];
|
int indx=mbIndices[j];
|
||||||
Vec3 c(mbVertices[indx].Pos.X,
|
Vec3 c(mbVertices[indx].Pos.X,
|
||||||
mbVertices[indx].Pos.Z,
|
mbVertices[indx].Pos.Y,
|
||||||
mbVertices[indx].Pos.Y );
|
mbVertices[indx].Pos.Z );
|
||||||
min->min(c);
|
min->min(c);
|
||||||
max->max(c);
|
max->max(c);
|
||||||
} // for j
|
} // for j
|
||||||
|
@ -47,7 +47,6 @@ SlipStream::SlipStream(Kart* kart) : MovingTexture(0, 0), m_kart(kart)
|
|||||||
m_node = irr_driver->addMesh(m_mesh);
|
m_node = irr_driver->addMesh(m_mesh);
|
||||||
//m_node->setParent(m_kart->getNode());
|
//m_node->setParent(m_kart->getNode());
|
||||||
m_node->setPosition(core::vector3df(0,
|
m_node->setPosition(core::vector3df(0,
|
||||||
// 0*0.25f,
|
|
||||||
0*0.25f+2.5,
|
0*0.25f+2.5,
|
||||||
m_kart->getKartLength()) );
|
m_kart->getKartLength()) );
|
||||||
setTextureMatrix(&(m_node->getMaterial(0).getTextureMatrix(0)));
|
setTextureMatrix(&(m_node->getMaterial(0).getTextureMatrix(0)));
|
||||||
|
@ -105,7 +105,6 @@ void InputManager::handleStaticAction(int key, int value)
|
|||||||
{
|
{
|
||||||
Kart* kart = world->getLocalPlayerKart(0);
|
Kart* kart = world->getLocalPlayerKart(0);
|
||||||
kart->setPowerup(POWERUP_BUBBLEGUM, 10000);
|
kart->setPowerup(POWERUP_BUBBLEGUM, 10000);
|
||||||
projectile_manager->newExplosion(Vec3(0, 8, 0.5));
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case KEY_F2:
|
case KEY_F2:
|
||||||
@ -129,16 +128,6 @@ void InputManager::handleStaticAction(int key, int value)
|
|||||||
kart->setPowerup(POWERUP_SWITCH, 10000);
|
kart->setPowerup(POWERUP_SWITCH, 10000);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case KEY_F11:
|
|
||||||
if(value && control_is_pressed)
|
|
||||||
{
|
|
||||||
UserConfigParams::m_bullet_debug = !UserConfigParams::m_bullet_debug;
|
|
||||||
if(UserConfigParams::m_bullet_debug)
|
|
||||||
world->getPhysics()->activateDebug();
|
|
||||||
else
|
|
||||||
world->getPhysics()->deactivateDebug();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case KEY_F5:
|
case KEY_F5:
|
||||||
if (race_manager->getNumPlayers() ==1 )
|
if (race_manager->getNumPlayers() ==1 )
|
||||||
{
|
{
|
||||||
@ -159,6 +148,12 @@ void InputManager::handleStaticAction(int key, int value)
|
|||||||
Kart* kart = world->getLocalPlayerKart(0);
|
Kart* kart = world->getLocalPlayerKart(0);
|
||||||
kart->setPowerup(POWERUP_ZIPPER, 10000);
|
kart->setPowerup(POWERUP_ZIPPER, 10000);
|
||||||
}
|
}
|
||||||
|
case KEY_F11:
|
||||||
|
if(value && control_is_pressed)
|
||||||
|
{
|
||||||
|
world->getPhysics()->nextDebugMode();
|
||||||
|
}
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
case KEY_F12:
|
case KEY_F12:
|
||||||
UserConfigParams::m_display_fps = !UserConfigParams::m_display_fps;
|
UserConfigParams::m_display_fps = !UserConfigParams::m_display_fps;
|
||||||
|
@ -47,16 +47,16 @@ Bowling::Bowling(Kart *kart) : Flyable(kart, POWERUP_BOWLING, 50.0f /* mass */)
|
|||||||
if(m_speed < min_speed) m_speed = min_speed;
|
if(m_speed < min_speed) m_speed = min_speed;
|
||||||
}
|
}
|
||||||
|
|
||||||
createPhysics(y_offset, btVector3(0.0f, m_speed*2, 0.0f),
|
createPhysics(y_offset, btVector3(0.0f, 0.0f, m_speed*2),
|
||||||
new btSphereShape(0.5f*m_extend.getY()),
|
new btSphereShape(0.5f*m_extend.getY()),
|
||||||
-70.0f /*gravity*/,
|
-70.0f /*gravity*/,
|
||||||
true /*rotates*/);
|
true /*rotates*/);
|
||||||
// Even if the ball is fired backwards, m_speed must be positive,
|
// Even if the ball is fired backwards, m_speed must be positive,
|
||||||
// otherwise the ball can start to vibrate when energy is added.
|
// otherwise the ball can start to vibrate when energy is added.
|
||||||
m_speed = fabsf(m_speed);
|
m_speed = fabsf(m_speed);
|
||||||
// Do not adjust the z velociy depending on height above terrain, since
|
// Do not adjust the up velociy depending on height above terrain, since
|
||||||
// this would disable gravity.
|
// this would disable gravity.
|
||||||
setAdjustZVelocity(false);
|
setAdjustUpVelocity(false);
|
||||||
|
|
||||||
// unset no_contact_response flags, so that the ball
|
// unset no_contact_response flags, so that the ball
|
||||||
// will bounce off the track
|
// will bounce off the track
|
||||||
@ -92,7 +92,7 @@ void Bowling::update(float dt)
|
|||||||
{
|
{
|
||||||
Flyable::update(dt);
|
Flyable::update(dt);
|
||||||
const Kart *kart=0;
|
const Kart *kart=0;
|
||||||
btVector3 direction;
|
Vec3 direction;
|
||||||
float minDistance;
|
float minDistance;
|
||||||
getClosestKart(&kart, &minDistance, &direction);
|
getClosestKart(&kart, &minDistance, &direction);
|
||||||
if(kart && minDistance<m_st_max_distance_squared) // move bowling towards kart
|
if(kart && minDistance<m_st_max_distance_squared) // move bowling towards kart
|
||||||
@ -112,7 +112,7 @@ void Bowling::update(float dt)
|
|||||||
// speed, which causes the speed to increase, which in turn causes
|
// speed, which causes the speed to increase, which in turn causes
|
||||||
// the ball to fly higher and higher.
|
// the ball to fly higher and higher.
|
||||||
btTransform trans = getTrans();
|
btTransform trans = getTrans();
|
||||||
float hat = trans.getOrigin().getZ();
|
float hat = trans.getOrigin().getY();
|
||||||
btVector3 v = m_body->getLinearVelocity();
|
btVector3 v = m_body->getLinearVelocity();
|
||||||
float vlen = v.length2();
|
float vlen = v.length2();
|
||||||
if (hat<= m_max_height)
|
if (hat<= m_max_height)
|
||||||
@ -120,7 +120,7 @@ void Bowling::update(float dt)
|
|||||||
if(vlen<0.8*m_speed*m_speed)
|
if(vlen<0.8*m_speed*m_speed)
|
||||||
{ // bowling lost energy (less than 80%), i.e. it's too slow - speed it up:
|
{ // bowling lost energy (less than 80%), i.e. it's too slow - speed it up:
|
||||||
if(vlen==0.0f) {
|
if(vlen==0.0f) {
|
||||||
v = btVector3(.5f, .5f, 0.0f); // avoid 0 div.
|
v = btVector3(.5f, .0, 0.5f); // avoid 0 div.
|
||||||
}
|
}
|
||||||
m_body->setLinearVelocity(v*m_speed/sqrt(vlen));
|
m_body->setLinearVelocity(v*m_speed/sqrt(vlen));
|
||||||
} // vlen < 0.8*m_speed*m_speed
|
} // vlen < 0.8*m_speed*m_speed
|
||||||
|
@ -42,32 +42,31 @@ Cake::Cake (Kart *kart) : Flyable(kart, POWERUP_CAKE)
|
|||||||
// collide with the track. By setting the mass to 1, collisions happen.
|
// collide with the track. By setting the mass to 1, collisions happen.
|
||||||
// (if bullet is compiled with _DEBUG, a warning will be printed the first
|
// (if bullet is compiled with _DEBUG, a warning will be printed the first
|
||||||
// time a homing-track collision happens).
|
// time a homing-track collision happens).
|
||||||
float y_offset=kart->getKartLength()/2.0f + m_extend.getY()/2.0f;
|
float forward_offset=kart->getKartLength()/2.0f + m_extend.getZ()/2.0f;
|
||||||
|
|
||||||
float up_velocity = m_speed/7.0f;
|
float up_velocity = m_speed/7.0f;
|
||||||
|
|
||||||
// give a speed proportional to kart speed
|
// give a speed proportional to kart speed. m_speed is defined in flyable
|
||||||
m_speed = kart->getSpeed() * m_speed / 23.0f;
|
m_speed *= kart->getSpeed() / 23.0f;
|
||||||
if (kart->getSpeed() < 0)
|
|
||||||
m_speed /= 3.6f; //when going backwards, decrease speed of cake by less
|
//when going backwards, decrease speed of cake by less
|
||||||
|
if (kart->getSpeed() < 0) m_speed /= 3.6f;
|
||||||
|
|
||||||
m_speed += 16.0f;
|
m_speed += 16.0f;
|
||||||
|
|
||||||
if (m_speed < 1.0f)
|
if (m_speed < 1.0f) m_speed = 1.0f;
|
||||||
m_speed = 1.0f;
|
|
||||||
|
|
||||||
btTransform trans = kart->getTrans();
|
btTransform trans = kart->getTrans();
|
||||||
|
|
||||||
btMatrix3x3 thisKartDirMatrix = kart->getKartHeading().getBasis();
|
float heading=kart->getHeading();
|
||||||
btVector3 thisKartDirVector(thisKartDirMatrix[0][1],
|
|
||||||
thisKartDirMatrix[1][1],
|
|
||||||
thisKartDirMatrix[2][1]);
|
|
||||||
float heading=atan2f(-thisKartDirVector.getX(), thisKartDirVector.getY());
|
|
||||||
float pitch = kart->getTerrainPitch(heading);
|
float pitch = kart->getTerrainPitch(heading);
|
||||||
|
|
||||||
// find closest kart in front of the current one
|
// Find closest kart in front of the current one
|
||||||
const Kart *closest_kart=0; btVector3 direction; float kartDistSquared;
|
const Kart *closest_kart=0;
|
||||||
getClosestKart(&closest_kart, &kartDistSquared, &direction, kart /* search in front of this kart */);
|
Vec3 direction;
|
||||||
|
float kartDistSquared;
|
||||||
|
getClosestKart(&closest_kart, &kartDistSquared, &direction,
|
||||||
|
kart /* search in front of this kart */);
|
||||||
|
|
||||||
// aim at this kart if 1) it's not too far, 2) if the aimed kart's speed
|
// aim at this kart if 1) it's not too far, 2) if the aimed kart's speed
|
||||||
// allows the projectile to catch up with it
|
// allows the projectile to catch up with it
|
||||||
@ -75,21 +74,18 @@ Cake::Cake (Kart *kart) : Flyable(kart, POWERUP_CAKE)
|
|||||||
// this code finds the correct angle and upwards velocity to hit an opponents'
|
// this code finds the correct angle and upwards velocity to hit an opponents'
|
||||||
// vehicle if they were to continue travelling in the same direction and same speed
|
// vehicle if they were to continue travelling in the same direction and same speed
|
||||||
// (barring any obstacles in the way of course)
|
// (barring any obstacles in the way of course)
|
||||||
if(closest_kart != NULL && kartDistSquared < m_st_max_distance_squared && m_speed>closest_kart->getSpeed())
|
if(closest_kart != NULL && kartDistSquared < m_st_max_distance_squared &&
|
||||||
|
m_speed>closest_kart->getSpeed())
|
||||||
{
|
{
|
||||||
m_target = (Kart*)closest_kart;
|
m_target = (Kart*)closest_kart;
|
||||||
|
|
||||||
float fire_angle = 0.0f;
|
float fire_angle = 0.0f;
|
||||||
float time_estimated = 0.0f;
|
getLinearKartItemIntersection (kart->getXYZ(), closest_kart,
|
||||||
|
m_speed, m_gravity, forward_offset,
|
||||||
getLinearKartItemIntersection (kart->getTrans().getOrigin(), closest_kart,
|
&fire_angle, &up_velocity);
|
||||||
m_speed, m_gravity, y_offset,
|
|
||||||
&fire_angle, &up_velocity, &time_estimated);
|
|
||||||
|
|
||||||
// apply transformation to the bullet object (without pitch)
|
// apply transformation to the bullet object (without pitch)
|
||||||
btMatrix3x3 m;
|
trans.setRotation(btQuaternion(btVector3(0,1,0), fire_angle));
|
||||||
m.setEulerZYX(0.0f, 0.0f, fire_angle /*+thisKartAngle*/);
|
|
||||||
trans.setBasis(m);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -99,14 +95,14 @@ Cake::Cake (Kart *kart) : Flyable(kart, POWERUP_CAKE)
|
|||||||
trans = kart->getKartHeading(pitch);
|
trans = kart->getKartHeading(pitch);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_initial_velocity = btVector3(0.0f, m_speed, up_velocity);
|
m_initial_velocity = Vec3(0.0f, up_velocity, m_speed);
|
||||||
|
|
||||||
createPhysics(y_offset, m_initial_velocity,
|
createPhysics(forward_offset, m_initial_velocity,
|
||||||
new btCylinderShape(0.5f*m_extend), -m_gravity,
|
new btCylinderShape(0.5f*m_extend), -m_gravity,
|
||||||
true /* rotation */, false /* backwards */, &trans);
|
true /* rotation */, false /* backwards */, &trans);
|
||||||
|
|
||||||
//do not adjust height according to terrain
|
//do not adjust height according to terrain
|
||||||
setAdjustZVelocity(false);
|
setAdjustUpVelocity(false);
|
||||||
|
|
||||||
m_body->setActivationState(DISABLE_DEACTIVATION);
|
m_body->setActivationState(DISABLE_DEACTIVATION);
|
||||||
|
|
||||||
@ -126,8 +122,7 @@ void Cake::init(const XMLNode &node, scene::IMesh *cake_model)
|
|||||||
m_st_max_distance_squared = 80.0f * 80.0f;
|
m_st_max_distance_squared = 80.0f * 80.0f;
|
||||||
m_gravity = 9.8f;
|
m_gravity = 9.8f;
|
||||||
|
|
||||||
if (m_gravity < 0)
|
if (m_gravity < 0) m_gravity *= -1.0f;
|
||||||
m_gravity *= -1;
|
|
||||||
|
|
||||||
node.get("max-distance", &m_st_max_distance );
|
node.get("max-distance", &m_st_max_distance );
|
||||||
m_st_max_distance_squared = m_st_max_distance*m_st_max_distance;
|
m_st_max_distance_squared = m_st_max_distance*m_st_max_distance;
|
||||||
@ -150,7 +145,7 @@ void Cake::update(float dt)
|
|||||||
float time_estimated = 0.0f;
|
float time_estimated = 0.0f;
|
||||||
float up_velocity = 0.0f;
|
float up_velocity = 0.0f;
|
||||||
|
|
||||||
btVector3 origin = my_trans.getOrigin() - m_target->getNormal() * 0.5 * m_target->getKartHeight();
|
Vec3 origin = my_trans.getOrigin() - m_target->getNormal() * 0.5 * m_target->getKartHeight();
|
||||||
|
|
||||||
getLinearKartItemIntersection (origin, m_target,
|
getLinearKartItemIntersection (origin, m_target,
|
||||||
m_speed, m_gravity, 0,
|
m_speed, m_gravity, 0,
|
||||||
|
@ -41,7 +41,7 @@ scene::IMesh* Flyable::m_st_model[POWERUP_MAX];
|
|||||||
float Flyable::m_st_min_height[POWERUP_MAX];
|
float Flyable::m_st_min_height[POWERUP_MAX];
|
||||||
float Flyable::m_st_max_height[POWERUP_MAX];
|
float Flyable::m_st_max_height[POWERUP_MAX];
|
||||||
float Flyable::m_st_force_updown[POWERUP_MAX];
|
float Flyable::m_st_force_updown[POWERUP_MAX];
|
||||||
btVector3 Flyable::m_st_extend[POWERUP_MAX];
|
Vec3 Flyable::m_st_extend[POWERUP_MAX];
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
Flyable::Flyable(Kart *kart, PowerupType type, float mass) : Moveable()
|
Flyable::Flyable(Kart *kart, PowerupType type, float mass) : Moveable()
|
||||||
@ -53,15 +53,12 @@ Flyable::Flyable(Kart *kart, PowerupType type, float mass) : Moveable()
|
|||||||
m_min_height = m_st_min_height[type];
|
m_min_height = m_st_min_height[type];
|
||||||
m_average_height = (m_min_height+m_max_height)/2.0f;
|
m_average_height = (m_min_height+m_max_height)/2.0f;
|
||||||
m_force_updown = m_st_force_updown[type];
|
m_force_updown = m_st_force_updown[type];
|
||||||
|
|
||||||
m_owner = kart;
|
m_owner = kart;
|
||||||
m_type = type;
|
|
||||||
m_has_hit_something = false;
|
m_has_hit_something = false;
|
||||||
m_exploded = false;
|
m_exploded = false;
|
||||||
m_shape = NULL;
|
m_shape = NULL;
|
||||||
m_mass = mass;
|
m_mass = mass;
|
||||||
m_adjust_z_velocity = true;
|
m_adjust_up_velocity = true;
|
||||||
|
|
||||||
m_time_since_thrown = 0;
|
m_time_since_thrown = 0;
|
||||||
m_owner_has_temporary_immunity = true;
|
m_owner_has_temporary_immunity = true;
|
||||||
m_max_lifespan = -1;
|
m_max_lifespan = -1;
|
||||||
@ -71,19 +68,32 @@ Flyable::Flyable(Kart *kart, PowerupType type, float mass) : Moveable()
|
|||||||
} // Flyable
|
} // Flyable
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
void Flyable::createPhysics(float y_offset, const btVector3 &velocity,
|
/** Creates a bullet physics body for the flyable item.
|
||||||
|
* \param forw_offset How far ahead of the kart the flyable should be
|
||||||
|
* positioned. Necessary to avoid exploding a rocket inside of the
|
||||||
|
* firing kart.
|
||||||
|
* \param velocity Initial velocity of the flyable.
|
||||||
|
* \param shape Collision shape of the flyable.
|
||||||
|
* \param gravity Gravity to use for this flyable.
|
||||||
|
* \param rotates True if the item should rotate, otherwise the angular factor
|
||||||
|
* is set to 0 preventing rotations from happening.
|
||||||
|
* \param turn_around True if the item is fired backwards.
|
||||||
|
* \param custom_direction If defined the initial heading for this item,
|
||||||
|
* otherwise the kart's heading will be used.
|
||||||
|
*/
|
||||||
|
void Flyable::createPhysics(float forw_offset, const Vec3 &velocity,
|
||||||
btCollisionShape *shape, const float gravity,
|
btCollisionShape *shape, const float gravity,
|
||||||
const bool rotates, const bool turn_around,
|
const bool rotates, const bool turn_around,
|
||||||
const btTransform* customDirection)
|
const btTransform* custom_direction)
|
||||||
{
|
{
|
||||||
// Get Kart heading direction
|
// Get Kart heading direction
|
||||||
btTransform trans = ( customDirection == NULL ? m_owner->getKartHeading() : *customDirection );
|
btTransform trans = ( custom_direction == NULL ? m_owner->getKartHeading()
|
||||||
|
: *custom_direction );
|
||||||
|
|
||||||
// Apply offset
|
// Apply offset
|
||||||
btTransform offset_transform;
|
btTransform offset_transform;
|
||||||
offset_transform.setIdentity();
|
offset_transform.setIdentity();
|
||||||
btVector3 offset=btVector3(0,y_offset,m_average_height);
|
offset_transform.setOrigin(Vec3(0,m_average_height,forw_offset));
|
||||||
offset_transform.setOrigin(offset);
|
|
||||||
|
|
||||||
// turn around
|
// turn around
|
||||||
if(turn_around)
|
if(turn_around)
|
||||||
@ -91,7 +101,7 @@ void Flyable::createPhysics(float y_offset, const btVector3 &velocity,
|
|||||||
btTransform turn_around_trans;
|
btTransform turn_around_trans;
|
||||||
//turn_around_trans.setOrigin(trans.getOrigin());
|
//turn_around_trans.setOrigin(trans.getOrigin());
|
||||||
turn_around_trans.setIdentity();
|
turn_around_trans.setIdentity();
|
||||||
turn_around_trans.setRotation(btQuaternion(btVector3(0, 0, 1), M_PI));
|
turn_around_trans.setRotation(btQuaternion(btVector3(0, 1, 0), M_PI));
|
||||||
trans *= turn_around_trans;
|
trans *= turn_around_trans;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,7 +112,7 @@ void Flyable::createPhysics(float y_offset, const btVector3 &velocity,
|
|||||||
m_user_pointer.set(this);
|
m_user_pointer.set(this);
|
||||||
World::getWorld()->getPhysics()->addBody(getBody());
|
World::getWorld()->getPhysics()->addBody(getBody());
|
||||||
|
|
||||||
m_body->setGravity(btVector3(0.0f, 0.0f, gravity));
|
m_body->setGravity(btVector3(0.0f, gravity, 0));
|
||||||
|
|
||||||
// Rotate velocity to point in the right direction
|
// Rotate velocity to point in the right direction
|
||||||
btVector3 v=trans.getBasis()*velocity;
|
btVector3 v=trans.getBasis()*velocity;
|
||||||
@ -143,10 +153,18 @@ Flyable::~Flyable()
|
|||||||
} // ~Flyable
|
} // ~Flyable
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
/** Returns information on what is the closest kart and at what distance it is.
|
||||||
|
* All 3 parameters first are of type 'out'. 'inFrontOf' can be set if you
|
||||||
|
* wish to know the closest kart in front of some karts (will ignore those
|
||||||
|
* behind). Useful e.g. for throwing projectiles in front only.
|
||||||
|
*/
|
||||||
|
|
||||||
void Flyable::getClosestKart(const Kart **minKart, float *minDistSquared,
|
void Flyable::getClosestKart(const Kart **minKart, float *minDistSquared,
|
||||||
btVector3 *minDelta, const Kart* inFrontOf, const bool backwards) const
|
Vec3 *minDelta, const Kart* inFrontOf,
|
||||||
|
const bool backwards) const
|
||||||
{
|
{
|
||||||
btTransform tProjectile = (inFrontOf != NULL ? inFrontOf->getTrans() : getTrans());
|
btTransform tProjectile = (inFrontOf != NULL ? inFrontOf->getTrans()
|
||||||
|
: getTrans());
|
||||||
|
|
||||||
*minDistSquared = -1.0f;
|
*minDistSquared = -1.0f;
|
||||||
*minKart = NULL;
|
*minKart = NULL;
|
||||||
@ -158,24 +176,23 @@ void Flyable::getClosestKart(const Kart **minKart, float *minDistSquared,
|
|||||||
if(kart->isEliminated() || kart == m_owner || kart->isRescue() ) continue;
|
if(kart->isEliminated() || kart == m_owner || kart->isRescue() ) continue;
|
||||||
btTransform t=kart->getTrans();
|
btTransform t=kart->getTrans();
|
||||||
|
|
||||||
btVector3 delta = t.getOrigin()-tProjectile.getOrigin();
|
Vec3 delta = t.getOrigin()-tProjectile.getOrigin();
|
||||||
float distance2 = delta.length2();
|
float distance2 = delta.length2();
|
||||||
|
|
||||||
if(inFrontOf != NULL)
|
if(inFrontOf != NULL)
|
||||||
{
|
{
|
||||||
// Ignore karts behind the current one
|
// Ignore karts behind the current one
|
||||||
btVector3 to_target = kart->getXYZ() - inFrontOf->getXYZ();
|
Vec3 to_target = kart->getXYZ() - inFrontOf->getXYZ();
|
||||||
const float distance = to_target.length();
|
const float distance = to_target.length();
|
||||||
if(distance > 50) continue; // kart too far, don't aim at it
|
if(distance > 50) continue; // kart too far, don't aim at it
|
||||||
|
|
||||||
btTransform trans = inFrontOf->getTrans();
|
btTransform trans = inFrontOf->getTrans();
|
||||||
// get heading=trans.getBasis*(0,1,0) ... so save the multiplication:
|
// get heading=trans.getBasis*(0,0,1) ... so save the multiplication:
|
||||||
btVector3 direction(trans.getBasis()[0][1],
|
Vec3 direction(trans.getBasis().getColumn(2));
|
||||||
trans.getBasis()[1][1],
|
|
||||||
trans.getBasis()[2][1]);
|
|
||||||
// Originally it used angle = to_target.angle( backwards ? -direction : direction );
|
// Originally it used angle = to_target.angle( backwards ? -direction : direction );
|
||||||
// but since sometimes due to rounding errors we get an acos(x) with x>1, causing
|
// but sometimes due to rounding errors we get an acos(x) with x>1, causing
|
||||||
// an assertion failure. So we remove the whole acos() test here:
|
// an assertion failure. So we remove the whole acos() test here and copy the
|
||||||
|
// code from to_target.angle(...)
|
||||||
Vec3 v = backwards ? -direction : direction;
|
Vec3 v = backwards ? -direction : direction;
|
||||||
float s = sqrt(v.length2() * to_target.length2());
|
float s = sqrt(v.length2() * to_target.length2());
|
||||||
float c = to_target.dot(v)/s;
|
float c = to_target.dot(v)/s;
|
||||||
@ -195,42 +212,52 @@ void Flyable::getClosestKart(const Kart **minKart, float *minDistSquared,
|
|||||||
} // getClosestKart
|
} // getClosestKart
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void Flyable::getLinearKartItemIntersection (const btVector3 origin, const Kart *target_kart,
|
/** Returns information on the parameters needed to hit a target kart moving
|
||||||
float item_XY_speed, float gravity, float y_offset,
|
* at constant velocity and direction for a given speed in the XZ-plane.
|
||||||
float *fire_angle, float *up_velocity, float *time_estimated)
|
* \param origin Location of the kart shooting the item.
|
||||||
|
* \param target_kart Which kart to target.
|
||||||
|
* \param item_xz_speed Speed of the item projected in XZ plane.
|
||||||
|
* \param gravity The gravity used for this item.
|
||||||
|
* \param forw_offset How far ahead of the kart the item is shot (so that
|
||||||
|
* the item does not originate inside of the shooting kart.
|
||||||
|
* \param fire_angle Returns the angle to fire the item at.
|
||||||
|
* \param up_velocity Returns the upwards velocity to use for the item.
|
||||||
|
*/
|
||||||
|
void Flyable::getLinearKartItemIntersection (const Vec3 &origin,
|
||||||
|
const Kart *target_kart,
|
||||||
|
float item_XZ_speed,
|
||||||
|
float gravity, float forw_offset,
|
||||||
|
float *fire_angle,
|
||||||
|
float *up_velocity)
|
||||||
{
|
{
|
||||||
Vec3 relative_target_kart_loc = target_kart->getTrans().getOrigin() - origin;
|
Vec3 relative_target_kart_loc = target_kart->getXYZ() - origin;
|
||||||
|
|
||||||
btTransform trans = target_kart->getTrans();
|
btTransform trans = target_kart->getTrans();
|
||||||
Vec3 target_direction(trans.getBasis()[0][1],
|
Vec3 target_direction(trans.getBasis().getColumn(2));
|
||||||
trans.getBasis()[1][1],
|
|
||||||
trans.getBasis()[2][1]);
|
|
||||||
|
|
||||||
float dx = relative_target_kart_loc.getX();
|
float dx = relative_target_kart_loc.getX();
|
||||||
float dy = relative_target_kart_loc.getY();
|
float dy = relative_target_kart_loc.getY();
|
||||||
float dz = relative_target_kart_loc.getZ();
|
float dz = relative_target_kart_loc.getZ();
|
||||||
|
|
||||||
float gx = target_direction.getX();
|
|
||||||
float gy = target_direction.getY();
|
float gy = target_direction.getY();
|
||||||
float gz = target_direction.getZ();
|
|
||||||
|
|
||||||
float target_kart_speed = target_direction.length_2d() * target_kart->getSpeed(); //Projected onto X-Y plane
|
//Projected onto X-Z plane
|
||||||
|
float target_kart_speed = target_direction.length_2d() * target_kart->getSpeed();
|
||||||
|
|
||||||
float target_kart_heading = atan2f(-gx, gy); //anti-clockwise
|
float target_kart_heading = target_kart->getHeading();
|
||||||
|
|
||||||
float dist = -(target_kart_speed / item_XY_speed) * (dx * cosf(target_kart_heading) + dy * sinf(target_kart_heading));
|
float dist = -(target_kart_speed / item_XZ_speed) * (dx * cosf(target_kart_heading) +
|
||||||
|
dz * sinf(target_kart_heading));
|
||||||
|
|
||||||
float fire_th = (dx*dist - dy * sqrtf(dx*dx + dy*dy - dist*dist)) / (dx*dx + dy*dy);
|
float fire_th = (dx*dist - dz * sqrtf(dx*dx + dz*dz - dist*dist)) / (dx*dx + dz*dz);
|
||||||
fire_th = (((dist - dx*fire_th) / dy < 0) ? -acosf(fire_th): acosf(fire_th));
|
fire_th = (((dist - dx*fire_th) / dz > 0) ? -acosf(fire_th): acosf(fire_th));
|
||||||
|
|
||||||
float time = 0.0f;
|
float time = 0.0f;
|
||||||
float a = item_XY_speed * sinf (fire_th) + target_kart_speed * sinf (target_kart_heading);
|
float a = item_XZ_speed * sinf (fire_th) + target_kart_speed * sinf (target_kart_heading);
|
||||||
float b = item_XY_speed * cosf (fire_th) + target_kart_speed * cosf (target_kart_heading);
|
float b = item_XZ_speed * cosf (fire_th) + target_kart_speed * cosf (target_kart_heading);
|
||||||
|
|
||||||
if (fabsf(a) > fabsf(b))
|
if (fabsf(a) > fabsf(b)) time = fabsf (dx / a);
|
||||||
time = fabsf (dx / a);
|
else if (b != 0.0f) time = fabsf(dz / b);
|
||||||
else if (b != 0.0f)
|
|
||||||
time = fabsf(dy / b);
|
|
||||||
|
|
||||||
if (fire_th > M_PI)
|
if (fire_th > M_PI)
|
||||||
fire_th -= M_PI;
|
fire_th -= M_PI;
|
||||||
@ -238,12 +265,11 @@ void Flyable::getLinearKartItemIntersection (const btVector3 origin, const Kart
|
|||||||
fire_th += M_PI;
|
fire_th += M_PI;
|
||||||
|
|
||||||
//createPhysics offset
|
//createPhysics offset
|
||||||
time -= y_offset / sqrt(a*a+b*b);
|
time -= forw_offset / sqrt(a*a+b*b);
|
||||||
|
|
||||||
*fire_angle = fire_th;
|
*fire_angle = fire_th;
|
||||||
*up_velocity = (0.5f * time * gravity) + (dz / time) + (gz * target_kart->getSpeed());
|
*up_velocity = (0.5f * time * gravity) + (dy / time) + (gy * target_kart->getSpeed());
|
||||||
*time_estimated = time;
|
} // getLinearKartItemIntersection
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void Flyable::update(float dt)
|
void Flyable::update(float dt)
|
||||||
@ -260,15 +286,15 @@ void Flyable::update(float dt)
|
|||||||
const Vec3 *min, *max;
|
const Vec3 *min, *max;
|
||||||
World::getWorld()->getTrack()->getAABB(&min, &max);
|
World::getWorld()->getTrack()->getAABB(&min, &max);
|
||||||
Vec3 xyz = getXYZ();
|
Vec3 xyz = getXYZ();
|
||||||
if(xyz[0]<(*min)[0] || xyz[1]<(*min)[1] || xyz[2]<(*min)[2] ||
|
if(xyz[0]<(*min)[0] || xyz[2]<(*min)[2] || xyz[1]<(*min)[1] ||
|
||||||
xyz[0]>(*max)[0] || xyz[1]>(*max)[1] )
|
xyz[0]>(*max)[0] || xyz[2]>(*max)[2] )
|
||||||
{
|
{
|
||||||
hit(NULL); // flyable out of track boundary
|
hit(NULL); // flyable out of track boundary
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(m_adjust_z_velocity)
|
if(m_adjust_up_velocity)
|
||||||
{
|
{
|
||||||
float hat = pos.getZ()-getHoT();
|
float hat = pos.getY()-getHoT();
|
||||||
|
|
||||||
// Use the Height Above Terrain to set the Z velocity.
|
// Use the Height Above Terrain to set the Z velocity.
|
||||||
// HAT is clamped by min/max height. This might be somewhat
|
// HAT is clamped by min/max height. This might be somewhat
|
||||||
@ -276,14 +302,14 @@ void Flyable::update(float dt)
|
|||||||
|
|
||||||
float delta = m_average_height - std::max(std::min(hat, m_max_height), m_min_height);
|
float delta = m_average_height - std::max(std::min(hat, m_max_height), m_min_height);
|
||||||
Vec3 v = getVelocity();
|
Vec3 v = getVelocity();
|
||||||
float heading = atan2f(-v.getX(), v.getY());
|
float heading = atan2f(v.getX(), v.getZ());
|
||||||
float pitch = getTerrainPitch(heading);
|
float pitch = getTerrainPitch(heading);
|
||||||
float vel_z = m_force_updown*(delta);
|
float vel_up = m_force_updown*(delta);
|
||||||
if (hat < m_max_height) // take into account pitch of surface
|
if (hat < m_max_height) // take into account pitch of surface
|
||||||
vel_z += v.length_2d()*tanf(pitch);
|
vel_up += v.length_2d()*tanf(pitch);
|
||||||
v.setZ(vel_z);
|
v.setY(vel_up);
|
||||||
setVelocity(v);
|
setVelocity(v);
|
||||||
} // if m_adjust_z_velocity
|
} // if m_adjust_up_velocity
|
||||||
|
|
||||||
Moveable::update(dt);
|
Moveable::update(dt);
|
||||||
} // update
|
} // update
|
||||||
|
@ -45,10 +45,10 @@ private:
|
|||||||
* It can happen that more than one collision between a rocket and
|
* It can happen that more than one collision between a rocket and
|
||||||
* a track or kart is reported by the physics. */
|
* a track or kart is reported by the physics. */
|
||||||
bool m_exploded;
|
bool m_exploded;
|
||||||
/** If this flag is set, the Z velocity of the kart will not be
|
/** If this flag is set, the up velocity of the kart will not be
|
||||||
* adjusted in case that the objects is too high or too low above the
|
* adjusted in case that the objects is too high or too low above the
|
||||||
* terrain. Otherwise gravity will not work correctly on this object. */
|
* terrain. Otherwise gravity will not work correctly on this object. */
|
||||||
bool m_adjust_z_velocity;
|
bool m_adjust_up_velocity;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Kart* m_owner; // the kart which released this flyable
|
Kart* m_owner; // the kart which released this flyable
|
||||||
@ -60,7 +60,7 @@ protected:
|
|||||||
float m_force_updown;
|
float m_force_updown;
|
||||||
float m_speed;
|
float m_speed;
|
||||||
float m_mass;
|
float m_mass;
|
||||||
btVector3 m_extend;
|
Vec3 m_extend;
|
||||||
// The flyable class stores the values for each flyable type, e.g.
|
// The flyable class stores the values for each flyable type, e.g.
|
||||||
// speed, min_height, max_height. These variables must be static,
|
// speed, min_height, max_height. These variables must be static,
|
||||||
// so we need arrays of these variables to have different values
|
// so we need arrays of these variables to have different values
|
||||||
@ -70,7 +70,7 @@ protected:
|
|||||||
static float m_st_min_height[POWERUP_MAX]; // min height above track
|
static float m_st_min_height[POWERUP_MAX]; // min height above track
|
||||||
static float m_st_max_height[POWERUP_MAX]; // max height above track
|
static float m_st_max_height[POWERUP_MAX]; // max height above track
|
||||||
static float m_st_force_updown[POWERUP_MAX]; // force pushing up/down
|
static float m_st_force_updown[POWERUP_MAX]; // force pushing up/down
|
||||||
static btVector3 m_st_extend[POWERUP_MAX]; // size of the model
|
static Vec3 m_st_extend[POWERUP_MAX]; // size of the model
|
||||||
|
|
||||||
/** time since thrown. used so a kart can't hit himself when trying something,
|
/** time since thrown. used so a kart can't hit himself when trying something,
|
||||||
and also to put some time limit to some collectibles */
|
and also to put some time limit to some collectibles */
|
||||||
@ -83,28 +83,20 @@ protected:
|
|||||||
for a short time */
|
for a short time */
|
||||||
bool m_owner_has_temporary_immunity;
|
bool m_owner_has_temporary_immunity;
|
||||||
|
|
||||||
/** Returns information on what is the closest kart and at what
|
|
||||||
distance it is. All 3 parameters first are of type 'out'.
|
|
||||||
'inFrontOf' can be set if you wish to know the closest
|
|
||||||
kart in front of some karts (will ignore those behind).
|
|
||||||
Useful e.g. for throwing projectiles in front only.
|
|
||||||
*/
|
|
||||||
void getClosestKart(const Kart **minKart, float *minDistSquared,
|
void getClosestKart(const Kart **minKart, float *minDistSquared,
|
||||||
btVector3 *minDelta, const Kart* inFrontOf=NULL,
|
Vec3 *minDelta, const Kart* inFrontOf=NULL,
|
||||||
const bool backwards=false) const;
|
const bool backwards=false) const;
|
||||||
|
|
||||||
/** Returns information on the parameters needed to hit a target kart
|
void getLinearKartItemIntersection(const Vec3 &origin,
|
||||||
moving at constant velocity and direction for a given speed in the
|
const Kart *target_kart,
|
||||||
XY-plane.
|
float item_XY_velocity, float gravity,
|
||||||
*/
|
float forw_offset,
|
||||||
void getLinearKartItemIntersection(const btVector3 origin, const Kart *target_kart,
|
float *fire_angle, float *up_velocity);
|
||||||
float item_XY_velocity, float gravity, float y_offset,
|
|
||||||
float *fire_angle, float *up_velocity, float *time);
|
|
||||||
|
|
||||||
|
|
||||||
/** init bullet for moving objects like projectiles */
|
/** init bullet for moving objects like projectiles */
|
||||||
void createPhysics(float y_offset,
|
void createPhysics(float y_offset,
|
||||||
const btVector3 &velocity,
|
const Vec3 &velocity,
|
||||||
btCollisionShape *shape, const float gravity=0.0f,
|
btCollisionShape *shape, const float gravity=0.0f,
|
||||||
const bool rotates=false, const bool turn_around=false,
|
const bool rotates=false, const bool turn_around=false,
|
||||||
const btTransform* customDirection=NULL);
|
const btTransform* customDirection=NULL);
|
||||||
@ -115,7 +107,7 @@ public:
|
|||||||
/** Enables/disables adjusting ov velocity depending on height above
|
/** Enables/disables adjusting ov velocity depending on height above
|
||||||
* terrain. Missiles can 'follow the terrain' with this adjustment,
|
* terrain. Missiles can 'follow the terrain' with this adjustment,
|
||||||
* but gravity will basically be disabled. */
|
* but gravity will basically be disabled. */
|
||||||
void setAdjustZVelocity(bool f) { m_adjust_z_velocity = f; }
|
void setAdjustUpVelocity(bool f) { m_adjust_up_velocity = f; }
|
||||||
static void init (const XMLNode &node, scene::IMesh *model,
|
static void init (const XMLNode &node, scene::IMesh *model,
|
||||||
PowerupType type);
|
PowerupType type);
|
||||||
virtual void update (float);
|
virtual void update (float);
|
||||||
|
@ -31,13 +31,10 @@ Item::Item(ItemType type, const Vec3& xyz, const Vec3& normal,
|
|||||||
{
|
{
|
||||||
setType(type);
|
setType(type);
|
||||||
m_event_handler = NULL;
|
m_event_handler = NULL;
|
||||||
|
m_xyz = xyz;
|
||||||
m_deactive_time = 0;
|
m_deactive_time = 0;
|
||||||
m_normal = normal;
|
|
||||||
// Sets heading to 0, and sets pitch and roll depending on the normal. */
|
// Sets heading to 0, and sets pitch and roll depending on the normal. */
|
||||||
Vec3 hpr = Vec3(0, normal);
|
Vec3 hpr = Vec3(0, normal);
|
||||||
m_coord = Coord(xyz, hpr);
|
|
||||||
m_rotate_to_normal = core::quaternion(hpr.toIrrVector());
|
|
||||||
m_rotate_amount = 0;
|
|
||||||
m_item_id = item_id;
|
m_item_id = item_id;
|
||||||
m_original_type = ITEM_NONE;
|
m_original_type = ITEM_NONE;
|
||||||
m_collected = false;
|
m_collected = false;
|
||||||
@ -148,8 +145,6 @@ void Item::update(float dt)
|
|||||||
// Make it visible by scaling it from 0 to 1:
|
// Make it visible by scaling it from 0 to 1:
|
||||||
m_node->setVisible(true);
|
m_node->setVisible(true);
|
||||||
m_node->setScale(core::vector3df(1,1,1)*(1-m_time_till_return));
|
m_node->setScale(core::vector3df(1,1,1)*(1-m_time_till_return));
|
||||||
core::vector3df pos = m_coord.getXYZ().toIrrVector();
|
|
||||||
pos.Y = pos.Y+2.0f*m_time_till_return;
|
|
||||||
} // time till return < 1
|
} // time till return < 1
|
||||||
} // if collected
|
} // if collected
|
||||||
else
|
else
|
||||||
@ -157,59 +152,13 @@ void Item::update(float dt)
|
|||||||
|
|
||||||
if(!m_rotate) return;
|
if(!m_rotate) return;
|
||||||
// have it rotate
|
// have it rotate
|
||||||
Vec3 rotation(dt*M_PI, 0, 0);
|
Vec3 rotation(0, dt*M_PI, 0);
|
||||||
m_coord.setHPR(m_coord.getHPR()+rotation);
|
core::vector3df r = m_node->getRotation();
|
||||||
m_node->setRotation(m_coord.getHPR().toIrrHPR());
|
r.Y += dt*180.0f;
|
||||||
m_node->setPosition(m_coord.getXYZ().toIrrVector());
|
if(r.Y>360.0f) r.Y -= 360.0f;
|
||||||
|
m_node->setRotation(r);
|
||||||
return;
|
return;
|
||||||
|
} // not m_collected
|
||||||
m_rotate_amount += dt*M_PI;
|
|
||||||
if(m_rotate_amount>2*M_PI) m_rotate_amount -= 2*M_PI;
|
|
||||||
|
|
||||||
core::quaternion qx;
|
|
||||||
qx.fromAngleAxis(m_rotate_amount, m_normal.toIrrVector());
|
|
||||||
core::quaternion qall = m_rotate_to_normal*qx;
|
|
||||||
core::vector3df qeuler;
|
|
||||||
qx.toEuler(qeuler);
|
|
||||||
qeuler *= 180/3.1415926f;
|
|
||||||
m_node->setRotation(qeuler);
|
|
||||||
return;
|
|
||||||
|
|
||||||
|
|
||||||
const core::matrix4 &m=m_node->getAbsoluteTransformation();
|
|
||||||
core::quaternion current_rotation(m);
|
|
||||||
float anglec;
|
|
||||||
core::vector3df axisc;
|
|
||||||
current_rotation.toAngleAxis(anglec, axisc);
|
|
||||||
printf("curre %f axis %f %f %f\n", anglec,axisc.X, axisc.Y, axisc.Z);
|
|
||||||
core::quaternion q2;
|
|
||||||
q2.fromAngleAxis(dt*M_PI, m_normal.toIrrVector());
|
|
||||||
float angle2;
|
|
||||||
core::vector3df axis2;
|
|
||||||
q2.toAngleAxis(angle2, axis2);
|
|
||||||
printf("new %f axis %f %f %f\n", angle2,axis2.X, axis2.Y, axis2.Z);
|
|
||||||
core::quaternion all=current_rotation*q2;
|
|
||||||
float angle;
|
|
||||||
core::vector3df axis;
|
|
||||||
all.toAngleAxis(angle, axis);
|
|
||||||
printf("angle %f axis %f %f %f\n", angle,axis.X, axis.Y, axis.Z);
|
|
||||||
core::vector3df euler;
|
|
||||||
all.toEuler(euler);
|
|
||||||
euler *=180/3.1415926f;
|
|
||||||
m_node->setRotation(euler);
|
|
||||||
|
|
||||||
return;
|
|
||||||
#ifdef xx
|
|
||||||
|
|
||||||
btQuaternion q(Vec3(0,0,1), t*0.1f);
|
|
||||||
btQuaternion q_orig(m_normal, 0);
|
|
||||||
btQuaternion result=q+q_orig;
|
|
||||||
btMatrix3x3 m(result);
|
|
||||||
float y, p, r;
|
|
||||||
m.getEuler(y, p, r);
|
|
||||||
m_node->setRotation(Vec3(y, p, r).toIrrHPR());
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
} // update
|
} // update
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -60,18 +60,15 @@ private:
|
|||||||
/** Time till a collected item reappears. */
|
/** Time till a collected item reappears. */
|
||||||
float m_time_till_return;
|
float m_time_till_return;
|
||||||
|
|
||||||
/** Original coordinates, used mainly when collected items reappear. */
|
|
||||||
Coord m_coord;
|
|
||||||
core::quaternion m_rotate_to_normal;
|
|
||||||
float m_rotate_amount;
|
|
||||||
|
|
||||||
/** Scene node of this item. */
|
/** Scene node of this item. */
|
||||||
scene::IMeshSceneNode *m_node;
|
scene::IMeshSceneNode *m_node;
|
||||||
|
|
||||||
/** Stores the original mesh in order to reset it. */
|
/** Stores the original mesh in order to reset it. */
|
||||||
scene::IMesh *m_original_mesh;
|
scene::IMesh *m_original_mesh;
|
||||||
|
|
||||||
Vec3 m_normal;
|
/** The original position - saves calls to m_node->getPosition()
|
||||||
|
* and then converting this value to a Vec3. */
|
||||||
|
Vec3 m_xyz;
|
||||||
|
|
||||||
/** Index in item_manager field. */
|
/** Index in item_manager field. */
|
||||||
unsigned int m_item_id;
|
unsigned int m_item_id;
|
||||||
@ -79,11 +76,12 @@ private:
|
|||||||
/** Set to false if item should not rotate. */
|
/** Set to false if item should not rotate. */
|
||||||
bool m_rotate;
|
bool m_rotate;
|
||||||
|
|
||||||
/** optionally, set this if this item was laid by a particular kart. in this case,
|
/** Optionally set this if this item was laid by a particular kart. in
|
||||||
the 'm_deactive_time' will also be set - see below. */
|
* this case the 'm_deactive_time' will also be set - see below. */
|
||||||
const Kart *m_event_handler;
|
const Kart *m_event_handler;
|
||||||
/** optionally, if item was placed by a kart, a timer can be used to temporarly
|
|
||||||
deactivate collision so a kart is not hit by its own item */
|
/** Optionally if item was placed by a kart, a timer can be used to
|
||||||
|
* temporarly deactivate collision so a kart is not hit by its own item */
|
||||||
float m_deactive_time;
|
float m_deactive_time;
|
||||||
|
|
||||||
void setType(ItemType type);
|
void setType(ItemType type);
|
||||||
@ -102,7 +100,7 @@ public:
|
|||||||
bool hitKart (Kart* kart ) const
|
bool hitKart (Kart* kart ) const
|
||||||
{
|
{
|
||||||
return (m_event_handler!=kart || m_deactive_time <=0) &&
|
return (m_event_handler!=kart || m_deactive_time <=0) &&
|
||||||
(kart->getXYZ()-m_coord.getXYZ()).length2()<0.8f;
|
(kart->getXYZ()-m_xyz).length2()<0.8f;
|
||||||
} // hitKart
|
} // hitKart
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
@ -46,48 +46,46 @@ Plunger::Plunger(Kart *kart) : Flyable(kart, POWERUP_PLUNGER)
|
|||||||
m_reverse_mode = kart->getControls().m_look_back;
|
m_reverse_mode = kart->getControls().m_look_back;
|
||||||
|
|
||||||
// find closest kart in front of the current one
|
// find closest kart in front of the current one
|
||||||
const Kart *closest_kart=0; btVector3 direction; float kartDistSquared;
|
const Kart *closest_kart=0;
|
||||||
getClosestKart(&closest_kart, &kartDistSquared, &direction, kart /* search in front of this kart */, m_reverse_mode);
|
Vec3 direction;
|
||||||
|
float kartDistSquared;
|
||||||
|
getClosestKart(&closest_kart, &kartDistSquared, &direction,
|
||||||
|
kart /* search in front of this kart */, m_reverse_mode);
|
||||||
|
|
||||||
btTransform trans = kart->getTrans();
|
btTransform trans = kart->getTrans();
|
||||||
|
|
||||||
btMatrix3x3 thisKartDirMatrix = kart->getKartHeading().getBasis();
|
btMatrix3x3 thisKartDirMatrix = kart->getKartHeading().getBasis();
|
||||||
btVector3 thisKartDirVector(thisKartDirMatrix[0][1],
|
btVector3 thisKartDirVector(thisKartDirMatrix.getColumn(2));
|
||||||
thisKartDirMatrix[1][1],
|
|
||||||
thisKartDirMatrix[2][1]);
|
|
||||||
|
|
||||||
float heading=atan2f(-thisKartDirVector.getX(), thisKartDirVector.getY());
|
float heading=kart->getHeading();
|
||||||
float pitch = kart->getTerrainPitch(heading);
|
float pitch = kart->getTerrainPitch(heading);
|
||||||
|
|
||||||
// aim at this kart if it's not too far
|
// aim at this kart if it's not too far
|
||||||
if(closest_kart != NULL && kartDistSquared < 30*30)
|
if(closest_kart != NULL && kartDistSquared < 30*30)
|
||||||
{
|
{
|
||||||
float fire_angle = 0.0f;
|
float fire_angle = 0.0f;
|
||||||
float time_estimated = 0.0f;
|
getLinearKartItemIntersection (kart->getXYZ(), closest_kart,
|
||||||
getLinearKartItemIntersection (kart->getTrans().getOrigin(), closest_kart,
|
|
||||||
plunger_speed, gravity, y_offset,
|
plunger_speed, gravity, y_offset,
|
||||||
&fire_angle, &up_velocity, &time_estimated);
|
&fire_angle, &up_velocity);
|
||||||
|
|
||||||
// apply transformation to the bullet object (without pitch)
|
trans.setRotation(btQuaternion(btVector3(0, 1, 0), fire_angle));
|
||||||
btMatrix3x3 m;
|
|
||||||
m.setEulerZYX(0.0f, 0.0f, fire_angle);
|
|
||||||
trans.setBasis(m);
|
|
||||||
|
|
||||||
m_initial_velocity = btVector3(0.0f, plunger_speed, up_velocity);
|
m_initial_velocity = btVector3(0.0f, up_velocity, plunger_speed);
|
||||||
|
|
||||||
createPhysics(y_offset, m_initial_velocity,
|
createPhysics(y_offset, m_initial_velocity,
|
||||||
new btCylinderShape(0.5f*m_extend), gravity, false /* rotates */, false, &trans );
|
new btCylinderShape(0.5f*m_extend), gravity,
|
||||||
|
/* rotates */false , /*turn around*/false, &trans );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
trans = kart->getKartHeading();
|
trans = kart->getKartHeading();
|
||||||
|
|
||||||
createPhysics(y_offset, btVector3(pitch, plunger_speed, 0.0f),
|
createPhysics(y_offset, btVector3(pitch, 0.0f, plunger_speed),
|
||||||
new btCylinderShape(0.5f*m_extend), gravity, false /* rotates */, m_reverse_mode, &trans );
|
new btCylinderShape(0.5f*m_extend), gravity, false /* rotates */, m_reverse_mode, &trans );
|
||||||
}
|
}
|
||||||
|
|
||||||
//adjust height according to terrain
|
//adjust height according to terrain
|
||||||
setAdjustZVelocity(true);
|
setAdjustUpVelocity(true);
|
||||||
|
|
||||||
// pulling back makes no sense in battle mode, since this mode is not a race.
|
// pulling back makes no sense in battle mode, since this mode is not a race.
|
||||||
// so in battle mode, always hide view
|
// so in battle mode, always hide view
|
||||||
@ -166,11 +164,10 @@ void Plunger::hit(Kart *kart, PhysicalObject *obj)
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_keep_alive = 0;
|
m_keep_alive = 0;
|
||||||
// Make this object invisible by placing it faaar down. Not that if this
|
// Make this object invisible by placing it faaar down. Note that if this
|
||||||
// objects is simply removed from the scene graph, it might be auto-deleted
|
// objects is simply removed from the scene graph, it might be auto-deleted
|
||||||
// because the ref count reaches zero.
|
// because the ref count reaches zero.
|
||||||
Vec3 hell(0, 0, -10000);
|
getNode()->setVisible(false);
|
||||||
getNode()->setPosition(hell.toIrrVector());
|
|
||||||
World::getWorld()->getPhysics()->removeBody(getBody());
|
World::getWorld()->getPhysics()->removeBody(getBody());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -183,8 +180,7 @@ void Plunger::hit(Kart *kart, PhysicalObject *obj)
|
|||||||
scene::ISceneNode *node = getNode();
|
scene::ISceneNode *node = getNode();
|
||||||
if(node)
|
if(node)
|
||||||
{
|
{
|
||||||
Vec3 hell(0, 0, -10000);
|
node->setVisible(false);
|
||||||
getNode()->setPosition(hell.toIrrVector());
|
|
||||||
}
|
}
|
||||||
World::getWorld()->getPhysics()->removeBody(getBody());
|
World::getWorld()->getPhysics()->removeBody(getBody());
|
||||||
|
|
||||||
|
@ -91,10 +91,10 @@ void RubberBand::updatePosition()
|
|||||||
const float hh=.1f; // half height of the band
|
const float hh=.1f; // half height of the band
|
||||||
const Vec3 &p=m_end_position; // for shorter typing
|
const Vec3 &p=m_end_position; // for shorter typing
|
||||||
irr::video::S3DVertex* v=(video::S3DVertex*)m_buffer->getVertices();
|
irr::video::S3DVertex* v=(video::S3DVertex*)m_buffer->getVertices();
|
||||||
v[0].Pos.X = p.getX()-hh; v[0].Pos.Z=p.getY(); v[0].Pos.Y = p.getZ()-hh;
|
v[0].Pos.X = p.getX()-hh; v[0].Pos.Y=p.getY(); v[0].Pos.Z = p.getZ()-hh;
|
||||||
v[1].Pos.X = p.getX()+hh; v[1].Pos.Z=p.getY(); v[1].Pos.Y = p.getZ()+hh;
|
v[1].Pos.X = p.getX()+hh; v[1].Pos.Y=p.getY(); v[1].Pos.Z = p.getZ()+hh;
|
||||||
v[2].Pos.X = k.getX()+hh; v[2].Pos.Z=k.getY(); v[2].Pos.Y = k.getZ()+hh;
|
v[2].Pos.X = k.getX()+hh; v[2].Pos.Y=k.getY(); v[2].Pos.Z = k.getZ()+hh;
|
||||||
v[3].Pos.X = k.getX()-hh; v[3].Pos.Z=k.getY(); v[3].Pos.Y = k.getZ()-hh;
|
v[3].Pos.X = k.getX()-hh; v[3].Pos.Y=k.getY(); v[3].Pos.Z = k.getZ()-hh;
|
||||||
m_buffer->recalculateBoundingBox();
|
m_buffer->recalculateBoundingBox();
|
||||||
m_mesh->setBoundingBox(m_buffer->getBoundingBox());
|
m_mesh->setBoundingBox(m_buffer->getBoundingBox());
|
||||||
} // updatePosition
|
} // updatePosition
|
||||||
|
@ -299,13 +299,13 @@ void DefaultAIController::handleBraking()
|
|||||||
//We may brake if we are about to get out of the road, but only if the
|
//We may brake if we are about to get out of the road, but only if the
|
||||||
//kart is on top of the road, and if we won't slow down below a certain
|
//kart is on top of the road, and if we won't slow down below a certain
|
||||||
//limit.
|
//limit.
|
||||||
if (m_crashes.m_road && m_kart->getVelocityLC().getY() > MIN_SPEED &&
|
if (m_crashes.m_road && m_kart->getVelocityLC().getZ() > MIN_SPEED &&
|
||||||
m_world->isOnRoad(m_kart->getWorldKartId()) )
|
m_world->isOnRoad(m_kart->getWorldKartId()) )
|
||||||
{
|
{
|
||||||
float kart_ang_diff =
|
float kart_ang_diff =
|
||||||
m_quad_graph->getAngleToNext(m_track_node,
|
m_quad_graph->getAngleToNext(m_track_node,
|
||||||
m_successor_index[m_track_node])
|
m_successor_index[m_track_node])
|
||||||
- m_kart->getHPR().getHeading();
|
- m_kart->getHeading();
|
||||||
kart_ang_diff = normalizeAngle(kart_ang_diff);
|
kart_ang_diff = normalizeAngle(kart_ang_diff);
|
||||||
kart_ang_diff = fabsf(kart_ang_diff);
|
kart_ang_diff = fabsf(kart_ang_diff);
|
||||||
|
|
||||||
@ -341,7 +341,7 @@ void DefaultAIController::handleBraking()
|
|||||||
//Brake if the kart's speed is bigger than the speed we need
|
//Brake if the kart's speed is bigger than the speed we need
|
||||||
//to go through the curve at the widest angle, or if the kart
|
//to go through the curve at the widest angle, or if the kart
|
||||||
//is not going straight in relation to the road.
|
//is not going straight in relation to the road.
|
||||||
if(m_kart->getVelocityLC().getY() > m_curve_target_speed ||
|
if(m_kart->getVelocityLC().getZ() > m_curve_target_speed ||
|
||||||
kart_ang_diff > MIN_TRACK_ANGLE )
|
kart_ang_diff > MIN_TRACK_ANGLE )
|
||||||
{
|
{
|
||||||
#ifdef AI_DEBUG
|
#ifdef AI_DEBUG
|
||||||
@ -778,7 +778,7 @@ float DefaultAIController::steerToAngle(const size_t SECTOR, const float ANGLE)
|
|||||||
m_successor_index[SECTOR]);
|
m_successor_index[SECTOR]);
|
||||||
|
|
||||||
//Desired angle minus current angle equals how many angles to turn
|
//Desired angle minus current angle equals how many angles to turn
|
||||||
float steer_angle = angle - m_kart->getHPR().getHeading();
|
float steer_angle = angle - m_kart->getHeading();
|
||||||
|
|
||||||
if(m_kart->hasViewBlockedByPlunger())
|
if(m_kart->hasViewBlockedByPlunger())
|
||||||
steer_angle += ANGLE/5;
|
steer_angle += ANGLE/5;
|
||||||
@ -802,15 +802,15 @@ float DefaultAIController::steerToPoint(const Vec3 &point, float dt)
|
|||||||
// No sense steering if we are not driving.
|
// No sense steering if we are not driving.
|
||||||
if(m_kart->getSpeed()==0) return 0.0f;
|
if(m_kart->getSpeed()==0) return 0.0f;
|
||||||
const float dx = point.getX() - m_kart->getXYZ().getX();
|
const float dx = point.getX() - m_kart->getXYZ().getX();
|
||||||
const float dy = point.getY() - m_kart->getXYZ().getY();
|
const float dz = point.getZ() - m_kart->getXYZ().getZ();
|
||||||
/** Angle from the kart position to the point in world coordinates. */
|
/** Angle from the kart position to the point in world coordinates. */
|
||||||
float theta = -atan2(dx, dy);
|
float theta = atan2(dx, dz);
|
||||||
|
|
||||||
// Angle is the point is relative to the heading - but take the current
|
// Angle is the point is relative to the heading - but take the current
|
||||||
// angular velocity into account, too. The value is multiplied by two
|
// angular velocity into account, too. The value is multiplied by two
|
||||||
// to avoid 'oversteering' - experimentally found.
|
// to avoid 'oversteering' - experimentally found.
|
||||||
float angle_2_point = theta - m_kart->getHPR().getHeading()
|
float angle_2_point = theta - m_kart->getHeading()
|
||||||
- dt*m_kart->getBody()->getAngularVelocity().getZ()*2.0f;
|
- dt*m_kart->getBody()->getAngularVelocity().getY()*2.0f;
|
||||||
angle_2_point = normalizeAngle(angle_2_point);
|
angle_2_point = normalizeAngle(angle_2_point);
|
||||||
if(fabsf(angle_2_point)<0.1) return 0.0f;
|
if(fabsf(angle_2_point)<0.1) return 0.0f;
|
||||||
|
|
||||||
@ -830,7 +830,7 @@ float DefaultAIController::steerToPoint(const Vec3 &point, float dt)
|
|||||||
float sin_steer_angle = m_kart->getKartProperties()->getWheelBase()/radius;
|
float sin_steer_angle = m_kart->getKartProperties()->getWheelBase()/radius;
|
||||||
#ifdef DEBUG_OUTPUT
|
#ifdef DEBUG_OUTPUT
|
||||||
printf("theta %f a2p %f angularv %f radius %f ssa %f\n",
|
printf("theta %f a2p %f angularv %f radius %f ssa %f\n",
|
||||||
theta, angle_2_point, m_body->getAngularVelocity().getZ(),
|
theta, angle_2_point, m_body->getAngularVelocity().getY(),
|
||||||
radius, sin_steer_angle);
|
radius, sin_steer_angle);
|
||||||
#endif
|
#endif
|
||||||
// Add 0.1 since rouding errors will otherwise result in the kart
|
// Add 0.1 since rouding errors will otherwise result in the kart
|
||||||
@ -857,7 +857,7 @@ void DefaultAIController::checkCrashes( const int STEPS, const Vec3& pos )
|
|||||||
|
|
||||||
//Protection against having vel_normal with nan values
|
//Protection against having vel_normal with nan values
|
||||||
const Vec3 &VEL = m_kart->getVelocity();
|
const Vec3 &VEL = m_kart->getVelocity();
|
||||||
Vec3 vel_normal(VEL.getX(), VEL.getY(), 0.0);
|
Vec3 vel_normal(VEL.getX(), VEL.getZ(), 0.0);
|
||||||
float speed=vel_normal.length();
|
float speed=vel_normal.length();
|
||||||
// If the velocity is zero, no sense in checking for crashes in time
|
// If the velocity is zero, no sense in checking for crashes in time
|
||||||
if(speed==0) return;
|
if(speed==0) return;
|
||||||
@ -882,7 +882,7 @@ void DefaultAIController::checkCrashes( const int STEPS, const Vec3& pos )
|
|||||||
if(kart==m_kart||kart->isEliminated()) continue; // ignore eliminated karts
|
if(kart==m_kart||kart->isEliminated()) continue; // ignore eliminated karts
|
||||||
const Kart *other_kart = m_world->getKart(j);
|
const Kart *other_kart = m_world->getKart(j);
|
||||||
// Ignore karts ahead that are faster than this kart.
|
// Ignore karts ahead that are faster than this kart.
|
||||||
if(m_kart->getVelocityLC().getY() < other_kart->getVelocityLC().getY())
|
if(m_kart->getVelocityLC().getZ() < other_kart->getVelocityLC().getZ())
|
||||||
continue;
|
continue;
|
||||||
Vec3 other_kart_xyz = other_kart->getXYZ() + other_kart->getVelocity()*(i*dt);
|
Vec3 other_kart_xyz = other_kart->getXYZ() + other_kart->getVelocity()*(i*dt);
|
||||||
float kart_distance = (step_coord - other_kart_xyz).length_2d();
|
float kart_distance = (step_coord - other_kart_xyz).length_2d();
|
||||||
@ -1012,7 +1012,7 @@ inline float DefaultAIController::normalizeAngle(float angle)
|
|||||||
*/
|
*/
|
||||||
int DefaultAIController::calcSteps()
|
int DefaultAIController::calcSteps()
|
||||||
{
|
{
|
||||||
int steps = int( m_kart->getVelocityLC().getY() / m_kart_length );
|
int steps = int( m_kart->getVelocityLC().getZ() / m_kart_length );
|
||||||
if( steps < m_min_steps ) steps = m_min_steps;
|
if( steps < m_min_steps ) steps = m_min_steps;
|
||||||
|
|
||||||
//Increase the steps depending on the width, if we steering hard,
|
//Increase the steps depending on the width, if we steering hard,
|
||||||
@ -1086,7 +1086,7 @@ void DefaultAIController::findCurve()
|
|||||||
{
|
{
|
||||||
float total_dist = 0.0f;
|
float total_dist = 0.0f;
|
||||||
int i;
|
int i;
|
||||||
for(i = m_track_node; total_dist < m_kart->getVelocityLC().getY();
|
for(i = m_track_node; total_dist < m_kart->getVelocityLC().getZ();
|
||||||
i = m_next_node_index[i])
|
i = m_next_node_index[i])
|
||||||
{
|
{
|
||||||
total_dist += m_quad_graph->getDistanceToNext(i, m_successor_index[i]);
|
total_dist += m_quad_graph->getDistanceToNext(i, m_successor_index[i]);
|
||||||
|
@ -301,7 +301,7 @@ float EndController::steerToAngle(const size_t SECTOR, const float ANGLE)
|
|||||||
m_successor_index[SECTOR]);
|
m_successor_index[SECTOR]);
|
||||||
|
|
||||||
//Desired angle minus current angle equals how many angles to turn
|
//Desired angle minus current angle equals how many angles to turn
|
||||||
float steer_angle = angle - m_kart->getHPR().getHeading();
|
float steer_angle = angle - m_kart->getHeading();
|
||||||
|
|
||||||
if(m_kart->hasViewBlockedByPlunger())
|
if(m_kart->hasViewBlockedByPlunger())
|
||||||
steer_angle += ANGLE/5;
|
steer_angle += ANGLE/5;
|
||||||
@ -325,15 +325,15 @@ float EndController::steerToPoint(const Vec3 &point, float dt)
|
|||||||
// No sense steering if we are not driving.
|
// No sense steering if we are not driving.
|
||||||
if(m_kart->getSpeed()==0) return 0.0f;
|
if(m_kart->getSpeed()==0) return 0.0f;
|
||||||
const float dx = point.getX() - m_kart->getXYZ().getX();
|
const float dx = point.getX() - m_kart->getXYZ().getX();
|
||||||
const float dy = point.getY() - m_kart->getXYZ().getY();
|
const float dz = point.getZ() - m_kart->getXYZ().getZ();
|
||||||
/** Angle from the kart position to the point in world coordinates. */
|
/** Angle from the kart position to the point in world coordinates. */
|
||||||
float theta = -atan2(dx, dy);
|
float theta = atan2(dx, dz);
|
||||||
|
|
||||||
// Angle is the point is relative to the heading - but take the current
|
// Angle is the point is relative to the heading - but take the current
|
||||||
// angular velocity into account, too. The value is multiplied by two
|
// angular velocity into account, too. The value is multiplied by two
|
||||||
// to avoid 'oversteering' - experimentally found.
|
// to avoid 'oversteering' - experimentally found.
|
||||||
float angle_2_point = theta - m_kart->getHPR().getHeading()
|
float angle_2_point = theta - m_kart->getHeading()
|
||||||
- dt*m_kart->getBody()->getAngularVelocity().getZ()*2.0f;
|
- dt*m_kart->getBody()->getAngularVelocity().getY()*2.0f;
|
||||||
angle_2_point = normalizeAngle(angle_2_point);
|
angle_2_point = normalizeAngle(angle_2_point);
|
||||||
if(fabsf(angle_2_point)<0.1) return 0.0f;
|
if(fabsf(angle_2_point)<0.1) return 0.0f;
|
||||||
|
|
||||||
@ -353,7 +353,7 @@ float EndController::steerToPoint(const Vec3 &point, float dt)
|
|||||||
float sin_steer_angle = m_kart->getKartProperties()->getWheelBase()/radius;
|
float sin_steer_angle = m_kart->getKartProperties()->getWheelBase()/radius;
|
||||||
#ifdef DEBUG_OUTPUT
|
#ifdef DEBUG_OUTPUT
|
||||||
printf("theta %f a2p %f angularv %f radius %f ssa %f\n",
|
printf("theta %f a2p %f angularv %f radius %f ssa %f\n",
|
||||||
theta, angle_2_point, m_body->getAngularVelocity().getZ(),
|
theta, angle_2_point, m_body->getAngularVelocity().getY(),
|
||||||
radius, sin_steer_angle);
|
radius, sin_steer_angle);
|
||||||
#endif
|
#endif
|
||||||
// Add 0.1 since rouding errors will otherwise result in the kart
|
// Add 0.1 since rouding errors will otherwise result in the kart
|
||||||
@ -463,7 +463,7 @@ inline float EndController::normalizeAngle(float angle)
|
|||||||
*/
|
*/
|
||||||
int EndController::calcSteps()
|
int EndController::calcSteps()
|
||||||
{
|
{
|
||||||
int steps = int( m_kart->getVelocityLC().getY() / m_kart_length );
|
int steps = int( m_kart->getVelocityLC().getZ() / m_kart_length );
|
||||||
if( steps < m_min_steps ) steps = m_min_steps;
|
if( steps < m_min_steps ) steps = m_min_steps;
|
||||||
|
|
||||||
//Increase the steps depending on the width, if we steering hard,
|
//Increase the steps depending on the width, if we steering hard,
|
||||||
@ -537,7 +537,7 @@ void EndController::findCurve()
|
|||||||
{
|
{
|
||||||
float total_dist = 0.0f;
|
float total_dist = 0.0f;
|
||||||
int i;
|
int i;
|
||||||
for(i = m_track_node; total_dist < m_kart->getVelocityLC().getY();
|
for(i = m_track_node; total_dist < m_kart->getVelocityLC().getZ();
|
||||||
i = m_next_node_index[i])
|
i = m_next_node_index[i])
|
||||||
{
|
{
|
||||||
total_dist += m_quad_graph->getDistanceToNext(i, m_successor_index[i]);
|
total_dist += m_quad_graph->getDistanceToNext(i, m_successor_index[i]);
|
||||||
|
@ -295,13 +295,13 @@ void NewAIController::handleBraking()
|
|||||||
//We may brake if we are about to get out of the road, but only if the
|
//We may brake if we are about to get out of the road, but only if the
|
||||||
//kart is on top of the road, and if we won't slow down below a certain
|
//kart is on top of the road, and if we won't slow down below a certain
|
||||||
//limit.
|
//limit.
|
||||||
if (m_crashes.m_road && m_kart->getVelocityLC().getY() > MIN_SPEED &&
|
if (m_crashes.m_road && m_kart->getVelocityLC().getZ() > MIN_SPEED &&
|
||||||
m_world->isOnRoad(m_kart->getWorldKartId()) )
|
m_world->isOnRoad(m_kart->getWorldKartId()) )
|
||||||
{
|
{
|
||||||
float kart_ang_diff =
|
float kart_ang_diff =
|
||||||
m_quad_graph->getAngleToNext(m_track_node,
|
m_quad_graph->getAngleToNext(m_track_node,
|
||||||
m_successor_index[m_track_node])
|
m_successor_index[m_track_node])
|
||||||
- m_kart->getHPR().getHeading();
|
- m_kart->getHeading();
|
||||||
kart_ang_diff = normalizeAngle(kart_ang_diff);
|
kart_ang_diff = normalizeAngle(kart_ang_diff);
|
||||||
kart_ang_diff = fabsf(kart_ang_diff);
|
kart_ang_diff = fabsf(kart_ang_diff);
|
||||||
|
|
||||||
@ -337,7 +337,7 @@ void NewAIController::handleBraking()
|
|||||||
//Brake if the kart's speed is bigger than the speed we need
|
//Brake if the kart's speed is bigger than the speed we need
|
||||||
//to go through the curve at the widest angle, or if the kart
|
//to go through the curve at the widest angle, or if the kart
|
||||||
//is not going straight in relation to the road.
|
//is not going straight in relation to the road.
|
||||||
if(m_kart->getVelocityLC().getY() > m_curve_target_speed ||
|
if(m_kart->getVelocityLC().getZ() > m_curve_target_speed ||
|
||||||
kart_ang_diff > MIN_TRACK_ANGLE )
|
kart_ang_diff > MIN_TRACK_ANGLE )
|
||||||
{
|
{
|
||||||
#ifdef AI_DEBUG
|
#ifdef AI_DEBUG
|
||||||
@ -765,7 +765,7 @@ float NewAIController::steerToAngle(const size_t SECTOR, const float ANGLE)
|
|||||||
m_successor_index[SECTOR]);
|
m_successor_index[SECTOR]);
|
||||||
|
|
||||||
//Desired angle minus current angle equals how many angles to turn
|
//Desired angle minus current angle equals how many angles to turn
|
||||||
float steer_angle = angle - m_kart->getHPR().getHeading();
|
float steer_angle = angle - m_kart->getHeading();
|
||||||
|
|
||||||
if(m_kart->hasViewBlockedByPlunger())
|
if(m_kart->hasViewBlockedByPlunger())
|
||||||
steer_angle += ANGLE/5;
|
steer_angle += ANGLE/5;
|
||||||
@ -789,15 +789,15 @@ float NewAIController::steerToPoint(const Vec3 &point, float dt)
|
|||||||
// No sense steering if we are not driving.
|
// No sense steering if we are not driving.
|
||||||
if(m_kart->getSpeed()==0) return 0.0f;
|
if(m_kart->getSpeed()==0) return 0.0f;
|
||||||
const float dx = point.getX() - m_kart->getXYZ().getX();
|
const float dx = point.getX() - m_kart->getXYZ().getX();
|
||||||
const float dy = point.getY() - m_kart->getXYZ().getY();
|
const float dz = point.getZ() - m_kart->getXYZ().getZ();
|
||||||
/** Angle from the kart position to the point in world coordinates. */
|
/** Angle from the kart position to the point in world coordinates. */
|
||||||
float theta = -atan2(dx, dy);
|
float theta = atan2(dx, dz);
|
||||||
|
|
||||||
// Angle is the point is relative to the heading - but take the current
|
// Angle is the point is relative to the heading - but take the current
|
||||||
// angular velocity into account, too. The value is multiplied by two
|
// angular velocity into account, too. The value is multiplied by two
|
||||||
// to avoid 'oversteering' - experimentally found.
|
// to avoid 'oversteering' - experimentally found.
|
||||||
float angle_2_point = theta - m_kart->getHPR().getHeading()
|
float angle_2_point = theta - m_kart->getHeading()
|
||||||
- dt*m_kart->getBody()->getAngularVelocity().getZ()*2.0f;
|
- dt*m_kart->getBody()->getAngularVelocity().getY()*2.0f;
|
||||||
angle_2_point = normalizeAngle(angle_2_point);
|
angle_2_point = normalizeAngle(angle_2_point);
|
||||||
if(fabsf(angle_2_point)<0.1) return 0.0f;
|
if(fabsf(angle_2_point)<0.1) return 0.0f;
|
||||||
|
|
||||||
@ -817,7 +817,7 @@ float NewAIController::steerToPoint(const Vec3 &point, float dt)
|
|||||||
float sin_steer_angle = m_kart->getKartProperties()->getWheelBase()/radius;
|
float sin_steer_angle = m_kart->getKartProperties()->getWheelBase()/radius;
|
||||||
#ifdef DEBUG_OUTPUT
|
#ifdef DEBUG_OUTPUT
|
||||||
printf("theta %f a2p %f angularv %f radius %f ssa %f\n",
|
printf("theta %f a2p %f angularv %f radius %f ssa %f\n",
|
||||||
theta, angle_2_point, m_body->getAngularVelocity().getZ(),
|
theta, angle_2_point, m_body->getAngularVelocity().getY(),
|
||||||
radius, sin_steer_angle);
|
radius, sin_steer_angle);
|
||||||
#endif
|
#endif
|
||||||
// Add 0.1 since rouding errors will otherwise result in the kart
|
// Add 0.1 since rouding errors will otherwise result in the kart
|
||||||
@ -904,10 +904,10 @@ float NewAIController::findNonCrashingAngle()
|
|||||||
|
|
||||||
float very_right = -atan2(right.getX()-xyz.getX(),
|
float very_right = -atan2(right.getX()-xyz.getX(),
|
||||||
right.getY()-xyz.getY())
|
right.getY()-xyz.getY())
|
||||||
- m_kart->getHPR().getHeading();
|
- m_kart->getHeading();
|
||||||
float very_left = -atan2(left.getX()-xyz.getX(),
|
float very_left = -atan2(left.getX()-xyz.getX(),
|
||||||
left.getY()-xyz.getY())
|
left.getY()-xyz.getY())
|
||||||
- m_kart->getHPR().getHeading();
|
- m_kart->getHeading();
|
||||||
very_left = normalizeAngle(very_left);
|
very_left = normalizeAngle(very_left);
|
||||||
very_right = normalizeAngle(very_right);
|
very_right = normalizeAngle(very_right);
|
||||||
float dist = 0;
|
float dist = 0;
|
||||||
@ -920,10 +920,10 @@ float NewAIController::findNonCrashingAngle()
|
|||||||
|
|
||||||
float angle_right = -atan2(right.getX()-xyz.getX(),
|
float angle_right = -atan2(right.getX()-xyz.getX(),
|
||||||
right.getY()-xyz.getY())
|
right.getY()-xyz.getY())
|
||||||
- m_kart->getHPR().getHeading();
|
- m_kart->getHeading();
|
||||||
float angle_left = -atan2(left.getX()-xyz.getX(),
|
float angle_left = -atan2(left.getX()-xyz.getX(),
|
||||||
left.getY()-xyz.getY())
|
left.getY()-xyz.getY())
|
||||||
- m_kart->getHPR().getHeading();
|
- m_kart->getHeading();
|
||||||
angle_left = normalizeAngle(angle_left);
|
angle_left = normalizeAngle(angle_left);
|
||||||
angle_right = normalizeAngle(angle_right);
|
angle_right = normalizeAngle(angle_right);
|
||||||
|
|
||||||
|
@ -118,17 +118,17 @@ void PlayerController::action(PlayerAction action, int value)
|
|||||||
switch (action)
|
switch (action)
|
||||||
{
|
{
|
||||||
case PA_LEFT:
|
case PA_LEFT:
|
||||||
m_steer_val_l = -value;
|
m_steer_val_l = value;
|
||||||
if (value)
|
if (value)
|
||||||
m_steer_val = -value;
|
m_steer_val = value;
|
||||||
else
|
else
|
||||||
m_steer_val = m_steer_val_r;
|
m_steer_val = m_steer_val_r;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case PA_RIGHT:
|
case PA_RIGHT:
|
||||||
m_steer_val_r = value;
|
m_steer_val_r = -value;
|
||||||
if (value)
|
if (value)
|
||||||
m_steer_val = value;
|
m_steer_val = -value;
|
||||||
else
|
else
|
||||||
m_steer_val = m_steer_val_l;
|
m_steer_val = m_steer_val_l;
|
||||||
|
|
||||||
|
@ -80,7 +80,6 @@ Kart::Kart (const std::string& ident, int position,
|
|||||||
m_nitro = NULL;
|
m_nitro = NULL;
|
||||||
m_slip_stream = NULL;
|
m_slip_stream = NULL;
|
||||||
m_skidmarks = NULL;
|
m_skidmarks = NULL;
|
||||||
m_animated_node = NULL;
|
|
||||||
m_camera = NULL;
|
m_camera = NULL;
|
||||||
m_controller = NULL;
|
m_controller = NULL;
|
||||||
m_saved_controller = NULL;
|
m_saved_controller = NULL;
|
||||||
@ -133,12 +132,12 @@ Kart::Kart (const std::string& ident, int position,
|
|||||||
}
|
}
|
||||||
|
|
||||||
loadData();
|
loadData();
|
||||||
float l = m_kart_properties->getSlipstreamLength();
|
float length = m_kart_properties->getSlipstreamLength();
|
||||||
|
|
||||||
Vec3 p0(-getKartWidth()*0.5f, -getKartLength()*0.5f, 0);
|
Vec3 p0(-getKartWidth()*0.5f, 0, -getKartLength()*0.5f );
|
||||||
Vec3 p1(-getKartWidth()*0.5f, -getKartLength()*0.5f-l, 0);
|
Vec3 p1(-getKartWidth()*0.5f, 0, -getKartLength()*0.5f-length);
|
||||||
Vec3 p2( getKartWidth()*0.5f, -getKartLength()*0.5f-l, 0);
|
Vec3 p2( getKartWidth()*0.5f, 0, -getKartLength()*0.5f-length);
|
||||||
Vec3 p3( getKartWidth()*0.5f, -getKartLength()*0.5f, 0);
|
Vec3 p3( getKartWidth()*0.5f, 0, -getKartLength()*0.5f );
|
||||||
m_slipstream_original_quad = new Quad(p0, p1, p2, p3);
|
m_slipstream_original_quad = new Quad(p0, p1, p2, p3);
|
||||||
m_slipstream_quad = new Quad(p0, p1, p2, p3);
|
m_slipstream_quad = new Quad(p0, p1, p2, p3);
|
||||||
|
|
||||||
@ -162,25 +161,21 @@ void Kart::setController(Controller *controller)
|
|||||||
|
|
||||||
btTransform Kart::getKartHeading(const float customPitch)
|
btTransform Kart::getKartHeading(const float customPitch)
|
||||||
{
|
{
|
||||||
btTransform trans = this->getTrans();
|
btTransform trans = getTrans();
|
||||||
|
|
||||||
// get heading=trans.getBasis*(0,1,0) ... so save the multiplication:
|
float pitch = (customPitch == -1 ? getTerrainPitch(getHeading()) : customPitch);
|
||||||
btVector3 direction(trans.getBasis()[0][1],
|
|
||||||
trans.getBasis()[1][1],
|
|
||||||
trans.getBasis()[2][1]);
|
|
||||||
float heading=atan2(-direction.getX(), direction.getY());
|
|
||||||
|
|
||||||
TerrainInfo::update(this->getXYZ());
|
|
||||||
float pitch = (customPitch == -1 ? getTerrainPitch(heading) : customPitch);
|
|
||||||
|
|
||||||
btMatrix3x3 m;
|
btMatrix3x3 m;
|
||||||
m.setEulerZYX(pitch, 0.0f, heading);
|
m.setEulerYPR(-getHeading(), pitch, 0.0f);
|
||||||
trans.setBasis(m);
|
trans.setBasis(m);
|
||||||
|
|
||||||
return trans;
|
return trans;
|
||||||
} // getKartHeading
|
} // getKartHeading
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
/** Created the physical representation of this kart. Atm it uses the actual
|
||||||
|
* extention of the kart model to determine the size of the collision body.
|
||||||
|
*/
|
||||||
void Kart::createPhysics()
|
void Kart::createPhysics()
|
||||||
{
|
{
|
||||||
// First: Create the chassis of the kart
|
// First: Create the chassis of the kart
|
||||||
@ -191,8 +186,8 @@ void Kart::createPhysics()
|
|||||||
float kart_height = km->getHeight();
|
float kart_height = km->getHeight();
|
||||||
|
|
||||||
btBoxShape *shape = new btBoxShape(btVector3(0.5f*kart_width,
|
btBoxShape *shape = new btBoxShape(btVector3(0.5f*kart_width,
|
||||||
0.5f*kart_length,
|
0.5f*kart_height,
|
||||||
0.5f*kart_height));
|
0.5f*kart_length));
|
||||||
btTransform shiftCenterOfGravity;
|
btTransform shiftCenterOfGravity;
|
||||||
shiftCenterOfGravity.setIdentity();
|
shiftCenterOfGravity.setIdentity();
|
||||||
// Shift center of gravity downwards, so that the kart
|
// Shift center of gravity downwards, so that the kart
|
||||||
@ -229,15 +224,15 @@ void Kart::createPhysics()
|
|||||||
|
|
||||||
// never deactivate the vehicle
|
// never deactivate the vehicle
|
||||||
m_body->setActivationState(DISABLE_DEACTIVATION);
|
m_body->setActivationState(DISABLE_DEACTIVATION);
|
||||||
m_vehicle->setCoordinateSystem(/*right: */ 0, /*up: */ 2, /*forward: */ 1);
|
m_vehicle->setCoordinateSystem(/*right: */ 0, /*up: */ 1, /*forward: */ 2);
|
||||||
|
|
||||||
// Add wheels
|
// Add wheels
|
||||||
// ----------
|
// ----------
|
||||||
float wheel_radius = m_kart_properties->getWheelRadius();
|
float wheel_radius = m_kart_properties->getWheelRadius();
|
||||||
float suspension_rest = m_kart_properties->getSuspensionRest();
|
float suspension_rest = m_kart_properties->getSuspensionRest();
|
||||||
|
|
||||||
btVector3 wheel_direction(0.0f, 0.0f, -1.0f);
|
btVector3 wheel_direction(0.0f, -1.0f, 0.0f);
|
||||||
btVector3 wheel_axle(1.0f,0.0f,0.0f);
|
btVector3 wheel_axle(-1.0f, 0.0f, 0.0f);
|
||||||
|
|
||||||
for(unsigned int i=0; i<4; i++)
|
for(unsigned int i=0; i<4; i++)
|
||||||
{
|
{
|
||||||
@ -255,7 +250,7 @@ void Kart::createPhysics()
|
|||||||
// Obviously these allocs have to be properly managed/freed
|
// Obviously these allocs have to be properly managed/freed
|
||||||
btTransform t;
|
btTransform t;
|
||||||
t.setIdentity();
|
t.setIdentity();
|
||||||
m_uprightConstraint=new btUprightConstraint(*m_body, t);
|
m_uprightConstraint=new btUprightConstraint(this, t);
|
||||||
m_uprightConstraint->setLimit(m_kart_properties->getUprightTolerance());
|
m_uprightConstraint->setLimit(m_kart_properties->getUprightTolerance());
|
||||||
m_uprightConstraint->setBounce(0.0f);
|
m_uprightConstraint->setBounce(0.0f);
|
||||||
m_uprightConstraint->setMaxLimitForce(m_kart_properties->getUprightMaxForce());
|
m_uprightConstraint->setMaxLimitForce(m_kart_properties->getUprightMaxForce());
|
||||||
@ -393,10 +388,6 @@ void Kart::reset()
|
|||||||
m_controller = m_saved_controller;
|
m_controller = m_saved_controller;
|
||||||
m_saved_controller = NULL;
|
m_saved_controller = NULL;
|
||||||
}
|
}
|
||||||
// Reset is also called when the kart is created, at which time
|
|
||||||
// m_controller is not yet defined.
|
|
||||||
if(m_controller)
|
|
||||||
m_controller->reset();
|
|
||||||
m_kart_properties->getKartModel()->setEndAnimation(false);
|
m_kart_properties->getKartModel()->setEndAnimation(false);
|
||||||
m_view_blocked_by_plunger = 0.0;
|
m_view_blocked_by_plunger = 0.0;
|
||||||
m_attachment.clear();
|
m_attachment.clear();
|
||||||
@ -443,6 +434,12 @@ void Kart::reset()
|
|||||||
}
|
}
|
||||||
|
|
||||||
TerrainInfo::update(getXYZ());
|
TerrainInfo::update(getXYZ());
|
||||||
|
|
||||||
|
// Reset is also called when the kart is created, at which time
|
||||||
|
// m_controller is not yet defined, so this has to be tested here.
|
||||||
|
if(m_controller)
|
||||||
|
m_controller->reset();
|
||||||
|
|
||||||
} // reset
|
} // reset
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -681,7 +678,6 @@ void Kart::update(float dt)
|
|||||||
else
|
else
|
||||||
m_uprightConstraint->setLimit(m_kart_properties->getUprightTolerance());
|
m_uprightConstraint->setLimit(m_kart_properties->getUprightTolerance());
|
||||||
|
|
||||||
|
|
||||||
m_zipper_time_left = m_zipper_time_left>0.0f ? m_zipper_time_left-dt : 0.0f;
|
m_zipper_time_left = m_zipper_time_left>0.0f ? m_zipper_time_left-dt : 0.0f;
|
||||||
|
|
||||||
//m_wheel_rotation gives the rotation around the X-axis, and since velocity's
|
//m_wheel_rotation gives the rotation around the X-axis, and since velocity's
|
||||||
@ -703,11 +699,11 @@ void Kart::update(float dt)
|
|||||||
}
|
}
|
||||||
World::getWorld()->getPhysics()->removeKart(this);
|
World::getWorld()->getPhysics()->removeKart(this);
|
||||||
|
|
||||||
btQuaternion q_roll (btVector3(0.f, 1.f, 0.f),
|
btQuaternion q_roll (btVector3(0.0f, 0.0f, 1.0f),
|
||||||
-m_rescue_roll*dt/rescue_time*M_PI/180.0f);
|
-m_rescue_roll*dt/rescue_time*M_PI/180.0f);
|
||||||
btQuaternion q_pitch(btVector3(1.f, 0.f, 0.f),
|
btQuaternion q_pitch(btVector3(1.f, 0.f, 0.f),
|
||||||
-m_rescue_pitch*dt/rescue_time*M_PI/180.0f);
|
-m_rescue_pitch*dt/rescue_time*M_PI/180.0f);
|
||||||
setXYZRotation(getXYZ()+Vec3(0, 0, rescue_height*dt/rescue_time),
|
setXYZRotation(getXYZ()+Vec3(0, rescue_height*dt/rescue_time, 0),
|
||||||
getRotation()*q_roll*q_pitch);
|
getRotation()*q_roll*q_pitch);
|
||||||
} // if rescue mode
|
} // if rescue mode
|
||||||
m_attachment.update(dt);
|
m_attachment.update(dt);
|
||||||
@ -1136,30 +1132,25 @@ void Kart::updatePhysics (float dt)
|
|||||||
if(f<0.1f) f=0.1f;
|
if(f<0.1f) f=0.1f;
|
||||||
applyEngineForce(-engine_power*f);
|
applyEngineForce(-engine_power*f);
|
||||||
}
|
}
|
||||||
else
|
else // -m_speed >= max speed on this terrain
|
||||||
{
|
{
|
||||||
applyEngineForce(0.0f);
|
applyEngineForce(0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // m_speed <00
|
||||||
}
|
}
|
||||||
}
|
else // !m_brake
|
||||||
else
|
|
||||||
{
|
{
|
||||||
// lift the foot from throttle, brakes with 10% engine_power
|
// lift the foot from throttle, brakes with 10% engine_power
|
||||||
applyEngineForce(-m_controls.m_accel*engine_power*0.1f);
|
applyEngineForce(-m_controls.m_accel*engine_power*0.1f);
|
||||||
|
|
||||||
#if 1
|
|
||||||
// If not giving power (forward or reverse gear), and speed is low
|
// If not giving power (forward or reverse gear), and speed is low
|
||||||
// we are "parking" the kart, so in battle mode we can ambush people, eg
|
// we are "parking" the kart, so in battle mode we can ambush people, eg
|
||||||
if(abs(m_speed) < 5.0f) {
|
if(abs(m_speed) < 5.0f) {
|
||||||
for(int i=0; i<4; i++) m_vehicle->setBrake(20.0f, i);
|
for(int i=0; i<4; i++) m_vehicle->setBrake(20.0f, i);
|
||||||
}
|
}
|
||||||
#else
|
} // !m_brake
|
||||||
if(!RaceManager::getWorld()->isStartPhase())
|
} // not accelerating
|
||||||
resetBrakes();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#ifdef ENABLE_JUMP
|
#ifdef ENABLE_JUMP
|
||||||
if(m_controls.jump && isOnGround())
|
if(m_controls.jump && isOnGround())
|
||||||
{
|
{
|
||||||
@ -1213,9 +1204,9 @@ void Kart::updatePhysics (float dt)
|
|||||||
// calculate direction of m_speed
|
// calculate direction of m_speed
|
||||||
const btTransform& chassisTrans = getVehicle()->getChassisWorldTransform();
|
const btTransform& chassisTrans = getVehicle()->getChassisWorldTransform();
|
||||||
btVector3 forwardW (
|
btVector3 forwardW (
|
||||||
chassisTrans.getBasis()[0][1],
|
chassisTrans.getBasis()[0][2],
|
||||||
chassisTrans.getBasis()[1][1],
|
chassisTrans.getBasis()[1][2],
|
||||||
chassisTrans.getBasis()[2][1]);
|
chassisTrans.getBasis()[2][2]);
|
||||||
|
|
||||||
if (forwardW.dot(getVehicle()->getRigidBody()->getLinearVelocity()) < btScalar(0.))
|
if (forwardW.dot(getVehicle()->getRigidBody()->getLinearVelocity()) < btScalar(0.))
|
||||||
m_speed *= -1.f;
|
m_speed *= -1.f;
|
||||||
@ -1228,7 +1219,7 @@ void Kart::updatePhysics (float dt)
|
|||||||
m_speed = max_speed;
|
m_speed = max_speed;
|
||||||
btVector3 velocity = m_body->getLinearVelocity();
|
btVector3 velocity = m_body->getLinearVelocity();
|
||||||
|
|
||||||
velocity.setY( velocity.getY() * velocity_ratio );
|
velocity.setZ( velocity.getZ() * velocity_ratio );
|
||||||
velocity.setX( velocity.getX() * velocity_ratio );
|
velocity.setX( velocity.getX() * velocity_ratio );
|
||||||
|
|
||||||
getVehicle()->getRigidBody()->setLinearVelocity( velocity );
|
getVehicle()->getRigidBody()->setLinearVelocity( velocity );
|
||||||
@ -1243,11 +1234,11 @@ void Kart::updatePhysics (float dt)
|
|||||||
// to suspensionTravel / dt with dt = 1/60 (since this is the dt
|
// to suspensionTravel / dt with dt = 1/60 (since this is the dt
|
||||||
// bullet is using).
|
// bullet is using).
|
||||||
const Vec3 &v = m_body->getLinearVelocity();
|
const Vec3 &v = m_body->getLinearVelocity();
|
||||||
if(v.getZ() < - m_kart_properties->getSuspensionTravelCM()*0.01f*60)
|
if(v.getY() < - m_kart_properties->getSuspensionTravelCM()*0.01f*60)
|
||||||
{
|
{
|
||||||
Vec3 v_clamped = v;
|
Vec3 v_clamped = v;
|
||||||
// clamp the speed to 99% of the maxium falling speed.
|
// clamp the speed to 99% of the maxium falling speed.
|
||||||
v_clamped.setZ(-m_kart_properties->getSuspensionTravelCM()*0.01f*60 * 0.99f);
|
v_clamped.setY(-m_kart_properties->getSuspensionTravelCM()*0.01f*60 * 0.99f);
|
||||||
m_body->setLinearVelocity(v_clamped);
|
m_body->setLinearVelocity(v_clamped);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1313,7 +1304,7 @@ void Kart::endRescue()
|
|||||||
|
|
||||||
void Kart::loadData()
|
void Kart::loadData()
|
||||||
{
|
{
|
||||||
m_kart_properties->getKartModel()->attachModel(&m_animated_node);
|
m_kart_properties->getKartModel()->attachModel(&m_node);
|
||||||
createPhysics();
|
createPhysics();
|
||||||
|
|
||||||
// Attach Particle System
|
// Attach Particle System
|
||||||
@ -1326,9 +1317,9 @@ void Kart::loadData()
|
|||||||
m_skidmarks = new SkidMarks(*this);
|
m_skidmarks = new SkidMarks(*this);
|
||||||
|
|
||||||
m_shadow = new Shadow(m_kart_properties->getShadowTexture(),
|
m_shadow = new Shadow(m_kart_properties->getShadowTexture(),
|
||||||
m_animated_node);
|
m_node);
|
||||||
|
|
||||||
m_stars_effect = new Stars(m_animated_node);
|
m_stars_effect = new Stars(m_node);
|
||||||
} // loadData
|
} // loadData
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -1374,32 +1365,42 @@ void Kart::applyEngineForce(float force)
|
|||||||
} // applyEngineForce
|
} // applyEngineForce
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void Kart::updateGraphics(const Vec3& off_xyz, const Vec3& off_hpr)
|
void Kart::updateGraphics(const Vec3& offset_xyz,
|
||||||
|
const btQuaternion& rotation)
|
||||||
|
/** Updates the graphics model. Mainly set the graphical position to be the
|
||||||
|
* same as the physics position, but uses offsets to position and rotation
|
||||||
|
* for special gfx effects (e.g. skidding will turn the karts more). These
|
||||||
|
* variables are actually not used here atm, but are defined here and then
|
||||||
|
* used in Moveable.
|
||||||
|
* \param offset_xyz Offset to be added to the position.
|
||||||
|
* \param rotation Additional rotation.
|
||||||
|
*/
|
||||||
{
|
{
|
||||||
float wheel_z_axis[4];
|
float wheel_up_axis[4];
|
||||||
KartModel *kart_model = m_kart_properties->getKartModel();
|
KartModel *kart_model = m_kart_properties->getKartModel();
|
||||||
for(unsigned int i=0; i<4; i++)
|
for(unsigned int i=0; i<4; i++)
|
||||||
{
|
{
|
||||||
// Set the suspension length
|
// Set the suspension length
|
||||||
wheel_z_axis[i] = m_default_suspension_length[i]
|
wheel_up_axis[i] = m_default_suspension_length[i]
|
||||||
- m_vehicle->getWheelInfo(i).m_raycastInfo.m_suspensionLength;
|
- m_vehicle->getWheelInfo(i).m_raycastInfo.m_suspensionLength;
|
||||||
}
|
}
|
||||||
#define AUTO_SKID_VISUAL 1.7f
|
const float auto_skid_visual=1.7f;
|
||||||
float auto_skid;
|
float auto_skid;
|
||||||
if (m_skidding>AUTO_SKID_VISUAL) // Above a limit, start counter rotating the wheels to get drifting look
|
// FIXME
|
||||||
auto_skid = m_controls.m_steer*30.0f*((AUTO_SKID_VISUAL - m_skidding) / 0.8f); // divisor comes from max_skid - AUTO_SKID_VISUAL
|
// if (m_skidding>auto_skid_visual) // Above a limit, start counter rotating the wheels to get drifting look
|
||||||
else
|
// auto_skid = m_controls.m_steer*30.0f*((auto_skid_visual - m_skidding) / 0.8f); // divisor comes from max_skid - AUTO_SKID_VISUAL
|
||||||
|
// else
|
||||||
auto_skid = m_controls.m_steer*30.0f;
|
auto_skid = m_controls.m_steer*30.0f;
|
||||||
kart_model->update(m_wheel_rotation, auto_skid,
|
kart_model->update(m_wheel_rotation, auto_skid,
|
||||||
getSteerPercent(), wheel_z_axis);
|
getSteerPercent(), wheel_up_axis);
|
||||||
|
|
||||||
Vec3 center_shift = getGravityCenterShift();
|
Vec3 center_shift = getGravityCenterShift();
|
||||||
float X = m_vehicle->getWheelInfo(0).m_chassisConnectionPointCS.getZ()
|
float y = m_vehicle->getWheelInfo(0).m_chassisConnectionPointCS.getY()
|
||||||
- m_default_suspension_length[0]
|
- m_default_suspension_length[0]
|
||||||
- m_vehicle->getWheelInfo(0).m_wheelsRadius
|
- m_vehicle->getWheelInfo(0).m_wheelsRadius
|
||||||
- (kart_model->getWheelGraphicsRadius(0)
|
- (kart_model->getWheelGraphicsRadius(0)
|
||||||
-kart_model->getWheelGraphicsPosition(0).getZ() );
|
-kart_model->getWheelGraphicsPosition(0).getY() );
|
||||||
center_shift.setZ(X);
|
center_shift.setY(y);
|
||||||
|
|
||||||
if(m_smoke_system)
|
if(m_smoke_system)
|
||||||
{
|
{
|
||||||
@ -1425,7 +1426,8 @@ void Kart::updateGraphics(const Vec3& off_xyz, const Vec3& off_hpr)
|
|||||||
float speed_ratio = getSpeed()/getMaxSpeed();
|
float speed_ratio = getSpeed()/getMaxSpeed();
|
||||||
float offset_heading = getSteerPercent()*m_kart_properties->getSkidVisual()
|
float offset_heading = getSteerPercent()*m_kart_properties->getSkidVisual()
|
||||||
* speed_ratio * m_skidding*m_skidding;
|
* speed_ratio * m_skidding*m_skidding;
|
||||||
Moveable::updateGraphics(center_shift, Vec3(offset_heading, 0, 0));
|
Moveable::updateGraphics(center_shift,
|
||||||
|
btQuaternion(offset_heading, 0, 0));
|
||||||
} // updateGraphics
|
} // updateGraphics
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
@ -204,7 +204,8 @@ public:
|
|||||||
unsigned int getWorldKartId() const { return m_world_kart_id; }
|
unsigned int getWorldKartId() const { return m_world_kart_id; }
|
||||||
void setWorldKartId(unsigned int n) { m_world_kart_id=n; }
|
void setWorldKartId(unsigned int n) { m_world_kart_id=n; }
|
||||||
void loadData();
|
void loadData();
|
||||||
virtual void updateGraphics(const Vec3& off_xyz, const Vec3& off_hpr);
|
virtual void updateGraphics(const Vec3& off_xyz,
|
||||||
|
const btQuaternion& off_rotation);
|
||||||
const KartProperties*
|
const KartProperties*
|
||||||
getKartProperties() const { return m_kart_properties; }
|
getKartProperties() const { return m_kart_properties; }
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
@ -272,7 +273,6 @@ public:
|
|||||||
/** Returns true if this kart has finished the race. */
|
/** Returns true if this kart has finished the race. */
|
||||||
bool hasFinishedRace () const { return m_finished_race; }
|
bool hasFinishedRace () const { return m_finished_race; }
|
||||||
void endRescue ();
|
void endRescue ();
|
||||||
void getClosestKart (float *cdist, int *closest);
|
|
||||||
|
|
||||||
bool hasViewBlockedByPlunger() const
|
bool hasViewBlockedByPlunger() const
|
||||||
{ return m_view_blocked_by_plunger > 0; }
|
{ return m_view_blocked_by_plunger > 0; }
|
||||||
|
@ -84,9 +84,10 @@ KartModel::~KartModel()
|
|||||||
/** Attach the kart model and wheels to the scene node.
|
/** Attach the kart model and wheels to the scene node.
|
||||||
* \param node Node to attach the models to.
|
* \param node Node to attach the models to.
|
||||||
*/
|
*/
|
||||||
void KartModel::attachModel(scene::IAnimatedMeshSceneNode **node)
|
void KartModel::attachModel(scene::ISceneNode **node)
|
||||||
{
|
{
|
||||||
m_node = *node = irr_driver->addAnimatedMesh(m_mesh);
|
*node = irr_driver->addAnimatedMesh(m_mesh);
|
||||||
|
m_node = static_cast<scene::IAnimatedMeshSceneNode*>(*node);
|
||||||
m_node->setAnimationSpeed(1500);
|
m_node->setAnimationSpeed(1500);
|
||||||
m_node->setLoopMode(false);
|
m_node->setLoopMode(false);
|
||||||
for(unsigned int i=0; i<4; i++)
|
for(unsigned int i=0; i<4; i++)
|
||||||
@ -109,8 +110,8 @@ void KartModel::loadModels(const KartProperties &kart_properties)
|
|||||||
Vec3 size = max-min;
|
Vec3 size = max-min;
|
||||||
m_z_offset = min.getZ();
|
m_z_offset = min.getZ();
|
||||||
m_kart_width = size.getX();
|
m_kart_width = size.getX();
|
||||||
m_kart_height = size.getZ();
|
m_kart_height = size.getY();
|
||||||
m_kart_length = size.getY();
|
m_kart_length = size.getZ();
|
||||||
// FIXME: How do we handle this? it's a mesh only, so we can't
|
// FIXME: How do we handle this? it's a mesh only, so we can't
|
||||||
// simply move it in a transform (unless we turn it into a scene
|
// simply move it in a transform (unless we turn it into a scene
|
||||||
// node). m_z_offset should probably be made available to kart.
|
// node). m_z_offset should probably be made available to kart.
|
||||||
@ -127,9 +128,9 @@ void KartModel::loadModels(const KartProperties &kart_properties)
|
|||||||
m_wheel_graphics_position[i].setX( ( i==1||i==3)
|
m_wheel_graphics_position[i].setX( ( i==1||i==3)
|
||||||
? -0.5f*m_kart_width
|
? -0.5f*m_kart_width
|
||||||
: 0.5f*m_kart_width );
|
: 0.5f*m_kart_width );
|
||||||
m_wheel_graphics_position[i].setY( (i<2) ? 0.5f*m_kart_length
|
m_wheel_graphics_position[i].setY(0);
|
||||||
|
m_wheel_graphics_position[i].setZ( (i<2) ? 0.5f*m_kart_length
|
||||||
: -0.5f*m_kart_length);
|
: -0.5f*m_kart_length);
|
||||||
m_wheel_graphics_position[i].setZ(0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -198,13 +199,13 @@ void KartModel::setDefaultPhysicsPosition(const Vec3 ¢er_shift,
|
|||||||
? -0.5f*m_kart_width
|
? -0.5f*m_kart_width
|
||||||
: 0.5f*m_kart_width
|
: 0.5f*m_kart_width
|
||||||
+center_shift.getX( ));
|
+center_shift.getX( ));
|
||||||
m_wheel_physics_position[i].setY( (0.5f*m_kart_length-wheel_radius)
|
|
||||||
* ( (i<2) ? 1 : -1)
|
|
||||||
+center_shift.getY());
|
|
||||||
// Set the connection point so that a maximum compressed wheel
|
// Set the connection point so that a maximum compressed wheel
|
||||||
// (susp. length=0) will still poke a little bit out under the
|
// (susp. length=0) will still poke a little bit out under the
|
||||||
// kart
|
// kart
|
||||||
m_wheel_physics_position[i].setZ(wheel_radius-0.05f);
|
m_wheel_physics_position[i].setY(wheel_radius-0.05f);
|
||||||
|
m_wheel_physics_position[i].setZ( (0.5f*m_kart_length-wheel_radius)
|
||||||
|
* ( (i<2) ? 1 : -1)
|
||||||
|
+center_shift.getZ());
|
||||||
} // if physics position is not defined
|
} // if physics position is not defined
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -263,9 +264,8 @@ void KartModel::update(float rotation, float visual_steer,
|
|||||||
clamped_suspension[i] = ratio*suspension_length;
|
clamped_suspension[i] = ratio*suspension_length;
|
||||||
} // for i<4
|
} // for i<4
|
||||||
|
|
||||||
// core::vector3df wheel_rear (RAD_TO_DEGREE(-rotation), 0, 0);
|
|
||||||
core::vector3df wheel_rear (-rotation, 0, 0);
|
core::vector3df wheel_rear (-rotation, 0, 0);
|
||||||
core::vector3df wheel_steer(0, -visual_steer, 0);
|
core::vector3df wheel_steer(0, visual_steer, 0);
|
||||||
core::vector3df wheel_front = wheel_rear+wheel_steer;
|
core::vector3df wheel_front = wheel_rear+wheel_steer;
|
||||||
|
|
||||||
for(unsigned int i=0; i<4; i++)
|
for(unsigned int i=0; i<4; i++)
|
||||||
|
@ -115,7 +115,7 @@ public:
|
|||||||
~KartModel();
|
~KartModel();
|
||||||
void loadInfo(const lisp::Lisp* lisp);
|
void loadInfo(const lisp::Lisp* lisp);
|
||||||
void loadModels(const KartProperties &kart_properties);
|
void loadModels(const KartProperties &kart_properties);
|
||||||
void attachModel(scene::IAnimatedMeshSceneNode **node);
|
void attachModel(scene::ISceneNode **node);
|
||||||
scene::IAnimatedMesh* getModel() const { return m_mesh; }
|
scene::IAnimatedMesh* getModel() const { return m_mesh; }
|
||||||
|
|
||||||
scene::IMesh* getWheelModel(const int wheelID) const { return m_wheel_model[wheelID]; }
|
scene::IMesh* getWheelModel(const int wheelID) const { return m_wheel_model[wheelID]; }
|
||||||
|
@ -64,7 +64,7 @@ KartProperties::KartProperties(const std::string &filename) : m_icon_material(0)
|
|||||||
m_wheel_radius = m_chassis_linear_damping =
|
m_wheel_radius = m_chassis_linear_damping =
|
||||||
m_chassis_angular_damping = m_suspension_rest =
|
m_chassis_angular_damping = m_suspension_rest =
|
||||||
m_max_speed_reverse_ratio = m_jump_velocity =
|
m_max_speed_reverse_ratio = m_jump_velocity =
|
||||||
m_z_rescue_offset = m_upright_tolerance = m_collision_side_impulse =
|
m_vert_rescue_offset = m_upright_tolerance = m_collision_side_impulse =
|
||||||
m_upright_max_force = m_suspension_travel_cm =
|
m_upright_max_force = m_suspension_travel_cm =
|
||||||
m_track_connection_accel = m_min_speed_turn = m_angle_at_min =
|
m_track_connection_accel = m_min_speed_turn = m_angle_at_min =
|
||||||
m_max_speed_turn = m_angle_at_max =
|
m_max_speed_turn = m_angle_at_max =
|
||||||
@ -175,14 +175,14 @@ void KartProperties::load(const std::string &filename, const std::string &node)
|
|||||||
if(m_gravity_center_shift.getX()==UNDEFINED)
|
if(m_gravity_center_shift.getX()==UNDEFINED)
|
||||||
{
|
{
|
||||||
m_gravity_center_shift.setX(0);
|
m_gravity_center_shift.setX(0);
|
||||||
m_gravity_center_shift.setY(0);
|
|
||||||
// Default: center at the very bottom of the kart.
|
// Default: center at the very bottom of the kart.
|
||||||
m_gravity_center_shift.setZ(m_kart_model.getHeight()*0.5f);
|
m_gravity_center_shift.setY(m_kart_model.getHeight()*0.5f);
|
||||||
|
m_gravity_center_shift.setZ(0);
|
||||||
}
|
}
|
||||||
m_kart_model.setDefaultPhysicsPosition(m_gravity_center_shift,
|
m_kart_model.setDefaultPhysicsPosition(m_gravity_center_shift,
|
||||||
m_wheel_radius );
|
m_wheel_radius );
|
||||||
m_wheel_base = fabsf( m_kart_model.getWheelPhysicsPosition(0).getY()
|
m_wheel_base = fabsf( m_kart_model.getWheelPhysicsPosition(0).getZ()
|
||||||
-m_kart_model.getWheelPhysicsPosition(2).getY());
|
-m_kart_model.getWheelPhysicsPosition(2).getZ());
|
||||||
m_angle_at_min = asinf(m_wheel_base/m_min_radius);
|
m_angle_at_min = asinf(m_wheel_base/m_min_radius);
|
||||||
m_angle_at_max = asinf(m_wheel_base/m_max_radius);
|
m_angle_at_max = asinf(m_wheel_base/m_max_radius);
|
||||||
if(m_max_speed_turn == m_min_speed_turn)
|
if(m_max_speed_turn == m_min_speed_turn)
|
||||||
@ -320,7 +320,7 @@ void KartProperties::getAllData(const XMLNode * root)
|
|||||||
root->get("suspension-travel-cm", &m_suspension_travel_cm);
|
root->get("suspension-travel-cm", &m_suspension_travel_cm);
|
||||||
root->get("jump-velocity", &m_jump_velocity);
|
root->get("jump-velocity", &m_jump_velocity);
|
||||||
root->get("collision-side-impulse", &m_collision_side_impulse);
|
root->get("collision-side-impulse", &m_collision_side_impulse);
|
||||||
root->get("z-rescue-offset", &m_z_rescue_offset);
|
root->get("vert-rescue-offset", &m_vert_rescue_offset);
|
||||||
|
|
||||||
//TODO: wheel front right and wheel front left is not loaded, yet is listed as an attribute in the xml file after wheel-radius
|
//TODO: wheel front right and wheel front left is not loaded, yet is listed as an attribute in the xml file after wheel-radius
|
||||||
//TODO: same goes for their rear equivalents
|
//TODO: same goes for their rear equivalents
|
||||||
@ -443,7 +443,7 @@ void KartProperties::getAllData(const lisp::Lisp* lisp)
|
|||||||
lisp->get("suspension-travel-cm", m_suspension_travel_cm );
|
lisp->get("suspension-travel-cm", m_suspension_travel_cm );
|
||||||
lisp->get("collision-side-impulse", m_collision_side_impulse );
|
lisp->get("collision-side-impulse", m_collision_side_impulse );
|
||||||
lisp->get("jump-velocity", m_jump_velocity );
|
lisp->get("jump-velocity", m_jump_velocity );
|
||||||
lisp->get("z-rescue-offset", m_z_rescue_offset );
|
lisp->get("vert-rescue-offset", m_vert_rescue_offset );
|
||||||
lisp->get("upright-tolerance", m_upright_tolerance );
|
lisp->get("upright-tolerance", m_upright_tolerance );
|
||||||
lisp->get("upright-max-force", m_upright_max_force );
|
lisp->get("upright-max-force", m_upright_max_force );
|
||||||
lisp->get("track-connection-accel", m_track_connection_accel );
|
lisp->get("track-connection-accel", m_track_connection_accel );
|
||||||
@ -540,7 +540,7 @@ void KartProperties::checkAllSet(const std::string &filename)
|
|||||||
CHECK_NEG(m_suspension_travel_cm, "suspension-travel-cm" );
|
CHECK_NEG(m_suspension_travel_cm, "suspension-travel-cm" );
|
||||||
CHECK_NEG(m_collision_side_impulse, "collision-side-impulse" );
|
CHECK_NEG(m_collision_side_impulse, "collision-side-impulse" );
|
||||||
CHECK_NEG(m_jump_velocity, "jump-velocity" );
|
CHECK_NEG(m_jump_velocity, "jump-velocity" );
|
||||||
CHECK_NEG(m_z_rescue_offset, "z-rescue-offset" );
|
CHECK_NEG(m_vert_rescue_offset, "vert-rescue-offset" );
|
||||||
CHECK_NEG(m_upright_tolerance, "upright-tolerance" );
|
CHECK_NEG(m_upright_tolerance, "upright-tolerance" );
|
||||||
CHECK_NEG(m_upright_max_force, "upright-max-force" );
|
CHECK_NEG(m_upright_max_force, "upright-max-force" );
|
||||||
CHECK_NEG(m_track_connection_accel, "track-connection-accel" );
|
CHECK_NEG(m_track_connection_accel, "track-connection-accel" );
|
||||||
|
@ -130,8 +130,8 @@ private:
|
|||||||
/** An additional artifical side-impulse that pushes the slower kart
|
/** An additional artifical side-impulse that pushes the slower kart
|
||||||
* out of the way of the faster kart in case of a collision. */
|
* out of the way of the faster kart in case of a collision. */
|
||||||
float m_collision_side_impulse;
|
float m_collision_side_impulse;
|
||||||
float m_jump_velocity; // z velocity set when jumping
|
float m_jump_velocity; /**< Vertical velocity set when jumping. */
|
||||||
float m_z_rescue_offset; // z offset after rescue
|
float m_vert_rescue_offset; /**< Vertical offset after rescue. */
|
||||||
float m_upright_tolerance;
|
float m_upright_tolerance;
|
||||||
float m_upright_max_force;
|
float m_upright_max_force;
|
||||||
|
|
||||||
@ -230,7 +230,9 @@ public:
|
|||||||
/** Returns the (artificial) collision side impulse this kart will apply
|
/** Returns the (artificial) collision side impulse this kart will apply
|
||||||
* to a slower kart in case of a collision. */
|
* to a slower kart in case of a collision. */
|
||||||
float getCollisionSideImpulse () const {return m_collision_side_impulse; }
|
float getCollisionSideImpulse () const {return m_collision_side_impulse; }
|
||||||
float getZRescueOffset () const {return m_z_rescue_offset; }
|
/** Returns the vertical offset when rescuing karts to avoid karts being
|
||||||
|
* rescued in (or under) the track. */
|
||||||
|
float getVertRescueOffset () const {return m_vert_rescue_offset; }
|
||||||
float getUprightTolerance () const {return m_upright_tolerance; }
|
float getUprightTolerance () const {return m_upright_tolerance; }
|
||||||
float getUprightMaxForce () const {return m_upright_max_force; }
|
float getUprightMaxForce () const {return m_upright_max_force; }
|
||||||
float getTrackConnectionAccel () const {return m_track_connection_accel; }
|
float getTrackConnectionAccel () const {return m_track_connection_accel; }
|
||||||
|
@ -32,9 +32,7 @@ Moveable::Moveable()
|
|||||||
m_motion_state = 0;
|
m_motion_state = 0;
|
||||||
m_first_time = true;
|
m_first_time = true;
|
||||||
m_mesh = NULL;
|
m_mesh = NULL;
|
||||||
m_animated_mesh = NULL;
|
|
||||||
m_node = NULL;
|
m_node = NULL;
|
||||||
m_animated_node = NULL;
|
|
||||||
} // Moveable
|
} // Moveable
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -44,47 +42,38 @@ Moveable::~Moveable()
|
|||||||
if(m_body) delete m_body;
|
if(m_body) delete m_body;
|
||||||
if(m_motion_state) delete m_motion_state;
|
if(m_motion_state) delete m_motion_state;
|
||||||
if(m_node) irr_driver->removeNode(m_node);
|
if(m_node) irr_driver->removeNode(m_node);
|
||||||
if(m_animated_node) irr_driver->removeNode(m_animated_node);
|
|
||||||
if(m_mesh) irr_driver->removeMesh(m_mesh);
|
if(m_mesh) irr_driver->removeMesh(m_mesh);
|
||||||
if(m_animated_mesh) irr_driver->removeMesh(m_animated_mesh);
|
|
||||||
} // ~Moveable
|
} // ~Moveable
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
/** Sets this model to be non-animated.
|
/** Sets the mesh for this model.
|
||||||
* \param n The scene node.
|
* \param n The scene node.
|
||||||
*/
|
*/
|
||||||
void Moveable::setNode(scene::ISceneNode *n)
|
void Moveable::setNode(scene::ISceneNode *n)
|
||||||
{
|
{
|
||||||
m_node = n;
|
m_node = n;
|
||||||
m_animated_node = NULL;
|
|
||||||
} // setNode
|
} // setNode
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
/** Sets this model to be animated.
|
/** Updates the graphics model. Mainly set the graphical position to be the
|
||||||
* \param n The animated scene node.
|
* same as the physics position, but uses offsets to position and rotation
|
||||||
|
* for special gfx effects (e.g. skidding will turn the karts more).
|
||||||
|
* \param offset_xyz Offset to be added to the position.
|
||||||
|
* \param rotation Additional rotation.
|
||||||
*/
|
*/
|
||||||
void Moveable::setAnimatedNode(scene::IAnimatedMeshSceneNode *n)
|
void Moveable::updateGraphics(const Vec3& offset_xyz,
|
||||||
{
|
const btQuaternion& rotation)
|
||||||
m_node = NULL;
|
|
||||||
m_animated_node = n;
|
|
||||||
} // setAnimatedNode
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void Moveable::updateGraphics(const Vec3& off_xyz, const Vec3& off_hpr)
|
|
||||||
{
|
|
||||||
Vec3 xyz=getXYZ()+off_xyz;
|
|
||||||
Vec3 hpr=getHPR()+off_hpr;
|
|
||||||
//sgCoord c=Coord(xyz, hpr).toSgCoord();
|
|
||||||
if(m_node)
|
|
||||||
{
|
{
|
||||||
|
#ifdef DEBUG_PRINT
|
||||||
|
printf("moveable: %f %f (%f %f)\n", getXYZ().getX(), getXYZ().getZ(),
|
||||||
|
off_xyz.getX(), off_xyz.getZ());
|
||||||
|
#endif
|
||||||
|
Vec3 xyz=getXYZ()+offset_xyz;
|
||||||
|
btQuaternion r_all = getRotation()*rotation;
|
||||||
|
Vec3 hpr;
|
||||||
|
hpr.setHPR(r_all);
|
||||||
m_node->setPosition(xyz.toIrrVector());
|
m_node->setPosition(xyz.toIrrVector());
|
||||||
m_node->setRotation(hpr.toIrrHPR());
|
m_node->setRotation(hpr.toIrrHPR());
|
||||||
}
|
|
||||||
else if(m_animated_node)
|
|
||||||
{
|
|
||||||
m_animated_node->setPosition(xyz.toIrrVector());
|
|
||||||
m_animated_node->setRotation(hpr.toIrrHPR());
|
|
||||||
}
|
|
||||||
} // updateGraphics
|
} // updateGraphics
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -97,13 +86,10 @@ void Moveable::reset()
|
|||||||
m_body->setAngularVelocity(btVector3(0, 0, 0));
|
m_body->setAngularVelocity(btVector3(0, 0, 0));
|
||||||
m_body->setCenterOfMassTransform(m_transform);
|
m_body->setCenterOfMassTransform(m_transform);
|
||||||
}
|
}
|
||||||
if(m_node)
|
|
||||||
m_node->setVisible(true); // In case that the objects was eliminated
|
m_node->setVisible(true); // In case that the objects was eliminated
|
||||||
if(m_animated_node)
|
|
||||||
m_animated_node->setVisible(true);
|
|
||||||
|
|
||||||
Coord c(m_transform);
|
Coord c(m_transform);
|
||||||
m_hpr = c.getHPR();
|
m_hpr.setHPR(m_transform.getRotation());
|
||||||
} // reset
|
} // reset
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -111,37 +97,20 @@ void Moveable::update(float dt)
|
|||||||
{
|
{
|
||||||
m_motion_state->getWorldTransform(m_transform);
|
m_motion_state->getWorldTransform(m_transform);
|
||||||
m_velocityLC = getVelocity()*m_transform.getBasis();
|
m_velocityLC = getVelocity()*m_transform.getBasis();
|
||||||
// The following code would synchronise bullet to irrlicht rotations, but
|
m_hpr.setHPR(m_transform.getRotation());
|
||||||
// heading etc. might not be 'correct', e.g. a 180 degree heading rotation
|
Vec3 forw_vec = m_transform.getBasis().getColumn(0);
|
||||||
// would be reported as 180 degree roll and pitch, and 0 degree heading.
|
m_heading = -atan2f(forw_vec.getZ(), forw_vec.getX());
|
||||||
// So to get heading, pitch etc. the way needed elsewhere (camera etc),
|
|
||||||
// we would still have to rotate unit vectors and compute heading etc.
|
|
||||||
// with atan.
|
|
||||||
//btQuaternion q = m_transform.getRotation();
|
|
||||||
//core::quaternion qirr(q.getX(), q.getZ(), q.getY(), -q.getW());
|
|
||||||
//core::vector3df r;
|
|
||||||
//qirr.toEuler(r);
|
|
||||||
// Note: toIrrHPR mixes the axis back etc., so the assignments below
|
|
||||||
// mean that getIrrHPR returns exactly (r.x,r.y,r.z)*RAD_TO_DEGREE
|
|
||||||
//m_hpr.setX(-r.Y);
|
|
||||||
//m_hpr.setY(-r.X);
|
|
||||||
//m_hpr.setZ(-r.Z);
|
|
||||||
|
|
||||||
|
// The pitch in hpr is in between -pi and pi. But for the camera it
|
||||||
|
// must be restricted to -pi/2 and pi/2 - so recompute it by restricting
|
||||||
|
// y to positive values, i.e. no pitch of more than pi/2.
|
||||||
|
Vec3 up = getTrans().getBasis().getColumn(1);
|
||||||
|
m_pitch = atan2(up.getZ(), fabsf(up.getY()));
|
||||||
|
|
||||||
m_hpr.setHPR(m_transform.getBasis());
|
updateGraphics(Vec3(0,0,0), btQuaternion(0, 0, 0, 1));
|
||||||
// roll is not set correctly, I assume due to a different HPR order.
|
|
||||||
// So we compute the proper roll (by taking the angle between the up
|
|
||||||
// vector and the rotated up vector).
|
|
||||||
Vec3 up(0,0,1);
|
|
||||||
Vec3 roll_vec = m_transform.getBasis()*up;
|
|
||||||
float roll = atan2(roll_vec.getX(), roll_vec.getZ());
|
|
||||||
m_hpr.setRoll(roll);
|
|
||||||
|
|
||||||
updateGraphics(Vec3(0,0,0), Vec3(0,0,0));
|
|
||||||
m_first_time = false ;
|
m_first_time = false ;
|
||||||
} // update
|
} // update
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void Moveable::createBody(float mass, btTransform& trans,
|
void Moveable::createBody(float mass, btTransform& trans,
|
||||||
btCollisionShape *shape) {
|
btCollisionShape *shape) {
|
||||||
@ -161,8 +130,7 @@ void Moveable::createBody(float mass, btTransform& trans,
|
|||||||
// functions are not called correctly. So only init the pointer to zero.
|
// functions are not called correctly. So only init the pointer to zero.
|
||||||
m_user_pointer.zero();
|
m_user_pointer.zero();
|
||||||
m_body->setUserPointer(&m_user_pointer);
|
m_body->setUserPointer(&m_user_pointer);
|
||||||
const btMatrix3x3& basis=m_body->getWorldTransform().getBasis();
|
m_hpr.setHPR(m_body->getWorldTransform().getRotation());
|
||||||
m_hpr.setHPR(basis);
|
|
||||||
} // createBody
|
} // createBody
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -40,17 +40,19 @@ class Material;
|
|||||||
class Moveable
|
class Moveable
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
btVector3 m_velocityLC; /**<Velocity in kart coordinates */
|
btVector3 m_velocityLC; /**<Velocity in kart coordinates. */
|
||||||
btTransform m_transform;
|
btTransform m_transform;
|
||||||
Vec3 m_hpr;
|
Vec3 m_hpr;
|
||||||
|
/** The heading in m_hpr is between -90 and 90 degrees only. The 'real'
|
||||||
|
* heading between -180 to 180 degrees is stored in this variable. */
|
||||||
|
float m_heading;
|
||||||
|
/** The pitch between -90 and 90 degrees. */
|
||||||
|
float m_pitch;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
UserPointer m_user_pointer;
|
UserPointer m_user_pointer;
|
||||||
scene::IAnimatedMesh *m_animated_mesh;
|
|
||||||
scene::IMesh *m_mesh;
|
scene::IMesh *m_mesh;
|
||||||
scene::ISceneNode *m_node;
|
scene::ISceneNode *m_node;
|
||||||
scene::IAnimatedMeshSceneNode
|
|
||||||
*m_animated_node;
|
|
||||||
int m_first_time ;
|
int m_first_time ;
|
||||||
btRigidBody *m_body;
|
btRigidBody *m_body;
|
||||||
KartMotionState *m_motion_state;
|
KartMotionState *m_motion_state;
|
||||||
@ -58,17 +60,25 @@ protected:
|
|||||||
public:
|
public:
|
||||||
Moveable();
|
Moveable();
|
||||||
virtual ~Moveable();
|
virtual ~Moveable();
|
||||||
|
/** Returns the scene node of this moveable. */
|
||||||
scene::ISceneNode
|
scene::ISceneNode
|
||||||
*getNode() const { return m_node ? m_node : m_animated_node; }
|
*getNode() const { return m_node; }
|
||||||
void setNode(scene::ISceneNode *n);
|
void setNode(scene::ISceneNode *n);
|
||||||
void setAnimatedNode(scene::IAnimatedMeshSceneNode *n);
|
|
||||||
virtual const btVector3
|
virtual const btVector3
|
||||||
&getVelocity() const {return m_body->getLinearVelocity();}
|
&getVelocity() const {return m_body->getLinearVelocity();}
|
||||||
const btVector3
|
const btVector3
|
||||||
&getVelocityLC() const {return m_velocityLC; }
|
&getVelocityLC() const {return m_velocityLC; }
|
||||||
virtual void setVelocity(const btVector3& v) {m_body->setLinearVelocity(v); }
|
virtual void setVelocity(const btVector3& v) {m_body->setLinearVelocity(v); }
|
||||||
const Vec3& getXYZ() const {return (Vec3&)m_transform.getOrigin();}
|
const Vec3& getXYZ() const {return (Vec3&)m_transform.getOrigin();}
|
||||||
|
/** Return the rotation, but heading is restricted to -90 and 90 degrees. */
|
||||||
const Vec3& getHPR() const {return m_hpr; }
|
const Vec3& getHPR() const {return m_hpr; }
|
||||||
|
/** Returns the heading between -180 and 180 degrees. Note that using
|
||||||
|
* getHPR().getHeading() can result a different heading (e.g. a heading
|
||||||
|
* of 180 degrees is the same as a roll and pitch around 180).*/
|
||||||
|
float getHeading() const {return m_heading; }
|
||||||
|
/** Returns the pitch of the kart, restricted to between -90 and 90 degrees.
|
||||||
|
* Note that using getHPR().getPitch can result in a different value! */
|
||||||
|
float getPitch() const {return m_pitch; }
|
||||||
const btQuaternion
|
const btQuaternion
|
||||||
getRotation() const {return m_transform.getRotation(); }
|
getRotation() const {return m_transform.getRotation(); }
|
||||||
|
|
||||||
@ -95,7 +105,8 @@ public:
|
|||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
virtual void handleZipper () {};
|
virtual void handleZipper () {};
|
||||||
virtual void updateGraphics(const Vec3& off_xyz, const Vec3& off_hpr);
|
virtual void updateGraphics(const Vec3& off_xyz,
|
||||||
|
const btQuaternion& off_rotation);
|
||||||
virtual void reset();
|
virtual void reset();
|
||||||
virtual void update(float dt) ;
|
virtual void update(float dt) ;
|
||||||
btRigidBody *getBody() const {return m_body; }
|
btRigidBody *getBody() const {return m_body; }
|
||||||
|
12
src/main.cpp
12
src/main.cpp
@ -245,10 +245,6 @@ int handleCmdLine(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
UserConfigParams::m_track_debug=1;
|
UserConfigParams::m_track_debug=1;
|
||||||
}
|
}
|
||||||
else if(!strcmp(argv[i], "--bullet-debug"))
|
|
||||||
{
|
|
||||||
UserConfigParams::m_bullet_debug=1;
|
|
||||||
}
|
|
||||||
else if(!strcmp(argv[i], "--kartsize-debug"))
|
else if(!strcmp(argv[i], "--kartsize-debug"))
|
||||||
{
|
{
|
||||||
UserConfigParams::m_print_kart_sizes=true;
|
UserConfigParams::m_print_kart_sizes=true;
|
||||||
@ -443,10 +439,18 @@ int handleCmdLine(int argc, char **argv)
|
|||||||
else if( sscanf(argv[i], "--history=%d", &n)==1)
|
else if( sscanf(argv[i], "--history=%d", &n)==1)
|
||||||
{
|
{
|
||||||
history->doReplayHistory( (History::HistoryReplayMode)n);
|
history->doReplayHistory( (History::HistoryReplayMode)n);
|
||||||
|
// Force the no-start screen flag, since this initialises
|
||||||
|
// the player structures correctly.
|
||||||
|
UserConfigParams::m_no_start_screen = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
else if( !strcmp(argv[i], "--history") )
|
else if( !strcmp(argv[i], "--history") )
|
||||||
{
|
{
|
||||||
history->doReplayHistory(History::HISTORY_POSITION);
|
history->doReplayHistory(History::HISTORY_POSITION);
|
||||||
|
// Force the no-start screen flag, since this initialises
|
||||||
|
// the player structures correctly.
|
||||||
|
UserConfigParams::m_no_start_screen = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
else if( !strcmp(argv[i], "--item") && i+1<argc )
|
else if( !strcmp(argv[i], "--item") && i+1<argc )
|
||||||
{
|
{
|
||||||
|
@ -303,12 +303,20 @@ int LinearWorld::getSectorForKart(const int kart_id) const
|
|||||||
} // getSectorForKart
|
} // getSectorForKart
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
/** Returns the distance the kart has travelled along the track since
|
||||||
|
* crossing the start line..
|
||||||
|
* \param kart_id Index of the kart.
|
||||||
|
*/
|
||||||
float LinearWorld::getDistanceDownTrackForKart(const int kart_id) const
|
float LinearWorld::getDistanceDownTrackForKart(const int kart_id) const
|
||||||
{
|
{
|
||||||
return m_kart_info[kart_id].m_curr_track_coords.getY();
|
return m_kart_info[kart_id].m_curr_track_coords.getZ();
|
||||||
} // getDistanceDownTrackForKart
|
} // getDistanceDownTrackForKart
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
/** Gets the distance of the kart from the center of the driveline. Positive
|
||||||
|
* is to the right of the center, negative values to the left.
|
||||||
|
* \param kart_id Index of kart.
|
||||||
|
*/
|
||||||
float LinearWorld::getDistanceToCenterForKart(const int kart_id) const
|
float LinearWorld::getDistanceToCenterForKart(const int kart_id) const
|
||||||
{
|
{
|
||||||
return m_kart_info[kart_id].m_curr_track_coords.getX();
|
return m_kart_info[kart_id].m_curr_track_coords.getX();
|
||||||
@ -528,7 +536,7 @@ void LinearWorld::moveKartAfterRescue(Kart* kart, btRigidBody* body)
|
|||||||
|
|
||||||
kart->setXYZ( m_track->trackToSpatial(info.m_track_sector) );
|
kart->setXYZ( m_track->trackToSpatial(info.m_track_sector) );
|
||||||
|
|
||||||
btQuaternion heading(btVector3(0.0f, 0.0f, 1.0f),
|
btQuaternion heading(btVector3(0.0f, 1.0f, 0.0f),
|
||||||
m_track->getAngle(info.m_track_sector) );
|
m_track->getAngle(info.m_track_sector) );
|
||||||
kart->setRotation(heading);
|
kart->setRotation(heading);
|
||||||
|
|
||||||
@ -539,8 +547,8 @@ void LinearWorld::moveKartAfterRescue(Kart* kart, btRigidBody* body)
|
|||||||
float epsilon = 0.5f * kart->getKartHeight();
|
float epsilon = 0.5f * kart->getKartHeight();
|
||||||
|
|
||||||
btTransform pos;
|
btTransform pos;
|
||||||
pos.setOrigin(kart->getXYZ()+btVector3(0, 0, kart->getKartHeight() + epsilon));
|
pos.setOrigin(kart->getXYZ()+btVector3(0, kart->getKartHeight() + epsilon, 0));
|
||||||
pos.setRotation(btQuaternion(btVector3(0.0f, 0.0f, 1.0f),
|
pos.setRotation(btQuaternion(btVector3(0.0f, 1.0f, 0.0f),
|
||||||
m_track->getAngle(info.m_track_sector)));
|
m_track->getAngle(info.m_track_sector)));
|
||||||
|
|
||||||
body->setCenterOfMassTransform(pos);
|
body->setCenterOfMassTransform(pos);
|
||||||
@ -551,9 +559,9 @@ void LinearWorld::moveKartAfterRescue(Kart* kart, btRigidBody* body)
|
|||||||
if (kart_over_ground)
|
if (kart_over_ground)
|
||||||
{
|
{
|
||||||
//add vertical offset so that the kart starts off above the track
|
//add vertical offset so that the kart starts off above the track
|
||||||
float vertical_offset = kart->getKartProperties()->getZRescueOffset() *
|
float vertical_offset = kart->getKartProperties()->getVertRescueOffset() *
|
||||||
kart->getKartHeight();
|
kart->getKartHeight();
|
||||||
body->translate(btVector3(0, 0, vertical_offset));
|
body->translate(btVector3(0, vertical_offset, 0));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -573,8 +581,9 @@ void LinearWorld::updateRacePosition()
|
|||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
bool rank_used[kart_amount+1];
|
std::vector<bool> rank_used;
|
||||||
for (unsigned int n=0; n<=kart_amount; n++) rank_used[n] = false;
|
for (unsigned int n=0; n<=kart_amount; n++)
|
||||||
|
rank_used.push_back(false);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (unsigned int i=0; i<kart_amount; i++)
|
for (unsigned int i=0; i<kart_amount; i++)
|
||||||
@ -663,7 +672,7 @@ void LinearWorld::updateRacePosition()
|
|||||||
sound_manager->switchToFastMusic();
|
sound_manager->switchToFastMusic();
|
||||||
m_faster_music_active=true;
|
m_faster_music_active=true;
|
||||||
}
|
}
|
||||||
}
|
} // for i<kart_amount
|
||||||
|
|
||||||
} // updateRacePosition
|
} // updateRacePosition
|
||||||
|
|
||||||
@ -688,7 +697,7 @@ void LinearWorld::checkForWrongDirection(unsigned int i)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// check if the player is going in the wrong direction
|
// check if the player is going in the wrong direction
|
||||||
float angle_diff = kart->getHPR().getHeading() -
|
float angle_diff = kart->getHeading() -
|
||||||
m_track->getAngle(m_kart_info[i].m_track_sector);
|
m_track->getAngle(m_kart_info[i].m_track_sector);
|
||||||
if(angle_diff > M_PI) angle_diff -= 2*M_PI;
|
if(angle_diff > M_PI) angle_diff -= 2*M_PI;
|
||||||
else if (angle_diff < -M_PI) angle_diff += 2*M_PI;
|
else if (angle_diff < -M_PI) angle_diff += 2*M_PI;
|
||||||
|
@ -252,18 +252,19 @@ void ThreeStrikesBattle::moveKartAfterRescue(Kart* kart, btRigidBody* body)
|
|||||||
const int start_spots_amount = world->getTrack()->getNumberOfStartPositions();
|
const int start_spots_amount = world->getTrack()->getNumberOfStartPositions();
|
||||||
assert(start_spots_amount > 0);
|
assert(start_spots_amount > 0);
|
||||||
|
|
||||||
int smallest_distance_found = -1, closest_id_found = -1;
|
float smallest_distance_found = -1;
|
||||||
|
int closest_id_found = -1;
|
||||||
|
|
||||||
const int kart_x = (int)(kart->getXYZ()[0]);
|
const float kart_x = kart->getXYZ().getX();
|
||||||
const int kart_y = (int)(kart->getXYZ()[1]);
|
const float kart_z = kart->getXYZ().getZ();
|
||||||
|
|
||||||
for(int n=0; n<start_spots_amount; n++)
|
for(int n=0; n<start_spots_amount; n++)
|
||||||
{
|
{
|
||||||
// no need for the overhead to compute exact distance with sqrt(), so using the
|
// no need for the overhead to compute exact distance with sqrt(), so using the
|
||||||
// 'manhattan' heuristic which will do fine enough.
|
// 'manhattan' heuristic which will do fine enough.
|
||||||
const Vec3 &v=world->getTrack()->getStartPosition(n);
|
const Vec3 &v=world->getTrack()->getStartPosition(n);
|
||||||
const int dist_n = abs((int)(kart_x - v.getX())) +
|
const float dist_n= fabs(kart_x - v.getX()) +
|
||||||
abs((int)(kart_y - v.getY()));
|
fabs(kart_z - v.getZ());
|
||||||
if(dist_n < smallest_distance_found || closest_id_found == -1)
|
if(dist_n < smallest_distance_found || closest_id_found == -1)
|
||||||
{
|
{
|
||||||
closest_id_found = n;
|
closest_id_found = n;
|
||||||
@ -276,14 +277,14 @@ void ThreeStrikesBattle::moveKartAfterRescue(Kart* kart, btRigidBody* body)
|
|||||||
kart->setXYZ( Vec3(v) );
|
kart->setXYZ( Vec3(v) );
|
||||||
|
|
||||||
// FIXME - implement correct heading
|
// FIXME - implement correct heading
|
||||||
btQuaternion heading(btVector3(0.0f, 0.0f, 1.0f),
|
btQuaternion heading(btVector3(0.0f, 1.0f, 0.0f),
|
||||||
world->getTrack()->getStartHeading(closest_id_found));
|
world->getTrack()->getStartHeading(closest_id_found));
|
||||||
kart->setRotation(heading);
|
kart->setRotation(heading);
|
||||||
|
|
||||||
//position kart from same height as in World::resetAllKarts
|
//position kart from same height as in World::resetAllKarts
|
||||||
btTransform pos;
|
btTransform pos;
|
||||||
pos.setOrigin(kart->getXYZ()+btVector3(0, 0, 0.5f*kart->getKartHeight()));
|
pos.setOrigin(kart->getXYZ()+btVector3(0, 0.5f*kart->getKartHeight(), 0.0f));
|
||||||
pos.setRotation( btQuaternion(btVector3(0.0f, 0.0f, 1.0f), 0 /* angle */) );
|
pos.setRotation( btQuaternion(btVector3(0.0f, 1.0f, 0.0f), 0 /* angle */) );
|
||||||
|
|
||||||
body->setCenterOfMassTransform(pos);
|
body->setCenterOfMassTransform(pos);
|
||||||
|
|
||||||
@ -293,9 +294,9 @@ void ThreeStrikesBattle::moveKartAfterRescue(Kart* kart, btRigidBody* body)
|
|||||||
if (kart_over_ground)
|
if (kart_over_ground)
|
||||||
{
|
{
|
||||||
//add vertical offset so that the kart starts off above the track
|
//add vertical offset so that the kart starts off above the track
|
||||||
float vertical_offset = kart->getKartProperties()->getZRescueOffset() *
|
float vertical_offset = kart->getKartProperties()->getVertRescueOffset() *
|
||||||
kart->getKartHeight();
|
kart->getKartHeight();
|
||||||
body->translate(btVector3(0, 0, vertical_offset));
|
body->translate(btVector3(0, vertical_offset, 0));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -312,7 +312,7 @@ void World::resetAllKarts()
|
|||||||
for ( KartList::iterator i=m_karts.begin(); i!=m_karts.end(); i++)
|
for ( KartList::iterator i=m_karts.begin(); i!=m_karts.end(); i++)
|
||||||
{
|
{
|
||||||
///start projection from top of kart
|
///start projection from top of kart
|
||||||
btVector3 up_offset(0, 0, 0.5f * ((*i)->getKartHeight()));
|
btVector3 up_offset(0, 0.5f * ((*i)->getKartHeight()), 0);
|
||||||
(*i)->getVehicle()->getRigidBody()->translate (up_offset);
|
(*i)->getVehicle()->getRigidBody()->translate (up_offset);
|
||||||
|
|
||||||
bool kart_over_ground = m_physics->projectKartDownwards(*i);
|
bool kart_over_ground = m_physics->projectKartDownwards(*i);
|
||||||
|
@ -754,7 +754,7 @@ void btKart::updateFriction(btScalar timeStep)
|
|||||||
|
|
||||||
btVector3 sideImp = m_axle[wheel] * m_sideImpulse[wheel];
|
btVector3 sideImp = m_axle[wheel] * m_sideImpulse[wheel];
|
||||||
|
|
||||||
rel_pos[2] *= wheelInfo.m_rollInfluence;
|
rel_pos[m_indexUpAxis] *= wheelInfo.m_rollInfluence;
|
||||||
m_chassisBody->applyImpulse(sideImp,rel_pos);
|
m_chassisBody->applyImpulse(sideImp,rel_pos);
|
||||||
|
|
||||||
//apply friction impulse on the ground
|
//apply friction impulse on the ground
|
||||||
|
@ -23,6 +23,8 @@ subject to the following restrictions:
|
|||||||
#include "BulletDynamics/Dynamics/btRigidBody.h"
|
#include "BulletDynamics/Dynamics/btRigidBody.h"
|
||||||
#include "LinearMath/btTransformUtil.h"
|
#include "LinearMath/btTransformUtil.h"
|
||||||
|
|
||||||
|
#include "karts/kart.hpp"
|
||||||
|
|
||||||
//!
|
//!
|
||||||
//!
|
//!
|
||||||
//!
|
//!
|
||||||
@ -83,17 +85,19 @@ void btUprightConstraint::solveAngularLimit(
|
|||||||
|
|
||||||
btVector3 motorImp = clippedMotorImpulse * limit->m_axis;
|
btVector3 motorImp = clippedMotorImpulse * limit->m_axis;
|
||||||
body0->applyTorqueImpulse(motorImp);
|
body0->applyTorqueImpulse(motorImp);
|
||||||
}
|
} // solveAngularLimit
|
||||||
|
|
||||||
//!
|
//!
|
||||||
//!
|
//!
|
||||||
//!
|
//!
|
||||||
|
|
||||||
btUprightConstraint::btUprightConstraint(btRigidBody& rbA, const btTransform& frameInA )
|
btUprightConstraint::btUprightConstraint(const Kart* kart,
|
||||||
: btTypedConstraint(D6_CONSTRAINT_TYPE, rbA)
|
const btTransform& frameInA)
|
||||||
|
: btTypedConstraint(D6_CONSTRAINT_TYPE, *(kart->getBody()))
|
||||||
, m_frameInA(frameInA)
|
, m_frameInA(frameInA)
|
||||||
|
|
||||||
{
|
{
|
||||||
|
m_kart = kart;
|
||||||
m_ERP = 1.0f;
|
m_ERP = 1.0f;
|
||||||
m_bounce = 0.0f;
|
m_bounce = 0.0f;
|
||||||
m_damping = 1.0f;
|
m_damping = 1.0f;
|
||||||
@ -105,7 +109,7 @@ btUprightConstraint::btUprightConstraint(btRigidBody& rbA, const btTransform& fr
|
|||||||
m_limit[ 0 ].m_axis = btVector3( 1, 0, 0 );
|
m_limit[ 0 ].m_axis = btVector3( 1, 0, 0 );
|
||||||
m_limit[ 1 ].m_axis = btVector3( 0, 1, 0 );
|
m_limit[ 1 ].m_axis = btVector3( 0, 1, 0 );
|
||||||
setLimit( SIMD_PI * 0.4f );
|
setLimit( SIMD_PI * 0.4f );
|
||||||
}
|
} // btUprightConstraint
|
||||||
|
|
||||||
//!
|
//!
|
||||||
//!
|
//!
|
||||||
@ -115,23 +119,18 @@ void btUprightConstraint::buildJacobian()
|
|||||||
{
|
{
|
||||||
btTransform worldTransform = m_rbA.getCenterOfMassTransform() * m_frameInA;
|
btTransform worldTransform = m_rbA.getCenterOfMassTransform() * m_frameInA;
|
||||||
btVector3 upAxis = worldTransform.getBasis().getColumn(2);
|
btVector3 upAxis = worldTransform.getBasis().getColumn(2);
|
||||||
m_limit[ 0 ].m_angle = btAtan2( upAxis.getZ(), upAxis.getY() )-SIMD_PI/2.0f;
|
m_limit[ 0 ].m_angle = m_kart->getPitch();
|
||||||
m_limit[ 1 ].m_angle = -btAtan2( upAxis.getZ(), upAxis.getX() )+SIMD_PI/2.0f;
|
m_limit[ 1 ].m_angle = m_kart->getHPR().getRoll();
|
||||||
|
|
||||||
for ( int i = 0; i < 2; i++ )
|
for ( int i = 0; i < 2; i++ )
|
||||||
{
|
{
|
||||||
if ( m_limit[ i ].m_angle < -SIMD_PI )
|
|
||||||
m_limit[ i ].m_angle += 2 * SIMD_PI;
|
|
||||||
if ( m_limit[ i ].m_angle > SIMD_PI )
|
|
||||||
m_limit[ i ].m_angle -= 2 * SIMD_PI;
|
|
||||||
|
|
||||||
new (&m_jacAng[ i ]) btJacobianEntry( m_limit[ i ].m_axis,
|
new (&m_jacAng[ i ]) btJacobianEntry( m_limit[ i ].m_axis,
|
||||||
m_rbA.getCenterOfMassTransform().getBasis().transpose(),
|
m_rbA.getCenterOfMassTransform().getBasis().transpose(),
|
||||||
m_rbB.getCenterOfMassTransform().getBasis().transpose(),
|
m_rbB.getCenterOfMassTransform().getBasis().transpose(),
|
||||||
m_rbA.getInvInertiaDiagLocal(),
|
m_rbA.getInvInertiaDiagLocal(),
|
||||||
m_rbB.getInvInertiaDiagLocal());
|
m_rbB.getInvInertiaDiagLocal());
|
||||||
}
|
}
|
||||||
}
|
} // buildJacobian
|
||||||
|
|
||||||
//!
|
//!
|
||||||
//!
|
//!
|
||||||
@ -150,5 +149,5 @@ void btUprightConstraint::solveConstraint(btScalar timeStep)
|
|||||||
|
|
||||||
solveAngularLimit( &m_limit[ 0 ], m_timeStep, btScalar(1.) / m_jacAng[ 0 ].getDiagonal(), &m_rbA );
|
solveAngularLimit( &m_limit[ 0 ], m_timeStep, btScalar(1.) / m_jacAng[ 0 ].getDiagonal(), &m_rbA );
|
||||||
solveAngularLimit( &m_limit[ 1 ], m_timeStep, btScalar(1.) / m_jacAng[ 1 ].getDiagonal(), &m_rbA );
|
solveAngularLimit( &m_limit[ 1 ], m_timeStep, btScalar(1.) / m_jacAng[ 1 ].getDiagonal(), &m_rbA );
|
||||||
}
|
} // solveConstraint
|
||||||
|
|
||||||
|
@ -22,11 +22,12 @@ subject to the following restrictions:
|
|||||||
#include "BulletDynamics/ConstraintSolver/btTypedConstraint.h"
|
#include "BulletDynamics/ConstraintSolver/btTypedConstraint.h"
|
||||||
|
|
||||||
class btRigidBody;
|
class btRigidBody;
|
||||||
|
class Kart;
|
||||||
|
|
||||||
//!
|
|
||||||
//!
|
|
||||||
//!
|
|
||||||
|
|
||||||
|
class btUprightConstraint : public btTypedConstraint
|
||||||
|
{
|
||||||
|
private:
|
||||||
class btUprightConstraintLimit
|
class btUprightConstraintLimit
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -36,10 +37,6 @@ public:
|
|||||||
btScalar m_currentLimitError;
|
btScalar m_currentLimitError;
|
||||||
};
|
};
|
||||||
|
|
||||||
class btUprightConstraint : public btTypedConstraint
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
|
|
||||||
//! relative_frames
|
//! relative_frames
|
||||||
|
|
||||||
//!@{
|
//!@{
|
||||||
@ -51,6 +48,7 @@ protected:
|
|||||||
btJacobianEntry m_jacAng[ 2 ];//!< angular constraint
|
btJacobianEntry m_jacAng[ 2 ];//!< angular constraint
|
||||||
//!@}
|
//!@}
|
||||||
|
|
||||||
|
const Kart *m_kart;
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
//! temporal variables
|
//! temporal variables
|
||||||
@ -76,54 +74,30 @@ protected:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void buildAngularJacobian(btJacobianEntry & jacAngular,const btVector3 & jointAxisW);
|
void buildAngularJacobian(btJacobianEntry & jacAngular,
|
||||||
|
const btVector3 & jointAxisW);
|
||||||
|
|
||||||
void solveAngularLimit(
|
void solveAngularLimit(btUprightConstraintLimit *limit,
|
||||||
btUprightConstraintLimit *limit,
|
|
||||||
btScalar timeStep, btScalar jacDiagABInv,
|
btScalar timeStep, btScalar jacDiagABInv,
|
||||||
btRigidBody * body0 );
|
btRigidBody * body0 );
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
btUprightConstraint(btRigidBody& rbA, const btTransform& frameInA );
|
btUprightConstraint(const Kart* kart, const btTransform& frameInA);
|
||||||
|
|
||||||
// -PI,+PI is the full range
|
// -PI,+PI is the full range
|
||||||
// 0,0 is no rotation around x or z
|
// 0,0 is no rotation around x or z
|
||||||
// -PI*0.2,+PI*0.2 is a nice bit of tilt
|
// -PI*0.2,+PI*0.2 is a nice bit of tilt
|
||||||
void setLimit( btScalar range )
|
void setLimit( btScalar range ) { m_loLimit = -range;
|
||||||
{
|
m_hiLimit = +range; }
|
||||||
m_loLimit = -range;
|
|
||||||
m_hiLimit = +range;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Error correction scaling
|
// Error correction scaling
|
||||||
// 0 - 1
|
// 0 - 1
|
||||||
//
|
void setErp( btScalar erp ) { m_ERP = erp; }
|
||||||
void setErp( btScalar erp )
|
void setBounce( btScalar bounce ) { m_bounce = bounce; }
|
||||||
{
|
void setMaxLimitForce( btScalar force ) { m_maxLimitForce = force; }
|
||||||
m_ERP = erp;
|
void setLimitSoftness( btScalar softness ) { m_limitSoftness = softness; }
|
||||||
}
|
void setDamping( btScalar damping ) { m_damping = damping; }
|
||||||
void setBounce( btScalar bounce )
|
void setDisableTime( btScalar t ) { m_disable_time = t; }
|
||||||
{
|
|
||||||
m_bounce = bounce;
|
|
||||||
}
|
|
||||||
void setMaxLimitForce( btScalar force )
|
|
||||||
{
|
|
||||||
m_maxLimitForce = force;
|
|
||||||
}
|
|
||||||
void setLimitSoftness( btScalar softness )
|
|
||||||
{
|
|
||||||
m_limitSoftness = softness;
|
|
||||||
}
|
|
||||||
void setDamping( btScalar damping )
|
|
||||||
{
|
|
||||||
m_damping = damping;
|
|
||||||
}
|
|
||||||
void setDisableTime( btScalar t )
|
|
||||||
{
|
|
||||||
m_disable_time = t;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void buildJacobian();
|
virtual void buildJacobian();
|
||||||
virtual void solveConstraint(btScalar timeStep);
|
virtual void solveConstraint(btScalar timeStep);
|
||||||
};
|
};
|
||||||
|
@ -23,48 +23,34 @@
|
|||||||
|
|
||||||
IrrDebugDrawer::IrrDebugDrawer()
|
IrrDebugDrawer::IrrDebugDrawer()
|
||||||
{
|
{
|
||||||
m_debug_mode = DBG_DrawAabb;
|
m_debug_mode = DM_NONE;
|
||||||
} // IrrDebugDrawer
|
} // IrrDebugDrawer
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
/** Activates the debug view. It makes all karts invisible (in irrlicht), so
|
/** Activates the next debug mode, or switches the mode off again.
|
||||||
* that the bullet view can be seen.
|
|
||||||
*/
|
*/
|
||||||
void IrrDebugDrawer::activate()
|
void IrrDebugDrawer::nextDebugMode()
|
||||||
{
|
{
|
||||||
|
// Go to next debug mode. Note that debug mode 3 (
|
||||||
|
m_debug_mode = (DebugModeType) ((m_debug_mode+1) % 3);
|
||||||
World *world = World::getWorld();
|
World *world = World::getWorld();
|
||||||
unsigned int num_karts = world->getNumKarts();
|
unsigned int num_karts = world->getNumKarts();
|
||||||
for(unsigned int i=0; i<num_karts; i++)
|
for(unsigned int i=0; i<num_karts; i++)
|
||||||
{
|
{
|
||||||
Kart *kart = world->getKart(i);
|
Kart *kart = world->getKart(i);
|
||||||
if(kart->isEliminated()) continue;
|
if(kart->isEliminated()) continue;
|
||||||
kart->getNode()->setVisible(false);
|
kart->getNode()->setVisible(!(m_debug_mode & DM_NO_KARTS_GRAPHICS));
|
||||||
}
|
}
|
||||||
} // activate
|
} // nextDebugMode
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
/** Deactivates the bullet debug view, and makes all karts visible again.
|
|
||||||
*/
|
|
||||||
void IrrDebugDrawer::deactivate()
|
|
||||||
{
|
|
||||||
World *world = World::getWorld();
|
|
||||||
unsigned int num_karts = world->getNumKarts();
|
|
||||||
for(unsigned int i=0; i<num_karts; i++)
|
|
||||||
{
|
|
||||||
Kart *kart = world->getKart(i);
|
|
||||||
if(kart->isEliminated()) continue;
|
|
||||||
kart->getNode()->setVisible(true);
|
|
||||||
}
|
|
||||||
} // deactivate
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
void IrrDebugDrawer::drawLine(const btVector3& from, const btVector3& to,
|
void IrrDebugDrawer::drawLine(const btVector3& from, const btVector3& to,
|
||||||
const btVector3& color)
|
const btVector3& color)
|
||||||
{
|
{
|
||||||
Vec3 f(from);
|
|
||||||
Vec3 t(to);
|
|
||||||
video::SColor c(255, (int)(color.getX()*255), (int)(color.getY()*255),
|
video::SColor c(255, (int)(color.getX()*255), (int)(color.getY()*255),
|
||||||
(int)(color.getZ()*255) );
|
(int)(color.getZ()*255) );
|
||||||
irr_driver->getVideoDriver()->draw3DLine(f.toIrrVector(),
|
irr_driver->getVideoDriver()->draw3DLine((const core::vector3df&)from,
|
||||||
t.toIrrVector(), c);
|
(const core::vector3df&)to, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
@ -30,9 +30,18 @@ using namespace irr;
|
|||||||
|
|
||||||
class IrrDebugDrawer : public btIDebugDraw
|
class IrrDebugDrawer : public btIDebugDraw
|
||||||
{
|
{
|
||||||
/** The drawing mode to use. */
|
/** The drawing mode to use:
|
||||||
int m_debug_mode;
|
* If bit 0 is set, draw the bullet collision shape of karts
|
||||||
|
* If bit 1 is set, don't draw the kart graphics
|
||||||
|
*/
|
||||||
|
enum DebugModeType { DM_NONE = 0x00,
|
||||||
|
DM_KARTS_PHYSICS = 0x01,
|
||||||
|
DM_NO_KARTS_GRAPHICS = 0x02
|
||||||
|
};
|
||||||
|
DebugModeType m_debug_mode;
|
||||||
|
protected:
|
||||||
|
virtual void setDebugMode(int debug_mode) {}
|
||||||
|
virtual int getDebugMode() const { return DBG_DrawWireframe;}
|
||||||
public:
|
public:
|
||||||
IrrDebugDrawer();
|
IrrDebugDrawer();
|
||||||
void render(float dt);
|
void render(float dt);
|
||||||
@ -47,11 +56,9 @@ public:
|
|||||||
virtual void reportErrorWarning(const char* warningString) {}
|
virtual void reportErrorWarning(const char* warningString) {}
|
||||||
virtual void draw3dText(const btVector3& location,
|
virtual void draw3dText(const btVector3& location,
|
||||||
const char* textString) {}
|
const char* textString) {}
|
||||||
virtual void setDebugMode(int debug_mode) { m_debug_mode = debug_mode; }
|
/** Returns true if debug mode is enabled. */
|
||||||
virtual int getDebugMode() const { return m_debug_mode; }
|
bool debugEnabled() const {return m_debug_mode!=0;}
|
||||||
void activate();
|
void nextDebugMode();
|
||||||
void deactivate();
|
|
||||||
|
|
||||||
}; // IrrDebugDrawer
|
}; // IrrDebugDrawer
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -48,17 +48,17 @@ void Physics::init(const Vec3 &world_min, const Vec3 &world_max)
|
|||||||
m_axis_sweep,
|
m_axis_sweep,
|
||||||
this,
|
this,
|
||||||
m_collision_conf);
|
m_collision_conf);
|
||||||
m_dynamics_world->setGravity(btVector3(0.0f, 0.0f,
|
m_dynamics_world->setGravity(btVector3(0.0f,
|
||||||
-World::getWorld()->getTrack()->getGravity()));
|
-World::getWorld()->getTrack()->getGravity(),
|
||||||
|
0.0f));
|
||||||
m_debug_drawer = new IrrDebugDrawer();
|
m_debug_drawer = new IrrDebugDrawer();
|
||||||
m_debug_drawer->setDebugMode(btIDebugDraw::DBG_DrawWireframe);
|
|
||||||
m_dynamics_world->setDebugDrawer(m_debug_drawer);
|
m_dynamics_world->setDebugDrawer(m_debug_drawer);
|
||||||
} // init
|
} // init
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
Physics::~Physics()
|
Physics::~Physics()
|
||||||
{
|
{
|
||||||
if(UserConfigParams::m_bullet_debug) delete m_debug_drawer;
|
delete m_debug_drawer;
|
||||||
delete m_dynamics_world;
|
delete m_dynamics_world;
|
||||||
delete m_axis_sweep;
|
delete m_axis_sweep;
|
||||||
delete m_dispatcher;
|
delete m_dispatcher;
|
||||||
@ -153,7 +153,7 @@ void Physics::update(float dt)
|
|||||||
|
|
||||||
bool Physics::projectKartDownwards(const Kart *k)
|
bool Physics::projectKartDownwards(const Kart *k)
|
||||||
{
|
{
|
||||||
btVector3 hell(0, 0, -10000);
|
btVector3 hell(0, -10000, 0);
|
||||||
return k->getVehicle()->projectVehicleToSurface(hell, true /*allow translation*/);
|
return k->getVehicle()->projectVehicleToSurface(hell, true /*allow translation*/);
|
||||||
} //projectKartsDownwards
|
} //projectKartsDownwards
|
||||||
|
|
||||||
@ -343,6 +343,9 @@ btScalar Physics::solveGroup(btCollisionObject** bodies, int numBodies,
|
|||||||
/** A debug draw function to show the track and all karts. */
|
/** A debug draw function to show the track and all karts. */
|
||||||
void Physics::draw()
|
void Physics::draw()
|
||||||
{
|
{
|
||||||
|
if(!m_debug_drawer->debugEnabled() ||
|
||||||
|
!World::getWorld()->isRacePhase()) return;
|
||||||
|
|
||||||
video::SColor color(77,179,0,0);
|
video::SColor color(77,179,0,0);
|
||||||
video::SMaterial material;
|
video::SMaterial material;
|
||||||
material.Thickness = 2;
|
material.Thickness = 2;
|
||||||
|
@ -101,11 +101,11 @@ public:
|
|||||||
void draw ();
|
void draw ();
|
||||||
btDynamicsWorld*
|
btDynamicsWorld*
|
||||||
getPhysicsWorld () const {return m_dynamics_world;}
|
getPhysicsWorld () const {return m_dynamics_world;}
|
||||||
void debugDraw (float m[16], btCollisionShape *s, const btVector3 color);
|
/** Activates the next debug mode (or switches it off again).
|
||||||
/** Activates the debug drawer. */
|
*/
|
||||||
void activateDebug () {m_debug_drawer->activate(); }
|
void nextDebugMode () {m_debug_drawer->nextDebugMode(); }
|
||||||
/** Deactivates the debug drawer. */
|
/** Returns true if the debug drawer is enabled. */
|
||||||
void deactivateDebug () {m_debug_drawer->deactivate(); }
|
bool isDebug() const {return m_debug_drawer->debugEnabled(); }
|
||||||
bool projectKartDownwards(const Kart *k);
|
bool projectKartDownwards(const Kart *k);
|
||||||
virtual btScalar solveGroup(btCollisionObject** bodies, int numBodies,
|
virtual btScalar solveGroup(btCollisionObject** bodies, int numBodies,
|
||||||
btPersistentManifold** manifold,int numManifolds,
|
btPersistentManifold** manifold,int numManifolds,
|
||||||
|
@ -28,6 +28,8 @@
|
|||||||
|
|
||||||
History* history = 0;
|
History* history = 0;
|
||||||
|
|
||||||
|
#define KEEP_OLD_FORMAT
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
/** Initialises the history object and sets the mode to none.
|
/** Initialises the history object and sets the mode to none.
|
||||||
*/
|
*/
|
||||||
@ -64,7 +66,7 @@ void History::initRecording()
|
|||||||
void History::allocateMemory(int number_of_frames)
|
void History::allocateMemory(int number_of_frames)
|
||||||
{
|
{
|
||||||
m_all_deltas.resize (number_of_frames);
|
m_all_deltas.resize (number_of_frames);
|
||||||
unsigned int num_karts = World::getWorld()->getNumKarts();
|
unsigned int num_karts = race_manager->getNumberOfKarts();
|
||||||
m_all_controls.resize (number_of_frames*num_karts);
|
m_all_controls.resize (number_of_frames*num_karts);
|
||||||
m_all_xyz.resize (number_of_frames*num_karts);
|
m_all_xyz.resize (number_of_frames*num_karts);
|
||||||
m_all_rotations.resize(number_of_frames*num_karts);
|
m_all_rotations.resize(number_of_frames*num_karts);
|
||||||
@ -186,8 +188,12 @@ void History::Save()
|
|||||||
m_all_controls[j].m_steer,
|
m_all_controls[j].m_steer,
|
||||||
m_all_controls[j].m_accel,
|
m_all_controls[j].m_accel,
|
||||||
m_all_controls[j].getButtonsCompressed(),
|
m_all_controls[j].getButtonsCompressed(),
|
||||||
m_all_xyz[j].getX(), m_all_xyz[j].getY(),
|
m_all_xyz[j].getX(),
|
||||||
m_all_xyz[j].getZ(),
|
#ifdef KEEP_OLD_FORMAT
|
||||||
|
m_all_xyz[j].getZ(), m_all_xyz[j].getY(),
|
||||||
|
#else
|
||||||
|
m_all_xyz[j].getY(), m_all_xyz[j].getZ(),
|
||||||
|
#endif
|
||||||
m_all_rotations[j].getX(), m_all_rotations[j].getY(),
|
m_all_rotations[j].getX(), m_all_rotations[j].getY(),
|
||||||
m_all_rotations[j].getZ(), m_all_rotations[j].getW() );
|
m_all_rotations[j].getZ(), m_all_rotations[j].getW() );
|
||||||
j=(j+1)%m_size;
|
j=(j+1)%m_size;
|
||||||
@ -297,7 +303,18 @@ void History::Load()
|
|||||||
&m_all_controls[i].m_steer,
|
&m_all_controls[i].m_steer,
|
||||||
&m_all_controls[i].m_accel,
|
&m_all_controls[i].m_accel,
|
||||||
&buttonsCompressed,
|
&buttonsCompressed,
|
||||||
&x, &y, &z, &rx, &ry, &rz, &rw);
|
&x,
|
||||||
|
#ifdef KEEP_OLD_FORMAT
|
||||||
|
&z, &y,
|
||||||
|
//xyz
|
||||||
|
//yxz
|
||||||
|
//yzx
|
||||||
|
&rx, &rz, &ry, &rw
|
||||||
|
#else
|
||||||
|
&y, &z,
|
||||||
|
&rx, &ry, &rz, &rw
|
||||||
|
#endif
|
||||||
|
);
|
||||||
m_all_xyz[i] = Vec3(x,y,z);
|
m_all_xyz[i] = Vec3(x,y,z);
|
||||||
m_all_rotations[i] = btQuaternion(rx,ry,rz,rw);
|
m_all_rotations[i] = btQuaternion(rx,ry,rz,rw);
|
||||||
m_all_controls[i].setButtonsCompressed(char(buttonsCompressed));
|
m_all_controls[i].setButtonsCompressed(char(buttonsCompressed));
|
||||||
|
@ -661,7 +661,7 @@ public:
|
|||||||
// Random kart
|
// Random kart
|
||||||
scene::IMesh* model = item_manager->getItemModel(Item::ITEM_BONUS_BOX);
|
scene::IMesh* model = item_manager->getItemModel(Item::ITEM_BONUS_BOX);
|
||||||
w3->clearModels();
|
w3->clearModels();
|
||||||
w3->addModel( model, Vec3(0.0f, 0.0f, -12.0f) );
|
w3->addModel( model, Vec3(0.0f, -12.0f, 0.0f) );
|
||||||
w3->update(0);
|
w3->update(0);
|
||||||
m_parent->m_kart_widgets[playerID].kartName->setText( _("Random Kart") );
|
m_parent->m_kart_widgets[playerID].kartName->setText( _("Random Kart") );
|
||||||
}
|
}
|
||||||
|
@ -60,7 +60,7 @@ void CheckLine::reset(const Track &track)
|
|||||||
Vec3 CheckLine::getCenterPoint() const
|
Vec3 CheckLine::getCenterPoint() const
|
||||||
{
|
{
|
||||||
core::vector2df c=m_line.getMiddle();
|
core::vector2df c=m_line.getMiddle();
|
||||||
Vec3 xyz(c.X, c.Y, m_min_height);
|
Vec3 xyz(c.X, m_min_height, c.Y);
|
||||||
return xyz;
|
return xyz;
|
||||||
} // getCenterPoint
|
} // getCenterPoint
|
||||||
|
|
||||||
@ -89,8 +89,8 @@ bool CheckLine::isTriggered(const Vec3 &old_pos, const Vec3 &new_pos, int indx)
|
|||||||
// between -1 and 4 units (negative numbers are unlikely, but help
|
// between -1 and 4 units (negative numbers are unlikely, but help
|
||||||
// in case that there is 'somewhat' inside of the track, or the
|
// in case that there is 'somewhat' inside of the track, or the
|
||||||
// checklines are a bit off in Z direction.
|
// checklines are a bit off in Z direction.
|
||||||
result = new_pos.getZ()-m_min_height<4.0f &&
|
result = new_pos.getY()-m_min_height<4.0f &&
|
||||||
new_pos.getZ()-m_min_height>-1.0f;
|
new_pos.getY()-m_min_height>-1.0f;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
result = false;
|
result = false;
|
||||||
|
@ -52,10 +52,10 @@ GraphNode::GraphNode(unsigned int index)
|
|||||||
+ (quad[3]-quad[2]).length() ) * 0.5f;
|
+ (quad[3]-quad[2]).length() ) * 0.5f;
|
||||||
Vec3 lower = (quad[0]+quad[1]) * 0.5f;
|
Vec3 lower = (quad[0]+quad[1]) * 0.5f;
|
||||||
Vec3 upper = (quad[2]+quad[3]) * 0.5f;
|
Vec3 upper = (quad[2]+quad[3]) * 0.5f;
|
||||||
m_line = core::line2df(lower.getX(), lower.getY(),
|
m_line = core::line2df(lower.getX(), lower.getZ(),
|
||||||
upper.getX(), upper.getY() );
|
upper.getX(), upper.getZ() );
|
||||||
// Only this 2d point is needed later
|
// Only this 2d point is needed later
|
||||||
m_lower_center = core::vector2df(lower.getX(), lower.getY());
|
m_lower_center = core::vector2df(lower.getX(), lower.getZ());
|
||||||
} // GraphNode
|
} // GraphNode
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@ -76,7 +76,7 @@ void GraphNode::addSuccessor(unsigned int to)
|
|||||||
Vec3 diff = next_quad.getCenter() - this_quad.getCenter();
|
Vec3 diff = next_quad.getCenter() - this_quad.getCenter();
|
||||||
m_distance_to_next.push_back(d2.getLength());
|
m_distance_to_next.push_back(d2.getLength());
|
||||||
|
|
||||||
float theta = -atan2(diff.getX(), diff.getY());
|
float theta = atan2(diff.getX(), diff.getZ());
|
||||||
m_angle_to_next.push_back(theta);
|
m_angle_to_next.push_back(theta);
|
||||||
|
|
||||||
// The length of this quad is the average of the left and right side
|
// The length of this quad is the average of the left and right side
|
||||||
@ -103,15 +103,15 @@ void GraphNode::addSuccessor(unsigned int to)
|
|||||||
* is it. All these computations are done in 2D only.
|
* is it. All these computations are done in 2D only.
|
||||||
* \param xyz The coordinates of the point.
|
* \param xyz The coordinates of the point.
|
||||||
* \param result The X coordinate contains the sidewards distance, the
|
* \param result The X coordinate contains the sidewards distance, the
|
||||||
* y coordinate the forward distance.
|
* Z coordinate the forward distance.
|
||||||
*/
|
*/
|
||||||
void GraphNode::getDistances(const Vec3 &xyz, Vec3 *result)
|
void GraphNode::getDistances(const Vec3 &xyz, Vec3 *result)
|
||||||
{
|
{
|
||||||
core::vector2df xyz2d(xyz.getX(), xyz.getY());
|
core::vector2df xyz2d(xyz.getX(), xyz.getZ());
|
||||||
core::vector2df closest = m_line.getClosestPoint(xyz2d);
|
core::vector2df closest = m_line.getClosestPoint(xyz2d);
|
||||||
if(m_line.getPointOrientation(xyz2d)>0)
|
if(m_line.getPointOrientation(xyz2d)>0)
|
||||||
result->setX( (closest-xyz2d).getLength()); // to the right
|
result->setX( (closest-xyz2d).getLength()); // to the right
|
||||||
else
|
else
|
||||||
result->setX(-(closest-xyz2d).getLength()); // to the left
|
result->setX(-(closest-xyz2d).getLength()); // to the left
|
||||||
result->setY( m_distance_from_start + (closest-m_lower_center).getLength());
|
result->setZ( m_distance_from_start + (closest-m_lower_center).getLength());
|
||||||
} // getDistances
|
} // getDistances
|
||||||
|
@ -41,8 +41,8 @@ Quad::Quad(const Vec3 &p0, const Vec3 &p1, const Vec3 &p2, const Vec3 &p3,
|
|||||||
m_p[0]=p0; m_p[1]=p1; m_p[2]=p2; m_p[3]=p3;
|
m_p[0]=p0; m_p[1]=p1; m_p[2]=p2; m_p[3]=p3;
|
||||||
}
|
}
|
||||||
m_center = 0.25f*(p0+p1+p2+p3);
|
m_center = 0.25f*(p0+p1+p2+p3);
|
||||||
m_min_height = std::min ( std::min(p0.getZ(), p1.getZ()),
|
m_min_height = std::min ( std::min(p0.getY(), p1.getY()),
|
||||||
std::min(p0.getZ(), p1.getZ()) );
|
std::min(p0.getY(), p1.getY()) );
|
||||||
m_invisible = invisible;
|
m_invisible = invisible;
|
||||||
} // Quad
|
} // Quad
|
||||||
|
|
||||||
@ -87,8 +87,8 @@ void Quad::getVertices(video::S3DVertex *v, const video::SColor &color) const
|
|||||||
*/
|
*/
|
||||||
float Quad::sideOfLine2D(const Vec3& l1, const Vec3& l2, const Vec3& p) const
|
float Quad::sideOfLine2D(const Vec3& l1, const Vec3& l2, const Vec3& p) const
|
||||||
{
|
{
|
||||||
return (l2.getX()-l1.getX())*(p.getY()-l1.getY()) -
|
return (l2.getX()-l1.getX())*(p.getZ()-l1.getZ()) -
|
||||||
(l2.getY()-l1.getY())*(p.getX()-l1.getX());
|
(l2.getZ()-l1.getZ())*(p.getX()-l1.getX());
|
||||||
} // sideOfLine
|
} // sideOfLine
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@ -102,6 +102,7 @@ bool Quad::pointInQuad(const Vec3& p) const
|
|||||||
sideOfLine2D(m_p[3], m_p[0], p) >= 0.0;
|
sideOfLine2D(m_p[3], m_p[0], p) >= 0.0;
|
||||||
}
|
}
|
||||||
} // pointInQuad
|
} // pointInQuad
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
/** Transforms a quad by a given transform (i.e. translation+rotation). This
|
/** Transforms a quad by a given transform (i.e. translation+rotation). This
|
||||||
* function does not modify this quad, the results are stored in the quad
|
* function does not modify this quad, the results are stored in the quad
|
||||||
|
@ -79,7 +79,7 @@ void QuadGraph::setStartCoordinate(const CheckLine &cl)
|
|||||||
}
|
}
|
||||||
Vec3 xyz;
|
Vec3 xyz;
|
||||||
spatialToTrack(&xyz, start_point, sector);
|
spatialToTrack(&xyz, start_point, sector);
|
||||||
m_offset_for_startline = xyz.getY();
|
m_offset_for_startline = xyz.getZ();
|
||||||
} // setStartCoordinate
|
} // setStartCoordinate
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
@ -311,7 +311,7 @@ void QuadGraph::getSuccessors(int node_number, std::vector<unsigned int>& succ)
|
|||||||
* of the returned vector is how much of the track the point has gone
|
* of the returned vector is how much of the track the point has gone
|
||||||
* through, the x-axis is on which side of the road it is. The Z axis
|
* through, the x-axis is on which side of the road it is. The Z axis
|
||||||
* is not changed.
|
* is not changed.
|
||||||
* \param dst Returns the results in the X and Y coordinates.
|
* \param dst Returns the results in the X and Z coordinates.
|
||||||
* \param xyz The position of the kart.
|
* \param xyz The position of the kart.
|
||||||
* \param sector The graph node the position is on.
|
* \param sector The graph node the position is on.
|
||||||
*/
|
*/
|
||||||
@ -325,10 +325,10 @@ void QuadGraph::spatialToTrack(Vec3 *dst, const Vec3& xyz,
|
|||||||
}
|
}
|
||||||
|
|
||||||
getNode(sector).getDistances(xyz, dst);
|
getNode(sector).getDistances(xyz, dst);
|
||||||
float y=dst->getY();
|
float z=dst->getZ();
|
||||||
y=y-m_offset_for_startline;
|
z=z-m_offset_for_startline;
|
||||||
if(y<0) y+=m_lap_length;
|
if(z<0) z+=m_lap_length;
|
||||||
dst->setY(y);
|
dst->setZ(z);
|
||||||
} // spatialToTrack
|
} // spatialToTrack
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -381,7 +381,7 @@ void QuadGraph::findRoadSector(const Vec3& xyz, int *sector,
|
|||||||
else
|
else
|
||||||
indx = indx<(int)m_all_nodes.size()-1 ? indx +1 : 0;
|
indx = indx<(int)m_all_nodes.size()-1 ? indx +1 : 0;
|
||||||
const Quad &q = getQuad(indx);
|
const Quad &q = getQuad(indx);
|
||||||
float dist = xyz.getZ() - q.getMinHeight();
|
float dist = xyz.getY() - q.getMinHeight();
|
||||||
// While negative distances are unlikely, we allow some small netative
|
// While negative distances are unlikely, we allow some small netative
|
||||||
// numbers in case that the kart is partly in the track.
|
// numbers in case that the kart is partly in the track.
|
||||||
if(q.pointInQuad(xyz) && dist < min_dist && dist>-1.0f)
|
if(q.pointInQuad(xyz) && dist < min_dist && dist>-1.0f)
|
||||||
@ -489,15 +489,15 @@ video::ITexture *QuadGraph::makeMiniMap(const core::dimension2du &dimension,
|
|||||||
Vec3 center = (bb_max+bb_min)*0.5f;
|
Vec3 center = (bb_max+bb_min)*0.5f;
|
||||||
core::matrix4 projection;
|
core::matrix4 projection;
|
||||||
projection.buildProjectionMatrixOrthoLH(bb_max.getX()-bb_min.getX(),
|
projection.buildProjectionMatrixOrthoLH(bb_max.getX()-bb_min.getX(),
|
||||||
bb_max.getY()-bb_min.getY(),
|
bb_max.getZ()-bb_min.getZ(),
|
||||||
-1, bb_max.getZ()-bb_min.getZ()+1);
|
-1, bb_max.getY()-bb_min.getY()+1);
|
||||||
camera->setProjectionMatrix(projection, true);
|
camera->setProjectionMatrix(projection, true);
|
||||||
// Adjust z position by +1 for max, -1 for min - this helps in case that
|
// Adjust z position by +1 for max, -1 for min - this helps in case that
|
||||||
// the maximum z coordinate is negative (otherwise the minimap is mirrored)
|
// the maximum z coordinate is negative (otherwise the minimap is mirrored)
|
||||||
// and avoids problems for tracks which have a flat (max z = min z) minimap.
|
// and avoids problems for tracks which have a flat (max z = min z) minimap.
|
||||||
camera->setPosition(core::vector3df(center.getX(), bb_max.getZ()+1, center.getY()));
|
camera->setPosition(core::vector3df(center.getX(), bb_max.getY()+1, center.getZ()));
|
||||||
camera->setUpVector(core::vector3df(0, 0, 1));
|
camera->setUpVector(core::vector3df(0, 0, 1));
|
||||||
camera->setTarget(core::vector3df(center.getX(),bb_min.getZ()-1,center.getY()));
|
camera->setTarget(core::vector3df(center.getX(),bb_min.getY()-1,center.getZ()));
|
||||||
|
|
||||||
video::ITexture *texture = rttProvider.renderToTexture();
|
video::ITexture *texture = rttProvider.renderToTexture();
|
||||||
|
|
||||||
@ -505,7 +505,7 @@ video::ITexture *QuadGraph::makeMiniMap(const core::dimension2du &dimension,
|
|||||||
irr_driver->removeCameraSceneNode(camera);
|
irr_driver->removeCameraSceneNode(camera);
|
||||||
m_min_coord = bb_min;
|
m_min_coord = bb_min;
|
||||||
m_scaling.setX(dimension.Width/(bb_max.getX()-bb_min.getX()));
|
m_scaling.setX(dimension.Width/(bb_max.getX()-bb_min.getX()));
|
||||||
m_scaling.setY(dimension.Width/(bb_max.getY()-bb_min.getY()));
|
m_scaling.setZ(dimension.Width/(bb_max.getZ()-bb_min.getZ()));
|
||||||
return texture;
|
return texture;
|
||||||
} // drawMiniMap
|
} // drawMiniMap
|
||||||
|
|
||||||
@ -519,6 +519,6 @@ video::ITexture *QuadGraph::makeMiniMap(const core::dimension2du &dimension,
|
|||||||
void QuadGraph::mapPoint2MiniMap(const Vec3 &xyz,Vec3 *draw_at) const
|
void QuadGraph::mapPoint2MiniMap(const Vec3 &xyz,Vec3 *draw_at) const
|
||||||
{
|
{
|
||||||
draw_at->setX((xyz.getX()-m_min_coord.getX())*m_scaling.getX());
|
draw_at->setX((xyz.getX()-m_min_coord.getX())*m_scaling.getX());
|
||||||
draw_at->setY((xyz.getY()-m_min_coord.getY())*m_scaling.getY());
|
draw_at->setY((xyz.getZ()-m_min_coord.getZ())*m_scaling.getZ());
|
||||||
|
|
||||||
} // mapPoint
|
} // mapPoint
|
||||||
|
@ -60,13 +60,13 @@ float TerrainInfo::getTerrainPitch(float heading) const {
|
|||||||
if(m_HoT==Track::NOHIT) return 0.0f;
|
if(m_HoT==Track::NOHIT) return 0.0f;
|
||||||
|
|
||||||
const float X =-sin(heading);
|
const float X =-sin(heading);
|
||||||
const float Y = cos(heading);
|
const float Z = cos(heading);
|
||||||
// Compute the angle between the normal of the plane and the line to
|
// Compute the angle between the normal of the plane and the line to
|
||||||
// (x,y,0). (x,y,0) is normalised, so are the coordinates of the plane,
|
// (x,0,z). (x,0,z) is normalised, so are the coordinates of the plane,
|
||||||
// simplifying the computation of the scalar product.
|
// simplifying the computation of the scalar product.
|
||||||
float pitch = ( m_normal.getX()*X + m_normal.getY()*Y ); // use ( x,y,0)
|
float pitch = ( m_normal.getX()*X + m_normal.getZ()*Z ); // use (x, 0, z)
|
||||||
|
|
||||||
// The actual angle computed above is between the normal and the (x,y,0)
|
// The actual angle computed above is between the normal and the (x, 0, z)
|
||||||
// line, so to compute the actual angles 90 degrees must be subtracted.
|
// line, so to compute the actual angles 90 degrees must be subtracted.
|
||||||
pitch = acosf(pitch) - NINETY_DEGREE_RAD;
|
pitch = acosf(pitch) - NINETY_DEGREE_RAD;
|
||||||
return pitch;
|
return pitch;
|
||||||
|
@ -166,7 +166,7 @@ btTransform Track::getStartTransform(unsigned int pos) const
|
|||||||
|
|
||||||
Vec3 orig = pos<m_start_positions.size()
|
Vec3 orig = pos<m_start_positions.size()
|
||||||
? m_start_positions[pos]
|
? m_start_positions[pos]
|
||||||
: Vec3( (pos%2==0)?1.5f:-1.5f, -1.5f*pos-1.5f, 1.0f);
|
: Vec3( (pos%2==0)?1.5f:-1.5f, 1.0f, -1.5f*pos-1.5f);
|
||||||
btTransform start;
|
btTransform start;
|
||||||
start.setOrigin(orig);
|
start.setOrigin(orig);
|
||||||
start.setRotation(btQuaternion(btVector3(0, 0, 1),
|
start.setRotation(btQuaternion(btVector3(0, 0, 1),
|
||||||
@ -391,7 +391,7 @@ void Track::convertTrackToBullet(const scene::IMesh *mesh,
|
|||||||
int indx=mbIndices[j+k];
|
int indx=mbIndices[j+k];
|
||||||
core::vector3df v = mbVertices[indx].Pos;
|
core::vector3df v = mbVertices[indx].Pos;
|
||||||
mat.transformVect(v);
|
mat.transformVect(v);
|
||||||
vertices[k] = Vec3(v);
|
vertices[k]=v;
|
||||||
} // for k
|
} // for k
|
||||||
if(tmesh) tmesh->addTriangle(vertices[0], vertices[1],
|
if(tmesh) tmesh->addTriangle(vertices[0], vertices[1],
|
||||||
vertices[2], material );
|
vertices[2], material );
|
||||||
@ -703,7 +703,7 @@ void Track::loadTrackModel(unsigned int mode_id)
|
|||||||
// Set some kind of default in case Z is not defined in the file
|
// Set some kind of default in case Z is not defined in the file
|
||||||
// (with the new track exporter it always is defined anyway).
|
// (with the new track exporter it always is defined anyway).
|
||||||
// Z is the height from which the item is dropped on the track.
|
// Z is the height from which the item is dropped on the track.
|
||||||
xyz.setZ(1000);
|
xyz.setY(1000);
|
||||||
node->getXYZ(&xyz);
|
node->getXYZ(&xyz);
|
||||||
bool drop=true;
|
bool drop=true;
|
||||||
node->get("drop", &drop);
|
node->get("drop", &drop);
|
||||||
@ -884,14 +884,14 @@ void Track::itemCommand(const Vec3 &xyz, Item::ItemType type,
|
|||||||
// 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(drop)
|
if(drop)
|
||||||
{
|
{
|
||||||
loc.setZ(getTerrainHeight(loc));
|
loc.setY(getTerrainHeight(loc));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't tilt the items, since otherwise the rotation will look odd,
|
// Don't tilt the items, since otherwise the rotation will look odd,
|
||||||
// i.e. the items will not rotate around the normal, but 'wobble'
|
// i.e. the items will not rotate around the normal, but 'wobble'
|
||||||
// around.
|
// around.
|
||||||
//Vec3 normal(0.7071f, 0, 0.7071f);
|
//Vec3 normal(0.7071f, 0, 0.7071f);
|
||||||
Vec3 normal(0, 0, 1);
|
Vec3 normal(0, 1, 0);
|
||||||
item_manager->newItem(type, loc, normal);
|
item_manager->newItem(type, loc, normal);
|
||||||
} // itemCommand
|
} // itemCommand
|
||||||
|
|
||||||
@ -900,7 +900,7 @@ void Track::getTerrainInfo(const Vec3 &pos, float *hot, Vec3 *normal,
|
|||||||
const Material **material) const
|
const Material **material) const
|
||||||
{
|
{
|
||||||
btVector3 to_pos(pos);
|
btVector3 to_pos(pos);
|
||||||
to_pos.setZ(-100000.f);
|
to_pos.setY(-100000.f);
|
||||||
|
|
||||||
class MaterialCollision : public btCollisionWorld::ClosestRayResultCallback
|
class MaterialCollision : public btCollisionWorld::ClosestRayResultCallback
|
||||||
{
|
{
|
||||||
@ -938,7 +938,7 @@ void Track::getTerrainInfo(const Vec3 &pos, float *hot, Vec3 *normal,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
*hot = rayCallback.m_hitPointWorld.getZ();
|
*hot = rayCallback.m_hitPointWorld.getY();
|
||||||
*normal = rayCallback.m_hitNormalWorld;
|
*normal = rayCallback.m_hitNormalWorld;
|
||||||
*material = rayCallback.m_material;
|
*material = rayCallback.m_material;
|
||||||
// Note: material might be NULL. This happens if the ray cast does not
|
// Note: material might be NULL. This happens if the ray cast does not
|
||||||
|
@ -56,7 +56,7 @@ public:
|
|||||||
Coord(const btTransform& t)
|
Coord(const btTransform& t)
|
||||||
{
|
{
|
||||||
m_xyz = t.getOrigin();
|
m_xyz = t.getOrigin();
|
||||||
m_hpr.setHPR(t.getBasis());
|
m_hpr.setHPR(t.getRotation());
|
||||||
//setSgCoord();
|
//setSgCoord();
|
||||||
} // Coord
|
} // Coord
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
@ -21,59 +21,22 @@
|
|||||||
|
|
||||||
#include "utils/constants.hpp"
|
#include "utils/constants.hpp"
|
||||||
|
|
||||||
void Vec3::setHPR(const btMatrix3x3& m)
|
|
||||||
|
void Vec3::setHPR(const btQuaternion& q)
|
||||||
{
|
{
|
||||||
float f[4][4];
|
float W = q.getW();
|
||||||
m.getOpenGLSubMatrix((float*)f);
|
float X = q.getX();
|
||||||
|
float Y = q.getY();
|
||||||
|
float Z = q.getZ();
|
||||||
|
float WSquared = W * W;
|
||||||
|
float XSquared = X * X;
|
||||||
|
float YSquared = Y * Y;
|
||||||
|
float ZSquared = Z * Z;
|
||||||
|
|
||||||
float s = m.getColumn(0).length();
|
setX(atan2f(2.0f * (Y * Z + X * W), -XSquared - YSquared + ZSquared + WSquared));
|
||||||
|
setY(asinf(-2.0f * (X * Z - Y * W)));
|
||||||
if ( s <= 0.00001 )
|
setZ(atan2f(2.0f * (X * Y + Z * W), XSquared - YSquared - ZSquared + WSquared));
|
||||||
{
|
} // setHPR(btQuaternion)
|
||||||
fprintf(stderr,"setHPR: bad matrix\n");
|
|
||||||
setValue(0,0,0);
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
s=1/s;
|
|
||||||
|
|
||||||
#define CLAMPTO1(x) x<-1 ? -1 : (x>1 ? 1 : x)
|
|
||||||
|
|
||||||
setY(asin(CLAMPTO1(m.getRow(2).getY())));
|
|
||||||
|
|
||||||
float cp = cos(getY());
|
|
||||||
|
|
||||||
/* If pointing nearly vertically up - then heading is ill-defined */
|
|
||||||
|
|
||||||
|
|
||||||
if ( cp > -0.00001 && cp < 0.00001 )
|
|
||||||
{
|
|
||||||
float cr = CLAMPTO1( m.getRow(1).getX()*s);
|
|
||||||
float sr = CLAMPTO1(-m.getRow(1).getZ()*s);
|
|
||||||
|
|
||||||
setX(0.0f);
|
|
||||||
setZ(atan2(sr, cr ));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cp = s / cp ; // includes the scaling factor
|
|
||||||
float sr = CLAMPTO1( -m.getRow(2).getX() * cp );
|
|
||||||
float cr = CLAMPTO1( m.getRow(2).getZ() * cp );
|
|
||||||
float sh = CLAMPTO1( -m.getRow(0).getY() * cp );
|
|
||||||
float ch = CLAMPTO1( m.getRow(1).getY() * cp );
|
|
||||||
|
|
||||||
if ( (sh == 0.0f && ch == 0.0f) || (sr == 0.0f && cr == 0.0f) )
|
|
||||||
{
|
|
||||||
cr = CLAMPTO1( m.getRow(1).getX()*s);
|
|
||||||
sr = CLAMPTO1(-m.getRow(1).getZ()*s) ;
|
|
||||||
|
|
||||||
setX(0.0f);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
setX(atan2(sh, ch ));
|
|
||||||
|
|
||||||
setZ(atan2(sr, cr ));
|
|
||||||
}
|
|
||||||
} // setHPR
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
void Vec3::degreeToRad()
|
void Vec3::degreeToRad()
|
||||||
@ -95,8 +58,8 @@ void Vec3::setPitchRoll(const Vec3 &normal)
|
|||||||
// Compute the angle between the normal of the plane and the line to
|
// Compute the angle between the normal of the plane and the line to
|
||||||
// (x,y,0). (x,y,0) is normalised, so are the coordinates of the plane,
|
// (x,y,0). (x,y,0) is normalised, so are the coordinates of the plane,
|
||||||
// simplifying the computation of the scalar product.
|
// simplifying the computation of the scalar product.
|
||||||
float pitch = ( normal.getX()*X + normal.getY()*Y ); // use ( x,y,0)
|
float pitch = ( normal.getX()*X + normal.getZ()*Y ); // use ( x,y,0)
|
||||||
float roll = (-normal.getX()*Y + normal.getY()*X ); // use (-y,x,0)
|
float roll = (-normal.getX()*Y + normal.getZ()*X ); // use (-y,x,0)
|
||||||
|
|
||||||
// The actual angle computed above is between the normal and the (x,y,0)
|
// The actual angle computed above is between the normal and the (x,y,0)
|
||||||
// line, so to compute the actual angles 90 degrees must be subtracted.
|
// line, so to compute the actual angles 90 degrees must be subtracted.
|
||||||
@ -111,22 +74,24 @@ void Vec3::setPitchRoll(const Vec3 &normal)
|
|||||||
*/
|
*/
|
||||||
const core::vector3df Vec3::toIrrHPR() const
|
const core::vector3df Vec3::toIrrHPR() const
|
||||||
{
|
{
|
||||||
core::vector3df r(RAD_TO_DEGREE*(-getY()), // pitch
|
core::vector3df r(RAD_TO_DEGREE*(getX()), // pitch
|
||||||
RAD_TO_DEGREE*(-getX()), // heading
|
RAD_TO_DEGREE*(getY()), // heading
|
||||||
RAD_TO_DEGREE*(-getZ()) ); // roll
|
RAD_TO_DEGREE*(getZ()) ); // roll
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
} // toIrrHPR
|
} // toIrrHPR
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
const core::vector3df Vec3::toIrrVector() const
|
/** Converts a vec3 into an irrlicht vector (which is a simple type cast).
|
||||||
|
*/
|
||||||
|
const core::vector3df& Vec3::toIrrVector() const
|
||||||
{
|
{
|
||||||
core::vector3df v(m_x, m_z, m_y);
|
return (const core::vector3df&)*this;
|
||||||
return v;
|
|
||||||
} // toIrrVector
|
} // toIrrVector
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
/** Returns the X and Y component as an irrlicht 2d vector. */
|
/** Returns the X and Y component as an irrlicht 2d vector. */
|
||||||
const core::vector2df Vec3::toIrrVector2d() const
|
const core::vector2df Vec3::toIrrVector2d() const
|
||||||
{
|
{
|
||||||
core::vector2df v(m_x, m_y);
|
core::vector2df v(m_x, m_z);
|
||||||
return v;
|
return v;
|
||||||
} // toIrrVector2d
|
} // toIrrVector2d
|
||||||
|
@ -40,8 +40,7 @@ public:
|
|||||||
* axis as well (so a vector3df can be stored in and restored from
|
* axis as well (so a vector3df can be stored in and restored from
|
||||||
* a vec3).
|
* a vec3).
|
||||||
*/
|
*/
|
||||||
inline Vec3(const core::vector3df &v) : btVector3(v.X, v.Z, v.Y) {}
|
inline Vec3(const core::vector3df &v) : btVector3(v.X, v.Y, v.Z) {}
|
||||||
//inline Vec3(sgVec3 a) : btVector3(a[0], a[1], a[2]) {}
|
|
||||||
inline Vec3(const btVector3& a) : btVector3(a) {}
|
inline Vec3(const btVector3& a) : btVector3(a) {}
|
||||||
inline Vec3() : btVector3() {}
|
inline Vec3() : btVector3() {}
|
||||||
inline Vec3(float x, float y, float z) : btVector3(x,y,z) {}
|
inline Vec3(float x, float y, float z) : btVector3(x,y,z) {}
|
||||||
@ -54,29 +53,28 @@ public:
|
|||||||
{m_x=heading;
|
{m_x=heading;
|
||||||
setPitchRoll(normal);}
|
setPitchRoll(normal);}
|
||||||
|
|
||||||
void setHPR(const btMatrix3x3& m);
|
void setHPR(const btQuaternion& q);
|
||||||
inline const float operator[](int n) const { return *(&m_x+n); }
|
inline const float operator[](int n) const { return *(&m_x+n); }
|
||||||
inline const float getHeading() const {return m_x; }
|
inline const float getHeading() const { return m_y; }
|
||||||
inline const float getPitch() const {return m_y; }
|
inline const float getPitch() const { return m_x; }
|
||||||
inline const float getRoll() const { return m_z; }
|
inline const float getRoll() const { return m_z; }
|
||||||
inline const void setHeading(float f) {m_x = f;}
|
inline const void setHeading(float f) { m_y = f; }
|
||||||
inline const void setPitch(float f) {m_y = f;}
|
inline const void setPitch(float f) { m_x = f; }
|
||||||
inline const void setRoll(float f) { m_z = f; }
|
inline const void setRoll(float f) { m_z = f; }
|
||||||
float* toFloat() const {return (float*)this; }
|
|
||||||
/** Converts a Vec3 to an irrlicht 3d floating point vector. */
|
/** Converts a Vec3 to an irrlicht 3d floating point vector. */
|
||||||
const core::vector3df toIrrVector() const;
|
const core::vector3df& toIrrVector() const;
|
||||||
const core::vector3df toIrrHPR() const;
|
const core::vector3df toIrrHPR() const;
|
||||||
const core::vector2df toIrrVector2d() const;
|
const core::vector2df toIrrVector2d() const;
|
||||||
void degreeToRad();
|
void degreeToRad();
|
||||||
Vec3& operator=(const btVector3& a) {*(btVector3*)this=a; return *this;}
|
Vec3& operator=(const btVector3& a) {*(btVector3*)this=a; return *this;}
|
||||||
Vec3& operator=(const btMatrix3x3& m) {setHPR(m); return *this;}
|
Vec3& operator=(const btQuaternion& q){setHPR(q); return *this;}
|
||||||
Vec3 operator-(const Vec3& v1) const {return (Vec3)(*(btVector3*)this-(btVector3)v1);}
|
Vec3 operator-(const Vec3& v1) const {return (Vec3)(*(btVector3*)this-(btVector3)v1);}
|
||||||
/** Helper functions to treat this vec3 as a 2d vector. This returns the
|
/** Helper functions to treat this vec3 as a 2d vector. This returns the
|
||||||
* square of the length of the first 2 dimensions. */
|
* square of the length of the first 2 dimensions. */
|
||||||
float length2_2d() const {return m_x*m_x + m_y*m_y;}
|
float length2_2d() const {return m_x*m_x + m_z*m_z;}
|
||||||
/** Returns the length of this vector in the plane, i.e. the vector is
|
/** Returns the length of this vector in the plane, i.e. the vector is
|
||||||
* used as a 2d vector. */
|
* used as a 2d vector. */
|
||||||
float length_2d() const {return sqrt(m_x*m_x + m_y*m_y);}
|
float length_2d() const {return sqrt(m_x*m_x + m_z*m_z);}
|
||||||
/** Sets this = max(this, a) componentwise.
|
/** Sets this = max(this, a) componentwise.
|
||||||
* \param Vector to compare with. */
|
* \param Vector to compare with. */
|
||||||
void max(const Vec3& a) {if(a.getX()>m_x) m_x=a.getX();
|
void max(const Vec3& a) {if(a.getX()>m_x) m_x=a.getX();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user