Wednesday, March 3, 2010

Of course...

I was mistaken yesterday when I thought I had solved all the problems. Of course. Because my mesh was not written (by hand) correctly to begin with, I didn't realise that when it looked right, it was actually wrong. I fixed the problem, but now something else is not quite right: there's some strange offset showing up when I rotate a bone around a joint. I'm still trying to figure out where that came from, I guess I have to re-think everything again.

Tuesday, March 2, 2010

Life is strange sometimes

I appologise in advance for a whole lot of boring detail you don't want to read, but I want to get off my chest.

I spent a good bit of time trying to get the animation system to deform meshes correctly, but I just couldn't quite get it to work and I couldn't figure out why. So I stopped working on it for a good long while. Now when I get into something, I really get into it - for a while. It may take months, but eventually I cool down and my enthusiasm dies. From the moment I came up with my current game dev plans I knew that once my obsession cooled I would stop working on the game, so I worked as hard as I could while the idea was still fresh, hoping that the progress I was making would sustain me. And it did, for a while. But eventually work, video games and Warhammer just pushed the project to the back of my mind.

So I've barely touched the code over a month. I wrote a bit a couple of weeks back, but then I undid all my changes and reverted to what was then month-old code. But it still gave me a better idea of how to solve the problem, and every once in a while I would spare a little thought to the issues I was having. And then today I finally sat down and in under two hours I re-wrote a good deal of the animation code and fixed all the problems. Under two hours. Days of coding in circles, six weeks of avoiding the problem, then two hours to fix it. In a way it's amazing when it happens, but on the other hand it makes you wonder what you were doing wrong the rest of the time.

Anyway, my mistake was that I was not applying bone length correctly, this wasn't a problem sometimes but it screwed up the inverse bind matrix, which made the problem hard to spot. I also removed the bone offset (this can be replaced by intermediate bones, it may be less efficient in some cases but typically the offset is not used so this is slightly more efficient for most rigs), but now that I've figured out the way the bone length is applied I beleive I can easily put the offset back in later if I decide I want it back.

So here's a couple of quick, and rather unspectacular, screenshots. Now I think I need to replace the linear interpolation of the matrices with a spherical linear interpolation, perhaps replace some of the 4x4 matrices with 3x3 for efficiency, then finish implementing the system in the actual animation pipeline. Then of course figure out how to get actual model bone and animation data out of blender and into my engine (either write custom exporters in Blender, which requires learning python, or writing an importer or converting from some other format - which I actually expect to be just as hard of not more so), which of course I can't do until I figure out animation and skinning in Blender... ugh, this is going to take forever, and those Warhammer armies aren't going to paint themselves either.


Sunday, January 17, 2010

I can't believe this hasn't been done yet!

OK, so I was thinking about an old episode of the Justice League cartoon, where Superman and Wonder Woman are trying to recover an ancient artifact that is part of the key to Hades because... you know what? Never mind. The point is, the artifact is protected by a curse that makes each one see the other as a demon, so they start fighting. There's a similar idea in an old episode of the Street Fighter animated series (I believe it predates the Justice League episode) where Ryu and Ken enter a cave which makes each see the other as a living statue, and of course they fight each other. For a better idea of what I mean, check out the Contract - the Cretcher cyborg is a perfect example.

So then I thought: bloody hell, why can't you do that in a game? Basically, a split-screen game where each player sees the same terrain and other players in a completely different way. Picture: you're running down a steel corridor in a high-tech cyborg part production factory, and you run into a combat cyborg with a chainsaw for a hand. You raise your machine-gun and take aim... meanwhile, your friend is exploring an ancient and cursed castle, when he rounds a corner and comes face to face with a hideous demon, all fire and brimstone. As the creature takes a deep breath and prepares to spew demonic fire at his face, he raises his sword and prepares to attack... cool enough online, but even better in split screen where you can see yourself through your opponent's eyes.

I believe there is something a little similar in Demon's Souls, where online players appear as ghosts or something (never played it), but you still see the same landscape. Of course games like Area 51 and Haze, which had special vision modes, allowed people to get different views, but that's not quite the same as entirely different realities that overlap.

Clearly this is related to my existing plan for the "spirit world" in which you see different things overlapping, but in this case the focus is not on you seeing different views, but rather on different people seeing the same thing in different ways (I'm sure there's a metaphor for life in there somewhere...).

I'm actually thinking a third person game would work better for this, so in split screen you can step alongside your friend and see the same scene (including your characters) and see the differences. Using headsets or when online you could even hear different sounds - imagine you talk to your friend online and the sound of you voice is modified to make you sound like a robot, while he sounds like a monster or ghost. Every player could decide separately what they are - robot, samurai, space marine, knight, cop etc. and the whole world and everything in it reflects that reality, perhaps you would never know what they were seeing. This could have game play implications if characters of different "realities" had different stats and abilities - for example, a knight or samurai has a 1-hit-kill melee attack but only very slow firing projectile weapons, so the decision about whether to close in or firefight from a distance is critical. Alternately, you could see everything as it would be in your reality except human players, who would appear to you as they see themselves, creating some interesting visual scenarios. For example picture a co-op game where you're a space marine battling aliens alongside a samurai.

