Exemplo n.º 1
0
	bool FS_GoNear::FindPathNear(Brain* brain)
	{
		BE::Entity* owner = brain->GetOwner();
		auto entities = std::move(owner->GetLayer()->GetEntities());

		auto sbc = owner->GetC<BE::SteeringBehaviorComponent>();
		auto tc = owner->GetC<BE::TransformComponent>();
		auto gtc = brain->GetOwner()->GetLayer()
			->FindEntity("terrain")->GetC<GridTerrainComponent>();
		if (!(sbc && tc && gtc)) return false;


		glm::vec3 agentPos = tc->GetPosition();
		glm::vec3 goalPos = brain->GetMemory()->GetGotoPos();
		float offset = float(gtc->GetTileSize());

		_path = gtc->GetAIWorld()->FindPath(
			agentPos.x, agentPos.z, goalPos.x + offset, goalPos.z);
		
		if (_path.empty())
			_path = gtc->GetAIWorld()->FindPath(
				agentPos.x, agentPos.z, goalPos.x - offset, goalPos.z);

		if (_path.empty())
			_path = gtc->GetAIWorld()->FindPath(
				agentPos.x, agentPos.z, goalPos.x, goalPos.z + offset);

		if (_path.empty())
			_path = gtc->GetAIWorld()->FindPath(
				agentPos.x, agentPos.z, goalPos.x, goalPos.z - offset);


		if (_path.empty())
		{
			if (sbc->GetType()._to_integral()
				== BE::SteeringBehavior::ENUM::FOLLOW_PATH)
			{
				sbc->SetType(BE::SteeringBehavior::ENUM::ARRIVE);
				sbc->GetTarget().position = agentPos;
			}
			return false;
		}

		auto& goal2d = _path.back();
		sbc->SetArrived(false);
		sbc->SetType(BE::SteeringBehavior::ENUM::FOLLOW_PATH);
		sbc->SetPath(_path);
		return true;
	}
Exemplo n.º 2
0
// 타일페이지가 1개인 경우의 코드
void XMapLayerTile::DrawForOnePage( void )
{
	// 타일페이지 vram에 올리기
	m_pTilePack->UploadTilePage( 0 );
	//
	float scale = m_prefMap->GetfCameraScale();
	int tw, th;
	GetTileSize( &tw, &th );
	XE::VEC2 vSizeTile( tw, th );
	// 현재 보이는화면에 속하는 맵을 돌면서 타일을 찍는다.
	XE::VEC2 vTSizeTile = vSizeTile * scale;
	if( GRAPHICS->GetPhyScreenWidth() == 480 )
	{
		vTSizeTile.x = (float)((int) vTSizeTile.x);
		vTSizeTile.y = (float)((int) vTSizeTile.y);
	} else
	{
#ifdef __NEW_RESO
#else
		vTSizeTile.x = ROUND_OFF2( vTSizeTile.x, 0.5f );
		vTSizeTile.y = ROUND_OFF2( vTSizeTile.y, 0.5f );
#endif
	}
	XE::VEC2 vPos = m_prefMap->GetvPosViewport();			// 뷰포트 좌상귀 픽셀좌표부터 시작
	vPos += (m_vDrawOffset * scale);
	XE::VEC2 vCurr = m_prefMap->GetvwLeftTop() / vSizeTile;		// 현재보이는곳의 좌상귀 맵좌표
	XE::VEC2 vNumDraw = m_prefMap->GetsizeViewport() / vTSizeTile;	// 화면에 보이는 가로세로 타일 개수.
	int xOfs = (int)m_prefMap->GetvwLeftTop().x % tw;
	int yOfs = (int)m_prefMap->GetvwLeftTop().y % th;
	XE::VEC2 vOfs = XE::VEC2( xOfs * scale, yOfs * scale );
	vPos -= vOfs;
	if( GRAPHICS->GetPhyScreenWidth() == 480 )
	{
		vPos.x = (float)((int) vPos.x);
		vPos.y = (float)((int) vPos.y);
	} else
	{
#ifdef __NEW_RESO
#else
		vPos.x = ROUND_OFF2( vPos.x, 0.5f );
		vPos.y = ROUND_OFF2( vPos.y, 0.5f );
#endif
	}
//	float xPos = vPos.x;
	float wView = m_prefMap->GetsizeViewport().w;
	float hView = m_prefMap->GetsizeViewport().h; 
	int i, k;
	float x, y;
	for( y = vPos.y, i = 0; y < hView; y += vTSizeTile.h, ++i )
	{
		int iy = i + (int)vCurr.y;
		if( iy >= 0 && iy < m_hMapTile )
		{
			for( x = vPos.x, k = 0; x < wView; x += vTSizeTile.w, ++k )
			{
				int ix = k + (int)vCurr.x;
				if( ix >= 0 && ix < m_wMapTile )
				{
					short idxTile = m_pMapDat[ iy * m_wMapTile + ix ];		// 맵에서 타일 인덱스 꺼냄
//					if( idxTile && i == 6 )
//					if( idxTile && k == 8 && i >= 7 && i <= 8 )
					if( idxTile )
					{
						// 타일을 하나씩 찍는 버전
						const XTilePack::TILE *pTile = m_pTilePack->GetpTile( idxTile );
						// 버텍스버퍼에 버텍스정보를 밀어넣는다.
						XBREAK( m_pVertexBuffer == NULL );
						m_pVertexBuffer->Add( x, y, vTSizeTile.w, vTSizeTile.h, pTile->u, pTile->v, pTile->u2, pTile->v2 );
					}
				}
			}
		}
	}
	XBREAK( m_pVertexBuffer == NULL );
	m_pVertexBuffer->Flush();
	m_pVertexBuffer->Draw( 0, 0 );
}
Exemplo n.º 3
0
void CEnvironmentGrid::CreateArcNebula (SCreateCtx &Ctx, TArray<STileDesc> *retTiles)

