Skip to content

Commit

Permalink
Model Renderer|ClientPlayer: Observe psprite and current weapon changes
Browse files Browse the repository at this point in the history
When the game notifies about current weapon and psprite state changes,
ClientPlayer checks that (respectively) if there is a 3D model asset
available with the weapon's identifier, and triggers animation
sequences.

Also started setting up support for ModelRenderer in vispsprite_t.
  • Loading branch information
skyjake committed Jul 31, 2015
1 parent 377512d commit 953b5b0
Show file tree
Hide file tree
Showing 10 changed files with 85 additions and 11 deletions.
2 changes: 2 additions & 0 deletions doomsday/apps/client/include/clientplayer.h
Expand Up @@ -93,6 +93,8 @@ class ClientPlayer : public Player
*/
void setWeaponAssetId(de::String const &id);

void weaponStateChanged(struct state_s const *state);

private:
DENG2_PRIVATE(d)
};
Expand Down
2 changes: 1 addition & 1 deletion doomsday/apps/client/include/def_main.h
Expand Up @@ -151,7 +151,7 @@ void Def_PostInit();
*/
void Def_Read();

de::String Def_GetStateName(state_t *state);
de::String Def_GetStateName(state_t const *state);

/**
* Can we reach 'snew' if we start searching from 'sold'?
Expand Down
4 changes: 4 additions & 0 deletions doomsday/apps/client/include/render/playerweaponanimator.h
Expand Up @@ -34,6 +34,10 @@ class PlayerWeaponAnimator
public:
PlayerWeaponAnimator(ClientPlayer *plr);

void setAsset(de::String const &identifier);

void stateChanged(state_t const *state);

MobjAnimator &animator();

void advanceTime(de::TimeDelta const &elapsed);
Expand Down
7 changes: 7 additions & 0 deletions doomsday/apps/client/include/render/vissprite.h
Expand Up @@ -22,6 +22,7 @@
#define CLIENT_RENDER_VISSPRITE_H

#include <de/Vector>
#include <de/GLState>

#include "render/billboard.h"
#include "rend_model.h"
Expand Down Expand Up @@ -188,6 +189,12 @@ struct vispsprite_t
de::dfloat yawAngleOffset;
de::dfloat inter; ///< Frame interpolation, 0..1
} model;
struct vispsprite_model2_s {
de::ModelDrawable const *drawable;
de::ModelDrawable::Animator const *animator;
float modelTransform[16];
de::gl::Cull cullFace;
} model2;
} data;
};

Expand Down
10 changes: 10 additions & 0 deletions doomsday/apps/client/src/clientapp.cpp
Expand Up @@ -255,6 +255,16 @@ DENG2_PIMPL(ClientApp)
DownloadDialog::showCompletedDownload();
break;

case DD_NOTIFY_PSPRITE_STATE_CHANGED:
if(data)
{
auto const *args = (ddnotify_psprite_state_changed_t *) data;
self.players().at(args->player)
.as<ClientPlayer>()
.weaponStateChanged(args->state);
}
break;

case DD_NOTIFY_PLAYER_WEAPON_CHANGED:
if(data)
{
Expand Down
20 changes: 13 additions & 7 deletions doomsday/apps/client/src/clientplayer.cpp
Expand Up @@ -30,6 +30,7 @@ DENG2_PIMPL(ClientPlayer)
clplayerstate_t clPlayerState;
DemoTimer demoTimer;

state_t const *lastPSpriteState = nullptr;
String weaponAssetId;

Instance(Public *i)
Expand All @@ -40,12 +41,6 @@ DENG2_PIMPL(ClientPlayer)
zap(clPlayerState);
zap(demoTimer);
}

void prepareAssets()
{
// Is there a model for the weapon?
qDebug() << "-=- looking for" << "model.weapon." + weaponAssetId;
}
};

ClientPlayer::ClientPlayer()
Expand Down Expand Up @@ -106,7 +101,18 @@ void ClientPlayer::setWeaponAssetId(String const &id)
{
if(id != d->weaponAssetId)
{
LOG_WIP("weapon asset: %s") << id;
d->weaponAssetId = id;
d->prepareAssets();
d->playerWeaponAnimator.setAsset("model.weapon." + id);
d->playerWeaponAnimator.stateChanged(d->lastPSpriteState);
}
}

void ClientPlayer::weaponStateChanged(state_t const *state)
{
if(state != d->lastPSpriteState)
{
d->lastPSpriteState = state;
d->playerWeaponAnimator.stateChanged(state);
}
}
2 changes: 1 addition & 1 deletion doomsday/apps/client/src/def_main.cpp
Expand Up @@ -1636,7 +1636,7 @@ bool Def_SameStateSequence(state_t *snew, state_t *sold)
return false;
}

String Def_GetStateName(state_t *state)
String Def_GetStateName(state_t const *state)
{
if(!state) return "(nullptr)";
dint const idx = ::runtimeDefs.states.indexOf(state);
Expand Down
5 changes: 4 additions & 1 deletion doomsday/apps/client/src/render/mobjanimator.cpp
Expand Up @@ -39,6 +39,8 @@ void MobjAnimator::triggerByState(String const &stateName)
auto found = _stateAnims->constFind(stateName);
if(found == _stateAnims->constEnd()) return;

LOG_WIP("triggerByState: ") << stateName;

foreach(ModelRenderer::AnimSequence const &seq, found.value())
{
// Test for the probability of this animation.
Expand All @@ -58,7 +60,8 @@ void MobjAnimator::triggerByState(String const &stateName)

start(animId, node);

qDebug() << "starting" << seq.name;
LOG_WIP(" Starting anim: " _E(b)) << seq.name;
break;
}
}

Expand Down
2 changes: 1 addition & 1 deletion doomsday/apps/client/src/render/modelrenderer.cpp
Expand Up @@ -352,7 +352,7 @@ void ModelRenderer::render(vissprite_t const &spr)

Matrix4f localMat =
Matrix4f::rotate(-90 + (spr.pose.viewAligned? spr.pose.yawAngleOffset :
spr.pose.yaw),
spr.pose.yaw),
Vector3f(0, 1, 0) /* vertical axis for yaw */);

