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"?>
|
||||
|
||||
<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
|
||||
|
||||
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
|
||||
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
|
||||
min-kart-version="1"
|
||||
max-kart-version="1"
|
||||
min-track-version="1"
|
||||
max-track-version="1"
|
||||
min-kart-version="2"
|
||||
max-kart-version="2"
|
||||
min-track-version="2"
|
||||
max-track-version="2"
|
||||
max-karts="8"
|
||||
scores="10 8 6 5 4 3 2 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),
|
||||
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
|
||||
|
||||
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"
|
||||
corn-f ="4"
|
||||
corn-r="4"
|
||||
gravity-center-shift="0 0 0.3"
|
||||
gravity-center-shift="0 0.3 0"
|
||||
nitro-power-boost="3"
|
||||
|
||||
skid-increase="1.05"
|
||||
@ -223,11 +244,11 @@ rubber-band-duration is the duration a rubber band acts.
|
||||
suspension-travel-cm="19"
|
||||
jump-velocity="3.0"
|
||||
collision-side-impulse="0"
|
||||
z-rescue-offset="0.0"
|
||||
wheel-front-right="0.38 0.6 0"
|
||||
wheel-front-left="-0.38 0.6 0"
|
||||
wheel-rear-right="0.38 -0.6 0"
|
||||
wheel-rear-left="-0.38 -0.6 0"
|
||||
vert-rescue-offset="0.0"
|
||||
wheel-front-right="0.38 0 0.6"
|
||||
wheel-front-left="-0.38 0 0.6"
|
||||
wheel-rear-right="0.38 0 -0.6"
|
||||
wheel-rear-left="-0.38 0 -0.6"
|
||||
gear-switch-ratio="0.25 0.7 1.0"
|
||||
gear-power-increase="2.2 1.7 1.3"
|
||||
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/*.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++)
|
||||
{
|
||||
//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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -690,7 +690,7 @@ void btRaycastVehicle::updateFriction(btScalar timeStep)
|
||||
|
||||
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);
|
||||
|
||||
//apply friction impulse on the ground
|
||||
|
@ -232,7 +232,6 @@ namespace UserConfigParams
|
||||
// ---- 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 bool m_bullet_debug PARAM_DEFAULT( false );
|
||||
PARAM_PREFIX bool m_print_kart_sizes PARAM_DEFAULT( false );
|
||||
|
||||
// ---- Networking
|
||||
|
@ -20,6 +20,8 @@
|
||||
|
||||
#include "graphics/camera.hpp"
|
||||
|
||||
#include "math.h"
|
||||
|
||||
#include "audio/sound_manager.hpp"
|
||||
#include "config/user_config.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
@ -48,7 +50,7 @@ Camera::Camera(int camera_index, const Kart* kart)
|
||||
m_position_speed = 8.0f;
|
||||
m_target_speed = 10.0f;
|
||||
m_rotation_range = 0.4f;
|
||||
|
||||
reset();
|
||||
} // Camera
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -169,6 +171,7 @@ Camera::Mode Camera::getMode()
|
||||
void Camera::reset()
|
||||
{
|
||||
setMode(CM_NORMAL);
|
||||
setInitialTransform();
|
||||
} // reset
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -177,7 +180,9 @@ void Camera::reset()
|
||||
*/
|
||||
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 ) );
|
||||
} // setInitialTransform
|
||||
|
||||
@ -206,7 +211,7 @@ void Camera::smoothMoveCamera(float dt, const Vec3 &wanted_position,
|
||||
// high above the kart straight down.
|
||||
#undef DEBUG_CAMERA
|
||||
#ifdef DEBUG_CAMERA
|
||||
core::vector3df xyz = RaceManager::getKart(0)->getXYZ().toIrrVector();
|
||||
core::vector3df xyz = m_kart->getXYZ().toIrrVector();
|
||||
m_camera->setTarget(xyz);
|
||||
xyz.Y = xyz.Y+30;
|
||||
m_camera->setPosition(xyz);
|
||||
@ -225,16 +230,21 @@ void Camera::computeNormalCameraPosition(Vec3 *wanted_position,
|
||||
Vec3 *wanted_target)
|
||||
{
|
||||
*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
|
||||
// towards where the kart is turning (and turning even more while skidding).
|
||||
float steering = m_kart->getSteerPercent() * (1.0f + (m_kart->getSkidding() - 1.0f)/2.3f ); // dampen skidding effect
|
||||
float dampened_steer = fabsf(steering) * steering; // quadratically to dampen small variations (but keep sign)
|
||||
float angle_around = m_kart->getHPR().getX() + m_rotation_range * dampened_steer * 0.5f;
|
||||
float angle_up = m_kart->getHPR().getY() - 30.0f*DEGREE_TO_RAD;
|
||||
wanted_position->setX( sin(angle_around));
|
||||
wanted_position->setY(-cos(angle_around));
|
||||
wanted_position->setZ(-sin(angle_up) );
|
||||
// The skidding effect is dampened.
|
||||
float steering = m_kart->getSteerPercent()
|
||||
* (1.0f + (m_kart->getSkidding() - 1.0f)/2.3f );
|
||||
// quadratically to dampen small variations (but keep sign)
|
||||
float dampened_steer = fabsf(steering) * steering;
|
||||
float angle_around = m_kart->getHeading()
|
||||
+ 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 += *wanted_target;
|
||||
} // computeNormalCameraPosition
|
||||
@ -247,7 +257,6 @@ void Camera::update(float dt)
|
||||
{
|
||||
Vec3 wanted_position;
|
||||
Vec3 wanted_target = m_kart->getXYZ();
|
||||
|
||||
// Each case should set wanted_position and wanted_target according to
|
||||
// what is needed for that mode. Yes, there is a lot of duplicate code
|
||||
// but it is (IMHO) much easier to follow this way.
|
||||
@ -261,12 +270,14 @@ void Camera::update(float dt)
|
||||
}
|
||||
case CM_REVERSE: // Same as CM_NORMAL except it looks backwards
|
||||
{
|
||||
wanted_target.setZ(wanted_target.getZ()+ 0.75f);
|
||||
float angle_around = m_kart->getHPR().getX() - m_rotation_range * m_kart->getSteerPercent() * m_kart->getSkidding();
|
||||
float angle_up = m_kart->getHPR().getY() + 30.0f*DEGREE_TO_RAD;
|
||||
wanted_position.setX(-sin(angle_around));
|
||||
wanted_position.setY( cos(angle_around));
|
||||
wanted_position.setZ( sin(angle_up) );
|
||||
wanted_target.setY(wanted_target.getY()+ 0.75f);
|
||||
float angle_around = m_kart->getHeading()
|
||||
+ m_rotation_range * m_kart->getSteerPercent()
|
||||
* m_kart->getSkidding();
|
||||
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 * 2.0f;
|
||||
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
|
||||
{
|
||||
wanted_target.setZ(wanted_target.getZ()+0.75f);
|
||||
float angle_around = m_kart->getHPR().getX() + m_rotation_range * m_kart->getSteerPercent() * m_kart->getSkidding();
|
||||
float angle_up = m_kart->getHPR().getY() - 20.0f*DEGREE_TO_RAD;
|
||||
wanted_target.setY(wanted_target.getY()+0.75f);
|
||||
float angle_around = m_kart->getHeading()
|
||||
+ 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.setY(-cos(angle_around));
|
||||
wanted_position.setZ(-sin(angle_up) );
|
||||
wanted_position.setY(-sin(angle_up) );
|
||||
wanted_position.setZ(-cos(angle_around));
|
||||
wanted_position *= m_distance * 0.5f;
|
||||
wanted_position += wanted_target;
|
||||
smoothMoveCamera(dt, wanted_position, wanted_target);
|
||||
@ -294,11 +308,11 @@ void Camera::update(float dt)
|
||||
wanted_target = kart->getXYZ().toIrrVector();
|
||||
// Follows the leader kart, higher off of the ground, further from the kart,
|
||||
// and turns in the opposite direction from the kart for a nice effect. :)
|
||||
float angle_around = kart->getHPR().getX();
|
||||
float angle_up = kart->getHPR().getY() + 40.0f*DEGREE_TO_RAD;
|
||||
float angle_around = kart->getHeading();
|
||||
float angle_up = kart->getPitch() + 40.0f*DEGREE_TO_RAD;
|
||||
wanted_position.setX(sin(angle_around));
|
||||
wanted_position.setY(cos(angle_around));
|
||||
wanted_position.setZ(sin(angle_up) );
|
||||
wanted_position.setY(sin(angle_up) );
|
||||
wanted_position.setZ(cos(angle_around));
|
||||
wanted_position *= m_distance * 2.0f;
|
||||
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++)
|
||||
{
|
||||
video::ITexture* t=irr_material.getTexture(j);
|
||||
if (!t) material_manager->setAllFlatMaterialFlags(mb);
|
||||
else material_manager->setAllMaterialFlags(t, mb);
|
||||
//if (!t) material_manager->setAllFlatMaterialFlags(mb);
|
||||
//else material_manager->setAllMaterialFlags(t, mb);
|
||||
if(t) material_manager->setAllMaterialFlags(t, mb);
|
||||
|
||||
} // for j<MATERIAL_MAX_TEXTURES
|
||||
material_manager->setAllUntexturedMaterialFlags(mb);
|
||||
@ -766,7 +767,7 @@ void IrrDriver::update(float dt)
|
||||
const bool inRace = world!=NULL;
|
||||
// With bullet debug view we have to clear the back buffer, but
|
||||
// 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,
|
||||
true, video::SColor(255,100,101,140));
|
||||
|
||||
@ -795,9 +796,11 @@ void IrrDriver::update(float dt)
|
||||
m_scene_manager->drawAll();
|
||||
// Note that drawAll must be called before rendering
|
||||
// the bullet debug view, since otherwise the camera
|
||||
// is not set up properly.
|
||||
if (UserConfigParams::m_bullet_debug)
|
||||
World::getWorld()->getPhysics()->draw();
|
||||
// is not set up properly. This is only used for
|
||||
// the bullet debug view.
|
||||
#ifdef DEBUG
|
||||
World::getWorld()->getPhysics()->draw();
|
||||
#endif
|
||||
} // if kart->Camera
|
||||
} // for i<world->getNumKarts()
|
||||
// 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) {
|
||||
int indx=mbIndices[j];
|
||||
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);
|
||||
max->max(c);
|
||||
} // 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->setParent(m_kart->getNode());
|
||||
m_node->setPosition(core::vector3df(0,
|
||||
// 0*0.25f,
|
||||
0*0.25f+2.5,
|
||||
m_kart->getKartLength()) );
|
||||
setTextureMatrix(&(m_node->getMaterial(0).getTextureMatrix(0)));
|
||||
|
@ -105,7 +105,6 @@ void InputManager::handleStaticAction(int key, int value)
|
||||
{
|
||||
Kart* kart = world->getLocalPlayerKart(0);
|
||||
kart->setPowerup(POWERUP_BUBBLEGUM, 10000);
|
||||
projectile_manager->newExplosion(Vec3(0, 8, 0.5));
|
||||
}
|
||||
break;
|
||||
case KEY_F2:
|
||||
@ -129,16 +128,6 @@ void InputManager::handleStaticAction(int key, int value)
|
||||
kart->setPowerup(POWERUP_SWITCH, 10000);
|
||||
}
|
||||
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:
|
||||
if (race_manager->getNumPlayers() ==1 )
|
||||
{
|
||||
@ -159,6 +148,12 @@ void InputManager::handleStaticAction(int key, int value)
|
||||
Kart* kart = world->getLocalPlayerKart(0);
|
||||
kart->setPowerup(POWERUP_ZIPPER, 10000);
|
||||
}
|
||||
case KEY_F11:
|
||||
if(value && control_is_pressed)
|
||||
{
|
||||
world->getPhysics()->nextDebugMode();
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case KEY_F12:
|
||||
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;
|
||||
}
|
||||
|
||||
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()),
|
||||
-70.0f /*gravity*/,
|
||||
true /*rotates*/);
|
||||
// Even if the ball is fired backwards, m_speed must be positive,
|
||||
// otherwise the ball can start to vibrate when energy is added.
|
||||
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.
|
||||
setAdjustZVelocity(false);
|
||||
setAdjustUpVelocity(false);
|
||||
|
||||
// unset no_contact_response flags, so that the ball
|
||||
// will bounce off the track
|
||||
@ -92,7 +92,7 @@ void Bowling::update(float dt)
|
||||
{
|
||||
Flyable::update(dt);
|
||||
const Kart *kart=0;
|
||||
btVector3 direction;
|
||||
Vec3 direction;
|
||||
float minDistance;
|
||||
getClosestKart(&kart, &minDistance, &direction);
|
||||
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
|
||||
// the ball to fly higher and higher.
|
||||
btTransform trans = getTrans();
|
||||
float hat = trans.getOrigin().getZ();
|
||||
float hat = trans.getOrigin().getY();
|
||||
btVector3 v = m_body->getLinearVelocity();
|
||||
float vlen = v.length2();
|
||||
if (hat<= m_max_height)
|
||||
@ -120,7 +120,7 @@ void Bowling::update(float dt)
|
||||
if(vlen<0.8*m_speed*m_speed)
|
||||
{ // bowling lost energy (less than 80%), i.e. it's too slow - speed it up:
|
||||
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));
|
||||
} // 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.
|
||||
// (if bullet is compiled with _DEBUG, a warning will be printed the first
|
||||
// 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;
|
||||
|
||||
// give a speed proportional to kart speed
|
||||
m_speed = kart->getSpeed() * m_speed / 23.0f;
|
||||
if (kart->getSpeed() < 0)
|
||||
m_speed /= 3.6f; //when going backwards, decrease speed of cake by less
|
||||
// give a speed proportional to kart speed. m_speed is defined in flyable
|
||||
m_speed *= kart->getSpeed() / 23.0f;
|
||||
|
||||
//when going backwards, decrease speed of cake by less
|
||||
if (kart->getSpeed() < 0) m_speed /= 3.6f;
|
||||
|
||||
m_speed += 16.0f;
|
||||
|
||||
if (m_speed < 1.0f)
|
||||
m_speed = 1.0f;
|
||||
if (m_speed < 1.0f) m_speed = 1.0f;
|
||||
|
||||
btTransform trans = kart->getTrans();
|
||||
|
||||
btMatrix3x3 thisKartDirMatrix = kart->getKartHeading().getBasis();
|
||||
btVector3 thisKartDirVector(thisKartDirMatrix[0][1],
|
||||
thisKartDirMatrix[1][1],
|
||||
thisKartDirMatrix[2][1]);
|
||||
float heading=atan2f(-thisKartDirVector.getX(), thisKartDirVector.getY());
|
||||
float heading=kart->getHeading();
|
||||
float pitch = kart->getTerrainPitch(heading);
|
||||
|
||||
// find closest kart in front of the current one
|
||||
const Kart *closest_kart=0; btVector3 direction; float kartDistSquared;
|
||||
getClosestKart(&closest_kart, &kartDistSquared, &direction, kart /* search in front of this kart */);
|
||||
// Find closest kart in front of the current one
|
||||
const Kart *closest_kart=0;
|
||||
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
|
||||
// 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'
|
||||
// vehicle if they were to continue travelling in the same direction and same speed
|
||||
// (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;
|
||||
|
||||
float fire_angle = 0.0f;
|
||||
float time_estimated = 0.0f;
|
||||
|
||||
getLinearKartItemIntersection (kart->getTrans().getOrigin(), closest_kart,
|
||||
m_speed, m_gravity, y_offset,
|
||||
&fire_angle, &up_velocity, &time_estimated);
|
||||
getLinearKartItemIntersection (kart->getXYZ(), closest_kart,
|
||||
m_speed, m_gravity, forward_offset,
|
||||
&fire_angle, &up_velocity);
|
||||
|
||||
// apply transformation to the bullet object (without pitch)
|
||||
btMatrix3x3 m;
|
||||
m.setEulerZYX(0.0f, 0.0f, fire_angle /*+thisKartAngle*/);
|
||||
trans.setBasis(m);
|
||||
trans.setRotation(btQuaternion(btVector3(0,1,0), fire_angle));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -99,14 +95,14 @@ Cake::Cake (Kart *kart) : Flyable(kart, POWERUP_CAKE)
|
||||
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,
|
||||
true /* rotation */, false /* backwards */, &trans);
|
||||
|
||||
//do not adjust height according to terrain
|
||||
setAdjustZVelocity(false);
|
||||
setAdjustUpVelocity(false);
|
||||
|
||||
m_body->setActivationState(DISABLE_DEACTIVATION);
|
||||
|
||||
@ -122,12 +118,11 @@ Cake::Cake (Kart *kart) : Flyable(kart, POWERUP_CAKE)
|
||||
void Cake::init(const XMLNode &node, scene::IMesh *cake_model)
|
||||
{
|
||||
Flyable::init(node, cake_model, POWERUP_CAKE);
|
||||
m_st_max_distance = 80.0f;
|
||||
m_st_max_distance = 80.0f;
|
||||
m_st_max_distance_squared = 80.0f * 80.0f;
|
||||
m_gravity = 9.8f;
|
||||
m_gravity = 9.8f;
|
||||
|
||||
if (m_gravity < 0)
|
||||
m_gravity *= -1;
|
||||
if (m_gravity < 0) m_gravity *= -1.0f;
|
||||
|
||||
node.get("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 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,
|
||||
m_speed, m_gravity, 0,
|
||||
|
@ -41,28 +41,25 @@ scene::IMesh* Flyable::m_st_model[POWERUP_MAX];
|
||||
float Flyable::m_st_min_height[POWERUP_MAX];
|
||||
float Flyable::m_st_max_height[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()
|
||||
{
|
||||
// get the appropriate data from the static fields
|
||||
m_speed = m_st_speed[type];
|
||||
m_extend = m_st_extend[type];
|
||||
m_max_height = m_st_max_height[type];
|
||||
m_min_height = m_st_min_height[type];
|
||||
m_average_height = (m_min_height+m_max_height)/2.0f;
|
||||
m_force_updown = m_st_force_updown[type];
|
||||
|
||||
m_owner = kart;
|
||||
m_type = type;
|
||||
m_has_hit_something = false;
|
||||
m_exploded = false;
|
||||
m_shape = NULL;
|
||||
m_mass = mass;
|
||||
m_adjust_z_velocity = true;
|
||||
|
||||
m_time_since_thrown = 0;
|
||||
m_speed = m_st_speed[type];
|
||||
m_extend = m_st_extend[type];
|
||||
m_max_height = m_st_max_height[type];
|
||||
m_min_height = m_st_min_height[type];
|
||||
m_average_height = (m_min_height+m_max_height)/2.0f;
|
||||
m_force_updown = m_st_force_updown[type];
|
||||
m_owner = kart;
|
||||
m_has_hit_something = false;
|
||||
m_exploded = false;
|
||||
m_shape = NULL;
|
||||
m_mass = mass;
|
||||
m_adjust_up_velocity = true;
|
||||
m_time_since_thrown = 0;
|
||||
m_owner_has_temporary_immunity = true;
|
||||
m_max_lifespan = -1;
|
||||
|
||||
@ -71,19 +68,32 @@ Flyable::Flyable(Kart *kart, PowerupType type, float mass) : Moveable()
|
||||
} // 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,
|
||||
const bool rotates, const bool turn_around,
|
||||
const btTransform* customDirection)
|
||||
const btTransform* custom_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
|
||||
btTransform offset_transform;
|
||||
offset_transform.setIdentity();
|
||||
btVector3 offset=btVector3(0,y_offset,m_average_height);
|
||||
offset_transform.setOrigin(offset);
|
||||
offset_transform.setOrigin(Vec3(0,m_average_height,forw_offset));
|
||||
|
||||
// turn around
|
||||
if(turn_around)
|
||||
@ -91,7 +101,7 @@ void Flyable::createPhysics(float y_offset, const btVector3 &velocity,
|
||||
btTransform turn_around_trans;
|
||||
//turn_around_trans.setOrigin(trans.getOrigin());
|
||||
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;
|
||||
}
|
||||
|
||||
@ -102,7 +112,7 @@ void Flyable::createPhysics(float y_offset, const btVector3 &velocity,
|
||||
m_user_pointer.set(this);
|
||||
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
|
||||
btVector3 v=trans.getBasis()*velocity;
|
||||
@ -143,10 +153,18 @@ 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,
|
||||
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;
|
||||
*minKart = NULL;
|
||||
@ -158,24 +176,23 @@ void Flyable::getClosestKart(const Kart **minKart, float *minDistSquared,
|
||||
if(kart->isEliminated() || kart == m_owner || kart->isRescue() ) continue;
|
||||
btTransform t=kart->getTrans();
|
||||
|
||||
btVector3 delta = t.getOrigin()-tProjectile.getOrigin();
|
||||
Vec3 delta = t.getOrigin()-tProjectile.getOrigin();
|
||||
float distance2 = delta.length2();
|
||||
|
||||
if(inFrontOf != NULL)
|
||||
{
|
||||
// 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();
|
||||
if(distance > 50) continue; // kart too far, don't aim at it
|
||||
|
||||
btTransform trans = inFrontOf->getTrans();
|
||||
// get heading=trans.getBasis*(0,1,0) ... so save the multiplication:
|
||||
btVector3 direction(trans.getBasis()[0][1],
|
||||
trans.getBasis()[1][1],
|
||||
trans.getBasis()[2][1]);
|
||||
// get heading=trans.getBasis*(0,0,1) ... so save the multiplication:
|
||||
Vec3 direction(trans.getBasis().getColumn(2));
|
||||
// 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
|
||||
// an assertion failure. So we remove the whole acos() test here:
|
||||
// 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 and copy the
|
||||
// code from to_target.angle(...)
|
||||
Vec3 v = backwards ? -direction : direction;
|
||||
float s = sqrt(v.length2() * to_target.length2());
|
||||
float c = to_target.dot(v)/s;
|
||||
@ -195,42 +212,52 @@ void Flyable::getClosestKart(const Kart **minKart, float *minDistSquared,
|
||||
} // getClosestKart
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void Flyable::getLinearKartItemIntersection (const btVector3 origin, const Kart *target_kart,
|
||||
float item_XY_speed, float gravity, float y_offset,
|
||||
float *fire_angle, float *up_velocity, float *time_estimated)
|
||||
/** Returns information on the parameters needed to hit a target kart moving
|
||||
* at constant velocity and direction for a given speed in the XZ-plane.
|
||||
* \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();
|
||||
Vec3 target_direction(trans.getBasis()[0][1],
|
||||
trans.getBasis()[1][1],
|
||||
trans.getBasis()[2][1]);
|
||||
Vec3 target_direction(trans.getBasis().getColumn(2));
|
||||
|
||||
float dx = relative_target_kart_loc.getX();
|
||||
float dy = relative_target_kart_loc.getY();
|
||||
float dz = relative_target_kart_loc.getZ();
|
||||
|
||||
float gx = target_direction.getX();
|
||||
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);
|
||||
fire_th = (((dist - dx*fire_th) / dy < 0) ? -acosf(fire_th): acosf(fire_th));
|
||||
float fire_th = (dx*dist - dz * sqrtf(dx*dx + dz*dz - dist*dist)) / (dx*dx + dz*dz);
|
||||
fire_th = (((dist - dx*fire_th) / dz > 0) ? -acosf(fire_th): acosf(fire_th));
|
||||
|
||||
float time = 0.0f;
|
||||
float a = item_XY_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 a = item_XZ_speed * sinf (fire_th) + target_kart_speed * sinf (target_kart_heading);
|
||||
float b = item_XZ_speed * cosf (fire_th) + target_kart_speed * cosf (target_kart_heading);
|
||||
|
||||
if (fabsf(a) > fabsf(b))
|
||||
time = fabsf (dx / a);
|
||||
else if (b != 0.0f)
|
||||
time = fabsf(dy / b);
|
||||
if (fabsf(a) > fabsf(b)) time = fabsf (dx / a);
|
||||
else if (b != 0.0f) time = fabsf(dz / b);
|
||||
|
||||
if (fire_th > M_PI)
|
||||
fire_th -= M_PI;
|
||||
@ -238,12 +265,11 @@ void Flyable::getLinearKartItemIntersection (const btVector3 origin, const Kart
|
||||
fire_th += M_PI;
|
||||
|
||||
//createPhysics offset
|
||||
time -= y_offset / sqrt(a*a+b*b);
|
||||
time -= forw_offset / sqrt(a*a+b*b);
|
||||
|
||||
*fire_angle = fire_th;
|
||||
*up_velocity = (0.5f * time * gravity) + (dz / time) + (gz * target_kart->getSpeed());
|
||||
*time_estimated = time;
|
||||
}
|
||||
*up_velocity = (0.5f * time * gravity) + (dy / time) + (gy * target_kart->getSpeed());
|
||||
} // getLinearKartItemIntersection
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void Flyable::update(float dt)
|
||||
@ -260,15 +286,15 @@ void Flyable::update(float dt)
|
||||
const Vec3 *min, *max;
|
||||
World::getWorld()->getTrack()->getAABB(&min, &max);
|
||||
Vec3 xyz = getXYZ();
|
||||
if(xyz[0]<(*min)[0] || xyz[1]<(*min)[1] || xyz[2]<(*min)[2] ||
|
||||
xyz[0]>(*max)[0] || xyz[1]>(*max)[1] )
|
||||
if(xyz[0]<(*min)[0] || xyz[2]<(*min)[2] || xyz[1]<(*min)[1] ||
|
||||
xyz[0]>(*max)[0] || xyz[2]>(*max)[2] )
|
||||
{
|
||||
hit(NULL); // flyable out of track boundary
|
||||
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.
|
||||
// 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);
|
||||
Vec3 v = getVelocity();
|
||||
float heading = atan2f(-v.getX(), v.getY());
|
||||
float pitch = getTerrainPitch (heading);
|
||||
float vel_z = m_force_updown*(delta);
|
||||
float heading = atan2f(v.getX(), v.getZ());
|
||||
float pitch = getTerrainPitch(heading);
|
||||
float vel_up = m_force_updown*(delta);
|
||||
if (hat < m_max_height) // take into account pitch of surface
|
||||
vel_z += v.length_2d()*tanf(pitch);
|
||||
v.setZ(vel_z);
|
||||
vel_up += v.length_2d()*tanf(pitch);
|
||||
v.setY(vel_up);
|
||||
setVelocity(v);
|
||||
} // if m_adjust_z_velocity
|
||||
} // if m_adjust_up_velocity
|
||||
|
||||
Moveable::update(dt);
|
||||
} // update
|
||||
|
@ -45,10 +45,10 @@ private:
|
||||
* It can happen that more than one collision between a rocket and
|
||||
* a track or kart is reported by the physics. */
|
||||
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
|
||||
* terrain. Otherwise gravity will not work correctly on this object. */
|
||||
bool m_adjust_z_velocity;
|
||||
bool m_adjust_up_velocity;
|
||||
|
||||
protected:
|
||||
Kart* m_owner; // the kart which released this flyable
|
||||
@ -60,7 +60,7 @@ protected:
|
||||
float m_force_updown;
|
||||
float m_speed;
|
||||
float m_mass;
|
||||
btVector3 m_extend;
|
||||
Vec3 m_extend;
|
||||
// The flyable class stores the values for each flyable type, e.g.
|
||||
// speed, min_height, max_height. These variables must be static,
|
||||
// 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_max_height[POWERUP_MAX]; // max height above track
|
||||
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,
|
||||
and also to put some time limit to some collectibles */
|
||||
@ -83,28 +83,20 @@ protected:
|
||||
for a short time */
|
||||
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,
|
||||
btVector3 *minDelta, const Kart* inFrontOf=NULL,
|
||||
Vec3 *minDelta, const Kart* inFrontOf=NULL,
|
||||
const bool backwards=false) const;
|
||||
|
||||
/** Returns information on the parameters needed to hit a target kart
|
||||
moving at constant velocity and direction for a given speed in the
|
||||
XY-plane.
|
||||
*/
|
||||
void getLinearKartItemIntersection(const btVector3 origin, const Kart *target_kart,
|
||||
float item_XY_velocity, float gravity, float y_offset,
|
||||
float *fire_angle, float *up_velocity, float *time);
|
||||
void getLinearKartItemIntersection(const Vec3 &origin,
|
||||
const Kart *target_kart,
|
||||
float item_XY_velocity, float gravity,
|
||||
float forw_offset,
|
||||
float *fire_angle, float *up_velocity);
|
||||
|
||||
|
||||
/** init bullet for moving objects like projectiles */
|
||||
void createPhysics(float y_offset,
|
||||
const btVector3 &velocity,
|
||||
const Vec3 &velocity,
|
||||
btCollisionShape *shape, const float gravity=0.0f,
|
||||
const bool rotates=false, const bool turn_around=false,
|
||||
const btTransform* customDirection=NULL);
|
||||
@ -115,7 +107,7 @@ public:
|
||||
/** Enables/disables adjusting ov velocity depending on height above
|
||||
* terrain. Missiles can 'follow the terrain' with this adjustment,
|
||||
* 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,
|
||||
PowerupType type);
|
||||
virtual void update (float);
|
||||
|
@ -31,13 +31,10 @@ Item::Item(ItemType type, const Vec3& xyz, const Vec3& normal,
|
||||
{
|
||||
setType(type);
|
||||
m_event_handler = NULL;
|
||||
m_xyz = xyz;
|
||||
m_deactive_time = 0;
|
||||
m_normal = normal;
|
||||
// Sets heading to 0, and sets pitch and roll depending on the 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_original_type = ITEM_NONE;
|
||||
m_collected = false;
|
||||
@ -148,8 +145,6 @@ void Item::update(float dt)
|
||||
// Make it visible by scaling it from 0 to 1:
|
||||
m_node->setVisible(true);
|
||||
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
|
||||
} // if collected
|
||||
else
|
||||
@ -157,59 +152,13 @@ void Item::update(float dt)
|
||||
|
||||
if(!m_rotate) return;
|
||||
// have it rotate
|
||||
Vec3 rotation(dt*M_PI, 0, 0);
|
||||
m_coord.setHPR(m_coord.getHPR()+rotation);
|
||||
m_node->setRotation(m_coord.getHPR().toIrrHPR());
|
||||
m_node->setPosition(m_coord.getXYZ().toIrrVector());
|
||||
Vec3 rotation(0, dt*M_PI, 0);
|
||||
core::vector3df r = m_node->getRotation();
|
||||
r.Y += dt*180.0f;
|
||||
if(r.Y>360.0f) r.Y -= 360.0f;
|
||||
m_node->setRotation(r);
|
||||
return;
|
||||
|
||||
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
|
||||
}
|
||||
} // not m_collected
|
||||
} // update
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -60,18 +60,15 @@ private:
|
||||
/** Time till a collected item reappears. */
|
||||
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::IMeshSceneNode *m_node;
|
||||
|
||||
/** Stores the original mesh in order to reset it. */
|
||||
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. */
|
||||
unsigned int m_item_id;
|
||||
@ -79,11 +76,12 @@ private:
|
||||
/** Set to false if item should not rotate. */
|
||||
bool m_rotate;
|
||||
|
||||
/** optionally, set this if this item was laid by a particular kart. in this case,
|
||||
the 'm_deactive_time' will also be set - see below. */
|
||||
/** Optionally set this if this item was laid by a particular kart. in
|
||||
* this case the 'm_deactive_time' will also be set - see below. */
|
||||
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;
|
||||
|
||||
void setType(ItemType type);
|
||||
@ -102,7 +100,7 @@ public:
|
||||
bool hitKart (Kart* kart ) const
|
||||
{
|
||||
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
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
@ -46,48 +46,46 @@ Plunger::Plunger(Kart *kart) : Flyable(kart, POWERUP_PLUNGER)
|
||||
m_reverse_mode = kart->getControls().m_look_back;
|
||||
|
||||
// find closest kart in front of the current one
|
||||
const Kart *closest_kart=0; btVector3 direction; float kartDistSquared;
|
||||
getClosestKart(&closest_kart, &kartDistSquared, &direction, kart /* search in front of this kart */, m_reverse_mode);
|
||||
const Kart *closest_kart=0;
|
||||
Vec3 direction;
|
||||
float kartDistSquared;
|
||||
getClosestKart(&closest_kart, &kartDistSquared, &direction,
|
||||
kart /* search in front of this kart */, m_reverse_mode);
|
||||
|
||||
btTransform trans = kart->getTrans();
|
||||
|
||||
btMatrix3x3 thisKartDirMatrix = kart->getKartHeading().getBasis();
|
||||
btVector3 thisKartDirVector(thisKartDirMatrix[0][1],
|
||||
thisKartDirMatrix[1][1],
|
||||
thisKartDirMatrix[2][1]);
|
||||
btVector3 thisKartDirVector(thisKartDirMatrix.getColumn(2));
|
||||
|
||||
float heading=atan2f(-thisKartDirVector.getX(), thisKartDirVector.getY());
|
||||
float heading=kart->getHeading();
|
||||
float pitch = kart->getTerrainPitch(heading);
|
||||
|
||||
// aim at this kart if it's not too far
|
||||
if(closest_kart != NULL && kartDistSquared < 30*30)
|
||||
{
|
||||
float fire_angle = 0.0f;
|
||||
float time_estimated = 0.0f;
|
||||
getLinearKartItemIntersection (kart->getTrans().getOrigin(), closest_kart,
|
||||
getLinearKartItemIntersection (kart->getXYZ(), closest_kart,
|
||||
plunger_speed, gravity, y_offset,
|
||||
&fire_angle, &up_velocity, &time_estimated);
|
||||
&fire_angle, &up_velocity);
|
||||
|
||||
// apply transformation to the bullet object (without pitch)
|
||||
btMatrix3x3 m;
|
||||
m.setEulerZYX(0.0f, 0.0f, fire_angle);
|
||||
trans.setBasis(m);
|
||||
trans.setRotation(btQuaternion(btVector3(0, 1, 0), fire_angle));
|
||||
|
||||
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,
|
||||
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
|
||||
{
|
||||
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 );
|
||||
}
|
||||
|
||||
//adjust height according to terrain
|
||||
setAdjustZVelocity(true);
|
||||
setAdjustUpVelocity(true);
|
||||
|
||||
// pulling back makes no sense in battle mode, since this mode is not a race.
|
||||
// so in battle mode, always hide view
|
||||
@ -166,11 +164,10 @@ void Plunger::hit(Kart *kart, PhysicalObject *obj)
|
||||
}
|
||||
|
||||
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
|
||||
// because the ref count reaches zero.
|
||||
Vec3 hell(0, 0, -10000);
|
||||
getNode()->setPosition(hell.toIrrVector());
|
||||
getNode()->setVisible(false);
|
||||
World::getWorld()->getPhysics()->removeBody(getBody());
|
||||
}
|
||||
else
|
||||
@ -183,8 +180,7 @@ void Plunger::hit(Kart *kart, PhysicalObject *obj)
|
||||
scene::ISceneNode *node = getNode();
|
||||
if(node)
|
||||
{
|
||||
Vec3 hell(0, 0, -10000);
|
||||
getNode()->setPosition(hell.toIrrVector());
|
||||
node->setVisible(false);
|
||||
}
|
||||
World::getWorld()->getPhysics()->removeBody(getBody());
|
||||
|
||||
|
@ -91,10 +91,10 @@ void RubberBand::updatePosition()
|
||||
const float hh=.1f; // half height of the band
|
||||
const Vec3 &p=m_end_position; // for shorter typing
|
||||
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[1].Pos.X = p.getX()+hh; v[1].Pos.Z=p.getY(); v[1].Pos.Y = p.getZ()+hh;
|
||||
v[2].Pos.X = k.getX()+hh; v[2].Pos.Z=k.getY(); v[2].Pos.Y = k.getZ()+hh;
|
||||
v[3].Pos.X = k.getX()-hh; v[3].Pos.Z=k.getY(); v[3].Pos.Y = k.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.Y=p.getY(); v[1].Pos.Z = p.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.Y=k.getY(); v[3].Pos.Z = k.getZ()-hh;
|
||||
m_buffer->recalculateBoundingBox();
|
||||
m_mesh->setBoundingBox(m_buffer->getBoundingBox());
|
||||
} // 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
|
||||
//kart is on top of the road, and if we won't slow down below a certain
|
||||
//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()) )
|
||||
{
|
||||
float kart_ang_diff =
|
||||
m_quad_graph->getAngleToNext(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 = fabsf(kart_ang_diff);
|
||||
|
||||
@ -341,7 +341,7 @@ void DefaultAIController::handleBraking()
|
||||
//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
|
||||
//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 )
|
||||
{
|
||||
#ifdef AI_DEBUG
|
||||
@ -778,7 +778,7 @@ float DefaultAIController::steerToAngle(const size_t SECTOR, const float ANGLE)
|
||||
m_successor_index[SECTOR]);
|
||||
|
||||
//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())
|
||||
steer_angle += ANGLE/5;
|
||||
@ -802,15 +802,15 @@ float DefaultAIController::steerToPoint(const Vec3 &point, float dt)
|
||||
// No sense steering if we are not driving.
|
||||
if(m_kart->getSpeed()==0) return 0.0f;
|
||||
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. */
|
||||
float theta = -atan2(dx, dy);
|
||||
float theta = atan2(dx, dz);
|
||||
|
||||
// Angle is the point is relative to the heading - but take the current
|
||||
// angular velocity into account, too. The value is multiplied by two
|
||||
// to avoid 'oversteering' - experimentally found.
|
||||
float angle_2_point = theta - m_kart->getHPR().getHeading()
|
||||
- dt*m_kart->getBody()->getAngularVelocity().getZ()*2.0f;
|
||||
float angle_2_point = theta - m_kart->getHeading()
|
||||
- dt*m_kart->getBody()->getAngularVelocity().getY()*2.0f;
|
||||
angle_2_point = normalizeAngle(angle_2_point);
|
||||
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;
|
||||
#ifdef DEBUG_OUTPUT
|
||||
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);
|
||||
#endif
|
||||
// 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
|
||||
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();
|
||||
// If the velocity is zero, no sense in checking for crashes in time
|
||||
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
|
||||
const Kart *other_kart = m_world->getKart(j);
|
||||
// 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;
|
||||
Vec3 other_kart_xyz = other_kart->getXYZ() + other_kart->getVelocity()*(i*dt);
|
||||
float kart_distance = (step_coord - other_kart_xyz).length_2d();
|
||||
@ -1012,7 +1012,7 @@ inline float DefaultAIController::normalizeAngle(float angle)
|
||||
*/
|
||||
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;
|
||||
|
||||
//Increase the steps depending on the width, if we steering hard,
|
||||
@ -1086,7 +1086,7 @@ void DefaultAIController::findCurve()
|
||||
{
|
||||
float total_dist = 0.0f;
|
||||
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])
|
||||
{
|
||||
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]);
|
||||
|
||||
//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())
|
||||
steer_angle += ANGLE/5;
|
||||
@ -325,15 +325,15 @@ float EndController::steerToPoint(const Vec3 &point, float dt)
|
||||
// No sense steering if we are not driving.
|
||||
if(m_kart->getSpeed()==0) return 0.0f;
|
||||
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. */
|
||||
float theta = -atan2(dx, dy);
|
||||
float theta = atan2(dx, dz);
|
||||
|
||||
// Angle is the point is relative to the heading - but take the current
|
||||
// angular velocity into account, too. The value is multiplied by two
|
||||
// to avoid 'oversteering' - experimentally found.
|
||||
float angle_2_point = theta - m_kart->getHPR().getHeading()
|
||||
- dt*m_kart->getBody()->getAngularVelocity().getZ()*2.0f;
|
||||
float angle_2_point = theta - m_kart->getHeading()
|
||||
- dt*m_kart->getBody()->getAngularVelocity().getY()*2.0f;
|
||||
angle_2_point = normalizeAngle(angle_2_point);
|
||||
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;
|
||||
#ifdef DEBUG_OUTPUT
|
||||
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);
|
||||
#endif
|
||||
// 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 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;
|
||||
|
||||
//Increase the steps depending on the width, if we steering hard,
|
||||
@ -537,7 +537,7 @@ void EndController::findCurve()
|
||||
{
|
||||
float total_dist = 0.0f;
|
||||
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])
|
||||
{
|
||||
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
|
||||
//kart is on top of the road, and if we won't slow down below a certain
|
||||
//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()) )
|
||||
{
|
||||
float kart_ang_diff =
|
||||
m_quad_graph->getAngleToNext(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 = fabsf(kart_ang_diff);
|
||||
|
||||
@ -337,7 +337,7 @@ void NewAIController::handleBraking()
|
||||
//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
|
||||
//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 )
|
||||
{
|
||||
#ifdef AI_DEBUG
|
||||
@ -765,7 +765,7 @@ float NewAIController::steerToAngle(const size_t SECTOR, const float ANGLE)
|
||||
m_successor_index[SECTOR]);
|
||||
|
||||
//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())
|
||||
steer_angle += ANGLE/5;
|
||||
@ -789,15 +789,15 @@ float NewAIController::steerToPoint(const Vec3 &point, float dt)
|
||||
// No sense steering if we are not driving.
|
||||
if(m_kart->getSpeed()==0) return 0.0f;
|
||||
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. */
|
||||
float theta = -atan2(dx, dy);
|
||||
float theta = atan2(dx, dz);
|
||||
|
||||
// Angle is the point is relative to the heading - but take the current
|
||||
// angular velocity into account, too. The value is multiplied by two
|
||||
// to avoid 'oversteering' - experimentally found.
|
||||
float angle_2_point = theta - m_kart->getHPR().getHeading()
|
||||
- dt*m_kart->getBody()->getAngularVelocity().getZ()*2.0f;
|
||||
float angle_2_point = theta - m_kart->getHeading()
|
||||
- dt*m_kart->getBody()->getAngularVelocity().getY()*2.0f;
|
||||
angle_2_point = normalizeAngle(angle_2_point);
|
||||
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;
|
||||
#ifdef DEBUG_OUTPUT
|
||||
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);
|
||||
#endif
|
||||
// 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(),
|
||||
right.getY()-xyz.getY())
|
||||
- m_kart->getHPR().getHeading();
|
||||
- m_kart->getHeading();
|
||||
float very_left = -atan2(left.getX()-xyz.getX(),
|
||||
left.getY()-xyz.getY())
|
||||
- m_kart->getHPR().getHeading();
|
||||
- m_kart->getHeading();
|
||||
very_left = normalizeAngle(very_left);
|
||||
very_right = normalizeAngle(very_right);
|
||||
float dist = 0;
|
||||
@ -920,10 +920,10 @@ float NewAIController::findNonCrashingAngle()
|
||||
|
||||
float angle_right = -atan2(right.getX()-xyz.getX(),
|
||||
right.getY()-xyz.getY())
|
||||
- m_kart->getHPR().getHeading();
|
||||
- m_kart->getHeading();
|
||||
float angle_left = -atan2(left.getX()-xyz.getX(),
|
||||
left.getY()-xyz.getY())
|
||||
- m_kart->getHPR().getHeading();
|
||||
- m_kart->getHeading();
|
||||
angle_left = normalizeAngle(angle_left);
|
||||
angle_right = normalizeAngle(angle_right);
|
||||
|
||||
|
@ -118,17 +118,17 @@ void PlayerController::action(PlayerAction action, int value)
|
||||
switch (action)
|
||||
{
|
||||
case PA_LEFT:
|
||||
m_steer_val_l = -value;
|
||||
m_steer_val_l = value;
|
||||
if (value)
|
||||
m_steer_val = -value;
|
||||
m_steer_val = value;
|
||||
else
|
||||
m_steer_val = m_steer_val_r;
|
||||
|
||||
break;
|
||||
case PA_RIGHT:
|
||||
m_steer_val_r = value;
|
||||
m_steer_val_r = -value;
|
||||
if (value)
|
||||
m_steer_val = value;
|
||||
m_steer_val = -value;
|
||||
else
|
||||
m_steer_val = m_steer_val_l;
|
||||
|
||||
|
@ -80,7 +80,6 @@ Kart::Kart (const std::string& ident, int position,
|
||||
m_nitro = NULL;
|
||||
m_slip_stream = NULL;
|
||||
m_skidmarks = NULL;
|
||||
m_animated_node = NULL;
|
||||
m_camera = NULL;
|
||||
m_controller = NULL;
|
||||
m_saved_controller = NULL;
|
||||
@ -133,12 +132,12 @@ Kart::Kart (const std::string& ident, int position,
|
||||
}
|
||||
|
||||
loadData();
|
||||
float l = m_kart_properties->getSlipstreamLength();
|
||||
float length = m_kart_properties->getSlipstreamLength();
|
||||
|
||||
Vec3 p0(-getKartWidth()*0.5f, -getKartLength()*0.5f, 0);
|
||||
Vec3 p1(-getKartWidth()*0.5f, -getKartLength()*0.5f-l, 0);
|
||||
Vec3 p2( getKartWidth()*0.5f, -getKartLength()*0.5f-l, 0);
|
||||
Vec3 p3( getKartWidth()*0.5f, -getKartLength()*0.5f, 0);
|
||||
Vec3 p0(-getKartWidth()*0.5f, 0, -getKartLength()*0.5f );
|
||||
Vec3 p1(-getKartWidth()*0.5f, 0, -getKartLength()*0.5f-length);
|
||||
Vec3 p2( getKartWidth()*0.5f, 0, -getKartLength()*0.5f-length);
|
||||
Vec3 p3( getKartWidth()*0.5f, 0, -getKartLength()*0.5f );
|
||||
m_slipstream_original_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 trans = this->getTrans();
|
||||
btTransform trans = getTrans();
|
||||
|
||||
// get heading=trans.getBasis*(0,1,0) ... so save the multiplication:
|
||||
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);
|
||||
float pitch = (customPitch == -1 ? getTerrainPitch(getHeading()) : customPitch);
|
||||
|
||||
btMatrix3x3 m;
|
||||
m.setEulerZYX(pitch, 0.0f, heading);
|
||||
m.setEulerYPR(-getHeading(), pitch, 0.0f);
|
||||
trans.setBasis(m);
|
||||
|
||||
return trans;
|
||||
} // 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()
|
||||
{
|
||||
// First: Create the chassis of the kart
|
||||
@ -191,8 +186,8 @@ void Kart::createPhysics()
|
||||
float kart_height = km->getHeight();
|
||||
|
||||
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;
|
||||
shiftCenterOfGravity.setIdentity();
|
||||
// Shift center of gravity downwards, so that the kart
|
||||
@ -229,15 +224,15 @@ void Kart::createPhysics()
|
||||
|
||||
// never deactivate the vehicle
|
||||
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
|
||||
// ----------
|
||||
float wheel_radius = m_kart_properties->getWheelRadius();
|
||||
float suspension_rest = m_kart_properties->getSuspensionRest();
|
||||
|
||||
btVector3 wheel_direction(0.0f, 0.0f, -1.0f);
|
||||
btVector3 wheel_axle(1.0f,0.0f,0.0f);
|
||||
btVector3 wheel_direction(0.0f, -1.0f, 0.0f);
|
||||
btVector3 wheel_axle(-1.0f, 0.0f, 0.0f);
|
||||
|
||||
for(unsigned int i=0; i<4; i++)
|
||||
{
|
||||
@ -255,7 +250,7 @@ void Kart::createPhysics()
|
||||
// Obviously these allocs have to be properly managed/freed
|
||||
btTransform t;
|
||||
t.setIdentity();
|
||||
m_uprightConstraint=new btUprightConstraint(*m_body, t);
|
||||
m_uprightConstraint=new btUprightConstraint(this, t);
|
||||
m_uprightConstraint->setLimit(m_kart_properties->getUprightTolerance());
|
||||
m_uprightConstraint->setBounce(0.0f);
|
||||
m_uprightConstraint->setMaxLimitForce(m_kart_properties->getUprightMaxForce());
|
||||
@ -393,10 +388,6 @@ void Kart::reset()
|
||||
m_controller = m_saved_controller;
|
||||
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_view_blocked_by_plunger = 0.0;
|
||||
m_attachment.clear();
|
||||
@ -443,6 +434,12 @@ void Kart::reset()
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -681,7 +678,6 @@ void Kart::update(float dt)
|
||||
else
|
||||
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_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);
|
||||
|
||||
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);
|
||||
btQuaternion q_pitch(btVector3(1.f, 0.f, 0.f),
|
||||
-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);
|
||||
} // if rescue mode
|
||||
m_attachment.update(dt);
|
||||
@ -1063,7 +1059,7 @@ bool Kart::playCustomSFX(unsigned int type)
|
||||
*/
|
||||
}
|
||||
// -----------------------------------------------------------------------------
|
||||
void Kart::updatePhysics (float dt)
|
||||
void Kart::updatePhysics(float dt)
|
||||
{
|
||||
|
||||
m_bounce_back_time-=dt;
|
||||
@ -1136,30 +1132,25 @@ void Kart::updatePhysics (float dt)
|
||||
if(f<0.1f) f=0.1f;
|
||||
applyEngineForce(-engine_power*f);
|
||||
}
|
||||
else
|
||||
else // -m_speed >= max speed on this terrain
|
||||
{
|
||||
applyEngineForce(0.0f);
|
||||
}
|
||||
|
||||
}
|
||||
} // m_speed <00
|
||||
}
|
||||
else
|
||||
else // !m_brake
|
||||
{
|
||||
// lift the foot from throttle, brakes with 10% engine_power
|
||||
applyEngineForce(-m_controls.m_accel*engine_power*0.1f);
|
||||
|
||||
#if 1
|
||||
// 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
|
||||
if(abs(m_speed) < 5.0f) {
|
||||
for(int i=0; i<4; i++) m_vehicle->setBrake(20.0f, i);
|
||||
}
|
||||
#else
|
||||
if(!RaceManager::getWorld()->isStartPhase())
|
||||
resetBrakes();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
} // !m_brake
|
||||
} // not accelerating
|
||||
#ifdef ENABLE_JUMP
|
||||
if(m_controls.jump && isOnGround())
|
||||
{
|
||||
@ -1213,9 +1204,9 @@ void Kart::updatePhysics (float dt)
|
||||
// calculate direction of m_speed
|
||||
const btTransform& chassisTrans = getVehicle()->getChassisWorldTransform();
|
||||
btVector3 forwardW (
|
||||
chassisTrans.getBasis()[0][1],
|
||||
chassisTrans.getBasis()[1][1],
|
||||
chassisTrans.getBasis()[2][1]);
|
||||
chassisTrans.getBasis()[0][2],
|
||||
chassisTrans.getBasis()[1][2],
|
||||
chassisTrans.getBasis()[2][2]);
|
||||
|
||||
if (forwardW.dot(getVehicle()->getRigidBody()->getLinearVelocity()) < btScalar(0.))
|
||||
m_speed *= -1.f;
|
||||
@ -1228,7 +1219,7 @@ void Kart::updatePhysics (float dt)
|
||||
m_speed = max_speed;
|
||||
btVector3 velocity = m_body->getLinearVelocity();
|
||||
|
||||
velocity.setY( velocity.getY() * velocity_ratio );
|
||||
velocity.setZ( velocity.getZ() * velocity_ratio );
|
||||
velocity.setX( velocity.getX() * velocity_ratio );
|
||||
|
||||
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
|
||||
// bullet is using).
|
||||
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;
|
||||
// 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);
|
||||
}
|
||||
|
||||
@ -1313,7 +1304,7 @@ void Kart::endRescue()
|
||||
|
||||
void Kart::loadData()
|
||||
{
|
||||
m_kart_properties->getKartModel()->attachModel(&m_animated_node);
|
||||
m_kart_properties->getKartModel()->attachModel(&m_node);
|
||||
createPhysics();
|
||||
|
||||
// Attach Particle System
|
||||
@ -1326,9 +1317,9 @@ void Kart::loadData()
|
||||
m_skidmarks = new SkidMarks(*this);
|
||||
|
||||
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
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -1374,32 +1365,42 @@ void Kart::applyEngineForce(float force)
|
||||
} // 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();
|
||||
for(unsigned int i=0; i<4; i++)
|
||||
{
|
||||
// Set the suspension length
|
||||
wheel_z_axis[i] = m_default_suspension_length[i]
|
||||
- m_vehicle->getWheelInfo(i).m_raycastInfo.m_suspensionLength;
|
||||
wheel_up_axis[i] = m_default_suspension_length[i]
|
||||
- m_vehicle->getWheelInfo(i).m_raycastInfo.m_suspensionLength;
|
||||
}
|
||||
#define AUTO_SKID_VISUAL 1.7f
|
||||
const float auto_skid_visual=1.7f;
|
||||
float auto_skid;
|
||||
if (m_skidding>AUTO_SKID_VISUAL) // Above a limit, start counter rotating the wheels to get drifting look
|
||||
auto_skid = m_controls.m_steer*30.0f*((AUTO_SKID_VISUAL - m_skidding) / 0.8f); // divisor comes from max_skid - AUTO_SKID_VISUAL
|
||||
else
|
||||
// FIXME
|
||||
// if (m_skidding>auto_skid_visual) // Above a limit, start counter rotating the wheels to get drifting look
|
||||
// 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;
|
||||
kart_model->update(m_wheel_rotation, auto_skid,
|
||||
getSteerPercent(), wheel_z_axis);
|
||||
getSteerPercent(), wheel_up_axis);
|
||||
|
||||
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_vehicle->getWheelInfo(0).m_wheelsRadius
|
||||
- (kart_model->getWheelGraphicsRadius(0)
|
||||
-kart_model->getWheelGraphicsPosition(0).getZ() );
|
||||
center_shift.setZ(X);
|
||||
-kart_model->getWheelGraphicsPosition(0).getY() );
|
||||
center_shift.setY(y);
|
||||
|
||||
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 offset_heading = getSteerPercent()*m_kart_properties->getSkidVisual()
|
||||
* 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
|
||||
|
||||
/* EOF */
|
||||
|
@ -204,7 +204,8 @@ public:
|
||||
unsigned int getWorldKartId() const { return m_world_kart_id; }
|
||||
void setWorldKartId(unsigned int n) { m_world_kart_id=n; }
|
||||
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*
|
||||
getKartProperties() const { return m_kart_properties; }
|
||||
// ------------------------------------------------------------------------
|
||||
@ -272,7 +273,6 @@ public:
|
||||
/** Returns true if this kart has finished the race. */
|
||||
bool hasFinishedRace () const { return m_finished_race; }
|
||||
void endRescue ();
|
||||
void getClosestKart (float *cdist, int *closest);
|
||||
|
||||
bool hasViewBlockedByPlunger() const
|
||||
{ return m_view_blocked_by_plunger > 0; }
|
||||
|
@ -84,9 +84,10 @@ KartModel::~KartModel()
|
||||
/** Attach the kart model and wheels to the scene node.
|
||||
* \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->setLoopMode(false);
|
||||
for(unsigned int i=0; i<4; i++)
|
||||
@ -109,8 +110,8 @@ void KartModel::loadModels(const KartProperties &kart_properties)
|
||||
Vec3 size = max-min;
|
||||
m_z_offset = min.getZ();
|
||||
m_kart_width = size.getX();
|
||||
m_kart_height = size.getZ();
|
||||
m_kart_length = size.getY();
|
||||
m_kart_height = size.getY();
|
||||
m_kart_length = size.getZ();
|
||||
// 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
|
||||
// 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)
|
||||
? -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);
|
||||
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
|
||||
+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
|
||||
// (susp. length=0) will still poke a little bit out under the
|
||||
// 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
|
||||
}
|
||||
|
||||
@ -263,9 +264,8 @@ void KartModel::update(float rotation, float visual_steer,
|
||||
clamped_suspension[i] = ratio*suspension_length;
|
||||
} // for i<4
|
||||
|
||||
// core::vector3df wheel_rear (RAD_TO_DEGREE(-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;
|
||||
|
||||
for(unsigned int i=0; i<4; i++)
|
||||
|
@ -115,7 +115,7 @@ public:
|
||||
~KartModel();
|
||||
void loadInfo(const lisp::Lisp* lisp);
|
||||
void loadModels(const KartProperties &kart_properties);
|
||||
void attachModel(scene::IAnimatedMeshSceneNode **node);
|
||||
void attachModel(scene::ISceneNode **node);
|
||||
scene::IAnimatedMesh* getModel() const { return m_mesh; }
|
||||
|
||||
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_chassis_angular_damping = m_suspension_rest =
|
||||
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_track_connection_accel = m_min_speed_turn = m_angle_at_min =
|
||||
m_max_speed_turn = m_angle_at_max =
|
||||
@ -175,21 +175,21 @@ void KartProperties::load(const std::string &filename, const std::string &node)
|
||||
if(m_gravity_center_shift.getX()==UNDEFINED)
|
||||
{
|
||||
m_gravity_center_shift.setX(0);
|
||||
m_gravity_center_shift.setY(0);
|
||||
// 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_wheel_radius);
|
||||
m_wheel_base = fabsf( m_kart_model.getWheelPhysicsPosition(0).getY()
|
||||
-m_kart_model.getWheelPhysicsPosition(2).getY());
|
||||
m_wheel_radius );
|
||||
m_wheel_base = fabsf( m_kart_model.getWheelPhysicsPosition(0).getZ()
|
||||
-m_kart_model.getWheelPhysicsPosition(2).getZ());
|
||||
m_angle_at_min = asinf(m_wheel_base/m_min_radius);
|
||||
m_angle_at_max = asinf(m_wheel_base/m_max_radius);
|
||||
if(m_max_speed_turn == m_min_speed_turn)
|
||||
m_speed_angle_increase = 0.0;
|
||||
else
|
||||
m_speed_angle_increase = (m_angle_at_min - m_angle_at_max)
|
||||
/ (m_max_speed_turn - m_min_speed_turn);
|
||||
/ (m_max_speed_turn - m_min_speed_turn);
|
||||
|
||||
|
||||
// Useful when tweaking kart parameters
|
||||
@ -313,14 +313,14 @@ void KartProperties::getAllData(const XMLNode * root)
|
||||
|
||||
//TODO: wheel width is not loaded, yet is listed as an attribute in the xml file after wheel-radius?
|
||||
|
||||
root->get("chassis-linear-damping", &m_chassis_linear_damping);
|
||||
root->get("chassis-linear-damping", &m_chassis_linear_damping);
|
||||
root->get("chassis-angular-damping", &m_chassis_angular_damping);
|
||||
root->get("max-speed-reverse-ratio", &m_max_speed_reverse_ratio);
|
||||
root->get("suspension-rest", &m_suspension_rest);
|
||||
root->get("suspension-travel-cm", &m_suspension_travel_cm);
|
||||
root->get("jump-velocity", &m_jump_velocity);
|
||||
root->get("collision-side-impulse", &m_collision_side_impulse);
|
||||
root->get("z-rescue-offset", &m_z_rescue_offset);
|
||||
root->get("suspension-rest", &m_suspension_rest);
|
||||
root->get("suspension-travel-cm", &m_suspension_travel_cm);
|
||||
root->get("jump-velocity", &m_jump_velocity);
|
||||
root->get("collision-side-impulse", &m_collision_side_impulse);
|
||||
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: 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("collision-side-impulse", m_collision_side_impulse );
|
||||
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-max-force", m_upright_max_force );
|
||||
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_collision_side_impulse, "collision-side-impulse" );
|
||||
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_max_force, "upright-max-force" );
|
||||
CHECK_NEG(m_track_connection_accel, "track-connection-accel" );
|
||||
|
@ -130,8 +130,8 @@ private:
|
||||
/** An additional artifical side-impulse that pushes the slower kart
|
||||
* out of the way of the faster kart in case of a collision. */
|
||||
float m_collision_side_impulse;
|
||||
float m_jump_velocity; // z velocity set when jumping
|
||||
float m_z_rescue_offset; // z offset after rescue
|
||||
float m_jump_velocity; /**< Vertical velocity set when jumping. */
|
||||
float m_vert_rescue_offset; /**< Vertical offset after rescue. */
|
||||
float m_upright_tolerance;
|
||||
float m_upright_max_force;
|
||||
|
||||
@ -230,7 +230,9 @@ public:
|
||||
/** Returns the (artificial) collision side impulse this kart will apply
|
||||
* to a slower kart in case of a collision. */
|
||||
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 getUprightMaxForce () const {return m_upright_max_force; }
|
||||
float getTrackConnectionAccel () const {return m_track_connection_accel; }
|
||||
|
@ -32,9 +32,7 @@ Moveable::Moveable()
|
||||
m_motion_state = 0;
|
||||
m_first_time = true;
|
||||
m_mesh = NULL;
|
||||
m_animated_mesh = NULL;
|
||||
m_node = NULL;
|
||||
m_animated_node = NULL;
|
||||
} // Moveable
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -44,47 +42,38 @@ Moveable::~Moveable()
|
||||
if(m_body) delete m_body;
|
||||
if(m_motion_state) delete m_motion_state;
|
||||
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_animated_mesh) irr_driver->removeMesh(m_animated_mesh);
|
||||
} // ~Moveable
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Sets this model to be non-animated.
|
||||
/** Sets the mesh for this model.
|
||||
* \param n The scene node.
|
||||
*/
|
||||
void Moveable::setNode(scene::ISceneNode *n)
|
||||
{
|
||||
m_node = n;
|
||||
m_animated_node = NULL;
|
||||
} // setNode
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Sets this model to be animated.
|
||||
* \param n The animated scene node.
|
||||
/** 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).
|
||||
* \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)
|
||||
{
|
||||
m_node->setPosition(xyz.toIrrVector());
|
||||
m_node->setRotation(hpr.toIrrHPR());
|
||||
}
|
||||
else if(m_animated_node)
|
||||
{
|
||||
m_animated_node->setPosition(xyz.toIrrVector());
|
||||
m_animated_node->setRotation(hpr.toIrrHPR());
|
||||
}
|
||||
#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->setRotation(hpr.toIrrHPR());
|
||||
} // updateGraphics
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -97,51 +86,31 @@ void Moveable::reset()
|
||||
m_body->setAngularVelocity(btVector3(0, 0, 0));
|
||||
m_body->setCenterOfMassTransform(m_transform);
|
||||
}
|
||||
if(m_node)
|
||||
m_node->setVisible(true); // In case that the objects was eliminated
|
||||
if(m_animated_node)
|
||||
m_animated_node->setVisible(true);
|
||||
m_node->setVisible(true); // In case that the objects was eliminated
|
||||
|
||||
Coord c(m_transform);
|
||||
m_hpr = c.getHPR();
|
||||
m_hpr.setHPR(m_transform.getRotation());
|
||||
} // reset
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void Moveable::update(float dt)
|
||||
{
|
||||
m_motion_state->getWorldTransform(m_transform);
|
||||
m_velocityLC = getVelocity()*m_transform.getBasis();
|
||||
// The following code would synchronise bullet to irrlicht rotations, but
|
||||
// heading etc. might not be 'correct', e.g. a 180 degree heading rotation
|
||||
// would be reported as 180 degree roll and pitch, and 0 degree heading.
|
||||
// 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);
|
||||
m_velocityLC = getVelocity()*m_transform.getBasis();
|
||||
m_hpr.setHPR(m_transform.getRotation());
|
||||
Vec3 forw_vec = m_transform.getBasis().getColumn(0);
|
||||
m_heading = -atan2f(forw_vec.getZ(), forw_vec.getX());
|
||||
|
||||
// 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());
|
||||
// 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));
|
||||
updateGraphics(Vec3(0,0,0), btQuaternion(0, 0, 0, 1));
|
||||
m_first_time = false ;
|
||||
} // update
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void Moveable::createBody(float mass, btTransform& trans,
|
||||
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.
|
||||
m_user_pointer.zero();
|
||||
m_body->setUserPointer(&m_user_pointer);
|
||||
const btMatrix3x3& basis=m_body->getWorldTransform().getBasis();
|
||||
m_hpr.setHPR(basis);
|
||||
m_hpr.setHPR(m_body->getWorldTransform().getRotation());
|
||||
} // createBody
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -40,17 +40,19 @@ class Material;
|
||||
class Moveable
|
||||
{
|
||||
private:
|
||||
btVector3 m_velocityLC; /**<Velocity in kart coordinates */
|
||||
btTransform m_transform;
|
||||
Vec3 m_hpr;
|
||||
btVector3 m_velocityLC; /**<Velocity in kart coordinates. */
|
||||
btTransform m_transform;
|
||||
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:
|
||||
UserPointer m_user_pointer;
|
||||
scene::IAnimatedMesh *m_animated_mesh;
|
||||
scene::IMesh *m_mesh;
|
||||
scene::ISceneNode *m_node;
|
||||
scene::IAnimatedMeshSceneNode
|
||||
*m_animated_node;
|
||||
int m_first_time ;
|
||||
btRigidBody *m_body;
|
||||
KartMotionState *m_motion_state;
|
||||
@ -58,19 +60,27 @@ protected:
|
||||
public:
|
||||
Moveable();
|
||||
virtual ~Moveable();
|
||||
/** Returns the scene node of this moveable. */
|
||||
scene::ISceneNode
|
||||
*getNode() const { return m_node ? m_node : m_animated_node; }
|
||||
*getNode() const { return m_node; }
|
||||
void setNode(scene::ISceneNode *n);
|
||||
void setAnimatedNode(scene::IAnimatedMeshSceneNode *n);
|
||||
virtual const btVector3
|
||||
&getVelocity() const {return m_body->getLinearVelocity();}
|
||||
const btVector3
|
||||
&getVelocityLC() const {return m_velocityLC; }
|
||||
virtual void setVelocity(const btVector3& v) {m_body->setLinearVelocity(v); }
|
||||
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; }
|
||||
/** 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
|
||||
getRotation() const {return m_transform.getRotation(); }
|
||||
getRotation() const {return m_transform.getRotation(); }
|
||||
|
||||
/** Sets the XYZ coordinates of the moveable. */
|
||||
void setXYZ(const Vec3& a)
|
||||
@ -95,7 +105,8 @@ public:
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
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 update(float dt) ;
|
||||
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;
|
||||
}
|
||||
else if(!strcmp(argv[i], "--bullet-debug"))
|
||||
{
|
||||
UserConfigParams::m_bullet_debug=1;
|
||||
}
|
||||
else if(!strcmp(argv[i], "--kartsize-debug"))
|
||||
{
|
||||
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)
|
||||
{
|
||||
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") )
|
||||
{
|
||||
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 )
|
||||
{
|
||||
|
@ -303,12 +303,20 @@ int LinearWorld::getSectorForKart(const int kart_id) const
|
||||
} // 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
|
||||
{
|
||||
return m_kart_info[kart_id].m_curr_track_coords.getY();
|
||||
return m_kart_info[kart_id].m_curr_track_coords.getZ();
|
||||
} // 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
|
||||
{
|
||||
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) );
|
||||
|
||||
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) );
|
||||
kart->setRotation(heading);
|
||||
|
||||
@ -539,8 +547,8 @@ void LinearWorld::moveKartAfterRescue(Kart* kart, btRigidBody* body)
|
||||
float epsilon = 0.5f * kart->getKartHeight();
|
||||
|
||||
btTransform pos;
|
||||
pos.setOrigin(kart->getXYZ()+btVector3(0, 0, kart->getKartHeight() + epsilon));
|
||||
pos.setRotation(btQuaternion(btVector3(0.0f, 0.0f, 1.0f),
|
||||
pos.setOrigin(kart->getXYZ()+btVector3(0, kart->getKartHeight() + epsilon, 0));
|
||||
pos.setRotation(btQuaternion(btVector3(0.0f, 1.0f, 0.0f),
|
||||
m_track->getAngle(info.m_track_sector)));
|
||||
|
||||
body->setCenterOfMassTransform(pos);
|
||||
@ -551,9 +559,9 @@ void LinearWorld::moveKartAfterRescue(Kart* kart, btRigidBody* body)
|
||||
if (kart_over_ground)
|
||||
{
|
||||
//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();
|
||||
body->translate(btVector3(0, 0, vertical_offset));
|
||||
body->translate(btVector3(0, vertical_offset, 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -573,8 +581,9 @@ void LinearWorld::updateRacePosition()
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
bool rank_used[kart_amount+1];
|
||||
for (unsigned int n=0; n<=kart_amount; n++) rank_used[n] = false;
|
||||
std::vector<bool> rank_used;
|
||||
for (unsigned int n=0; n<=kart_amount; n++)
|
||||
rank_used.push_back(false);
|
||||
#endif
|
||||
|
||||
for (unsigned int i=0; i<kart_amount; i++)
|
||||
@ -663,7 +672,7 @@ void LinearWorld::updateRacePosition()
|
||||
sound_manager->switchToFastMusic();
|
||||
m_faster_music_active=true;
|
||||
}
|
||||
}
|
||||
} // for i<kart_amount
|
||||
|
||||
} // updateRacePosition
|
||||
|
||||
@ -688,7 +697,7 @@ void LinearWorld::checkForWrongDirection(unsigned int i)
|
||||
return;
|
||||
|
||||
// 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);
|
||||
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();
|
||||
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 int kart_y = (int)(kart->getXYZ()[1]);
|
||||
const float kart_x = kart->getXYZ().getX();
|
||||
const float kart_z = kart->getXYZ().getZ();
|
||||
|
||||
for(int n=0; n<start_spots_amount; n++)
|
||||
{
|
||||
// no need for the overhead to compute exact distance with sqrt(), so using the
|
||||
// 'manhattan' heuristic which will do fine enough.
|
||||
const Vec3 &v=world->getTrack()->getStartPosition(n);
|
||||
const int dist_n = abs((int)(kart_x - v.getX())) +
|
||||
abs((int)(kart_y - v.getY()));
|
||||
const float dist_n= fabs(kart_x - v.getX()) +
|
||||
fabs(kart_z - v.getZ());
|
||||
if(dist_n < smallest_distance_found || closest_id_found == -1)
|
||||
{
|
||||
closest_id_found = n;
|
||||
@ -276,14 +277,14 @@ void ThreeStrikesBattle::moveKartAfterRescue(Kart* kart, btRigidBody* body)
|
||||
kart->setXYZ( Vec3(v) );
|
||||
|
||||
// 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));
|
||||
kart->setRotation(heading);
|
||||
|
||||
//position kart from same height as in World::resetAllKarts
|
||||
btTransform pos;
|
||||
pos.setOrigin(kart->getXYZ()+btVector3(0, 0, 0.5f*kart->getKartHeight()));
|
||||
pos.setRotation( btQuaternion(btVector3(0.0f, 0.0f, 1.0f), 0 /* angle */) );
|
||||
pos.setOrigin(kart->getXYZ()+btVector3(0, 0.5f*kart->getKartHeight(), 0.0f));
|
||||
pos.setRotation( btQuaternion(btVector3(0.0f, 1.0f, 0.0f), 0 /* angle */) );
|
||||
|
||||
body->setCenterOfMassTransform(pos);
|
||||
|
||||
@ -293,9 +294,9 @@ void ThreeStrikesBattle::moveKartAfterRescue(Kart* kart, btRigidBody* body)
|
||||
if (kart_over_ground)
|
||||
{
|
||||
//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();
|
||||
body->translate(btVector3(0, 0, vertical_offset));
|
||||
body->translate(btVector3(0, vertical_offset, 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -312,7 +312,7 @@ void World::resetAllKarts()
|
||||
for ( KartList::iterator i=m_karts.begin(); i!=m_karts.end(); i++)
|
||||
{
|
||||
///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);
|
||||
|
||||
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];
|
||||
|
||||
rel_pos[2] *= wheelInfo.m_rollInfluence;
|
||||
rel_pos[m_indexUpAxis] *= wheelInfo.m_rollInfluence;
|
||||
m_chassisBody->applyImpulse(sideImp,rel_pos);
|
||||
|
||||
//apply friction impulse on the ground
|
||||
|
@ -23,6 +23,8 @@ subject to the following restrictions:
|
||||
#include "BulletDynamics/Dynamics/btRigidBody.h"
|
||||
#include "LinearMath/btTransformUtil.h"
|
||||
|
||||
#include "karts/kart.hpp"
|
||||
|
||||
//!
|
||||
//!
|
||||
//!
|
||||
@ -83,29 +85,31 @@ void btUprightConstraint::solveAngularLimit(
|
||||
|
||||
btVector3 motorImp = clippedMotorImpulse * limit->m_axis;
|
||||
body0->applyTorqueImpulse(motorImp);
|
||||
}
|
||||
} // solveAngularLimit
|
||||
|
||||
//!
|
||||
//!
|
||||
//!
|
||||
|
||||
btUprightConstraint::btUprightConstraint(btRigidBody& rbA, const btTransform& frameInA )
|
||||
: btTypedConstraint(D6_CONSTRAINT_TYPE, rbA)
|
||||
, m_frameInA(frameInA)
|
||||
btUprightConstraint::btUprightConstraint(const Kart* kart,
|
||||
const btTransform& frameInA)
|
||||
: btTypedConstraint(D6_CONSTRAINT_TYPE, *(kart->getBody()))
|
||||
, m_frameInA(frameInA)
|
||||
|
||||
{
|
||||
m_ERP = 1.0f;
|
||||
m_bounce = 0.0f;
|
||||
m_damping = 1.0f;
|
||||
m_limitSoftness = 1.0f;
|
||||
m_maxLimitForce = 3000.0f;
|
||||
m_disable_time = 0.0f;
|
||||
m_limit[0].m_accumulatedImpulse = 0.0f;
|
||||
m_limit[1].m_accumulatedImpulse = 0.0f;
|
||||
m_limit[ 0 ].m_axis = btVector3( 1, 0, 0 );
|
||||
m_limit[ 1 ].m_axis = btVector3( 0, 1, 0 );
|
||||
setLimit( SIMD_PI * 0.4f );
|
||||
}
|
||||
m_kart = kart;
|
||||
m_ERP = 1.0f;
|
||||
m_bounce = 0.0f;
|
||||
m_damping = 1.0f;
|
||||
m_limitSoftness = 1.0f;
|
||||
m_maxLimitForce = 3000.0f;
|
||||
m_disable_time = 0.0f;
|
||||
m_limit[0].m_accumulatedImpulse = 0.0f;
|
||||
m_limit[1].m_accumulatedImpulse = 0.0f;
|
||||
m_limit[ 0 ].m_axis = btVector3( 1, 0, 0 );
|
||||
m_limit[ 1 ].m_axis = btVector3( 0, 1, 0 );
|
||||
setLimit( SIMD_PI * 0.4f );
|
||||
} // btUprightConstraint
|
||||
|
||||
//!
|
||||
//!
|
||||
@ -113,31 +117,26 @@ btUprightConstraint::btUprightConstraint(btRigidBody& rbA, const btTransform& fr
|
||||
|
||||
void btUprightConstraint::buildJacobian()
|
||||
{
|
||||
btTransform worldTransform = m_rbA.getCenterOfMassTransform() * m_frameInA;
|
||||
btVector3 upAxis = worldTransform.getBasis().getColumn(2);
|
||||
m_limit[ 0 ].m_angle = btAtan2( upAxis.getZ(), upAxis.getY() )-SIMD_PI/2.0f;
|
||||
m_limit[ 1 ].m_angle = -btAtan2( upAxis.getZ(), upAxis.getX() )+SIMD_PI/2.0f;
|
||||
btTransform worldTransform = m_rbA.getCenterOfMassTransform() * m_frameInA;
|
||||
btVector3 upAxis = worldTransform.getBasis().getColumn(2);
|
||||
m_limit[ 0 ].m_angle = m_kart->getPitch();
|
||||
m_limit[ 1 ].m_angle = m_kart->getHPR().getRoll();
|
||||
|
||||
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,
|
||||
m_rbA.getCenterOfMassTransform().getBasis().transpose(),
|
||||
m_rbB.getCenterOfMassTransform().getBasis().transpose(),
|
||||
m_rbA.getInvInertiaDiagLocal(),
|
||||
m_rbB.getInvInertiaDiagLocal());
|
||||
}
|
||||
}
|
||||
for ( int i = 0; i < 2; i++ )
|
||||
{
|
||||
new (&m_jacAng[ i ]) btJacobianEntry( m_limit[ i ].m_axis,
|
||||
m_rbA.getCenterOfMassTransform().getBasis().transpose(),
|
||||
m_rbB.getCenterOfMassTransform().getBasis().transpose(),
|
||||
m_rbA.getInvInertiaDiagLocal(),
|
||||
m_rbB.getInvInertiaDiagLocal());
|
||||
}
|
||||
} // buildJacobian
|
||||
|
||||
//!
|
||||
//!
|
||||
//!
|
||||
|
||||
void btUprightConstraint::solveConstraint(btScalar timeStep)
|
||||
void btUprightConstraint::solveConstraint(btScalar timeStep)
|
||||
{
|
||||
m_timeStep = timeStep;
|
||||
|
||||
@ -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[ 1 ], m_timeStep, btScalar(1.) / m_jacAng[ 1 ].getDiagonal(), &m_rbA );
|
||||
}
|
||||
} // solveConstraint
|
||||
|
||||
|
@ -22,35 +22,33 @@ subject to the following restrictions:
|
||||
#include "BulletDynamics/ConstraintSolver/btTypedConstraint.h"
|
||||
|
||||
class btRigidBody;
|
||||
class Kart;
|
||||
|
||||
//!
|
||||
//!
|
||||
//!
|
||||
|
||||
class btUprightConstraintLimit
|
||||
{
|
||||
public:
|
||||
btVector3 m_axis;
|
||||
btScalar m_angle;
|
||||
btScalar m_accumulatedImpulse;
|
||||
btScalar m_currentLimitError;
|
||||
};
|
||||
|
||||
class btUprightConstraint : public btTypedConstraint
|
||||
{
|
||||
protected:
|
||||
private:
|
||||
class btUprightConstraintLimit
|
||||
{
|
||||
public:
|
||||
btVector3 m_axis;
|
||||
btScalar m_angle;
|
||||
btScalar m_accumulatedImpulse;
|
||||
btScalar m_currentLimitError;
|
||||
};
|
||||
|
||||
//! relative_frames
|
||||
|
||||
//!@{
|
||||
btTransform m_frameInA;//!< the constraint space w.r.t body A
|
||||
btTransform m_frameInA;//!< the constraint space w.r.t body A
|
||||
//!@}
|
||||
|
||||
//! Jacobians
|
||||
//!@{
|
||||
btJacobianEntry m_jacAng[ 2 ];//!< angular constraint
|
||||
btJacobianEntry m_jacAng[ 2 ];//!< angular constraint
|
||||
//!@}
|
||||
|
||||
const Kart *m_kart;
|
||||
protected:
|
||||
|
||||
//! temporal variables
|
||||
@ -61,71 +59,47 @@ protected:
|
||||
btScalar m_damping;
|
||||
btScalar m_maxLimitForce;
|
||||
btScalar m_limitSoftness;
|
||||
btScalar m_hiLimit;
|
||||
btScalar m_loLimit;
|
||||
btScalar m_disable_time;
|
||||
btScalar m_hiLimit;
|
||||
btScalar m_loLimit;
|
||||
btScalar m_disable_time;
|
||||
|
||||
btUprightConstraintLimit m_limit[ 2 ];
|
||||
|
||||
//!@}
|
||||
|
||||
btUprightConstraint& operator=(btUprightConstraint& other)
|
||||
btUprightConstraint& operator=(btUprightConstraint& other)
|
||||
{
|
||||
btAssert(0);
|
||||
(void) other;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void buildAngularJacobian(btJacobianEntry & jacAngular,const btVector3 & jointAxisW);
|
||||
void buildAngularJacobian(btJacobianEntry & jacAngular,
|
||||
const btVector3 & jointAxisW);
|
||||
|
||||
void solveAngularLimit(
|
||||
btUprightConstraintLimit *limit,
|
||||
btScalar timeStep, btScalar jacDiagABInv,
|
||||
btRigidBody * body0 );
|
||||
void solveAngularLimit(btUprightConstraintLimit *limit,
|
||||
btScalar timeStep, btScalar jacDiagABInv,
|
||||
btRigidBody * body0 );
|
||||
|
||||
public:
|
||||
|
||||
btUprightConstraint(btRigidBody& rbA, const btTransform& frameInA );
|
||||
|
||||
// -PI,+PI is the full range
|
||||
// 0,0 is no rotation around x or z
|
||||
// -PI*0.2,+PI*0.2 is a nice bit of tilt
|
||||
void setLimit( btScalar range )
|
||||
{
|
||||
m_loLimit = -range;
|
||||
m_hiLimit = +range;
|
||||
}
|
||||
|
||||
// Error correction scaling
|
||||
// 0 - 1
|
||||
//
|
||||
void setErp( btScalar erp )
|
||||
{
|
||||
m_ERP = erp;
|
||||
}
|
||||
void setBounce( btScalar bounce )
|
||||
{
|
||||
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;
|
||||
}
|
||||
btUprightConstraint(const Kart* kart, const btTransform& frameInA);
|
||||
|
||||
// -PI,+PI is the full range
|
||||
// 0,0 is no rotation around x or z
|
||||
// -PI*0.2,+PI*0.2 is a nice bit of tilt
|
||||
void setLimit( btScalar range ) { m_loLimit = -range;
|
||||
m_hiLimit = +range; }
|
||||
// Error correction scaling
|
||||
// 0 - 1
|
||||
void setErp( btScalar erp ) { m_ERP = erp; }
|
||||
void setBounce( btScalar bounce ) { 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 solveConstraint(btScalar timeStep);
|
||||
virtual void solveConstraint(btScalar timeStep);
|
||||
};
|
||||
|
||||
|
||||
|
@ -23,48 +23,34 @@
|
||||
|
||||
IrrDebugDrawer::IrrDebugDrawer()
|
||||
{
|
||||
m_debug_mode = DBG_DrawAabb;
|
||||
m_debug_mode = DM_NONE;
|
||||
} // IrrDebugDrawer
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
/** Activates the debug view. It makes all karts invisible (in irrlicht), so
|
||||
* that the bullet view can be seen.
|
||||
/** Activates the next debug mode, or switches the mode off again.
|
||||
*/
|
||||
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();
|
||||
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(false);
|
||||
kart->getNode()->setVisible(!(m_debug_mode & DM_NO_KARTS_GRAPHICS));
|
||||
}
|
||||
} // activate
|
||||
// -----------------------------------------------------------------------------
|
||||
/** 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
|
||||
} // nextDebugMode
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
void IrrDebugDrawer::drawLine(const btVector3& from, const btVector3& to,
|
||||
const btVector3& color)
|
||||
{
|
||||
Vec3 f(from);
|
||||
Vec3 t(to);
|
||||
video::SColor c(255, (int)(color.getX()*255), (int)(color.getY()*255),
|
||||
(int)(color.getZ()*255) );
|
||||
irr_driver->getVideoDriver()->draw3DLine(f.toIrrVector(),
|
||||
t.toIrrVector(), c);
|
||||
irr_driver->getVideoDriver()->draw3DLine((const core::vector3df&)from,
|
||||
(const core::vector3df&)to, c);
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
@ -30,9 +30,18 @@ using namespace irr;
|
||||
|
||||
class IrrDebugDrawer : public btIDebugDraw
|
||||
{
|
||||
/** The drawing mode to use. */
|
||||
int m_debug_mode;
|
||||
|
||||
/** The drawing mode to use:
|
||||
* 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:
|
||||
IrrDebugDrawer();
|
||||
void render(float dt);
|
||||
@ -47,11 +56,9 @@ public:
|
||||
virtual void reportErrorWarning(const char* warningString) {}
|
||||
virtual void draw3dText(const btVector3& location,
|
||||
const char* textString) {}
|
||||
virtual void setDebugMode(int debug_mode) { m_debug_mode = debug_mode; }
|
||||
virtual int getDebugMode() const { return m_debug_mode; }
|
||||
void activate();
|
||||
void deactivate();
|
||||
|
||||
/** Returns true if debug mode is enabled. */
|
||||
bool debugEnabled() const {return m_debug_mode!=0;}
|
||||
void nextDebugMode();
|
||||
}; // IrrDebugDrawer
|
||||
|
||||
#endif
|
||||
|
@ -45,20 +45,20 @@ void Physics::init(const Vec3 &world_min, const Vec3 &world_max)
|
||||
{
|
||||
m_axis_sweep = new btAxisSweep3(world_min, world_max);
|
||||
m_dynamics_world = new btDiscreteDynamicsWorld(m_dispatcher,
|
||||
m_axis_sweep,
|
||||
m_axis_sweep,
|
||||
this,
|
||||
m_collision_conf);
|
||||
m_dynamics_world->setGravity(btVector3(0.0f, 0.0f,
|
||||
-World::getWorld()->getTrack()->getGravity()));
|
||||
m_dynamics_world->setGravity(btVector3(0.0f,
|
||||
-World::getWorld()->getTrack()->getGravity(),
|
||||
0.0f));
|
||||
m_debug_drawer = new IrrDebugDrawer();
|
||||
m_debug_drawer->setDebugMode(btIDebugDraw::DBG_DrawWireframe);
|
||||
m_dynamics_world->setDebugDrawer(m_debug_drawer);
|
||||
} // init
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
Physics::~Physics()
|
||||
{
|
||||
if(UserConfigParams::m_bullet_debug) delete m_debug_drawer;
|
||||
delete m_debug_drawer;
|
||||
delete m_dynamics_world;
|
||||
delete m_axis_sweep;
|
||||
delete m_dispatcher;
|
||||
@ -153,7 +153,7 @@ void Physics::update(float dt)
|
||||
|
||||
bool Physics::projectKartDownwards(const Kart *k)
|
||||
{
|
||||
btVector3 hell(0, 0, -10000);
|
||||
btVector3 hell(0, -10000, 0);
|
||||
return k->getVehicle()->projectVehicleToSurface(hell, true /*allow translation*/);
|
||||
} //projectKartsDownwards
|
||||
|
||||
@ -343,6 +343,9 @@ btScalar Physics::solveGroup(btCollisionObject** bodies, int numBodies,
|
||||
/** A debug draw function to show the track and all karts. */
|
||||
void Physics::draw()
|
||||
{
|
||||
if(!m_debug_drawer->debugEnabled() ||
|
||||
!World::getWorld()->isRacePhase()) return;
|
||||
|
||||
video::SColor color(77,179,0,0);
|
||||
video::SMaterial material;
|
||||
material.Thickness = 2;
|
||||
|
@ -101,11 +101,11 @@ public:
|
||||
void draw ();
|
||||
btDynamicsWorld*
|
||||
getPhysicsWorld () const {return m_dynamics_world;}
|
||||
void debugDraw (float m[16], btCollisionShape *s, const btVector3 color);
|
||||
/** Activates the debug drawer. */
|
||||
void activateDebug () {m_debug_drawer->activate(); }
|
||||
/** Deactivates the debug drawer. */
|
||||
void deactivateDebug () {m_debug_drawer->deactivate(); }
|
||||
/** Activates the next debug mode (or switches it off again).
|
||||
*/
|
||||
void nextDebugMode () {m_debug_drawer->nextDebugMode(); }
|
||||
/** Returns true if the debug drawer is enabled. */
|
||||
bool isDebug() const {return m_debug_drawer->debugEnabled(); }
|
||||
bool projectKartDownwards(const Kart *k);
|
||||
virtual btScalar solveGroup(btCollisionObject** bodies, int numBodies,
|
||||
btPersistentManifold** manifold,int numManifolds,
|
||||
|
@ -28,6 +28,8 @@
|
||||
|
||||
History* history = 0;
|
||||
|
||||
#define KEEP_OLD_FORMAT
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Initialises the history object and sets the mode to none.
|
||||
*/
|
||||
@ -64,7 +66,7 @@ void History::initRecording()
|
||||
void History::allocateMemory(int 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_xyz.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_accel,
|
||||
m_all_controls[j].getButtonsCompressed(),
|
||||
m_all_xyz[j].getX(), m_all_xyz[j].getY(),
|
||||
m_all_xyz[j].getZ(),
|
||||
m_all_xyz[j].getX(),
|
||||
#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].getZ(), m_all_rotations[j].getW() );
|
||||
j=(j+1)%m_size;
|
||||
@ -297,7 +303,18 @@ void History::Load()
|
||||
&m_all_controls[i].m_steer,
|
||||
&m_all_controls[i].m_accel,
|
||||
&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_rotations[i] = btQuaternion(rx,ry,rz,rw);
|
||||
m_all_controls[i].setButtonsCompressed(char(buttonsCompressed));
|
||||
|
@ -661,7 +661,7 @@ public:
|
||||
// Random kart
|
||||
scene::IMesh* model = item_manager->getItemModel(Item::ITEM_BONUS_BOX);
|
||||
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);
|
||||
m_parent->m_kart_widgets[playerID].kartName->setText( _("Random Kart") );
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ void CheckLine::reset(const Track &track)
|
||||
Vec3 CheckLine::getCenterPoint() const
|
||||
{
|
||||
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;
|
||||
} // 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
|
||||
// in case that there is 'somewhat' inside of the track, or the
|
||||
// checklines are a bit off in Z direction.
|
||||
result = new_pos.getZ()-m_min_height<4.0f &&
|
||||
new_pos.getZ()-m_min_height>-1.0f;
|
||||
result = new_pos.getY()-m_min_height<4.0f &&
|
||||
new_pos.getY()-m_min_height>-1.0f;
|
||||
}
|
||||
else
|
||||
result = false;
|
||||
|
@ -52,10 +52,10 @@ GraphNode::GraphNode(unsigned int index)
|
||||
+ (quad[3]-quad[2]).length() ) * 0.5f;
|
||||
Vec3 lower = (quad[0]+quad[1]) * 0.5f;
|
||||
Vec3 upper = (quad[2]+quad[3]) * 0.5f;
|
||||
m_line = core::line2df(lower.getX(), lower.getY(),
|
||||
upper.getX(), upper.getY() );
|
||||
m_line = core::line2df(lower.getX(), lower.getZ(),
|
||||
upper.getX(), upper.getZ() );
|
||||
// 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
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -76,7 +76,7 @@ void GraphNode::addSuccessor(unsigned int to)
|
||||
Vec3 diff = next_quad.getCenter() - this_quad.getCenter();
|
||||
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);
|
||||
|
||||
// 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.
|
||||
* \param xyz The coordinates of the point.
|
||||
* \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)
|
||||
{
|
||||
core::vector2df xyz2d(xyz.getX(), xyz.getY());
|
||||
core::vector2df xyz2d(xyz.getX(), xyz.getZ());
|
||||
core::vector2df closest = m_line.getClosestPoint(xyz2d);
|
||||
if(m_line.getPointOrientation(xyz2d)>0)
|
||||
result->setX( (closest-xyz2d).getLength()); // to the right
|
||||
else
|
||||
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
|
||||
|
@ -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_center = 0.25f*(p0+p1+p2+p3);
|
||||
m_min_height = std::min ( std::min(p0.getZ(), p1.getZ()),
|
||||
std::min(p0.getZ(), p1.getZ()) );
|
||||
m_min_height = std::min ( std::min(p0.getY(), p1.getY()),
|
||||
std::min(p0.getY(), p1.getY()) );
|
||||
m_invisible = invisible;
|
||||
} // 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
|
||||
{
|
||||
return (l2.getX()-l1.getX())*(p.getY()-l1.getY()) -
|
||||
(l2.getY()-l1.getY())*(p.getX()-l1.getX());
|
||||
return (l2.getX()-l1.getX())*(p.getZ()-l1.getZ()) -
|
||||
(l2.getZ()-l1.getZ())*(p.getX()-l1.getX());
|
||||
} // sideOfLine
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -102,6 +102,7 @@ bool Quad::pointInQuad(const Vec3& p) const
|
||||
sideOfLine2D(m_p[3], m_p[0], p) >= 0.0;
|
||||
}
|
||||
} // pointInQuad
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** 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
|
||||
|
@ -79,7 +79,7 @@ void QuadGraph::setStartCoordinate(const CheckLine &cl)
|
||||
}
|
||||
Vec3 xyz;
|
||||
spatialToTrack(&xyz, start_point, sector);
|
||||
m_offset_for_startline = xyz.getY();
|
||||
m_offset_for_startline = xyz.getZ();
|
||||
} // 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
|
||||
* through, the x-axis is on which side of the road it is. The Z axis
|
||||
* 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 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);
|
||||
float y=dst->getY();
|
||||
y=y-m_offset_for_startline;
|
||||
if(y<0) y+=m_lap_length;
|
||||
dst->setY(y);
|
||||
float z=dst->getZ();
|
||||
z=z-m_offset_for_startline;
|
||||
if(z<0) z+=m_lap_length;
|
||||
dst->setZ(z);
|
||||
} // spatialToTrack
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -381,7 +381,7 @@ void QuadGraph::findRoadSector(const Vec3& xyz, int *sector,
|
||||
else
|
||||
indx = indx<(int)m_all_nodes.size()-1 ? indx +1 : 0;
|
||||
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
|
||||
// numbers in case that the kart is partly in the track.
|
||||
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;
|
||||
core::matrix4 projection;
|
||||
projection.buildProjectionMatrixOrthoLH(bb_max.getX()-bb_min.getX(),
|
||||
bb_max.getY()-bb_min.getY(),
|
||||
-1, bb_max.getZ()-bb_min.getZ()+1);
|
||||
bb_max.getZ()-bb_min.getZ(),
|
||||
-1, bb_max.getY()-bb_min.getY()+1);
|
||||
camera->setProjectionMatrix(projection, true);
|
||||
// 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)
|
||||
// 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->setUpVector(core::vector3df(0,0,1));
|
||||
camera->setTarget(core::vector3df(center.getX(),bb_min.getZ()-1,center.getY()));
|
||||
camera->setPosition(core::vector3df(center.getX(), bb_max.getY()+1, center.getZ()));
|
||||
camera->setUpVector(core::vector3df(0, 0, 1));
|
||||
camera->setTarget(core::vector3df(center.getX(),bb_min.getY()-1,center.getZ()));
|
||||
|
||||
video::ITexture *texture = rttProvider.renderToTexture();
|
||||
|
||||
@ -505,7 +505,7 @@ video::ITexture *QuadGraph::makeMiniMap(const core::dimension2du &dimension,
|
||||
irr_driver->removeCameraSceneNode(camera);
|
||||
m_min_coord = bb_min;
|
||||
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;
|
||||
} // drawMiniMap
|
||||
|
||||
@ -519,6 +519,6 @@ video::ITexture *QuadGraph::makeMiniMap(const core::dimension2du &dimension,
|
||||
void QuadGraph::mapPoint2MiniMap(const Vec3 &xyz,Vec3 *draw_at) const
|
||||
{
|
||||
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
|
||||
|
@ -60,13 +60,13 @@ float TerrainInfo::getTerrainPitch(float heading) const {
|
||||
if(m_HoT==Track::NOHIT) return 0.0f;
|
||||
|
||||
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
|
||||
// (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.
|
||||
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.
|
||||
pitch = acosf(pitch) - NINETY_DEGREE_RAD;
|
||||
return pitch;
|
||||
|
@ -166,7 +166,7 @@ btTransform Track::getStartTransform(unsigned int pos) const
|
||||
|
||||
Vec3 orig = pos<m_start_positions.size()
|
||||
? 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;
|
||||
start.setOrigin(orig);
|
||||
start.setRotation(btQuaternion(btVector3(0, 0, 1),
|
||||
@ -391,7 +391,7 @@ void Track::convertTrackToBullet(const scene::IMesh *mesh,
|
||||
int indx=mbIndices[j+k];
|
||||
core::vector3df v = mbVertices[indx].Pos;
|
||||
mat.transformVect(v);
|
||||
vertices[k] = Vec3(v);
|
||||
vertices[k]=v;
|
||||
} // for k
|
||||
if(tmesh) tmesh->addTriangle(vertices[0], vertices[1],
|
||||
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
|
||||
// (with the new track exporter it always is defined anyway).
|
||||
// Z is the height from which the item is dropped on the track.
|
||||
xyz.setZ(1000);
|
||||
xyz.setY(1000);
|
||||
node->getXYZ(&xyz);
|
||||
bool drop=true;
|
||||
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(drop)
|
||||
{
|
||||
loc.setZ(getTerrainHeight(loc));
|
||||
loc.setY(getTerrainHeight(loc));
|
||||
}
|
||||
|
||||
// Don't tilt the items, since otherwise the rotation will look odd,
|
||||
// i.e. the items will not rotate around the normal, but 'wobble'
|
||||
// around.
|
||||
//Vec3 normal(0.7071f, 0, 0.7071f);
|
||||
Vec3 normal(0, 0, 1);
|
||||
Vec3 normal(0, 1, 0);
|
||||
item_manager->newItem(type, loc, normal);
|
||||
} // itemCommand
|
||||
|
||||
@ -900,7 +900,7 @@ void Track::getTerrainInfo(const Vec3 &pos, float *hot, Vec3 *normal,
|
||||
const Material **material) const
|
||||
{
|
||||
btVector3 to_pos(pos);
|
||||
to_pos.setZ(-100000.f);
|
||||
to_pos.setY(-100000.f);
|
||||
|
||||
class MaterialCollision : public btCollisionWorld::ClosestRayResultCallback
|
||||
{
|
||||
@ -938,7 +938,7 @@ void Track::getTerrainInfo(const Vec3 &pos, float *hot, Vec3 *normal,
|
||||
return;
|
||||
}
|
||||
|
||||
*hot = rayCallback.m_hitPointWorld.getZ();
|
||||
*hot = rayCallback.m_hitPointWorld.getY();
|
||||
*normal = rayCallback.m_hitNormalWorld;
|
||||
*material = rayCallback.m_material;
|
||||
// Note: material might be NULL. This happens if the ray cast does not
|
||||
|
@ -56,7 +56,7 @@ public:
|
||||
Coord(const btTransform& t)
|
||||
{
|
||||
m_xyz = t.getOrigin();
|
||||
m_hpr.setHPR(t.getBasis());
|
||||
m_hpr.setHPR(t.getRotation());
|
||||
//setSgCoord();
|
||||
} // Coord
|
||||
// ------------------------------------------------------------------------
|
||||
|
@ -21,59 +21,22 @@
|
||||
|
||||
#include "utils/constants.hpp"
|
||||
|
||||
void Vec3::setHPR(const btMatrix3x3& m)
|
||||
|
||||
void Vec3::setHPR(const btQuaternion& q)
|
||||
{
|
||||
float f[4][4];
|
||||
m.getOpenGLSubMatrix((float*)f);
|
||||
float W = q.getW();
|
||||
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();
|
||||
|
||||
if ( s <= 0.00001 )
|
||||
{
|
||||
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
|
||||
setX(atan2f(2.0f * (Y * Z + X * W), -XSquared - YSquared + ZSquared + WSquared));
|
||||
setY(asinf(-2.0f * (X * Z - Y * W)));
|
||||
setZ(atan2f(2.0f * (X * Y + Z * W), XSquared - YSquared - ZSquared + WSquared));
|
||||
} // setHPR(btQuaternion)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
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
|
||||
// (x,y,0). (x,y,0) is normalised, so are the coordinates of the plane,
|
||||
// simplifying the computation of the scalar product.
|
||||
float pitch = ( normal.getX()*X + normal.getY()*Y ); // use ( x,y,0)
|
||||
float roll = (-normal.getX()*Y + normal.getY()*X ); // use (-y,x,0)
|
||||
float pitch = ( normal.getX()*X + normal.getZ()*Y ); // use ( x,y,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)
|
||||
// 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
|
||||
{
|
||||
core::vector3df r(RAD_TO_DEGREE*(-getY()), // pitch
|
||||
RAD_TO_DEGREE*(-getX()), // heading
|
||||
RAD_TO_DEGREE*(-getZ()) ); // roll
|
||||
core::vector3df r(RAD_TO_DEGREE*(getX()), // pitch
|
||||
RAD_TO_DEGREE*(getY()), // heading
|
||||
RAD_TO_DEGREE*(getZ()) ); // roll
|
||||
return r;
|
||||
|
||||
} // 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 v;
|
||||
return (const core::vector3df&)*this;
|
||||
} // toIrrVector
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Returns the X and Y component as an irrlicht 2d vector. */
|
||||
const core::vector2df Vec3::toIrrVector2d() const
|
||||
{
|
||||
core::vector2df v(m_x, m_y);
|
||||
core::vector2df v(m_x, m_z);
|
||||
return v;
|
||||
} // toIrrVector2d
|
||||
|
@ -40,8 +40,7 @@ public:
|
||||
* axis as well (so a vector3df can be stored in and restored from
|
||||
* a vec3).
|
||||
*/
|
||||
inline Vec3(const core::vector3df &v) : btVector3(v.X, v.Z, v.Y) {}
|
||||
//inline Vec3(sgVec3 a) : btVector3(a[0], a[1], a[2]) {}
|
||||
inline Vec3(const core::vector3df &v) : btVector3(v.X, v.Y, v.Z) {}
|
||||
inline Vec3(const btVector3& a) : btVector3(a) {}
|
||||
inline Vec3() : btVector3() {}
|
||||
inline Vec3(float x, float y, float z) : btVector3(x,y,z) {}
|
||||
@ -54,29 +53,28 @@ public:
|
||||
{m_x=heading;
|
||||
setPitchRoll(normal);}
|
||||
|
||||
void setHPR(const btMatrix3x3& m);
|
||||
inline const float operator[](int n) const {return *(&m_x+n); }
|
||||
inline const float getHeading() const {return m_x; }
|
||||
inline const float getPitch() const {return m_y; }
|
||||
inline const float getRoll() const {return m_z; }
|
||||
inline const void setHeading(float f) {m_x = f;}
|
||||
inline const void setPitch(float f) {m_y = f;}
|
||||
inline const void setRoll(float f) {m_z = f;}
|
||||
float* toFloat() const {return (float*)this; }
|
||||
void setHPR(const btQuaternion& q);
|
||||
inline const float operator[](int n) const { return *(&m_x+n); }
|
||||
inline const float getHeading() const { return m_y; }
|
||||
inline const float getPitch() const { return m_x; }
|
||||
inline const float getRoll() const { return m_z; }
|
||||
inline const void setHeading(float f) { m_y = f; }
|
||||
inline const void setPitch(float f) { m_x = f; }
|
||||
inline const void setRoll(float f) { m_z = f; }
|
||||
/** Converts a Vec3 to an irrlicht 3d floating point vector. */
|
||||
const core::vector3df toIrrVector() const;
|
||||
const core::vector3df toIrrHPR() const;
|
||||
const core::vector2df toIrrVector2d() const;
|
||||
void degreeToRad();
|
||||
const core::vector3df& toIrrVector() const;
|
||||
const core::vector3df toIrrHPR() const;
|
||||
const core::vector2df toIrrVector2d() const;
|
||||
void degreeToRad();
|
||||
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);}
|
||||
/** Helper functions to treat this vec3 as a 2d vector. This returns the
|
||||
* 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
|
||||
* 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.
|
||||
* \param Vector to compare with. */
|
||||
void max(const Vec3& a) {if(a.getX()>m_x) m_x=a.getX();
|
||||
|
Loading…
Reference in New Issue
Block a user