// *********************************************************************************************************
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;
}
Esempio n. 3
0
//*********************************************************************************************************
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));
	}
}