Improved handling of physical objects (size computation and matching of physical
and graphical position now better) - rotations still need to be fixed. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/irrlicht@3821 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
@@ -78,10 +78,12 @@ PhysicalObject::PhysicalObject(const XMLNode *xml_node)
|
||||
m_body = NULL;
|
||||
m_motion_state = NULL;
|
||||
m_mass = 1;
|
||||
m_radius = -1;
|
||||
|
||||
std::string shape;
|
||||
xml_node->get("shape", &shape);
|
||||
xml_node->get("mass", &m_mass);
|
||||
xml_node->get("mass", &m_mass );
|
||||
xml_node->get("radius", &m_radius);
|
||||
xml_node->get("shape", &shape );
|
||||
|
||||
m_body_type = MP_NONE;
|
||||
if (shape=="cone" ) m_body_type = MP_CONE;
|
||||
@@ -104,36 +106,56 @@ PhysicalObject::~PhysicalObject()
|
||||
void PhysicalObject::init()
|
||||
{
|
||||
assert(m_mesh);
|
||||
|
||||
// 1. Determine size of the object
|
||||
// -------------------------------
|
||||
Vec3 min, max;
|
||||
MeshTools::minMax3D(m_mesh, &min, &max);
|
||||
Vec3 extend = max-min;
|
||||
m_half_height = 0.5f*(extend.getZ());
|
||||
// Adjust the mesth of the graphical object so that its center is where it
|
||||
// is in bullet (usually at (0,0,0)). It can be changed in the case clause
|
||||
// if this is not correct for a particular shape.
|
||||
Vec3 offset_from_center = -0.5f*(max+min);
|
||||
switch (m_body_type)
|
||||
{
|
||||
case MP_CONE: {
|
||||
float radius = 0.5f*std::max(extend.getX(), extend.getY());
|
||||
m_shape = new btConeShapeZ(radius, extend.getZ());
|
||||
if(m_radius<0) m_radius = 0.5f*extend.length_2d();
|
||||
m_shape = new btConeShapeZ(m_radius, extend.getZ());
|
||||
break;
|
||||
}
|
||||
case MP_BOX: m_shape = new btBoxShape(0.5*extend);
|
||||
break;
|
||||
case MP_SPHERE: {
|
||||
float radius = std::max(extend.getX(), extend.getY());
|
||||
radius = 0.5f*std::max(radius, extend.getZ());
|
||||
m_shape = new btSphereShape(radius);
|
||||
if(m_radius<0)
|
||||
{
|
||||
float max_axis = std::max(extend.getX(), extend.getY());
|
||||
max_axis = std::max(max_axis, extend.getZ());
|
||||
// Worst case radius: if the actual shape is more like
|
||||
// a box, the actual radius can be up to sqrt(3) larger
|
||||
// than the maxium axis size:
|
||||
// sqrt(x*x+y*y+z*z) <= sqrt(3*max_axis*max_axis)
|
||||
m_radius = sqrt(3.0f)*max_axis;
|
||||
}
|
||||
m_shape = new btSphereShape(m_radius);
|
||||
break;
|
||||
}
|
||||
case MP_NONE: fprintf(stderr, "WARNING: Uninitialised moving shape\n");
|
||||
break;
|
||||
}
|
||||
|
||||
// 2. Adjust the mesh so that its center is where it is in bullet
|
||||
// --------------------------------------------------------------
|
||||
// This means that the graphical and physical position are identical
|
||||
// which simplifies drawing later on.
|
||||
scene::IMeshManipulator *mesh_manipulator =
|
||||
irr_driver->getSceneManager()->getMeshManipulator();
|
||||
core::matrix4 transform(core::matrix4::EM4CONST_IDENTITY); //
|
||||
transform.setTranslation(offset_from_center.toIrrVector());
|
||||
mesh_manipulator->transformMesh(m_mesh, transform);
|
||||
|
||||
// 2. Create the rigid object
|
||||
// --------------------------
|
||||
Vec3 pos = m_init_pos.getOrigin();
|
||||
pos.setZ(m_init_pos.getOrigin().getZ()+m_half_height);
|
||||
m_init_pos.setOrigin(pos);
|
||||
m_init_pos.setOrigin(m_init_pos.getOrigin()-offset_from_center);
|
||||
m_motion_state = new btDefaultMotionState(m_init_pos);
|
||||
btVector3 inertia;
|
||||
m_shape->calculateLocalInertia(m_mass, inertia);
|
||||
|
||||
@@ -21,13 +21,15 @@
|
||||
#define HEADER_PHYSICAL_OBJECT_HPP
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "irrlicht.h"
|
||||
using namespace irr;
|
||||
|
||||
#include "btBulletDynamicsCommon.h"
|
||||
#include "physics/user_pointer.hpp"
|
||||
|
||||
class Vec3;
|
||||
#include "physics/user_pointer.hpp"
|
||||
#include "utils/vec3.hpp"
|
||||
|
||||
class scene::IAnimatedMesh;
|
||||
class XMLNode;
|
||||
|
||||
@@ -37,16 +39,27 @@ public:
|
||||
enum bodyTypes {MP_NONE, MP_CONE, MP_BOX, MP_SPHERE};
|
||||
|
||||
protected:
|
||||
/** The shape of this object. */
|
||||
bodyTypes m_body_type;
|
||||
/** The bullet collision shape. */
|
||||
btCollisionShape *m_shape;
|
||||
/** The corresponding bullet rigid body. */
|
||||
btRigidBody *m_body;
|
||||
/** Bullet's motion state for this object. */
|
||||
btDefaultMotionState *m_motion_state;
|
||||
float m_half_height;
|
||||
/** The mass of this object. */
|
||||
float m_mass;
|
||||
/** The pointer that is stored in the bullet rigid body back to
|
||||
* this object. */
|
||||
UserPointer m_user_pointer;
|
||||
/** This is the initial position of the object for the physics. */
|
||||
btTransform m_init_pos;
|
||||
/** The irrlicht mesh for this object. */
|
||||
scene::IMesh *m_mesh;
|
||||
/** The irrlicht scene node this object is attached to. */
|
||||
scene::ISceneNode *m_node;
|
||||
/** Radius of the object - this obviously depends on the actual shape. */
|
||||
float m_radius;
|
||||
public:
|
||||
PhysicalObject (const XMLNode *node);
|
||||
virtual ~PhysicalObject ();
|
||||
|
||||
Reference in New Issue
Block a user