box selecting 3d
Blitz3D Forums/Blitz3D Beginners Area/box selecting 3d
| ||
I am getting frusterated at this code. It is used when the mouse is released after dragging. It determines if a unit is inside the box or not. For unit.unit = Each unit CameraProject camera,EntityX#(unit\entity),EntityY#(unit\entity),EntityZ#(unit\entity) tempx# = ProjectedX#(): tempy# = Projectedy#() If ((tempx > x1) And (tempx < x2)) And ((tempy > y1) And (tempy < y1)) Then unit\selected = True Else unit\selected = False End If Next End Function where x1 and y1 is top left corner and x2,y2 is bottom right corner. Why does this code not work? |
| ||
Hard to say. You don't tell us much information, like what kind of results you get. All I can say at this point is; Have you tried using the Global flag with your EntityXYZ# commands? Have you verified that x1,x2,y1,y2 all have valid values (I can't tell from your code)? |
| ||
You realise that in the code above you have used 'y1' twice. It should read: if ((tempx>x1) and (tempx<x2)) and ((tempy>y1) and (tempy<y2)) then .... |
| ||
even with the change the program does not work. Here is an example illustrating what I am trying to do. |
| ||
I get a MAV with that program. Do you? |
| ||
If this is 3d, why not, grab the XYZ co-ords of a CameraPick, for the initial positions, then grab the XYZ co-ords of a CameraPick on releasing the mouse, and see if an of the entities centre points lie within this? |
| ||
sorry blitznerd, forgot to put in graphics 3d. if you try it now it should work. Ross, that is a great suggestion! I will try it out. In the meantime, why would the way I did it not work (for future reference)? |
| ||
How exactly does camera pick work? I know that it goes the way the camera is facing at screen coordinates inputed in the function. If it encounters no entities,however, how do I get the coordinates of the camera pick? If no entity is picked then pickedx, pickedy, and pickedz all return nothing. |
| ||
I'm not entirely sure why. I take it your projecting the entity's co-ords, into the screen co-ords, and then checking to see if the point lies within the box? (Come to think of it, that's prolly a better idea :o)) Try this: Graphics3D 800,600 SetBuffer BackBuffer() Global camera = CreateCamera() PositionEntity camera,0,5,-10 RotateEntity camera,45,0,0 Global light = CreateLight() Global plane = CreatePlane() PositionEntity plane,0,-0.5,0 EntityColor plane,100,255,100 EntityPickMode plane,2 Global sx = 0 Global sy = 0 Global st_x# = 0 Global st_z# = 0 Global fin_x# = 0 Global fin_z# = 0 Global mouse_down = 0 Type entity Field mesh Field selected End Type e.entity = New entity e\mesh = CreateCube() EntityColor e\mesh,0,100,0 e\selected = 0 PositionEntity e\mesh,3,0,3 e.entity = New entity e\mesh = CreateCube() EntityColor e\mesh,0,100,0 e\selected = 0 PositionEntity e\mesh,3,0,-3 While Not KeyHit(1) If MouseDown(1) Then If mouse_down = 0 Then mouse_down = 1 CameraPick(camera,MouseX(),MouseY()) st_x = PickedX() st_z = PickedZ() DebugLog("setting - "+st_x+","+st_z) sx = MouseX() sy = MouseY() End If Else If mouse_down = 1 Then CameraPick(camera,MouseX(),MouseY()) fin_x = PickedX() fin_z = PickedZ() If fin_x < st_x Then temp# = st_x st_x = fin_x fin_x = temp End If If fin_z < st_z Then temp# = st_z st_z = fin_z fin_z = temp End If mouse_down = 0 select_entity() End If End If UpdateWorld RenderWorld draw_bounding_box() Rect MouseX(),MouseY(),2,2 Text 0,0,st_x+" , "+st_z Flip Wend End Function draw_bounding_box() If mouse_down = 1 Then temp_sx = sx temp_sy = sy temp_fx = MouseX() temp_fy = MouseY() If temp_fx < temp_sx Then temp# = temp_sx temp_sx = temp_fx temp_fx = temp End If If temp_fy < temp_sy Then temp# = temp_sy temp_sy = temp_fy temp_fy = temp End If Rect temp_sx,temp_sy,temp_fx-temp_sx,temp_fy-temp_sy,0 End If End Function Function select_entity() For e.entity = Each entity If EntityX(e\mesh) > st_x And EntityX(e\mesh) < fin_x Then If EntityZ(e\mesh) > st_z And EntityZ(e\mesh) < fin_z Then e\selected = 1 EntityColor e\mesh,0,255,0 DebugLog("selected!") Else e\selected = 0 EntityColor e\mesh,0,100,0 End If Else e\selected = 0 EntityColor e\mesh,0,100,0 End If Next End Function |
| ||
Ok, i've looked at your code. You entity is being selected. If you debuglog() the unit\selected part:If tempx > x1 And tempx < x2 And tempy > y1 And tempy < y2 Then unit\selected = True DebugLog("Selected") Else unit\selected = False End If It's just that your selected_entity variable doesn't get set. But, if your bandbox selecting, you could only hold one entity in that anyway. So, your selection method works ;o) |
| ||
WHat to do, if your using a camera pick, is put a large, invisible quad/sprite (Entity alpha, NOT hide entity), to stop the pick reaching too far. Long picks are slow, so this will act as a stopper. If the pick returns nothing, it will be:If PickedEntity() = 0 then ; no entity picked end if |
| ||
In my example, i use a plane to pick from. The camerapick collides with the plane, i grab the co-ords from that. Your way of doing this, is alot better, so i'd definetly stick with it :o) |
| ||
Long picks are slow Hmm, yeah - I wonder why CameraPick doesn't have an optional 'pick_distance' parameter?!Mark!!! :P |
| ||
It does, it's called CameraRange. |
| ||
Er, OK, but that's not exactly what I meant. :) |
| ||
Thanks for all the help! It really showed me a lot about camera project and entity pick. Thanks! |