diff --git a/data/stk_config.xml b/data/stk_config.xml index 73d855010..ff3e5c64f 100644 --- a/data/stk_config.xml +++ b/data/stk_config.xml @@ -2,11 +2,32 @@ - + + + + + + + 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; +" diff --git a/src/bullet/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp b/src/bullet/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp index 40de23400..89615f816 100644 --- a/src/bullet/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp +++ b/src/bullet/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp @@ -262,7 +262,12 @@ void btDiscreteDynamicsWorld::synchronizeMotionStates() for (int v=0;vgetNumWheels();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; } } } diff --git a/src/bullet/src/BulletDynamics/Vehicle/btRaycastVehicle.cpp b/src/bullet/src/BulletDynamics/Vehicle/btRaycastVehicle.cpp index 458cf9827..d5a76a17f 100644 --- a/src/bullet/src/BulletDynamics/Vehicle/btRaycastVehicle.cpp +++ b/src/bullet/src/BulletDynamics/Vehicle/btRaycastVehicle.cpp @@ -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 diff --git a/src/config/user_config.hpp b/src/config/user_config.hpp index 86c31334e..8f80a5164 100644 --- a/src/config/user_config.hpp +++ b/src/config/user_config.hpp @@ -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 diff --git a/src/graphics/camera.cpp b/src/graphics/camera.cpp index b2f38593d..ce20ff8da 100644 --- a/src/graphics/camera.cpp +++ b/src/graphics/camera.cpp @@ -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); diff --git a/src/graphics/irr_driver.cpp b/src/graphics/irr_driver.cpp index 31008bc4e..163d45f61 100644 --- a/src/graphics/irr_driver.cpp +++ b/src/graphics/irr_driver.cpp @@ -411,8 +411,9 @@ void IrrDriver::setAllMaterialFlags(scene::IAnimatedMesh *mesh) const for(unsigned int j=0; jsetAllFlatMaterialFlags(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 jsetAllUntexturedMaterialFlags(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 igetNumKarts() // To draw the race gui we set the viewport back to the full diff --git a/src/graphics/mesh_tools.cpp b/src/graphics/mesh_tools.cpp index 57d8b83e0..0c16dba07 100644 --- a/src/graphics/mesh_tools.cpp +++ b/src/graphics/mesh_tools.cpp @@ -36,8 +36,8 @@ void MeshTools::minMax3D(scene::IMesh* mesh, Vec3 *min, Vec3 *max) { for(unsigned int j=0; jgetIndexCount(); 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 diff --git a/src/graphics/slip_stream.cpp b/src/graphics/slip_stream.cpp index fa3f8c55e..426a89b57 100644 --- a/src/graphics/slip_stream.cpp +++ b/src/graphics/slip_stream.cpp @@ -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))); diff --git a/src/input/input_manager.cpp b/src/input/input_manager.cpp index 282f1674b..fb665e0e6 100644 --- a/src/input/input_manager.cpp +++ b/src/input/input_manager.cpp @@ -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; diff --git a/src/items/bowling.cpp b/src/items/bowling.cpp index 19cfb9d3d..06d88b116 100644 --- a/src/items/bowling.cpp +++ b/src/items/bowling.cpp @@ -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 && minDistancegetLinearVelocity(); 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 diff --git a/src/items/cake.cpp b/src/items/cake.cpp index b362d7558..db0a34f4f 100644 --- a/src/items/cake.cpp +++ b/src/items/cake.cpp @@ -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, diff --git a/src/items/flyable.cpp b/src/items/flyable.cpp index 0683ea116..b853e4142 100644 --- a/src/items/flyable.cpp +++ b/src/items/flyable.cpp @@ -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 diff --git a/src/items/flyable.hpp b/src/items/flyable.hpp index faa978739..13ac44196 100644 --- a/src/items/flyable.hpp +++ b/src/items/flyable.hpp @@ -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); diff --git a/src/items/item.cpp b/src/items/item.cpp index 289e94554..a2cb1e3b8 100644 --- a/src/items/item.cpp +++ b/src/items/item.cpp @@ -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 //----------------------------------------------------------------------------- diff --git a/src/items/item.hpp b/src/items/item.hpp index bbf921111..7b551bac8 100644 --- a/src/items/item.hpp +++ b/src/items/item.hpp @@ -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 // ------------------------------------------------------------------------ diff --git a/src/items/plunger.cpp b/src/items/plunger.cpp index 3f94a2d59..7d097d435 100644 --- a/src/items/plunger.cpp +++ b/src/items/plunger.cpp @@ -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()); diff --git a/src/items/rubber_band.cpp b/src/items/rubber_band.cpp index edcb0d132..8af54f55b 100644 --- a/src/items/rubber_band.cpp +++ b/src/items/rubber_band.cpp @@ -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 diff --git a/src/karts/controller/default_ai_controller.cpp b/src/karts/controller/default_ai_controller.cpp index 8f79bbeb0..ff22c2267 100644 --- a/src/karts/controller/default_ai_controller.cpp +++ b/src/karts/controller/default_ai_controller.cpp @@ -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]); diff --git a/src/karts/controller/end_controller.cpp b/src/karts/controller/end_controller.cpp index a27ad108c..da79b47d8 100644 --- a/src/karts/controller/end_controller.cpp +++ b/src/karts/controller/end_controller.cpp @@ -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]); diff --git a/src/karts/controller/new_ai_controller.cpp b/src/karts/controller/new_ai_controller.cpp index 9706c14eb..9b10f1bf7 100755 --- a/src/karts/controller/new_ai_controller.cpp +++ b/src/karts/controller/new_ai_controller.cpp @@ -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); diff --git a/src/karts/controller/player_controller.cpp b/src/karts/controller/player_controller.cpp index a41097c9b..cdd9d944a 100644 --- a/src/karts/controller/player_controller.cpp +++ b/src/karts/controller/player_controller.cpp @@ -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; diff --git a/src/karts/kart.cpp b/src/karts/kart.cpp index 34149dd9e..d47816884 100644 --- a/src/karts/kart.cpp +++ b/src/karts/kart.cpp @@ -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 */ diff --git a/src/karts/kart.hpp b/src/karts/kart.hpp index 879a11ae7..4d8b86bfe 100644 --- a/src/karts/kart.hpp +++ b/src/karts/kart.hpp @@ -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; } diff --git a/src/karts/kart_model.cpp b/src/karts/kart_model.cpp index 1714c0b47..2e0ccf811 100644 --- a/src/karts/kart_model.cpp +++ b/src/karts/kart_model.cpp @@ -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(*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++) diff --git a/src/karts/kart_model.hpp b/src/karts/kart_model.hpp index ab13cc320..1e89db656 100644 --- a/src/karts/kart_model.hpp +++ b/src/karts/kart_model.hpp @@ -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]; } diff --git a/src/karts/kart_properties.cpp b/src/karts/kart_properties.cpp index 658ee503f..cc5017989 100644 --- a/src/karts/kart_properties.cpp +++ b/src/karts/kart_properties.cpp @@ -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" ); diff --git a/src/karts/kart_properties.hpp b/src/karts/kart_properties.hpp index e067b23ba..8eebf1c36 100644 --- a/src/karts/kart_properties.hpp +++ b/src/karts/kart_properties.hpp @@ -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; } diff --git a/src/karts/moveable.cpp b/src/karts/moveable.cpp index fd9df3e61..3c264895a 100644 --- a/src/karts/moveable.cpp +++ b/src/karts/moveable.cpp @@ -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 //----------------------------------------------------------------------------- diff --git a/src/karts/moveable.hpp b/src/karts/moveable.hpp index 026102296..60a7d4012 100644 --- a/src/karts/moveable.hpp +++ b/src/karts/moveable.hpp @@ -40,17 +40,19 @@ class Material; class Moveable { private: - btVector3 m_velocityLC; /**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; } diff --git a/src/main.cpp b/src/main.cpp index d9c1b92f8..6389bb564 100644 --- a/src/main.cpp +++ b/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+1setXYZ( 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 rank_used; + for (unsigned int n=0; n<=kart_amount; n++) + rank_used.push_back(false); #endif for (unsigned int i=0; iswitchToFastMusic(); m_faster_music_active=true; } - } + } // for igetHPR().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; diff --git a/src/modes/three_strikes_battle.cpp b/src/modes/three_strikes_battle.cpp index 3345c4764..a294fdc4d 100644 --- a/src/modes/three_strikes_battle.cpp +++ b/src/modes/three_strikes_battle.cpp @@ -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; ngetTrack()->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 { diff --git a/src/modes/world.cpp b/src/modes/world.cpp index 527845525..14d64b59f 100644 --- a/src/modes/world.cpp +++ b/src/modes/world.cpp @@ -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); diff --git a/src/physics/btKart.cpp b/src/physics/btKart.cpp index 6799a25b0..41e194bef 100644 --- a/src/physics/btKart.cpp +++ b/src/physics/btKart.cpp @@ -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 diff --git a/src/physics/btUprightConstraint.cpp b/src/physics/btUprightConstraint.cpp index f97009d19..305630c84 100644 --- a/src/physics/btUprightConstraint.cpp +++ b/src/physics/btUprightConstraint.cpp @@ -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 diff --git a/src/physics/btUprightConstraint.hpp b/src/physics/btUprightConstraint.hpp index b5068b19b..08e6d1490 100644 --- a/src/physics/btUprightConstraint.hpp +++ b/src/physics/btUprightConstraint.hpp @@ -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); }; diff --git a/src/physics/irr_debug_drawer.cpp b/src/physics/irr_debug_drawer.cpp index 62f880a89..e3152d8bb 100644 --- a/src/physics/irr_debug_drawer.cpp +++ b/src/physics/irr_debug_drawer.cpp @@ -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; igetKart(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; igetKart(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 */ diff --git a/src/physics/irr_debug_drawer.hpp b/src/physics/irr_debug_drawer.hpp index 07e4688a8..6a1b3c165 100644 --- a/src/physics/irr_debug_drawer.hpp +++ b/src/physics/irr_debug_drawer.hpp @@ -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 diff --git a/src/physics/physics.cpp b/src/physics/physics.cpp index 14fdb507a..8d2b02ce7 100644 --- a/src/physics/physics.cpp +++ b/src/physics/physics.cpp @@ -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; diff --git a/src/physics/physics.hpp b/src/physics/physics.hpp index 4ab0c0347..55059b802 100644 --- a/src/physics/physics.hpp +++ b/src/physics/physics.hpp @@ -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, diff --git a/src/race/history.cpp b/src/race/history.cpp index b768dd1ca..9fa6d3f7b 100644 --- a/src/race/history.cpp +++ b/src/race/history.cpp @@ -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)); diff --git a/src/states_screens/kart_selection.cpp b/src/states_screens/kart_selection.cpp index 3e475e829..ee9930343 100644 --- a/src/states_screens/kart_selection.cpp +++ b/src/states_screens/kart_selection.cpp @@ -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") ); } diff --git a/src/tracks/check_line.cpp b/src/tracks/check_line.cpp index 66f4d2792..b3c8eba65 100644 --- a/src/tracks/check_line.cpp +++ b/src/tracks/check_line.cpp @@ -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; diff --git a/src/tracks/graph_node.cpp b/src/tracks/graph_node.cpp index 745a7be5c..4b6000b48 100644 --- a/src/tracks/graph_node.cpp +++ b/src/tracks/graph_node.cpp @@ -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 diff --git a/src/tracks/quad.cpp b/src/tracks/quad.cpp index dd36bf777..37d35f566 100644 --- a/src/tracks/quad.cpp +++ b/src/tracks/quad.cpp @@ -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 diff --git a/src/tracks/quad_graph.cpp b/src/tracks/quad_graph.cpp index 0eed8c793..27c2f0082 100644 --- a/src/tracks/quad_graph.cpp +++ b/src/tracks/quad_graph.cpp @@ -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& 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 diff --git a/src/tracks/terrain_info.cpp b/src/tracks/terrain_info.cpp index eac469d9f..18e4e6a0b 100644 --- a/src/tracks/terrain_info.cpp +++ b/src/tracks/terrain_info.cpp @@ -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; diff --git a/src/tracks/track.cpp b/src/tracks/track.cpp index 09253dbb3..c2b78014b 100644 --- a/src/tracks/track.cpp +++ b/src/tracks/track.cpp @@ -166,7 +166,7 @@ btTransform Track::getStartTransform(unsigned int pos) const Vec3 orig = posaddTriangle(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 diff --git a/src/utils/coord.hpp b/src/utils/coord.hpp index 8e978b793..1fcfa5242 100644 --- a/src/utils/coord.hpp +++ b/src/utils/coord.hpp @@ -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 // ------------------------------------------------------------------------ diff --git a/src/utils/vec3.cpp b/src/utils/vec3.cpp index 57df5a5f4..585c51228 100644 --- a/src/utils/vec3.cpp +++ b/src/utils/vec3.cpp @@ -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 diff --git a/src/utils/vec3.hpp b/src/utils/vec3.hpp index 3f5eb08da..c9e0928c5 100644 --- a/src/utils/vec3.hpp +++ b/src/utils/vec3.hpp @@ -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();