Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Problem with std::vector (my std::vector is modified outside a function)  (Read 1401 times)

0 Members and 1 Guest are viewing this topic.

Lolilolight

  • Hero Member
  • *****
  • Posts: 1232
    • View Profile
Hi!

There is something that I really don't understand.

I'm putting all static leaf visible entities of a scene node into a std::vector, this work well.

And then, I copy this vector into another vector and I insert dynamic visible entities in this other vector, here's the to last function (the one which copy the 2D vector to a 1D vector and the other which insert dynamic visible entities into the 1D vector)

vector<Entity*> Map::getVisibleEntities (std::string type) {
    View view = window->getView();
    Vec3f position (view.getPosition().x - view.getSize().x * 0.5f, view.getPosition().y - view.getSize().y * 0.5f, 0);
    Vec3f size (view.getSize().x, view.getSize().y, 0);
    lightMap->setView(view);
    shadowMap->setView(view);
    std::vector<Entity*> shadowEntities;
    std::vector<Entity*> lightEntities;
    sf::Color ambientColor = AmbientLight::getAmbientLight()->getColor();
    lightMap->clear(ambientColor);
    std::vector<Entity*> entities;
    if (type.at(0) == '*') {
        VEntitiesTypeByZ it;
        if (type.find("-") != string::npos)
            type = type.substr(2, type.size() - 2);
        vector<string> excl = split(type, "-");
        for (unsigned int l = 0; l < gridMap->getNbLayers(); l++) {
            for (it = vEntitiesByZ.begin(); it != vEntitiesByZ.end(); it++) {
                bool exclude = false;
                for (unsigned int i = 0; i < excl.size(); i++) {
                    if (it->first == excl[i])
                        exclude = true;
                }
                if (!exclude) {
                    for (unsigned int i = 0; i < it->second[l].size(); i++) {
                        if (it->second[l][i]->isShadow())
                            shadowEntities.push_back(it->second[l][i]);
                        else if (it->second[l][i]->isLight())
                            lightEntities.push_back(it->second[l][i]);
                        else {
                            entities.push_back(it->second[l][i]);
                        }
                    }
                }
            }
        }              
        bool exclude = false;
        for (unsigned int i = 0; i < animatedVisibleEntities.size(); i++) {
            for (unsigned int j = 0; j < excl.size(); j++) {
                if (animatedVisibleEntities[i]->getType() == excl[j])
                    exclude = true;
            }
            if (!exclude) {
                insertAnimatedVisibleEntity(animatedVisibleEntities[i], entities);
            }
        }      
        return entities;
    }
    vector<string> types = split(type, "+");
    for (unsigned int l = 0; l < gridMap->getNbLayers(); l++) {
        for (unsigned int i = 0; i < types.size(); i++) {
            VEntitiesTypeByZ it = vEntitiesByZ.find(types[i]);
            if (it != vEntitiesByZ.end()) {
                for (unsigned int i = 0; i < it->second[l].size(); i++) {
                    if (it->second[l][i]->isShadow())
                        shadowEntities.push_back(it->second[l][i]);
                    else if (it->second[l][i]->isLight())
                        lightEntities.push_back(it->second[l][i]);
                    else {
                        entities.push_back(it->second[l][i]);
                    }
                }
            }
        }
    }
   
    for (unsigned int i = 0; i < animatedVisibleEntities.size(); i++) {

        for (unsigned int j = 0; j < types.size(); j++) {

            if (types[j] == animatedVisibleEntities[i]->getType()) {
                insertAnimatedVisibleEntity(animatedVisibleEntities[i], entities);
            }
        }
    }
    return entities;

}
 

void Map::insertAnimatedVisibleEntity (Entity *ae, std::vector<Entity*>& entities) {

    if (ae->isAnimated()) {
        insertAnimatedVisibleEntity(static_cast<AnimatedEntity*> (ae)->getCurrentEntity(), entities);
    }
    if (ae->isModel() || (ae->getParent() != nullptr && ae->getParent()->isAnimated())) {
        std::vector<Entity*> behind;
        std::vector<Entity*> before;
        std::vector<Entity*> tmpVisibleEntities = entities;
        entities.clear();
        for (unsigned int i = 0; i < tmpVisibleEntities.size(); i++) {

            if (tmpVisibleEntities[i]->getParent() != nullptr
                && (tmpVisibleEntities[i]->getParent()->isModel() || tmpVisibleEntities[i]->getParent()->isAnimated())) {

                Model *m1 = static_cast<Model*>(tmpVisibleEntities[i]->getParent());
                Model *m2 = static_cast<Model*>(ae);
                Vec2f gc1 = m1->getGravityCenter();
                Vec2f gc2 = m2->getGravityCenter();
                Vec2f orig(gc1.x - m1->getSize().x * 0.5f, gc1.y);
                Vec2f ext(gc1.x + m1->getSize().x * 0.5f, gc1.y);
                Segment seg(orig, ext);
                Segment seg2(orig, gc2);
                int det = seg.getDir().x * seg2.getDir().y - seg.getDir().y * seg2.getDir().x;
                (det >= 0) ?  behind.push_back(m1) : before.push_back(m1);
            } else {
                entities.push_back(tmpVisibleEntities[i]);
            }
        }
        tmpVisibleEntities.clear();
        for (unsigned int i = 0; i < behind.size(); i++)
            entities.push_back(behind[i]);
        vector<Entity*> children;
        getChildren(ae, children, "*");
        if (children.size() != 0) {
            for (unsigned int i = 0; i < children.size(); i++) {
                if (!containsVisibleEntity(children[i])
                    && !children[i]->isShadow()
                    && !children[i]->isLight()) {
                    entities.push_back(children[i]);
                }
            }

        } else {
            if (!containsVisibleEntity(ae)) {
                entities.push_back(ae);
            }
        }
        for (unsigned int i = 0; i < before.size(); i++)
           entities.push_back(before[i]);

    }
}
 

In the first function the vector "entities" contains only sprite or shapes (leafs entities of the scene node), but when I pass this vector to the second function, the vector "entities" contains also root scene node entities, it seems that this vector is modified outside the second function and I don't know why.

If I don't pass a reference to the std::vector, the "entities" vector isn't modified so dynamic entities aren't insert.






Aster

  • Full Member
  • ***
  • Posts: 130
    • View Profile
Could you please provide a simple code example that reproduces the issue? Nobody wants to read through your messy code to find a bug that probably isn't even SFML's fault.

Lolilolight

  • Hero Member
  • *****
  • Posts: 1232
    • View Profile
I've found why sorry, it's not m1 which is a root entity scene node but tmpVisibleEntities that I had to insert into the behind and before vectors :

(det >= 0) ?  behind.push_back(tmpVisibleEntities[i]) : before.push_back(tmpVisibleEntities[i]);
 


 

anything