Skip to content

Commit

Permalink
Definitions: Interpret legacy Group defs into material anims
Browse files Browse the repository at this point in the history
Support the now deprecated Group-based method of defining entirely
new material animations if a material is otherwise not animated.
  • Loading branch information
danij-deng committed Mar 6, 2013
1 parent 1da4f61 commit 0cd0004
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 8 deletions.
23 changes: 20 additions & 3 deletions doomsday/client/include/resource/material.h
Expand Up @@ -120,15 +120,24 @@ class Material : public de::MapElement
float glowStrengthVariance;
de::Vector2f texOrigin;

Stage(de::Texture *_texture, int _tics, float _variance,
float _glowStrength, float _glowStrengthVariance,
de::Vector2f const _texOrigin)
Stage(de::Texture *_texture, int _tics, float _variance = 0,
float _glowStrength = 0, float _glowStrengthVariance = 0,
de::Vector2f const _texOrigin = de::Vector2f())
: texture(_texture), tics(_tics), variance(_variance),
glowStrength(_glowStrength),
glowStrengthVariance(_glowStrengthVariance),
texOrigin(_texOrigin)
{}

Stage(Stage const &other)
: texture(other.texture),
tics(other.tics),
variance(other.variance),
glowStrength(other.glowStrength),
glowStrengthVariance(other.glowStrengthVariance),
texOrigin(other.texOrigin)
{}

static Stage *fromDef(ded_material_layer_stage_t const &def);
};

Expand All @@ -155,6 +164,14 @@ class Material : public de::MapElement
*/
int stageCount() const;

/**
* Add a new animation stage to the layer.
*
* @param stage New stage to add (a copy is made).
* @return Index of the newly added stage (0-based).
*/
int addStage(Stage const &stage);

/**
* Provides access to the animation stages for efficient traversal.
*/
Expand Down
95 changes: 90 additions & 5 deletions doomsday/client/src/def_main.cpp
Expand Up @@ -1052,26 +1052,112 @@ static void generateMaterialDefs()
generateMaterialDefsForAllTexturesInScheme("Sprites");
}

static ded_group_t *findGroupDefByFrameTextureUri(de::Uri const &uri)
{
if(uri.isEmpty()) return 0;

// Reverse iteration (later defs override earlier ones).
for(int i = defs.count.groups.num; i--> 0; )
{
ded_group_t &grp = defs.groups[i];

// We aren't interested in precache groups.
if(grp.flags & AGF_PRECACHE) continue;

// Or empty/single-frame groups.
if(grp.count.num < 2) continue;

for(int k = grp.count.num; k--> 0; )
{
ded_group_member_t &gm = grp.members[k];

if(!gm.material) continue;

if(reinterpret_cast<de::Uri const &>(*gm.material) == uri)
{
// Found one.
return &grp;
}
}
}

return 0; // Not found.
}

static void rebuildMaterialLayers(Material &material, ded_material_t const &def)
{
material.clearLayers();

for(int i = 0; i < DED_MAX_MATERIAL_LAYERS; ++i)
{
Material::Layer *layer = material.newLayer(&def.layers[i]);
material.newLayer(&def.layers[i]);
}

if(material.layerCount() && material.layers()[0]->stageCount())
{
Material::Layer *layer0 = material.layers()[0];
Material::Layer::Stage *stage0 = layer0->stages()[0];

foreach(Material::Layer::Stage *stageDef, layer->stages())
if(stage0->texture)
{
if(!stageDef->texture) continue;
de::Uri textureUri(stage0->texture->manifest().composeUri());

// We may need to interpret the layer animation from the now
// deprecated Group definitions.

if(def.autoGenerated && layer0->stageCount() == 1)
{
// Possibly; see if there is a compatible definition with
// a member named similarly to the texture for layer #0.

if(ded_group_t const *grp = findGroupDefByFrameTextureUri(textureUri))
{
// Determine the start frame.
int startFrame = 0;
while(!grp->members[startFrame].material ||
reinterpret_cast<de::Uri const &>(*grp->members[startFrame].material) != textureUri)
{
startFrame++;
}

// Configure the first stage.
ded_group_member_t const &gm0 = grp->members[startFrame];
stage0->tics = gm0.tics;
stage0->variance = gm0.randomTics / float( gm0.tics );

// Add further stages for each frame in the group.
startFrame++;
for(int i = 0; i < grp->count.num - 1; ++i)
{
int frame = startFrame + i;
// Wrap around?
if(frame >= grp->count.num) frame -= grp->count.num;
ded_group_member_t const &gm = grp->members[frame];

if(!gm.material) continue;

try
{
Texture &texture = App_Textures().find(reinterpret_cast<de::Uri const &>(*gm.material)).texture();
layer0->addStage(Material::Layer::Stage(&texture, gm.tics, gm.randomTics / float( gm.tics )));
}
catch(TextureManifest::MissingTextureError const &)
{} // Ignore this error.
catch(Textures::NotFoundError const &)
{} // Ignore this error.
}
}
}

de::Uri textureUri(stageDef->texture->manifest().composeUri());
// Is there a Detail definition we need to produce a layer for?
ded_detailtexture_t *detailDef = Def_GetDetailTex(reinterpret_cast<uri_s *>(&textureUri)/*, UNKNOWN VALUE, manifest.isCustom()*/);
if(detailDef)
{
material.newDetailLayer(detailDef);
// Add stages.
}

// Is there a Reflection definition we need to produce a layer for?
ded_reflection_t *shineDef = Def_GetReflection(reinterpret_cast<uri_s *>(&textureUri)/*, UNKNOWN VALUE, manifest.isCustom()*/);
if(shineDef)
{
Expand Down Expand Up @@ -1623,7 +1709,6 @@ void Def_Read()

static void initMaterialGroup(ded_group_t &def)
{
//int animNumber = -1;
Materials::ManifestGroup *group = 0;
for(int i = 0; i < def.count.num; ++i)
{
Expand Down
6 changes: 6 additions & 0 deletions doomsday/client/src/resource/material.cpp
Expand Up @@ -77,6 +77,12 @@ int Material::Layer::stageCount() const
return stages_.count();
}

int Material::Layer::addStage(Material::Layer::Stage const &stageToCopy)
{
stages_.push_back(new Stage(stageToCopy));
return stages_.count() - 1;
}

Material::Layer::Stages const &Material::Layer::stages() const
{
return stages_;
Expand Down

0 comments on commit 0cd0004

Please sign in to comment.