Train bounding boxes

Place to post guides, observations, things related to modding that are not mods themselves.
Post Reply
mknejp
Fast Inserter
Fast Inserter
Posts: 154
Joined: Wed Apr 27, 2016 8:29 pm
Contact:

Train bounding boxes

Post by mknejp »

While working on electric-vehicles I noticed that the "bounding_box" property doesn't really seem to work the way I expected. That part is probably my own fault for making assumptions because the property has no description in the API reference.

Basically what I was trying to do is take the locomotive's "bounding_box", use it as the "area" filter in "find_entities_filtered" and hoping I would get the rail segments the train was standing on. This worked fine for a train that was standing vertically in the north-south direction. But when the train was oriented east/west the game didn't seem to incorporate this information into the "bounding_box" value returned to Lua. As an example I have a locomotive placed at {-7.8, -3} and its bounding box is {{-8.4, -5.5}, {-7.2, -0.4}} which is clearly a vertically stretched box. The "direction" property always returns 0 regardless how the train is oriented thus I couldn't rotate the BB myself. So what I'm doing right now is take a fixed 6x6 search area centered on the locomotive, search for my electric-energy-interface entities and then do the reverse: check if find_entity() at the position of each found entity returns the locomotive. This method seems to be quite accurate, I assume find_entity() is testing against the oriented collision boxes, but I wonder if isn't overkill. Not that I'm doing this every tick but stil...

So, my conclusion here is basically: is there a better way to achieve what I'm doing? is this behavior of "bounding_box" intended, and if so is there a chance of getting a "collision_box" added to LuaEntity? It wouldn't have to be an oriented BB as there ins't much use for one but the AABB could be useful in this situation.

Nexela
Smart Inserter
Smart Inserter
Posts: 1828
Joined: Wed May 25, 2016 11:09 am
Contact:

Re: Train bounding boxes

Post by Nexela »

http://lua-api.factorio.com/latest/LuaTrain.html

using front rail and back rail you can get all the rails in between

mknejp
Fast Inserter
Fast Inserter
Posts: 154
Joined: Wed Apr 27, 2016 8:29 pm
Contact:

Re: Train bounding boxes

Post by mknejp »

I looked at those but how would I know which direction to use in get_connected_rail if there is a track switch in the middle of the train?

mknejp
Fast Inserter
Fast Inserter
Posts: 154
Joined: Wed Apr 27, 2016 8:29 pm
Contact:

Re: Train bounding boxes

Post by mknejp »

Nexela wrote:http://lua-api.factorio.com/latest/LuaTrain.html

using front rail and back rail you can get all the rails in between
Please show me how you would do that. I have been pondering about this for a while now and can't figure it out. In a situation like this
train1.PNG
train1.PNG (465.33 KiB) Viewed 12387 times
it's obvious. Using LuaTrain.front_rail, LauTrain.rail_direction_from_front_rail and iterating with LuaEntity.get_connected_rail until I hit LuaTrain.back_rail it's easy. But if the train is standing like this
train2.PNG
train2.PNG (868.5 KiB) Viewed 12387 times
then how do I know which rail_connection_direction to use at the separation without testing every combination for X amount of track? Is there a call I am missing or misunderstanding?

Nexela
Smart Inserter
Smart Inserter
Posts: 1828
Joined: Wed May 25, 2016 11:09 am
Contact:

Re: Train bounding boxes

Post by Nexela »

mknejp wrote:
Nexela wrote:http://lua-api.factorio.com/latest/LuaTrain.html

then how do I know which rail_connection_direction to use at the separation without testing every combination for X amount of track? Is there a call I am missing or misunderstanding?

You will have to do exactly what you don't want to do and test x pieces of track in all three directions. To make the check go quicker you might be able to check rail.minable. It is possible that if there is a train on it this will return false.

mknejp
Fast Inserter
Fast Inserter
Posts: 154
Joined: Wed Apr 27, 2016 8:29 pm
Contact:

Re: Train bounding boxes

Post by mknejp »

