// ********************************************************************************************************* void CDisplayerVisualEntity::updateWorldMapPresence() { //H_AUTO(R2_CDisplayerVisualEntity_updateWorldMapPresence) if (!getActive()) return; // if not in current map then remove // if entity not in that map then ignore bool inIsland = false; CIslandCollision &col = getEditor().getIslandCollision(); R2::CScenarioEntryPoints::CCompleteIsland *currIsland = col.getCurrIslandDesc(); if (currIsland) { inIsland = currIsland->isIn(getWorldPos2f()); } // in map (displayed only if selectable for now) if (getDisplayedInstance()->getSelectable() && inIsland) { if (!_MapDeco.isAddedToMap()) { CGroupMap *gm = CTool::getWorldMap(); if (gm) { _MapDeco.setDisplayedInstance(getDisplayedInstance(), true); // retrieve icon from the displayed object (lua code) CLuaState &ls = getEditor().getLua(); std::string texName = ""; { CLuaStackChecker lsc(&ls); if (getDisplayedInstance()->getLuaProjection().callMethodByNameNoThrow("getSelectBarIcon", 0, 1)) { texName = ls.toString(-1); ls.pop(); } } gm->addDeco(&_MapDeco); _MapDeco.setCloseTexture(texName); _MapDeco.invalidateCoords(); } } } else { if (_MapDeco.isAddedToMap()) { CGroupMap *gm = CTool::getWorldMap(); if (gm) { gm->removeDeco(&_MapDeco); } } } }
// ********************************************************************************************************* void CDisplayerVisualShape::onPreRender() { //H_AUTO(R2_CDisplayerVisualShape_onPreRender) if (SkipFrame != 0) { // a tp was done -> invalidate visual collision entity deleteVisualCollisionEntity(); } if (!_Instance.empty()) { bool inIsland = false; CIslandCollision &col = getEditor().getIslandCollision(); R2::CScenarioEntryPoints::CCompleteIsland *currIsland = col.getCurrIslandDesc(); if (currIsland) { inIsland = currIsland->isIn(getWorldPos2f()); } if (getActualVisibility() && inIsland) { _Instance.show(); if (_WorldMapDisplay && !_MapDeco.getActive()) { _MapDeco.setActive(true); _Touched = true; } } else { _Instance.hide(); _MapDeco.setActive(false); } } if (!getActualVisibility()) return; if (_BadShapeName) return; if (_Active) { if (testNeedZEval()) _VisualSnapToGroundDone = false; if (!_VisualSnapToGroundDone && SkipFrame == 0) { snapToGround(); // force visual snap to ground if not already done + icon update } } if (!_Touched) { if (!_Instance.empty()) _BBoxMatrix = _Instance.getMatrix(); else _BBoxMatrix = CMatrix::Identity; return; } if (_Active) { updateMapDeco(); if (_Instance.empty()) { sint64 startTime = 0; static volatile bool bench = false; if (bench) { startTime = CTime::getPerformanceTime(); } _Instance = Scene->createInstance(_ShapeName); if (bench) { sint64 endTime = CTime::getPerformanceTime(); nlwarning("clip time = %.2f ms", 1000.f * CTime::ticksToSecond(endTime - startTime)); } if (_Instance.empty()) { _BadShapeName = true; return; } _Instance.setTransformMode(NL3D::UTransform::DirectMatrix); _Instance.enableCastShadowMap(true); } CMatrix instanceMat; instanceMat.setScale(_Scale); instanceMat.setPos(getWorldPos().asVector()); _Instance.setMatrix(instanceMat); _VisualSnapToGroundDone = false; visualSnapToGround(); // force visual snap to ground if not already done } else { if (!_Instance.empty()) { Scene->deleteInstance(_Instance); } } if (!_Instance.empty()) { _BBoxMatrix = _Instance.getMatrix(); // ensure that bbox and shape displayed at same pos // (events that modify the instance pos may be received after the display of this frame) } _MapDeco.setInvalidPosFlag(getDisplayFlag(FlagBadPos)); _Touched = false; }
//********************************************************************************************************* void CInstanceMapDeco::onUpdate(CGroupMap &groupMap) { //H_AUTO(R2_CInstanceMapDeco_onUpdate) if (!_Active) return; nlassert(_Instance); _GlowStarActive = false; if (!_Main || !_Over || !_OverInvalid) return; sint32 x; sint32 y; CVector2f worldPos = getWorldPos(); // if not in current map then don't disply anything CIslandCollision &col = getEditor().getIslandCollision(); R2::CScenarioEntryPoints::CCompleteIsland *currIsland = col.getCurrIslandDesc(); if (currIsland) { if (!currIsland->isIn(worldPos)) { setActive(false); return; } } groupMap.worldToWindowSnapped(x, y, getWorldPos()); _Main->setX(x); _Main->setY(y); CDisplayerVisual *vd = _Instance->getDisplayerVisual(); if (!vd) { _Over->setActive(false); _OverInvalid->setActive(false); return; } // bool closeView = _CloseTexture.empty() ? false : groupMap.getMeterPerPixel() < CV_MapEntityCloseDist.get(); // bool selected = vd->getDisplayFlag(CDisplayerVisual::FlagSelected); bool hasFocus = vd->getDisplayFlag(CDisplayerVisual::FlagHasFocus); // setTextureAndFit(closeView ? _CloseTexture : CV_MapEntitySmallTexture.get()); _Main->setColor((selected && ! closeView) ? CV_MapEntitySelectColor.get() : vd->getDisplayModeColorInMap()); // if small icon, then change the icon color directly, because no over will be displayed // if (selected || hasFocus) { // if the selection is out of the window, then draw an arrow to locate it const CVector2f &wmin = groupMap.getVisibleWorldMin(); const CVector2f &wmax = groupMap.getVisibleWorldMax(); if (worldPos.x < wmin.x || worldPos.x > wmax.x || worldPos.y < wmin.y || worldPos.y > wmax.y) { // OUT OF VISIBLE REGION CASE _Over->setActive(true); _Over->setColorRGBA(selected ? CV_MapEntitySelectColor.get() : CV_MapEntityHighlightColor.get()); // out of the visible portion, so draw an arrow instead _Over->setTexture(CV_MapEntityFarTexture.get()); // snap position to inner visible world rect CVector2f m = 0.5f * (wmin + wmax); CVector2f dir = worldPos - m; CVector2f inter; float d0; float d1; if (dir.x > 0.f) { d0 = (wmax.x - m.x) / dir.x; if (dir.y > 0.f) { d1 = (wmax.y - m.y) / dir.y; inter = m + std::min(d0, d1) * dir; } else if (dir.y < 0.f) { d1 = (wmin.y - m.y) / dir.y; inter = m + std::min(d0, d1) * dir; } else { inter.set(wmax.x, m.y); } } else if (dir.x < 0.f) { d0 = (wmin.x - m.x) / dir.x; if (dir.y > 0.f) { d1 = (wmax.y - m.y) / dir.y; inter = m + std::min(d0, d1) * dir; } else if (dir.y < 0.f) { d1 = (wmin.y - m.y) / dir.y; inter = m + std::min(d0, d1) * dir; } else { inter.set(wmin.x, m.y); } } else { if (dir.y > 0.f) { inter.set(m.x, wmax.y); } else if (dir.y < 0.f) { inter.set(m.x, wmin.y); } else { inter = m; } } float size = CV_MapEntityFarArrowSize.get(); // TMP TMP size = size; float bias = 1.f; dir.normalize(); CVector2f winInter; groupMap.worldToWindow(winInter, inter); _Over->setRenderLayer(3); _Over->setQuad(winInter - (size + bias) * dir, winInter - bias * dir, 0.5f * size); // if (_GlowStar[0]) { sint32 screenInterX, screenInterY; groupMap.windowToScreen(screenInterX, screenInterY, (sint32) winInter.x, (sint32) winInter.y); sint32 refCornerX, refCornerY; _GlowStar[0]->getParent()->getCorner(refCornerX, refCornerY, Hotspot_BL); _GlowStarPos.set((float) (screenInterX - refCornerX), (float) (screenInterY - refCornerY), 0.f); _GlowStarActive = true; } } else { // VISIBLE CASE _GlowStar[0]->setActive(false); _GlowStar[1]->setActive(false); if (closeView || hasFocus) { _Over->setActive(true); if (!closeView) { _Over->setColorRGBA(CV_MapEntitySelectColor.get()); } else { _Over->setColorRGBA(selected ? CV_MapEntitySelectColor.get() : CV_MapEntityHighlightColor.get()); } const std::string &tex = closeView ? CV_MapEntitySelectTexture.get() : CV_MapEntitySmallHighlightTexture.get(); _Over->setTexture(tex); _Over->setRenderLayer(2); _Over->setQuad(tex, CVector((float) x, (float) y, 0.f)); } else { _Over->setActive(false); } } } else { // no focus _Over->setActive(false); _GlowStar[0]->setActive(false); _GlowStar[1]->setActive(false); } // update 'quad that signal invalid pos' if (_OverInvalid->getActive()) { const std::string &tex = closeView ? CV_MapEntityInvalidTexture.get() : CV_MapEntityInvalidTextureSmall.get(); _OverInvalid->setTexture(tex); _OverInvalid->setQuad(tex, CVector((float) x, (float) y, 0.f)); } }