CameraProject question

Blitz3D Forums/Blitz3D Programming/CameraProject question

John Blackledge(Posted 2009) [#1]
When I use....

x#=EntityX#(ent,True)
y#=EntityY#(ent,True)
z#=EntityZ#(ent,True)
CameraProject(cam\hcam,x#,y#,z#)
tx=ProjectedX#()
ty=ProjectedY#()

...I have a massive FPS slowdown.

I'm assuming that the fault lies with the CameraProject() distance to entity. (It's a space game, and too late to change all the scaling.)

Is there any alternative to CameraProject()?


_PJ_(Posted 2009) [#2]
Never knew about that slowdown, but if you want an alternative, presumably you could try just getting the X and Y offsets from the entities to the camera. Maybe using the z-buffer disabled ortho camera mode too?

This will probably involve some funkiness regarding the camera orientation though, and that's where I fail - my limit of trig is "Something to do with angles" :P

If you can resolve the offset amounts. you would likely need to then scale these offsets to the camera viewport or screen width.

Then again, I assume this is all that cameraproject should do behind the scenes, but I can't see it being a significantly slow process :?


John Blackledge(Posted 2009) [#3]
Malice, I think you've correctly described what CameraProject does.

At first I thought "If Blitz can display it on a 2D screen then why can't it tell me where, more easily?"

But of course it's DX doing the display work.

I have 32 astronomical bodies, and no matter how far away they are I need to put their names (icon-sized) on the screen.
This is no problem thanks to FastText.
But the further-off bodies cause a real slow-down.

I've added in (for each ent in the loop)
If EntityInView(ent,cam\hcam)
If EntityVisible(cam\hcam, ent)
which has improved it, but I'd still like a faster method.

I wonder if CameraProject(cam\hcam,x#,y#,z#) is actually doing a controlled linepick.
And we all know how slow _that_ is.


Warner(Posted 2009) [#4]
It might be a good idea to ensure that the slowdown is caused by CameraProject before searching a replacement for it. It might as well be caused by the usage of Text or any other 2D commands.


John Blackledge(Posted 2009) [#5]
Warner, I've already done that.
As I said FastText has solved 2D text display problems.
It's CameraProject which is causing the slowdown.


Charrua(Posted 2009) [#6]
hi, dont know if it helps, but i remember to suffer with some thing similar a while ago, and if i don't forget my trouble were slowdown by EntityVisible and EntityInView, and of course Text, but you has not that problem. if all fail, i think that you has to work with projection equations, but i think that is what CameraProject do.

Juan


Warner(Posted 2009) [#7]
I don't think CameraProject performs any picking. Picking would require some geometry.
I tried to write something that uses TFormPoint instead of CameraProject. It is just a small experiment and it might need some tweaking to get it right:

Not sure if it would be faster though, since it should be similair to what CameraProject does.


_PJ_(Posted 2009) [#8]
This might be of some help, it will need some tweaking:

;parallax

Graphics3D 800,600
SetBuffer BackBuffer()

Global cam=CreateCamera()

Global planet1=CreateSphere()
MoveEntity planet1,Rand(-5,5),Rand(-5,5),Rand(20,100)

While (Not(KeyDown(1)))
	
	; ARROWS  MOVE UP/DOWN, LEFT/RIGHT MOUSE BUTTONS MOVE Z-DIMENSION
	MoveEntity planet1,(KeyDown(205)-KeyDown(203))*0.1,(KeyDown(200)-KeyDown(208))*0.1,(MouseDown(1)-MouseDown(2))*0.1
	
	UpdateWorld 
	RenderWorld
	If ((EntityInView(planet1,cam)) And (EntityVisible(planet1,cam))) Then UpdateParallax(planet1,cam)
	Flip
Wend

Function UpdateParallax(entity,camera)
	Local Distance%=EntityDistance(entity,camera)
	; Y Dimensions reversed as 2D coordinates involve Y increasing DOWN the screen.
	TFormVector EntityX(camera)-EntityX(entity),EntityY(entity)-EntityY(camera),EntityZ(camera)-EntityZ(entity),camera,entity
	
	Text EntityX(camera)-TFormedX(),EntityY(camera)-TFormedY(),"Here"
End Function



Kryzon(Posted 2009) [#9]
Why does the UpdateParallax function retrieves the Distance% if it never uses it for anything?


D4NM4N(Posted 2009) [#10]
Not noticed any slowdown myself, and i have had it sticking sprite based text labels on 1000 trees.

The only difference i can see from the way i use it is i use ProjectedX wihout the float type identifier. It should not matter because i asuume TX TY are ints anyway but you could try it without, you never know :/

Edit: just thought of something, what are you doing with the result, are you drawing 2d graphics, ie text or image over 3d at that location? If so it might be that giving you the hit rather than the project itself.


John Blackledge(Posted 2009) [#11]
Malice, that looked interesting, but all it gave was a ball in the centre of the window and "Here" in the top-left corner.
(They didn't move in unison.)


DareDevil(Posted 2009) [#12]
Hi all

Hi have changed the code Warner for test the difference coord and time

test this




Bobysait(Posted 2009) [#13]
First thing :
TFormPoint x,y,z, cam, 0 is wrong !
+>as you do it , it will work in only one case : Camera is positioned at 0,0,0 with no rotation, so the TForm just compute x,y,z to ... x,y,z ^^

good way : TFormPoint x,y,z,0,cam that will transform coordinates locally to camera.

second thing :
For a = 0 To g_MaxCicle
TFormPoint x, y, z, cam, 0
CameraProject(cam, TFormedX(), TFormedY(), TFormedZ())
px# = ProjectedX#()
py# = ProjectedY#()
Next

there is no need for TForm here as CameraProject already performs it.


If you want a test that make sense replace with this :

	If(Not KeyDown(57))Then 
		g_str = "Solution A"
		For a = 0 To g_MaxCicle
			TFormPoint x, y, z, 0, cam
			zz# = TFormedZ()
			px# = g_HWidth * ( 1.0 + TFormedX() / zz )
			py# = g_HWidth * ( Float(g_HHeight)/g_HWidth - TFormedY() / zz )
		Next
	Else
		g_str = "Solution CameraProject"
		For a = 0 To g_MaxCicle
			CameraProject(cam, x,y,z)
			px# =  ProjectedX#()
			py# =  ProjectedY#()
		Next
	EndIf



Warner(Posted 2009) [#14]
Indeed, the TFormPoint line was reversed. The following should be better:



_PJ_(Posted 2009) [#15]

Why does the UpdateParallax function retrieves the Distance% if it never uses it for anything?


The original function where I cut this from makes use of distance in measuring parallax. In a full versdion of the function here, it would require distance though I never incorporated it.



Malice, that looked interesting, but all it gave was a ball in the centre of the window and "Here" in the top-left corner.
(They didn't move in unison.)



Yeah it wasn't intended as a fix per se, just as a basic example of the method. Moving the sphere SHOULD show the 'Here' text moving in relative XY dimensions even if it's not lined up...


John Blackledge(Posted 2009) [#16]
Warner (and all) - absolutely brilliant! That makes all the difference.
I just substituted

TFormPoint x, y, z, 0, cam
zz# = TFormedZ()
If zz = 0 Then zz = 1 ;avoid division by zero
px# = (TFormedX() * zoom * 400 / zz#) + 400 ;divide by Z
py# = -(TFormedY() * zoom * 400 / zz#) + 300 ;y-axis is flipped

for the noraml Blitz code, and now it's as smooth as it can be.

Thanks, all.