Starting the merge with the swatter branch. Now it should be automatic with karts, but doesn't work with items (yet).
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@9275 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
747489c917
commit
d26b406780
Binary file not shown.
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 8.8 KiB |
Binary file not shown.
BIN
data/models/swatter.png
Normal file
BIN
data/models/swatter.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 42 KiB |
63
data/shaders/skinning.vert
Normal file
63
data/shaders/skinning.vert
Normal file
@ -0,0 +1,63 @@
|
||||
// skinning.vert
|
||||
|
||||
#define MAX_JOINT_NUM 36
|
||||
#define MAX_LIGHT_NUM 8
|
||||
|
||||
uniform mat4 JointTransform[MAX_JOINT_NUM];
|
||||
|
||||
void main()
|
||||
{
|
||||
int index;
|
||||
vec4 ecPos;
|
||||
vec3 normal;
|
||||
vec3 light_dir;
|
||||
float n_dot_l;
|
||||
float dist;
|
||||
|
||||
mat4 ModelTransform = gl_ModelViewProjectionMatrix;
|
||||
|
||||
index = int(gl_Color.r * 255.99);
|
||||
mat4 vertTran = JointTransform[index - 1];
|
||||
|
||||
index = int(gl_Color.g * 255.99);
|
||||
if(index > 0)
|
||||
vertTran += JointTransform[index - 1];
|
||||
|
||||
index = int(gl_Color.b * 255.99);
|
||||
if(index > 0)
|
||||
vertTran += JointTransform[index - 1];
|
||||
|
||||
index = int(gl_Color.a * 255.99);
|
||||
if(index > 0)
|
||||
vertTran += JointTransform[index - 1];
|
||||
|
||||
ecPos = gl_ModelViewMatrix * vertTran * gl_Vertex;
|
||||
|
||||
normal = normalize(gl_NormalMatrix * mat3(vertTran) * gl_Normal);
|
||||
|
||||
gl_FrontColor = vec4(0,0,0,0);
|
||||
for(int i = 0;i < MAX_LIGHT_NUM;i++)
|
||||
{
|
||||
light_dir = vec3(gl_LightSource[i].position-ecPos);
|
||||
n_dot_l = max(dot(normal, normalize(light_dir)), 0.0);
|
||||
dist = length(light_dir);
|
||||
n_dot_l *= 1.0 / (gl_LightSource[0].constantAttenuation + gl_LightSource[0].linearAttenuation * dist);
|
||||
gl_FrontColor += gl_LightSource[i].diffuse * n_dot_l;
|
||||
}
|
||||
gl_FrontColor = clamp(gl_FrontColor,0.3,1.0);
|
||||
|
||||
|
||||
ModelTransform *= vertTran;
|
||||
|
||||
gl_Position = ModelTransform * gl_Vertex;
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
gl_TexCoord[1] = gl_MultiTexCoord1;
|
||||
|
||||
/*
|
||||
// Reflections.
|
||||
vec3 r = reflect( ecPos.xyz , normal );
|
||||
float m = 2.0 * sqrt( r.x*r.x + r.y*r.y + (r.z+1.0)*(r.z+1.0) );
|
||||
gl_TexCoord[1].s = r.x/m + 0.5;
|
||||
gl_TexCoord[1].t = r.y/m + 0.5;
|
||||
*/
|
||||
}
|
@ -177,17 +177,12 @@
|
||||
max-speed-increase="5" duration="1" fade-out-time="2"/>
|
||||
|
||||
<!-- Kart-specific settings for the swatter:
|
||||
duration: how long can the swatter be readied.
|
||||
count: how often can it be used.
|
||||
distance: How close a kart must be before it can be hit.
|
||||
animation-time: How long it takes for the swatter to hit a target.
|
||||
item-animation-time: How long the swatter will swat when a
|
||||
projectile hits.
|
||||
duration: how long can the swatter be active.
|
||||
distance: How close a kart or an item must be before it can be hit.
|
||||
squash-duration: How long a kart will remain squashed.
|
||||
squash-slowdown: percentage of max speed that a kart is
|
||||
restricted to. -->
|
||||
<swatter duration="10" count="2" distance="3" animation-time="0.2"
|
||||
item-animation-time="0.04" squash-duration="5"
|
||||
<swatter duration="10" distance="3" squash-duration="5"
|
||||
squash-slowdown="0.5"/>
|
||||
|
||||
<!-- min-speed-radius and max-speed-radius define the smallest turn
|
||||
|
@ -385,7 +385,7 @@ namespace UserConfigParams
|
||||
PARAM_PREFIX bool m_profiler_enabled PARAM_DEFAULT( false );
|
||||
|
||||
/** True if hardware skinning should be enabled */
|
||||
PARAM_PREFIX bool m_hw_skinning_enabled PARAM_DEFAULT( true );
|
||||
PARAM_PREFIX bool m_hw_skinning_enabled PARAM_DEFAULT( false );
|
||||
|
||||
// not saved to file
|
||||
|
||||
|
@ -26,8 +26,6 @@
|
||||
|
||||
void HardwareSkinning::prepareNode(scene::IAnimatedMeshSceneNode *node)
|
||||
{
|
||||
return; // BOUM
|
||||
|
||||
scene::IAnimatedMesh* mesh = node->getMesh();
|
||||
video::IVideoDriver* driver = irr_driver->getVideoDriver();
|
||||
video::IGPUProgrammingServices* gpu = driver->getGPUProgrammingServices();
|
||||
@ -56,7 +54,7 @@ void HardwareSkinning::prepareNode(scene::IAnimatedMeshSceneNode *node)
|
||||
|
||||
// Use VBOs and avoid streaming the vertex data
|
||||
//mesh->setHardwareMappingHint(scene::EHM_STATIC);
|
||||
mesh->setHardwareMappingHint(scene::EHM_DYNAMIC); // BOUM
|
||||
mesh->setHardwareMappingHint(scene::EHM_DYNAMIC); // TODO: is it really better?
|
||||
|
||||
// Hardware skinning is not implemented in Irrlicht (as of version 1.7.2) so "enabling" it
|
||||
// results in the data not being sent and the CPU not computing software skinning.
|
||||
|
@ -21,7 +21,7 @@
|
||||
|
||||
#include "config/user_config.hpp"
|
||||
#include "graphics/camera.hpp"
|
||||
#include "graphics/hardware_skinning.hpp" // BOUM
|
||||
#include "graphics/hardware_skinning.hpp"
|
||||
#include "graphics/material_manager.hpp"
|
||||
#include "graphics/particle_kind_manager.hpp"
|
||||
#include "graphics/per_camera_node.hpp"
|
||||
@ -1244,10 +1244,7 @@ void IrrDriver::update(float dt)
|
||||
|
||||
kart->getCamera()->activate();
|
||||
|
||||
// BEGIN BOUM
|
||||
m_scene_manager->drawAll();
|
||||
//m_scene_manager->drawAll();
|
||||
// END BOUM
|
||||
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
|
||||
|
@ -18,8 +18,8 @@
|
||||
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "graphics/lod_node.hpp"
|
||||
#include "graphics/hardware_skinning.hpp" // BOUM
|
||||
#include "config/user_config.hpp" // BOUM
|
||||
#include "graphics/hardware_skinning.hpp"
|
||||
#include "config/user_config.hpp"
|
||||
|
||||
#include <ISceneManager.h>
|
||||
#include <ICameraSceneNode.h>
|
||||
@ -94,7 +94,6 @@ void LODNode::add(int level, scene::ISceneNode* node, bool reparent)
|
||||
|
||||
assert(node != NULL);
|
||||
|
||||
// BOUM Funto: why grab(), then remove(), then drop()...??
|
||||
node->grab();
|
||||
node->remove();
|
||||
m_detail.push_back(level*level);
|
||||
@ -102,10 +101,8 @@ void LODNode::add(int level, scene::ISceneNode* node, bool reparent)
|
||||
m_nodes_set.insert(node);
|
||||
node->setParent(this);
|
||||
|
||||
// BEGIN BOUM
|
||||
if(UserConfigParams::m_hw_skinning_enabled && node->getType() == scene::ESNT_ANIMATED_MESH)
|
||||
HardwareSkinning::prepareNode((scene::IAnimatedMeshSceneNode*)node);
|
||||
// END BOUM
|
||||
|
||||
node->drop();
|
||||
}
|
||||
|
@ -113,9 +113,6 @@ void MaterialManager::adjustForFog(video::ITexture* t,
|
||||
|
||||
void MaterialManager::setAllUntexturedMaterialFlags(scene::IMeshBuffer *mb) const
|
||||
{
|
||||
// BEGIN BOUM
|
||||
// for(int i = (int)m_materials.size()-1; i>=0; i-- )
|
||||
// {
|
||||
irr::video::SMaterial& material = mb->getMaterial();
|
||||
if (material.getTexture(0) == NULL)
|
||||
{
|
||||
@ -127,8 +124,6 @@ void MaterialManager::setAllUntexturedMaterialFlags(scene::IMeshBuffer *mb) cons
|
||||
material.ColorMaterial = irr::video::ECM_DIFFUSE_AND_AMBIENT;
|
||||
material.MaterialType = irr::video::EMT_SOLID;
|
||||
}
|
||||
// } // for i
|
||||
// END BOUM
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
int MaterialManager::addEntity(Material *m)
|
||||
|
@ -48,6 +48,7 @@ Attachment::Attachment(Kart* kart)
|
||||
std::string debug_name = kart->getIdent()+" (attachment)";
|
||||
m_node->setName(debug_name.c_str());
|
||||
#endif
|
||||
m_node->setAnimationEndCallback(this);
|
||||
m_node->setParent(m_kart->getNode());
|
||||
m_node->setVisible(false);
|
||||
} // Attachment
|
||||
@ -64,12 +65,14 @@ void Attachment::set(AttachmentType type, float time, Kart *current_kart)
|
||||
{
|
||||
clear();
|
||||
|
||||
// If necessary create the appropriate plugin which encapsulates
|
||||
// If necessary create the appropriate plugin which encapsulates the associated behavior
|
||||
switch(type)
|
||||
{
|
||||
case ATTACH_SWATTER :
|
||||
m_plugin = new Swatter(this, m_kart);
|
||||
default: break;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
} // switch(type)
|
||||
|
||||
m_node->setMesh(attachment_manager->getMesh(type));
|
||||
@ -84,9 +87,6 @@ void Attachment::set(AttachmentType type, float time, Kart *current_kart)
|
||||
m_time_left = time;
|
||||
m_previous_owner = current_kart;
|
||||
m_node->setRotation(core::vector3df(0, 0, 0));
|
||||
m_count = m_type==ATTACH_SWATTER
|
||||
? m_kart->getKartProperties()->getSwatterCount()
|
||||
: 1;
|
||||
|
||||
// A parachute can be attached as result of the usage of an item. In this
|
||||
// case we have to save the current kart speed so that it can be detached
|
||||
@ -123,6 +123,8 @@ void Attachment::clear()
|
||||
|
||||
m_time_left=0.0;
|
||||
m_node->setVisible(false);
|
||||
m_node->setPosition(core::vector3df());
|
||||
m_node->setRotation(core::vector3df());
|
||||
|
||||
// Resets the weight of the kart if the previous attachment affected it
|
||||
// (e.g. anvil). This must be done *after* setting m_type to
|
||||
@ -253,7 +255,6 @@ void Attachment::update(float dt)
|
||||
clear(); // also removes the plugin
|
||||
return;
|
||||
}
|
||||
m_node->setRotation(m_plugin->getRotation());
|
||||
}
|
||||
|
||||
switch (m_type)
|
||||
@ -303,20 +304,9 @@ void Attachment::update(float dt)
|
||||
} // update
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Uses the swatter to swat at an item. The actual functionality is
|
||||
* implemented in the swatter plugin.
|
||||
* \pre The item must be an attachment (and m_plugin must be a swatter).
|
||||
*/
|
||||
void Attachment::swatItem()
|
||||
/** Inform any eventual plugin when an animation is done. */
|
||||
void Attachment::OnAnimationEnd(scene::IAnimatedMeshSceneNode* node)
|
||||
{
|
||||
assert(m_type==ATTACH_SWATTER);
|
||||
((Swatter*)m_plugin)->swatItem();
|
||||
} // swatItem
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Returns if the swatter is currently aiming, i.e. can be used to
|
||||
* swat an incoming projectile. */
|
||||
bool Attachment::isSwatterReady() const
|
||||
{
|
||||
assert(m_type==ATTACH_SWATTER);
|
||||
return ((Swatter*)m_plugin)->isSwatterReady();
|
||||
} // isSwatterReady
|
||||
if(m_plugin)
|
||||
m_plugin->onAnimationEnd();
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ class Item;
|
||||
* a scene node).
|
||||
* \ingroup items
|
||||
*/
|
||||
class Attachment: public NoCopy
|
||||
class Attachment: public NoCopy, public scene::IAnimationEndCallBack
|
||||
{
|
||||
public:
|
||||
// Some loop in attachment.cpp depend on ATTACH_FIRST and ATTACH_MAX.
|
||||
@ -66,9 +66,6 @@ private:
|
||||
/** Kart the attachment is attached to. */
|
||||
Kart *m_kart;
|
||||
|
||||
/** How often an attachment can be used (e.g. swatter). */
|
||||
int m_count;
|
||||
|
||||
/** Time left till attachment expires. */
|
||||
float m_time_left;
|
||||
|
||||
@ -97,8 +94,6 @@ public:
|
||||
void hitBanana(Item *item, int new_attachment=-1);
|
||||
void update (float dt);
|
||||
void moveBombFromTo(Kart *from, Kart *to);
|
||||
void swatItem();
|
||||
bool isSwatterReady() const;
|
||||
|
||||
void set (AttachmentType type, float time, Kart *previous_kart=NULL);
|
||||
// ------------------------------------------------------------------------
|
||||
@ -122,6 +117,11 @@ public:
|
||||
float weightAdjust() const {
|
||||
return m_type==ATTACH_ANVIL ? stk_config->m_anvil_weight : 0.0f; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Return the currently associated scene node (used by e.g the swatter) */
|
||||
scene::IAnimatedMeshSceneNode* getNode() {return m_node;}
|
||||
// ------------------------------------------------------------------------
|
||||
/** Implement IAnimatedMeshSceneNode */
|
||||
virtual void OnAnimationEnd(scene::IAnimatedMeshSceneNode* node);
|
||||
}; // Attachment
|
||||
|
||||
#endif
|
||||
|
@ -38,15 +38,18 @@ class Attachment;
|
||||
class AttachmentPlugin
|
||||
{
|
||||
protected:
|
||||
/** Keeps track of the rotation of an attachment, this base class
|
||||
* will set it to 0. */
|
||||
core::vector3df m_rotation;
|
||||
/** Parent Attachment of this plugin */
|
||||
Attachment *m_attachment;
|
||||
|
||||
/** Kart the attachment is attached to. */
|
||||
Kart *m_kart;
|
||||
|
||||
public:
|
||||
/** Constructor for a plugin. */
|
||||
AttachmentPlugin(Attachment *attachment, Kart *kart)
|
||||
{
|
||||
m_rotation = core::vector3df(0,0,0);
|
||||
m_attachment = attachment;
|
||||
m_kart = kart;
|
||||
}
|
||||
|
||||
virtual ~AttachmentPlugin() {}
|
||||
@ -57,8 +60,8 @@ public:
|
||||
virtual bool updateAndTestFinished(float dt) = 0;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the rotation of the attachment. */
|
||||
virtual const core::vector3df& getRotation() const { return m_rotation; }
|
||||
/** Called when the animation of the Attachment's node is done. */
|
||||
virtual void onAnimationEnd() {}
|
||||
}; // AttachmentPlugin
|
||||
|
||||
#endif
|
||||
|
@ -17,24 +17,36 @@
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
// TODO: be able to squash karts
|
||||
// TODO: use a proportional corrector for avoiding brutal movements
|
||||
// TODO: make the swatter (and other items) appear and disappear progressively
|
||||
// TODO: remove the maximum number of squashes
|
||||
// TODO: add a swatter music
|
||||
// TODO: be able to squash items
|
||||
// TODO: move some constants to KartProperties, use all constants from KartProperties
|
||||
|
||||
#include "items/swatter.hpp"
|
||||
|
||||
#include "items/attachment.hpp"
|
||||
#include "modes/world.hpp"
|
||||
#include "karts/kart.hpp"
|
||||
|
||||
#define SWAT_ANGLE 22.0f
|
||||
#define SWAT_POS_OFFSET core::vector3df(0.0, 0.2, -0.4)
|
||||
#define SWAT_ANGLE_MIN 45
|
||||
#define SWAT_ANGLE_MAX 135
|
||||
#define SWAT_ANGLE_OFFSET (90.0f + 15.0f)
|
||||
#define SWATTER_ANIMATION_SPEED 100.0f
|
||||
|
||||
Swatter::Swatter(Attachment *attachment, Kart *kart)
|
||||
: AttachmentPlugin(attachment, kart)
|
||||
{
|
||||
m_kart = kart;
|
||||
m_count = kart->getKartProperties()->getSwatterCount();
|
||||
m_animation_timer = 0.0f;
|
||||
m_animation_phase = SWATTER_AIMING;
|
||||
m_rot_per_sec = core::vector3df(0,0,0);
|
||||
m_rotation = core::vector3df(0,0,0);
|
||||
m_animation_target = NULL;
|
||||
m_target = NULL;
|
||||
|
||||
// Setup the node
|
||||
scene::IAnimatedMeshSceneNode* node = m_attachment->getNode();
|
||||
node->setPosition(SWAT_POS_OFFSET);
|
||||
node->setAnimationSpeed(0);
|
||||
} // Swatter
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -50,181 +62,137 @@ Swatter::~Swatter()
|
||||
*/
|
||||
bool Swatter::updateAndTestFinished(float dt)
|
||||
{
|
||||
m_rotation += m_rot_per_sec * dt;
|
||||
switch(m_animation_phase)
|
||||
{
|
||||
case SWATTER_AIMING:
|
||||
aimSwatter();
|
||||
break;
|
||||
case SWATTER_TO_KART:
|
||||
if(fabsf(m_rotation.Z)>=90)
|
||||
{
|
||||
checkForHitKart(m_rotation.Z>0);
|
||||
m_rot_per_sec *= -1.0f;
|
||||
m_animation_phase = SWATTER_BACK_FROM_KART;
|
||||
}
|
||||
break;
|
||||
case SWATTER_BACK_FROM_KART:
|
||||
if (m_rotation.Z>0)
|
||||
{
|
||||
m_rotation = core::vector3df(0,0,0);
|
||||
m_rot_per_sec = core::vector3df(0,0,0);
|
||||
m_animation_phase = SWATTER_AIMING;
|
||||
m_animation_target = NULL;
|
||||
}
|
||||
break;
|
||||
case SWATTER_ITEM_1: // swatter going to the left
|
||||
if(m_rotation.Z>SWAT_ANGLE)
|
||||
{
|
||||
m_animation_phase = SWATTER_ITEM_2;
|
||||
m_rot_per_sec *= -1.0f;
|
||||
}
|
||||
break;
|
||||
case SWATTER_ITEM_2: // swatter going all the way to the right
|
||||
if(m_rotation.Z<-SWAT_ANGLE)
|
||||
{
|
||||
m_animation_phase = SWATTER_ITEM_3;
|
||||
m_rot_per_sec *= -1.0f;
|
||||
}
|
||||
break;
|
||||
case SWATTER_ITEM_3: // swatter going back to rest position.
|
||||
if(m_rotation.Z>0)
|
||||
{
|
||||
m_rotation = core::vector3df(0,0,0);
|
||||
m_rot_per_sec = core::vector3df(0,0,0);
|
||||
m_animation_phase = SWATTER_AIMING;
|
||||
}
|
||||
break;
|
||||
} // switch m_animation_phase
|
||||
chooseTarget();
|
||||
pointToTarget();
|
||||
|
||||
if(!m_target)
|
||||
break;
|
||||
|
||||
// Is the target too near?
|
||||
float dist_to_target2 = (m_target->getXYZ() - m_attachment->getNode()->getAbsolutePosition()).length2();
|
||||
float min_dist2 = m_kart->getKartProperties()->getSwatterDistance2();
|
||||
if(dist_to_target2 < min_dist2)
|
||||
{
|
||||
// Start squashing
|
||||
m_animation_phase = SWATTER_TO_TARGET;
|
||||
|
||||
// Setup the animation
|
||||
scene::IAnimatedMeshSceneNode* node = m_attachment->getNode();
|
||||
node->setCurrentFrame(0.0f);
|
||||
node->setLoopMode(false);
|
||||
node->setAnimationSpeed(SWATTER_ANIMATION_SPEED);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SWATTER_TO_TARGET:
|
||||
{
|
||||
pointToTarget();
|
||||
|
||||
scene::IAnimatedMeshSceneNode *node = m_attachment->getNode();
|
||||
const float middle_frame = node->getEndFrame()/2.0f;
|
||||
float current_frame = node->getFrameNr();
|
||||
|
||||
// Did we just finish the first part of the movement?
|
||||
if(current_frame >= middle_frame)
|
||||
{
|
||||
// Squash the karts and items around and change the current phase
|
||||
squashThingsAround();
|
||||
m_animation_phase = SWATTER_FROM_TARGET;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SWATTER_FROM_TARGET:
|
||||
break;
|
||||
}
|
||||
|
||||
// If the swatter is used up, trigger cleaning up
|
||||
return (m_count==0);
|
||||
// TODO: use a timeout
|
||||
// TODO: how does it work currently...?
|
||||
return false;
|
||||
} // updateAndTestFinished
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Returns true if the point xyz is to the left of the kart.
|
||||
* \param xyz Point to determine the direction
|
||||
*/
|
||||
bool Swatter::isLeftSideOfKart(const Vec3 &xyz)
|
||||
/** When the animation ends, the swatter is ready again */
|
||||
void Swatter::onAnimationEnd()
|
||||
{
|
||||
Vec3 forw_vec = m_kart->getTrans().getBasis().getColumn(2);
|
||||
const Vec3& k1 = m_kart->getXYZ();
|
||||
const Vec3 k2 = k1+forw_vec;
|
||||
return xyz.sideOfLine2D(k1, k2)>0;
|
||||
} // isLeftSideOfKart
|
||||
m_animation_phase = SWATTER_AIMING;
|
||||
} // onAnimationEnd
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** This function is called when the swatter reaches the hit angle (i.e. it
|
||||
* is furthest down). Check all karts if any one is hit, i.e. is at the right
|
||||
* side and at the right angle and distance.
|
||||
* \param isWattingLeft True if the swatter is aiming to the left side
|
||||
* of the kart.
|
||||
*/
|
||||
void Swatter::checkForHitKart(bool isSwattingLeft)
|
||||
/** Determine the nearest kart or item and update the current target accordingly */
|
||||
void Swatter::chooseTarget()
|
||||
{
|
||||
// Square of the minimum distance
|
||||
const KartProperties *kp = m_kart->getKartProperties();
|
||||
float min_dist2 = kp->getSwatterDistance2();
|
||||
Kart *hit_kart = NULL;
|
||||
Vec3 forw_vec = m_kart->getTrans().getBasis().getColumn(2);
|
||||
// TODO: for the moment, only handle karts...
|
||||
const World *world = World::getWorld();
|
||||
Kart *closest_kart = NULL;
|
||||
float min_dist2 = FLT_MAX;
|
||||
|
||||
for(unsigned int i=0; i<world->getNumKarts(); i++)
|
||||
{
|
||||
Kart *kart = world->getKart(i);
|
||||
// TODO: isSwatterReady(), isSquashable()?
|
||||
if(kart->isEliminated() || kart==m_kart || kart->isSquashed())
|
||||
continue;
|
||||
float f = (kart->getXYZ()-m_kart->getXYZ()).length2();
|
||||
|
||||
// Distance is too great, ignore this kart.
|
||||
if(f>min_dist2) continue;
|
||||
|
||||
// Check if the kart is at the right side.
|
||||
const bool left = isLeftSideOfKart(kart->getXYZ());
|
||||
if(left!=isSwattingLeft)
|
||||
float dist2 = (kart->getXYZ()-m_kart->getXYZ()).length2();
|
||||
if(dist2<min_dist2)
|
||||
{
|
||||
//printf("%s wrong side: %d %d\n",
|
||||
// kart->getIdent().c_str(), left, isSwattingLeft);
|
||||
continue;
|
||||
min_dist2 = dist2;
|
||||
closest_kart = kart;
|
||||
}
|
||||
}
|
||||
m_target = closest_kart; // may be NULL
|
||||
}
|
||||
|
||||
Vec3 kart_vec = m_kart->getXYZ()-kart->getXYZ();
|
||||
// cos alpha = a*b/||a||/||b||
|
||||
// Since forw_vec is a unit vector, we only have to divide by
|
||||
// the length of the vector to the kart.
|
||||
float cos_angle = kart_vec.dot(forw_vec)/kart_vec.length();
|
||||
float angle = acosf(cos_angle)*180/M_PI;
|
||||
if(angle<45 || angle>135)
|
||||
/** If there is a current target, point in its direction, otherwise adopt the default position */
|
||||
void Swatter::pointToTarget()
|
||||
{
|
||||
//printf("%s angle %f\n", kart->getIdent().c_str(), angle);
|
||||
continue;
|
||||
if(!m_target)
|
||||
{
|
||||
m_attachment->getNode()->setRotation(core::vector3df());
|
||||
}
|
||||
else
|
||||
{
|
||||
Vec3 swatter_to_target = m_target->getXYZ() - m_attachment->getNode()->getAbsolutePosition();
|
||||
float dy = -swatter_to_target.getZ();
|
||||
float dx = swatter_to_target.getX();
|
||||
float angle = SWAT_ANGLE_OFFSET + (atan2(dy, dx) - m_kart->getHeading()) * 180.0f/M_PI;
|
||||
|
||||
m_attachment->getNode()->setRotation(core::vector3df(0.0, angle, 0.0));
|
||||
}
|
||||
}
|
||||
|
||||
/** Squash karts or items that are around the end position (determined using a joint) of the swatter */
|
||||
void Swatter::squashThingsAround()
|
||||
{
|
||||
const KartProperties* kp = m_kart->getKartProperties();
|
||||
float min_dist2 = kp->getSwatterDistance2(); // Square of the minimum distance
|
||||
const World* world = World::getWorld();
|
||||
scene::IAnimatedMeshSceneNode *node = m_attachment->getNode();
|
||||
|
||||
// Get the node corresponding to the joint at the center of the swatter (by swatter, I mean
|
||||
// the thing hold in the hand, not the whole thing)
|
||||
scene::ISceneNode* swatter_node = node->getJointNode("Swatter");
|
||||
assert(swatter_node);
|
||||
Vec3 swatter_pos = swatter_node->getAbsolutePosition();
|
||||
|
||||
// Squash karts around
|
||||
for(unsigned int i=0; i<world->getNumKarts(); i++)
|
||||
{
|
||||
Kart *kart = world->getKart(i);
|
||||
// TODO: isSwatterReady()
|
||||
if(kart->isEliminated() || kart==m_kart || kart->isSquashed())
|
||||
continue;
|
||||
float dist2 = (kart->getXYZ()-swatter_pos).length2();
|
||||
|
||||
if(dist2 < min_dist2)
|
||||
{
|
||||
kart->setSquash(kp->getSquashDuration(),
|
||||
kp->getSquashSlowdown());
|
||||
// It is assumed that only one kart is within reach of the swatter,
|
||||
// so we can stop testing karts here.
|
||||
return;
|
||||
} // for i < num_karts
|
||||
|
||||
} // angleToKart
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Checks for any kart that is not already squashed that is close enough.
|
||||
* If a kart is found, it changes the state of the swatter to be
|
||||
* SWATTER_TARGET and starts the animation.
|
||||
*/
|
||||
void Swatter::aimSwatter()
|
||||
{
|
||||
const World *world = World::getWorld();
|
||||
Kart *min_kart = NULL;
|
||||
// Square of the minimum distance
|
||||
float min_dist2 = m_kart->getKartProperties()->getSwatterDistance2();
|
||||
|
||||
for(unsigned int i=0; i<world->getNumKarts(); i++)
|
||||
{
|
||||
Kart *kart = world->getKart(i);
|
||||
if(kart->isEliminated() || kart==m_kart || kart->isSquashed())
|
||||
continue;
|
||||
float f = (kart->getXYZ()-m_kart->getXYZ()).length2();
|
||||
if(f<min_dist2)
|
||||
{
|
||||
min_dist2 = f;
|
||||
min_kart = kart;
|
||||
}
|
||||
}
|
||||
// No kart close enough, nothing to do.
|
||||
if(!min_kart) return;
|
||||
|
||||
m_count --;
|
||||
m_animation_phase = SWATTER_TO_KART;
|
||||
m_animation_target = min_kart;
|
||||
if(UserConfigParams::logMisc())
|
||||
printf("[swatter] %s aiming at %s.\n",
|
||||
m_kart->getIdent().c_str(), min_kart->getIdent().c_str());
|
||||
const KartProperties *kp = m_kart->getKartProperties();
|
||||
m_animation_timer = kp->getSwatterAnimationTime();
|
||||
const bool left = isLeftSideOfKart(min_kart->getXYZ());
|
||||
m_rot_per_sec = core::vector3df(0, 0,
|
||||
left ?90.0f:-90.0f) / m_animation_timer;
|
||||
|
||||
} // aimSwatter
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Starts a (smaller) and faster swatting movement to be played
|
||||
* when the kart is hit by an item.
|
||||
*/
|
||||
void Swatter::swatItem()
|
||||
{
|
||||
if(UserConfigParams::logMisc())
|
||||
printf("[swatter] %s swatting item.\n",
|
||||
m_kart->getIdent().c_str());
|
||||
assert(m_animation_target==NULL);
|
||||
|
||||
m_animation_phase = SWATTER_ITEM_1;
|
||||
m_animation_timer =
|
||||
m_kart->getKartProperties()->getSwatterItemAnimationTime();
|
||||
m_count--;
|
||||
m_rot_per_sec = core::vector3df(0, 0, SWAT_ANGLE) / m_animation_timer;
|
||||
} // swatItem
|
||||
// TODO: squash items
|
||||
}
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
#include "config/stk_config.hpp"
|
||||
#include "items/attachment_plugin.hpp"
|
||||
#include "karts/moveable.hpp"
|
||||
#include "utils/no_copy.hpp"
|
||||
#include "utils/random_generator.hpp"
|
||||
|
||||
@ -38,41 +39,21 @@ class Swatter : public NoCopy, public AttachmentPlugin
|
||||
{
|
||||
|
||||
private:
|
||||
/** Kart the attachment is attached to. */
|
||||
Kart *m_kart;
|
||||
|
||||
/** How often an attachment can be used (e.g. swatter). */
|
||||
int m_count;
|
||||
|
||||
/** State of a swatter animation. The swatter is either aiming (looking
|
||||
* for a kart and/or swatting an incoming item), moving towards or back
|
||||
* from a kart, or swatting left and right to hit an item - which has
|
||||
* three phases: going left to an angle a (phae 1), then going to -a
|
||||
* (phase 2), then going back to 0. */
|
||||
enum {SWATTER_AIMING, SWATTER_TO_KART,
|
||||
SWATTER_BACK_FROM_KART,
|
||||
SWATTER_ITEM_1, SWATTER_ITEM_2, SWATTER_ITEM_3,
|
||||
SWATTER_BACK_FROM_ITEM} m_animation_phase;
|
||||
|
||||
/** Timer for swatter animation. */
|
||||
float m_animation_timer;
|
||||
/** State of the animation: the swatter is successively:
|
||||
- aiming (default state) => it's turning to the nearest target
|
||||
- going down to the target
|
||||
- going up from the target
|
||||
*/
|
||||
enum {SWATTER_AIMING, SWATTER_TO_TARGET, SWATTER_FROM_TARGET}
|
||||
m_animation_phase;
|
||||
|
||||
/** The kart the swatter is aiming at. */
|
||||
Kart *m_animation_target;
|
||||
|
||||
/** Rotation per second so that the swatter will hit the kart. */
|
||||
core::vector3df m_rot_per_sec;
|
||||
|
||||
void aimSwatter();
|
||||
bool isLeftSideOfKart(const Vec3 &xyz);
|
||||
void checkForHitKart(bool isSwattingToLeft);
|
||||
Moveable *m_target;
|
||||
|
||||
public:
|
||||
Swatter(Attachment *attachment, Kart *kart);
|
||||
virtual ~Swatter();
|
||||
bool updateAndTestFinished(float dt);
|
||||
void updateSwatter(float dt);
|
||||
void swatItem();
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns if the swatter is currently aiming, i.e. can be used to
|
||||
@ -81,6 +62,18 @@ public:
|
||||
return m_animation_phase == SWATTER_AIMING;
|
||||
} // isSwatterReady
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void onAnimationEnd();
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
private:
|
||||
/** Determine the nearest kart or item and update the current target accordingly */
|
||||
void chooseTarget();
|
||||
|
||||
/** If there is a current target, point to it, otherwise adopt the default position */
|
||||
void pointToTarget();
|
||||
|
||||
/** Squash karts or items that are around the end position (determined using a joint) of the swatter */
|
||||
void squashThingsAround();
|
||||
}; // Swatter
|
||||
|
||||
#endif
|
||||
|
@ -134,16 +134,21 @@ void EmergencyAnimation::forceRescue(bool is_auto_rescue)
|
||||
void EmergencyAnimation::handleExplosion(const Vec3 &pos, bool direct_hit)
|
||||
{
|
||||
// Avoid doing another explosion while a kart is thrown around in the air.
|
||||
if(playingEmergencyAnimation()) return;
|
||||
if(playingEmergencyAnimation())
|
||||
return;
|
||||
|
||||
if(m_kart->isInvulnerable())
|
||||
return;
|
||||
Attachment *a=m_kart->getAttachment();
|
||||
|
||||
// !Funto! TODO: squash items with the swatter...should we do it here or in the Swatter class?
|
||||
/* Attachment *a=m_kart->getAttachment();
|
||||
if(a->getType()==Attachment::ATTACH_SWATTER &&
|
||||
a->isSwatterReady())
|
||||
{
|
||||
a->swatItem();
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
m_xyz = m_kart->getXYZ();
|
||||
// Ignore explosion that are too far away.
|
||||
|
@ -91,13 +91,11 @@ KartProperties::KartProperties(const std::string &filename)
|
||||
m_camera_backward_up_angle = m_explosion_invulnerability_time =
|
||||
m_rescue_time = m_rescue_height = m_explosion_time =
|
||||
m_explosion_radius = m_ai_steering_variation =
|
||||
m_swatter_distance2 = m_swatter_duration = m_swatter_animation_time =
|
||||
m_swatter_item_animation_time = m_squash_slowdown =
|
||||
m_swatter_distance2 = m_swatter_duration = m_squash_slowdown =
|
||||
m_squash_duration = UNDEFINED;
|
||||
|
||||
m_gravity_center_shift = Vec3(UNDEFINED);
|
||||
m_has_skidmarks = true;
|
||||
m_swatter_count = -1;
|
||||
m_version = 0;
|
||||
m_color = video::SColor(255, 0, 0, 0);
|
||||
m_shape = 32; // close enough to a circle.
|
||||
@ -452,10 +450,6 @@ void KartProperties::getAllData(const XMLNode * root)
|
||||
if(const XMLNode *swatter_node= root->getNode("swatter"))
|
||||
{
|
||||
swatter_node->get("duration", &m_swatter_duration );
|
||||
swatter_node->get("count", &m_swatter_count );
|
||||
swatter_node->get("animation-time", &m_swatter_animation_time);
|
||||
swatter_node->get("item-animation-time",
|
||||
&m_swatter_item_animation_time);
|
||||
swatter_node->get("squash-duration", &m_squash_duration );
|
||||
swatter_node->get("squash-slowdown", &m_squash_slowdown );
|
||||
if(swatter_node->get("distance", &m_swatter_distance2) )
|
||||
@ -626,12 +620,9 @@ void KartProperties::checkAllSet(const std::string &filename)
|
||||
CHECK_NEG(m_nitro_duration, "nitro duration" );
|
||||
CHECK_NEG(m_nitro_fade_out_time, "nitro fade-out-time" );
|
||||
CHECK_NEG(m_swatter_distance2, "swatter distance" );
|
||||
CHECK_NEG(m_swatter_animation_time, "swatter animation-time" );
|
||||
CHECK_NEG(m_swatter_item_animation_time,"swatter item-animation-time" );
|
||||
CHECK_NEG(m_swatter_duration, "swatter duration" );
|
||||
CHECK_NEG(m_swatter_count, "swatter count" );
|
||||
CHECK_NEG(m_squash_duration, "swatter squash-duration" );
|
||||
CHECK_NEG(m_squash_slowdown, "swatter squash-slowdown" );
|
||||
CHECK_NEG(m_squash_duration, "squash-duration" );
|
||||
CHECK_NEG(m_squash_slowdown, "squash-slowdown" );
|
||||
|
||||
CHECK_NEG(m_rescue_height, "rescue height" );
|
||||
CHECK_NEG(m_rescue_time, "rescue time" );
|
||||
|
@ -201,8 +201,6 @@ private:
|
||||
float m_nitro_fade_out_time;
|
||||
/** Square of the maximum distance a swatter can operate. */
|
||||
float m_swatter_distance2;
|
||||
/** How often the swatter can be fired. */
|
||||
int m_swatter_count;
|
||||
/** How long the swatter lasts. */
|
||||
float m_swatter_duration;
|
||||
/** How long a kart will remain squashed. */
|
||||
@ -210,10 +208,6 @@ private:
|
||||
/** The slowdown to apply while a kart is squashed. The new maxspeed
|
||||
* is max_speed*m_squash_slowdown. */
|
||||
float m_squash_slowdown;
|
||||
/** Animation time for the swatter. */
|
||||
float m_swatter_animation_time;
|
||||
/** How long the item swatting animation will last. */
|
||||
float m_swatter_item_animation_time;
|
||||
|
||||
/** Engine sound effect. */
|
||||
std::string m_engine_sfx_type;
|
||||
@ -632,9 +626,6 @@ public:
|
||||
* can hit karts. */
|
||||
float getSwatterDistance2() const { return m_swatter_distance2; }
|
||||
|
||||
/** Returns how often a swatter can be used. */
|
||||
int getSwatterCount() const { return m_swatter_count; }
|
||||
|
||||
/** Returns how long a swatter will stay attached/ready to be used. */
|
||||
float getSwatterDuration() const { return m_swatter_duration; }
|
||||
|
||||
@ -644,12 +635,6 @@ public:
|
||||
/** Returns the slowdown of a kart that is squashed. */
|
||||
float getSquashSlowdown() const {return m_squash_slowdown; }
|
||||
|
||||
/** Returns how long it takes for the swatter to hit a target. */
|
||||
float getSwatterAnimationTime() const { return m_swatter_animation_time; }
|
||||
|
||||
/** Returns how long it takes for the swatter to swat at an item. */
|
||||
float getSwatterItemAnimationTime() const
|
||||
{return m_swatter_item_animation_time; }
|
||||
bool hasRandomWheels() const { return m_has_rand_wheels; }
|
||||
}; // KartProperties
|
||||
|
||||
|
@ -52,7 +52,7 @@
|
||||
#include "config/stk_config.hpp"
|
||||
#include "config/user_config.hpp"
|
||||
#include "config/player.hpp"
|
||||
#include "graphics/hardware_skinning.hpp" // BOUM
|
||||
#include "graphics/hardware_skinning.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "graphics/material_manager.hpp"
|
||||
#include "guiengine/engine.hpp"
|
||||
|
@ -153,7 +153,6 @@ void MainLoop::run()
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
|
||||
PROFILER_SYNC_FRAME();
|
||||
//printf("--- end frame ---\n"); // BOUM
|
||||
}
|
||||
} // while !m_exit
|
||||
|
||||
|
@ -31,7 +31,7 @@
|
||||
#include "challenges/unlock_manager.hpp"
|
||||
#include "config/user_config.hpp"
|
||||
#include "graphics/camera.hpp"
|
||||
#include "graphics/hardware_skinning.hpp" // BOUM
|
||||
#include "graphics/hardware_skinning.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
#include "items/projectile_manager.hpp"
|
||||
#include "karts/controller/default_ai_controller.hpp"
|
||||
|
Loading…
Reference in New Issue
Block a user