WallSpec WallSpec::fromMapSide(LineSide const &side, int section) // static { bool const isTwoSidedMiddle = (section == LineSide::Middle && !side.considerOneSided()); WallSpec spec(section); if(side.line().definesPolyobj() || isTwoSidedMiddle) { spec.flags &= ~WallSpec::ForceOpaque; spec.flags |= WallSpec::NoEdgeDivisions; } if(isTwoSidedMiddle) { if(viewPlayer && ((viewPlayer->shared.flags & (DDPF_NOCLIP|DDPF_CAMERA)) || !side.line().isFlagged(DDLF_BLOCKING))) spec.flags |= WallSpec::NearFade; spec.flags |= WallSpec::SortDynLights; } // Suppress the sky clipping in debug mode. if(devRendSkyMode) spec.flags &= ~WallSpec::SkyClip; if(side.line().definesPolyobj()) spec.flags |= WallSpec::NoFakeRadio; bool useLightLevelDeltas = useWallSectionLightLevelDeltas(side, section); if(!useLightLevelDeltas) spec.flags |= WallSpec::NoLightDeltas; // We can skip normal smoothing if light level delta smoothing won't be done. if(!useLightLevelDeltas || !rendLightWallAngleSmooth) spec.flags |= WallSpec::NoEdgeNormalSmoothing; return spec; }
/// @todo fixme: Should use the visual plane heights of sector clusters. bool R_SideBackClosed(LineSide const &side, bool ignoreOpacity) { if(!side.hasSections()) return false; if(!side.hasSector()) return false; if(side.line().isSelfReferencing()) return false; // Never. if(side.considerOneSided()) return true; Sector const &frontSec = side.sector(); Sector const &backSec = side.back().sector(); if(backSec.floor().heightSmoothed() >= backSec.ceiling().heightSmoothed()) return true; if(backSec.ceiling().heightSmoothed() <= frontSec.floor().heightSmoothed()) return true; if(backSec.floor().heightSmoothed() >= frontSec.ceiling().heightSmoothed()) return true; // Perhaps a middle material completely covers the opening? if(side.middle().hasMaterial()) { MaterialAnimator &matAnimator = side.middle().material().getAnimator(Rend_MapSurfaceMaterialSpec()); // Ensure we have up to date info about the material. matAnimator.prepare(); if(ignoreOpacity || (matAnimator.isOpaque() && !side.middle().blendMode() && side.middle().opacity() >= 1)) { // Stretched middles always cover the opening. if(side.isFlagged(SDF_MIDDLE_STRETCH)) return true; if(side.leftHEdge()) // possibility of degenerate BSP leaf { coord_t openRange, openBottom, openTop; openRange = visOpenRange(side, &openBottom, &openTop); if(matAnimator.dimensions().y >= openRange) { // Possibly; check the placement. WallEdge edge(WallSpec::fromMapSide(side, LineSide::Middle), *side.leftHEdge(), Line::From); return (edge.isValid() && edge.top().z() > edge.bottom().z() && edge.top().z() >= openTop && edge.bottom().z() <= openBottom); } } } } return false; }
void Cl_ReadSideDelta(dint /*deltaType*/) { /// @todo Do not assume the CURRENT map. world::Map &map = App_World().map(); dint const index = Reader_ReadUInt16(msgReader); dint const df = Reader_ReadPackedUInt32(msgReader); // Flags. LineSide *side = map.sidePtr(index); DENG2_ASSERT(side != 0); if (df & SIDF_TOP_MATERIAL) { dint matIndex = Reader_ReadPackedUInt16(msgReader); side->top().setMaterial(Cl_LocalMaterial(matIndex)); } if (df & SIDF_MID_MATERIAL) { dint matIndex = Reader_ReadPackedUInt16(msgReader); side->middle().setMaterial(Cl_LocalMaterial(matIndex)); } if (df & SIDF_BOTTOM_MATERIAL) { dint matIndex = Reader_ReadPackedUInt16(msgReader); side->bottom().setMaterial(Cl_LocalMaterial(matIndex)); } if (df & SIDF_LINE_FLAGS) { // The delta includes the entire lowest byte. dint lineFlags = Reader_ReadByte(msgReader); Line &line = side->line(); line.setFlags((line.flags() & ~0xff) | lineFlags, de::ReplaceFlags); } if (df & (SIDF_TOP_COLOR_RED | SIDF_TOP_COLOR_GREEN | SIDF_TOP_COLOR_BLUE)) { Vector3f newColor = side->top().color(); if (df & SIDF_TOP_COLOR_RED) newColor.x = Reader_ReadByte(msgReader) / 255.f; if (df & SIDF_TOP_COLOR_GREEN) newColor.y = Reader_ReadByte(msgReader) / 255.f; if (df & SIDF_TOP_COLOR_BLUE) newColor.z = Reader_ReadByte(msgReader) / 255.f; side->top().setColor(newColor); } if (df & (SIDF_MID_COLOR_RED | SIDF_MID_COLOR_GREEN | SIDF_MID_COLOR_BLUE)) { Vector3f newColor = side->middle().color(); if (df & SIDF_MID_COLOR_RED) newColor.x = Reader_ReadByte(msgReader) / 255.f; if (df & SIDF_MID_COLOR_GREEN) newColor.y = Reader_ReadByte(msgReader) / 255.f; if (df & SIDF_MID_COLOR_BLUE) newColor.z = Reader_ReadByte(msgReader) / 255.f; side->middle().setColor(newColor); } if (df & SIDF_MID_COLOR_ALPHA) { side->middle().setOpacity(Reader_ReadByte(msgReader) / 255.f); } if (df & (SIDF_BOTTOM_COLOR_RED | SIDF_BOTTOM_COLOR_GREEN | SIDF_BOTTOM_COLOR_BLUE)) { Vector3f newColor = side->bottom().color(); if (df & SIDF_BOTTOM_COLOR_RED) newColor.x = Reader_ReadByte(msgReader) / 255.f; if (df & SIDF_BOTTOM_COLOR_GREEN) newColor.y = Reader_ReadByte(msgReader) / 255.f; if (df & SIDF_BOTTOM_COLOR_BLUE) newColor.z = Reader_ReadByte(msgReader) / 255.f; side->bottom().setColor(newColor); } if (df & SIDF_MID_BLENDMODE) { side->middle().setBlendMode(blendmode_t(Reader_ReadInt32(msgReader))); } if (df & SIDF_FLAGS) { // The delta includes the entire lowest byte. dint sideFlags = Reader_ReadByte(msgReader); side->setFlags((side->flags() & ~0xff) | sideFlags, de::ReplaceFlags); } }