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! |