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; }
// 타일페이지가 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 ); }
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; } } } }
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; } } } }