Figuring out the way to make default Cal3D sprites (aka animated characters) and their animations work again in Eulora's client turned out some unexpected pockets of sanity in CS/CAL3D, once the pile of rotten PS on top of this particular bit managed to finally get on my nerves to such extent that I fully sidelined it - if not yet removed as such (mainly because I didn't spend the time to fully follow what else might depend on it *being there* for the time being). Nevertheless, the overall evaluation of this part as likely to be more time consuming and iffier than previous parts remains valid - it took this whole past week to figure out quite important parts of it and although I have a whole pile of findings to unload here so that I can move on more easily, there is still a lot more that needs to be done and none of it looks in any way easy or even all that *clear*, no matter how you squint or glare at it. Leaving the squinting and glaring for the very end though, I'll go first through the illustrated guide of what works so far and what I added new since last article in this series.
Aiming this time to set in stone a default character rather than just have something to move about, I looked more closely at what concrete options there are currently - in the deployed client as well as in CS and Cal3D. The two Euloran characters (male & female aka Boxy & Foxy) have a few advantages, namely that they are made for Eulora and that they have some items of clothing that suit them reasonably. Nevertheless, both the characters themselves and the clothing are not really suited for any defaults, because they basically are too monolithical to start with - the body/clothing parts are already linked together so that one can't switch/mix/match as required for various changes. Moreover, there are only 2 animations so not much scope to even test all sorts and - even more surprisingly to me - the binary files failed to convert to non-binary with the default converter that Cal3D ships with. So far I left this with a question mark next to it and didn't investigate further since it's not totally clear that there is much to get from getting to the bottom of it right now.
Given the above lacks of the current euloran models, I turned again to Cal3D's test character, Cally, who has at least an abundance of body parts - some of them extremely perky parts, too. Compared to the euloran characters, Cally is huge though (100 times bigger!) and moreover in a different initial position but such differences are easily corrected with basic parameters when loading the model's files: the code can rescale, rotate a model as desired and set flags regarding the position so that further transformations don't end up flipping it all back to the original undesired stance or something1.
A few unexpected surprises came from the sidelines as they usually do. First of all, CS is incapable of handling properly collision detection when animated sprites are involved so it wraps instead everything in bounding boxes that are big enough to contain the character fully at all times - basically the collision happens with a cube of personal space within which the animated character moves. While currently there's little concern from this, it still sounds rather silly to me and it will probably make for relatively weird char to char fights and the like but each problem when its time comes and all that. Second, while Cal3D has its own format for materials, it turns out that CS can NOT load that format and therefore one HAS TO use CS materials even for Cal3D sprites! So to get it going for the time being, I simply borrowed Foxy's skin and set it on Cally - since it's anyway a basic texture otherwise, it turns out that skin sharing and borrowing works just fine at this level:
Since skin otherwise comes with the eyes in it too2 but you wouldn't be able to tell that if you looked at Cally, I tried on as well other materials - namely the ones otherwise used by the current client for Foxy's dress and Boxy's jacket. They simply turned gray and blue on Cally and I suspect quite a large part of it has to do with size and lack of specific cloths shader perhaps, but it's not something with high priority right now - perhaps later on when I actually have some sort of clothing to speak of. For now, here's Cally with gray (dress material) and blue (jacket material) skin, respectively:
For my peace of mind and thorough investigation of character's skin at this stage, I did try on the character-specific shader (there is one - it focuses mainly on lighting) but it made ~0 difference on all three different skins so I took it out again and stuck to the basic material with one single texture. The main reason I tried this shader specifically is mainly the fact that Cal3d's specification of materials focuses as well on lighting - basically it defines light-reflecting properties of the material and since CS doesn't import them directly, I wondered for a minute if they'd do anything specified the CS way aka through the corresponding shader variables - empirical results suggest they don't really do a lot really, just tiny adjustments that seem hardly worth the whole mess otherwise.
Before moving on to the animations themselves, it's worth for my future self to set down clearly in here the way Cal3D sprites are made and managed within CS, since the documentation is extremely brief to the point of missing in parts, skipping details otherwise and generally giving only the bare minimum at most. CS essentially wraps Cal3D's own classes so that it provides an interface that is at least similar to all the other meshes and factories and similar graphical elements. Moreover, there is a way to access directly the wrapped Cal3D model but apparently that's more of a rake set at a good angle to take your eyes out with, since it comes with the clear statement that modifying the Cal3D model directly comes with a near guarantee of getting it out of sync with the rest of what CS knows of it and therefore making it all a huge mess. The only way I can see this is as a sort of passive-aggressive programming - I never even knew such a thing was to be a thing, what can I tell you.
Leaving aside the direct access that is unlikely to help otherwise in the least, Cal3D provides a factory that is meant to store *all* available & possible parts and equipment for a whole class/type of character3. Seeing this in the best light, the Cal3D factory would contain all the lego-like parts that are compatible with one another. The best light is not exactly what one gets in practice though, of course, but at least the intention and potential are there, let's say4.
The very core of a Cal3D factory is the skeleton - basically all instances made of the same factory will share a common skeleton structure - everything else can in principle be different from one instance to another, but not the skeleton. On this skeleton, each instance can show a set of component meshes (basically body parts) and attached meshes (basically stuff, be it tools or cloths, that is attached via the sockets mechanism - each socket specifies the exact triangle in the host mesh where another mesh can be attached; this requires of course the host mesh to be defined through triangles at the very least). Both component meshes and any attached meshes that are equipped at any given time are selected out of all those available in the factory. Each instance of a Cal3D factory aka an actual character active in the game has its own state and can therefore keep track of its own set of meshes that are active at any given time, while also being able to switch meshes at will - in theory as I haven't yet gotten around to see this in action, mainly for lack of *alternative* meshes for the same place.
On the sad side, I have to note that all my attempts to actually use existing meshes as parts of an overall puzzle game failed miserably - basically *any* use of a mesh part from one model to another resulted in a segfault in the Cal3D lib. I'll probably have to investigate this further to get to the bottom of it in the sense of figuring out what is required exactly to produce "matching" mesh parts - and what makes them incompatible to this extent - but I suspect it all boils down to the bones they reference really, meaning that the skeleton itself will likely to have to be the main fixed part around which perhaps the rest can be allowed more flexibility.
The skeleton is so crucial to a Cal3D sprite mainly because everything depends on it, from component meshes' position to animations that represent actions and/or movement of all sorts. The skeletal animations list the ways in which bones affected by the desired movement change position. In turn, bones influence in principle any connected/attached meshes and may also cause deformations/influence cloths or the like - though this part certainly needs more investigation and testing as at the moment there are no examples to look at nor any clear documentation as to how exactly everything works there.
At any rate, the skeletal animations as defined for instance for the Cally model work perfectly fine as expected - once PS is taken out of the loop and the velocity interval is set correctly when each animation is loaded. Cal3D activates animations based on the velocity of the sprite at any given moment and the velocity intervals in which each animation is meant to be active. In principle several animations can therefore be active at the same time and Cal3D claims to be bright enough to blend them smoothly and taking into consideration priorities too - though I haven't yet seen this in action. For some basic animations, here are some screenshots of Cally in action strutting about the island, walking, waving and in mid-kick (note that the animations in game look even better than in the stills - sometimes the screenshot was basically not quick enough and got slightly messed up in between frames):
In addition to skeletal animations, Cal3D claims to also provide support for morphanimations. As far as I understand them currently, morphanimations would be required for more fine-grained movements/changes to a model, especially those involving parts that don't rely on skeletal bone movements as such - in practical terms, facial movements and expressions first and foremost. At the moment this is a big unknown since not even Cally has such advanced stuff and so I guess I'll have to... just figure it out, oh joy. On the notes-to-future-self side, there is some reasonable relevant theory writing on this, especially with respect to a supposedly robust way of reusing morphanimations across different models: the core idea is that there is a "neutral" pose and any non-neutral poses are defined by subtraction from this one so that the actual morphanimation can then be adequately calculated for any model based on its own, specific, "neutral" pose. While I haven't yet reviewed this in enough detail, it would seem to me that a similar approach could perhaps be used for skeletal animations too - a neutral skeletal pose as reference for animations described as changes to *that* rather than as tweaks to a particular set and setting of bones.
For the next steps on this, I'll have to figure out and somehow test practically the socket mechanism at the very least. Given however the desired subquest on graphics production, the socket mechanism by itself is certainly required but not sufficient - what I'll have to do is to extract/decide on what makes the essence of "euloran", fix that and provide acceptable (as in close enough to be natively recognizable but diverse enough to be also identified as distinct) ways to change/mix those. While some ideas on the topic are pushing around at various boundaries, the gritty part still has to start with digging deeper into the skeleton, meshes and morphanimations definitions, formats and use as provided by Cal3d since that's the practical starting point currently - at the very least, I clearly have to figure out what exactly is required so as not to crash in segfault the whole lib whenever replacing a part with an "unexpected" mesh.
Given the above, I plan to continue with the focus on the characters part of the client data hierarchy unless it's considered otherwise a higher priority to get the remaining missing parts back in first, even before sorting out some sort of way to cloth and diversify the characters.
This role of the flags and their interplay with applied transformations otherwise is what tripped me over previously and had caused the dive-in of the model when moving about. Yet another puzzle solved, I suppose. ↩
Doesn't this strike you already as such a deeply held conviction that knowing it *all* is always possible and even required and all that? I'm not sure how it can sit otherwise so apparently unchallenged right in code and on computers but there it is. ↩
The only thing I can say on this is that apparently I really am an incurable optimist, no idea why and how come. I can only shake my head in disbelief. ↩
Comments feed: RSS 2.0