Speedup attachement handling by replacing vector search by direct array access and secondary child lookup vector
parent
56bf867874
commit
35ec3855f6
|
@ -723,52 +723,29 @@ void GenericCAO::setAttachments()
|
||||||
ClientActiveObject* GenericCAO::getParent()
|
ClientActiveObject* GenericCAO::getParent()
|
||||||
{
|
{
|
||||||
ClientActiveObject *obj = NULL;
|
ClientActiveObject *obj = NULL;
|
||||||
for(std::vector<core::vector2d<int> >::const_iterator cii = m_env->attachment_list.begin(); cii != m_env->attachment_list.end(); cii++)
|
|
||||||
{
|
u16 attached_id = m_env->m_attachements[getId()];
|
||||||
if(cii->X == getId()) // This ID is our child
|
|
||||||
{
|
if ((attached_id != 0) &&
|
||||||
if(cii->Y > 0) // A parent ID exists for our child
|
(attached_id != getId())) {
|
||||||
{
|
obj = m_env->getActiveObject(attached_id);
|
||||||
if(cii->X != cii->Y) // The parent and child ID are not the same
|
|
||||||
{
|
|
||||||
obj = m_env->getActiveObject(cii->Y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if(obj)
|
return obj;
|
||||||
return obj;
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenericCAO::removeFromScene(bool permanent)
|
void GenericCAO::removeFromScene(bool permanent)
|
||||||
{
|
{
|
||||||
if(permanent) // Should be true when removing the object permanently and false when refreshing (eg: updating visuals)
|
if(permanent) // Should be true when removing the object permanently and false when refreshing (eg: updating visuals)
|
||||||
{
|
{
|
||||||
// Detach this object's children
|
for(std::vector<u16>::iterator ci = m_children.begin();
|
||||||
for(std::vector<core::vector2d<int> >::iterator ii = m_env->attachment_list.begin();
|
ci != m_children.end(); ci++)
|
||||||
ii != m_env->attachment_list.end(); ii++)
|
|
||||||
{
|
{
|
||||||
if(ii->Y == getId()) // Is a child of our object
|
if (m_env->m_attachements[*ci] == getId()) {
|
||||||
{
|
m_env->m_attachements[*ci] = 0;
|
||||||
ii->Y = 0;
|
|
||||||
// Get the object of the child
|
|
||||||
ClientActiveObject *obj = m_env->getActiveObject(ii->X);
|
|
||||||
if(obj)
|
|
||||||
obj->setAttachments();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Delete this object from the attachments list
|
|
||||||
for(std::vector<core::vector2d<int> >::iterator ii = m_env->attachment_list.begin();
|
|
||||||
ii != m_env->attachment_list.end(); ii++)
|
|
||||||
{
|
|
||||||
if(ii->X == getId()) // Is our object
|
|
||||||
{
|
|
||||||
m_env->attachment_list.erase(ii);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_env->m_attachements[getId()] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_meshnode)
|
if(m_meshnode)
|
||||||
|
@ -1098,45 +1075,43 @@ void GenericCAO::step(float dtime, ClientEnvironment *env)
|
||||||
|
|
||||||
// Attachments, part 1: All attached objects must be unparented first,
|
// Attachments, part 1: All attached objects must be unparented first,
|
||||||
// or Irrlicht causes a segmentation fault
|
// or Irrlicht causes a segmentation fault
|
||||||
for(std::vector<core::vector2d<int> >::iterator ii = m_env->attachment_list.begin();
|
for(std::vector<u16>::iterator ci = m_children.begin();
|
||||||
ii != m_env->attachment_list.end(); ii++)
|
ci != m_children.end();)
|
||||||
{
|
{
|
||||||
if(ii->Y == getId()) // This is a child of our parent
|
if (m_env->m_attachements[*ci] != getId()) {
|
||||||
{
|
ci = m_children.erase(ci);
|
||||||
// Get the object of the child
|
continue;
|
||||||
ClientActiveObject *obj = m_env->getActiveObject(ii->X);
|
|
||||||
if(obj)
|
|
||||||
{
|
|
||||||
scene::IMeshSceneNode *m_child_meshnode
|
|
||||||
= obj->getMeshSceneNode();
|
|
||||||
scene::IAnimatedMeshSceneNode *m_child_animated_meshnode
|
|
||||||
= obj->getAnimatedMeshSceneNode();
|
|
||||||
scene::IBillboardSceneNode *m_child_spritenode
|
|
||||||
= obj->getSpriteSceneNode();
|
|
||||||
if(m_child_meshnode)
|
|
||||||
m_child_meshnode->setParent(m_smgr->getRootSceneNode());
|
|
||||||
if(m_child_animated_meshnode)
|
|
||||||
m_child_animated_meshnode->setParent(m_smgr->getRootSceneNode());
|
|
||||||
if(m_child_spritenode)
|
|
||||||
m_child_spritenode->setParent(m_smgr->getRootSceneNode());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
ClientActiveObject *obj = m_env->getActiveObject(*ci);
|
||||||
|
if(obj)
|
||||||
|
{
|
||||||
|
scene::IMeshSceneNode *m_child_meshnode
|
||||||
|
= obj->getMeshSceneNode();
|
||||||
|
scene::IAnimatedMeshSceneNode *m_child_animated_meshnode
|
||||||
|
= obj->getAnimatedMeshSceneNode();
|
||||||
|
scene::IBillboardSceneNode *m_child_spritenode
|
||||||
|
= obj->getSpriteSceneNode();
|
||||||
|
if(m_child_meshnode)
|
||||||
|
m_child_meshnode->setParent(m_smgr->getRootSceneNode());
|
||||||
|
if(m_child_animated_meshnode)
|
||||||
|
m_child_animated_meshnode->setParent(m_smgr->getRootSceneNode());
|
||||||
|
if(m_child_spritenode)
|
||||||
|
m_child_spritenode->setParent(m_smgr->getRootSceneNode());
|
||||||
|
}
|
||||||
|
++ci;
|
||||||
}
|
}
|
||||||
|
|
||||||
removeFromScene(false);
|
removeFromScene(false);
|
||||||
addToScene(m_smgr, m_gamedef->tsrc(), m_irr);
|
addToScene(m_smgr, m_gamedef->tsrc(), m_irr);
|
||||||
|
|
||||||
// Attachments, part 2: Now that the parent has been refreshed, put its attachments back
|
// Attachments, part 2: Now that the parent has been refreshed, put its attachments back
|
||||||
for(std::vector<core::vector2d<int> >::iterator ii = m_env->attachment_list.begin();
|
for(std::vector<u16>::iterator ci = m_children.begin();
|
||||||
ii != m_env->attachment_list.end(); ii++)
|
ci != m_children.end(); ci++)
|
||||||
{
|
{
|
||||||
if(ii->Y == getId()) // This is a child of our parent
|
|
||||||
{
|
|
||||||
// Get the object of the child
|
// Get the object of the child
|
||||||
ClientActiveObject *obj = m_env->getActiveObject(ii->X);
|
ClientActiveObject *obj = m_env->getActiveObject(*ci);
|
||||||
if(obj)
|
if(obj)
|
||||||
obj->setAttachments();
|
obj->setAttachments();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1803,16 +1778,8 @@ void GenericCAO::processMessage(const std::string &data)
|
||||||
updateBonePosition();
|
updateBonePosition();
|
||||||
}
|
}
|
||||||
else if(cmd == GENERIC_CMD_SET_ATTACHMENT) {
|
else if(cmd == GENERIC_CMD_SET_ATTACHMENT) {
|
||||||
// If an entry already exists for this object, delete it first to avoid duplicates
|
m_env->m_attachements[getId()] = readS16(is);
|
||||||
for(std::vector<core::vector2d<int> >::iterator ii = m_env->attachment_list.begin(); ii != m_env->attachment_list.end(); ii++)
|
m_children.push_back(m_env->m_attachements[getId()]);
|
||||||
{
|
|
||||||
if(ii->X == getId()) // This is the ID of our object
|
|
||||||
{
|
|
||||||
m_env->attachment_list.erase(ii);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m_env->attachment_list.push_back(core::vector2d<int>(getId(), readS16(is)));
|
|
||||||
m_attachment_bone = deSerializeString(is);
|
m_attachment_bone = deSerializeString(is);
|
||||||
m_attachment_position = readV3F1000(is);
|
m_attachment_position = readV3F1000(is);
|
||||||
m_attachment_rotation = readV3F1000(is);
|
m_attachment_rotation = readV3F1000(is);
|
||||||
|
|
|
@ -102,6 +102,8 @@ private:
|
||||||
u8 m_last_light;
|
u8 m_last_light;
|
||||||
bool m_is_visible;
|
bool m_is_visible;
|
||||||
|
|
||||||
|
std::vector<u16> m_children;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GenericCAO(IGameDef *gamedef, ClientEnvironment *env);
|
GenericCAO(IGameDef *gamedef, ClientEnvironment *env);
|
||||||
|
|
||||||
|
|
|
@ -1379,7 +1379,7 @@ bool ServerEnvironment::addActiveObjectAsStatic(ServerActiveObject *obj)
|
||||||
{
|
{
|
||||||
assert(obj);
|
assert(obj);
|
||||||
|
|
||||||
v3f objectpos = obj->getBasePosition();
|
v3f objectpos = obj->getBasePosition();
|
||||||
|
|
||||||
// The block in which the object resides in
|
// The block in which the object resides in
|
||||||
v3s16 blockpos_o = getNodeBlockPos(floatToInt(objectpos, BS));
|
v3s16 blockpos_o = getNodeBlockPos(floatToInt(objectpos, BS));
|
||||||
|
@ -1591,7 +1591,7 @@ u16 ServerEnvironment::addActiveObjectRaw(ServerActiveObject *object,
|
||||||
object->m_static_block = blockpos;
|
object->m_static_block = blockpos;
|
||||||
|
|
||||||
if(set_changed)
|
if(set_changed)
|
||||||
block->raiseModified(MOD_STATE_WRITE_NEEDED,
|
block->raiseModified(MOD_STATE_WRITE_NEEDED,
|
||||||
"addActiveObjectRaw");
|
"addActiveObjectRaw");
|
||||||
} else {
|
} else {
|
||||||
v3s16 p = floatToInt(objectpos, BS);
|
v3s16 p = floatToInt(objectpos, BS);
|
||||||
|
@ -1828,7 +1828,7 @@ void ServerEnvironment::activateObjects(MapBlock *block, u32 dtime_s)
|
||||||
If force_delete is set, active object is deleted nevertheless. It
|
If force_delete is set, active object is deleted nevertheless. It
|
||||||
shall only be set so in the destructor of the environment.
|
shall only be set so in the destructor of the environment.
|
||||||
|
|
||||||
If block wasn't generated (not in memory or on disk),
|
If block wasn't generated (not in memory or on disk),
|
||||||
*/
|
*/
|
||||||
void ServerEnvironment::deactivateFarObjects(bool force_delete)
|
void ServerEnvironment::deactivateFarObjects(bool force_delete)
|
||||||
{
|
{
|
||||||
|
@ -1849,7 +1849,7 @@ void ServerEnvironment::deactivateFarObjects(bool force_delete)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
u16 id = i->first;
|
u16 id = i->first;
|
||||||
v3f objectpos = obj->getBasePosition();
|
v3f objectpos = obj->getBasePosition();
|
||||||
|
|
||||||
// The block in which the object resides in
|
// The block in which the object resides in
|
||||||
v3s16 blockpos_o = getNodeBlockPos(floatToInt(objectpos, BS));
|
v3s16 blockpos_o = getNodeBlockPos(floatToInt(objectpos, BS));
|
||||||
|
@ -2078,6 +2078,8 @@ ClientEnvironment::ClientEnvironment(ClientMap *map, scene::ISceneManager *smgr,
|
||||||
m_gamedef(gamedef),
|
m_gamedef(gamedef),
|
||||||
m_irr(irr)
|
m_irr(irr)
|
||||||
{
|
{
|
||||||
|
char zero = 0;
|
||||||
|
memset(m_attachements, zero, sizeof(m_attachements));
|
||||||
}
|
}
|
||||||
|
|
||||||
ClientEnvironment::~ClientEnvironment()
|
ClientEnvironment::~ClientEnvironment()
|
||||||
|
|
|
@ -492,7 +492,7 @@ public:
|
||||||
// Get event from queue. CEE_NONE is returned if queue is empty.
|
// Get event from queue. CEE_NONE is returned if queue is empty.
|
||||||
ClientEnvEvent getClientEvent();
|
ClientEnvEvent getClientEvent();
|
||||||
|
|
||||||
std::vector<core::vector2d<int> > attachment_list; // X is child ID, Y is parent ID
|
u16 m_attachements[USHRT_MAX];
|
||||||
|
|
||||||
std::list<std::string> getPlayerNames()
|
std::list<std::string> getPlayerNames()
|
||||||
{ return m_player_names; }
|
{ return m_player_names; }
|
||||||
|
|
Loading…
Reference in New Issue