//============================================================================= Vector2F Rectangle2::up_() const { Vector2F result = width_; result.setPerpendLeft(); result.setLength(height_); return result; }
const RectangleF* FieldController::FindClosestRectangles(RectangleF* pRectangle, Chromosome* pChromosome, bool bDirection) { std::vector<const RectangleF*> pModels = FindIntersectedRectangles(pRectangle, pChromosome, bDirection); const RectangleF* pResultModel = NULL; Vector2F projectionAxis; if (!bDirection) projectionAxis = Vector2F(0, 1); else projectionAxis = Vector2F(1, 0); Vector2F min, max, modelMin, modelMax; float minLength = 12345678.f; GetProjection(pRectangle, projectionAxis, modelMin, modelMax); for (int i = 0, i_end = pModels.size(); i < i_end; ++i) { GetProjection(pModels[i], projectionAxis, min, max); // we are interested in one side models only if (min > modelMin) { Vector2F lengthVec = (modelMax - min); float tempLength = lengthVec.X() * lengthVec.X() + lengthVec.Y() * lengthVec.Y(); if (tempLength < minLength) { pResultModel = pModels[i]; minLength = tempLength; } } } return pResultModel; }
//============================================================================= double Ray2::nearestParam( const Point2F& pt ) { double parameter = 0.0; Vector2F dir = getDir(); dir.setPerpendLeft(); intersectParam( *this, Ray2(pt, dir), parameter); return parameter; }
//============================================================================= void Rectangle2::originIsCenter_() { Vector2F dw = width_; Vector2F dh = up_(); dw.multiply(-0.5); dh.multiply(-0.5); origin_.add(dw); origin_.add(dh); }
/*---------------------------------------------------------------------*//** メニューの位置調整 **//*---------------------------------------------------------------------*/ void FocusMenu::adjustMenuPos(MenuKind mkind) { // フォローなしの場合は必要なし if(_unitFllowRef[mkind] == 0) { return; } do { MenuTreeNode* mtnode = _menu[mkind]->getCurrentMenuNode(); if(mtnode == 0L) { break; } MenuWindow* mwnd = (MenuWindow*)mtnode->getPanel(); if(mwnd == 0L) { break; } const RectF32* rectMwnd = mwnd->getRectangle(); // 対象がいなくなった if(!_unitFllowRef[mkind]->isEnable()) { break; // メニューを閉じる } // スクリーン座標に変換 Vector2F vScr; CalcUtils::calc3dPosToScreenPos(&vScr, _unitFllowRef[mkind]->getCenterPos()); f32 x = vScr.x(); f32 y = vScr.y(); // ユニット自体が画面外に出たときはメニューを閉じる if((x < 0) || (x > Game::getGame()->getLogicalWidth()) || (y < 0) || (y > Game::getGame()->getLogicalHeight())) { break; // メニューを閉じる } // 画面内に収めるように位置修正 if((x + rectMwnd->w()) > Game::getGame()->getLogicalWidth()) { x = Game::getGame()->getLogicalWidth() - rectMwnd->w(); } else if(x < 0) { x = 0; } if((y + rectMwnd->h()) > Game::getGame()->getLogicalHeight()) { y = Game::getGame()->getLogicalHeight() - rectMwnd->h(); } else if(y < 0) { y = 0; } // 修正を反映 if((x != rectMwnd->x()) || (y != rectMwnd->y())) { PointF32 pt(x, y); mwnd->move(&pt); } return; // 正常終了 } while(false); // なんらかエラーが発生したのでメニューを閉じる _menu[mkind]->closeMenu(); }
//---------------------------------------------------------------------------- void Player::LookAt(const Vector2F& rLookAt) { mLookAt = rLookAt; Application* pApp = Application::GetApplication(); const Float width = pApp->GetWidthF() * 0.5F; Float deadZoneX = width * mLookUpDeadZone.X(); Float xB = width - deadZoneX; if (rLookAt.X() > deadZoneX) { mYawIncrement -= mRotateSpeed * (rLookAt.X() - deadZoneX) / xB; } else if (rLookAt.X() < -deadZoneX) { mYawIncrement -= mRotateSpeed * (rLookAt.X() + deadZoneX) / xB; } const Float height = pApp->GetHeightF() * 0.5F; Float deadZoneY = height * mLookUpDeadZone.Y(); Float yB = height - deadZoneY; if (rLookAt.Y() > deadZoneY) { mPitchIncrement -= mRotateSpeed * (rLookAt.Y() - deadZoneY) / yB; } else if (rLookAt.Y() < -deadZoneY) { mPitchIncrement -= mRotateSpeed * (rLookAt.Y() + deadZoneY) / yB; } }
int grinliz::PointInPolygon( const Vector2F& p, const Vector2F* vertex, int numVertex ) { for( int i=0; i<numVertex; ++i ) { // Inside if every point is to the left. int j = (i+1)%numVertex; Vector2F line = vertex[j]-vertex[i]; line.RotatePos90(); if ( DotProduct( line, p - vertex[i] ) < 0.0f ) return REJECT; } return INTERSECT; }
inline float Vector2F::Angle (Vector2F const& other) const { // P.Q = ||P|| * ||Q|| * cos(theta) // P.Q/(||P|| * ||Q||) = cos(theta) // Therefore, theta = arccos( P.Q/(||P|| * ||Q||) ) return acos(Dot(other)/(Norm() * other.Norm())); }
void World::GenerateEnemies(Player &player) { GameObjectFactory *factory = GameObjectFactory::GetInstance(); const int numEnemies = GameMath::Random(100, 50); int x; int y; for(int i = 0; i < numEnemies; i++) { bool valid = false; while(!valid) { valid = true; do { x = rand() % COLS; y = rand() % ROWS; }while(At(x, y).IsObstacle()); Vector2 enemyCoords(x, y); for(std::vector<Enemy*>::iterator it = enemies.begin(); it != enemies.end(); ++it) { if(enemyCoords == (*it)->GetCoords()) { valid = false; break; } } if(valid) { Vector2F enemyPosition = enemyCoords.toV2F() * Tile::TILE_SIZE; if(enemyPosition.DistanceTo(player.position) >= 500) { Enemy *newEnemy = factory->CreateRandomWorldEnemy(enemyCoords, player.level); enemies.push_back(newEnemy); } } } } }
bool Scene::Process3DTap(int action, const grinliz::Vector2F& view, const grinliz::Ray& world, Engine* engine) { Ray ray; bool result = false; switch( action ) { case GAME_PAN_START: { game->GetScreenport().ViewProjectionInverse3D( &dragData3D.mvpi ); engine->RayFromViewToYPlane( view, dragData3D.mvpi, &ray, &dragData3D.start3D ); dragData3D.startCameraWC = engine->camera.PosWC(); dragData3D.end3D = dragData3D.start3D; dragData3D.start2D = dragData3D.end2D = view; threeDTapDown = true; break; } case GAME_PAN_MOVE: case GAME_PAN_END: { // Not sure how this happens. Why is the check for down needed?? if( threeDTapDown ) { Vector3F drag; engine->RayFromViewToYPlane( view, dragData3D.mvpi, &ray, &drag ); dragData3D.end2D = view; Vector3F delta = drag - dragData3D.start3D; GLASSERT( fabsf( delta.x ) < 1000.f && fabsf( delta.y ) < 1000.0f ); delta.y = 0; drag.y = 0; dragData3D.end3D = drag; if ( action == GAME_TAP_UP ) { threeDTapDown = false; Vector2F vDelta = dragData3D.start2D - dragData3D.end2D; if ( vDelta.Length() < 10.f ) result = true; } engine->camera.SetPosWC(dragData3D.startCameraWC - delta); } break; } } return result; }
void Shader::SendVector2(const std::string &pVarName, const Vector2F &pVector){ float toSend[2]; pVector.XY(toSend); glUniform2fv(glGetUniformLocation(mProgram, pVarName.c_str()), 1, toSend); #ifdef _DEBUG GLenum error = GL_NO_ERROR; if((error = glGetError()) != GL_NO_ERROR){ throw Exception(String("OpenGL Error: \"")+GetGLErrorStr(error)+"\" in function \"SendVector2\"\n\tDoes \""+pVarName+"\" exists or has the right type?"); } #endif }
//---------------------------------------------------------------------------- void Camera::GetPickRay(const Vector2F& rPosition, Vector3F& rRayOrigin, Vector3F& rRayDirection) { WIRE_ASSERT(rPosition.X() >= -1.0F && rPosition.X() <= 1.0F); WIRE_ASSERT(rPosition.Y() >= -1.0F && rPosition.Y() <= 1.0F); Matrix4F projectionMatrix = GetProjectionMatrix(); Vector3F v(rPosition.X() / projectionMatrix(0, 0), rPosition.Y() / projectionMatrix(1, 1), 1); rRayDirection = GetViewMatrixInverse34().Times3(v); rRayOrigin = GetViewMatrixInverse34().GetColumn(3); }
//============================================================================= Point2F Ray2::getPoint(double parameter, double offset) const { Vector2F delta = dir_; delta.multiply(parameter); Point2F result = origin_; result.add(delta); if (offset == 0.0) return result; Vector2F offsetVec = dir_; offsetVec.setPerpendLeft(); offsetVec.multiply( offset/offsetVec.getLength() ); result.add(offsetVec); return result; }
void FieldController::GetProjection(const RectangleF* pRect, const Vector2F& dir, Vector2F& min, Vector2F& max) { Vector2F projectionAxis(-dir.Y(), dir.X()); float sqrlen = projectionAxis.X() * projectionAxis.X() + projectionAxis.Y() * projectionAxis.Y(); // projection rectangle points to projAxis float dp = pRect->GetTopLeft().X() * projectionAxis.X() + pRect->GetTopLeft().Y() * projectionAxis.Y(); float tempValue = dp / sqrlen; min.X() = tempValue * projectionAxis.X(); min.Y() = tempValue * projectionAxis.Y(); dp = pRect->GetBottomRight().X() * projectionAxis.X() + pRect->GetBottomRight().Y() * projectionAxis.Y(); tempValue = dp / sqrlen; max.X() = tempValue * projectionAxis.X(); max.Y() = tempValue * projectionAxis.Y(); }
/*---------------------------------------------------------------------*//** フレーム制御 **//*---------------------------------------------------------------------*/ void MoveCursor::exec(ExecRes* res, const ExecCtx* ec) { if(TFW_IS_FLAG(_edchFlags, EDCH_EXT_MASK)) { return; } // 外部からの無効化 // 歩行処理 GameExecCtx* gec = (GameExecCtx*)ec; TouchPanel* ui = gec->getTouchPanel(); bool isEnableSelf = (!gec->isOpenedLockGui()) && (!gec->isLockOperating()); TFW_SET_FLAG(_edchFlags, EDCH_SELF, !isEnableSelf); if(isEnableSelf && !ui->isReacted()) { // 差分を求める Vector2F vDiff; do { // 最初にクリックしたとこからの差分で移動 bool isTouched = _isTouching; _isTouching = (ui->getTouchingNum() == 1); // タッチ時のポイントを得る if(!isTouched && _isTouching) // タッチした { ui->getTouchPosition(_ptTouchStart); // 開始のタッチ位置を得る ui->setDragOperating(true); _ext->onTapStart(_ptTouchStart); } else if(isTouched && !_isTouching) // 離した { // UI 反応済みフラグを立てるかどうかの判定 Vector2F vDiff( (f32)(_ptTouchLast->x() - _ptTouchStart->x()), (f32)(_ptTouchLast->y() - _ptTouchStart->y()) ); f32 lenDiffSq = vDiff.lengthSq(); if(lenDiffSq >= LEN_MIN_SQ) // 最小長さを超えている { ui->setReacted(true); // 反応済みフラグを立てる } _ptTouchStart->set(F32_PMAX, F32_PMAX); _ptTouchLast->set(F32_PMAX, F32_PMAX); _xDiff = 0; _yDiff = 0; _ext->onTapEnd(); break; // 差分計算から抜ける } if(_isTouching) { ui->getTouchPosition(_ptTouchLast); // 現在のタッチ位置を得る } // 差分を計算する vDiff.set( (f32)(_ptTouchLast->x() - _ptTouchStart->x()), (f32)(_ptTouchLast->y() - _ptTouchStart->y()) ); f32 lenDiffPw = vDiff.lengthSq(); if(lenDiffPw > LEN_MAX_SQ) // 最大長さを超えている { // 最大長さに収める vDiff.normalize(); vDiff *= LEN_MAX; // タッチ位置の補正 _ptTouchLast->x() = _ptTouchStart->x() + (s32)vDiff.x(); _ptTouchLast->y() = _ptTouchStart->y() + (s32)vDiff.y(); ui->setReacted(true); // 反応済みフラグを立てる } else if(lenDiffPw < LEN_MIN_SQ) // 最小長さ未満 { vDiff.set(0.0f, 0.0f); _xDiff = 0; _yDiff = 0; break; // 差分計算から抜ける } else { ui->setReacted(true); // 反応済みフラグを立てる } _xDiff = (s32)vDiff.x(); _yDiff = (s32)vDiff.y(); } while(false); // 描画用に角度を得ておく Calc::calcAngle(&_angle, vDiff.x(), vDiff.y()); } else if(_isTouching) { _xDiff = 0; _yDiff = 0; _isTouching = false; _ext->onTapEnd(); } // 2点間の距離を求める f32 lenPw = (f32)((_xDiff * _xDiff) + (_yDiff * _yDiff)); _length = ::sqrtf(lenPw); _rateLength = _length / LEN_MAX; // 状態を更新する if(_length < LEN_WALK) { _state = STATE_STOP; } else if(_length < LEN_RUN) { _state = STATE_WALK; } else { _state = STATE_RUN; } }
//---------------------------------------------------------------------------- Texture2D* Sample5::CreateTexture() { if (mspTexture) { return mspTexture; } // define the properties of the image to be used as a texture const UInt width = 256; const UInt height = 256; const Image2D::FormatMode format = Image2D::FM_RGB888; const UInt bpp = Image2D::GetBytesPerPixel(format); ColorRGB* const pColorDst = WIRE_NEW ColorRGB[width*height]; // create points with random x,y position and color TArray<Cell> cells; Random random; for (UInt i = 0; i < 10; i++) { Cell cell; cell.point.X() = random.GetFloat() * width; cell.point.Y() = random.GetFloat() * height; cell.color.R() = random.GetFloat(); cell.color.G() = random.GetFloat(); cell.color.B() = random.GetFloat(); Float max = 0.0F; max = max < cell.color.R() ? cell.color.R() : max; max = max < cell.color.G() ? cell.color.G() : max; max = max < cell.color.B() ? cell.color.B() : max; max = 1.0F / max; cell.color *= max; cells.Append(cell); } // iterate over all texels and use the distance to the 2 closest random // points to calculate the texel's color Float max = 0; for (UInt y = 0; y < height; y++) { for (UInt x = 0; x < width; x++) { Float minDist = MathF::MAX_REAL; Float min2Dist = MathF::MAX_REAL; UInt minIndex = 0; for (UInt i = 0; i < cells.GetQuantity(); i++) { Vector2F pos(static_cast<Float>(x), static_cast<Float>(y)); // Handle tiling Vector2F vec = cells[i].point - pos; vec.X() = MathF::FAbs(vec.X()); vec.Y() = MathF::FAbs(vec.Y()); vec.X() = vec.X() > width/2 ? width-vec.X() : vec.X(); vec.Y() = vec.Y() > height/2 ? height-vec.Y() : vec.Y(); Float distance = vec.Length(); if (minDist > distance) { min2Dist = minDist; minDist = distance; minIndex = i; } else if (min2Dist > distance) { min2Dist = distance; } } Float factor = (min2Dist - minDist) + 3; ColorRGB color = cells[minIndex].color * factor; pColorDst[y*width+x] = color; max = max < color.R() ? color.R() : max; max = max < color.G() ? color.G() : max; max = max < color.B() ? color.B() : max; } } // convert and normalize the ColorRGBA float array to an 8-bit per // channel texture max = 255.0F / max; UChar* const pDst = WIRE_NEW UChar[width * height * bpp]; for (UInt i = 0; i < width*height; i++) { ColorRGB color = pColorDst[i]; pDst[i*bpp] = static_cast<UChar>(color.R() * max); pDst[i*bpp+1] = static_cast<UChar>(color.G() * max); pDst[i*bpp+2] = static_cast<UChar>(color.B() * max); } Image2D* pImage = WIRE_NEW Image2D(format, width, height, pDst); Texture2D* pTexture = WIRE_NEW Texture2D(pImage); // The texture tiles are supposed to be seamless, therefore // we need the UV set to be repeating. pTexture->SetWrapType(0, Texture2D::WT_REPEAT); pTexture->SetWrapType(1, Texture2D::WT_REPEAT); // save the texture for later reference mspTexture = pTexture; return pTexture; }
/*---------------------------------------------------------------------*//** 描画 **//*---------------------------------------------------------------------*/ void FocusCursor::draw(const RenderCtx* rc) { if(!_isEnableOut || !_isEnableSelf) { return; } // 無効化中 GameRenderCtx* grc = (GameRenderCtx*)rc; Renderer* rdr = rc->getRenderer(); RectF32 uv; // テクスチャ設定 rdr->bindTexture(_texRef); // 加算アルファ合成 rdr->setAlphaBlendFunc(Renderer::AFUNC_ADD); // 2D 解像描画比 f32 rate2dr = Env_get2drRate(); // 頂点カラーを基本色に rdr->setSolidColor(255, 255, 255, 255); // クリック対象を描画 { Tfw* tfw = Game::getGame()->getTfw(); ASSERT(tfw != 0L); View* view = tfw->getView(); ASSERT(view != 0L); SorSgm* sgm = (SorSgm*)tfw->getSgManager(); ASSERT(sgm != 0L); Camera* cam = sgm->getVisibleCamera(); if(cam != 0L) { UnitManager* unitmng = Game::getGame()->getUnitManager(); ASSERT(unitmng != 0L); for(int i = 0; i < unitmng->getUnitNum(); i++) { const Unit* unit = unitmng->getUnitFromIndex(i); ASSERT(unit != 0L); if(!unit->isEnable()) { continue; } // 無効なユニットは除外 if(!unit->isEnableFocus()) { continue; } // フォーカスされないユニットは除外 if(unit->isHidden()) { continue; } // 隠し属性ユニットは除外 if(unit->isHiddenClick()) { continue; } // クリック選択不可 if(unit->getUnitType() == UNITTYPE_EQUIPMENT_ITEM) { continue; } // 所持品は除外 if(unit->getCenterPos()->z() >= cam->getLoc()->z()) { continue; } // カメラより手前は除外 // 既にフォーカスがあるユニットは不要 bool isHadFocus = false; for(s32 j = 0; j < NUM_FOCUS_MAX; j++) { if(_focusarr->getUnit(j) == unit) { isHadFocus = true; break; } } if(isHadFocus) { continue; } // スクリーン座標に変換 Vector2F vScr; Gcalc::conv3dPosToScreenPos(&vScr, unit->getCenterPos(), cam, view); // 画面外チェック if( ((vScr.x() + W_FOCUS_CIRC) < 0) || ((vScr.x() - W_FOCUS_CIRC) >= Game::getGame()->getLogicalWidth()) || ((vScr.y() + H_FOCUS_CIRC) < 0) || ((vScr.y() - H_FOCUS_CIRC) >= Game::getGame()->getLogicalHeight()) ) { continue; } // 描画 ::glPushMatrix(); // 行列を保存 ::glTranslatef(vScr.x(), vScr.y(), 0.0f); drawQuestIcon(rdr, unit, rate2dr); // クエストアイコン表示 ::glRotatef(_dangFocusable, 0.0f, 0.0f, 1.0f); // フォーカス可能アイコン表示 RectF32 vtx(- W_FOCUS_CIRC / 2, - H_FOCUS_CIRC / 2, W_FOCUS_CIRC, H_FOCUS_CIRC); RendererUtils::draw2dTextureRect(rdr, &vtx, Gcalc::calcTexUv(&uv, UV_FOCUSABLE, W_TEX, H_TEX, rate2dr)); ::glPopMatrix(); // 行列を戻す } } } // フォーカスカーソル表示 drawFocusCursor(rdr, _focusarr, 1.0f, rate2dr); // マジッククラスターのフォーカスを表示 MagicSys* mgsys = Game::getGame()->getMagicSys(); for(int i = 0; i < mgsys->getMaxClusterNum(); i++) { MagicCluster* mc = mgsys->getClusterFromIndex(i); if(mc == 0L) { continue; } if(!mc->isValid()) { continue; } if(!TFW_IS_FLAG(mc->getConfFlags(), MagicCluster::CONFF_SHOW_FC)) { continue; } rdr->setSolidColor(63, 0, 255, 255); drawFocusCursor(rdr, mc->getFocusArray(), 0.5f, rate2dr); } // 通常アルファ合成 rdr->setAlphaBlendFunc(Renderer::AFUNC_NORMAL); // フォーカスゲージ表示 for(s32 i = 0; i < NUM_FOCUS_MAX; i++) { const Unit* unitFocused = _focusarr->getUnit(i); if(unitFocused == 0L) { continue; } // フォーカスがある場合のみ以下を処理する const Vector2F* posScr = _focusarr->getScreenPos(i); f32 x = posScr->x() + W_FOCUS_CIRC * 0.5f; f32 y = posScr->y(); // ゲージ表示 if(unitFocused->isCategory(Unit::UNITCAT_CHAR)) { const CharUnit* cunit = (CharUnit*)unitFocused; const CharStat* cstat = cunit->getCharStat(); if(cstat != 0L) { StatusDrawer::drawCharStat(rc, _texRef, cstat, x, y, StatusDrawer::W_GAUGE_DEFAULT, StatusDrawer::H_GAUGE_DEFAULT, false, false); } } else if(unitFocused->getUnitType() == UNITTYPE_EQUIPMENT_ITEM) { const EquipmentItemUnit* iunit = (EquipmentItemUnit*)unitFocused; const Item* item = iunit->getItem(); if(item != 0L) { // 名前表示 const VcString* name = item->getItemDef()->getName(Env_getLangId()); if(name != 0L) { rdr->setSolidColor(255, 255, 255, 255); Font* fontJp = grc->getFontSet()->getFont(GameFontSet::JP); EasyStringDrawer::draw(fontJp, name, x, y, 8, rc); y += 8.0f; } const EleneStat* eestat = item->getEleneStat(); if(eestat != 0L) { StatusDrawer::drawEleneStat(rc, _texRef, eestat, x, y, 60.0f, StatusDrawer::H_ENEGAUGE_DEFAULT, false); } } } else if(unitFocused->getUnitType() == UNITTYPE_PUT_ITEM) { const PutItemUnit* diunit = (PutItemUnit*)unitFocused; const ItemDef* itmdf = diunit->getItemDef(); if(itmdf != 0L) { // 名前表示 const VcString* name = itmdf->getName(Env_getLangId()); if(name != 0L) { rdr->setSolidColor(255, 255, 255, 255); Font* fontJp = grc->getFontSet()->getFont(GameFontSet::JP); EasyStringDrawer::draw(fontJp, name, x, y, 8, rc); y += 8.0f; } } const EleneStat* eestat = diunit->getEleneStat(); if(eestat != 0L) { StatusDrawer::drawEleneStat(rc, _texRef, eestat, x, y, 60.0f, StatusDrawer::H_ENEGAUGE_DEFAULT, false); } } } }
/*---------------------------------------------------------------------*//** フレーム制御 **//*---------------------------------------------------------------------*/ void FocusCursor::exec(ExecRes* res, const ExecCtx* ec) { if(!_isEnableOut) { return; } // 外部からの無効化 GameExecCtx* gec = (GameExecCtx*)ec; TouchPanel* ui = gec->getTouchPanel(); // フォーカスの有効性更新 _focusarr->updateValidity(); // フォーカスの座標値をリセット for(s32 i = 0; i < NUM_FOCUS_MAX; i++) { _focusarr->invalidateScreenPos(i); } // 有効性判定 _isEnableSelf = !gec->isLockOperating(); bool isEnableUiReact = _isEnableSelf && !gec->isOpenedLockGui() && !ui->isReacted() && (_fcntPreventTap == 0.0f); // タッチ操作による処理 if(isEnableUiReact) { PointF32 ptTouch, ptStart; bool isTap = false; bool isDblTapRel = false; if(!ui->isReacted()) { const f32 DIFF_TAP_RANGE = 20.0f; if(ui->isTapRelease(&ptTouch, &ptStart)) { isTap = ptTouch.isNear(&ptStart, DIFF_TAP_RANGE, DIFF_TAP_RANGE); } // 面積が狭いので、isClickRelease だとストレスに感じる if(ui->isDoubleClickRelease(&ptTouch)) { isDblTapRel = true; } } if(isTap || isDblTapRel) { Tfw* tfw = Game::getGame()->getTfw(); ASSERT(tfw != 0L); View* view = tfw->getView(); ASSERT(view != 0L); SorSgm* sgm = (SorSgm*)tfw->getSgManager(); ASSERT(sgm != 0L); Camera* cam = sgm->getVisibleCamera(); ASSERT(cam != 0L); UnitManager* unitmng = Game::getGame()->getUnitManager(); ASSERT(unitmng != 0L); for(int i = 0; i < unitmng->getUnitNum(); i++) { Unit* unit = unitmng->getUnitFromIndex(i); ASSERT(unit != 0L); if(!unit->isEnable()) { continue; } // 無効なユニットは除外 if(!unit->isEnableFocus()) { continue; } // フォーカスされないユニットは除外 if(unit->isHidden()) { continue; } // 隠し属性ユニットは除外 if(unit->getUnitType() == UNITTYPE_EQUIPMENT_ITEM) { continue; } // 所持品は除外 if(unit->getCenterPos()->z() >= cam->getLoc()->z()) { continue; } // カメラより手前は除外 // スクリーン座標に変換 Vector2F vScr; Gcalc::conv3dPosToScreenPos(&vScr, unit->getCenterPos(), cam, view); if(isDblTapRel) // ダブルクリック時は直接フォーカスをセットする { // 一度フォーカスをリセット for(int j = 0; j < NUM_FOCUS_MAX; j++) { setFocus(j, 0L, 0L); } // 範囲内かどうか判定して、範囲内だったらフォーカス設定する if(TFW_IS_NEAR(vScr.x(), ptTouch.x(), RANGE_TOTRG) && TFW_IS_NEAR(vScr.y(), ptTouch.y(), RANGE_TOTRG)) { // フォーカスをセット(上部でリセットしているので、[0] 決めうち) setFocus(0, unit, &vScr); // UI に反応済みフラグを立てる ui->setReacted(true); break; } } else if(isTap) // タップ時はメニューを表示 { // 範囲内かどうか判定して、範囲内だったらメニューを表示する TRACELN("{FocusCursor::exec} unit touch?; scr_x=%f, scr_y=%f, click_x=%d, click_y=%d", vScr.x(), vScr.y(), ptTouch.x(), ptTouch.y()); if(TFW_IS_NEAR(vScr.x(), ptTouch.x(), RANGE_TOTRG) && TFW_IS_NEAR(vScr.y(), ptTouch.y(), RANGE_TOTRG)) { showFocusMenu(unit, &vScr); // フォーカスメニュー表示 ui->setReacted(true); // UI に反応済みフラグを立てる } } } } } // フォーカスカーソルの画面位置を計算 for(s32 i = 0; i < NUM_FOCUS_MAX; i++) { // 無効になったユニットは外す const Unit* unitFocused = _focusarr->getUnit(i); if(unitFocused == 0L) { continue; } if(!unitFocused->isEnable()) { setFocus(i, 0L, 0L); } // スクリーン座標値が未計算の場合、計算する if(!_focusarr->isValidScreenPos(i)) { _focusarr->calcScreenPos(i); } } // マジッククラスターのフォーカスの画面位置を計算 MagicSys* mgsys = Game::getGame()->getMagicSys(); for(int i = 0; i < mgsys->getMaxClusterNum(); i++) { MagicCluster* mc = mgsys->getClusterFromIndex(i); if(mc == 0L) { continue; } if(!mc->isValid()) { continue; } mc->focusArray()->calcScreenPosAll(); } // タップ防止カウンタの更新 if(_fcntPreventTap > 0.0f) { _fcntPreventTap -= ec->getDeltaFrame(); if(_fcntPreventTap < 0.0f) { _fcntPreventTap = 0.0f; } } // カーソル回転角度の更新 _dangFocus += DANG_FOCUS_DELTA; if(_dangFocus > 180.0f) { _dangFocus -= 360.0f; } _dangFocusable += DANG_FOCUSABLE_DELTA; if(_dangFocusable > 180.0f) { _dangFocusable -= 360.0f; } }
void grinliz::TessellateCube( const Vector3F& center, const Vector3F& size, std::vector< Vector3F >* _vertex, std::vector< U32 >* _index, std::vector< Vector3F >* _normal, std::vector< Vector2F >* _texture ) { GLASSERT( _vertex ); GLASSERT( _index ); _vertex->resize( 0 ); _index->resize( 0 ); if ( _normal ) _normal->resize( 0 ); if ( _texture ) _texture->resize( 0 ); const Vector3F X = { size.x*0.5f, 0.0f, 0.0f }; const Vector3F Y = { 0.0f, size.y*0.5f, 0.0f }; const Vector3F Z = { 0.0f, 0.0f, size.z*0.5f }; Vector3F xyz[8] = { center - X - Y - Z, // 0 center + X - Y - Z, // 1 center - X + Y - Z, // 2 center + X + Y - Z, // 3 center - X - Y + Z, // 4 center + X - Y + Z, // 5 center - X + Y + Z, // 6 center + X + Y + Z }; // 7 // Front, right, back, left, top, bottom // positive would from lower left int face[] = { 4, 5, 7, 6, // Front 5, 1, 3, 7, // Right 1, 0, 2, 3, // Back 0, 4, 6, 2, // Left 6, 7, 3, 2, // Top 0, 1, 5, 4 }; // Bottom Vector3F normal[] = { { 0.f, 0.f, 1.f }, { 1.f, 0.f, 0.f }, { 0.f, 0.f, -1.f }, { -1.f, 0.f, 0.f }, { 0.f, 1.f, 0.f }, { 0.f, -1.f, 0.f } }; for( int i=0; i<6; ++i ) { U32 index = (U32)_vertex->size(); _vertex->push_back( xyz[ face[i*4+0] ] ); _vertex->push_back( xyz[ face[i*4+1] ] ); _vertex->push_back( xyz[ face[i*4+2] ] ); _vertex->push_back( xyz[ face[i*4+3] ] ); _index->push_back( index + 0 ); _index->push_back( index + 1 ); _index->push_back( index + 2 ); _index->push_back( index + 0 ); _index->push_back( index + 2 ); _index->push_back( index + 3 ); if ( _normal ) { for( int k=0; k<4; ++k ) _normal->push_back( normal[i] ); } if ( _texture ) { Vector2F uv; uv.Set( 0.0f, 0.0f ); _texture->push_back( uv ); uv.Set( 1.0f, 0.0f ); _texture->push_back( uv ); uv.Set( 1.0f, 1.0f ); _texture->push_back( uv ); uv.Set( 0.0f, 1.0f ); _texture->push_back( uv ); } } }
void MapScene::DrawMap() { CDynArray<Chit*> query; const ChitContext* context = lumosChitBag->Context(); const Web& web = lumosChitBag->GetSim()->CalcWeb(); Rectangle2I subBounds = MapBounds2(); float map2X = float(subBounds.min.x) / float(NUM_SECTORS); float map2Y = float(subBounds.min.y) / float(NUM_SECTORS); RenderAtom subAtom = mapImage.GetRenderAtom(); subAtom.tx0 = map2X; subAtom.ty1 = map2Y; subAtom.tx1 = map2X + float(MAP2_SIZE) / float(NUM_SECTORS); subAtom.ty0 = map2Y + float(MAP2_SIZE) / float(NUM_SECTORS); mapImage2.SetAtom(subAtom); for (Rectangle2IIterator it(subBounds); !it.Done(); it.Next()) { Vector2I sector = it.Pos(); const SectorData& sd = worldMap->GetSectorData( sector ); int i = (sector.x - subBounds.min.x); int j = (sector.y - subBounds.min.y); int index = j * MAP2_SIZE + i; CoreScript* coreScript = CoreScript::GetCore(sector); CStr<64> str = ""; const char* owner = ""; if (coreScript) { if ( coreScript->InUse() ) { owner = Team::Instance()->TeamName( coreScript->ParentChit()->Team() ).safe_str(); } } str.Format( "%s\n%s", sd.name.safe_str(), owner ); Rectangle2F r = GridBounds2(i, j, true); gridWidget[index].SetPos(r.min.x, r.min.y); gridWidget[index].SetSize(r.Width(), r.Height()); gridWidget[index].Set(context, coreScript, lumosChitBag->GetHomeCore(), &web); } Vector2I homeSector = lumosChitBag->GetHomeSector(); if ( !data->destSector.IsZero() && data->destSector != homeSector ) { const SectorData& sd = worldMap->GetSectorData( data->destSector ); CStr<64> str; str.Format( "Grid Travel\n%s", sd.name.c_str() ); gridTravel.SetText( str.c_str() ); gridTravel.SetEnabled( true ); } else { gridTravel.SetText( "Grid Travel" ); gridTravel.SetEnabled( false ); } // --- MAIN --- Rectangle2I mapBounds = data->worldMap->Bounds(); Rectangle2I map2Bounds; map2Bounds.Set(subBounds.min.x*SECTOR_SIZE, subBounds.min.y*SECTOR_SIZE, subBounds.max.x*SECTOR_SIZE + SECTOR_SIZE-1, subBounds.max.y*SECTOR_SIZE + SECTOR_SIZE-1); Vector2F playerPos = { 0, 0 }; Chit* player = data->player; if ( player ) { playerPos = ToWorld2F(player->Position()); } const float dx = mapImage.Width() / float(NUM_SECTORS); const float dy = mapImage.Height() / float(NUM_SECTORS); for (int j = 0; j < NUM_SECTORS; ++j) { for (int i = 0; i < NUM_SECTORS; ++i) { diplomacy[j*NUM_SECTORS + i].SetSize(dx, dy); diplomacy[j*NUM_SECTORS + i].SetPos(mapImage.X() + dx * float(i), mapImage.Y() + dy * float(j)); } } bool inBounds = true; Vector2F v; for (int i = 0; i < 2; ++i) { const Rectangle2I& b = (i == 0) ? mapBounds : map2Bounds; v = ToUI(i, playerPos, b, &inBounds); playerMark[i].SetCenterPos(v.x, v.y); playerMark[i].SetVisible(inBounds); Vector2F pos = { float(homeSector.x * SECTOR_SIZE), float(homeSector.y * SECTOR_SIZE) }; v = ToUI(i,pos, b, &inBounds); homeMark[i].SetPos(v.x, v.y); homeMark[i].SetVisible(inBounds && !homeSector.IsZero()); pos.Set(float(data->destSector.x * SECTOR_SIZE), float(data->destSector.y * SECTOR_SIZE)); v = ToUI(i,pos, b, &inBounds); // if (i == 0) { // travelMark.SetPos(v.x, v.y); // travelMark.SetVisible(inBounds && !data->destSector.IsZero()); // } for (int k = 0; k < MAX_SQUADS; ++k) { v = ToUI(i, ToWorld2F(data->squadDest[k]), b, &inBounds); squadMark[i][k].SetCenterPos(v.x, v.y); squadMark[i][k].SetVisible(!data->squadDest[k].IsZero() && inBounds); } } { Vector2F world = { (float)map2Bounds.min.x, (float)map2Bounds.min.y }; Vector2F pos = ToUI(0, world, mapBounds, 0); selectionMark.SetPos(pos.x, pos.y); } float scale = float(mapImage.Width()) / float(NUM_SECTORS); { webCanvas.Clear(); for (int i = 1; i < web.NumNodes(); i++) { const MinSpanTree::Node& node = web.NodeAt(i); Vector2I s0 = node.parentPos; Vector2I s1 = node.pos; Vector2F p0 = { (float(s0.x) + 0.5f) * scale, (float(s0.y) + 0.5f) * scale }; Vector2F p1 = { (float(s1.x) + 0.5f) * scale, (float(s1.y) + 0.5f) * scale }; webCanvas.DrawLine(p0.x, p0.y, p1.x, p1.y, 1.0f + node.strength * 2.0f); } } CoreScript* homeCore = context->chitBag->GetHomeCore(); CChitArray citizens; if (homeCore) { homeCore->Citizens(&citizens); } for (int i = 0; i < MAX_CITIZENS; ++i) { if (i < citizens.Size()) { Vector2F cPos = ToWorld2F(citizens[i]->Position()); Vector2F pos = ToUI(0, cPos, mapBounds, 0); unitMarker[i].SetSize(8, 8); unitMarker[i].SetCenterPos(pos.x, pos.y); unitMarker[i].SetVisible(true); } else { unitMarker[i].SetVisible(false); } } for (int j = 0; j < NUM_SECTORS; ++j) { for (int i = 0; i < NUM_SECTORS; ++i) { diplomacy[i].SetAtom(RenderAtom()); Vector2I sector = { i, j }; CoreScript* core = CoreScript::GetCore(sector); RenderAtom atom; if (core && homeCore && homeCore->InUse() && core->InUse()) { ERelate relate = Team::Instance()->GetRelationship(core->ParentChit(), homeCore->ParentChit()); if (relate == ERelate::FRIEND) atom = LumosGame::CalcUIIconAtom("friend"); else if (relate == ERelate::NEUTRAL) atom = LumosGame::CalcUIIconAtom("neutral"); else if (relate == ERelate::ENEMY) atom = LumosGame::CalcUIIconAtom("enemy"); diplomacy[j*NUM_SECTORS + i].SetSize(scale*0.8f, scale*0.8f); } if (core && core->InUse() && Team::IsDeity(core->ParentChit()->Team())) { atom = LumosGame::CalcDeityAtom(core->ParentChit()->Team()); diplomacy[j*NUM_SECTORS + i].SetSize(scale, scale); } diplomacy[j*NUM_SECTORS + i].SetAtom(atom); diplomacy[j*NUM_SECTORS + i].SetCenterPos(mapImage.X() + scale * (float(i) + 0.5f), mapImage.Y() + scale * (float(j) + 0.5f)); } } }
Vector2F Vector2F::operator-(Vector2F& vec) { Vector2F v (this->x - vec.getX(), this->y - vec.getY()); return v; }
Vector2F Vector2F::operator+(Vector2F& vec) { Vector2F v (this->x + vec.getX(), this->y + vec.getY()); return v; }
Vector2F InverseBilinearInterpolate::solve(Vector2F M1, Vector2F M2, Vector2F b, bool safeInvert) { float det = M1.cross(M2); if(safeInvert || det != 0.f) det = 1.f/det; return Vector2F(b.cross(M2), -b.cross(M1)) * det; }