finding XY coordinates for entities
Blitz3D Forums/Blitz3D Beginners Area/finding XY coordinates for entities
| ||
I have a bunch of entity's on screen (namely sprites). Now, I've got entitypickmode and camerapick working fine, so that once I move the cursor over an entity, it is correctly targeted. However, I want to draw a box around it. I tried doing this with a sprite, ie - have a box sprite, position the box sprite where the entity is when its "picked", but of course with using a sprite comes blurry lines, missing lines, etc - with distance. Is there an easy way to figure out the XY size of an entity AS rendered on-screen? Or is it going to take a whole bunch of calculations to turn the entity XYZ information into useable XY coordinates? Thanks, BlackD |
| ||
deleted.. |
| ||
Have a look at the CameraProject commmand. |
| ||
err.. CameraProject command appears to have absolutely nothing to do with what I'm trying except to see if a given XYZ coordinate is visible. I'm way past that. :) I want to convert an already known visible entity at an XYZ position into XY,WH coords. I even already know the XY position, but how do I find out the width and height of that object as rendered on the screen? |
| ||
cameraproject will give you the screen coordinates of a 3d-coordinate, but still not the screen size of an entity. I'd suggest to use camerazoom (default is 1.0) * distance * real entity size. Unfortunately the real entitysize sometimes cannot be found using MeshWidth etc. THere are some ways around this, eg: parse all vertices of a mesh and find the min and max x,y,z (using tformpoint with vertexX etc.). These 6 Coordinates will give you a box of the real size of the entity. But now this box is still not aligned to the screen. A very quick and dirty workaround is to create a big screen-oriented cube around the entity, then move it towards all 6 directions seperately until MeshesIntersect will signal that the box was touching the entity (because they won't intersect as long as the entity is completely inside the box). I know, this is a silly method, but at least it works and you won't get too much headache. If you would seek the locations of intersetion with a boolen stepwidth concept, it would also be extremly fast. |
| ||
thanks a bunch JFK. Although not direct, you answered my question - ur ideas there stimulated some thinking. I think it'll take less space to code it than explain it, but heres how I'll do it. - I already know what sizes the entities are. - Create a cube around the entity and orient it to the screen. - extract the XYZ coordinates of the 4 facing corners. - create pivots on these points. - Find the Screen XY locations of each of these pivots. - Voila! You have 4 sets of coordinates from which you can make up X1,Y1 to X2,Y2 With X1,Y1,X2,Y2 I can do a lot more than just draw a box. :) Only a small amount of hacking would be required to take into account entities that are partly off screen, since the entity size is already known. Hehe.. you'd think there'd be a single command to do it. Theres still lots of us 2D-USING-3D programmers. :) Mark - EntityVisWidth() EntityVisHeight() ;) Thanks again, +BlackD |
| ||
Okay.. figured out the quickest way to do it. Buggy when two entities are overlapped, would need a little more coding there. Used CAMERAPROJECT as suggested simply to remove another loop from the code and double the speed. Quick and easy (and very dirty) 2D entity-bounding box: Graphics3D 800,600,0,2 camera=CreateCamera() light=CreateLight() SeedRnd MilliSecs() ;create some pickable entities Type thing Field mesh Field x Field y Field z End Type For i = 1 To 20 sphere.thing = New thing sphere\mesh = CreateSphere() sphere\x=Rnd(-20,20) sphere\y=Rnd(-20,20) sphere\z=Rnd(10,40) EntityPickMode sphere\mesh,1 EntityRadius sphere\mesh,1 PositionEntity sphere\mesh,sphere\x,sphere\y,sphere\z Next While Not KeyHit(1) UpdateWorld RenderWorld For sphere.thing = Each thing If sphere\mesh=CameraPick(camera,MouseX(),MouseY()) Then CameraProject camera,sphere\x,sphere\y,sphere\z x=ProjectedX() y=ProjectedY() ;find top ty=y While sphere\mesh=CameraPick(camera,x,ty) ty=ty-1 Wend ;find bottom by=y While sphere\mesh=CameraPick(camera,x,by) by=by+1 Wend ;find left lx=x While sphere\mesh=CameraPick(camera,lx,y) lx=lx-1 Wend ;find right rx=x While sphere\mesh=CameraPick(camera,rx,y) rx=rx+1 Wend w=rx-lx h=by-ty Rect lx,ty,w,h,0 End If Next Flip Wend End |
| ||
You should be able to use PickedTime() multiplied by a constant to scale the box sprite. It should then remain at a constant size onscreen, regardless of the distance the selected sprite is away from the camera. I've used this method before to scale a small sphere I was using as a 3D mouse cursor. It seems to work well. |