entitypickmode problem

Blitz3D Forums/Blitz3D Programming/entitypickmode problem

I don't know why....but, why doesn't entitypickmode work with scaled sprites? I have to work with entityradius, but it's not the effect I want....

Is this a blitz bug?

how do I overcome this problem..

Best Wishes

But does it work with unscaled sprites ? Because I think PickMode 2 doesn't work with sprites at all. Maybe that is because they aren't the same as meshes in terms of geometry/vertices/faces. For instance, Pivots are also not compatible with PickMode 2.
You could maybe create a square shape instead:
Function MyLoadSprite(filename$, texflag = 9, parent = 0)

	tex = LoadTexture(filename$, texflag)
	
	mesh = CreateMesh(parent)
	surf = CreateSurface(mesh)
	
	AddVertex surf, -1, -1, 0, 0, 0
	AddVertex surf, +1, -1, 0, 1, 0
	AddVertex surf, +1, +1, 0, 1, 1
	AddVertex surf, -1, +1, 0, 0, 1
	
	AddTriangle surf, 0, 1, 2
	AddTriangle surf, 0, 2, 3
	
	EntityTexture mesh, tex
	FreeTexture tex
	
	;double sided
	EntityFX mesh, 16
	
	Return mesh
	
End Function

And optionally use "PointEntity sprite, camera" to aim this 'sprite' on the camera.

Yes, it works with unscaled sprites..... but with entitypickmode 1....
goshh I'll have to change everything?? and scale it all over again??
jezzz

Wait a minute .. do you mean your problem is that you are using spherical picking mode on your sprites, which is what you need, but the picking radius doesn't change automatically when you are scaling the sprites ?
Then you could keep using sprites and simply write a function that scales the sprite and sets the radius at the same time.

Or did you mean that you need pickmode 2, but you can't get it to work with sprites ? That was what I understood, so that is why I suggested using a mesh instead. If so, how are you using the sprites ? You could then write functions that are more or less compatible with the original sprite functions and use Ctrl+R to replace them.

no,no... If I scale the sprite, the entitypickmode will work as if it wasn't scaled....
I use entityradius (wich is stupid) because it decreases the area of entitypick.. but obviously, it's a spherical pick area....
for now I only use text textures for these sprites...
so it only works with smal Texts, For instance "no" or "yes"... If use a sprite with the text "Load Game" the area will not cover all of the, X.
I've thought of using PickedX() or PickedY(), but it harder, to do it...

For instance:

Graphics3D 800, 600, 32, 2
Cam = CreateCamera()
PositionEntity Cam, 0,0,0

textu = CreateTexture(80, 15)
SetBuffer TextureBuffer(Textu)
Cls
Text 1,1, " no"
SetBuffer BackBuffer()
Spt = CreateSprite()
EntityTexture Spt, Textu
ScaleSprite spt, 0.5, 0.1
PositionEntity spt, 0,0, 2

EntityPickMode Spt, 1
EntityRadius spt, 0.13, 0.9

While Not KeyHit(1)
e=CameraPick(Cam, MouseX(),MouseY())
If e<>Entity
entity=e
Else
entity = 0
EndIf
RenderWorld()
Text 1,1, entity
Flip
Wend

ClearWorld()
EndGraphics()

(Test it, You'll see that it works.....but the area works as if it wasn't scaled... then try it with entityradius)

Here, try this:
; CreateSphere Example
; --------------------

Graphics3D 640,480,0,2
SetBuffer BackBuffer()

piv=CreatePivot()
camera=CreateCamera(piv)
MoveEntity camera, 0, 0, -2

textu = CreateTexture(80, 15)
SetBuffer TextureBuffer(Textu)
ClsColor 255, 0, 0
Cls
Text 1,1, "no"
SetBuffer BackBuffer()

Sprite = CreateSprite()
EntityTexture Sprite, Textu
ScaleSprite sprite, 0.5, 0.1
SpriteViewMode sprite, 1
FreeTexture Textu

EntityPickMode Sprite, 2
;EntityRadius sprite, 0.13, 0.9


;create spheres
For i = 0 To 1000
	ok = CreateSphere()
	PositionEntity ok, Rnd(-100, 100), Rnd(-100, 100), Rnd(-100, 100)
	EntityColor ok, Rand(255), Rand(255), Rand(255)
Next

Repeat

	TurnEntity piv, 0, 1, 0
	UpdateSprites(camera)
	RenderWorld
	CameraPick camera, MouseX(), MouseY()
	Color 255, 255, 255
	Text 0, 0, "you picked: " + PickedEntity()
	Flip
	
Until KeyHit(1)

End


;-----------------------------------------------------------------------------------------------------
; 											MESH-BASED SPRITE COMMANDS
;-----------------------------------------------------------------------------------------------------

Type Sprites
	Field mesh
	Field view
End Type

