Performance

Blitz3D Forums/Blitz3D Programming/Performance

Boiled Sweets(Posted 2003) [#1]
If I wanted to create a 3d maze (ie including up and down) would it be better to design it as a BSP file or create it out of a 3d array of cubes removing cubes for the path? How clever is Blitz3d? Will it have to handle/draw all the cubes that are left 'hidden' in the walls? Is there a way to get it to elimate unseen object?

Mahy question but I would value your answers...

Thanks.

P.S. Out of interest how do you post code so it looks green on black as opposed to this white on blue?


Ross C(Posted 2003) [#2]
Well, you could store a cube in an array or a type collection. Since each wall or cube fits snug-ly into it's bounding box then loop thru each cube, and say:

if entityvisible(c\ent)=false then
      hideentity c\ent
else
      showentity c\ent
end if


You'd best read up on the command, as i'm not sure of what you need to get it to work.

and for code

[ code ]

code here blah blah

blah

[ /code ]

except no spaces between the [] and code.


Ross C(Posted 2003) [#3]
here's some code i posted in the advanced forum. Very basic, but may do for what you need it.

1 and 2 key to switch cameras to see what's happening, and the arrow keys to move.

Graphics3D 800,600
SetBuffer BackBuffer()


camera=CreateCamera()

camera_overhead=CreateCamera()

PositionEntity camera_overhead,0,60,0
HideEntity camera_overhead

sphere=CreateCone()
ScaleEntity sphere,1,1,3
EntityParent camera,sphere
PositionEntity camera,0,1,0


PointEntity camera_overhead,sphere

light=CreateLight()

Type cube
	Field ent
	Field x#,y#,z#
	Field hidden
End Type


For loop=0 To 20
	c.cube=New cube
	c\ent=CreateCube()
	c\x=Rnd(-20,20)
	c\y=0
	c\z=Rnd(-20,20)
	PositionEntity c\ent,c\x,c\y,c\z
	c\hidden=0
Next


While Not KeyHit(1)



	If KeyDown(200) Then MoveEntity sphere,0,0,0.2
	If KeyDown(208) Then MoveEntity sphere,0,0,-0.2
	If KeyDown(203) Then TurnEntity sphere,0,1,0
	If KeyDown(205) Then TurnEntity sphere,0,-1,0
	
	If KeyHit(2) Then
		ShowEntity camera
		HideEntity camera_overhead
	End If
	If KeyHit(3) Then
		ShowEntity camera_overhead
		HideEntity camera
	End If
	
	Gosub checkvis
	UpdateWorld
	RenderWorld
	Flip
Wend
End

.checkvis
	For c.cube=Each cube
		If EntityInView(c\ent,camera) Then
			If c\hidden=1 Then
				ShowEntity c\ent
				c\hidden=0
			End If
		Else
			If c\hidden=0 Then
				HideEntity c\ent
				c\hidden=1
			End If
		End If
	Next
Return



Boiled Sweets(Posted 2003) [#4]
Thats great but does is there a performance increase. Doesn't Blitz3d still have to handle all the non visible items?

Would a BSP file be far more quicker?


Ross C(Posted 2003) [#5]
I'm not sure if a BSP file would be quicker, but i know when blitz hides entities, is doesn't process them at all. Mainly collisions are not checked for, so that should give you a speed up. That above btw doesn't occlude anything ie. it doesn't hide walls behind other walls that ar eon screen. I'm working on something right now regarding that. :o)


Boiled Sweets(Posted 2003) [#6]
Hi Ross,

regarding hiding non visible walls...

Now that sounds kinda a bit more like it. However would there not be loads more processing power required to work out what to hide/show and then not actually speed up processing...


Ross C(Posted 2003) [#7]
Yeah, there is a balance that needs to be struck. But you could set up some sort of portal system. Meaning when you enter a certain area of the maze, you hide other sections of it.

.123456789
a.........
b.........
c.........
d.........

And say if your in area b3, work out before-hand which areas will be hidden when in certain areas. Or you could work it out by distance. Or work it out using a 2d grid system, since each maze wall is probably the same height.

Check the 2d grid, which would be a representation of you maze, and use some sort of calculation whether 2 grid locations could see each other. That should be pretty fast. I'm sort of a beginner to this sort stuff so i'm still learning :)


Fred(Posted 2003) [#8]
I think the 3d pipeline is smart enough to eliminate the objects/vertex that are not shown. Thats the main point of a 3d engine. Rendering is secondary.

There is most likely a series of tests performed as part of RenderWorld to determine wether or not the object is within the view port


Ross C(Posted 2003) [#9]
Hey Fred. I think what he wants tho, is entities not to be rendered if they can't be seen, but are within the viewport.


darklordz(Posted 2003) [#10]
This gave me a cool idea, design a game that resembled teh movie "The Cube", 5 ppl inside trying to find their way out.....you have noidea where you are inside the cube but there is only one way out....


Boiled Sweets(Posted 2003) [#11]
that is exactly my game!


Not Available(Posted 2003) [#12]
I think if you change this:

.checkvis
For c.cube=Each cube
If EntityInView(c\ent,camera) Then
If c\hidden=1 Then
ShowEntity c\ent
c\hidden=0
End If
Else
If c\hidden=0 Then
HideEntity c\ent
c\hidden=1
End If
End If
Next
Return


to this:

.checkvis
For c.cube=Each cube
If EntityVisible(c\ent,camera) Then
If EntityInView(c\ent,camera) then
If c\hidden=1 Then
ShowEntity c\ent
c\hidden=0
End If
else
If c\hidden=0 Then
HideEntity c\ent
c\hidden=1
End If

endif

Else
If c\hidden=0 Then
HideEntity c\ent
c\hidden=1
End If
End If
Next
Return


Sorry about the formatting, I'm typing it into this box...

I remember doing some stuff with this a while ago, no for culling, but to see whether I had to animate/procedural texture an object only when it was in view - I checked first EntityVisible for the object and then EntityInview for the object if they were both true then we were in business otherwise it didn't matter. How I got some performance was to run the visibility check every 66 millisecs (why that magic number I can't remember... not documented in the source)...

The Ray_Intersect_Triangle, and Ray_Intersect_Mesh functions in the code archives could be useful for doing triangle level occulsion, again - I'd only do it every few hundred frames, and even then I'd limit just how much removal it could do in it's time (ie. a limit of say 30 ms per occulsion run). I'd also make a copy of the original object before I started removing triangles and add some velocity to camera rotates so I could predict whether an object was going to be coming back into full view and use the original copy. Also, depending on how complex the scene was - I'd probably think about storing copies of the occluded mesh at various stages so that they could be re-used without re-occulsion if that makes sense.

eg. Complex mesh in middle of screen
do
cursor left adds velocity to camera rotation
predict worst case scenario (ie. if you took your finger off the key now)

trace ray from center camera to four corners of object (or more)
if none are visible then hide object

on next removal call (ie. every N millisecs)
remove triangles based on worst case scenario

loop

Just some ideas; I don't really have a need for this sort of thing at the moment; however I will in the next 6 months - if I crack the code I'll share...

-R


ChrML(Posted 2003) [#13]
Ross C: Why do you use Gosub, instead of using the bottom code as a function? That's 100 times simplier, and would make the code a lot...better... ;)


Ross C(Posted 2003) [#14]
I don't see how it would make the code simplier if it were in a function? The reason i use gosubs (everyone hates them i know, don't know why ^_^) is because there is no parameters needing passed between. The check vis can run without any input into it.

Well, i'm prob stuck in the C64 ways :)


Ross C(Posted 2003) [#15]
@sirRicho

Only thing about entityinview is blitz only checks to see if the centre point is in view so entities sort of pop in and out of view, and can be seen by the user :(


ChrML(Posted 2003) [#16]
Wanna use a function without parameters?
Simply declare it like this:

Function Myfunction()
...my function code...
End Function


And call it like this:
Myfunction()

I would call that hundred times simplier :), lol. You have right. Everyone hates gosubs :).


Not Available(Posted 2003) [#17]
RossC,

Have a look at what I wrote here on that subject:

http://www.blitzbasic.com/bbs/posts.php?topic=26335

Kid of a cross post but a little more thought out...

-R


Ross C(Posted 2003) [#18]
mmmm.... I still don't see how it would make that code any simplier

Gosub
.checkvis
	For c.cube=Each cube
		If EntityInView(c\ent,camera) Then
			If c\hidden=1 Then
				ShowEntity c\ent
				c\hidden=0
			End If
		Else
			If c\hidden=0 Then
				HideEntity c\ent
				c\hidden=1
			End If
		End If
	Next
Return


Function
function check_vis()
	For c.cube=Each cube
		If EntityInView(c\ent,camera) Then
			If c\hidden=1 Then
				ShowEntity c\ent
				c\hidden=0
			End If
		Else
			If c\hidden=0 Then
				HideEntity c\ent
				c\hidden=1
			End If
		End If
	Next
end function


Only real difference is
gosub check_vis

and
check_vis()


:D

@SirRicho

I was think about tracing rays to the four corners of the bounding box of an entity, but i realised i would need probably four lines coming from each corner of the camera too. The top left side of the camera might be able to 'see' an entity, that the bottom right might not.

But if you take the ray from the centre of the camera, the might might not be able to see something the player can. It's a toughy :)


ChrML(Posted 2003) [#19]
Makes it more organized, cuz then it's easier to split all functions into one file you can for example call "Functions.bb", and then simply place the function itself there, and then simply use Include "Functions.bb" to include it. So, then you can use the function as many times as you want just as simple as with a Blitz command, in any project where you include functions.bb with the Include "Functions.bb" command.


Ross C(Posted 2003) [#20]
Yeah, i suppose that's really useful. Never thought of that. btw when an blitz file with includes is compiled into an exe, what happens with the include files?

Are they put in the exe or just left alone?

Cheers for the tip :)

(I think i'll leave the above program in a gosub for now :D ) Just to be stubborn!


ChrML(Posted 2003) [#21]
Who wants one codefile on 1000 pages? Cheers... :)

What's done when you use Include, is that the compilor before it compiles, kind off "pastes" the contents of the included file where you have the functions where you have the include command. Like this:

Game.bb:
Graphics3D 800,600,32
SetBuffer BackBuffer()

MyFunction()

Include "Functions.bb"


Functions.bb:
Function MyFunction()
  Print("This is my result from a function call!")
  WaitKey()
End Function



Then, what really happens is this:
Graphics3D 800,600,32
SetBuffer BackBuffer()

MyFunction()

Function MyFunction()
  Print("This is my result from a function call!")
  WaitKey()
End Function


But when you do the programming, you won't think as it like that. You just write all functions inside a Functions.bb file, and the game itself inside Game.bb, and then you can call all functions you've written inside Functions.bb inside Game.bb. When you compile to an exe, you will still have one .exe. The only difference from including the Functions.bb at the bottom, from simply "having" it in the bottom, is that the code won't be as big at all.

That's my greatest help. My .bb files are only at about 2000 lines each, and then I have the next one included. Also, I have short .bb files.


Ross C(Posted 2003) [#22]
Sounds good. Also, it would be cool cause you could tab between the open functions.bb and the main file :D


ChrML(Posted 2003) [#23]
Ofcourse you can use parameters with the functions, and use globals, to let the functions use the same variables.