//	CreateArcNebula
//
//	Creates an arc of nebula

	{
	if (Ctx.pEnv == NULL || Ctx.pOrbitDesc == NULL || Ctx.rWidth == 0.0)
		return;

	//	Compute some constants

	Metric rHalfWidth = Ctx.rWidth / 2.0;
	Metric rMaxVariation = Ctx.iWidthVariation * rHalfWidth / 100.0;
	Metric rHalfVariation = rMaxVariation / 2.0;
	Metric rHalfSpan = g_Pi * Ctx.iSpan / 360.0;

	//	Shape of the arc

	CVector vCenter = Ctx.pOrbitDesc->GetFocus();
	Metric rArcCenterAngle = Ctx.pOrbitDesc->GetObjectAngle();
	Metric rMaxRadius = Ctx.pOrbitDesc->GetSemiMajorAxis() + rHalfWidth;
	Metric rMinRadius = Ctx.pOrbitDesc->GetSemiMajorAxis() - rHalfWidth;

	//	Shape parameters

	CWaveGenerator2 OuterWave(
			0.75,	//	Wave 0 amplitude
			5.0,	//	Wave 0 cycles
			0.25,	//	Wave 1 amplitude
			11.0	//	Wave 1 cycles
			);

	CWaveGenerator2 InnerWave(
			0.5,
			6.0,
			0.5,
			15.0
			);

	//	Compute the bounds of the nebula

	Metric rDiag = rMaxRadius + (GetTileSize() * g_KlicksPerPixel);
	CVector vUL = vCenter + CVector(-rDiag, rDiag);
	CVector vLR = vCenter + CVector(rDiag, -rDiag);

	//	Now iterate over every tile in bounds and see if it is within
	//	the band that we have defined.

	int xTileStart, yTileStart, xTileEnd, yTileEnd;
	VectorToTile(vUL, &xTileStart, &yTileStart);
	VectorToTile(vLR, &xTileEnd, &yTileEnd);

	//	Set the granularity of the result array (so that we don't keep on
	//	reallocating).

	if (retTiles)
		{
		retTiles->DeleteAll();
		int iGranularity = Max(DEFAULT_ARRAY_GRANULARITY, (xTileEnd - xTileStart + 1) * (yTileEnd - yTileStart + 1) / 2);
		retTiles->SetGranularity(iGranularity);
		}

	//	Set all tiles

	int x, y;
	for (x = xTileStart; x <= xTileEnd; x++)
		for (y = yTileStart; y <= yTileEnd; y++)
			{
			CVector vTile = TileToVector(x, y);
			CVector vRadius = vTile - vCenter;

			//	Convert to polar coordinates

			Metric rRadius;
			Metric rAngle = VectorToPolarRadians(vRadius, &rRadius);

			//	Skip if outside bounds

			if (rRadius > rMaxRadius || rRadius < rMinRadius)
				continue;

			//	Figure out our distance from the center angle

			Metric rDistAngle = rAngle - rArcCenterAngle;
			if (rDistAngle > g_Pi)
				rDistAngle -= 2.0 * g_Pi;
			else if (rDistAngle < -g_Pi)
				rDistAngle += 2.0 * g_Pi;

			Metric rDistAngleAbs = Absolute(rDistAngle);
			if (rDistAngleAbs > rHalfSpan)
				continue;

			//	Compute the shape at this angle

			Metric rMidRadius;
			Ctx.pOrbitDesc->GetPointAndRadius(rAngle, &rMidRadius);

			Metric rOuterWave = rHalfVariation * OuterWave.GetValue(rAngle);
			Metric rInnerWave = rHalfVariation * InnerWave.GetValue(rAngle);

			//	Taper the shape

			Metric rTaper = 1.0 - (rDistAngleAbs / rHalfSpan);

			//	Calc radius

			Metric rOuterRadius = rMidRadius + rTaper * (rHalfWidth - rOuterWave);
			Metric rInnerRadius = rMidRadius - rTaper * (rHalfWidth + rInnerWave);

			//	If we're inside the ring, then put a nebula down

			if (rRadius > rInnerRadius && rRadius < rOuterRadius)
				{
				SetTileType(x, y, Ctx.pEnv);

				//	Add to list of tiles

				if (retTiles)
					{
					STileDesc *pNewTile = retTiles->Insert();
					pNewTile->x = x;
					pNewTile->y = y;
					pNewTile->pEnv = Ctx.pEnv;
					pNewTile->dwEdgeMask = 0;
					}
				}
			}
	}
