diff --git a/doomsday/engine/portable/include/p_maptypes.h b/doomsday/engine/portable/include/p_maptypes.h index 9a03564596..397eff71d0 100644 --- a/doomsday/engine/portable/include/p_maptypes.h +++ b/doomsday/engine/portable/include/p_maptypes.h @@ -141,6 +141,7 @@ typedef enum { typedef struct surfacedecor_s { float pos[3]; // World coordinates of the decoration. + subsector_t *subsector; decortype_t type; union surfacedecor_data_u { struct surfacedecor_light_s { diff --git a/doomsday/engine/portable/include/r_world.h b/doomsday/engine/portable/include/r_world.h index 6e0c82dc12..b9b9cc91f3 100644 --- a/doomsday/engine/portable/include/r_world.h +++ b/doomsday/engine/portable/include/r_world.h @@ -74,8 +74,7 @@ void R_OrderVertices(const linedef_t *line, const sector_t *sector, plane_t *R_NewPlaneForSector(sector_t *sec); void R_DestroyPlaneOfSector(uint id, sector_t *sec); -surfacedecor_t *R_CreateSurfaceDecoration(decortype_t type, surface_t *suf, - const float *pos); +surfacedecor_t *R_CreateSurfaceDecoration(decortype_t type, surface_t *suf); void R_ClearSurfaceDecorations(surface_t *suf); void R_UpdateWatchedPlanes(watchedplanelist_t *wpl); diff --git a/doomsday/engine/portable/src/r_world.c b/doomsday/engine/portable/src/r_world.c index feb2ca7b25..c72f8efda3 100644 --- a/doomsday/engine/portable/src/r_world.c +++ b/doomsday/engine/portable/src/r_world.c @@ -549,8 +549,7 @@ void R_DestroyPlaneOfSector(uint id, sector_t *sec) sec->planes = newList; } -surfacedecor_t* R_CreateSurfaceDecoration(decortype_t type, surface_t *suf, - const float *pos) +surfacedecor_t* R_CreateSurfaceDecoration(decortype_t type, surface_t *suf) { uint i; surfacedecor_t *d, *s, *decorations; @@ -578,9 +577,6 @@ surfacedecor_t* R_CreateSurfaceDecoration(decortype_t type, surface_t *suf, // Add the new decoration. d = &decorations[suf->numDecorations - 1]; d->type = type; - d->pos[VX] = pos[VX]; - d->pos[VY] = pos[VY]; - d->pos[VZ] = pos[VZ]; suf->decorations = decorations; @@ -1700,6 +1696,17 @@ void R_BuildSectorLinks(gamemap_t *map) #undef DOMINANT_SIZE } +static __inline void initSurfaceMaterialOffset(surface_t *suf) +{ + if(!suf) + return; + + suf->visOffset[VX] = suf->oldOffset[0][VX] = + suf->oldOffset[1][VX] = suf->offset[VX]; + suf->visOffset[VY] = suf->oldOffset[0][VY] = + suf->oldOffset[1][VY] = suf->offset[VY]; +} + /** * Called by the game at various points in the level setup process. */ @@ -1730,21 +1737,34 @@ void R_SetupLevel(int mode, int flags) R_SkyFix(true, true); // fix floors and ceilings. - // Update all sectors. Set intial values of various tracked - // and interpolated properties (lighting, smoothed planes etc). + // Set intial values of various tracked and interpolated properties + // (lighting, smoothed planes etc). for(i = 0; i < numSectors; ++i) { - uint j; - sector_t *sec = SECTOR_PTR(i); + uint j; + sector_t *sec = SECTOR_PTR(i); R_UpdateSector(sec, false); for(j = 0; j < sec->planeCount; ++j) { - sec->planes[j]->visHeight = sec->planes[j]->oldHeight[0] = - sec->planes[j]->oldHeight[1] = sec->planes[j]->height; + plane_t *pln = sec->SP_plane(j); + + pln->visHeight = pln->oldHeight[0] = pln->oldHeight[1] = + pln->height; + + initSurfaceMaterialOffset(&pln->surface); } } + for(i = 0; i < numSideDefs; ++i) + { + sidedef_t *si = SIDE_PTR(i); + + initSurfaceMaterialOffset(&si->SW_topsurface); + initSurfaceMaterialOffset(&si->SW_middlesurface); + initSurfaceMaterialOffset(&si->SW_bottomsurface); + } + // We don't render fakeradio on polyobjects... PO_InitForMap(); return; @@ -1766,17 +1786,30 @@ void R_SetupLevel(int mode, int flags) // and interpolated properties (lighting, smoothed planes etc). for(i = 0; i < numSectors; ++i) { - uint l; - sector_t *sec = SECTOR_PTR(i); + uint l; + sector_t *sec = SECTOR_PTR(i); R_UpdateSector(sec, true); for(l = 0; l < sec->planeCount; ++l) { - sec->planes[l]->visHeight = sec->planes[l]->oldHeight[0] = - sec->planes[l]->oldHeight[1] = sec->planes[l]->height; + plane_t *pln = sec->SP_plane(l); + + pln->visHeight = pln->oldHeight[0] = pln->oldHeight[1] = + pln->height; + + initSurfaceMaterialOffset(&pln->surface); } } + for(i = 0; i < numSideDefs; ++i) + { + sidedef_t *si = SIDE_PTR(i); + + initSurfaceMaterialOffset(&si->SW_topsurface); + initSurfaceMaterialOffset(&si->SW_middlesurface); + initSurfaceMaterialOffset(&si->SW_bottomsurface); + } + // We don't render fakeradio on polyobjects... PO_InitForMap(); diff --git a/doomsday/engine/portable/src/rend_decor.c b/doomsday/engine/portable/src/rend_decor.c index df4b047439..a9ec685905 100644 --- a/doomsday/engine/portable/src/rend_decor.c +++ b/doomsday/engine/portable/src/rend_decor.c @@ -371,7 +371,7 @@ static void createSurfaceDecoration(const surface_t *suf, source->pos[VY] = dec->pos[VY]; source->pos[VZ] = dec->pos[VZ]; source->maxDist = maxDist; - source->subsector = R_PointInSubsector(dec->pos[VX], dec->pos[VY]); + source->subsector = dec->subsector; source->surface = suf; source->type = dec->type; switch(source->type) @@ -543,7 +543,7 @@ static void decorateLineSection(const linedef_t *line, sidedef_t *side, getDecorationSkipPattern(modelDef->patternSkip, skip); posBase[VX] = v[0]->V_pos[VX] + modelDef->elevation * suf->normal[VX]; - posBase[VY] = v[0]->V_pos[VY] + modelDef->elevation * suf->normal[VZ]; + posBase[VY] = v[0]->V_pos[VY] + modelDef->elevation * suf->normal[VY]; patternW = surfTexW * skip[VX]; patternH = surfTexH * skip[VY]; @@ -567,8 +567,13 @@ static void decorateLineSection(const linedef_t *line, sidedef_t *side, pos[VY] = posBase[VY] + delta[VY] * s / line->length; pos[VZ] = top - t; - if(NULL != (d = R_CreateSurfaceDecoration(DT_MODEL, suf, pos))) + if(NULL != (d = R_CreateSurfaceDecoration(DT_MODEL, suf))) { + d->pos[VX] = pos[VX]; + d->pos[VY] = pos[VY]; + d->pos[VZ] = pos[VZ]; + d->subsector = R_PointInSubsector(d->pos[VX], d->pos[VY]); + DEC_MODEL(d)->mf = mf; DEC_MODEL(d)->def = modelDef; DEC_MODEL(d)->rotation = 0; @@ -614,8 +619,13 @@ static void decorateLineSection(const linedef_t *line, sidedef_t *side, pos[VY] = posBase[VY] + delta[VY] * s / line->length; pos[VZ] = top - t; - if(NULL != (d = R_CreateSurfaceDecoration(DT_LIGHT, suf, pos))) + if(NULL != (d = R_CreateSurfaceDecoration(DT_LIGHT, suf))) { + d->pos[VX] = pos[VX]; + d->pos[VY] = pos[VY]; + d->pos[VZ] = pos[VZ]; + d->subsector = R_PointInSubsector(d->pos[VX], d->pos[VY]); + DEC_LIGHT(d)->def = lightDef; } } @@ -819,8 +829,13 @@ static void decoratePlane(const sector_t *sec, plane_t *pln, pos[VZ] = pln->visHeight + modelDef->elevation * suf->normal[VZ]; - if(NULL != (d = R_CreateSurfaceDecoration(DT_MODEL, suf, pos))) + if(NULL != (d = R_CreateSurfaceDecoration(DT_MODEL, suf))) { + d->pos[VX] = pos[VX]; + d->pos[VY] = pos[VY]; + d->pos[VZ] = pos[VZ]; + d->subsector = R_PointInSubsector(d->pos[VX], d->pos[VY]); + DEC_MODEL(d)->def = modelDef; DEC_MODEL(d)->mf = mf; DEC_MODEL(d)->rotation = 90; // Degrees. @@ -875,8 +890,13 @@ static void decoratePlane(const sector_t *sec, plane_t *pln, pos[VZ] = pln->visHeight + lightDef->elevation * suf->normal[VZ]; - if(NULL != (d = R_CreateSurfaceDecoration(DT_LIGHT, suf, pos))) + if(NULL != (d = R_CreateSurfaceDecoration(DT_LIGHT, suf))) { + d->pos[VX] = pos[VX]; + d->pos[VY] = pos[VY]; + d->pos[VZ] = pos[VZ]; + d->subsector = R_PointInSubsector(d->pos[VX], d->pos[VY]); + DEC_LIGHT(d)->def = lightDef; } }