Skip to content
Permalink
Browse files

Speedup attachement handling by replacing vector search by direct arr…

…ay access and secondary child lookup vector
  • Loading branch information...
sapier sapier
sapier authored and sapier committed Jun 8, 2014
1 parent 56bf867 commit 35ec3855f689cf2c6b1504a5813b7c3d9697ae14
Showing with 48 additions and 77 deletions.
  1. +39 −72 src/content_cao.cpp
  2. +2 −0 src/content_cao.h
  3. +6 −4 src/environment.cpp
  4. +1 −1 src/environment.h
@@ -723,52 +723,29 @@ void GenericCAO::setAttachments()
ClientActiveObject* GenericCAO::getParent()
{
ClientActiveObject *obj = NULL;
for(std::vector<core::vector2d<int> >::const_iterator cii = m_env->attachment_list.begin(); cii != m_env->attachment_list.end(); cii++)
{
if(cii->X == getId()) // This ID is our child
{
if(cii->Y > 0) // A parent ID exists for our child
{
if(cii->X != cii->Y) // The parent and child ID are not the same
{
obj = m_env->getActiveObject(cii->Y);
}
}
break;
}

u16 attached_id = m_env->m_attachements[getId()];

if ((attached_id != 0) &&
(attached_id != getId())) {
obj = m_env->getActiveObject(attached_id);
}
if(obj)
return obj;
return NULL;
return obj;
}

void GenericCAO::removeFromScene(bool permanent)
{
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<core::vector2d<int> >::iterator ii = m_env->attachment_list.begin();
ii != m_env->attachment_list.end(); ii++)
{
if(ii->Y == getId()) // Is a child of our object
{
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++)
for(std::vector<u16>::iterator ci = m_children.begin();
ci != m_children.end(); ci++)
{
if(ii->X == getId()) // Is our object
{
m_env->attachment_list.erase(ii);
break;
if (m_env->m_attachements[*ci] == getId()) {
m_env->m_attachements[*ci] = 0;
}
}

m_env->m_attachements[getId()] = 0;
}

if(m_meshnode)
@@ -1098,45 +1075,43 @@ void GenericCAO::step(float dtime, ClientEnvironment *env)

// Attachments, part 1: All attached objects must be unparented first,
// or Irrlicht causes a segmentation fault
for(std::vector<core::vector2d<int> >::iterator ii = m_env->attachment_list.begin();
ii != m_env->attachment_list.end(); ii++)
for(std::vector<u16>::iterator ci = m_children.begin();
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);
continue;
}
ClientActiveObject *obj = m_env->getActiveObject(*ci);
if(obj)
{
// Get the object of the child
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());
}
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);
addToScene(m_smgr, m_gamedef->tsrc(), m_irr);

// 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();
ii != m_env->attachment_list.end(); ii++)
for(std::vector<u16>::iterator ci = m_children.begin();
ci != m_children.end(); ci++)
{
if(ii->Y == getId()) // This is a child of our parent
{
// Get the object of the child
ClientActiveObject *obj = m_env->getActiveObject(ii->X);
ClientActiveObject *obj = m_env->getActiveObject(*ci);
if(obj)
obj->setAttachments();
}
}
}

@@ -1803,16 +1778,8 @@ void GenericCAO::processMessage(const std::string &data)
updateBonePosition();
}
else if(cmd == GENERIC_CMD_SET_ATTACHMENT) {
// If an entry already exists for this object, delete it first to avoid duplicates
for(std::vector<core::vector2d<int> >::iterator ii = m_env->attachment_list.begin(); ii != m_env->attachment_list.end(); ii++)
{
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_env->m_attachements[getId()] = readS16(is);
m_children.push_back(m_env->m_attachements[getId()]);
m_attachment_bone = deSerializeString(is);
m_attachment_position = readV3F1000(is);
m_attachment_rotation = readV3F1000(is);
@@ -102,6 +102,8 @@ class GenericCAO : public ClientActiveObject
u8 m_last_light;
bool m_is_visible;

std::vector<u16> m_children;

public:
GenericCAO(IGameDef *gamedef, ClientEnvironment *env);

@@ -1379,7 +1379,7 @@ bool ServerEnvironment::addActiveObjectAsStatic(ServerActiveObject *obj)
{
assert(obj);

v3f objectpos = obj->getBasePosition();
v3f objectpos = obj->getBasePosition();

// The block in which the object resides in
v3s16 blockpos_o = getNodeBlockPos(floatToInt(objectpos, BS));
@@ -1591,7 +1591,7 @@ u16 ServerEnvironment::addActiveObjectRaw(ServerActiveObject *object,
object->m_static_block = blockpos;

if(set_changed)
block->raiseModified(MOD_STATE_WRITE_NEEDED,
block->raiseModified(MOD_STATE_WRITE_NEEDED,
"addActiveObjectRaw");
} else {
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
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)
{
@@ -1849,7 +1849,7 @@ void ServerEnvironment::deactivateFarObjects(bool force_delete)
continue;

u16 id = i->first;
v3f objectpos = obj->getBasePosition();
v3f objectpos = obj->getBasePosition();

// The block in which the object resides in
v3s16 blockpos_o = getNodeBlockPos(floatToInt(objectpos, BS));
@@ -2078,6 +2078,8 @@ ClientEnvironment::ClientEnvironment(ClientMap *map, scene::ISceneManager *smgr,
m_gamedef(gamedef),
m_irr(irr)
{
char zero = 0;
memset(m_attachements, zero, sizeof(m_attachements));

This comment has been minimized.

Copy link
@ShadowNinja

ShadowNinja Jul 3, 2014

Member

Why a zero variable instead of just using 0 directly?

}

ClientEnvironment::~ClientEnvironment()
@@ -492,7 +492,7 @@ class ClientEnvironment : public Environment
// Get event from queue. CEE_NONE is returned if queue is empty.
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()
{ return m_player_names; }

0 comments on commit 35ec385

Please sign in to comment.
You can’t perform that action at this time.