Is it better to use extern or pass in a pointer (C++)

Started by
13 comments, last by lukesmith123 12 years, 7 months ago
Bounding box checks need to be done to remove objects that are not in the view frustum. Yes, this needs to be done, but why would you make the camera do it?
The camera’s job is to use its own camera data to create view and projection matrices, which in turn causes the image of your world to be projected onto your screen based off where the camera is and what its camera-specific settings are (field of view, aspect, etc.)

Your flawed logic stems from thinking the camera does anything more than this (though you can inherit from your basic camera to add functionality suitable for FPS games etc., but even here you are just adding controls to it and not extending its scope of visibility). As you grow in experience you will be able to more properly evaluate what jobs and information certain classes/objects should do/have.


Now, what information is needed in order to cull objects from view?
#1: A view frustum. This is composed of 6 planes.
#2: Object bounding boxes. AABB or OBB, who cares.
#3: Probably a quad tree or octree. Some way to partition space. This is technically even optional, but it does help performance a lot.

I mentioned a frustum, which is a general-purpose structure (not used specifically just for cameras) made by planes, which are also general-purpose (not used only by frustums).
AABB’s and OBB’s are also general-purpose structures.
All of these structures so far could fit fine into a base module designed to facilitate math functions or collision-detection structures etc. So far, no knowledge of a level has entered the picture at all.


Let’s think about where these structures are located.
Camera frustum: Should it be part of the camera itself? This is typically how it is done. Since the frustum only changes when the camera moves, and that is only once per frame at most, the typical way to go is to have a camera that knows about its own view frustum and updates it once per frame. Other objects can access it in order to perform frustum culling.

AABB’s/OBB’s: Should these be part of the level?
NO. They should be part of the objects that own them. A frustum is a bounding box for a camera, which the camera updates on its own once per frame. Entities with AABB’s or OBB’s should do exactly the same.

Quad tree/octree: How about these? Part of the level?
NO. The scene manager is the manager of the game world. It should be responsible for managing the tree. Entities can take themselves out of the tree and put themselves back in just fine. The entities can know what an octree is because it is again a generic structure that does not endow the entity with completely unrelated information.
But the scene manager needs to give them an octree into which to insert themselves, and it needs to tell them when to do so (since objects may move temporarily many times per frame, it would be wasteful to update the octree every time, so once again it should only be done once per frame).



Seems this “level” thing is pretty useless.
In fact, it is. There is no real concept of a level. What makes up a level? A skybox, piece of terrain, some buildings, and interactive characters?
Being so specific is harmful. What happens when you make your editor and there is no terrain or skybox?


The term we use is a “scene”. Inside a scene, it doesn’t matter how many or few characters or objects there are. It doesn’t matter if there is terrain or not. No skybox? No biggie.

Now that the concept of a level is thrown out, and a new term introduced, you might have figured out what is responsible for performing frustum culling: The scene manager.
The scene manager has the octree and can run down it however it pleases to collect objects. It also happens to be the one being that can know about all the types of objects in your game world (cameras, 3D meshes, terrain, etc.) without overstepping the boundaries of what it should know.
For a camera to know about the terrain or for the terrain to know about the camera is a sin.


So, the entities have information about their bounding boxes. The camera has information about its frustum. Neither of them use that information (well not here).
The scene manager takes the frustum from the camera, runs through its octree, checks the bounding boxes of all the entities it finds, and compiles the list of visible objects.

Simple, huh?


By the way, just because the scene manager used the frustum of the camera to run its trace through the octree does not mean its trace through the octree requires a camera. It requires a frustum. It doesn’t matter that the frustum came from a camera, so don’t make your implementation rely on a camera. The frustum could have come from anywhere.
Do yourself one better and make your implementation rely on a k-DOP. A frustum is a specialized case of a k-DOP. If you take a general k-DOP as input you can use the same function for culling objects for shadow mapping.


L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

Advertisement
Thanks for the the really detailed help with this. My frustum culling is done exactly as you described so its good to know I was on the right track.

My level geometry is created from bsp. So the reason I had been passing the level to the camera was to test collisions with the level geometry and the camera. So for example if the camera collides with the wall you wont pass through the wall but you will stop.

So currently the camera knows about the .bsplevel object and calls a function in the .bsplevel to test collisions against it.

I cant see any way that I could do this without the camera knowing about the bsplevel

So would the correct way to organise this be to still pass the bsp object to the camera so that the camera can collide with the world but to not think of the bsp as the level and make sure all other objects like meshes, skybox whatever are handled outside of the bsp, in the "scene manager" ?
By the sounds of things your camera class is doing too much; it should only be doing the things it needs to do to be a camera in the world. So holding position, FoV, direction etc and a reference to a bounding box for collision reasons (assuming a 3rd person camera; a 1st person camera would depend upon the collision hull the player is using).

There is no need for the camera to even be aware it is in a world, it certainly should't be responding to input directly or reacting to collisions. Instead this should be dealt with in higher logic, where other piece of logic which is aware of the camera and, to some degree, the collision world it lives in, attempts to move the camera and reacts to the collision event to reset it.

Single Responsibility Principle is key here; never have a class do more than it needs to in order to be what it represents.
Yeah I agree too any culling or especially game logic like running into a wall and stopping should not be in the camera.

As for the level yogurt emeror describes the typical arrangement but for many things you can have a variety of designs. The most general arrangement can also be the least easy to use so I would not go crazy trying to make everything too generalized when you are really making one game not an engine for other people's use. I can't count the times I will be annoyingly traversing a tree to find the SINGLE geometry element for an object, for example.

This is my thread. There are many threads like it, but this one is mine.

Ok I see, so the correct way to do this would be to have a scene manager class that has an instance of the camera and an instance of the level geometry and then uses the data in the camera object to test for collisions in the level geometry object?

never have a class do more than it needs to in order to be what it represents[/quote]

thats really well put I will keep that in mind from now on.

This topic is closed to new replies.

Advertisement