Skip to content

Commit

Permalink
Fixed|Renderer|Resources: Illegal access of submodel particle offsets
Browse files Browse the repository at this point in the history
The particle offsets are currently kept in a separate array where the
indices match those of the submodels array. Fixed an out-of-bounds
access of the particle offsets when spawning particles.
  • Loading branch information
skyjake committed Jul 9, 2013
1 parent 1d47022 commit 050a426
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 22 deletions.
22 changes: 19 additions & 3 deletions doomsday/client/include/resource/models.h
Expand Up @@ -144,7 +144,7 @@ struct ModelDef
float scale[3];

typedef std::vector<de::Vector3f> PtcOffsets;
PtcOffsets ptcOffset;
PtcOffsets _ptcOffset;

float visualRadius;

Expand Down Expand Up @@ -184,14 +184,14 @@ struct ModelDef
SubmodelDef *addSub()
{
_sub.push_back(SubmodelDef());
ptcOffset.push_back(de::Vector3f());
_ptcOffset.push_back(de::Vector3f());
return &_sub.back();
}

void clearSubs()
{
_sub.clear();
ptcOffset.clear();
_ptcOffset.clear();
}

uint subCount() const
Expand Down Expand Up @@ -227,6 +227,22 @@ struct ModelDef
{
return subnum < _sub.size();
}

de::Vector3f particleOffset(unsigned int subnum) const
{
if(hasSub(subnum))
{
DENG_ASSERT(subnum < _ptcOffset.size());
return _ptcOffset[subnum];
}
return de::Vector3f();
}

void setParticleOffset(unsigned int subnum, de::Vector3f const &off)
{
DENG_ASSERT(hasSub(subnum));
_ptcOffset[subnum] = off;
}
};

typedef ModelDef modeldef_t;
Expand Down
9 changes: 5 additions & 4 deletions doomsday/client/src/render/rend_particle.cpp
Expand Up @@ -630,10 +630,11 @@ static void renderParticles(int rtype, boolean withBlend)
{
// We may need to change the blending mode.
newMode =
(gen->flags & PGF_SUB_BLEND ? BM_SUBTRACT : gen->
flags & PGF_REVSUB_BLEND ? BM_REVERSE_SUBTRACT : gen->
flags & PGF_MUL_BLEND ? BM_MUL : gen->
flags & PGF_INVMUL_BLEND ? BM_INVERSE_MUL : BM_NORMAL);
(gen->flags & PGF_SUB_BLEND ? BM_SUBTRACT :
gen->flags & PGF_REVSUB_BLEND ? BM_REVERSE_SUBTRACT :
gen->flags & PGF_MUL_BLEND ? BM_MUL :
gen->flags & PGF_INVMUL_BLEND ? BM_INVERSE_MUL :
BM_NORMAL);
if(newMode != mode)
{
glEnd();
Expand Down
9 changes: 3 additions & 6 deletions doomsday/client/src/resource/models.cpp
Expand Up @@ -1251,21 +1251,18 @@ static void setupModel(ded_model_t& def)
for(uint i = 0; i < modef->subCount(); ++i)
{
SubmodelDef *sub = &modef->subModelDef(i);
de::Vector3f off;
if(sub->modelId)
{
Models_ToModel(sub->modelId)->frame(sub->frame).getBounds(min, max);

// Apply the various scalings and offsets.
for(int k = 0; k < 3; ++k)
{
modef->ptcOffset[i][k] =
((max[k] + min[k]) / 2 + sub->offset[k]) * modef->scale[k] + modef->offset[k];
off[k] = ((max[k] + min[k]) / 2 + sub->offset[k]) * modef->scale[k] + modef->offset[k];
}
}
else
{
modef->ptcOffset[i] = de::Vector3f();
}
modef->setParticleOffset(i, off);
}

// Calculate visual radius for shadows.
Expand Down
18 changes: 9 additions & 9 deletions doomsday/client/src/world/p_particle.cpp
Expand Up @@ -591,24 +591,24 @@ static void P_NewParticle(ptcgen_t *gen)
// Interpolate the offset.
if(inter > 0 && nextmf)
{
off[VX] = nextmf->ptcOffset[subidx][VX] - mf->ptcOffset[subidx][VX];
off[VY] = nextmf->ptcOffset[subidx][VY] - mf->ptcOffset[subidx][VY];
off[VZ] = nextmf->ptcOffset[subidx][VZ] - mf->ptcOffset[subidx][VZ];
off[VX] = nextmf->particleOffset(subidx)[VX] - mf->particleOffset(subidx)[VX];
off[VY] = nextmf->particleOffset(subidx)[VY] - mf->particleOffset(subidx)[VY];
off[VZ] = nextmf->particleOffset(subidx)[VZ] - mf->particleOffset(subidx)[VZ];

off[VX] *= inter;
off[VY] *= inter;
off[VZ] *= inter;
}

off[VX] += mf->ptcOffset[subidx][VX];
off[VY] += mf->ptcOffset[subidx][VY];
off[VZ] += mf->ptcOffset[subidx][VZ];
off[VX] += mf->particleOffset(subidx)[VX];
off[VY] += mf->particleOffset(subidx)[VY];
off[VZ] += mf->particleOffset(subidx)[VZ];

// Apply it to the particle coords.
pt->origin[VX] += FixedMul(fineCosine[ang], FLT2FIX(off[VX]));
pt->origin[VX] += FixedMul(fineCosine[ang], FLT2FIX(off[VX]));
pt->origin[VX] += FixedMul(fineCosine[ang2], FLT2FIX(off[VZ]));
pt->origin[VY] += FixedMul(finesine[ang], FLT2FIX(off[VX]));
pt->origin[VY] += FixedMul(finesine[ang2], FLT2FIX(off[VZ]));
pt->origin[VY] += FixedMul(finesine[ang], FLT2FIX(off[VX]));
pt->origin[VY] += FixedMul(finesine[ang2], FLT2FIX(off[VZ]));
pt->origin[VZ] += FLT2FIX(off[VY]);
}
}
Expand Down

0 comments on commit 050a426

Please sign in to comment.