1
0
鏡像自 https://github.com/luanti-org/luanti.git 已同步 2025-11-09 03:25:28 +01:00

Speedup attachement handling by replacing vector search by direct array access and secondary child lookup vector

此提交包含在:
sapier
2014-06-08 12:49:06 +02:00
父節點 56bf867874
當前提交 35ec3855f6
共有 4 個檔案被更改,包括 49 行新增78 行删除

查看文件

@@ -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++)
for(std::vector<u16>::iterator ci = m_children.begin();
ci != m_children.end(); ci++)
{
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++)
{
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
{
// 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());
}
if (m_env->m_attachements[*ci] != getId()) {
ci = m_children.erase(ci);
continue;
}
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);
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 @@ private:
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));
}
ClientEnvironment::~ClientEnvironment()

查看文件

@@ -492,7 +492,7 @@ public:
// 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; }