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>
|
#include <algorithm>
|
||||||
|
|
||||||
AnimationBase::AnimationBase(const XMLNode &node)
|
AnimationBase::AnimationBase(const XMLNode &node)
|
||||||
: TrackObject(node)
|
|
||||||
{
|
{
|
||||||
float fps=25;
|
float fps=25;
|
||||||
node.get("fps", &fps);
|
node.get("fps", &fps);
|
||||||
@ -43,12 +42,12 @@ AnimationBase::AnimationBase(const XMLNode &node)
|
|||||||
{
|
{
|
||||||
m_playing = false;
|
m_playing = false;
|
||||||
}
|
}
|
||||||
|
reset();
|
||||||
} // AnimationBase
|
} // AnimationBase
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
/** Special constructor which takes one IPO (or curve). This is used by the
|
/** 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_anim_type = ATT_CYCLIC_ONCE;
|
||||||
m_playing = true;
|
m_playing = true;
|
||||||
@ -83,8 +82,6 @@ void AnimationBase::reset()
|
|||||||
{
|
{
|
||||||
curr->reset();
|
curr->reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
TrackObject::reset();
|
|
||||||
} // reset
|
} // reset
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@ -95,12 +92,14 @@ void AnimationBase::reset()
|
|||||||
*/
|
*/
|
||||||
void AnimationBase::update(float dt, Vec3 *xyz, Vec3 *hpr, Vec3 *scale)
|
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
|
// Don't do anything if the animation is disabled
|
||||||
if(!m_playing) return;
|
if(!m_playing) return;
|
||||||
m_current_time += dt;
|
m_current_time += dt;
|
||||||
|
|
||||||
|
assert(!isnan(m_current_time));
|
||||||
|
|
||||||
Ipo* curr;
|
Ipo* curr;
|
||||||
for_in (curr, m_all_ipos)
|
for_in (curr, m_all_ipos)
|
||||||
{
|
{
|
||||||
|
@ -30,7 +30,6 @@
|
|||||||
// Note that ipo.hpp is included here in order that PtrVector<Ipo> can call
|
// Note that ipo.hpp is included here in order that PtrVector<Ipo> can call
|
||||||
// the proper destructor!
|
// the proper destructor!
|
||||||
#include "animations/ipo.hpp"
|
#include "animations/ipo.hpp"
|
||||||
#include "tracks/track_object.hpp"
|
|
||||||
#include "utils/ptr_vector.hpp"
|
#include "utils/ptr_vector.hpp"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
@ -41,7 +40,7 @@ class XMLNode;
|
|||||||
* \brief A base class for all animations.
|
* \brief A base class for all animations.
|
||||||
* \ingroup animations
|
* \ingroup animations
|
||||||
*/
|
*/
|
||||||
class AnimationBase : public TrackObject
|
class AnimationBase
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
/** Two types of animations: cyclic ones that play all the time, and
|
/** 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)
|
* \param scale The scale that needs to be updated (can be NULL)
|
||||||
*/
|
*/
|
||||||
void Ipo::update(float time, Vec3 *xyz, Vec3 *hpr,Vec3 *scale)
|
void Ipo::update(float time, Vec3 *xyz, Vec3 *hpr,Vec3 *scale)
|
||||||
{
|
{
|
||||||
|
assert(!isnan(time));
|
||||||
switch(m_ipo_data->m_channel)
|
switch(m_ipo_data->m_channel)
|
||||||
{
|
{
|
||||||
case Ipo::IPO_LOCX : if(xyz) xyz ->setX(get(time, 0)); break;
|
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
|
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.
|
// Avoid crash in case that only one point is given for this IPO.
|
||||||
if(m_next_n==0)
|
if(m_next_n==0)
|
||||||
return m_ipo_data->m_points[0][index];
|
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 &&
|
while(m_next_n<m_ipo_data->m_points.size()-1 &&
|
||||||
time >=m_ipo_data->m_points[m_next_n].getW())
|
time >=m_ipo_data->m_points[m_next_n].getW())
|
||||||
m_next_n++;
|
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
|
} // get
|
||||||
|
@ -29,15 +29,17 @@
|
|||||||
#include "modes/world.hpp"
|
#include "modes/world.hpp"
|
||||||
#include "physics/kart_motion_state.hpp"
|
#include "physics/kart_motion_state.hpp"
|
||||||
#include "physics/physics.hpp"
|
#include "physics/physics.hpp"
|
||||||
|
#include "physics/physical_object.hpp"
|
||||||
#include "physics/triangle_mesh.hpp"
|
#include "physics/triangle_mesh.hpp"
|
||||||
#include "tracks/bezier_curve.hpp"
|
#include "tracks/bezier_curve.hpp"
|
||||||
#include "utils/constants.hpp"
|
#include "utils/constants.hpp"
|
||||||
#include <ISceneManager.h>
|
#include <ISceneManager.h>
|
||||||
#include <IMeshSceneNode.h>
|
#include <IMeshSceneNode.h>
|
||||||
|
|
||||||
ThreeDAnimation::ThreeDAnimation(const XMLNode &node)
|
ThreeDAnimation::ThreeDAnimation(const XMLNode &node, TrackObject* object) : AnimationBase(node)
|
||||||
: AnimationBase(node)
|
|
||||||
{
|
{
|
||||||
|
m_object = object;
|
||||||
|
|
||||||
m_crash_reset = false;
|
m_crash_reset = false;
|
||||||
m_explode_kart = false;
|
m_explode_kart = false;
|
||||||
node.get("reset", &m_crash_reset);
|
node.get("reset", &m_crash_reset);
|
||||||
@ -45,259 +47,21 @@ ThreeDAnimation::ThreeDAnimation(const XMLNode &node)
|
|||||||
|
|
||||||
m_important_animation = (World::getWorld()->getIdent() == IDENT_CUSTSCENE);
|
m_important_animation = (World::getWorld()->getIdent() == IDENT_CUSTSCENE);
|
||||||
node.get("important", &m_important_animation);
|
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;
|
/** Save the initial position and rotation in the base animation object. */
|
||||||
m_motion_state = NULL;
|
setInitialTransform(object->getInitXYZ(),
|
||||||
m_collision_shape = NULL;
|
object->getInitRotation() );
|
||||||
std::string shape;
|
m_hpr = object->getInitRotation();
|
||||||
node.get("shape", &shape);
|
|
||||||
if(shape!="")
|
assert(!isnan(m_hpr.getX()));
|
||||||
{
|
assert(!isnan(m_hpr.getY()));
|
||||||
createPhysicsBody(shape);
|
assert(!isnan(m_hpr.getZ()));
|
||||||
}
|
|
||||||
if (m_node == NULL)
|
|
||||||
{
|
|
||||||
m_node = irr_driver->getSceneManager()->addEmptySceneNode();
|
|
||||||
}
|
|
||||||
} // ThreeDAnimation
|
} // 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. */
|
/** Destructor. */
|
||||||
ThreeDAnimation::~ThreeDAnimation()
|
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
|
} // ~ThreeDAnimation
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@ -308,12 +72,13 @@ void ThreeDAnimation::update(float dt)
|
|||||||
{
|
{
|
||||||
//if ( UserConfigParams::m_graphical_effects || m_important_animation )
|
//if ( UserConfigParams::m_graphical_effects || m_important_animation )
|
||||||
{
|
{
|
||||||
Vec3 xyz = m_node->getPosition();
|
Vec3 xyz = m_object->getPosition();
|
||||||
Vec3 scale = m_node->getScale();
|
Vec3 scale = m_object->getScale();
|
||||||
|
|
||||||
AnimationBase::update(dt, &xyz, &m_hpr, &scale); //updates all IPOs
|
AnimationBase::update(dt, &xyz, &m_hpr, &scale); //updates all IPOs
|
||||||
m_node->setPosition(xyz.toIrrVector());
|
//m_node->setPosition(xyz.toIrrVector());
|
||||||
m_node->setScale(scale.toIrrVector());
|
//m_node->setScale(scale.toIrrVector());
|
||||||
|
|
||||||
// Note that the rotation order of irrlicht is different from the one
|
// Note that the rotation order of irrlicht is different from the one
|
||||||
// in blender. So in order to reproduce the blender IPO rotations
|
// in blender. So in order to reproduce the blender IPO rotations
|
||||||
// correctly, we have to get the rotations around each axis and combine
|
// correctly, we have to get the rotations around each axis and combine
|
||||||
@ -321,6 +86,9 @@ void ThreeDAnimation::update(float dt)
|
|||||||
core::matrix4 m;
|
core::matrix4 m;
|
||||||
m.makeIdentity();
|
m.makeIdentity();
|
||||||
core::matrix4 mx;
|
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));
|
mx.setRotationDegrees(core::vector3df(m_hpr.getX(), 0, 0));
|
||||||
core::matrix4 my;
|
core::matrix4 my;
|
||||||
my.setRotationDegrees(core::vector3df(0, m_hpr.getY(), 0));
|
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()));
|
mz.setRotationDegrees(core::vector3df(0, 0, m_hpr.getZ()));
|
||||||
m = my*mz*mx;
|
m = my*mz*mx;
|
||||||
core::vector3df hpr = m.getRotationDegrees();
|
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_object)
|
||||||
if(m_body)
|
|
||||||
{
|
{
|
||||||
Vec3 hpr2(hpr);
|
m_object->move(xyz.toIrrVector(), hpr, scale.toIrrVector());
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // update
|
} // update
|
||||||
|
@ -29,6 +29,12 @@ using namespace irr;
|
|||||||
#include "animations/animation_base.hpp"
|
#include "animations/animation_base.hpp"
|
||||||
#include "physics/user_pointer.hpp"
|
#include "physics/user_pointer.hpp"
|
||||||
|
|
||||||
|
namespace irr
|
||||||
|
{
|
||||||
|
namespace scene { class IAnimatedMesh; class ISceneNode; class IMesh; }
|
||||||
|
}
|
||||||
|
|
||||||
|
class TrackObject;
|
||||||
class BezierCurve;
|
class BezierCurve;
|
||||||
class XMLNode;
|
class XMLNode;
|
||||||
|
|
||||||
@ -38,21 +44,8 @@ class XMLNode;
|
|||||||
class ThreeDAnimation : public AnimationBase
|
class ThreeDAnimation : public AnimationBase
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
/** The bullet collision shape for the physics. */
|
TrackObject *m_object;
|
||||||
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;
|
|
||||||
|
|
||||||
/** True if a collision with this object should trigger
|
/** True if a collision with this object should trigger
|
||||||
* rescuing a kart. */
|
* rescuing a kart. */
|
||||||
bool m_crash_reset;
|
bool m_crash_reset;
|
||||||
@ -71,10 +64,10 @@ private:
|
|||||||
*/
|
*/
|
||||||
bool m_important_animation;
|
bool m_important_animation;
|
||||||
|
|
||||||
void createPhysicsBody(const std::string &shape);
|
//scene::ISceneNode* m_node;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ThreeDAnimation(const XMLNode &node);
|
ThreeDAnimation(const XMLNode &node, TrackObject* object);
|
||||||
virtual ~ThreeDAnimation();
|
virtual ~ThreeDAnimation();
|
||||||
virtual void update(float dt);
|
virtual void update(float dt);
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
@ -589,3 +589,12 @@ int XMLNode::getHPR(Vec3 *value) const
|
|||||||
} // getHPR Vec3
|
} // 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 getXYZ(Vec3 *vaslue) const;
|
||||||
int getHPR(core::vector3df *value) const;
|
int getHPR(core::vector3df *value) const;
|
||||||
int getHPR(Vec3 *value) const;
|
int getHPR(Vec3 *value) const;
|
||||||
|
|
||||||
|
bool hasChildNamed(const char* name) const;
|
||||||
|
|
||||||
/** Handy functions to test the bit pattern returned by get(vector3df*).*/
|
/** Handy functions to test the bit pattern returned by get(vector3df*).*/
|
||||||
static bool hasX(int b) { return (b&1)==1; }
|
static bool hasX(int b) { return (b&1)==1; }
|
||||||
static bool hasY(int b) { return (b&2)==2; }
|
static bool hasY(int b) { return (b&2)==2; }
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include <ISceneManager.h>
|
#include <ISceneManager.h>
|
||||||
|
|
||||||
#include "animations/animation_base.hpp"
|
#include "animations/animation_base.hpp"
|
||||||
|
#include "animations/three_d_animation.hpp"
|
||||||
#include "audio/music_manager.hpp"
|
#include "audio/music_manager.hpp"
|
||||||
#include "challenges/game_slot.hpp"
|
#include "challenges/game_slot.hpp"
|
||||||
#include "challenges/unlock_manager.hpp"
|
#include "challenges/unlock_manager.hpp"
|
||||||
@ -82,9 +83,10 @@ void CutsceneWorld::init()
|
|||||||
TrackObject* curr;
|
TrackObject* curr;
|
||||||
for_in(curr, objects)
|
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 "))
|
if (StringUtils::startsWith(condition, "frame "))
|
||||||
{
|
{
|
||||||
@ -102,9 +104,9 @@ void CutsceneWorld::init()
|
|||||||
m_particles_to_trigger[frame / FPS].push_back(curr);
|
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 "))
|
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
|
float FPS = 25.0f; // for now we assume the cutscene is saved at 25 FPS
|
||||||
m_sounds_to_stop[frame / FPS].push_back(curr);
|
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,
|
m_duration = std::max(m_duration,
|
||||||
(double)dynamic_cast<AnimationBase*>(curr)
|
(double)curr->getAnimator()->getAnimationDuration());
|
||||||
->getAnimationDuration());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -273,10 +274,11 @@ void CutsceneWorld::update(float dt)
|
|||||||
{
|
{
|
||||||
if (curr->getType() == "cutscene_camera")
|
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();
|
m_camera->updateAbsolutePosition();
|
||||||
|
|
||||||
core::vector3df rot = curr->getNode()->getRotation();
|
core::vector3df rot = anchorNode->getRotation();
|
||||||
Vec3 rot2(rot);
|
Vec3 rot2(rot);
|
||||||
rot2.setPitch(rot2.getPitch() + 90.0f);
|
rot2.setPitch(rot2.getPitch() + 90.0f);
|
||||||
m_camera->setRotation(rot2.toIrrVector());
|
m_camera->setRotation(rot2.toIrrVector());
|
||||||
@ -299,7 +301,7 @@ void CutsceneWorld::update(float dt)
|
|||||||
std::vector<TrackObject*> objects = it->second;
|
std::vector<TrackObject*> objects = it->second;
|
||||||
for (unsigned int i = 0; i < objects.size(); i++)
|
for (unsigned int i = 0; i < objects.size(); i++)
|
||||||
{
|
{
|
||||||
objects[i]->triggerSound();
|
objects[i]->getPresentation<TrackObjectPresentationSound>()->triggerSound(false);
|
||||||
}
|
}
|
||||||
m_sounds_to_trigger.erase(it++);
|
m_sounds_to_trigger.erase(it++);
|
||||||
}
|
}
|
||||||
@ -317,7 +319,7 @@ void CutsceneWorld::update(float dt)
|
|||||||
std::vector<TrackObject*> objects = it->second;
|
std::vector<TrackObject*> objects = it->second;
|
||||||
for (unsigned int i = 0; i < objects.size(); i++)
|
for (unsigned int i = 0; i < objects.size(); i++)
|
||||||
{
|
{
|
||||||
objects[i]->triggerParticles();
|
objects[i]->getPresentation<TrackObjectPresentationParticles>()->triggerParticles();
|
||||||
}
|
}
|
||||||
m_particles_to_trigger.erase(it++);
|
m_particles_to_trigger.erase(it++);
|
||||||
}
|
}
|
||||||
@ -334,7 +336,7 @@ void CutsceneWorld::update(float dt)
|
|||||||
std::vector<TrackObject*> objects = it->second;
|
std::vector<TrackObject*> objects = it->second;
|
||||||
for (unsigned int i = 0; i < objects.size(); i++)
|
for (unsigned int i = 0; i < objects.size(); i++)
|
||||||
{
|
{
|
||||||
objects[i]->stopSound();
|
objects[i]->getPresentation<TrackObjectPresentationSound>()->stopSound();
|
||||||
}
|
}
|
||||||
m_sounds_to_stop.erase(it++);
|
m_sounds_to_stop.erase(it++);
|
||||||
}
|
}
|
||||||
|
@ -123,7 +123,7 @@ void ThreeStrikesBattle::reset()
|
|||||||
evt.m_kart_info = m_kart_info;
|
evt.m_kart_info = m_kart_info;
|
||||||
m_battle_events.push_back(evt);
|
m_battle_events.push_back(evt);
|
||||||
|
|
||||||
PhysicalObject *obj;
|
TrackObject *obj;
|
||||||
for_in(obj, m_tires)
|
for_in(obj, m_tires)
|
||||||
{
|
{
|
||||||
m_track->getTrackObjectManager()->removeObject(obj);
|
m_track->getTrackObjectManager()->removeObject(obj);
|
||||||
@ -330,6 +330,8 @@ void ThreeStrikesBattle::update(float dt)
|
|||||||
tire = m_tire_dir+"/wheel-rear-right.b3d";
|
tire = m_tire_dir+"/wheel-rear-right.b3d";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: add back tires
|
||||||
|
#if 0
|
||||||
TrackObjectManager* tom = m_track->getTrackObjectManager();
|
TrackObjectManager* tom = m_track->getTrackObjectManager();
|
||||||
PhysicalObject* obj =
|
PhysicalObject* obj =
|
||||||
tom->insertObject(tire,
|
tom->insertObject(tire,
|
||||||
@ -349,6 +351,7 @@ void ThreeStrikesBattle::update(float dt)
|
|||||||
m_insert_tire = 0;
|
m_insert_tire = 0;
|
||||||
|
|
||||||
m_tires.push_back(obj);
|
m_tires.push_back(obj);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
} // update
|
} // update
|
||||||
|
|
||||||
|
@ -19,7 +19,9 @@
|
|||||||
#ifndef THREE_STRIKES_HPP
|
#ifndef THREE_STRIKES_HPP
|
||||||
#define THREE_STRIKES_HPP
|
#define THREE_STRIKES_HPP
|
||||||
|
|
||||||
|
|
||||||
#include "modes/world_with_rank.hpp"
|
#include "modes/world_with_rank.hpp"
|
||||||
|
#include "tracks/track_object.hpp"
|
||||||
#include "states_screens/race_gui_base.hpp"
|
#include "states_screens/race_gui_base.hpp"
|
||||||
|
|
||||||
#include <IMesh.h>
|
#include <IMesh.h>
|
||||||
@ -68,7 +70,7 @@ private:
|
|||||||
/** A rotation to apply to the tires when inserting them. */
|
/** A rotation to apply to the tires when inserting them. */
|
||||||
float m_tire_rotation;
|
float m_tire_rotation;
|
||||||
|
|
||||||
PtrVector<PhysicalObject, REF> m_tires;
|
PtrVector<TrackObject, REF> m_tires;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -746,6 +746,14 @@ void World::updateWorld(float dt)
|
|||||||
|
|
||||||
#define MEASURE_FPS 0
|
#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.
|
/** Updates the physics, all karts, the track, and projectile manager.
|
||||||
* \param dt Time step size.
|
* \param dt Time step size.
|
||||||
|
@ -252,8 +252,7 @@ public:
|
|||||||
void schedulePause(Phase phase);
|
void schedulePause(Phase phase);
|
||||||
void scheduleUnpause();
|
void scheduleUnpause();
|
||||||
void scheduleExitRace() { m_schedule_exit_race = true; }
|
void scheduleExitRace() { m_schedule_exit_race = true; }
|
||||||
void scheduleTutorial() { m_schedule_exit_race = true;
|
void scheduleTutorial();
|
||||||
m_schedule_tutorial = true; }
|
|
||||||
void updateWorld(float dt);
|
void updateWorld(float dt);
|
||||||
void handleExplosion(const Vec3 &xyz, AbstractKart *kart_hit,
|
void handleExplosion(const Vec3 &xyz, AbstractKart *kart_hit,
|
||||||
PhysicalObject *object);
|
PhysicalObject *object);
|
||||||
|
@ -24,11 +24,13 @@
|
|||||||
using namespace irr;
|
using namespace irr;
|
||||||
|
|
||||||
#include "graphics/irr_driver.hpp"
|
#include "graphics/irr_driver.hpp"
|
||||||
|
#include "graphics/material_manager.hpp"
|
||||||
#include "graphics/mesh_tools.hpp"
|
#include "graphics/mesh_tools.hpp"
|
||||||
#include "io/file_manager.hpp"
|
#include "io/file_manager.hpp"
|
||||||
#include "io/xml_node.hpp"
|
#include "io/xml_node.hpp"
|
||||||
#include "modes/world.hpp"
|
#include "modes/world.hpp"
|
||||||
#include "physics/physics.hpp"
|
#include "physics/physics.hpp"
|
||||||
|
#include "physics/triangle_mesh.hpp"
|
||||||
#include "tracks/track.hpp"
|
#include "tracks/track.hpp"
|
||||||
#include "utils/constants.hpp"
|
#include "utils/constants.hpp"
|
||||||
#include "utils/string_utils.hpp"
|
#include "utils/string_utils.hpp"
|
||||||
@ -37,8 +39,9 @@ using namespace irr;
|
|||||||
#include <IMeshSceneNode.h>
|
#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_shape = NULL;
|
||||||
m_body = NULL;
|
m_body = NULL;
|
||||||
@ -50,6 +53,12 @@ PhysicalObject::PhysicalObject(const XMLNode &xml_node)
|
|||||||
m_crash_reset = false;
|
m_crash_reset = false;
|
||||||
m_explode_kart = 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;
|
std::string shape;
|
||||||
xml_node.get("mass", &m_mass );
|
xml_node.get("mass", &m_mass );
|
||||||
xml_node.get("radius", &m_radius );
|
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=="box" ) m_body_type = MP_BOX;
|
||||||
else if(shape=="sphere" ) m_body_type = MP_SPHERE;
|
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());
|
else fprintf(stderr, "Unknown shape type : %s\n", shape.c_str());
|
||||||
|
|
||||||
m_init_pos.setIdentity();
|
m_init_pos.setIdentity();
|
||||||
Vec3 hpr(m_init_hpr);
|
Vec3 radHpr(m_init_hpr);
|
||||||
hpr.degreeToRad();
|
radHpr.degreeToRad();
|
||||||
btQuaternion q;
|
btQuaternion q;
|
||||||
q.setEuler(hpr.getY(), hpr.getX(), hpr.getZ());
|
q.setEuler(radHpr.getY(),radHpr.getX(), radHpr.getZ());
|
||||||
m_init_pos.setRotation(q);
|
m_init_pos.setRotation(q);
|
||||||
Vec3 init_xyz(m_init_xyz);
|
Vec3 init_xyz(m_init_xyz);
|
||||||
m_init_pos.setOrigin(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::PhysicalObject(const std::string& model,
|
PhysicalObject::PhysicalObject(const std::string& model,
|
||||||
bodyTypes shape, float mass, float radius,
|
bodyTypes shape, float mass, float radius,
|
||||||
const core::vector3df& hpr,
|
const core::vector3df& hpr,
|
||||||
const core::vector3df& pos,
|
const core::vector3df& pos,
|
||||||
const core::vector3df& scale)
|
const core::vector3df& scale)
|
||||||
: TrackObject(pos, hpr, scale, model)
|
|
||||||
{
|
{
|
||||||
m_body_type = shape;
|
m_body_type = shape;
|
||||||
m_mass = mass;
|
m_mass = mass;
|
||||||
@ -114,16 +118,48 @@ PhysicalObject::PhysicalObject(const std::string& model,
|
|||||||
m_init_pos.setRotation(q);
|
m_init_pos.setRotation(q);
|
||||||
m_init_pos.setOrigin(btVector3(pos.X, pos.Y, pos.Z));
|
m_init_pos.setOrigin(btVector3(pos.X, pos.Y, pos.Z));
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
PhysicalObject::~PhysicalObject()
|
PhysicalObject::~PhysicalObject()
|
||||||
{
|
{
|
||||||
World::getWorld()->getPhysics()->removeBody(m_body);
|
World::getWorld()->getPhysics()->removeBody(m_body);
|
||||||
delete m_body;
|
delete m_body;
|
||||||
delete m_motion_state;
|
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
|
} // ~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.
|
/** Additional initialisation after loading of the model is finished.
|
||||||
*/
|
*/
|
||||||
@ -187,57 +223,197 @@ void PhysicalObject::init()
|
|||||||
m_graphical_offset = -0.5f*(max+min);
|
m_graphical_offset = -0.5f*(max+min);
|
||||||
switch (m_body_type)
|
switch (m_body_type)
|
||||||
{
|
{
|
||||||
case MP_CONE_Y: {
|
case MP_CONE_Y:
|
||||||
if(m_radius<0) m_radius = 0.5f*extend.length_2d();
|
{
|
||||||
m_shape = new btConeShape(m_radius, extend.getY());
|
if (m_radius < 0) m_radius = 0.5f*extend.length_2d();
|
||||||
break;
|
m_shape = new btConeShape(m_radius, extend.getY());
|
||||||
}
|
break;
|
||||||
case MP_CONE_X: {
|
}
|
||||||
if(m_radius<0)
|
case MP_CONE_X:
|
||||||
m_radius = 0.5f*sqrt(extend.getY()*extend.getY() +
|
{
|
||||||
extend.getZ()*extend.getZ());
|
if (m_radius < 0)
|
||||||
m_shape = new btConeShapeX(m_radius, extend.getY());
|
m_radius = 0.5f*sqrt(extend.getY()*extend.getY() +
|
||||||
break;
|
extend.getZ()*extend.getZ());
|
||||||
}
|
m_shape = new btConeShapeX(m_radius, extend.getY());
|
||||||
case MP_CONE_Z: {
|
break;
|
||||||
if(m_radius<0)
|
}
|
||||||
m_radius = 0.5f*sqrt(extend.getX()*extend.getX() +
|
case MP_CONE_Z:
|
||||||
extend.getY()*extend.getY());
|
{
|
||||||
m_shape = new btConeShapeZ(m_radius, extend.getY());
|
if (m_radius < 0)
|
||||||
break;
|
m_radius = 0.5f*sqrt(extend.getX()*extend.getX() +
|
||||||
}
|
extend.getY()*extend.getY());
|
||||||
case MP_CYLINDER_Y: {
|
m_shape = new btConeShapeZ(m_radius, extend.getY());
|
||||||
if(m_radius<0) m_radius = 0.5f*extend.length_2d();
|
break;
|
||||||
m_shape = new btCylinderShape(0.5f*extend);
|
}
|
||||||
break;
|
case MP_CYLINDER_Y:
|
||||||
}
|
{
|
||||||
case MP_CYLINDER_X: {
|
if (m_radius < 0) m_radius = 0.5f*extend.length_2d();
|
||||||
if(m_radius<0)
|
m_shape = new btCylinderShape(0.5f*extend);
|
||||||
m_radius = 0.5f*sqrt(extend.getY()*extend.getY() +
|
break;
|
||||||
extend.getZ()*extend.getZ());
|
}
|
||||||
m_shape = new btCylinderShapeX(0.5f*extend);
|
case MP_CYLINDER_X:
|
||||||
break;
|
{
|
||||||
}
|
if (m_radius < 0)
|
||||||
case MP_CYLINDER_Z: {
|
m_radius = 0.5f*sqrt(extend.getY()*extend.getY() +
|
||||||
if(m_radius<0)
|
extend.getZ()*extend.getZ());
|
||||||
m_radius = 0.5f*sqrt(extend.getX()*extend.getX() +
|
m_shape = new btCylinderShapeX(0.5f*extend);
|
||||||
extend.getY()*extend.getY());
|
break;
|
||||||
m_shape = new btCylinderShapeZ(0.5f*extend);
|
}
|
||||||
break;
|
case MP_CYLINDER_Z:
|
||||||
}
|
{
|
||||||
case MP_BOX: m_shape = new btBoxShape(0.5*extend);
|
if (m_radius < 0)
|
||||||
break;
|
m_radius = 0.5f*sqrt(extend.getX()*extend.getX() +
|
||||||
case MP_SPHERE: {
|
extend.getY()*extend.getY());
|
||||||
if(m_radius<0)
|
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());
|
int indx=mbIndices[j+k];
|
||||||
m_radius = 0.5f*std::max(m_radius, extend.getZ());
|
core::vector3df v = mbVertices[indx].Pos;
|
||||||
}
|
//mat.transformVect(v);
|
||||||
m_shape = new btSphereShape(m_radius);
|
vertices[k]=v;
|
||||||
break;
|
normals[k]=mbVertices[indx].Normal;
|
||||||
}
|
} // for k
|
||||||
case MP_NONE: fprintf(stderr, "WARNING: Uninitialised moving shape\n");
|
if(tmesh) tmesh->addTriangle(vertices[0], vertices[1],
|
||||||
break;
|
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
|
// 2. Create the rigid object
|
||||||
@ -258,11 +434,19 @@ void PhysicalObject::init()
|
|||||||
m_body->setUserPointer(&m_user_pointer);
|
m_body->setUserPointer(&m_user_pointer);
|
||||||
|
|
||||||
World::getWorld()->getPhysics()->addBody(m_body);
|
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
|
} // init
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
void PhysicalObject::update(float dt)
|
void PhysicalObject::update(float dt)
|
||||||
{
|
{
|
||||||
|
if (!m_kinetic) return;
|
||||||
|
|
||||||
btTransform t;
|
btTransform t;
|
||||||
m_motion_state->getWorldTransform(t);
|
m_motion_state->getWorldTransform(t);
|
||||||
|
|
||||||
|
@ -26,22 +26,35 @@
|
|||||||
#include "physics/user_pointer.hpp"
|
#include "physics/user_pointer.hpp"
|
||||||
#include "tracks/track_object.hpp"
|
#include "tracks/track_object.hpp"
|
||||||
#include "utils/vec3.hpp"
|
#include "utils/vec3.hpp"
|
||||||
|
#include "utils/leak_check.hpp"
|
||||||
|
|
||||||
class XMLNode;
|
class XMLNode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \ingroup physics
|
* \ingroup physics
|
||||||
*/
|
*/
|
||||||
class PhysicalObject : public TrackObject
|
class PhysicalObject
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/** The supported collision shapes. */
|
/** The supported collision shapes. */
|
||||||
enum bodyTypes {MP_NONE,
|
enum bodyTypes {MP_NONE,
|
||||||
MP_CONE_Y, MP_CONE_X, MP_CONE_Z,
|
MP_CONE_Y, MP_CONE_X, MP_CONE_Z,
|
||||||
MP_CYLINDER_Y, MP_CYLINDER_X, MP_CYLINDER_Z,
|
MP_CYLINDER_Y, MP_CYLINDER_X, MP_CYLINDER_Z,
|
||||||
MP_BOX, MP_SPHERE};
|
MP_BOX, MP_SPHERE, MP_EXACT};
|
||||||
|
|
||||||
private:
|
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. */
|
/** The shape of this object. */
|
||||||
bodyTypes m_body_type;
|
bodyTypes m_body_type;
|
||||||
|
|
||||||
@ -90,20 +103,31 @@ private:
|
|||||||
/** If m_reset_when_too_low this object is set back to its start
|
/** If m_reset_when_too_low this object is set back to its start
|
||||||
* position if its height is below this value. */
|
* position if its height is below this value. */
|
||||||
float m_reset_height;
|
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,
|
PhysicalObject(const std::string& model,
|
||||||
bodyTypes shape, float mass, float radius,
|
bodyTypes shape, float mass, float radius,
|
||||||
const core::vector3df& hpr,
|
const core::vector3df& hpr,
|
||||||
const core::vector3df& pos,
|
const core::vector3df& pos,
|
||||||
const core::vector3df& scale);
|
const core::vector3df& scale);
|
||||||
|
*/
|
||||||
|
|
||||||
virtual ~PhysicalObject ();
|
virtual ~PhysicalObject ();
|
||||||
virtual void reset ();
|
virtual void reset ();
|
||||||
virtual void handleExplosion(const Vec3& pos, bool directHit);
|
virtual void handleExplosion(const Vec3& pos, bool directHit);
|
||||||
void update (float dt);
|
void update (float dt);
|
||||||
void init ();
|
void init ();
|
||||||
|
bool isKinetic () const { return m_kinetic; }
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
/** Returns the rigid body of this physical object. */
|
/** Returns the rigid body of this physical object. */
|
||||||
btRigidBody *getBody () { return m_body; }
|
btRigidBody *getBody () { return m_body; }
|
||||||
@ -112,6 +136,10 @@ public:
|
|||||||
* hits it. */
|
* hits it. */
|
||||||
bool isCrashReset() const { return m_crash_reset; }
|
bool isCrashReset() const { return m_crash_reset; }
|
||||||
bool isExplodeKartObject () const { return m_explode_kart; }
|
bool isExplodeKartObject () const { return m_explode_kart; }
|
||||||
|
|
||||||
|
void move(const Vec3& xyz, const core::vector3df& hpr);
|
||||||
|
|
||||||
|
LEAK_CHECK()
|
||||||
}; // PhysicalObject
|
}; // PhysicalObject
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -66,12 +66,12 @@ void CheckGoal::update(float dt)
|
|||||||
if(!obj->isSoccerBall())
|
if(!obj->isSoccerBall())
|
||||||
continue;
|
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(isTriggered(m_previous_position[ball_index], xyz, ball_index))
|
||||||
{
|
{
|
||||||
if(UserConfigParams::m_check_debug)
|
if(UserConfigParams::m_check_debug)
|
||||||
printf("CHECK: Goal check structure %d triggered for object %s.\n",
|
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);
|
trigger(ball_index);
|
||||||
}
|
}
|
||||||
m_previous_position[ball_index] = xyz;
|
m_previous_position[ball_index] = xyz;
|
||||||
@ -122,7 +122,7 @@ void CheckGoal::reset(const Track &track)
|
|||||||
if(!obj->isSoccerBall())
|
if(!obj->isSoccerBall())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const Vec3 &xyz = obj->getNode()->getPosition();
|
const Vec3 &xyz = obj->getPresentation<TrackObjectPresentationMesh>()->getNode()->getPosition();
|
||||||
|
|
||||||
m_previous_position.push_back(xyz);
|
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;
|
using namespace irr;
|
||||||
|
|
||||||
#include "items/item.hpp"
|
#include "items/item.hpp"
|
||||||
|
#include "utils/cpp2011.h"
|
||||||
#include "utils/no_copy.hpp"
|
#include "utils/no_copy.hpp"
|
||||||
#include "utils/vec3.hpp"
|
#include "utils/vec3.hpp"
|
||||||
#include <string>
|
#include <string>
|
||||||
@ -36,50 +37,12 @@ using namespace irr;
|
|||||||
class XMLNode;
|
class XMLNode;
|
||||||
class SFXBase;
|
class SFXBase;
|
||||||
class ParticleEmitter;
|
class ParticleEmitter;
|
||||||
|
class PhysicalObject;
|
||||||
|
class ThreeDAnimation;
|
||||||
|
|
||||||
/**
|
class TrackObjectPresentation
|
||||||
* \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
|
|
||||||
{
|
{
|
||||||
//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:
|
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. */
|
/** The initial XYZ position of the object. */
|
||||||
core::vector3df m_init_xyz;
|
core::vector3df m_init_xyz;
|
||||||
|
|
||||||
@ -88,42 +51,80 @@ protected:
|
|||||||
|
|
||||||
/** The initial scale of the object. */
|
/** The initial scale of the object. */
|
||||||
core::vector3df m_init_scale;
|
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:
|
public:
|
||||||
TrackObject(const XMLNode &xml_node);
|
|
||||||
TrackObject();
|
TrackObjectPresentation(const XMLNode& xml_node);
|
||||||
TrackObject(const core::vector3df& pos, const core::vector3df& hpr,
|
virtual ~TrackObjectPresentation() {}
|
||||||
const core::vector3df& scale, const std::string& model);
|
|
||||||
~TrackObject();
|
virtual void reset() {}
|
||||||
virtual void update(float dt);
|
virtual void setEnable(bool enabled) {}
|
||||||
virtual void reset();
|
virtual void update(float dt) {}
|
||||||
/** To finish object constructions. Called after the track model
|
virtual void move(const core::vector3df& xyz, const core::vector3df& hpr,
|
||||||
* is ready. */
|
const core::vector3df& scale) {}
|
||||||
virtual void init() {};
|
|
||||||
/** Called when an explosion happens. As a default does nothing, will
|
virtual const core::vector3df& getPosition() const { return m_init_xyz; }
|
||||||
* e.g. be overwritten by physical objects etc. */
|
virtual const core::vector3df& getRotation() const { return m_init_hpr; }
|
||||||
virtual void handleExplosion(const Vec3& pos, bool directHit) {};
|
virtual const core::vector3df& getScale() const { return m_init_scale; }
|
||||||
void setEnable(bool mode);
|
|
||||||
|
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; }
|
scene::ISceneNode* getNode() { return m_node; }
|
||||||
const scene::ISceneNode* getNode() const { 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 */
|
/** 2-step construction */
|
||||||
void setNode(scene::ISceneNode* node)
|
void setNode(scene::ISceneNode* node)
|
||||||
@ -149,22 +150,182 @@ public:
|
|||||||
m_node->setScale(m_init_scale);
|
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& getLodGroup() const { return m_lod_group; }
|
||||||
|
|
||||||
const std::string& getType() const { return m_type; }
|
const std::string& getType() const { return m_type; }
|
||||||
|
|
||||||
bool isSoccerBall() const { return m_soccer_ball; }
|
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 */
|
void move(const core::vector3df& xyz, const core::vector3df& hpr, const core::vector3df& scale);
|
||||||
const std::string& getTriggerCondition() const { return m_trigger_condition; }
|
|
||||||
|
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);
|
ThreeDAnimation* getAnimator() { return m_animator; }
|
||||||
void stopSound();
|
const ThreeDAnimation* getAnimator() const { return m_animator; }
|
||||||
void triggerParticles();
|
|
||||||
|
|
||||||
virtual void onTriggerItemApproached(Item* who);
|
|
||||||
|
|
||||||
|
const core::vector3df& getPosition() const;
|
||||||
|
const core::vector3df& getRotation() const;
|
||||||
|
const core::vector3df& getScale() const;
|
||||||
}; // TrackObject
|
}; // TrackObject
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -20,7 +20,6 @@
|
|||||||
|
|
||||||
#include "animations/ipo.hpp"
|
#include "animations/ipo.hpp"
|
||||||
#include "config/user_config.hpp"
|
#include "config/user_config.hpp"
|
||||||
#include "animations/billboard_animation.hpp"
|
|
||||||
#include "animations/three_d_animation.hpp"
|
#include "animations/three_d_animation.hpp"
|
||||||
#include "graphics/irr_driver.hpp"
|
#include "graphics/irr_driver.hpp"
|
||||||
#include "graphics/lod_node.hpp"
|
#include "graphics/lod_node.hpp"
|
||||||
@ -52,6 +51,8 @@ void TrackObjectManager::add(const XMLNode &xml_node)
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
m_all_objects.push_back(new TrackObject(xml_node));
|
||||||
|
/*
|
||||||
std::string groupname;
|
std::string groupname;
|
||||||
xml_node.get("lod_group", &groupname);
|
xml_node.get("lod_group", &groupname);
|
||||||
bool is_lod = !groupname.empty();
|
bool is_lod = !groupname.empty();
|
||||||
@ -67,11 +68,12 @@ void TrackObjectManager::add(const XMLNode &xml_node)
|
|||||||
{
|
{
|
||||||
if (is_lod)
|
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
|
else
|
||||||
{
|
{
|
||||||
m_all_objects.push_back(new PhysicalObject(xml_node));
|
m_all_objects.push_back(new TrackObject(xml_node));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(type=="animation")
|
else if(type=="animation")
|
||||||
@ -106,6 +108,7 @@ void TrackObjectManager::add(const XMLNode &xml_node)
|
|||||||
fprintf(stderr, "Unknown track object: '%s' - ignored.\n",
|
fprintf(stderr, "Unknown track object: '%s' - ignored.\n",
|
||||||
type.c_str());
|
type.c_str());
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
{
|
{
|
||||||
@ -153,8 +156,8 @@ void TrackObjectManager::handleExplosion(const Vec3 &pos, const PhysicalObject *
|
|||||||
TrackObject* curr;
|
TrackObject* curr;
|
||||||
for_in (curr, m_all_objects)
|
for_in (curr, m_all_objects)
|
||||||
{
|
{
|
||||||
if(secondary_hits || mp==curr)
|
if(secondary_hits || mp == curr->getPhysics())
|
||||||
curr->handleExplosion(pos, mp == curr);
|
curr->handleExplosion(pos, mp == curr->getPhysics());
|
||||||
}
|
}
|
||||||
} // handleExplosion
|
} // handleExplosion
|
||||||
|
|
||||||
@ -228,27 +231,33 @@ void TrackObjectManager::enableFog(bool enable)
|
|||||||
TrackObject* curr;
|
TrackObject* curr;
|
||||||
for_in (curr, m_all_objects)
|
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
|
} // enableFog
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
PhysicalObject* TrackObjectManager::insertObject(const std::string& model,
|
TrackObject* TrackObjectManager::insertObject(const std::string& model,
|
||||||
PhysicalObject::bodyTypes shape,
|
PhysicalObject::bodyTypes shape,
|
||||||
float mass, float radius,
|
float mass, float radius,
|
||||||
const core::vector3df& hpr,
|
const core::vector3df& hpr,
|
||||||
const core::vector3df& pos,
|
const core::vector3df& pos,
|
||||||
const core::vector3df& scale)
|
const core::vector3df& scale)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
PhysicalObject* object = new PhysicalObject(model, shape, mass, radius,
|
PhysicalObject* object = new PhysicalObject(model, shape, mass, radius,
|
||||||
hpr, pos, scale);
|
hpr, pos, scale);
|
||||||
object->init();
|
object->init();
|
||||||
m_all_objects.push_back(object);
|
m_all_objects.push_back(object);
|
||||||
return object;
|
return object;
|
||||||
|
*/
|
||||||
|
assert(false);
|
||||||
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@ -256,7 +265,7 @@ PhysicalObject* TrackObjectManager::insertObject(const std::string& model,
|
|||||||
* track objects, and then frees the object.
|
* track objects, and then frees the object.
|
||||||
* \param obj The physical object to remove.
|
* \param obj The physical object to remove.
|
||||||
*/
|
*/
|
||||||
void TrackObjectManager::removeObject(PhysicalObject* obj)
|
void TrackObjectManager::removeObject(TrackObject* obj)
|
||||||
{
|
{
|
||||||
m_all_objects.remove(obj);
|
m_all_objects.remove(obj);
|
||||||
delete 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() ];
|
std::vector<TrackObject*>& queue = m_lod_objects[ lod_nodes[n]->getGroupName() ];
|
||||||
assert( queue.size() > 0 );
|
assert( queue.size() > 0 );
|
||||||
TrackObject* obj = queue[ queue.size() - 1 ];
|
TrackObject* obj = queue[ queue.size() - 1 ];
|
||||||
obj->setNode( lod_nodes[n] );
|
obj->getPresentation<TrackObjectPresentationMesh>()->setNode( lod_nodes[n] );
|
||||||
queue.erase( queue.end() - 1 );
|
queue.erase( queue.end() - 1 );
|
||||||
|
|
||||||
m_all_objects.push_back(obj);
|
m_all_objects.push_back(obj);
|
||||||
|
@ -64,14 +64,14 @@ public:
|
|||||||
/** Enable or disable fog on objects */
|
/** Enable or disable fog on objects */
|
||||||
void enableFog(bool enable);
|
void enableFog(bool enable);
|
||||||
|
|
||||||
PhysicalObject* insertObject(const std::string& model,
|
TrackObject* insertObject(const std::string& model,
|
||||||
PhysicalObject::bodyTypes shape,
|
PhysicalObject::bodyTypes shape,
|
||||||
float mass, float radius,
|
float mass, float radius,
|
||||||
const core::vector3df& hpr,
|
const core::vector3df& hpr,
|
||||||
const core::vector3df& pos,
|
const core::vector3df& pos,
|
||||||
const core::vector3df& scale);
|
const core::vector3df& scale);
|
||||||
|
|
||||||
void removeObject(PhysicalObject* who);
|
void removeObject(TrackObject* who);
|
||||||
|
|
||||||
void assingLodNodes(const std::vector<LODNode*>& lod);
|
void assingLodNodes(const std::vector<LODNode*>& lod);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user