Jump to content

Picking from a rectangle


beo6
 Share

Recommended Posts

Hello everybody.

 

i have a small speed issue and i hope someone can bump me into a better solution.

 

I am currently working on a strategy controller which i hope i will be able to add to the Workshop when it works. :)

 

I am currently drawing a rectangle for selecting units.

Now i make a camera:Pick for every pixel inside this rectangle to get all entities inside of it.

 

However that is very slow and freezes the window for quite a long time.

 

 

Does anyone have any better idea?

 

I thought about using the pick radius that is the size of the selection rectangle. However that is a picking sphere and not a picking box so it would keep out units at the corners.

 

 

Thanks for every hint in advance.

post-60-0-40215900-1390864266_thumb.jpg

Link to comment
Share on other sites

What Christian said. Then use http://www.leadwerks.com/werkspace/page/documentation/_/command-reference/world/worldforeachentityinaabbdo-r66

 

The bummer about the callback is that it's global, but it has an 'extra' parameter which you can pass 'self' to if you are using entity scripts for this, so that you could add the entities to a table that 'self' has.

Link to comment
Share on other sites

thank you a lot. didn't thought about using an aabb

 

had no luck so far.

 

For some reason the coordinates for the start and end position of the rectangle are the same after unprojecting.

 

function Script:SelectUnitsAABB(xy1, xy2)
 System:Print("xyz1 "..xy1:ToString())
 System:Print("xyz2 "..xy2:ToString())
 local globalxyz = self.entity:UnProject(xy1)
 local globalxyz2 = self.entity:UnProject(xy2)
 System:Print("globalxyz1 "..globalxyz:ToString())
 System:Print("globalxyz2 "..globalxyz2:ToString())
end

 

maybe it is late and i miss my error.

will look into it further tomorrow / later today.

 

 

Good night

Link to comment
Share on other sites

and project entity pivot points (position) in to 2D screen space and check that against rectangle you have already made

 

What do you mean project entity pivot points into 2D space? Do you mean to project ALL possible entities position in the scene to 2D space each frame, or at request time of selection, and to use that to check against the 2D rect? Why would that be considered faster than using AABB? I mean he could possibly have hundreds of entities on screen depending on his game. I would think that would be slower to project every entity to 2D space than just project the 2D rectangle to an AABB variable. The looping of entities checking against some area still has to happen either way so that would be the same for both, but with the AABB at least you are only having to project 1 thing vs possible hundreds, so I would think using AABB would be faster, but I'm interested to hear why you think otherwise.

Link to comment
Share on other sites

I would be interested in that too.

 

i could only project the entities to 2D in looping over all entities. Maybe it is faster then my first approach.

 

Has anyone tested the method i posted? Can anyone reproduce that it returns the same value for both unprojected coordinates even though the original 2d coordinates where different?

Link to comment
Share on other sites

..why would you do such transformations every frame ? Such system require that NPC class, does that only when NPC moves, or inside camera sight, and then then update itself, what is not processing heavy at all, then store its transformed screen space coordinates. All it takes is to read it and simple > or < comparisons to determine is specific entity inside rectangle. Its much much faster than 3D bounding space calculation check against every single entity..not to mention that most probably, he will have to use oriented bounding space if he really want acceptable accuracy of detection, and that goes much more expensive for check..

 

Link to comment
Share on other sites

So beo if you were to go NA's route, which sounds faster, and the entity script route I think you would need the following.

 

 

1) Whenever an entity moves you project it's 3D position to 2D position and store that in it's entity script. Ideally you'd have a way to tell if it's visible at all by the camera, but I don't think there is a great way to do that. There is this function: http://www.leadwerks.com/werkspace/page/documentation/_/command-reference/world/worldforeachvisibleentitydo-r506 but you'd have to figure out a way to do this that isn't expensive. Instead of using that you might just project all entities when they move no matter what because you probably wouldn't want to call that inside all actor scripts. You could maybe do this inside the camera script and set some flag for that entity or something.

 

2) Now that all entities/actors have a 2D position in your camera script where you do the selecting, you just cycle through all visible entities (using the function I posted above) and check that it's x value is > the left of the rect and < the right of the rect, and that y is > the top of the rect and < the bottom of the rect and now it's selected.

 

 

It's an extra step of tracking the 2D position for each entity, than the AABB method, but like NA says it's faster (with a memory trade off to store the 2D space, which is small anyway).

Link to comment
Share on other sites

Hello,

 

thanks for all your feedback. I already thought doing it this way.

 

And i think i might need the 2D coordinates anyway to draw the health of the units on the screen. so maybe i can use it not only for the selection.

 

Who talked about doing any transformation every frame? :) maybe a missunderstanding.

Link to comment
Share on other sites

Hello,

 

sorry that i only got to try it out today.

 

Unfortunately i again stumbled over an issue.

 

Whenever i call world:ForEachVisibleEntityDo(self.entity,"Callback",context)

inside the entity script i get the error "Assert failed."

 

The Function "Callback" is empty so there should be no error:

function Callback(camera,entity, extra)
 --nothing here
end

 

inside the App.lua it just crashes with no error.

 

Also the example of the function looks a bit odd and copy/pasted from the ForEachEntityInAABBDo function.

For example there is the unused aabb variable and the description talks about specifying an aabb but there is no parameter for it.

Link to comment
Share on other sites

I would just get the middle from the rectangle and do a pick at this point with dynamic radius. sure the selection is not a real rectangle but I think this would be superfast. then you can pptimize the script when you calculate that the entity is not in the rectangle with checking x1 x2, z1 z2

 

so you have a circle selection and delete "wrong" picked entities.

It doesn´t work... why? mhmmm It works... why?

Link to comment
Share on other sites

I seem to recall the radius parameter of the pick doesn't work right now? Maybe I'm wrong, but I seem to recall that being an issue.

 

@beo6 I'll test this out when I get home. Try not sending an extra parameter once to see if that helps with the error. I assume that script is attached to a camera object so that self.entity is the camera object?

 

I'm sure the example was just copied and pasted from the AABB function.

Link to comment
Share on other sites

oh ok dont know and tested it biggrin.png just used the pick() function but dont know that the radius doesnt work.

 

 

but

 

 

whats about drawing a rectancle shape? and get entities from the collision?

 

the mouse just click and we have x1y1 and where the mouse stops is x2y2 so we have everything we need to create a rectangle shape and get the entities from the collision should also be fast?

It doesn´t work... why? mhmmm It works... why?

Link to comment
Share on other sites

@Dude, yeah you could make an AABB (bounding box) and do collisions or you can do what NA was saying, which is faster and can be more accurate. I think the differences are probably pretty small but it is technically faster and more accurate the way NA has mentioned.

Link to comment
Share on other sites

Thanks everyone. I really appreciate the help.

 

I tested around and i think at least ForEachVisibleEntityDo is bugged. See my bugreport:

http://www.leadwerks.com/werkspace/topic/8457-crash-on-foreachvisibleentitydo-when-entity-is-too-far-away/

 

I will see if i can find out why ForEachEntityInAABBDo didn't worked for me. But for now i am stuck until the bug is fixed.

Or i just go over all entites of the world. Must see how fast that is.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...