• entries
743
1924
• views
584207

# Various

997 views

tl:dr; collapsed in the street, spend a night in hospital. Transparent rendering works. Character controller works. Animation works. Have a first person arm-rig sort of working.

I'll start with a personal note - collapsed in the street last Wednesday and discovered I couldn't get up. A couple of very nice passers-by stopped and called me an ambulance and waited with me till it arrived - really restores your faith in humanity.

Ambulance scraped me up and took me to hospital where they decided I was severly anemic and transfused four units of blood through me overnight. Had an endoscopy the next day and, like an idiot, thought I'd get out of hospital quicker if I didn't have the sedation. Swallowed the camera okay - thought that would be the worst bit - but once it got as far down as my bowel I freaked right out and they ended up having to sedate me halfway through. I would not recommend anyone ever have an endoscopy without sedation - felt like I was being assimilated by the Borg :)

Anyway, they let me out and I'm feeling a lot better. Need to eat a bit better but my body should be able to maintain the levels now okay. All good fun. Smashed my hand and knees up a bit and a bit achy from where I fell but otherwise seem to have fully recovered and am back to work already.

I decided to wimp out and make my game first-person perspective. It is just so much easier and increases the chance I might actually get a game out of this project.

Have made some slight architectural changes to the [font='courier new']Scene[/font] manager in my game. I have set it up now so that there are multiple [font='courier new']RenderGroups[/font] - currently [font='courier new']RenderGroup::Main[/font] and [font='courier new']RenderGroup::Transparents[/font]. I've added a [font='courier new']Scene::prepare(const SceneParams&)[/font] method that can then sort the [font='courier new']RenderGroup::Transparents[/font] into back to front order based on the current view and projection matrices so that they render correctly. Nothing very exciting really.

The player character is now a proper kinematic character controller with the camera sat inside a capsule, and collides and slides with the level geometry correctly.

I imported my skeleton animation system into my [font='courier new']Gx[/font] library and have set up first-person rig using a nice low-poly arm model I found on the internet. The camera is actually attached to a head bone in the rig, so when I animate the rig, the camera should move with the head nicely.

I'm struggling to make decent animation using my model editor though. I need to spend a bit more time on this figuring out what the problems are and improving the editor's facilities.

So [font='courier new']GxAnimation[/font] is structured as follows.

You have a [font='courier new']Gx::Skeleton[/font] class that represents the skeleton, loaded from one of the bespoke binary formats my model editor exports. The basic idea is that you set a [font='courier new']Gx::KeyFrame[/font] on the skeleton, then read back the [font='courier new']Gx::MatrixPalette[/font] to feed into the scene node that then passes this into the rigging vertex shaders.

class Skeleton{public: Skeleton(); Skeleton(const Skeleton &other); ~Skeleton(); Skeleton &operator=(const Skeleton &other); Index count() const; SkeletonJoint joint(Index index) const; void setKeyFrame(const KeyFrame &key); Matrix parentMatrix(Index index) const; Vec3 bindPosition(Index index, const Matrix &world) const; Vec3 transformedPosition(Index index, const Matrix &world) const; Matrix placementTransform(Index index, const Matrix &offset, const Matrix &world) const; Index index(const std::string &name) const; std::string name(Index index) const; MatrixPalette palette() const; void loadFromStream(DataInStream &ds); static const unsigned char invalidJoint = 255;private: Matrix buildMatrix(Index index, const PodVector &pose) const; class Rep; Rep *rep;};I had great fun importing this from the old code, when I decided to implement it using PIMPL and forgot to add copy and assignment constructors. That drove me mad for a while.

The [font='courier new']placementTransform()[/font] method is very useful - you can use this to, for example, attach a sword to a hand bone and so on.

The [font='courier new']Gx::KeyFrames[/font] are generated from the [font='courier new']Gx::AnimationController[/font] class, which is able to interpolate between any number of running animation tracks. [font='courier new']Gx::Animations[/font] are loaded into a [font='courier new']Gx::AnimationMap[/font] from the binary export file and you can then set a current animation, or ask for a transition from one animation to another.

class AnimationController{public: AnimationController(); AnimationController(const AnimationController &other); ~AnimationController(); AnimationController &operator=(const AnimationController &other); void setCurrent(AnimationId id); void transitionTo(AnimationId id, bool matchToCurrent); AnimationId currentAnimation() const; void store(); void update(float delta, const AnimationMap &map); KeyFrame keyFrame(float blend, const AnimationMap &map) const; Signal event;private: void registerId(AnimationId id); void checkEvents(AnimationId id, const Animation &a, float from, float to); class Rep; Rep *rep;};So, game-side, it looks a bit like this in the [font='courier new']Pc[/font] class representing the player character:

Gx::ViewTransform Pc::viewTransform(float blend) const{ Gx::Matrix tr = Gx::rotationYMatrix(data.ang.value(blend).x) * Gx::translationMatrix(data.pos.value(blend)); Gx::Vec3 pos = data.anim.skeleton.transformedPosition(data.anim.headBone, tr); Gx::Vec2 ang = data.ang.value(blend); return Gx::ViewTransform(pos, ang);}Gx::Matrix Pc::calculateView(float blend){ data.anim.skeleton.setKeyFrame(data.anim.controller.keyFrame(blend, data.anim.map)); Gx::ViewTransform tr = viewTransform(blend); Gx::Vec3 look, right, up; Gx::computeViewVectors(look, right, up, tr.angle()); return Gx::lookAtMatrix(tr.position(), tr.position() + look, up);}void Pc::update(GameState &state, float delta){ data.pos.store(); data.ang.store(); Gx::Vec3 step(0, 0, 0); // snip, read the input events to update the step for the KCC data.kcc.move(state.physics, step); data.pos.set(data.kcc.position()); data.anim.controller.store(); data.anim.controller.update(delta, data.anim.map);}void Pc::prepareScene(SceneParams ¶ms, float blend){ node->setPalette(data.anim.skeleton.palette()); node->setTransform(Gx::translationMatrix(Gx::Vec3(0, -1.5f, 0)) * Gx::inverseMatrix(params.view));}This is probably all a bit impenetrable to the casual reader. Not sure why I bother posting it really.

Anyway, that's pretty much where we are. Next step is to try and figure out how to make some better animations for the player rig and get some kind of weapon attached to the hand.

Looks good, I respect the fact that you're making a lot of your own visual code and what not.

Stay healthy.

Glad to hear you are better.

Thanks guys.

No idea really. Perhaps a dungeon crawler but I'm not really sure. Starting to have second thoughts about the first-person perspective now anyway.

Dear lord, I could hardly focus on the code after that dramatic intro! Hope you are and stay okay, man, take care of yourself!

## Create an account

Register a new account