It's been a long while since I'd given an update on progress. Honestly this is because things slowed down a bit as I'd started to think about things a little differently following some events.
Critically, I've made the conclusion that my plans for QM1 were too ambitious. But that's left me in an odd spot of trying to figure out where I go next, and what I can work towards that isn't too ambitious but is still interesting enough.
This is surprisingly harder than you'd think - at least for me. I've got so many ideas on the go but they're all very ambitious. It needs to be something that works well within the current limitations of the engine.
I think I've settled on something, but just like with QM1, I'm probably going to keep things mostly to myself until I can demonstrate what I'm working on.
Anyway, now I'll try to cover all the progress made since the last milestone.
Decals
One of the items that was up for milestone 3 of QM1 was decals, and those are finally done. Well, at least to a basic point where I can move onto other things for now.
For now you can only cast a decal by setting up a ray, but there will probably be support for just skipping the ray step entirely to avoid duplicating that work, or can do it by a simple intersection test instead.
This turned out to be a bit of a pain in the ass as I'm absolutely terrible at math, so trying to wrap my head around it was, uh, yeah... If the code ever goes public, don't ask me how it works.
As I've been writing everything in C, rather than C++, one thing this necessitated was the introduction of a special type to count references to a given pointer, as faces and decals are created and destroyed at runtime.
For this I'd ended up introducing a com_shared_ptr
API that handles all of this now, and will likely end up being used for other things too (like portal connections.)
Third-Person Camera
Another milestone 3 item was getting a third-person camera together. This actually ended up a little better than I'd envisioned, and it's possible to toggle between different modes from which the camera correctly travels to and from.
It wasn't demonstrated in the video but the camera will also correctly collide (and try to avoid) surrounding geometry too. The entity the camera attaches to can provide a set of different properties that would let the camera smoothly shift sides if you so wanted as well.
Ironically, the third-person perspective is probably going to go unused in the game I'm planning on cobbling together instead but I'll likely retain the system itself if I ever want to use it in future.
For now there's the third-person and a free-cam mode, so I'm going to have to introduce a first-person mode next.
Unlimited Grid
Before, the grid was literally just a limited area, so you were forced to move it around a lot. It was an absolute pain in the ass, and to top that off, my code for it was fairly awful - it was a collection of points drawn into a selection buffer for determining where your mouse was.
Anyway that's all gone now, a ray is traced from the camera against a plane representing the grid. Which means you don't need to worry about moving the grid around all the time, particularly a pain point when working with larger environments.
It also got some visual treatment at the same time.
Very happy with it now! There's one minor bug I still need to investigate which occurs when aligning it to some surfaces, but it's not come up often enough for me to look into just yet.
Distance Detail
Fairly sure it was mentioned before that the goal visually was to reproduce that Spyro the Dragon look on the PSX (though modern I guess), so one of the things I introduced recently was a minor change allowing distant objects to transition into a single-colour representation.
This is basically just transitioning to the lowest mip level, so it doesn't look quite as nice as what's done in the Spyro games, which appears to transition to a lower-poly mesh with per-vertex shading. But it's probably good enough.
Per the image above, there's some annoying aliasing that needs to be investigated at some point though.
To make it a little more consistent, I'm considering just introducing a parameter you can set for the fallback colour rather than just pulling it from the lowest mip (maybe that can just be a fallback?)
UV Editor
I'm a little surprised this isn't a thing elsewhere, besides Red Faction's editor and Trenchbroom. But there's a UV editor gradually coming together, and by god it's incredibly useful even if you're not using it directly.
It still needs a lot of TLC, and hasn't been a huge priority, but being able to see where everything is lining up is already incredibly useful. Dragging the points is possible but there's some screwy crap with mouse vs. window coordinates I'll need to figure out, plus I need to introduce some sort of grid you can align to.
Coloured Strings
Some games allow you to set the colour of some text within the string itself. I'd decided to implement a similar feature.
Not fantastically exciting, but was on my mental todo list.
At the moment, they need to be formatted like this;
"$cFF0000FFWARNING: $cFFFFFFFF%s"
, but I've seen some games use some sort of shorthand for colours so I'd like to look into something similar at some point.
Didn't want to spend much time on it otherwise though, hence why that's not already the case.
More Portal and Mirror Madness
It's slow going on this because it's tricky trying to come up with a method of exposing this that doesn't feel awful.
There's now support for dynamic portal creation at runtime. This is actually an entity that procedurally creates a brush with a single face (marked as a mirror in this case) that the player can place.
I'm a little annoyed in hindsight I didn't create a follow-up video showing these opening and closing like window-blinds but bleh.
A change introduced at the same time was a tagging system for faces. So you can tag a face, and then import a room into your world instance and then connect a face to the other tagged face, in-turn creating a portal.
In addition to that, you can click onto a face and explicitly create a new room from it; this'll create a portal in the new room pointing back to the portal in the first room.
There's still more work to do here. I'm not actually happy with this, but I'm going to have to just accept this is how it's going to work for now (otherwise I'll never get it done).
That's everything I can think of mentioning for now. This was supposed to go live on Sunday, and then I was without my desktop for the day so couldn't get at the draft to finish things up. And following that there was a lot here I ended up scooping out...
It's not been a good year honestly. I don't really want to talk about personal on-goings, but yeah, it's been a big struggle. This is why things have been so quiet for the TalonBrave.info site, and one of the reasons why my momentum has slowed a bit.
Anyway, just got to keep on as best I can. I'd recently posted about the engine in the Graphics Programming Discord and had some good feedback, so that's helped me mentally, at least a little.