About Store Forum Documentation Contact



Post Reply 
object counter
Author Message
PRG3D Offline
Member

Post: #1
object counter
How I can count all object once type in entire world? Method container.elems() and increment some variable is wrong, exist any other way?
(This post was last modified: 06-08-2011 12:44 PM by PRG3D.)
06-04-2011 04:29 PM
Find all posts by this user Quote this message in a reply
Driklyn Offline
Member

Post: #2
RE: object counter
The easiest way is to do what you said, but this way will ONLY include objects in the active areas. If you have a large world and you want to know the count of every single object in the ENTIRE world, you will have to set a custom area data using Game::World.setAreaData<CustomAreaData>(), loop through all areas in Data/World/yourworld.world/Game, and increment a variable to keep count.

This post shows you how to create a custom area data struct. Override the method customActivate() and use area().objs() to get the count per area.
06-04-2011 10:07 PM
Find all posts by this user Quote this message in a reply
PRG3D Offline
Member

Post: #3
RE: object counter
Hmm, I wrote:

Code:
struct CustomAreaData : Game::Area::Data
{
    CustomAreaData(Game::Area &area) : Game::Area::Data(area)
    {
        game.numOfTurrent += T.area().objs();
    }
}

but game.numOfTurrent is still 0. How I can realize loop through all areas in world?
06-05-2011 06:52 PM
Find all posts by this user Quote this message in a reply
Driklyn Offline
Member

Post: #4
RE: object counter
PHP Code:
struct CustomAreaData Game::Area::Data
{
    
CustomAreaData(Game::Area &area) : Game::Area::Data(area) {}

    
void customLoadFromCache()
    {
        
game.numOfTurrent += T.area().objs();
    }


You'll need to loop through all areas once, then set area data back to Game::Area::Data instead of CustomAreaData, so the count doesn't increase later on when walking through the game.
06-05-2011 08:41 PM
Find all posts by this user Quote this message in a reply
PRG3D Offline
Member

Post: #5
RE: object counter
Ok, it's work, but how do it only one time?

Code:
    Game::World.init()
        .setAreaData<CustomAreaData>()
        .setObjType(stat,OBJ_STATIC)
        .setObjType(walls,OBJ_WALL)
        .setObjType(turrents,OBJ_TURRENT)
        .setObjType(balls,OBJ_BALL)
        .setObjType(_mechs,OBJ_MECH)
        .New("world/mapa2.world");

    Game::World.update(Cam.at);

    Game::World.setAreaData<Game::Area::Data>();

PS. If I run it progress of load map doesn't work, why?
06-06-2011 07:12 PM
Find all posts by this user Quote this message in a reply
Driklyn Offline
Member

Post: #6
RE: object counter
You know what? You don't need to use a custom area data. Now I'm actually thinking this could produce an incorrect count, depending upon the size of your world.

Here is what you need:

Code:
Memc<VecI2> areas;
Int         objs = 0;

Bool Init()
{
    // ...
    Game::World.New("world/mapa2.world");
    FAll(Game::World.gameDir() + "Area", GetArea);

    FREPA(areas)
    {
        VecI2 &xz = areas(i);
        Game::World.update(Game::World.areaSize() * xz);

        if (Grid<Game::Area> *grid = Game::World.areaActive(xz))
        {
            Game::Area &area = (*grid)();
            objs += area.objs();
        }
    }
}

void GetArea(CChar *name)
{
    areas.add(TextVecI2(Split(name, '/').last()));
}

I haven't tested this exact code so it might need a little tweaking, but it looks to me like it will work.
(This post was last modified: 06-07-2011 06:15 AM by Driklyn.)
06-07-2011 06:13 AM
Find all posts by this user Quote this message in a reply
Esenthel Offline
Administrator

Post: #7
RE: object counter
use GetBase(name) instead of Split(name, '/').last()
06-07-2011 02:51 PM
Find all posts by this user Quote this message in a reply
PRG3D Offline
Member

Post: #8
RE: object counter
This function seems to be very slow smile :
Code:
Game::World.update(Game::World.areaSize() * xz);

For big map that way its to slow to use it... Its my code:
Code:
void GetArea(CChar *name)
{
    game.areas.add(TextVecI2(GetBase(name)));
}

//in init
FREPA(game.areas)
{
    VecI2 &xz = game.areas(i);
    Game::World.update(Game::World.areaSize() * xz);

    if (Grid<Game::Area> *grid = Game::World.areaActive(xz))
    {
        Game::Area &area = (*grid)();

        REP(area.objs())
        {
            if(area.obj(i).type() == OBJ_TURRENT)
            {
                game.numOfTurrent++;
            }

            if(area.obj(i).type() == OBJ_BALL)
            {
                game.numOfBall++;
            }
        }
    }
}
(This post was last modified: 06-07-2011 05:18 PM by PRG3D.)
06-07-2011 04:39 PM
Find all posts by this user Quote this message in a reply
Driklyn Offline
Member

Post: #9
RE: object counter
(06-07-2011 02:51 PM)Esenthel Wrote:  use GetBase(name) instead of Split(name, '/').last()

Hey, thanks for the tip! That's much better to use...

(06-07-2011 04:39 PM)PRG3D Wrote:  This function seems to be very slow smile

Yeah, it's gonna take a while, especially if you have a very large map.

Calling Game::World.update() forces that area to be loaded into the world so Game::World.areaActive() returns valid data for the current area.

Each heightmap tile in your world must be looped through, if you want to count the total number of objects for the entire world.

This means that other nearby tiles are constantly being loaded/unloaded as well, which further adds to the delay.

However, I think I just thought of a solution while writing this post just now.

Try this:

Code:
Bool Init()
{
    D.viewRange(1); // lower the viewRange so there will only be 1 active area
    Game.World.init();

    // ...
    FREPA(areas) { // ... }

    D.viewRange(100); // reset viewRange
    Game::World.activeRange(D.viewRange()); // reset activeRange
}

What this does is initially sets a low viewRange/activeRange so there will only ever be 1 active area at a time. This should mean that there will be much less loading/unloading of nearby areas, which should result in greater speeds overall.
(This post was last modified: 06-07-2011 10:46 PM by Driklyn.)
06-07-2011 10:44 PM
Find all posts by this user Quote this message in a reply
Driklyn Offline
Member

Post: #10
RE: object counter
@Esenthel: Is it possible to switch WORLD_MODE's without calling Game::World.init() again? This would be extremely useful for when you need to loop through a world in the background (i.e. the player won't ever see the world during this process).

Here's a usage example related to this thread of how this process would work is:

