First part of track object refactor
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@12596 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
cc6446cd1c
commit
bc1d1e7d31
@ -27,7 +27,6 @@
|
||||
#include <algorithm>
|
||||
|
||||
AnimationBase::AnimationBase(const XMLNode &node)
|
||||
: TrackObject(node)
|
||||
{
|
||||
float fps=25;
|
||||
node.get("fps", &fps);
|
||||
@ -43,12 +42,12 @@ AnimationBase::AnimationBase(const XMLNode &node)
|
||||
{
|
||||
m_playing = false;
|
||||
}
|
||||
|
||||
reset();
|
||||
} // AnimationBase
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Special constructor which takes one IPO (or curve). This is used by the
|
||||
*/
|
||||
AnimationBase::AnimationBase(Ipo *ipo) : TrackObject()
|
||||
AnimationBase::AnimationBase(Ipo *ipo)
|
||||
{
|
||||
m_anim_type = ATT_CYCLIC_ONCE;
|
||||
m_playing = true;
|
||||
@ -83,8 +82,6 @@ void AnimationBase::reset()
|
||||
{
|
||||
curr->reset();
|
||||
}
|
||||
|
||||
TrackObject::reset();
|
||||
} // reset
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -95,12 +92,14 @@ void AnimationBase::reset()
|
||||
*/
|
||||
void AnimationBase::update(float dt, Vec3 *xyz, Vec3 *hpr, Vec3 *scale)
|
||||
{
|
||||
TrackObject::update(dt);
|
||||
assert(!isnan(m_current_time));
|
||||
|
||||
// Don't do anything if the animation is disabled
|
||||
if(!m_playing) return;
|
||||
m_current_time += dt;
|
||||
|
||||
assert(!isnan(m_current_time));
|
||||
|
||||
Ipo* curr;
|
||||
for_in (curr, m_all_ipos)
|
||||
{
|
||||
|
@ -30,7 +30,6 @@
|
||||
// Note that ipo.hpp is included here in order that PtrVector<Ipo> can call
|
||||
// the proper destructor!
|
||||
#include "animations/ipo.hpp"
|
||||
#include "tracks/track_object.hpp"
|
||||
#include "utils/ptr_vector.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
@ -41,7 +40,7 @@ class XMLNode;
|
||||
* \brief A base class for all animations.
|
||||
* \ingroup animations
|
||||
*/
|
||||
class AnimationBase : public TrackObject
|
||||
class AnimationBase
|
||||
{
|
||||
private:
|
||||
/** Two types of animations: cyclic ones that play all the time, and
|
||||
|
@ -1,102 +0,0 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2009 Joerg Henrichs
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 3
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include "animations/billboard_animation.hpp"
|
||||
#include "config/user_config.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "graphics/material.hpp"
|
||||
#include "graphics/material_manager.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
|
||||
#include <ISceneManager.h>
|
||||
#include <ICameraSceneNode.h>
|
||||
#include <SColor.h>
|
||||
#include <IBillboardSceneNode.h>
|
||||
|
||||
class XMLNode;
|
||||
|
||||
/** A 2d billboard animation. */
|
||||
BillboardAnimation::BillboardAnimation(const XMLNode &xml_node)
|
||||
: AnimationBase(xml_node)
|
||||
{
|
||||
std::string texture_name;
|
||||
float width, height;
|
||||
|
||||
xml_node.get("texture", &texture_name);
|
||||
xml_node.get("width", &width );
|
||||
xml_node.get("height", &height );
|
||||
|
||||
m_fade_out_when_close = false;
|
||||
xml_node.get("fadeout", &m_fade_out_when_close);
|
||||
|
||||
if (m_fade_out_when_close)
|
||||
{
|
||||
xml_node.get("start", &m_fade_out_start);
|
||||
xml_node.get("end", &m_fade_out_end );
|
||||
}
|
||||
|
||||
video::ITexture *texture =
|
||||
irr_driver->getTexture(file_manager->getTextureFile(texture_name));
|
||||
m_node = irr_driver->addBillboard(core::dimension2df(width, height),
|
||||
texture);
|
||||
Material *stk_material = material_manager->getMaterial(texture_name);
|
||||
stk_material->setMaterialProperties(&(m_node->getMaterial(0)), NULL);
|
||||
|
||||
m_node->setPosition(m_init_xyz);
|
||||
} // BillboardAnimation
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Update the animation, called one per time step.
|
||||
* \param dt Time since last call. */
|
||||
void BillboardAnimation::update(float dt)
|
||||
{
|
||||
//if ( UserConfigParams::m_graphical_effects )
|
||||
{
|
||||
Vec3 xyz(m_node->getPosition());
|
||||
// Rotation doesn't make too much sense for a billboard,
|
||||
// so just set it to 0
|
||||
Vec3 hpr(0, 0, 0);
|
||||
Vec3 scale = m_node->getScale();
|
||||
AnimationBase::update(dt, &xyz, &hpr, &scale);
|
||||
m_node->setPosition(xyz.toIrrVector());
|
||||
m_node->setScale(scale.toIrrVector());
|
||||
// Setting rotation doesn't make sense
|
||||
}
|
||||
|
||||
if (m_fade_out_when_close)
|
||||
{
|
||||
scene::ICameraSceneNode* curr_cam = irr_driver->getSceneManager()->getActiveCamera();
|
||||
const float dist = m_node->getPosition().getDistanceFrom( curr_cam->getPosition() );
|
||||
|
||||
scene::IBillboardSceneNode* node = (scene::IBillboardSceneNode*)m_node;
|
||||
|
||||
if (dist < m_fade_out_start)
|
||||
{
|
||||
node->setColor(video::SColor(0, 255, 255, 255));
|
||||
}
|
||||
else if (dist > m_fade_out_end)
|
||||
{
|
||||
node->setColor(video::SColor(255, 255, 255, 255));
|
||||
}
|
||||
else
|
||||
{
|
||||
int a = (int)(255*(dist - m_fade_out_start) / (m_fade_out_end - m_fade_out_start));
|
||||
node->setColor(video::SColor(a, 255, 255, 255));
|
||||
}
|
||||
}
|
||||
} // update
|
@ -1,48 +0,0 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2009 Joerg Henrichs
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 3
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#ifndef HEADER_BILLBOARD_ANIMATION_HPP
|
||||
#define HEADER_BILLBOARD_ANIMATION_HPP
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "animations/animation_base.hpp"
|
||||
|
||||
class XMLNode;
|
||||
|
||||
/**
|
||||
* \brief A 2d billboard animation.
|
||||
* \ingroup animations
|
||||
*/
|
||||
class BillboardAnimation : public AnimationBase
|
||||
{
|
||||
/** To create halo-like effects where the halo disapears when you get
|
||||
close to it. Requested by samuncle */
|
||||
bool m_fade_out_when_close;
|
||||
float m_fade_out_start;
|
||||
float m_fade_out_end;
|
||||
|
||||
public:
|
||||
BillboardAnimation(const XMLNode &node);
|
||||
virtual ~BillboardAnimation() {};
|
||||
virtual void update(float dt);
|
||||
|
||||
}; // BillboardAnimation
|
||||
|
||||
#endif
|
||||
|
@ -440,7 +440,8 @@ void Ipo::reset()
|
||||
* \param scale The scale that needs to be updated (can be NULL)
|
||||
*/
|
||||
void Ipo::update(float time, Vec3 *xyz, Vec3 *hpr,Vec3 *scale)
|
||||
{
|
||||
{
|
||||
assert(!isnan(time));
|
||||
switch(m_ipo_data->m_channel)
|
||||
{
|
||||
case Ipo::IPO_LOCX : if(xyz) xyz ->setX(get(time, 0)); break;
|
||||
@ -474,6 +475,8 @@ void Ipo::update(float time, Vec3 *xyz, Vec3 *hpr,Vec3 *scale)
|
||||
*/
|
||||
float Ipo::get(float time, unsigned int index) const
|
||||
{
|
||||
assert(!isnan(time));
|
||||
|
||||
// Avoid crash in case that only one point is given for this IPO.
|
||||
if(m_next_n==0)
|
||||
return m_ipo_data->m_points[0][index];
|
||||
@ -489,5 +492,7 @@ float Ipo::get(float time, unsigned int index) const
|
||||
while(m_next_n<m_ipo_data->m_points.size()-1 &&
|
||||
time >=m_ipo_data->m_points[m_next_n].getW())
|
||||
m_next_n++;
|
||||
return m_ipo_data->get(time, index, m_next_n-1);
|
||||
float rval = m_ipo_data->get(time, index, m_next_n-1);
|
||||
assert(!isnan(rval));
|
||||
return rval;
|
||||
} // get
|
||||
|
@ -29,15 +29,17 @@
|
||||
#include "modes/world.hpp"
|
||||
#include "physics/kart_motion_state.hpp"
|
||||
#include "physics/physics.hpp"
|
||||
#include "physics/physical_object.hpp"
|
||||
#include "physics/triangle_mesh.hpp"
|
||||
#include "tracks/bezier_curve.hpp"
|
||||
#include "utils/constants.hpp"
|
||||
#include <ISceneManager.h>
|
||||
#include <IMeshSceneNode.h>
|
||||
|
||||
ThreeDAnimation::ThreeDAnimation(const XMLNode &node)
|
||||
: AnimationBase(node)
|
||||
ThreeDAnimation::ThreeDAnimation(const XMLNode &node, TrackObject* object) : AnimationBase(node)
|
||||
{
|
||||
m_object = object;
|
||||
|
||||
m_crash_reset = false;
|
||||
m_explode_kart = false;
|
||||
node.get("reset", &m_crash_reset);
|
||||
@ -45,259 +47,21 @@ ThreeDAnimation::ThreeDAnimation(const XMLNode &node)
|
||||
|
||||
m_important_animation = (World::getWorld()->getIdent() == IDENT_CUSTSCENE);
|
||||
node.get("important", &m_important_animation);
|
||||
|
||||
m_triangle_mesh = NULL;
|
||||
|
||||
if (AnimationBase::m_node)
|
||||
{
|
||||
/** Save the initial position and rotation in the base animation object. */
|
||||
setInitialTransform(AnimationBase::m_node->getPosition(),
|
||||
AnimationBase::m_node->getRotation() );
|
||||
m_hpr = AnimationBase::m_node->getRotation();
|
||||
}
|
||||
else
|
||||
m_hpr = m_init_hpr;
|
||||
|
||||
m_body = NULL;
|
||||
m_motion_state = NULL;
|
||||
m_collision_shape = NULL;
|
||||
std::string shape;
|
||||
node.get("shape", &shape);
|
||||
if(shape!="")
|
||||
{
|
||||
createPhysicsBody(shape);
|
||||
}
|
||||
if (m_node == NULL)
|
||||
{
|
||||
m_node = irr_driver->getSceneManager()->addEmptySceneNode();
|
||||
}
|
||||
/** Save the initial position and rotation in the base animation object. */
|
||||
setInitialTransform(object->getInitXYZ(),
|
||||
object->getInitRotation() );
|
||||
m_hpr = object->getInitRotation();
|
||||
|
||||
assert(!isnan(m_hpr.getX()));
|
||||
assert(!isnan(m_hpr.getY()));
|
||||
assert(!isnan(m_hpr.getZ()));
|
||||
} // ThreeDAnimation
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Creates a bullet rigid body for this animated model. */
|
||||
void ThreeDAnimation::createPhysicsBody(const std::string &shape)
|
||||
{
|
||||
if (m_interaction == "ghost" || m_node == NULL) return;
|
||||
|
||||
// 1. Determine size of the object
|
||||
// -------------------------------
|
||||
Vec3 extend = Vec3(1.0f, 1.0f, 1.0f);
|
||||
|
||||
if (m_mesh != NULL)
|
||||
{
|
||||
Vec3 min, max;
|
||||
MeshTools::minMax3D(m_mesh, &min, &max);
|
||||
extend = max - min;
|
||||
}
|
||||
|
||||
if(shape=="box")
|
||||
{
|
||||
m_collision_shape = new btBoxShape(0.5*extend);
|
||||
}
|
||||
else if(shape=="coneX")
|
||||
{
|
||||
float radius = 0.5f*std::max(extend.getY(), extend.getZ());
|
||||
m_collision_shape = new btConeShapeX(radius, extend.getX());
|
||||
}
|
||||
else if(shape=="coneY" || shape=="cone")
|
||||
{
|
||||
float radius = 0.5f*std::max(extend.getX(), extend.getZ());
|
||||
m_collision_shape = new btConeShape(radius, extend.getY());
|
||||
}
|
||||
else if(shape=="coneZ")
|
||||
{
|
||||
// Note that the b3d model and therefore the extend has the
|
||||
// irrlicht axis, i.e. Y and Z swapped. Also we need to
|
||||
// convert
|
||||
float radius = 0.5f*std::max(extend.getX(), extend.getY());
|
||||
m_collision_shape = new btConeShapeZ(radius, extend.getZ());
|
||||
}
|
||||
else if(shape=="cylinderX")
|
||||
{
|
||||
m_collision_shape = new btCylinderShapeX(0.5f*extend);
|
||||
}
|
||||
else if(shape=="cylinderY")
|
||||
{
|
||||
m_collision_shape = new btCylinderShape(0.5f*extend);
|
||||
}
|
||||
else if(shape=="cylinderZ")
|
||||
{
|
||||
m_collision_shape = new btCylinderShapeZ(0.5f*extend);
|
||||
}
|
||||
else if(shape=="sphere")
|
||||
{
|
||||
float radius = std::max(extend.getX(), extend.getY());
|
||||
radius = 0.5f*std::max(radius, extend.getZ());
|
||||
m_collision_shape = new btSphereShape(radius);
|
||||
}
|
||||
else if(shape=="exact")
|
||||
{
|
||||
TriangleMesh* triangle_mesh = new TriangleMesh();
|
||||
|
||||
// In case of readonly materials we have to get the material from
|
||||
// the mesh, otherwise from the node. This is esp. important for
|
||||
// water nodes, which only have the material defined in the node,
|
||||
// but not in the mesh at all!
|
||||
bool is_readonly_material = false;
|
||||
|
||||
scene::IMesh* mesh = NULL;
|
||||
switch (m_node->getType())
|
||||
{
|
||||
case scene::ESNT_MESH :
|
||||
case scene::ESNT_WATER_SURFACE :
|
||||
case scene::ESNT_OCTREE :
|
||||
mesh = ((scene::IMeshSceneNode*)m_node)->getMesh();
|
||||
is_readonly_material =
|
||||
((scene::IMeshSceneNode*)m_node)->isReadOnlyMaterials();
|
||||
break;
|
||||
case scene::ESNT_ANIMATED_MESH :
|
||||
// for now just use frame 0
|
||||
mesh = ((scene::IAnimatedMeshSceneNode*)m_node)->getMesh()->getMesh(0);
|
||||
is_readonly_material =
|
||||
((scene::IAnimatedMeshSceneNode*)m_node)->isReadOnlyMaterials();
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "[3DAnimation] Unknown object type, cannot create exact collision body!\n");
|
||||
return;
|
||||
} // switch node->getType()
|
||||
|
||||
|
||||
//core::matrix4 mat;
|
||||
//mat.setRotationDegrees(hpr);
|
||||
//mat.setTranslation(pos);
|
||||
//core::matrix4 mat_scale;
|
||||
|
||||
// Note that we can't simply call mat.setScale, since this would
|
||||
// overwrite the elements on the diagonal, making any rotation incorrect.
|
||||
//mat_scale.setScale(scale);
|
||||
//mat *= mat_scale;
|
||||
|
||||
for(unsigned int i=0; i<mesh->getMeshBufferCount(); i++)
|
||||
{
|
||||
scene::IMeshBuffer *mb = mesh->getMeshBuffer(i);
|
||||
// FIXME: take translation/rotation into account
|
||||
if (mb->getVertexType() != video::EVT_STANDARD &&
|
||||
mb->getVertexType() != video::EVT_2TCOORDS)
|
||||
{
|
||||
fprintf(stderr, "WARNING: ThreeDAnimation::createPhysicsBody: Ignoring type '%d'!\n",
|
||||
mb->getVertexType());
|
||||
continue;
|
||||
}
|
||||
|
||||
// Handle readonly materials correctly: mb->getMaterial can return
|
||||
// NULL if the node is not using readonly materials. E.g. in case
|
||||
// of a water scene node, the mesh (which is the animated copy of
|
||||
// the original mesh) does not contain any material information,
|
||||
// the material is only available in the node.
|
||||
const video::SMaterial &irrMaterial =
|
||||
is_readonly_material ? mb->getMaterial()
|
||||
: m_node->getMaterial(i);
|
||||
video::ITexture* t=irrMaterial.getTexture(0);
|
||||
|
||||
const Material* material=0;
|
||||
TriangleMesh *tmesh = triangle_mesh;
|
||||
if(t)
|
||||
{
|
||||
std::string image = std::string(core::stringc(t->getName()).c_str());
|
||||
material=material_manager->getMaterial(StringUtils::getBasename(image));
|
||||
if(material->isIgnore())
|
||||
continue;
|
||||
}
|
||||
|
||||
u16 *mbIndices = mb->getIndices();
|
||||
Vec3 vertices[3];
|
||||
Vec3 normals[3];
|
||||
|
||||
if (mb->getVertexType() == video::EVT_STANDARD)
|
||||
{
|
||||
irr::video::S3DVertex* mbVertices=(video::S3DVertex*)mb->getVertices();
|
||||
for(unsigned int j=0; j<mb->getIndexCount(); j+=3)
|
||||
{
|
||||
for(unsigned int k=0; k<3; k++)
|
||||
{
|
||||
int indx=mbIndices[j+k];
|
||||
core::vector3df v = mbVertices[indx].Pos;
|
||||
//mat.transformVect(v);
|
||||
vertices[k]=v;
|
||||
normals[k]=mbVertices[indx].Normal;
|
||||
} // for k
|
||||
if(tmesh) tmesh->addTriangle(vertices[0], vertices[1],
|
||||
vertices[2], normals[0],
|
||||
normals[1], normals[2],
|
||||
material );
|
||||
} // for j
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mb->getVertexType() == video::EVT_2TCOORDS)
|
||||
{
|
||||
irr::video::S3DVertex2TCoords* mbVertices = (video::S3DVertex2TCoords*)mb->getVertices();
|
||||
for(unsigned int j=0; j<mb->getIndexCount(); j+=3)
|
||||
{
|
||||
for(unsigned int k=0; k<3; k++)
|
||||
{
|
||||
int indx=mbIndices[j+k];
|
||||
core::vector3df v = mbVertices[indx].Pos;
|
||||
//mat.transformVect(v);
|
||||
vertices[k]=v;
|
||||
normals[k]=mbVertices[indx].Normal;
|
||||
} // for k
|
||||
if(tmesh) tmesh->addTriangle(vertices[0], vertices[1],
|
||||
vertices[2], normals[0],
|
||||
normals[1], normals[2],
|
||||
material );
|
||||
} // for j
|
||||
|
||||
}
|
||||
}
|
||||
} // for i<getMeshBufferCount
|
||||
triangle_mesh->createCollisionShape();
|
||||
m_collision_shape = &triangle_mesh->getCollisionShape();
|
||||
m_triangle_mesh = triangle_mesh;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "[3DAnimation] WARNING: Shape '%s' is not supported, ignored.\n", shape.c_str());
|
||||
return;
|
||||
}
|
||||
const core::vector3df &hpr = m_node->getRotation()*DEGREE_TO_RAD;
|
||||
btQuaternion q(hpr.X, hpr.Y, hpr.Z);
|
||||
const core::vector3df &xyz=m_node->getPosition();
|
||||
Vec3 p(xyz);
|
||||
btTransform trans(q,p);
|
||||
m_motion_state = new KartMotionState(trans);
|
||||
btRigidBody::btRigidBodyConstructionInfo info(0, m_motion_state,
|
||||
m_collision_shape);
|
||||
|
||||
m_body = new btRigidBody(info);
|
||||
m_user_pointer.set(this);
|
||||
m_body->setUserPointer(&m_user_pointer);
|
||||
World::getWorld()->getPhysics()->addBody(m_body);
|
||||
m_body->setCollisionFlags( m_body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
|
||||
m_body->setActivationState(DISABLE_DEACTIVATION);
|
||||
} // createPhysicsBody
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Destructor. */
|
||||
ThreeDAnimation::~ThreeDAnimation()
|
||||
{
|
||||
if(m_body)
|
||||
{
|
||||
World::getWorld()->getPhysics()->removeBody(m_body);
|
||||
delete m_body;
|
||||
delete m_motion_state;
|
||||
// If an exact shape was used, the collision shape pointer
|
||||
// here is a copy of the collision shape pointer in the
|
||||
// triangle mesh. In order to avoid double-freeing this
|
||||
// pointer, we don't free the pointer in this case.
|
||||
if(!m_triangle_mesh)
|
||||
delete m_collision_shape;
|
||||
}
|
||||
|
||||
if (m_triangle_mesh)
|
||||
{
|
||||
delete m_triangle_mesh;
|
||||
}
|
||||
} // ~ThreeDAnimation
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -308,12 +72,13 @@ void ThreeDAnimation::update(float dt)
|
||||
{
|
||||
//if ( UserConfigParams::m_graphical_effects || m_important_animation )
|
||||
{
|
||||
Vec3 xyz = m_node->getPosition();
|
||||
Vec3 scale = m_node->getScale();
|
||||
Vec3 xyz = m_object->getPosition();
|
||||
Vec3 scale = m_object->getScale();
|
||||
|
||||
AnimationBase::update(dt, &xyz, &m_hpr, &scale); //updates all IPOs
|
||||
m_node->setPosition(xyz.toIrrVector());
|
||||
m_node->setScale(scale.toIrrVector());
|
||||
//m_node->setPosition(xyz.toIrrVector());
|
||||
//m_node->setScale(scale.toIrrVector());
|
||||
|
||||
// Note that the rotation order of irrlicht is different from the one
|
||||
// in blender. So in order to reproduce the blender IPO rotations
|
||||
// correctly, we have to get the rotations around each axis and combine
|
||||
@ -321,6 +86,9 @@ void ThreeDAnimation::update(float dt)
|
||||
core::matrix4 m;
|
||||
m.makeIdentity();
|
||||
core::matrix4 mx;
|
||||
assert(!isnan(m_hpr.getX()));
|
||||
assert(!isnan(m_hpr.getY()));
|
||||
assert(!isnan(m_hpr.getZ()));
|
||||
mx.setRotationDegrees(core::vector3df(m_hpr.getX(), 0, 0));
|
||||
core::matrix4 my;
|
||||
my.setRotationDegrees(core::vector3df(0, m_hpr.getY(), 0));
|
||||
@ -328,30 +96,11 @@ void ThreeDAnimation::update(float dt)
|
||||
mz.setRotationDegrees(core::vector3df(0, 0, m_hpr.getZ()));
|
||||
m = my*mz*mx;
|
||||
core::vector3df hpr = m.getRotationDegrees();
|
||||
m_node->setRotation(hpr);
|
||||
//m_node->setRotation(hpr);
|
||||
|
||||
// Now update the position of the bullet body if there is one:
|
||||
if(m_body)
|
||||
if (m_object)
|
||||
{
|
||||
Vec3 hpr2(hpr);
|
||||
hpr2.degreeToRad();
|
||||
btQuaternion q;
|
||||
|
||||
core::matrix4 mat;
|
||||
mat.setRotationDegrees(hpr);
|
||||
|
||||
irr::core::quaternion tempQuat(mat);
|
||||
q = btQuaternion(-tempQuat.X, -tempQuat.Y, -tempQuat.Z, tempQuat.W);
|
||||
|
||||
|
||||
Vec3 p(xyz);
|
||||
btTransform trans(q,p);
|
||||
m_motion_state->setWorldTransform(trans);
|
||||
}
|
||||
|
||||
if (m_sound != NULL)
|
||||
{
|
||||
m_sound->position(xyz);
|
||||
m_object->move(xyz.toIrrVector(), hpr, scale.toIrrVector());
|
||||
}
|
||||
}
|
||||
} // update
|
||||
|
@ -29,6 +29,12 @@ using namespace irr;
|
||||
#include "animations/animation_base.hpp"
|
||||
#include "physics/user_pointer.hpp"
|
||||
|
||||
namespace irr
|
||||
{
|
||||
namespace scene { class IAnimatedMesh; class ISceneNode; class IMesh; }
|
||||
}
|
||||
|
||||
class TrackObject;
|
||||
class BezierCurve;
|
||||
class XMLNode;
|
||||
|
||||
@ -38,21 +44,8 @@ class XMLNode;
|
||||
class ThreeDAnimation : public AnimationBase
|
||||
{
|
||||
private:
|
||||
/** The bullet collision shape for the physics. */
|
||||
btCollisionShape *m_collision_shape;
|
||||
|
||||
/** The bullet rigid body. */
|
||||
btRigidBody *m_body;
|
||||
|
||||
/** Motion state of the physical object. */
|
||||
btMotionState *m_motion_state;
|
||||
|
||||
/** A user pointer to connect a bullet body with this object. */
|
||||
UserPointer m_user_pointer;
|
||||
|
||||
/** Non-null only if the shape is exact */
|
||||
TriangleMesh *m_triangle_mesh;
|
||||
|
||||
TrackObject *m_object;
|
||||
|
||||
/** True if a collision with this object should trigger
|
||||
* rescuing a kart. */
|
||||
bool m_crash_reset;
|
||||
@ -71,10 +64,10 @@ private:
|
||||
*/
|
||||
bool m_important_animation;
|
||||
|
||||
void createPhysicsBody(const std::string &shape);
|
||||
//scene::ISceneNode* m_node;
|
||||
|
||||
public:
|
||||
ThreeDAnimation(const XMLNode &node);
|
||||
ThreeDAnimation(const XMLNode &node, TrackObject* object);
|
||||
virtual ~ThreeDAnimation();
|
||||
virtual void update(float dt);
|
||||
// ------------------------------------------------------------------------
|
||||
|
@ -589,3 +589,12 @@ int XMLNode::getHPR(Vec3 *value) const
|
||||
} // getHPR Vec3
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
bool XMLNode::hasChildNamed(const char* name) const
|
||||
{
|
||||
for (unsigned int i = 0; i < m_nodes.size(); i++)
|
||||
{
|
||||
if (m_nodes[i]->getName() == name) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
@ -100,6 +100,9 @@ public:
|
||||
int getXYZ(Vec3 *vaslue) const;
|
||||
int getHPR(core::vector3df *value) const;
|
||||
int getHPR(Vec3 *value) const;
|
||||
|
||||
bool hasChildNamed(const char* name) const;
|
||||
|
||||
/** Handy functions to test the bit pattern returned by get(vector3df*).*/
|
||||
static bool hasX(int b) { return (b&1)==1; }
|
||||
static bool hasY(int b) { return (b&2)==2; }
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <ISceneManager.h>
|
||||
|
||||
#include "animations/animation_base.hpp"
|
||||
#include "animations/three_d_animation.hpp"
|
||||
#include "audio/music_manager.hpp"
|
||||
#include "challenges/game_slot.hpp"
|
||||
#include "challenges/unlock_manager.hpp"
|
||||
@ -82,9 +83,10 @@ void CutsceneWorld::init()
|
||||
TrackObject* curr;
|
||||
for_in(curr, objects)
|
||||
{
|
||||
if (curr->getType() == "particle-emitter" && !curr->getTriggerCondition().empty())
|
||||
if (curr->getType() == "particle-emitter" &&
|
||||
!curr->getPresentation<TrackObjectPresentationParticles>()->getTriggerCondition().empty())
|
||||
{
|
||||
const std::string& condition = curr->getTriggerCondition();
|
||||
const std::string& condition = curr->getPresentation<TrackObjectPresentationParticles>()->getTriggerCondition();
|
||||
|
||||
if (StringUtils::startsWith(condition, "frame "))
|
||||
{
|
||||
@ -102,9 +104,9 @@ void CutsceneWorld::init()
|
||||
m_particles_to_trigger[frame / FPS].push_back(curr);
|
||||
}
|
||||
}
|
||||
else if (curr->getType() == "sfx-emitter" && !curr->getTriggerCondition().empty())
|
||||
else if (curr->getType() == "sfx-emitter" && !curr->getPresentation<TrackObjectPresentationSound>()->getTriggerCondition().empty())
|
||||
{
|
||||
const std::string& condition = curr->getTriggerCondition();
|
||||
const std::string& condition = curr->getPresentation<TrackObjectPresentationSound>()->getTriggerCondition();
|
||||
|
||||
if (StringUtils::startsWith(condition, "frame "))
|
||||
{
|
||||
@ -135,15 +137,14 @@ void CutsceneWorld::init()
|
||||
|
||||
float FPS = 25.0f; // for now we assume the cutscene is saved at 25 FPS
|
||||
m_sounds_to_stop[frame / FPS].push_back(curr);
|
||||
curr->triggerSound(true);
|
||||
curr->getPresentation<TrackObjectPresentationSound>()->triggerSound(true);
|
||||
}
|
||||
}
|
||||
|
||||
if (dynamic_cast<AnimationBase*>(curr) != NULL)
|
||||
if (curr->getAnimator() != NULL)
|
||||
{
|
||||
m_duration = std::max(m_duration,
|
||||
(double)dynamic_cast<AnimationBase*>(curr)
|
||||
->getAnimationDuration());
|
||||
(double)curr->getAnimator()->getAnimationDuration());
|
||||
}
|
||||
}
|
||||
|
||||
@ -273,10 +274,11 @@ void CutsceneWorld::update(float dt)
|
||||
{
|
||||
if (curr->getType() == "cutscene_camera")
|
||||
{
|
||||
m_camera->setPosition(curr->getNode()->getPosition());
|
||||
scene::ISceneNode* anchorNode = curr->getPresentation<TrackObjectPresentationEmpty>()->getNode();
|
||||
m_camera->setPosition(anchorNode->getPosition());
|
||||
m_camera->updateAbsolutePosition();
|
||||
|
||||
core::vector3df rot = curr->getNode()->getRotation();
|
||||
core::vector3df rot = anchorNode->getRotation();
|
||||
Vec3 rot2(rot);
|
||||
rot2.setPitch(rot2.getPitch() + 90.0f);
|
||||
m_camera->setRotation(rot2.toIrrVector());
|
||||
@ -299,7 +301,7 @@ void CutsceneWorld::update(float dt)
|
||||
std::vector<TrackObject*> objects = it->second;
|
||||
for (unsigned int i = 0; i < objects.size(); i++)
|
||||
{
|
||||
objects[i]->triggerSound();
|
||||
objects[i]->getPresentation<TrackObjectPresentationSound>()->triggerSound(false);
|
||||
}
|
||||
m_sounds_to_trigger.erase(it++);
|
||||
}
|
||||
@ -317,7 +319,7 @@ void CutsceneWorld::update(float dt)
|
||||
std::vector<TrackObject*> objects = it->second;
|
||||
for (unsigned int i = 0; i < objects.size(); i++)
|
||||
{
|
||||
objects[i]->triggerParticles();
|
||||
objects[i]->getPresentation<TrackObjectPresentationParticles>()->triggerParticles();
|
||||
}
|
||||
m_particles_to_trigger.erase(it++);
|
||||
}
|
||||
@ -334,7 +336,7 @@ void CutsceneWorld::update(float dt)
|
||||
std::vector<TrackObject*> objects = it->second;
|
||||
for (unsigned int i = 0; i < objects.size(); i++)
|
||||
{
|
||||
objects[i]->stopSound();
|
||||
objects[i]->getPresentation<TrackObjectPresentationSound>()->stopSound();
|
||||
}
|
||||
m_sounds_to_stop.erase(it++);
|
||||
}
|
||||
|
@ -123,7 +123,7 @@ void ThreeStrikesBattle::reset()
|
||||
evt.m_kart_info = m_kart_info;
|
||||
m_battle_events.push_back(evt);
|
||||
|
||||
PhysicalObject *obj;
|
||||
TrackObject *obj;
|
||||
for_in(obj, m_tires)
|
||||
{
|
||||
m_track->getTrackObjectManager()->removeObject(obj);
|
||||
@ -330,6 +330,8 @@ void ThreeStrikesBattle::update(float dt)
|
||||
tire = m_tire_dir+"/wheel-rear-right.b3d";
|
||||
}
|
||||
|
||||
// TODO: add back tires
|
||||
#if 0
|
||||
TrackObjectManager* tom = m_track->getTrackObjectManager();
|
||||
PhysicalObject* obj =
|
||||
tom->insertObject(tire,
|
||||
@ -349,6 +351,7 @@ void ThreeStrikesBattle::update(float dt)
|
||||
m_insert_tire = 0;
|
||||
|
||||
m_tires.push_back(obj);
|
||||
#endif
|
||||
}
|
||||
} // update
|
||||
|
||||
|
@ -19,7 +19,9 @@
|
||||
#ifndef THREE_STRIKES_HPP
|
||||
#define THREE_STRIKES_HPP
|
||||
|
||||
|
||||
#include "modes/world_with_rank.hpp"
|
||||
#include "tracks/track_object.hpp"
|
||||
#include "states_screens/race_gui_base.hpp"
|
||||
|
||||
#include <IMesh.h>
|
||||
@ -68,7 +70,7 @@ private:
|
||||
/** A rotation to apply to the tires when inserting them. */
|
||||
float m_tire_rotation;
|
||||
|
||||
PtrVector<PhysicalObject, REF> m_tires;
|
||||
PtrVector<TrackObject, REF> m_tires;
|
||||
|
||||
public:
|
||||
|
||||
|
@ -746,6 +746,14 @@ void World::updateWorld(float dt)
|
||||
|
||||
#define MEASURE_FPS 0
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void World::scheduleTutorial()
|
||||
{
|
||||
m_schedule_exit_race = true;
|
||||
m_schedule_tutorial = true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Updates the physics, all karts, the track, and projectile manager.
|
||||
* \param dt Time step size.
|
||||
|
@ -252,8 +252,7 @@ public:
|
||||
void schedulePause(Phase phase);
|
||||
void scheduleUnpause();
|
||||
void scheduleExitRace() { m_schedule_exit_race = true; }
|
||||
void scheduleTutorial() { m_schedule_exit_race = true;
|
||||
m_schedule_tutorial = true; }
|
||||
void scheduleTutorial();
|
||||
void updateWorld(float dt);
|
||||
void handleExplosion(const Vec3 &xyz, AbstractKart *kart_hit,
|
||||
PhysicalObject *object);
|
||||
|
@ -24,11 +24,13 @@
|
||||
using namespace irr;
|
||||
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "graphics/material_manager.hpp"
|
||||
#include "graphics/mesh_tools.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
#include "io/xml_node.hpp"
|
||||
#include "modes/world.hpp"
|
||||
#include "physics/physics.hpp"
|
||||
#include "physics/triangle_mesh.hpp"
|
||||
#include "tracks/track.hpp"
|
||||
#include "utils/constants.hpp"
|
||||
#include "utils/string_utils.hpp"
|
||||
@ -37,8 +39,9 @@ using namespace irr;
|
||||
#include <IMeshSceneNode.h>
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
PhysicalObject::PhysicalObject(const XMLNode &xml_node)
|
||||
: TrackObject(xml_node)
|
||||
|
||||
PhysicalObject::PhysicalObject(bool kinetic, const XMLNode &xml_node,
|
||||
scene::ISceneNode* scenenode)
|
||||
{
|
||||
m_shape = NULL;
|
||||
m_body = NULL;
|
||||
@ -50,6 +53,12 @@ PhysicalObject::PhysicalObject(const XMLNode &xml_node)
|
||||
m_crash_reset = false;
|
||||
m_explode_kart = false;
|
||||
|
||||
m_node = scenenode;
|
||||
|
||||
m_init_xyz = scenenode->getPosition();
|
||||
m_init_hpr = scenenode->getRotation();
|
||||
m_init_scale = scenenode->getScale();
|
||||
|
||||
std::string shape;
|
||||
xml_node.get("mass", &m_mass );
|
||||
xml_node.get("radius", &m_radius );
|
||||
@ -71,36 +80,31 @@ PhysicalObject::PhysicalObject(const XMLNode &xml_node)
|
||||
|
||||
else if(shape=="box" ) m_body_type = MP_BOX;
|
||||
else if(shape=="sphere" ) m_body_type = MP_SPHERE;
|
||||
else if(shape=="exact") m_body_type = MP_EXACT;
|
||||
|
||||
else fprintf(stderr, "Unknown shape type : %s\n", shape.c_str());
|
||||
|
||||
|
||||
m_init_pos.setIdentity();
|
||||
Vec3 hpr(m_init_hpr);
|
||||
hpr.degreeToRad();
|
||||
Vec3 radHpr(m_init_hpr);
|
||||
radHpr.degreeToRad();
|
||||
btQuaternion q;
|
||||
q.setEuler(hpr.getY(), hpr.getX(), hpr.getZ());
|
||||
q.setEuler(radHpr.getY(),radHpr.getX(), radHpr.getZ());
|
||||
m_init_pos.setRotation(q);
|
||||
Vec3 init_xyz(m_init_xyz);
|
||||
m_init_pos.setOrigin(init_xyz);
|
||||
|
||||
if (m_node == NULL)
|
||||
{
|
||||
std::string model_name;
|
||||
xml_node.get("model", &model_name );
|
||||
fprintf(stderr,
|
||||
"[PhysicalObject] WARNING, could not locate model '%s'\n",
|
||||
model_name.c_str());
|
||||
}
|
||||
|
||||
m_kinetic = kinetic;
|
||||
|
||||
init();
|
||||
} // PhysicalObject
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
PhysicalObject::PhysicalObject(const std::string& model,
|
||||
bodyTypes shape, float mass, float radius,
|
||||
const core::vector3df& hpr,
|
||||
const core::vector3df& pos,
|
||||
const core::vector3df& scale)
|
||||
: TrackObject(pos, hpr, scale, model)
|
||||
{
|
||||
m_body_type = shape;
|
||||
m_mass = mass;
|
||||
@ -114,16 +118,48 @@ PhysicalObject::PhysicalObject(const std::string& model,
|
||||
m_init_pos.setRotation(q);
|
||||
m_init_pos.setOrigin(btVector3(pos.X, pos.Y, pos.Z));
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
PhysicalObject::~PhysicalObject()
|
||||
{
|
||||
World::getWorld()->getPhysics()->removeBody(m_body);
|
||||
delete m_body;
|
||||
delete m_motion_state;
|
||||
delete m_shape;
|
||||
|
||||
// If an exact shape was used, the collision shape pointer
|
||||
// here is a copy of the collision shape pointer in the
|
||||
// triangle mesh. In order to avoid double-freeing this
|
||||
// pointer, we don't free the pointer in this case.
|
||||
if (!m_triangle_mesh)
|
||||
delete m_shape;
|
||||
|
||||
if (m_triangle_mesh)
|
||||
{
|
||||
delete m_triangle_mesh;
|
||||
}
|
||||
} // ~PhysicalObject
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void PhysicalObject::move(const Vec3& xyz, const core::vector3df& hpr)
|
||||
{
|
||||
Vec3 hpr2(hpr);
|
||||
hpr2.degreeToRad();
|
||||
btQuaternion q;
|
||||
|
||||
core::matrix4 mat;
|
||||
mat.setRotationDegrees(hpr);
|
||||
|
||||
irr::core::quaternion tempQuat(mat);
|
||||
q = btQuaternion(-tempQuat.X, -tempQuat.Y, -tempQuat.Z, tempQuat.W);
|
||||
|
||||
|
||||
Vec3 p(xyz);
|
||||
btTransform trans(q,p);
|
||||
m_motion_state->setWorldTransform(trans);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Additional initialisation after loading of the model is finished.
|
||||
*/
|
||||
@ -187,57 +223,197 @@ void PhysicalObject::init()
|
||||
m_graphical_offset = -0.5f*(max+min);
|
||||
switch (m_body_type)
|
||||
{
|
||||
case MP_CONE_Y: {
|
||||
if(m_radius<0) m_radius = 0.5f*extend.length_2d();
|
||||
m_shape = new btConeShape(m_radius, extend.getY());
|
||||
break;
|
||||
}
|
||||
case MP_CONE_X: {
|
||||
if(m_radius<0)
|
||||
m_radius = 0.5f*sqrt(extend.getY()*extend.getY() +
|
||||
extend.getZ()*extend.getZ());
|
||||
m_shape = new btConeShapeX(m_radius, extend.getY());
|
||||
break;
|
||||
}
|
||||
case MP_CONE_Z: {
|
||||
if(m_radius<0)
|
||||
m_radius = 0.5f*sqrt(extend.getX()*extend.getX() +
|
||||
extend.getY()*extend.getY());
|
||||
m_shape = new btConeShapeZ(m_radius, extend.getY());
|
||||
break;
|
||||
}
|
||||
case MP_CYLINDER_Y: {
|
||||
if(m_radius<0) m_radius = 0.5f*extend.length_2d();
|
||||
m_shape = new btCylinderShape(0.5f*extend);
|
||||
break;
|
||||
}
|
||||
case MP_CYLINDER_X: {
|
||||
if(m_radius<0)
|
||||
m_radius = 0.5f*sqrt(extend.getY()*extend.getY() +
|
||||
extend.getZ()*extend.getZ());
|
||||
m_shape = new btCylinderShapeX(0.5f*extend);
|
||||
break;
|
||||
}
|
||||
case MP_CYLINDER_Z: {
|
||||
if(m_radius<0)
|
||||
m_radius = 0.5f*sqrt(extend.getX()*extend.getX() +
|
||||
extend.getY()*extend.getY());
|
||||
m_shape = new btCylinderShapeZ(0.5f*extend);
|
||||
break;
|
||||
}
|
||||
case MP_BOX: m_shape = new btBoxShape(0.5*extend);
|
||||
break;
|
||||
case MP_SPHERE: {
|
||||
if(m_radius<0)
|
||||
case MP_CONE_Y:
|
||||
{
|
||||
if (m_radius < 0) m_radius = 0.5f*extend.length_2d();
|
||||
m_shape = new btConeShape(m_radius, extend.getY());
|
||||
break;
|
||||
}
|
||||
case MP_CONE_X:
|
||||
{
|
||||
if (m_radius < 0)
|
||||
m_radius = 0.5f*sqrt(extend.getY()*extend.getY() +
|
||||
extend.getZ()*extend.getZ());
|
||||
m_shape = new btConeShapeX(m_radius, extend.getY());
|
||||
break;
|
||||
}
|
||||
case MP_CONE_Z:
|
||||
{
|
||||
if (m_radius < 0)
|
||||
m_radius = 0.5f*sqrt(extend.getX()*extend.getX() +
|
||||
extend.getY()*extend.getY());
|
||||
m_shape = new btConeShapeZ(m_radius, extend.getY());
|
||||
break;
|
||||
}
|
||||
case MP_CYLINDER_Y:
|
||||
{
|
||||
if (m_radius < 0) m_radius = 0.5f*extend.length_2d();
|
||||
m_shape = new btCylinderShape(0.5f*extend);
|
||||
break;
|
||||
}
|
||||
case MP_CYLINDER_X:
|
||||
{
|
||||
if (m_radius < 0)
|
||||
m_radius = 0.5f*sqrt(extend.getY()*extend.getY() +
|
||||
extend.getZ()*extend.getZ());
|
||||
m_shape = new btCylinderShapeX(0.5f*extend);
|
||||
break;
|
||||
}
|
||||
case MP_CYLINDER_Z:
|
||||
{
|
||||
if (m_radius < 0)
|
||||
m_radius = 0.5f*sqrt(extend.getX()*extend.getX() +
|
||||
extend.getY()*extend.getY());
|
||||
m_shape = new btCylinderShapeZ(0.5f*extend);
|
||||
break;
|
||||
}
|
||||
case MP_SPHERE:
|
||||
{
|
||||
if(m_radius<0)
|
||||
{
|
||||
m_radius = std::max(extend.getX(), extend.getY());
|
||||
m_radius = 0.5f*std::max(m_radius, extend.getZ());
|
||||
}
|
||||
m_shape = new btSphereShape(m_radius);
|
||||
break;
|
||||
}
|
||||
case MP_EXACT:
|
||||
{
|
||||
TriangleMesh* triangle_mesh = new TriangleMesh();
|
||||
|
||||
// In case of readonly materials we have to get the material from
|
||||
// the mesh, otherwise from the node. This is esp. important for
|
||||
// water nodes, which only have the material defined in the node,
|
||||
// but not in the mesh at all!
|
||||
bool is_readonly_material = false;
|
||||
|
||||
scene::IMesh* mesh = NULL;
|
||||
switch (m_node->getType())
|
||||
{
|
||||
case scene::ESNT_MESH :
|
||||
case scene::ESNT_WATER_SURFACE :
|
||||
case scene::ESNT_OCTREE :
|
||||
mesh = ((scene::IMeshSceneNode*)m_node)->getMesh();
|
||||
is_readonly_material =
|
||||
((scene::IMeshSceneNode*)m_node)->isReadOnlyMaterials();
|
||||
break;
|
||||
case scene::ESNT_ANIMATED_MESH :
|
||||
// for now just use frame 0
|
||||
mesh = ((scene::IAnimatedMeshSceneNode*)m_node)->getMesh()->getMesh(0);
|
||||
is_readonly_material =
|
||||
((scene::IAnimatedMeshSceneNode*)m_node)->isReadOnlyMaterials();
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "[3DAnimation] Unknown object type, cannot create exact collision body!\n");
|
||||
return;
|
||||
} // switch node->getType()
|
||||
|
||||
|
||||
//core::matrix4 mat;
|
||||
//mat.setRotationDegrees(hpr);
|
||||
//mat.setTranslation(pos);
|
||||
//core::matrix4 mat_scale;
|
||||
|
||||
// Note that we can't simply call mat.setScale, since this would
|
||||
// overwrite the elements on the diagonal, making any rotation incorrect.
|
||||
//mat_scale.setScale(scale);
|
||||
//mat *= mat_scale;
|
||||
|
||||
for(unsigned int i=0; i<mesh->getMeshBufferCount(); i++)
|
||||
{
|
||||
scene::IMeshBuffer *mb = mesh->getMeshBuffer(i);
|
||||
// FIXME: take translation/rotation into account
|
||||
if (mb->getVertexType() != video::EVT_STANDARD &&
|
||||
mb->getVertexType() != video::EVT_2TCOORDS)
|
||||
{
|
||||
fprintf(stderr, "WARNING: ThreeDAnimation::createPhysicsBody: Ignoring type '%d'!\n",
|
||||
mb->getVertexType());
|
||||
continue;
|
||||
}
|
||||
|
||||
// Handle readonly materials correctly: mb->getMaterial can return
|
||||
// NULL if the node is not using readonly materials. E.g. in case
|
||||
// of a water scene node, the mesh (which is the animated copy of
|
||||
// the original mesh) does not contain any material information,
|
||||
// the material is only available in the node.
|
||||
const video::SMaterial &irrMaterial =
|
||||
is_readonly_material ? mb->getMaterial()
|
||||
: m_node->getMaterial(i);
|
||||
video::ITexture* t=irrMaterial.getTexture(0);
|
||||
|
||||
const Material* material=0;
|
||||
TriangleMesh *tmesh = triangle_mesh;
|
||||
if(t)
|
||||
{
|
||||
std::string image = std::string(core::stringc(t->getName()).c_str());
|
||||
material=material_manager->getMaterial(StringUtils::getBasename(image));
|
||||
if(material->isIgnore())
|
||||
continue;
|
||||
}
|
||||
|
||||
u16 *mbIndices = mb->getIndices();
|
||||
Vec3 vertices[3];
|
||||
Vec3 normals[3];
|
||||
|
||||
if (mb->getVertexType() == video::EVT_STANDARD)
|
||||
{
|
||||
irr::video::S3DVertex* mbVertices=(video::S3DVertex*)mb->getVertices();
|
||||
for(unsigned int j=0; j<mb->getIndexCount(); j+=3)
|
||||
{
|
||||
for(unsigned int k=0; k<3; k++)
|
||||
{
|
||||
m_radius = std::max(extend.getX(), extend.getY());
|
||||
m_radius = 0.5f*std::max(m_radius, extend.getZ());
|
||||
}
|
||||
m_shape = new btSphereShape(m_radius);
|
||||
break;
|
||||
}
|
||||
case MP_NONE: fprintf(stderr, "WARNING: Uninitialised moving shape\n");
|
||||
break;
|
||||
int indx=mbIndices[j+k];
|
||||
core::vector3df v = mbVertices[indx].Pos;
|
||||
//mat.transformVect(v);
|
||||
vertices[k]=v;
|
||||
normals[k]=mbVertices[indx].Normal;
|
||||
} // for k
|
||||
if(tmesh) tmesh->addTriangle(vertices[0], vertices[1],
|
||||
vertices[2], normals[0],
|
||||
normals[1], normals[2],
|
||||
material );
|
||||
} // for j
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mb->getVertexType() == video::EVT_2TCOORDS)
|
||||
{
|
||||
irr::video::S3DVertex2TCoords* mbVertices = (video::S3DVertex2TCoords*)mb->getVertices();
|
||||
for(unsigned int j=0; j<mb->getIndexCount(); j+=3)
|
||||
{
|
||||
for(unsigned int k=0; k<3; k++)
|
||||
{
|
||||
int indx=mbIndices[j+k];
|
||||
core::vector3df v = mbVertices[indx].Pos;
|
||||
//mat.transformVect(v);
|
||||
vertices[k]=v;
|
||||
normals[k]=mbVertices[indx].Normal;
|
||||
} // for k
|
||||
if(tmesh) tmesh->addTriangle(vertices[0], vertices[1],
|
||||
vertices[2], normals[0],
|
||||
normals[1], normals[2],
|
||||
material );
|
||||
} // for j
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
} // for i<getMeshBufferCount
|
||||
triangle_mesh->createCollisionShape();
|
||||
m_shape = &triangle_mesh->getCollisionShape();
|
||||
m_triangle_mesh = triangle_mesh;
|
||||
|
||||
break;
|
||||
}
|
||||
case MP_NONE:
|
||||
default:
|
||||
fprintf(stderr, "WARNING: Uninitialised moving shape\n");
|
||||
// intended fall-through
|
||||
case MP_BOX:
|
||||
{
|
||||
m_shape = new btBoxShape(0.5*extend);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Create the rigid object
|
||||
@ -258,11 +434,19 @@ void PhysicalObject::init()
|
||||
m_body->setUserPointer(&m_user_pointer);
|
||||
|
||||
World::getWorld()->getPhysics()->addBody(m_body);
|
||||
|
||||
if (!m_kinetic)
|
||||
{
|
||||
m_body->setCollisionFlags( m_body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
|
||||
m_body->setActivationState(DISABLE_DEACTIVATION);
|
||||
}
|
||||
} // init
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void PhysicalObject::update(float dt)
|
||||
{
|
||||
if (!m_kinetic) return;
|
||||
|
||||
btTransform t;
|
||||
m_motion_state->getWorldTransform(t);
|
||||
|
||||
|
@ -26,22 +26,35 @@
|
||||
#include "physics/user_pointer.hpp"
|
||||
#include "tracks/track_object.hpp"
|
||||
#include "utils/vec3.hpp"
|
||||
#include "utils/leak_check.hpp"
|
||||
|
||||
class XMLNode;
|
||||
|
||||
/**
|
||||
* \ingroup physics
|
||||
*/
|
||||
class PhysicalObject : public TrackObject
|
||||
class PhysicalObject
|
||||
{
|
||||
public:
|
||||
/** The supported collision shapes. */
|
||||
enum bodyTypes {MP_NONE,
|
||||
MP_CONE_Y, MP_CONE_X, MP_CONE_Z,
|
||||
MP_CYLINDER_Y, MP_CYLINDER_X, MP_CYLINDER_Z,
|
||||
MP_BOX, MP_SPHERE};
|
||||
MP_BOX, MP_SPHERE, MP_EXACT};
|
||||
|
||||
private:
|
||||
|
||||
/** The initial XYZ position of the object. */
|
||||
core::vector3df m_init_xyz;
|
||||
|
||||
/** The initial hpr of the object. */
|
||||
core::vector3df m_init_hpr;
|
||||
|
||||
/** The initial scale of the object. */
|
||||
core::vector3df m_init_scale;
|
||||
|
||||
scene::ISceneNode* m_node;
|
||||
|
||||
/** The shape of this object. */
|
||||
bodyTypes m_body_type;
|
||||
|
||||
@ -90,20 +103,31 @@ private:
|
||||
/** If m_reset_when_too_low this object is set back to its start
|
||||
* position if its height is below this value. */
|
||||
float m_reset_height;
|
||||
public:
|
||||
PhysicalObject (const XMLNode &node);
|
||||
|
||||
bool m_kinetic;
|
||||
|
||||
/** Non-null only if the shape is exact */
|
||||
TriangleMesh *m_triangle_mesh;
|
||||
|
||||
public:
|
||||
PhysicalObject(bool kinetic, const XMLNode &node,
|
||||
scene::ISceneNode* scenenode);
|
||||
|
||||
/*
|
||||
PhysicalObject(const std::string& model,
|
||||
bodyTypes shape, float mass, float radius,
|
||||
const core::vector3df& hpr,
|
||||
const core::vector3df& pos,
|
||||
const core::vector3df& scale);
|
||||
*/
|
||||
|
||||
virtual ~PhysicalObject ();
|
||||
virtual void reset ();
|
||||
virtual void handleExplosion(const Vec3& pos, bool directHit);
|
||||
void update (float dt);
|
||||
void init ();
|
||||
bool isKinetic () const { return m_kinetic; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the rigid body of this physical object. */
|
||||
btRigidBody *getBody () { return m_body; }
|
||||
@ -112,6 +136,10 @@ public:
|
||||
* hits it. */
|
||||
bool isCrashReset() const { return m_crash_reset; }
|
||||
bool isExplodeKartObject () const { return m_explode_kart; }
|
||||
|
||||
void move(const Vec3& xyz, const core::vector3df& hpr);
|
||||
|
||||
LEAK_CHECK()
|
||||
}; // PhysicalObject
|
||||
|
||||
#endif
|
||||
|
@ -66,12 +66,12 @@ void CheckGoal::update(float dt)
|
||||
if(!obj->isSoccerBall())
|
||||
continue;
|
||||
|
||||
const Vec3 &xyz = obj->getNode()->getPosition();
|
||||
const Vec3 &xyz = obj->getPresentation<TrackObjectPresentationMesh>()->getNode()->getPosition();
|
||||
if(isTriggered(m_previous_position[ball_index], xyz, ball_index))
|
||||
{
|
||||
if(UserConfigParams::m_check_debug)
|
||||
printf("CHECK: Goal check structure %d triggered for object %s.\n",
|
||||
m_index, obj->getDebugName());
|
||||
m_index, obj->getPresentation<TrackObjectPresentationMesh>()->getNode()->getDebugName());
|
||||
trigger(ball_index);
|
||||
}
|
||||
m_previous_position[ball_index] = xyz;
|
||||
@ -122,7 +122,7 @@ void CheckGoal::reset(const Track &track)
|
||||
if(!obj->isSoccerBall())
|
||||
continue;
|
||||
|
||||
const Vec3 &xyz = obj->getNode()->getPosition();
|
||||
const Vec3 &xyz = obj->getPresentation<TrackObjectPresentationMesh>()->getNode()->getPosition();
|
||||
|
||||
m_previous_position.push_back(xyz);
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -28,6 +28,7 @@ namespace irr
|
||||
using namespace irr;
|
||||
|
||||
#include "items/item.hpp"
|
||||
#include "utils/cpp2011.h"
|
||||
#include "utils/no_copy.hpp"
|
||||
#include "utils/vec3.hpp"
|
||||
#include <string>
|
||||
@ -36,50 +37,12 @@ using namespace irr;
|
||||
class XMLNode;
|
||||
class SFXBase;
|
||||
class ParticleEmitter;
|
||||
class PhysicalObject;
|
||||
class ThreeDAnimation;
|
||||
|
||||
/**
|
||||
* \ingroup tracks
|
||||
* This is a base object for any separate object on the track, which
|
||||
* might also have a skeletal animation. This is used by objects that
|
||||
* have an IPO animation, as well as physical objects.
|
||||
*/
|
||||
class TrackObject : public scene::IAnimationEndCallBack, public NoCopy,
|
||||
public TriggerItemListener
|
||||
class TrackObjectPresentation
|
||||
{
|
||||
//public:
|
||||
// The different type of track objects: physical objects, graphical
|
||||
// objects (without a physical representation) - the latter might be
|
||||
// eye candy (to reduce work for physics), ...
|
||||
//enum TrackObjectType {TO_PHYSICAL, TO_GRAPHICAL};
|
||||
|
||||
private:
|
||||
/** True if the object is currently being displayed. */
|
||||
bool m_enabled;
|
||||
|
||||
/** True if it is a looped animation. */
|
||||
bool m_is_looped;
|
||||
|
||||
/** Start frame of the animation to be played. */
|
||||
unsigned int m_frame_start;
|
||||
|
||||
/** End frame of the animation to be played. */
|
||||
unsigned int m_frame_end;
|
||||
|
||||
/** Currently used for sound effects only, in cutscenes only atm */
|
||||
std::string m_trigger_condition;
|
||||
|
||||
virtual void OnAnimationEnd(scene::IAnimatedMeshSceneNode* node);
|
||||
|
||||
ParticleEmitter* m_emitter;
|
||||
|
||||
protected:
|
||||
/** The irrlicht scene node this object is attached to. */
|
||||
scene::ISceneNode *m_node;
|
||||
|
||||
/** The mesh used here. It needs to be stored so that it can be
|
||||
* removed from irrlicht's mesh cache when it is deleted. */
|
||||
scene::IMesh *m_mesh;
|
||||
|
||||
/** The initial XYZ position of the object. */
|
||||
core::vector3df m_init_xyz;
|
||||
|
||||
@ -88,42 +51,80 @@ protected:
|
||||
|
||||
/** The initial scale of the object. */
|
||||
core::vector3df m_init_scale;
|
||||
|
||||
/** If a sound is attached to this object and/or this is a sound emitter object */
|
||||
SFXBase* m_sound;
|
||||
|
||||
/** LOD group this object is part of, if it is LOD */
|
||||
std::string m_lod_group;
|
||||
|
||||
/** For action trigger objects */
|
||||
std::string m_action;
|
||||
|
||||
std::string m_interaction;
|
||||
|
||||
std::string m_type;
|
||||
|
||||
LODNode* m_lod_emitter_node;
|
||||
|
||||
bool m_soccer_ball;
|
||||
|
||||
|
||||
public:
|
||||
TrackObject(const XMLNode &xml_node);
|
||||
TrackObject();
|
||||
TrackObject(const core::vector3df& pos, const core::vector3df& hpr,
|
||||
const core::vector3df& scale, const std::string& model);
|
||||
~TrackObject();
|
||||
virtual void update(float dt);
|
||||
virtual void reset();
|
||||
/** To finish object constructions. Called after the track model
|
||||
* is ready. */
|
||||
virtual void init() {};
|
||||
/** Called when an explosion happens. As a default does nothing, will
|
||||
* e.g. be overwritten by physical objects etc. */
|
||||
virtual void handleExplosion(const Vec3& pos, bool directHit) {};
|
||||
void setEnable(bool mode);
|
||||
|
||||
TrackObjectPresentation(const XMLNode& xml_node);
|
||||
virtual ~TrackObjectPresentation() {}
|
||||
|
||||
virtual void reset() {}
|
||||
virtual void setEnable(bool enabled) {}
|
||||
virtual void update(float dt) {}
|
||||
virtual void move(const core::vector3df& xyz, const core::vector3df& hpr,
|
||||
const core::vector3df& scale) {}
|
||||
|
||||
virtual const core::vector3df& getPosition() const { return m_init_xyz; }
|
||||
virtual const core::vector3df& getRotation() const { return m_init_hpr; }
|
||||
virtual const core::vector3df& getScale() const { return m_init_scale; }
|
||||
|
||||
LEAK_CHECK()
|
||||
};
|
||||
|
||||
class TrackObjectPresentationSceneNode : public TrackObjectPresentation
|
||||
{
|
||||
protected:
|
||||
scene::ISceneNode* m_node;
|
||||
public:
|
||||
|
||||
TrackObjectPresentationSceneNode(const XMLNode& xml_node) :
|
||||
TrackObjectPresentation(xml_node)
|
||||
{
|
||||
m_node = NULL;
|
||||
}
|
||||
|
||||
virtual const core::vector3df& getPosition() const OVERRIDE;
|
||||
virtual const core::vector3df& getRotation() const OVERRIDE;
|
||||
virtual const core::vector3df& getScale() const OVERRIDE;
|
||||
virtual void move(const core::vector3df& xyz, const core::vector3df& hpr,
|
||||
const core::vector3df& scale) OVERRIDE;
|
||||
virtual void setEnable(bool enabled) OVERRIDE;
|
||||
virtual void reset() OVERRIDE;
|
||||
|
||||
scene::ISceneNode* getNode() { return m_node; }
|
||||
const scene::ISceneNode* getNode() const { return m_node; }
|
||||
};
|
||||
|
||||
class TrackObjectPresentationEmpty : public TrackObjectPresentationSceneNode
|
||||
{
|
||||
public:
|
||||
|
||||
TrackObjectPresentationEmpty(const XMLNode& xml_node);
|
||||
virtual ~TrackObjectPresentationEmpty();
|
||||
};
|
||||
|
||||
class TrackObjectPresentationMesh : public TrackObjectPresentationSceneNode
|
||||
{
|
||||
private:
|
||||
/** The mesh used here. It needs to be stored so that it can be
|
||||
* removed from irrlicht's mesh cache when it is deleted. */
|
||||
scene::IMesh *m_mesh;
|
||||
|
||||
/** True if it is a looped animation. */
|
||||
bool m_is_looped;
|
||||
|
||||
/** Start frame of the animation to be played. */
|
||||
unsigned int m_frame_start;
|
||||
|
||||
/** End frame of the animation to be played. */
|
||||
unsigned int m_frame_end;
|
||||
|
||||
public:
|
||||
TrackObjectPresentationMesh(const XMLNode& xml_node, bool enabled);
|
||||
virtual ~TrackObjectPresentationMesh();
|
||||
|
||||
virtual void reset() OVERRIDE;
|
||||
|
||||
|
||||
/** 2-step construction */
|
||||
void setNode(scene::ISceneNode* node)
|
||||
@ -149,22 +150,182 @@ public:
|
||||
m_node->setScale(m_init_scale);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class TrackObjectPresentationSound : public TrackObjectPresentation,
|
||||
public TriggerItemListener
|
||||
{
|
||||
private:
|
||||
|
||||
/** If a sound is attached to this object and/or this is a sound emitter object */
|
||||
SFXBase* m_sound;
|
||||
|
||||
/** Currently used for sound effects only, in cutscenes only atm */
|
||||
std::string m_trigger_condition;
|
||||
|
||||
core::vector3df m_xyz;
|
||||
|
||||
public:
|
||||
|
||||
TrackObjectPresentationSound(const XMLNode& xml_node);
|
||||
virtual ~TrackObjectPresentationSound();
|
||||
virtual void onTriggerItemApproached(Item* who) OVERRIDE;
|
||||
virtual void update(float dt) OVERRIDE;
|
||||
void triggerSound(bool loop);
|
||||
void stopSound();
|
||||
|
||||
/** Currently used for sound effects only, in cutscenes only atm */
|
||||
const std::string& getTriggerCondition() const { return m_trigger_condition; }
|
||||
|
||||
virtual void move(const core::vector3df& xyz, const core::vector3df& hpr,
|
||||
const core::vector3df& scale) OVERRIDE;
|
||||
};
|
||||
|
||||
class TrackObjectPresentationBillboard : public TrackObjectPresentationSceneNode
|
||||
{
|
||||
/** To make the billboard disappear when close to the camera. Useful for light halos :
|
||||
* instead of "colliding" with the camera and suddenly disappearing when clipped by
|
||||
* frustum culling, it will gently fade out.
|
||||
*/
|
||||
bool m_fade_out_when_close;
|
||||
float m_fade_out_start;
|
||||
float m_fade_out_end;
|
||||
public:
|
||||
TrackObjectPresentationBillboard(const XMLNode& xml_node);
|
||||
virtual ~TrackObjectPresentationBillboard();
|
||||
virtual void update(float dt) OVERRIDE;
|
||||
};
|
||||
|
||||
|
||||
class TrackObjectPresentationParticles : public TrackObjectPresentation
|
||||
{
|
||||
private:
|
||||
ParticleEmitter* m_emitter;
|
||||
LODNode* m_lod_emitter_node;
|
||||
std::string m_trigger_condition;
|
||||
|
||||
public:
|
||||
TrackObjectPresentationParticles(const XMLNode& xml_node);
|
||||
virtual ~TrackObjectPresentationParticles();
|
||||
|
||||
virtual void update(float dt) OVERRIDE;
|
||||
virtual void move(const core::vector3df& xyz, const core::vector3df& hpr,
|
||||
const core::vector3df& scale) OVERRIDE;
|
||||
std::string& getTriggerCondition() { return m_trigger_condition; }
|
||||
|
||||
void triggerParticles();
|
||||
};
|
||||
|
||||
class TrackObjectPresentationActionTrigger : public TrackObjectPresentation,
|
||||
public TriggerItemListener
|
||||
{
|
||||
private:
|
||||
|
||||
/** For action trigger objects */
|
||||
std::string m_action;
|
||||
|
||||
public:
|
||||
|
||||
|
||||
TrackObjectPresentationActionTrigger(const XMLNode& xml_node);
|
||||
virtual ~TrackObjectPresentationActionTrigger() {}
|
||||
|
||||
virtual void onTriggerItemApproached(Item* who) OVERRIDE;
|
||||
};
|
||||
|
||||
/**
|
||||
* \ingroup tracks
|
||||
* This is a base object for any separate object on the track, which
|
||||
* might also have a skeletal animation. This is used by objects that
|
||||
* have an IPO animation, as well as physical objects.
|
||||
*/
|
||||
class TrackObject : public NoCopy
|
||||
{
|
||||
//public:
|
||||
// The different type of track objects: physical objects, graphical
|
||||
// objects (without a physical representation) - the latter might be
|
||||
// eye candy (to reduce work for physics), ...
|
||||
//enum TrackObjectType {TO_PHYSICAL, TO_GRAPHICAL};
|
||||
|
||||
private:
|
||||
/** True if the object is currently being displayed. */
|
||||
bool m_enabled;
|
||||
|
||||
TrackObjectPresentation* m_presentation;
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
/** The initial XYZ position of the object. */
|
||||
core::vector3df m_init_xyz;
|
||||
|
||||
/** The initial hpr of the object. */
|
||||
core::vector3df m_init_hpr;
|
||||
|
||||
/** The initial scale of the object. */
|
||||
core::vector3df m_init_scale;
|
||||
|
||||
/** LOD group this object is part of, if it is LOD */
|
||||
std::string m_lod_group;
|
||||
|
||||
std::string m_interaction;
|
||||
|
||||
std::string m_type;
|
||||
|
||||
bool m_soccer_ball;
|
||||
|
||||
PhysicalObject* m_rigid_body;
|
||||
|
||||
ThreeDAnimation* m_animator;
|
||||
|
||||
|
||||
public:
|
||||
TrackObject(const XMLNode &xml_node);
|
||||
TrackObject();
|
||||
|
||||
/*
|
||||
TrackObject(const core::vector3df& pos, const core::vector3df& hpr,
|
||||
const core::vector3df& scale, const std::string& model);
|
||||
*/
|
||||
~TrackObject();
|
||||
virtual void update(float dt);
|
||||
virtual void reset();
|
||||
/** To finish object constructions. Called after the track model
|
||||
* is ready. */
|
||||
virtual void init() {};
|
||||
/** Called when an explosion happens. As a default does nothing, will
|
||||
* e.g. be overwritten by physical objects etc. */
|
||||
virtual void handleExplosion(const Vec3& pos, bool directHit) {};
|
||||
void setEnable(bool mode);
|
||||
|
||||
const std::string& getLodGroup() const { return m_lod_group; }
|
||||
|
||||
const std::string& getType() const { return m_type; }
|
||||
|
||||
bool isSoccerBall() const { return m_soccer_ball; }
|
||||
|
||||
const PhysicalObject* getPhysics() const { return m_rigid_body; }
|
||||
PhysicalObject* getPhysics() { return m_rigid_body; }
|
||||
|
||||
const core::vector3df getInitXYZ() const { return m_init_xyz; }
|
||||
const core::vector3df getInitRotation() const { return m_init_hpr; }
|
||||
const core::vector3df getInitScale() const { return m_init_scale; }
|
||||
|
||||
/** Currently used for sound effects only, in cutscenes only atm */
|
||||
const std::string& getTriggerCondition() const { return m_trigger_condition; }
|
||||
void move(const core::vector3df& xyz, const core::vector3df& hpr, const core::vector3df& scale);
|
||||
|
||||
template<typename T>
|
||||
T* getPresentation() { return dynamic_cast<T*>(m_presentation); }
|
||||
|
||||
template<typename T>
|
||||
const T* getPresentation() const { return dynamic_cast<T*>(m_presentation); }
|
||||
|
||||
void triggerSound(bool loop=false);
|
||||
void stopSound();
|
||||
void triggerParticles();
|
||||
|
||||
virtual void onTriggerItemApproached(Item* who);
|
||||
ThreeDAnimation* getAnimator() { return m_animator; }
|
||||
const ThreeDAnimation* getAnimator() const { return m_animator; }
|
||||
|
||||
const core::vector3df& getPosition() const;
|
||||
const core::vector3df& getRotation() const;
|
||||
const core::vector3df& getScale() const;
|
||||
}; // TrackObject
|
||||
|
||||
#endif
|
||||
|
@ -20,7 +20,6 @@
|
||||
|
||||
#include "animations/ipo.hpp"
|
||||
#include "config/user_config.hpp"
|
||||
#include "animations/billboard_animation.hpp"
|
||||
#include "animations/three_d_animation.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "graphics/lod_node.hpp"
|
||||
@ -52,6 +51,8 @@ void TrackObjectManager::add(const XMLNode &xml_node)
|
||||
{
|
||||
try
|
||||
{
|
||||
m_all_objects.push_back(new TrackObject(xml_node));
|
||||
/*
|
||||
std::string groupname;
|
||||
xml_node.get("lod_group", &groupname);
|
||||
bool is_lod = !groupname.empty();
|
||||
@ -67,11 +68,12 @@ void TrackObjectManager::add(const XMLNode &xml_node)
|
||||
{
|
||||
if (is_lod)
|
||||
{
|
||||
m_lod_objects[groupname].push_back(new PhysicalObject(xml_node));
|
||||
assert(false); // TODO
|
||||
//_lod_objects[groupname].push_back(new TrackObject(xml_node));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_all_objects.push_back(new PhysicalObject(xml_node));
|
||||
m_all_objects.push_back(new TrackObject(xml_node));
|
||||
}
|
||||
}
|
||||
else if(type=="animation")
|
||||
@ -106,6 +108,7 @@ void TrackObjectManager::add(const XMLNode &xml_node)
|
||||
fprintf(stderr, "Unknown track object: '%s' - ignored.\n",
|
||||
type.c_str());
|
||||
}
|
||||
*/
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
@ -153,8 +156,8 @@ void TrackObjectManager::handleExplosion(const Vec3 &pos, const PhysicalObject *
|
||||
TrackObject* curr;
|
||||
for_in (curr, m_all_objects)
|
||||
{
|
||||
if(secondary_hits || mp==curr)
|
||||
curr->handleExplosion(pos, mp == curr);
|
||||
if(secondary_hits || mp == curr->getPhysics())
|
||||
curr->handleExplosion(pos, mp == curr->getPhysics());
|
||||
}
|
||||
} // handleExplosion
|
||||
|
||||
@ -228,27 +231,33 @@ void TrackObjectManager::enableFog(bool enable)
|
||||
TrackObject* curr;
|
||||
for_in (curr, m_all_objects)
|
||||
{
|
||||
if (curr->getNode() != NULL)
|
||||
TrackObjectPresentationMesh* meshPresentation =
|
||||
curr->getPresentation<TrackObjectPresentationMesh>();
|
||||
if (meshPresentation!= NULL)
|
||||
{
|
||||
adjustForFog(curr->getNode(), enable);
|
||||
adjustForFog(meshPresentation->getNode(), enable);
|
||||
}
|
||||
}
|
||||
} // enableFog
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
PhysicalObject* TrackObjectManager::insertObject(const std::string& model,
|
||||
TrackObject* TrackObjectManager::insertObject(const std::string& model,
|
||||
PhysicalObject::bodyTypes shape,
|
||||
float mass, float radius,
|
||||
const core::vector3df& hpr,
|
||||
const core::vector3df& pos,
|
||||
const core::vector3df& scale)
|
||||
{
|
||||
/*
|
||||
PhysicalObject* object = new PhysicalObject(model, shape, mass, radius,
|
||||
hpr, pos, scale);
|
||||
object->init();
|
||||
m_all_objects.push_back(object);
|
||||
return object;
|
||||
*/
|
||||
assert(false);
|
||||
// TODO
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -256,7 +265,7 @@ PhysicalObject* TrackObjectManager::insertObject(const std::string& model,
|
||||
* track objects, and then frees the object.
|
||||
* \param obj The physical object to remove.
|
||||
*/
|
||||
void TrackObjectManager::removeObject(PhysicalObject* obj)
|
||||
void TrackObjectManager::removeObject(TrackObject* obj)
|
||||
{
|
||||
m_all_objects.remove(obj);
|
||||
delete obj;
|
||||
@ -277,7 +286,7 @@ void TrackObjectManager::assingLodNodes(const std::vector<LODNode*>& lod_nodes)
|
||||
std::vector<TrackObject*>& queue = m_lod_objects[ lod_nodes[n]->getGroupName() ];
|
||||
assert( queue.size() > 0 );
|
||||
TrackObject* obj = queue[ queue.size() - 1 ];
|
||||
obj->setNode( lod_nodes[n] );
|
||||
obj->getPresentation<TrackObjectPresentationMesh>()->setNode( lod_nodes[n] );
|
||||
queue.erase( queue.end() - 1 );
|
||||
|
||||
m_all_objects.push_back(obj);
|
||||
|
@ -64,14 +64,14 @@ public:
|
||||
/** Enable or disable fog on objects */
|
||||
void enableFog(bool enable);
|
||||
|
||||
PhysicalObject* insertObject(const std::string& model,
|
||||
TrackObject* insertObject(const std::string& model,
|
||||
PhysicalObject::bodyTypes shape,
|
||||
float mass, float radius,
|
||||
const core::vector3df& hpr,
|
||||
const core::vector3df& pos,
|
||||
const core::vector3df& scale);
|
||||
|
||||
void removeObject(PhysicalObject* who);
|
||||
void removeObject(TrackObject* who);
|
||||
|
||||
void assingLodNodes(const std::vector<LODNode*>& lod);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user