Visible entity
Blitz3D Forums/Blitz3D Beginners Area/Visible entity
| ||
Hi all, How to detect if an entity is visible by a rectangle area of a screen. Let's say an area specified by: upper_left, upper_top, width, height Thanks! |
| ||
Crude but effective. Parent 8 pivots to your entity, at the extremities of the meshes corners. Then do EntityInView () on the pivot you want to check for. That's the only practical way i'm afraid. |
| ||
Thanks Ross C. I tried the bbCameraViewport(cam, upper_left, upper_top, width, height) in combination with the bbEntityInView(entity, cam) but it didn't work :( |
| ||
i may not be 1 of the top coders, but i may know this, correct if i am wrong. try this: bbCameraViewport(cam, upper_left, upper_top, width, height) bbentityinview(cam, entity) use this if you wish for the cam to see the entity, or the way you used if you wish for the entity to see the cam. hope this helps! =) g/l w/ ur project! =) ~DarkShadowWing~ |
| ||
Thanks DarkShadowWing. Your idea is very clever but Blitz3D seems does not like clever people... I am getting an error: "Entity is not a camera" |
| ||
Another way is similar to Ross C solution: I can project the bounding box, 8 points total, for each entity to screen coordinates and see if these points are ALL lies within the rectangle. This check could be only for visible meshes in order to increase speed |
| ||
Wait 1 second Moraldi. What have you named the camera variable? and did you make sure you turned it into a Global variable? An example: Graphics3D 800, 600, 0, 2 AmbientLight 255, 255, 255 Global show_text Global show Global cam = CreateCamera() CameraRange cam, 1, 5000 PositionEntity cam, 0, 1, 0 Global my_object = CreateCube() EntityColor my_object, 0, 0, 255 PositionEntity my_object, 0, 1, 4 Global sky = CreateSphere(25) ScaleEntity sky, 1000, 1000, 1000 EntityColor sky, 0, 192, 255 EntityOrder sky, 9 FlipMesh sky EntityAlpha my_object, .7 EntityShininess my_object, 1.0 Global land = CreatePlane() Global landtex landtex = LoadTexture("grass.jpg") EntityTexture land, landtex While 1-KeyDown(1) PositionEntity sky, EntityX(cam), EntityY(cam), EntityZ(cam) ;position sky at cam coordinates so player cannot walk through sky object MoveEntity cam, 0, 0, 0.4*(KeyDown(200)-KeyDown(208)) TurnEntity cam, 0, 1.0*(KeyDown(203)-KeyDown(205)), 0 UpdateWorld() RenderWorld() keyz = KeyHit(44) keyx = KeyHit(45) If keyz = 1 show = 1 If keyx = 1 show = 0 If show = 1 If EntityInView(my_object, cam) ;my_object: any object that you want the object to see the camera with or switch it around and same thing. Text 10, 10, "I can see object: "+my_object Text 10, 30, "Hint: move camera around until object is not seen" Else Text 10, 10, "I cant see object: "+my_object Text 10, 30, "Hint: move camera around until object is not seen" Text 10, 50, EntityX(cam) Text 10, 70, EntityY(cam) Text 10, 90, EntityZ(cam) EndIf EndIf Flip Wend End Arrow keys to move camera Z key to show debug menu X key to hide debug menu Note: You will need the grass.jpg texture from the media file inside of samples/mak/castle =) hope that helps u! =) g/l w/ ur project! =) ~DarkShadowWing~ |
| ||
I am way from a Blitz3D installation now. I'll check your code ASAP and let you know :) Thanks! |
| ||
Its not 100% clear what you are trying to achieve. Some of the above ideas check if the corners of the entity are visible to the camera. But from your question it looks like you want to know if an entity is visible in a certain section of the screen. If so then it would be easier to use to the camerproject function. You could simply grab the 2D x,y pos of entity and then check where it appears on the screen i.e. if it appears in the top left half of the screen and the screen resolution is 1024 x 768 then x<512 and y would be <384. |
| ||
But from your question it looks like you want to know if an entity is visible in a certain section of the screen. You are right! But it is not that so simple I want to select objects using a rubber rectangle selection with the mouse. Like the way you do select icons on your XP desktop using a rectangle selection. DarkShadowWing: Thanks for your code but it is not what I am looking for. |
| ||
You are right! But it is not that so simple I want to select objects using a rubber rectangle selection with the mouse. Like the way you do select icons on your XP desktop using a rectangle selection. How accurate does your selection need to be? If you use a single cameraproject on the entity, it will return the position of the center of object. Therefore it is possible if the center of the object it not in the selection rectangle then the it wont be selected. If however this isn't an issue then its quite easy to do. Otherwise it becomes a little tricky, and you would need a mixture of the solutions above i.e. you would need to check the extremities of each object - you could to this in a couple of ways (cycling through each vertex to see if they in the rectangle, or a less precise method of attaching a bounding box to each object based on its meshsize) Once you know the extremities of your object you can then project them into 2D and check if they are in your rectangle. |
| ||
It should be simple ... You should know what the top left and bottom right 2d coords are for the rubber rect in screen space, call them x0, y0 and x1, y1 respectively. Then iterate through all the entities in the scene ( you may want to attach them to a global Mypivot for easier iteration ) and check that their 2d screen coords are within this defined rectangle. Entities = Countchildren( MyPivot ) For c = 1 to Entities entity = getchild( MyPivot, c ) cameraproject Camera, entityx( entity,1 ) , entityy( entity,1 ) , entityz( entity,1 ) if rectsoverlap( x0 , y0 , ( x1-x0), ( y1-y0 ) , projectedx(), projectedy(), 1, 1 ) ;this entity is within the rubber rectangle endif next Does that work for you? |
| ||
As Stevie G says... here's a full demo Graphics3D 1024,768,0,2 HidePointer Color 255,255,0 Global camera=CreateCamera() Global boxX%=100 Global boxY%=100 Global boxW%=300 Global boxH%=300 Type objs Field entity End Type Function addObjects() For x=1 To 40 obj.objs=New objs obj\entity=CreateCube() EntityColor obj\entity,255,0,0 PositionEntity obj\entity,Rand(-100,100),Rand(-100,100),Rand(-200,200) Next End Function Function checkBox() For obj.objs=Each objs CameraProject camera,EntityX(obj\entity),EntityY(obj\entity),EntityZ(obj\entity) If ProjectedX()>=boxX And ProjectedX()<=boxX+boxW And ProjectedY()>=boxY And ProjectedY()<=boxY+boxH Then EntityColor obj\entity,0,255,0 Else EntityColor obj\entity,255,0,0 EndIf Next End Function Function moveBox() boxX=MouseX() boxY=MouseY() End Function addObjects() While Not KeyDown(1) TurnEntity camera,0.5,0.5,0 moveBox() checkBox() RenderWorld Text 10,10, "Move mouse to move selection box" Rect boxX,boxY,boxW,boxH,0 Flip Wend You can swap the "If ProjectedX()>=boxX And ProjectedX()<=boxX+boxW And ProjectedY()>=boxY And ProjectedY()<=boxY+boxH Then" for the rectoverlap command. I didnt know that one existed ;) |
| ||
Stevie G, Uncle: You are great guys. Thank you both for your code. I need a more precise selection and I will follow the bounding box method: or a less precise method of attaching a bounding box to each object based on its meshsize) I will project the bounding box of the entity and then I will check if this projection lies within my rubber selection |
| ||
Sorry for the bad info man. I mis-read your post. I though you wanted to check whether a corner of the mesh was visible to the camera. |
| ||
No problem Ross C. I do not speak very well the English language… |
| ||
I do, i'm just sometimes terrible at reading it ;o) |