Nexela wrote:You will have to do exactly what you don't want to do and test x pieces of track in all three directions. To make the check go quicker you might be able to check rail.minable. It is possible that if there is a train on it this will return false.
Sigh. This seems really redundant to me. The game clearly already has this information available. Guess I'll stick to my existing solution for now. It's not only simpler but also seems a lot less computationally expensive.

User avatar
aubergine18
Smart Inserter
Smart Inserter
Posts: 1264
Joined: Fri Jul 22, 2016 8:51 pm
Contact:

Re: Train bounding boxes

Post by aubergine18 »

Can't you get the x,y,rotation of cargo carriages and use that to determine where rails are likely to be (when you encounter a rail junction)?
Better forum search for modders: Enclose your search term in quotes, eg. "font_color" or "custom-input" - it prevents the forum search from splitting on hypens and underscores, resulting in much more accurate results.

mknejp
Fast Inserter
Fast Inserter
Posts: 154
Joined: Wed Apr 27, 2016 8:29 pm
Contact:

Re: Train bounding boxes

Post by mknejp »

aubergine18 wrote:Can't you get the x,y,rotation of cargo carriages and use that to determine where rails are likely to be (when you encounter a rail junction)?
There is no rotation. Only direction but that always returns 0 for rolling stock.

User avatar
DedlySpyder
Filter Inserter
Filter Inserter
Posts: 253
Joined: Fri Jun 20, 2014 11:42 am
Contact:

Re: Train bounding boxes

Post by DedlySpyder »

mknejp wrote:There is no rotation. Only direction but that always returns 0 for rolling stock.
I think trains use orientation instead of direction

Nexela
Smart Inserter
Smart Inserter
Posts: 1828
Joined: Wed May 25, 2016 11:09 am
Contact:

Re: Train bounding boxes

Post by Nexela »

All rails underneath the train.

Code: Select all

function Position.expand_to_area(pos, radius) --liberated from Factorio STDLIB
    if #pos == 2 then
        return { left_top = { x = pos[1] - radius, y = pos[2] - radius }, right_bottom = { x = pos[1] + radius, y = pos[2] + radius } }
    end
    return { left_top = { x = pos.x - radius, y = pos.y - radius}, right_bottom = { x = pos.x + radius, y = pos.y + radius } }
end

local debug_picker = {}
debug_picker.name = "debug_picker"


local function valid(entity)
    if entity and entity.valid then return true else return false end
end

function debug_picker.do_script(event)
    local player = game.players[event.player_index]
    local entity = player.selected
    local rails = {}

    for _, text in pairs(player.surface.find_entities_filtered({type="flying-text"})) do
        if text and text.valid then text.destroy() end
    end
    if not entity then return end

    if valid(player) and valid(entity) and (entity.type == "cargo-wagon" or entity.type == "locomotive") then
        local train = entity.train
        if valid(train) then
            local carriages=train.carriages
            for _, carriage in pairs(carriages) do
                for _, rail in pairs(carriage.surface.find_entities_filtered({area=Position.expand_to_area(carriage.position, 4), type="straight-rail"})) do
                    if rail.minable==false then rails[rail.unit_number]=rail end --index by unique unit num to avoid dupes
                end
                --repeat above block using type=curved-rail if you want curved rail.
            end
            for _, rail in pairs(rails) do
                local text = rail.surface.create_entity({name="flying-text", position=rail.position, force=rail.force, text="RAIL", color=colors.yellow})
                text.active=false
            end
        end
    end
end
Pics or it didnt happen

mknejp
Fast Inserter
Fast Inserter
Posts: 154
Joined: Wed Apr 27, 2016 8:29 pm
Contact:

Re: Train bounding boxes

Post by mknejp »

Well yes this is obviously what I'm already doing as I described in my initial post and I find it inefficient, so I'm not sure that your point is. You suggested to use the LuaTrain API instead for more reliable results but I suggest that it's insufficient.

mknejp
Fast Inserter
Fast Inserter
Posts: 154
Joined: Wed Apr 27, 2016 8:29 pm
Contact:

Re: Train bounding boxes

Post by mknejp »

DedlySpyder wrote:
mknejp wrote:There is no rotation. Only direction but that always returns 0 for rolling stock.
I think trains use orientation instead of direction
You're right I totally missed that.

Post Reply

Return to “Modding discussion”