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:
auria
2013-04-05 00:20:14 +00:00
parent 94cd32d20d
commit 6bc216f203
13 changed files with 117 additions and 91 deletions

View File

@@ -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

View File

@@ -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();
}

View File

@@ -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

View File

@@ -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

View File

@@ -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,

View File

@@ -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 );

View File

@@ -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

View File

@@ -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);
}
// ----------------------------------------------------------------------------

View File

@@ -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); }

View File

@@ -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);

View File

@@ -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();

View File

@@ -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()
}
// ----------------------------------------------------------------------------

View File

@@ -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);
}
}
};
/**