Пример #1
0
// *********************************************************
void CPrimRender::updatePos()
{
	//H_AUTO(R2_CPrimRender_updatePos)
	// world map
	if (_AddedToWorldMap)
	{
		setWorldMapNumVertices(_Look.VertexLook.WorldMapTexture.empty() ? 0 : (uint)_Vertices.size());
		setWorldMapNumEdges(_Look.EdgeLook.WorldMapTexture.empty() ? 0 : _NumEdges);
	}
	//
	if (!_Vertices.empty())
	{
		// edges update
		switch(_Look.Shape)
		{
			case CPrimLook::Star:
			{
				CVector centerPos = _Vertices[0];
				for(uint k = 1; k < _Vertices.size(); ++k)
				{
					//
					if (!_EdgeShapeInstances.empty())
					{
						updateEdge(_EdgeShapeInstances[k - 1], centerPos, _Vertices[k]);
					}
					if (!_EdgeDecals.empty())
					{
						updateEdgeDecal(*(_EdgeDecals[k - 1]), centerPos, _Vertices[k], _Look.FirstVertexLook.DecalDistToEdgeDecal, _Look.VertexLook.DecalDistToEdgeDecal);
					}
				}
			}
			break;
			case CPrimLook::PolyLine:
			case CPrimLook::ClosedPolyLine:
			{
				for(sint k = 0; k < _NumEdges; ++k)
				{
					//
					if (!_EdgeShapeInstances.empty())
					{
						updateEdge(_EdgeShapeInstances[k], _Vertices[k], _Vertices[(k + 1) % _Vertices.size()]);
					}
					if (!_EdgeDecals.empty())
					{
						updateEdgeDecal(*(_EdgeDecals[k]), _Vertices[k], _Vertices[(k + 1) % _Vertices.size()],
									k == 0 ? _Look.VertexLook.DecalDistToEdgeDecal : _Look.FirstVertexLook.DecalDistToEdgeDecal,
									_Look.VertexLook.DecalDistToEdgeDecal
								   );
					}
				}
			}
			break;
			default:
				nlassert(0);
			break;
		}
	}
	// update vertices
	for(uint k = 0; k < _Vertices.size(); ++k)
	{
		if (!_Look.VertexShapeName.empty())
		{
			if (!_VertexShapeInstances[k].empty())
			{
				CMatrix vertexMat;
				vertexMat.setScale(_Look.VertexShapeScale);
				vertexMat.setPos(_Vertices[k]);
				_VertexShapeInstances[k].setTransformMode(UTransform::DirectMatrix);
				_VertexShapeInstances[k].setMatrix(vertexMat);
			}
		}
		if (!_VertexDecals.empty())
		{
			_VertexDecals[k]->setWorldMatrixForSpot(CVector2f(_Vertices[k].x, _Vertices[k].y), k == 0 ? _Look.FirstVertexLook.DecalSize : _Look.VertexLook.DecalSize);
		}
	}
	//
	if (_AddedToWorldMap)
	{
		updateWorldMapDisplay();
	}
}
//*********************************************************************************************************
void CDisplayerVisualActivitySequence::update()
{
	//H_AUTO(R2_CDisplayerVisualActivitySequence_update)
	if (!_Active) return;
	if (!_Touched) return;
	_Touched = false;
	CObjectTable *activities = getProps().toTable("Components");
	if (!activities)
	{
		clear();
		return;
	}
	// get first world object parent to get start position
	nlassert(getDisplayedInstance());
	CInstance *prevZone = NULL;
	CDisplayerVisual *prevDV = getParentDV();
	if (!prevDV)
	{
		clear();
		return;
	}
	//
	clear(false);
	//
	for(uint k = 0; k < activities->getSize(); ++k)
	{
		// search next zone of activity
		CObjectTable *activity = activities->getValue(k)->toTable();
		if (!activity) continue;
		std::string activityStr = getString(activity, "Activity");
		if (activityStr == "Stand Still" || activityStr == "Inactive") continue;
		//
		CInstance *nextZone = NULL;
		std::string zoneId = getString(activity, "ActivityZoneId");
		//
		if (!zoneId.empty())
		{
			_ObserverHandles.push_back(getEditor().addInstanceObserver(zoneId, this));
			nextZone = getEditor().getInstanceFromId(zoneId);
		}

		if (!nextZone) break;
		CDisplayerVisual *nextDV = nextZone->getDisplayerVisual();
		if (!nextDV) break;

		_TraversedPrimInfos.push_back(CTraversedPrimInfo());
		_TraversedPrimInfos.back().PrimDisplay = nextDV;
		_TraversedPrimInfos.back().Visible = nextDV->getActualDisplayMode() != DisplayModeHidden;


		CWorldPosCache wpc;
		wpc.DV = nextDV;
		wpc.WorldPos2f = nextDV->getWorldPos2f();
		_WPCache.push_back(wpc);

		if (nextDV->getActualDisplayMode() != DisplayModeHidden
			&& prevDV->getActualDisplayMode() != DisplayModeHidden)
		{
			// special case for regions
			if (nextZone->isKindOf("Region"))
			{
				// first case : previous zone is not a region
				if (!prevZone || !prevZone->isKindOf("Region"))
				{
					// search shortest distance bewteen last pos and the region
					CVector entryPos;
					if (nextDV->evalEnterPoint(prevDV->evalExitPoint(), entryPos))
					{
						addFootSteps(CLine(prevDV->evalExitPoint(), entryPos));
					}
					else
					{
						addWanderSteps(prevDV->evalExitPoint());
					}
				}
				else
				{
					// region-region footsteps
					// just use the couple of vertices for which the distance is the smallest
					static std::vector<CVector2f> r0;
					static std::vector<CVector2f> r1;
					prevDV->getSonsWorldPos2f(r0);
					nextDV->getSonsWorldPos2f(r1);
					if (!r0.empty() && !r1.empty())
					{
						CVector2f p0, p1;
						float bestDist = FLT_MAX;
						for(uint k = 0; k < r0.size(); ++k)
						{
							for(uint l = 0; l < r0.size(); ++l)
							{
								float dist = (r0[k] - r1[l]).norm();
								if (dist <bestDist)
								{
									bestDist = dist;
									p0 = r0[k];
									p1 = r1[l];
								}
							}
						}
						nlassert(bestDist != FLT_MAX);
						addFootSteps(CLine(p0.asVector(), p1.asVector()));
					}
				}
			}
			else
			{
				// special case if prev zone is a region
				if (prevZone && prevZone->isKindOf("Region"))
				{
					// search shortest distance bewteen last pos and the region
					CVector entryPos;
					if (prevDV->evalEnterPoint(nextDV->evalLinkPoint(), entryPos))
					{
						addFootSteps(CLine(entryPos, nextDV->evalLinkPoint()));
					}
					else
					{
						addWanderSteps(nextDV->evalLinkPoint());
					}
				}
				else
				{
					// simple footsteps between last & new pos
					addFootSteps(CLine(prevDV->evalExitPoint(), nextDV->evalLinkPoint()));
				}
			}
		}
		prevDV   = nextDV;
		prevZone = nextZone;
	}
	//
	CGroupMap *gm = CTool::getWorldMap();
	if (!_AddedToWorldMap && gm)
	{
		gm->addDeco(this);
	}
	if (_AddedToWorldMap)
	{
		setWorldMapNumEdges((uint)_FootSteps.size());
		nlassert(gm);
		onUpdate(*gm);
	}
}