This is the next post in my Fondusi’s Development Blog series. Click here to check out week 4 or start at the beginning.
Week 5 – August 29th – September 4th
This week we managed to get a lot of things done. Andrew did a lot of work on the region editor and I added some cool new features and fixed bugs in the lighting system.
Lighting Changes
As I mentioned in the previous post, there was a bit of a problem with how I organized the light objects. As I said before, Light objects were linked into MapCells. The problem with doing it this way is that the camera only draws the MapCells that are visible on screen, but a light can be larger than a single cell. This means that if a light spans across cells, but the MapCell that it’s linked to is no longer within the camera’s view, the Light will not get added to the main List<Light>. Which means that the Light no longer gets drawn, and since some lights were several tiles or larger, they would just disappear when they weren’t supposed to. I had to develop a system for the lights that was dependent both upon the size of the screen and the size of the largest light.
Spatial Hashing/Partitioning
I read a bit about spatial hashing and it’s essentially the same way that the tilesets are separated into tiles. The only real difference is that the spaces are “buckets” ( List<Light>) instead of tiles.
Taking the Lights into Account
So, the idea is that the map gets split up into a spatial grid where each square is 1280×1280 (in pixels). I chose this number because it is half the maximum size of my lights. The lights are radial as you probably noticed from my previous post, and so this number corresponds to the maximum distance away that the Light can be positioned before it should stop being drawn. Each 1280×1280 square in the grid will represent a bucket ( List<Light>) into which I will add the Light objects that are located within that area.
What about the screen?
That takes care of the size of the lights, now we need to take into account the size of the screen. Why? Well consider that the screen may be differently sized on different computers. It could be as small as 640×480 or as large as 1900×1600. In the first case, the screen would only ever overlap 4 buckets maximum (if it were at the corner of a bucket). However, with the larger resolution, you could see up to 9 buckets at a time! So, in order to include lights from all of the buckets that you can see, you get the IDs of the buckets that each corner of the screen overlaps. Then, with a bit of looping and some math, you can figure out all of the buckets that the screen overlaps. You can’t use only the buckets overlapped by the corners because, depending on the screen size and position, there may be buckets between them.
Ok, so once you have all of the overlapped buckets, instead of looping through tiles in the Draw loop, you can loop through the buckets to get the appropriate Lights to draw. You simply loop through the bucket list and then add all of the Lights from the bucket to the to-be-drawn Light list and Voila! Only visible lights are drawn.
On a side note, it’s possible to make it more efficient by only updating the “currently overlapped” list when one of the corners changes to a new bucket (as opposed to calculating it every frame).
The Rest
Here’s the rest of what we did this week:
- Added a controller for handling the time of day.
- Added an enum for time of day
- Updated the shader to use the new time of day values
- Updated infobox text to show different info
- Updated the tile engine based on changes
- Fixed pixel shader drawing black
- Added stuff to region and to controls form
- Added control for the time of day to the menu on controls form
- Set default override TOD for the map engine to Day
- Changed some things in the region editor
- Region colours are drawn
- Made the rain engine emitter an area emitter and tweaked some settings.
- Regions are drawing and saving
- Added light texture scaling.
- Lighting editor now changes to Night when switching to the tab
- Added ability to modify light’s scale and luminosity (lumin not yet implemented visually)
- Added controls to the lighting editor
- Created a LightingManager class
- Added a static helper class for spatial partitioning
- Moved some labels on controls form
- Updated lighting shader
- New lights now become the active light when created
- Added ability to delete selected light by pressing delete key
- Removed keyboard delete for lights
- Implemented lighting luminosity
- Added removal of lights by right clicking
- Added deselection of light by right clicking in a non-light area
- Added drawing of new light at the mouse cursor
- Added lighting draw handler
- Added the ability to click and drag the selected light
- Have lights drawing from buckets instead of tiles
- Removed linked lights from the map layer
- Changed lighting drawing code in applicable places
- Fixed bug with drawing lights that are off screen.
- Removed extra light textures
- Removed testing pixel shader variables
- Renamed the spatial partition class and made it non-static
- Added spatial partition handler to the map class
- Added snow texture
- Added WeatherSnow and WeatherController classes
- Added weather controller
- Added weather snow
- Added weather interface
- Added weather class for none
- Added ability for particle engines to remove themselves from the list
- Added status to particle engines
- Fixed bug in weather controller
- Tweaked the snow settings
- Added new layer behaviours for switching layers
- Added map properties page for testing
- Fixed control form issues
- Removed map properties
- Updated map property grid
- Set up default region textbox
- Fixed a bug with the spatial partition class
- Added temporary arrow texture
- Changed property on one of the tab controls – modified the designer manually so it *shouldn’t* cause conflicts
- Added code for drawing the layer change tool
- Actually setting tile behaviours is not done yet
- Fixed a bug with map editor spawn points (probably removing them anyways)
- Added ability to add layer change behaviours
That’s all for now! I know this has been a bit long in coming. That’s because LBC has been working on another project and I haven’t had the time to finish the post (it’s been sitting in draft since Sept 24!). The next week’s post will be about networking and all the fun stuff we’ve come across with that. Drop a comment if you have any questions.