Performance
Blitz3D Forums/Blitz3D Programming/Performance
| ||
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? |
| ||
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. |
| ||
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 |
| ||
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? |
| ||
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) |
| ||
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... |
| ||
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 :) |
| ||
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 |
| ||
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. |
| ||
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.... |
| ||
that is exactly my game! |
| ||
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 |
| ||
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... ;) |
| ||
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 :) |
| ||
@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 :( |
| ||
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 :). |
| ||
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 |
| ||
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 :) |
| ||
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. |
| ||
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! |
| ||
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. |
| ||
Sounds good. Also, it would be cool cause you could tab between the open functions.bb and the main file :D |
| ||
Ofcourse you can use parameters with the functions, and use globals, to let the functions use the same variables. |