gl::Cull culling = gl::Back;
Expand Down
42 changes: 42 additions & 0 deletions doomsday/apps/client/src/render/playerweaponanimator.cpp
Expand Up @@ -19,23 +19,65 @@
#include "render/playerweaponanimator.h"
#include "render/mobjanimator.h"
#include "clientplayer.h"
#include "clientapp.h"

using namespace de;

DENG2_PIMPL_NOREF(PlayerWeaponAnimator)
{
ClientPlayer *player;
std::unique_ptr<MobjAnimator> animator;
Matrix4f transform;
gl::Cull cullFace;

Instance(ClientPlayer *plr)
: player(plr)
{}

void setupAsset(String const &identifier)
{
// Is there a model for the weapon?
if(modelBank().has(identifier))
{
// Prepare the animation state of the model.
ModelBank::ModelWithData loaded = modelBank().modelAndData(identifier);
ModelDrawable &model = *loaded.first;
animator.reset(new MobjAnimator(identifier, model));

// The basic transformation of the model.
auto const &aux = loaded.second->as<ModelRenderer::AuxiliaryData>();
cullFace = aux.cull;
transform = aux.transformation;
}
else
{
animator.reset();
}
}

static ModelBank &modelBank()
{
return ClientApp::renderSystem().modelRenderer().bank();
}
};

PlayerWeaponAnimator::PlayerWeaponAnimator(ClientPlayer *plr)
: d(new Instance(plr))
{}

void PlayerWeaponAnimator::setAsset(String const &identifier)
{
d->setupAsset(identifier);
}

void PlayerWeaponAnimator::stateChanged(state_t const *state)
{
if(d->animator)
{
d->animator->triggerByState(Def_GetStateName(state));
}
}

MobjAnimator &PlayerWeaponAnimator::animator()
{
DENG2_ASSERT(bool(d->animator));
Expand Down

0 comments on commit 953b5b0

Please sign in to comment.