Now I realise that there are serious issues with the idea, namely loading two completely separate sets of textures and models for everything (even animations and perhaps even sounds) will damn near double the memory requirements, so everything will have to be downsized to compensate for that. But the fact is there's plenty of stylized games which don't push system limits yet are still enjoyable and visually pleasing. Portal wasn't graphically amazing, but the graphics were perfectly suitable for the setting and it was a great game. When playing online there won't be any problem at all of course.

So the question now is, is it worth trying to actually do something with this idea? Of course I can't be too ambitious, but if it seems feasable later on in the project I would like to try.

Monday, January 11, 2010

Bones! Jim!

I've been spending a bit of time on a skeletal animation system. I've written the core of the bone, rig, and animation classes, so now I can animate a rig. The next step is to bind vertices so that I can animate actual models, followed by writing tools to export the data from a modelling package (or load or convert from an existing format, whichever I decide is easier).

The problem is thus; the way I planned to animate the vertices will not work because of the data format. Either I change the format with much effort and lose any hope of getting the engine to work on the PSP (admittedly a rather distant hope at this point), or I use an unpleasant and inefficient work-around. So for now I'm putting it off, hopefully I'll get the chance to do some reading and maybe I'll spot something that I'm missing.



Thursday, December 3, 2009

For the Emperor!

Since I haven't posted anything in a while, I decided to put up a picture of my Ultramarines. They all look different because I was experimenting with colour combinations and painting techniques. I'm thinking of going for either Crimson Fists or Iron Hands instead of Ultramarines, or creating my own chapter (who I'm thinking of calling the Bleeding Hearts, for reasons I won't go into right now).

Friday, November 6, 2009

Brave new chicken

I've not really done any programming recently, which does not make me happy. The last thing I completed was some edge-polygon intersection code for the mesh splitting system. While I was testing this I ran into some issues that I had faced before in my previous mesh splitting system. The thing is, the last time I chickened out due to time constraints and went with a simpler version. This time, however, I shall try to keep hacking away at it and see if I can't implement the full system that I failed to complete last time. But I'll be doing it bit at a time while I work on the other parts of the engine, which of course I'm barely working on since I'm hella-busy with work and since I've just taken up painting Warhammer 40K miniatures, which I'm almost stunningly slow at. Seriously, I'm still working on my space-marines starter pack. Hopefully someday I'll get around to those Grey Knight Terminators that I just couldn't resist buying.

Thursday, October 8, 2009

Killing time

Right now I'm putting off starting any major jobs on my engine, mainly because I need to spend more time with Blender but don't want to because I'm currently trying to learn 3D studio Max (and other softwares) for my job. Until I can start working on the animation system, I've been spending a little time integrating my old mesh splitting system using the new mesh format I'm using. This has given me a chance to experiment with a pattern of code organisation I thought up. Basically, there are some functions that I may use often in areas that aren't speed-critical, but will also need on rare occasion in very speed-critical areas. This may seem obvious to most people, but I've never seen it in use and so I'm kind of happy with the idea, but basically what I do is write the function as an inlined function, but also have a non-inlined version that just calls the inlined version. For example:

int calculateThing(int i1, int i2);
int calculateThingFast(int i1, int i2);

inline int calculateThingFast(int i1, int i2)
{ ***blahblahblah*** }

int calculateThing(int i1, int i2)
{ return calculateThingFast(i1, i2); }


Now, assuming that the compiler actually inlines the function properly (not sure how to check on that, if anyone knows how to make sure it does actually inline the function please let me know), I will be able to inline the function where needed and call it normally where needed. By the way, if anyone knows a better way to do this, by all means let me know.

Anyway, I've written an infinite plane cut class using inlined line-test functions, which curently tests edges against a plane (it is also capable of figuring out if the ends of the edges are exactly on the plane, which I will need later). Here's some sample images. The plane is represented by a square with a red dot representing the center (or a point on the plane) and a fading line representing the normal. Since the plane is of infinite size, the size of the square is not relevant.
The red dots signify that the plane is intersecting the exact ends of the edge. While it isn't obvious, the bottom edge, which is parallel to the plane and therefore fails normal line tests, is correctly being handled, and the two ends of the edge are being marked as exactly on the line.

Now a normal line test against the two upright edges.
The top of the edges are being detected as exactly on the edge.

So some progress is happening, next I want to work on a finite, circle-shaped cut, then a convex polygon cut. Once that is done, the next step is to start handling the different possible cuts, then triangle sorting, new face generation, handling transforms etc. Of course in the long run it has to be integrated with the model format rather than the current simple mesh, as well as needing to work properly with the animation system (a problem I never solved in the past) which doesn't even exist yet... basically it's going to take a while, and I'm busier than ever now. Still, I shall try to keep at it. Wish me luck.