beo6 Posted January 27, 2014 Share Posted January 27, 2014 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. Quote Link to comment Share on other sites More sharing options...
Christian Clavet Posted January 27, 2014 Share Posted January 27, 2014 Instead of doing for "every pixel" of the rectangle, I would translate the rectangle start and end coordinate in 3D. Then from these coordinates create a bounding box Then: - Inside a loop, check all the objects that are in view(if possible or all of them), then check if they are inside the bounding box. 2 Quote Link to comment Share on other sites More sharing options...
Rick Posted January 27, 2014 Share Posted January 27, 2014 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. Quote Link to comment Share on other sites More sharing options...
beo6 Posted January 28, 2014 Author Share Posted January 28, 2014 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 Quote Link to comment Share on other sites More sharing options...
Naughty Alien Posted January 28, 2014 Share Posted January 28, 2014 ..i will not create any form of 3D box..instead Ill use just 2D rectangle you have already created, and project entity pivot points (position) in to 2D screen space and check that against rectangle you have already made..much much faster and way better accuracy.. 2 Quote Link to comment Share on other sites More sharing options...
Rick Posted January 28, 2014 Share Posted January 28, 2014 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. Quote Link to comment Share on other sites More sharing options...
beo6 Posted January 28, 2014 Author Share Posted January 28, 2014 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? Quote Link to comment Share on other sites More sharing options...
Naughty Alien Posted January 28, 2014 Share Posted January 28, 2014 ..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.. Quote Link to comment Share on other sites More sharing options...
Rick Posted January 28, 2014 Share Posted January 28, 2014 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). Quote Link to comment Share on other sites More sharing options...
beo6 Posted January 28, 2014 Author Share Posted January 28, 2014 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. Quote Link to comment Share on other sites More sharing options...
Rick Posted January 28, 2014 Share Posted January 28, 2014 I did, but it was just more of a question on what he was meaning with his description. Quote Link to comment Share on other sites More sharing options...
beo6 Posted January 30, 2014 Author Share Posted January 30, 2014 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. Quote Link to comment Share on other sites More sharing options...
DudeAwesome Posted January 30, 2014 Share Posted January 30, 2014 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. Quote It doesn´t work... why? mhmmm It works... why? Link to comment Share on other sites More sharing options...
Rick Posted January 30, 2014 Share Posted January 30, 2014 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. Quote Link to comment Share on other sites More sharing options...
DudeAwesome Posted January 30, 2014 Share Posted January 30, 2014 oh ok dont know and tested it 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? Quote It doesn´t work... why? mhmmm It works... why? Link to comment Share on other sites More sharing options...
Rick Posted January 30, 2014 Share Posted January 30, 2014 @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. Quote Link to comment Share on other sites More sharing options...
beo6 Posted January 30, 2014 Author Share Posted January 30, 2014 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. Quote Link to comment Share on other sites More sharing options...
beo6 Posted February 2, 2014 Author Share Posted February 2, 2014 Hello again. i got it working now with going through all entities of the world. So far the speed is good. Will need to see how it goes when more entities are there. Thanks again Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.