Exemplo n.º 4
0
void CEnvironmentGrid::CreateCircularNebula (SCreateCtx &Ctx, TArray<STileDesc> *retTiles)

//	CreateCircularNebula
//
//	The nebula is a ring:
//
//	radius: Ctx.pOrbitDesc radius
//	width of ring: Ctx.rWidth

	{
	if (Ctx.pEnv == NULL || Ctx.pOrbitDesc == NULL || Ctx.rWidth == 0.0)
		return;

	//	Compute some constants

	Metric rHalfWidth = Ctx.rWidth / 2.0;
	Metric rMaxVariation = Ctx.iWidthVariation * rHalfWidth / 100.0;
	Metric rHalfVariation = rMaxVariation / 2.0;

	//	Shape parameters

	CWaveGenerator2 OuterWave(
			0.75,	//	Wave 0 amplitude
			5.0,	//	Wave 0 cycles
			0.25,	//	Wave 1 amplitude
			11.0	//	Wave 1 cycles
			);

	CWaveGenerator2 InnerWave(
			0.5,
			6.0,
			0.5,
			15.0
			);

	//	The maximum diameter of the ring is the orbit diameter plus half the
	//	width.

	Metric rMaxRadius = Ctx.pOrbitDesc->GetSemiMajorAxis() + rHalfWidth;
	CVector vCenter = Ctx.pOrbitDesc->GetFocus();

	//	Compute the bounds of the nebula

	Metric rDiag = rMaxRadius + (GetTileSize() * g_KlicksPerPixel);
	CVector vUL = vCenter + CVector(-rDiag, rDiag);
	CVector vLR = vCenter + CVector(rDiag, -rDiag);

	//	Now iterate over every tile in bounds and see if it is within
	//	the band that we have defined.

	int xTileStart, yTileStart, xTileEnd, yTileEnd;
	VectorToTile(vUL, &xTileStart, &yTileStart);
	VectorToTile(vLR, &xTileEnd, &yTileEnd);

	//	Set the granularity of the result array (so that we don't keep on
	//	reallocating).

	if (retTiles)
		{
		retTiles->DeleteAll();
		int iGranularity = Max(DEFAULT_ARRAY_GRANULARITY, (xTileEnd - xTileStart + 1) * (yTileEnd - yTileStart + 1) / 2);
		retTiles->SetGranularity(iGranularity);
		}

	//	Set all tiles

	int x, y;
	for (x = xTileStart; x <= xTileEnd; x++)
		for (y = yTileStart; y <= yTileEnd; y++)
			{
			CVector vTile = TileToVector(x, y);
			CVector vRadius = vTile - vCenter;

			//	Convert to polar coordinates

			Metric rRadius;
			Metric rAngle = VectorToPolarRadians(vRadius, &rRadius);

			//	Compute the shape at this angle

			Metric rMidRadius;
			Ctx.pOrbitDesc->GetPointAndRadius(rAngle, &rMidRadius);

			Metric rOuterWave = rHalfVariation * OuterWave.GetValue(rAngle);
			Metric rInnerWave = rHalfVariation * InnerWave.GetValue(rAngle);

			Metric rOuterRadius = rMidRadius + rHalfWidth - rOuterWave;
			Metric rInnerRadius = rMidRadius - rHalfWidth + rInnerWave;

			//	If we're inside the ring, then put a nebula down

			if (rRadius > rInnerRadius && rRadius < rOuterRadius)
				{
				SetTileType(x, y, Ctx.pEnv);

				//	Add to list of tiles

				if (retTiles)
					{
					STileDesc *pNewTile = retTiles->Insert();
					pNewTile->x = x;
					pNewTile->y = y;
					pNewTile->pEnv = Ctx.pEnv;
					pNewTile->dwEdgeMask = 0;
					}
				}
			}
	}