;-----------------------------------------------------------------------------------------------------
;												LoadSprite()
;-----------------------------------------------------------------------------------------------------
Function LoadSprite(filename$, texflag = 9, parent = 0)

	tex = LoadTexture(filename$, texflag)
	
	mesh = CreateMesh(parent)
	surf = CreateSurface(mesh)
	
	AddVertex surf, -1, -1, 0, 1, 1
	AddVertex surf, +1, -1, 0, 0, 1
	AddVertex surf, +1, +1, 0, 0, 0
	AddVertex surf, -1, +1, 0, 1, 0
	
	AddTriangle surf, 0, 1, 2
	AddTriangle surf, 0, 2, 3

	;double sided method I, works with PickMode 2
	;AddTriangle surf, 2, 1, 0
	;AddTriangle surf, 3, 2, 0
	
	If tex <> 0 Then	
		EntityTexture mesh, tex
		FreeTexture tex
	End If
	
	;double sided method II, could give problems with PickMode 2
	EntityFX mesh, 16
	
	s.Sprites = New Sprites
	s\mesh = mesh
	
	Return mesh
	
End Function

;-----------------------------------------------------------------------------------------------------
;												ScaleSprite()
;-----------------------------------------------------------------------------------------------------
Function ScaleSprite(sp, x#, y#)

	ScaleEntity sp, x, y, 1
	
End Function

;-----------------------------------------------------------------------------------------------------
;												RotateSprite()
;-----------------------------------------------------------------------------------------------------
Function RotateSprite(sp, x#)

	RotateEntity sp, 0, 0, x, 1
	
End Function

;-----------------------------------------------------------------------------------------------------
;												HandleSprite()
;-----------------------------------------------------------------------------------------------------
Function HandleSprite(sp, x#, y#)

	PositionMesh sp, x, y, 0
	
End Function

;-----------------------------------------------------------------------------------------------------
;												SpriteViewMode()
;-----------------------------------------------------------------------------------------------------
Function SpriteViewMode(sp, vm)

  For s.Sprites = Each Sprites
	If s\mesh = sp Then s\view = vm
  Next

End Function

;-----------------------------------------------------------------------------------------------------
;											UpdateSprites()
;-----------------------------------------------------------------------------------------------------
Function UpdateSprites(cam)

  For s.Sprites = Each Sprites
	 If s\mesh <> 0 Then 
	
		 ;sprite view modes
	     Select s\view
	     Case 1	  
		   PointEntity s\mesh, cam, 0
		 Case 2
		   ;nothing needed
		 Case 3
		   PointEntity s\mesh, cam, EntityRoll(cam, 1)		
		 Case 4
		   orgpt# = EntityPitch(s\mesh)
		   PointEntity s\mesh, cam, EntityRoll(cam, 1)
		   RotateEntity s\mesh, orgpt, EntityYaw(s\mesh), EntityRoll(s\mesh)
		 End Select
	 
     End If
  Next

End Function

;-----------------------------------------------------------------------------------------------------
;												FreeSprite()
;-----------------------------------------------------------------------------------------------------
Function FreeSprite(sp)

  For s.Sprites = Each Sprites
	If s\mesh = sp Then
		FreeEntity sp
		Delete s
	End If
  Next
		
End Function

;-----------------------------------------------------------------------------------------------------
;												CreateSprite()
;-----------------------------------------------------------------------------------------------------
Function CreateSprite(parent = 0)
	Return LoadSprite("", 0, parent)
End Function

I've made a mesh-based version of the sprite commands.
To use them, copy everything from the line 'MESH-BASED SPRITE COMMANDS' into your program.

Two commands are different:
'UpdateSprites' should be called before RenderWorld, to enable the SpriteViewModes, and 'FreeSprite' should be used instead of FreeEntity.

yeh but how do I turn them faced to camera??? if you move them along, x, they face another direction!....

Have you tried using 'updatesprites (camera)'? If the sprite view mode is set to one, they should be facing the camera.

lol... ofcourse.. nope... even your code does the same thing, for instance place your camera at 1,0,-2, and you'll see

Yes, I see .. Hmm .. I replaced the PointEntity command in the UpdateSprites function, and inserted a pivot to parent the sprite, so that aligning it to the camera doesn't affect it's orientation:
; CreateSphere Example
; --------------------

Graphics3D 640,480,0,2
SetBuffer BackBuffer()

piv=CreatePivot()
camera=CreateCamera()
MoveEntity camera, 0, 0, -2

textu = CreateTexture(80, 15)
SetBuffer TextureBuffer(Textu)
ClsColor 255, 0, 0
Cls
Text 1,1, "no"
SetBuffer BackBuffer()

Sprite = CreateSprite()
EntityTexture Sprite, Textu
ScaleSprite sprite, 0.5, 0.1
SpriteViewMode sprite, 1
FreeTexture Textu

EntityPickMode Sprite, 2
;EntityRadius sprite, 0.13, 0.9


;create spheres
For i = 0 To 1000
	ok = CreateSphere()
	PositionEntity ok, Rnd(-100, 100), Rnd(-100, 100), Rnd(-100, 100)
	EntityColor ok, Rand(255), Rand(255), Rand(255)
Next

PositionEntity camera, 1,0,-2
Repeat

	If KeyDown(203) Then TurnEntity camera, 0, +1, 0
	If KeyDown(205) Then TurnEntity camera, 0, -1, 0
	If KeyDown(200) Then TurnEntity camera, -1, 0, 0
	If KeyDown(208) Then TurnEntity camera, +1, 0, 0
	
	UpdateSprites(camera)
	
	RenderWorld
	CameraPick camera, MouseX(), MouseY()
	Color 255, 255, 255
	Text 0, 0, "you picked: " + PickedEntity()
	Flip
	
Until KeyHit(1)

End


;-----------------------------------------------------------------------------------------------------
; 											MESH-BASED SPRITE COMMANDS
;-----------------------------------------------------------------------------------------------------

Type Sprites
	Field pivot
	Field mesh
	Field view
End Type

;-----------------------------------------------------------------------------------------------------
;												LoadSprite()
;-----------------------------------------------------------------------------------------------------
Function LoadSprite(filename$, texflag = 9, parent = 0)

	tex = LoadTexture(filename$, texflag)

	pivot = CreatePivot(parent)	
	mesh = CreateMesh(pivot)
	surf = CreateSurface(mesh)
	
	AddVertex surf, -1, -1, 0, 1, 1
	AddVertex surf, +1, -1, 0, 0, 1
	AddVertex surf, +1, +1, 0, 0, 0
	AddVertex surf, -1, +1, 0, 1, 0
	
	AddTriangle surf, 0, 1, 2
	AddTriangle surf, 0, 2, 3

	;double sided method I, works with PickMode 2
	;AddTriangle surf, 2, 1, 0
	;AddTriangle surf, 3, 2, 0
	
	If tex <> 0 Then	
		EntityTexture mesh, tex
		FreeTexture tex
	End If
	
	;double sided method II, could give problems with PickMode 2
	;EntityFX mesh, 16
	
	s.Sprites = New Sprites
	s\mesh = mesh
	s\pivot = pivot
	
	Return mesh
	
End Function

;-----------------------------------------------------------------------------------------------------
;												ScaleSprite()
;-----------------------------------------------------------------------------------------------------
Function ScaleSprite(sp, x#, y#)

	ScaleEntity sp, x, y, 1
	
End Function

;-----------------------------------------------------------------------------------------------------
;												RotateSprite()
;-----------------------------------------------------------------------------------------------------
Function RotateSprite(sp, x#)

	RotateEntity sp, 0, 0, x, 1
	
End Function

;-----------------------------------------------------------------------------------------------------
;												HandleSprite()
;-----------------------------------------------------------------------------------------------------
Function HandleSprite(sp, x#, y#)

	PositionMesh sp, x, y, 0
	
End Function

;-----------------------------------------------------------------------------------------------------
;												SpriteViewMode()
;-----------------------------------------------------------------------------------------------------
Function SpriteViewMode(sp, vm)

  For s.Sprites = Each Sprites
	If s\mesh = sp Then s\view = vm
  Next

End Function

;-----------------------------------------------------------------------------------------------------
;											UpdateSprites()
;-----------------------------------------------------------------------------------------------------
Function UpdateSprites(cam)

  For s.Sprites = Each Sprites
	 If s\mesh <> 0 Then 
	
		 ;sprite view modes
	     Select s\view
	     Case 1	  
		   RotateEntity s\mesh, 0, 180 + EntityYaw(cam, 1), 0
		 Case 2
		   ;nothing needed
		 Case 3
			RotateEntity s\mesh, -EntityPitch(cam, 1), 180 + EntityYaw(cam, 1), -EntityRoll(cam, 1)
		 Case 4	
			RotateEntity s\mesh, 0, 180 + EntityYaw(cam, 1), -EntityRoll(cam, 1)
		 End Select
	 
     End If
  Next

End Function

;-----------------------------------------------------------------------------------------------------
;												FreeSprite()
;-----------------------------------------------------------------------------------------------------
Function FreeSprite(sp)

  For s.Sprites = Each Sprites
	If s\mesh = sp Then
		FreeEntity sp
		Delete s
	End If
  Next
		
End Function

;-----------------------------------------------------------------------------------------------------
;												CreateSprite()
;-----------------------------------------------------------------------------------------------------
Function CreateSprite(parent = 0)
	Return LoadSprite("", 0, parent)
End Function


it works perfectly now, thanks a lot for all your help^_^

I saw there is another problem: now, there is no to access the sprite's pivot. So, now if you move the sprite sideways, it will still move relatively to the camera.

You could use EntityParent(sprite) to get a handle to the pivot. If you want to Rotate/Position/Turn/Move the 'sprites', it is better to use that entity instead:
MoveEntity GetParent(sprite), -0.01, 0, 0