Add full support for LOD in track objects
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@12608 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
@@ -100,7 +100,7 @@ void ThreeDAnimation::update(float dt)
|
||||
|
||||
if (m_object)
|
||||
{
|
||||
m_object->move(xyz.toIrrVector(), hpr, scale.toIrrVector());
|
||||
m_object->move(xyz.toIrrVector(), hpr, scale.toIrrVector(), true);
|
||||
}
|
||||
}
|
||||
} // update
|
||||
|
||||
@@ -270,6 +270,7 @@ void LODNode::add(int level, scene::ISceneNode* node, bool reparent)
|
||||
|
||||
node->grab();
|
||||
node->remove();
|
||||
node->setPosition(core::vector3df(0,0,0));
|
||||
m_detail.push_back(level*level);
|
||||
m_nodes.push_back(node);
|
||||
m_nodes_set.insert(node);
|
||||
@@ -279,4 +280,6 @@ void LODNode::add(int level, scene::ISceneNode* node, bool reparent)
|
||||
HardwareSkinning::prepareNode((scene::IAnimatedMeshSceneNode*)node);
|
||||
|
||||
node->drop();
|
||||
|
||||
node->updateAbsolutePosition();
|
||||
}
|
||||
|
||||
@@ -122,31 +122,6 @@ public:
|
||||
virtual scene::ESCENE_NODE_TYPE getType() const { return (scene::ESCENE_NODE_TYPE)scene::ESNT_LOD_NODE; }
|
||||
|
||||
const std::string& getGroupName() const { return m_group_name; }
|
||||
|
||||
void setNodesPosition(const core::vector3df& xyz)
|
||||
{
|
||||
for (unsigned int n=0; n<m_nodes.size(); n++)
|
||||
{
|
||||
m_nodes[n]->setPosition(xyz);
|
||||
}
|
||||
}
|
||||
|
||||
void setNodesRotation(const core::vector3df& hpr)
|
||||
{
|
||||
for (unsigned int n=0; n<m_nodes.size(); n++)
|
||||
{
|
||||
m_nodes[n]->setRotation(hpr);
|
||||
}
|
||||
}
|
||||
|
||||
void setNodesScale(const core::vector3df& scale)
|
||||
{
|
||||
for (unsigned int n=0; n<m_nodes.size(); n++)
|
||||
{
|
||||
m_nodes[n]->setScale(scale);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -41,7 +41,7 @@ using namespace irr;
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
PhysicalObject::PhysicalObject(bool kinetic, const XMLNode &xml_node,
|
||||
scene::ISceneNode* scenenode)
|
||||
TrackObject* object)
|
||||
{
|
||||
m_shape = NULL;
|
||||
m_body = NULL;
|
||||
@@ -53,11 +53,11 @@ PhysicalObject::PhysicalObject(bool kinetic, const XMLNode &xml_node,
|
||||
m_crash_reset = false;
|
||||
m_explode_kart = false;
|
||||
|
||||
m_node = scenenode;
|
||||
m_object = object;
|
||||
|
||||
m_init_xyz = scenenode->getPosition();
|
||||
m_init_hpr = scenenode->getRotation();
|
||||
m_init_scale = scenenode->getScale();
|
||||
m_init_xyz = object->getPosition();
|
||||
m_init_hpr = object->getRotation();
|
||||
m_init_scale = object->getScale();
|
||||
|
||||
std::string shape;
|
||||
xml_node.get("mass", &m_mass );
|
||||
@@ -169,24 +169,26 @@ void PhysicalObject::init()
|
||||
// -------------------------------
|
||||
Vec3 min, max;
|
||||
|
||||
TrackObjectPresentationSceneNode* presentation =
|
||||
m_object->getPresentation<TrackObjectPresentationSceneNode>();
|
||||
|
||||
if (m_node->getType() == scene::ESNT_ANIMATED_MESH)
|
||||
if (presentation->getNode()->getType() == scene::ESNT_ANIMATED_MESH)
|
||||
{
|
||||
scene::IAnimatedMesh *mesh
|
||||
= ((scene::IAnimatedMeshSceneNode*)m_node)->getMesh();
|
||||
= ((scene::IAnimatedMeshSceneNode*)presentation->getNode())->getMesh();
|
||||
|
||||
MeshTools::minMax3D(mesh, &min, &max);
|
||||
}
|
||||
else if (m_node->getType()==scene::ESNT_MESH)
|
||||
else if (presentation->getNode()->getType()==scene::ESNT_MESH)
|
||||
{
|
||||
scene::IMesh *mesh
|
||||
= ((scene::IMeshSceneNode*)m_node)->getMesh();
|
||||
= ((scene::IMeshSceneNode*)presentation->getNode())->getMesh();
|
||||
|
||||
MeshTools::minMax3D(mesh, &min, &max);
|
||||
}
|
||||
else if (m_node->getType()==scene::ESNT_LOD_NODE)
|
||||
else if (presentation->getNode()->getType()==scene::ESNT_LOD_NODE)
|
||||
{
|
||||
scene::ISceneNode* node = ((LODNode*)m_node)->getAllNodes()[0];
|
||||
scene::ISceneNode* node = ((LODNode*)presentation->getNode())->getAllNodes()[0];
|
||||
if (node->getType() == scene::ESNT_ANIMATED_MESH)
|
||||
{
|
||||
scene::IAnimatedMesh *mesh
|
||||
@@ -288,20 +290,20 @@ void PhysicalObject::init()
|
||||
bool is_readonly_material = false;
|
||||
|
||||
scene::IMesh* mesh = NULL;
|
||||
switch (m_node->getType())
|
||||
switch (presentation->getNode()->getType())
|
||||
{
|
||||
case scene::ESNT_MESH :
|
||||
case scene::ESNT_WATER_SURFACE :
|
||||
case scene::ESNT_OCTREE :
|
||||
mesh = ((scene::IMeshSceneNode*)m_node)->getMesh();
|
||||
mesh = ((scene::IMeshSceneNode*)presentation->getNode())->getMesh();
|
||||
is_readonly_material =
|
||||
((scene::IMeshSceneNode*)m_node)->isReadOnlyMaterials();
|
||||
((scene::IMeshSceneNode*)presentation->getNode())->isReadOnlyMaterials();
|
||||
break;
|
||||
case scene::ESNT_ANIMATED_MESH :
|
||||
// for now just use frame 0
|
||||
mesh = ((scene::IAnimatedMeshSceneNode*)m_node)->getMesh()->getMesh(0);
|
||||
mesh = ((scene::IAnimatedMeshSceneNode*)presentation->getNode())->getMesh()->getMesh(0);
|
||||
is_readonly_material =
|
||||
((scene::IAnimatedMeshSceneNode*)m_node)->isReadOnlyMaterials();
|
||||
((scene::IAnimatedMeshSceneNode*)presentation->getNode())->isReadOnlyMaterials();
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "[3DAnimation] Unknown object type, cannot create exact collision body!\n");
|
||||
@@ -338,7 +340,7 @@ void PhysicalObject::init()
|
||||
// the material is only available in the node.
|
||||
const video::SMaterial &irrMaterial =
|
||||
is_readonly_material ? mb->getMaterial()
|
||||
: m_node->getMaterial(i);
|
||||
: presentation->getNode()->getMaterial(i);
|
||||
video::ITexture* t=irrMaterial.getTexture(0);
|
||||
|
||||
const Material* material=0;
|
||||
@@ -461,10 +463,13 @@ void PhysicalObject::update(float dt)
|
||||
// Offset the graphical position correctly:
|
||||
xyz += t.getBasis()*m_graphical_offset;
|
||||
|
||||
m_node->setPosition(xyz.toIrrVector());
|
||||
//m_node->setPosition(xyz.toIrrVector());
|
||||
Vec3 hpr;
|
||||
hpr.setHPR(t.getRotation());
|
||||
m_node->setRotation(hpr.toIrrHPR());
|
||||
//m_node->setRotation(hpr.toIrrHPR());
|
||||
|
||||
core::vector3df scale(1,1,1);
|
||||
m_object->move(xyz.toIrrVector(), hpr.toIrrVector(), scale, false);
|
||||
return;
|
||||
} // update
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ private:
|
||||
/** The initial scale of the object. */
|
||||
core::vector3df m_init_scale;
|
||||
|
||||
scene::ISceneNode* m_node;
|
||||
TrackObject *m_object;
|
||||
|
||||
/** The shape of this object. */
|
||||
bodyTypes m_body_type;
|
||||
@@ -111,7 +111,7 @@ private:
|
||||
|
||||
public:
|
||||
PhysicalObject(bool kinetic, const XMLNode &node,
|
||||
scene::ISceneNode* scenenode);
|
||||
TrackObject* object);
|
||||
|
||||
/*
|
||||
PhysicalObject(const std::string& model,
|
||||
|
||||
@@ -145,6 +145,10 @@ void LodNodeLoader::done(Track* track,
|
||||
if (group.size() > 0)
|
||||
{
|
||||
LODNode* lod_node = new LODNode(groupname, sroot, sm);
|
||||
lod_node->setPosition(xyz);
|
||||
lod_node->setRotation(hpr);
|
||||
lod_node->setScale(scale);
|
||||
lod_node->updateAbsolutePosition();
|
||||
for (unsigned int m=0; m<group.size(); m++)
|
||||
{
|
||||
full_path = directory + "/" + group[m].second.m_model_file;
|
||||
@@ -172,9 +176,9 @@ void LodNodeLoader::done(Track* track,
|
||||
cache.push_back(a_mesh);
|
||||
irr_driver->grabAllTextures(a_mesh);
|
||||
scene::IMeshSceneNode* scene_node = irr_driver->addMesh(a_mesh);
|
||||
scene_node->setPosition(xyz);
|
||||
scene_node->setRotation(hpr);
|
||||
scene_node->setScale(scale);
|
||||
//scene_node->setPosition(xyz);
|
||||
//scene_node->setRotation(hpr);
|
||||
//scene_node->setScale(scale);
|
||||
|
||||
track->handleAnimatedTextures( scene_node, *group[m].second.m_xml );
|
||||
|
||||
|
||||
@@ -542,6 +542,9 @@ void Track::createPhysicsModel(unsigned int main_track_count)
|
||||
*/
|
||||
void Track::convertTrackToBullet(scene::ISceneNode *node)
|
||||
{
|
||||
const core::vector3df &hpr = node->getRotation();
|
||||
const core::vector3df &scale = node->getScale();
|
||||
|
||||
if (node->getType() == scene::ESNT_LOD_NODE)
|
||||
{
|
||||
node = ((LODNode*)node)->getFirstNode();
|
||||
@@ -552,10 +555,10 @@ void Track::convertTrackToBullet(scene::ISceneNode *node)
|
||||
return;
|
||||
}
|
||||
}
|
||||
node->updateAbsolutePosition();
|
||||
|
||||
const core::vector3df &pos = node->getPosition();
|
||||
const core::vector3df &hpr = node->getRotation();
|
||||
const core::vector3df &scale = node->getScale();
|
||||
const core::vector3df &pos = node->getAbsolutePosition();
|
||||
|
||||
|
||||
scene::IMesh *mesh;
|
||||
// In case of readonly materials we have to get the material from
|
||||
|
||||
@@ -37,6 +37,20 @@
|
||||
* model, enable/disable status, timer information.
|
||||
*/
|
||||
TrackObject::TrackObject(const XMLNode &xml_node)
|
||||
{
|
||||
init(xml_node, NULL);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
TrackObject::TrackObject(const XMLNode &xml_node, LODNode* lod_node)
|
||||
{
|
||||
init(xml_node, lod_node);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void TrackObject::init(const XMLNode &xml_node, LODNode* lod_node)
|
||||
{
|
||||
m_init_xyz = core::vector3df(0,0,0);
|
||||
m_init_hpr = core::vector3df(0,0,0);
|
||||
@@ -65,7 +79,12 @@ TrackObject::TrackObject(const XMLNode &xml_node)
|
||||
m_type = type;
|
||||
|
||||
|
||||
if (xml_node.getName() == "particle-emitter")
|
||||
if (lod_node != NULL)
|
||||
{
|
||||
m_type = "lod";
|
||||
m_presentation = new TrackObjectPresentationLOD(xml_node, lod_node);
|
||||
}
|
||||
else if (xml_node.getName() == "particle-emitter")
|
||||
{
|
||||
m_type = "particle-emitter";
|
||||
m_presentation = new TrackObjectPresentationParticles(xml_node);
|
||||
@@ -100,7 +119,7 @@ TrackObject::TrackObject(const XMLNode &xml_node)
|
||||
{
|
||||
m_rigid_body = new PhysicalObject(type == "movable",
|
||||
xml_node,
|
||||
mesh_presentation->getNode());
|
||||
this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,10 +184,10 @@ void TrackObject::update(float dt)
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void TrackObject::move(const core::vector3df& xyz, const core::vector3df& hpr,
|
||||
const core::vector3df& scale)
|
||||
const core::vector3df& scale, bool updateRigidBody)
|
||||
{
|
||||
if (m_presentation != NULL) m_presentation->move(xyz, hpr, scale);
|
||||
if (m_rigid_body != NULL) m_rigid_body->move(xyz, hpr);
|
||||
if (updateRigidBody && m_rigid_body != NULL) m_rigid_body->move(xyz, hpr);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
@@ -78,9 +78,11 @@ protected:
|
||||
|
||||
ThreeDAnimation* m_animator;
|
||||
|
||||
void init(const XMLNode &xml_node, LODNode* lodNode);
|
||||
|
||||
public:
|
||||
TrackObject(const XMLNode &xml_node);
|
||||
TrackObject(const XMLNode &xml_node, LODNode* lodNode);
|
||||
TrackObject();
|
||||
|
||||
/*
|
||||
@@ -111,7 +113,8 @@ public:
|
||||
const core::vector3df getInitRotation() const { return m_init_hpr; }
|
||||
const core::vector3df getInitScale() const { return m_init_scale; }
|
||||
|
||||
void move(const core::vector3df& xyz, const core::vector3df& hpr, const core::vector3df& scale);
|
||||
void move(const core::vector3df& xyz, const core::vector3df& hpr,
|
||||
const core::vector3df& scale, bool updateRigidBody);
|
||||
|
||||
template<typename T>
|
||||
T* getPresentation() { return dynamic_cast<T*>(m_presentation); }
|
||||
|
||||
@@ -51,7 +51,20 @@ 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();
|
||||
|
||||
if (is_lod)
|
||||
{
|
||||
printf("Adding lod obj to group <%s>\n", groupname.c_str());
|
||||
m_lod_objects[groupname].push_back(&xml_node);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_all_objects.push_back(new TrackObject(xml_node));
|
||||
}
|
||||
|
||||
/*
|
||||
std::string groupname;
|
||||
xml_node.get("lod_group", &groupname);
|
||||
@@ -284,10 +297,11 @@ void TrackObjectManager::assingLodNodes(const std::vector<LODNode*>& lod_nodes)
|
||||
{
|
||||
for (unsigned int n=0; n<lod_nodes.size(); n++)
|
||||
{
|
||||
std::vector<TrackObject*>& queue = m_lod_objects[ lod_nodes[n]->getGroupName() ];
|
||||
std::vector<const XMLNode*>& queue = m_lod_objects[ lod_nodes[n]->getGroupName() ];
|
||||
assert( queue.size() > 0 );
|
||||
TrackObject* obj = queue[ queue.size() - 1 ];
|
||||
obj->getPresentation<TrackObjectPresentationMesh>()->setNode( lod_nodes[n] );
|
||||
const XMLNode* xml = queue[ queue.size() - 1 ];
|
||||
|
||||
TrackObject* obj = new TrackObject(*xml, lod_nodes[n]);
|
||||
queue.erase( queue.end() - 1 );
|
||||
|
||||
m_all_objects.push_back(obj);
|
||||
|
||||
@@ -49,7 +49,7 @@ protected:
|
||||
/** Temporary storage for LOD objects whose XML node was read but whose
|
||||
* scene node is not yet ready
|
||||
*/
|
||||
std::map<std::string, std::vector<TrackObject*> > m_lod_objects;
|
||||
std::map<std::string, std::vector<const XMLNode*> > m_lod_objects;
|
||||
|
||||
public:
|
||||
TrackObjectManager();
|
||||
|
||||
@@ -112,6 +112,21 @@ TrackObjectPresentationEmpty::~TrackObjectPresentationEmpty()
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
TrackObjectPresentationLOD::TrackObjectPresentationLOD(const XMLNode& xml_node, LODNode* lod_node) :
|
||||
TrackObjectPresentationSceneNode(xml_node)
|
||||
{
|
||||
m_node = lod_node;
|
||||
m_node->setPosition(m_init_xyz);
|
||||
m_node->setRotation(m_init_hpr);
|
||||
m_node->setScale(m_init_scale);
|
||||
}
|
||||
|
||||
TrackObjectPresentationLOD::~TrackObjectPresentationLOD()
|
||||
{
|
||||
irr_driver->removeNode(m_node);
|
||||
}
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
TrackObjectPresentationMesh::TrackObjectPresentationMesh(const XMLNode& xml_node, bool enabled) :
|
||||
TrackObjectPresentationSceneNode(xml_node)
|
||||
{
|
||||
@@ -227,7 +242,6 @@ void TrackObjectPresentationMesh::reset()
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
@@ -99,6 +99,19 @@ public:
|
||||
virtual ~TrackObjectPresentationEmpty();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \ingroup tracks
|
||||
* A track object representation that consists of a level-of-detail scene node
|
||||
*/
|
||||
class TrackObjectPresentationLOD : public TrackObjectPresentationSceneNode
|
||||
{
|
||||
public:
|
||||
|
||||
TrackObjectPresentationLOD(const XMLNode& xml_node, LODNode* lod_node);
|
||||
virtual ~TrackObjectPresentationLOD();
|
||||
};
|
||||
|
||||
/**
|
||||
* \ingroup tracks
|
||||
* A track object representation that consists of a mesh scene node.
|
||||
@@ -124,33 +137,6 @@ public:
|
||||
virtual ~TrackObjectPresentationMesh();
|
||||
|
||||
virtual void reset() OVERRIDE;
|
||||
|
||||
|
||||
/** 2-step construction */
|
||||
void setNode(scene::ISceneNode* node)
|
||||
{
|
||||
//assert(m_node == NULL);
|
||||
if (m_node != NULL)
|
||||
{
|
||||
m_node->remove();
|
||||
}
|
||||
|
||||
m_node = node;
|
||||
|
||||
if (m_node->getType() == irr::scene::ESNT_LOD_NODE)
|
||||
{
|
||||
((LODNode*)m_node)->setNodesPosition(m_init_xyz);
|
||||
((LODNode*)m_node)->setNodesRotation(m_init_hpr);
|
||||
((LODNode*)m_node)->setNodesScale(m_init_scale);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_node->setPosition(m_init_xyz);
|
||||
m_node->setRotation(m_init_hpr);
|
||||
m_node->setScale(m_init_scale);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user