  1. Initially load a world using WORLD_MANUAL
  2. Manually load the first area and increment the object counter by the area's object count
  3. Manually unload the current area
  4. Load the next area and repeat

After you loop through all areas individually and you have the total amount of objects in the world, you would then switch the world to WORLD_STREAM for actual gameplay.

The benefit would be that only ONE area is ever loaded at any one time. Neighboring areas would no longer have to be loaded/unloaded for no reason at all.

This would also be useful for tools, like the World Editor or the tool that I'm currently working on, that have to loop through the entire world and save data on a per area basis.
06-08-2011 03:42 AM
Find all posts by this user Quote this message in a reply
PRG3D Offline
Member

Post: #11
RE: object counter
Driklyn its much slowly then eariel method... I've very big map unfortunately. Method Game::World.objGet is it too wrong?
06-08-2011 01:27 PM
Find all posts by this user Quote this message in a reply
PRG3D Offline
Member

Post: #12
RE: object counter
Game::World.objGet don't work correctly to me grin. Is it posibble to create an object which will be never deleted and will be created at start game?
06-08-2011 02:58 PM
Find all posts by this user Quote this message in a reply
Driklyn Offline
Member

Post: #13
RE: object counter
(06-08-2011 01:27 PM)PRG3D Wrote:  Driklyn its much slowly then eariel method...

Really? My tests seem to be about 33% faster.

----------

EDIT: This probably has to do with the caching of objects. The smaller your viewRange/activeRange is, the more frequent objects will have to be unloaded/loaded and created again.

You might want to try using a higher number than 1, like 1000, and see what that does.

(06-08-2011 02:58 PM)PRG3D Wrote:  Is it posibble to create an object which will be never deleted and will be created at start game?

Look at some of the rendering tutorials, like this one: "EsenthelEngineSDK\Tutorials\Source\Advanced\2 - Animation, Physics, Rendering\Rendering\01 - Rendering.cpp". I think that will do what you want.
(This post was last modified: 06-08-2011 07:14 PM by Driklyn.)
06-08-2011 06:44 PM
Find all posts by this user Quote this message in a reply
PRG3D Offline
Member

Post: #14
RE: object counter
(06-08-2011 06:44 PM)Driklyn Wrote:  Look at some of the rendering tutorials, like this one: "EsenthelEngineSDK\Tutorials\Source\Advanced\2 - Animation, Physics, Rendering\Rendering\01 - Rendering.cpp". I think that will do what you want.

I don't see in tutorial any useful thing.
For a map containing 20000 areas, it's slow to use it in-game. Now I manually calculate object count in the editor.
06-08-2011 08:10 PM
Find all posts by this user Quote this message in a reply
Esenthel Offline
Administrator

Post: #15
RE: object counter
Well You can use world_manual and iterate all areas as mentioned earlier
But processing all areas will always be slow for real time game so do this in separate tool
You can call game world init multiple times. Maybe you need to call set obj type after it again
06-09-2011 10:45 AM
Find all posts by this user Quote this message in a reply
Post Reply