Пример #1
0
    void IrrlichtGraphics::drawImage(const Image* image,
                                int srcX,
                                int srcY,
                                int dstX,
                                int dstY,
                                int width,
                                int height)
    {
        if (mClipStack.empty())
        {
            throw FCN_EXCEPTION("Clip stack is empty, perhaps you called a draw funtion outside of _beginDraw() and _endDraw()?");
        }

        const ClipRectangle& top = mClipStack.top();

        const IrrlichtImage* srcImage = dynamic_cast<const IrrlichtImage*>(image);

        if (srcImage == NULL)
        {
            throw FCN_EXCEPTION("Trying to draw an image of unknown format, must be an IrrlichtImage.");
        }

        irr::core::position2d<irr::s32> destPos(dstX + top.xOffset, dstY + top.yOffset);
        irr::core::rect<irr::s32> sourceRect(srcX, srcY, srcX + width, srcY + height);
        irr::core::rect<irr::s32> clipRect(top.x, top.y, top.x + top.width, top.y + top.height);
        irr::video::SColor color(255, 255, 255, 255);

        mDriver->draw2DImage(srcImage->getTexture(), destPos, sourceRect, &clipRect, color, true);
    }
Пример #2
0
// allCandidates contains the previous positions, scaled to the original
// dimension of image of the found face
// thus we can exploit this thing to skip a big section of the level = the
// intersection of the candidates
// scaled by factor (thus is compatible with level) with level
void FaceClassifier::_slidingSearch(cv::Mat1b& level,
                                    float factor,
                                    std::vector<cv::Rect>& allCandidates) {
  cv::Size winSize(std::ceil(_windowSize.width * factor),
                   std::ceil(_windowSize.height * factor));

  std::vector<cv::Rect> toSkip;
  for (const cv::Rect& r : allCandidates) {
    toSkip.push_back(cv::Rect(r.x / factor, r.y / factor, r.width / factor,
                              r.height / factor));
  }

  for (auto y = 0; y < level.rows - _windowSize.height; y += _step) {
    for (auto x = 0; x < level.cols - _windowSize.width; x += _step) {
      cv::Rect roi_rect(x, y, _windowSize.width, _windowSize.height);

      // if roi_rect intersect a toSkip element, lets continue
      auto exists =
          std::find_if(toSkip.begin(), toSkip.end(), [&](const cv::Rect& skip) {
            cv::Rect intersection(skip & roi_rect);
            if (intersection.area() > 0) {
              x += intersection.width + _step;
              return true;
            }
            return false;
          });

      if (exists != toSkip.end()) {  // intersection exists, we can skip
        continue;
      }

      cv::Mat1b roi = level(roi_rect);
      if (_vc->classify(roi)) {  // variance
        // std::cout << "V";
        if (_fc->classify(roi)) {  // features (shape)
          // std::cout << "F";
          if (_sc->classify(roi)) {  // svm to refine
            // std::cout << "S";
            cv::Rect destPos(std::floor(x * factor), std::floor(y * factor),
                             winSize.width + 1, winSize.height + 1);
            allCandidates.push_back(destPos);
            // add current roi to toSkip vector
            toSkip.push_back(roi_rect);
            x += _windowSize.height;
          }
        }
        // std::cout << std::endl;
      }
    }
  }
}
Пример #3
0
void TickerTape::setPositions(TextAction &action) {
	Vec2i txtDims = Vec2i(textDims(this, getText(action.m_targetIndex)));
	Vec2i widgetSize = getSize() - getBordersAll();
	int yPos = (widgetSize.h - txtDims.h) / 2;
	int aPos;
	if (m_anchor.isPercentage()) {
		if (m_anchor.getPercentage() == -1) {
			aPos = widgetSize.w;
		} else {
			aPos = int(m_anchor.getPercentage() / 100.f * widgetSize.w);
		}
	} else {
		aPos = m_anchor.getAbsolute();
	}
	if (m_align == Alignment::CENTERED) {
		aPos -= txtDims.w / 2;
	} else if (m_align == Alignment::FLUSH_LEFT) {
		// nop
	} else if (m_align == Alignment::FLUSH_RIGHT) {
		aPos -= txtDims.w;
	} else {
		assert(false);
	}
	Vec2i destPos(getBorderLeft() + aPos, getBorderTop() + yPos);
	TextWidget::setTextPos(destPos, action.m_targetIndex);
	Vec2f targetPos = Vec2f(destPos);	
	Vec2f startOffset, endOffset;
	if (m_alternateOrigin && action.m_actionNumber % 2 == 1) {
		startOffset = m_endOffset;
		endOffset = m_startOffset;
	} else {
		startOffset = m_startOffset;
		endOffset = m_endOffset;
	}
	if (action.m_phaseNumber == 0) {
		action.m_startPos = targetPos + startOffset;
		action.m_destPos = targetPos;
	} else if (action.m_phaseNumber == 1) {
		action.m_startPos = action.m_destPos = targetPos;
	} else if (action.m_phaseNumber == 2) {
		action.m_startPos = targetPos;
		action.m_destPos = targetPos + endOffset;
	}
	setTextPos(Vec2i(action.m_startPos), action.m_targetIndex);
	setTextFade(action.m_startAlpha, action.m_targetIndex);
}
Пример #4
0
void CGame::interpView ()
{
	CVector3 viewPos, viewCtr;
	CVector3 destPos(3, 40, 3);
	CVector3 sourcePos(m_tolleyPos.x + m_tolleyForward.x*10 , 5, m_tolleyPos.z + m_tolleyForward.z*10);
	if (m_viewInterp < 1) {
	m_viewInterp+=m_deltaT;
	viewPos =  sourcePos *(1-m_viewInterp) + destPos * m_viewInterp;
	viewCtr =  m_aimPos *(1-m_viewInterp)  + m_tolleyPos * m_viewInterp;
	} else {
	viewCtr = m_tolleyPos;
	viewPos = destPos;//CCamera::Instance().LookAt( 3, 20, 3, 0, 0, 0, 0, 1, 0 );
	}
	CCamera::Instance().LookAt(viewPos.x, viewPos.y, viewPos.z,
							   viewCtr.x, viewCtr.y, viewCtr.z,
							   0, 1, 0);
}
Пример #5
0
void DirtyAreas::copy(MSurface *srcSurface, MSurface *destSurface, const Common::Point &posAdjust) {
	for (uint i = 0; i < size(); ++i) {
		const Common::Rect &srcBounds = (*this)[i]._bounds;

		// Check if this is a sane rectangle before attempting to create it
		if (srcBounds.left >= srcBounds.right || srcBounds.top >= srcBounds.bottom)
			continue;

		Common::Rect bounds(srcBounds.left + posAdjust.x, srcBounds.top + posAdjust.y,
			srcBounds.right + posAdjust.x, srcBounds.bottom + posAdjust.y);
		Common::Point destPos(bounds.left, bounds.top);

		if ((*this)[i]._active && bounds.isValidRect()) {
			srcSurface->copyTo(destSurface, bounds, destPos);
		}
	}
}
Пример #6
0
CFPos CMemberAI::GetSelfCorrectPos()
{
    CFPos destPos(0.0f,0.0f);
    CDummyAI* pDummyAI = GetGroupLeaderDummyAI();
    if (!pDummyAI)
        return destPos;
    CFPos dummyPos;
    pDummyAI->GetCharacter()->GetPixelPos(dummyPos);
    uint uSubDir = pDummyAI->GetCharacter()->GetActionDir();
    float newdir = (float)((float)uSubDir/255.0f * TWO_PI);

    if(pDummyAI->m_eMoveType == ENpcMove_Trip && !pDummyAI->m_bMoveDir && pDummyAI->m_uCurrentPoint != pDummyAI->m_mapMovePath.size())
        destPos = pDummyAI->ChangeLocalPosToWorldPos(dummyPos,m_LocalMirrorPos,newdir);
    else if(pDummyAI->m_eMoveType == ENpcMove_Trip && pDummyAI->m_bMoveDir && pDummyAI->m_uCurrentPoint == 1)
        destPos = pDummyAI->ChangeLocalPosToWorldPos(dummyPos,m_LocalMirrorPos,newdir);
    else
        destPos = pDummyAI->ChangeLocalPosToWorldPos(dummyPos,m_LocalPos,newdir);
    return destPos;
}
// CraterParticle2D
//---------------------------------------------------------------------------
CraterParticle2D::CraterParticle2D(const fXYZ  &pos) : Particle2D(pos)
{
    packedSurface.setData(staticPackedCrater);

    packedSurface.setDrawModeSolid();

    packedSurface.setFrame(rand() % staticPackedCrater.getFrameCount());

    // Check to see if this is valid crater ground.

    // Check the crater cache for a hit.
    iXY destPos((int) pos.x, (int) pos.z);

    for (int i = 0; i < craterCache.getCount(); i++) {
        if (craterCache[i].bounds.contains(destPos)) {
            // Since a crater already exists near this point, do not add another.
            isAlive = false;

            cacheHitCount++;

            //ConsoleInterface::postMessage("Crater Cache Hit");
        }
    }

    // If there was a cache miss, add the crater location to the cache.
    if (isAlive) {
        cacheMissCount++;

        craterCache[curCraterIndex].bounds = iRect(destPos.x - halfBoundsSize, destPos.y - halfBoundsSize, destPos.x + halfBoundsSize, destPos.y + halfBoundsSize);
        craterCache[curCraterIndex].pos    = destPos;

        // Save the cache position.
        cacheIndex = curCraterIndex;

        if (++curCraterIndex >= craterCache.getCount()) {
            curCraterIndex = 0;
        }

        lifetime = 60.0f * float((rand() % 4) + 2);
    }

} // end CraterParticle2D::CraterParticle2D
Пример #8
0
wxBitmap* DialogReplacePiece::PackImage(const wxSize& bmpSize, const TV_PACKING_PIECE_INFO& vPackingInfo)
{
	wxBitmap* pNewBitmap = new wxBitmap(bmpSize);
	pNewBitmap->UseAlpha();

	wxMemoryDC memDC(*pNewBitmap);
	wxGCDC dc(memDC);

	dc.SetBackground(*wxTRANSPARENT_BRUSH);
	dc.Clear();

	for (TV_PACKING_PIECE_INFO::const_iterator it = vPackingInfo.begin(); it != vPackingInfo.end(); ++it)
	{
		const PACKING_PIECE_INFO* pPackingInfo = (*it);
		wxPoint destPos(pPackingInfo->pNode->x, pPackingInfo->pNode->y);

		wxBitmap& subBitmap = (wxBitmap)pPackingInfo->subBitmap;
		wxMemoryDC memSubDC(subBitmap);
		dc.Blit(destPos, pPackingInfo->subBitmap.GetSize(), &memSubDC, wxPoint(0, 0));
	}

	return pNewBitmap;
}
Пример #9
0
Pathway PathwayHelper::randomWay(CityPtr city, TilePos startPos, int walkRadius)
{
    int loopCounter = 0; //loop limiter
    do
    {
        const Tilemap& tmap = city->getTilemap();

        TilePos destPos( std::rand() % walkRadius - walkRadius / 2, std::rand() % walkRadius - walkRadius / 2 );
        destPos = (startPos+destPos).fit( TilePos( 0, 0 ), TilePos( tmap.getSize()-1, tmap.getSize()-1 ) );

        if( tmap.at( destPos ).isWalkable( true) )
        {
            Pathway pathway = create( city, startPos, destPos, PathwayHelper::allTerrain );

            if( pathway.isValid() )
            {
                return pathway;
            }
        }
    }
    while( ++loopCounter < 20 );

    return Pathway();
}
Пример #10
0
void SequenceManager::signal() {
	if (g_globals->_sceneObjects->contains(&_sceneText))
		_sceneText.hide();

	bool continueFlag = true;
	while (continueFlag) {
		if (_sequenceOffset >=_sequenceData.size()) {
			// Reached the end of the sequence
			if (!_keepActive)
				remove();
			break;
		}

		uint16 idx = static_cast<uint16>(getNextValue() - 32000);

		int16 v1, v2, v3;
		switch (idx) {
		case 0:
			// Stop sequence
			continueFlag = false;
			break;
		case 1:
			_sceneObject->animate(ANIM_MODE_1, NULL);
			break;
		case 2:
			_sceneObject->animate(ANIM_MODE_2, NULL);
			break;
		case 3:
			_sceneObject->animate(ANIM_MODE_3);
			break;
		case 4:
			v1 = getNextValue();
			v2 = getNextValue();
			_sceneObject->animate(ANIM_MODE_8, v1, v2 ? this : NULL);
			break;
		case 5:
			v1 = getNextValue();
			v2 = getNextValue();
			_sceneObject->animate(ANIM_MODE_7, v1, v2 ? this : NULL);
			break;
		case 6:
			v2 = getNextValue();
			_sceneObject->animate(ANIM_MODE_5, v2 ? this : NULL);
			break;
		case 7:
			v2 = getNextValue();
			_sceneObject->animate(ANIM_MODE_6, v2 ? this : NULL);
			break;
		case 8:
			v1 = getNextValue();
			v3 = getNextValue();
			v2 = getNextValue();
			_sceneObject->animate(ANIM_MODE_4, v1, v3, v2 ? this : NULL);
			break;
		case 9:
			v1 = getNextValue();
			v3 = getNextValue();
			v2 = getNextValue();
			g_globals->_sceneManager._scene->_sceneBounds.moveTo(v3, v2);
			g_globals->_sceneManager._scene->loadScene(v1);
			break;
		case 10: {
			int resNum= getNextValue();
			int lineNum = getNextValue();
			int color = getNextValue();
			int xp = getNextValue();
			int yp = getNextValue();
			int width = getNextValue();
			setMessage(resNum, lineNum, color, Common::Point(xp, yp), width);
			break;
		}
		case 11:
			v1 = getNextValue();
			v2 = getNextValue();
			setAction(globalManager(), v2 ? this : NULL, v1, _objectList[0], _objectList[1], _objectList[2], _objectList[3], NULL);
			break;
		case 12:
			v1 = getNextValue();
			setDelay(v1);
			break;
		case 13: {
			v1 = getNextValue();
			v3 = getNextValue();
			v2 = getNextValue();
			NpcMover *mover = new NpcMover();
			Common::Point destPos(v1, v3);
			_sceneObject->addMover(mover, &destPos, v2 ? this : NULL);
			break;
		}
		case 14:
			v1 = getNextValue();
			_sceneObject->_numFrames = v1;
			break;
		case 15:
			v1 = getNextValue();
			_sceneObject->_moveRate = v1;
			break;
		case 16:
			v1 = getNextValue();
			v2 = getNextValue();
			_sceneObject->_moveDiff = Common::Point(v1, v2);
			break;
		case 17:
			_sceneObject->hide();
			break;
		case 18:
			_sceneObject->show();
			break;
		case 19:
			v1 = getNextValue();
			_sceneObject->setVisage(v1);
			break;
		case 20:
			v1 = getNextValue();
			_sceneObject->setStrip(v1);
			break;
		case 21:
			v1 = getNextValue();
			_sceneObject->setFrame(v1);
			break;
		case 22:
			v1 = getNextValue();
			_sceneObject->fixPriority(v1);
			break;
		case 23:
			v1 = getNextValue();
			_sceneObject->changeZoom(v1);
			break;
		case 24:
			v1 = getNextValue();
			v2 = getNextValue();
			v3 = getNextValue();
			_sceneObject->setPosition(Common::Point(v1, v2), v3);
			break;
		case 25: {
			int yStart = getNextValue();
			int minPercent = getNextValue();
			int yEnd = getNextValue();
			int maxPercent = getNextValue();
			g_globals->_sceneManager._scene->setZoomPercents(yStart, minPercent, yEnd, maxPercent);
			break;
		}
		case 26:
			v1 = getNextValue();
			v2 = getNextValue();
			_soundHandler.play(v1, v2 ? this : NULL, 127);
			break;
		case 27: {
			v1 = getNextValue();
			v3 = getNextValue();
			v2 = getNextValue();
			PlayerMover *mover = new PlayerMover();
			Common::Point destPos(v1, v3);
			_sceneObject->addMover(mover, &destPos, v2 ? this : NULL);
			break;
		}
		case 28:
			_objectIndex = getNextValue();
			assert((_objectIndex >= 0) && (_objectIndex < 6));
			_sceneObject = _objectList[_objectIndex];
			assert(_sceneObject);
			break;
		case 29:
			_sceneObject->animate(ANIM_MODE_NONE);
			break;
		case 30:
			v1 = getNextValue();
			g_globals->_scrollFollower = (v1 == -1) ? NULL : _objectList[v1];
			break;
		case 31:
			_sceneObject->setObjectWrapper(new SceneObjectWrapper());
			break;
		case 32:
			_sceneObject->setObjectWrapper(NULL);
			break;
		case 33:
			v1 = getNextValue();
			if (_keepActive)
				setDelay(1);
			else {
				_sceneText.remove();
				g_globals->_sceneManager._scene->_stripManager.start(v1, this);
			}
			break;
		case 34: {
			v1 = getNextValue();
			v2 = getNextValue();
			int objIndex1 = getNextValue() - 1;
			int objIndex2 = getNextValue() - 1;
			int objIndex3 = getNextValue() - 1;
			int objIndex4 = getNextValue() - 1;
			int objIndex5 = getNextValue() - 1;
			int objIndex6 = getNextValue() - 1;

			setAction(globalManager(), v2 ? this : NULL, v1, _objectList[objIndex1], _objectList[objIndex2],
				_objectList[objIndex3], _objectList[objIndex4], _objectList[objIndex5], _objectList[objIndex6], NULL);
			break;
		}
		/* Following indexes were introduced for Blue Force */
		case 35:
			v1 = getNextValue();
			_sceneObject->updateAngle(_objectList[v1]->_position);
			break;
		case 36:
			_sceneObject->animate(ANIM_MODE_9, NULL);
			break;
		case 37:
			v1 = getNextValue();
			v2 = getNextValue();
			if (_onCallback)
				_onCallback(v1, v2);
			break;
		case 38: {
			int resNum = getNextValue();
			int lineNum = getNextValue();
			int fontNum = getNextValue();
			int color1 = getNextValue();
			int color2 = getNextValue();
			int color3 = getNextValue();
			int xp = getNextValue();
			int yp = getNextValue();
			int width = getNextValue();
			setMessage(resNum, lineNum, fontNum, color1, color2, color3, Common::Point(xp, yp), width);
			break;
		}
		default:
			error("SequenceManager::signal - Unknown action %d at offset %xh", idx, _sequenceOffset - 2);
			break;
		}
	}
}
Пример #11
0
void CppiaStackVar::genDefault(CppiaCompiler *compiler, const CppiaConst &inDefault)
{
   if (argType==etString)
   {
      if (inDefault.type == CppiaConst::cString)
      {
         JumpId notNull = compiler->compare(cmpP_NOT_ZERO, JitFramePos(defaultStackPos+offsetof(String,__s)).as(jtPointer),(void *)0);
         String val = module->strings[ inDefault.ival ];
         compiler->move(JitFramePos(defaultStackPos).as(jtInt), (int)val.length);
         compiler->move(JitFramePos(defaultStackPos+offsetof(String,__s)).as(jtPointer), (void *)val.__s);
         compiler->comeFrom(notNull);
      }
   }
   else
   {
      JitFramePos srcPos(defaultStackPos);
      JitFramePos destPos(stackPos);
      compiler->move( sJitTemp0, srcPos.as(jtPointer) );
      JumpId notNull = compiler->compare(cmpP_NOT_ZERO, sJitTemp0, (void *)0);

      switch(storeType)
      {
         case fsByte:
         case fsBool: 
            compiler->move( destPos.as(jtByte), JitVal(inDefault.ival).as(jtByte));
            break;

         case fsInt:
            compiler->move( destPos.as(jtInt), inDefault.ival);
             break;
         case fsFloat:
            compiler->move( sJitTemp0, (void *)&inDefault.dval);
            compiler->move( destPos.as(jtFloat), sJitTemp0.star(jtFloat));
            break;
         case fsObject:
            if (inDefault.type==CppiaConst::cInt)
               compiler->callNative( (void *)intToObject, inDefault.ival );
            else if (inDefault.type==CppiaConst::cFloat)
               compiler->callNative( (void *)floatToObject, (void *)&inDefault.dval );
            else if (inDefault.type==CppiaConst::cString)
               compiler->callNative( (void *)stringToObject, (void *)&module->strings[ inDefault.ival ] );
            else
               break;
            compiler->move(destPos.as(jtPointer), sJitReturnReg.as(jtPointer));
            break;
         case fsString: // handled
         case fsUnknown: // ?
            break;
      }

      JumpId defaultDone = compiler->jump();
      compiler->comeFrom(notNull);

      switch(storeType)
      {
         case fsByte:
         case fsBool: 
            compiler->callNative( (void *)objToInt, sJitTemp0.as(jtPointer) );
            //compiler->move( destPos.as(jtByte), sJitReturnReg.as(jtByte));
            compiler->move( destPos.as(jtInt), sJitReturnReg.as(jtInt));
            break;

         case fsInt:
            compiler->callNative( (void *)objToInt, sJitTemp0.as(jtPointer) );
            compiler->move( destPos.as(jtInt), sJitReturnReg.as(jtInt));
             break;
         case fsFloat:
            compiler->callNative( (void *)objToFloat, sJitTemp0.as(jtPointer), destPos.as(jtFloat)) ;
            break;
         case fsObject:
            // Should be same pos
            //compiler->move(destPos.as(jtPointer), sJitTemp0.as(jtPointer));
            break;
         case fsString: // handled
         case fsUnknown: // ?
            break;
      }

      compiler->comeFrom(defaultDone);
   }

}
Пример #12
0
//-------------------------------------------------------------------------------------
bool MoveToPointHandler::update()
{
	if(pController_ == NULL)
	{
		delete this;
		return false;
	}
	
	Entity* pEntity = pController_->pEntity();
	const Position3D& dstPos = destPos();
	Position3D currpos = pEntity->getPosition();
	Direction3D direction = pEntity->getDirection();

	Vector3 movement = dstPos - currpos;
	if (!moveVertically_) movement.y = 0.f;
	
	bool ret = true;

	if(KBEVec3Length(&movement) < velocity_ + range_)
	{
		float y = currpos.y;
		currpos = dstPos;

		if(range_ > 0.0f)
		{
			// 单位化向量
			KBEVec3Normalize(&movement, &movement); 
			movement *= range_;
			currpos -= movement;
		}

		if (!moveVertically_)
			currpos.y = y;

		ret = false;
	}
	else
	{
		// 单位化向量
		KBEVec3Normalize(&movement, &movement); 

		// 移动位置
		movement *= velocity_;
		currpos += movement;
	}
	
	// 是否需要改变面向
	if (faceMovement_ && (movement.x != 0.f || movement.z != 0.f))
		direction.yaw(movement.yaw());
	
	// 设置entity的新位置和面向
	if(pController_)
		pEntity->setPositionAndDirection(currpos, direction);

	// 非navigate都不能确定其在地面上
	if(pController_)
		pEntity->isOnGround(isOnGround());

	// 通知脚本
	if(pController_)
		pEntity->onMove(pController_->id(), pyuserarg_);

	// 如果达到目的地则返回true
	if(!ret)
	{
		return !requestMoveOver();
	}

	return true;
}
Пример #13
0
//-------------------------------------------------------------------------------------
bool MoveToPointHandler::update(TimerHandle& handle)
{
	if(pEntity_ == NULL)
	{
		handle.cancel();
		return false;
	}
	
	Entity* pEntity = pEntity_;
	const Position3D& dstPos = destPos();
	Position3D currpos = pEntity->position();
	Position3D currpos_backup = currpos;
	Direction3D direction = pEntity->direction();

	Vector3 movement = dstPos - currpos;
	if (!moveVertically_) movement.y = 0.f;
	
	bool ret = true;

	if(KBEVec3Length(&movement) < velocity_ + distance_)
	{
		float y = currpos.y;
		currpos = dstPos;

		if(distance_ > 0.0f)
		{
			// 单位化向量
			KBEVec3Normalize(&movement, &movement); 
			movement *= distance_;
			currpos -= movement;
		}

		if (!moveVertically_)
			currpos.y = y;

		ret = false;
	}
	else
	{
		// 单位化向量
		KBEVec3Normalize(&movement, &movement); 

		// 移动位置
		movement *= velocity_;
		currpos += movement;
	}
	
	// 是否需要改变面向
	if (faceMovement_ && (movement.x != 0.f || movement.z != 0.f))
		direction.yaw(movement.yaw());
	
	// 设置entity的新位置和面向
	pEntity_->position(currpos);
	pEntity_->direction(direction);

	// 非navigate都不能确定其在地面上
	pEntity_->isOnGound(false);

	// 通知脚本
	pEntity->onMove(scriptCallbacks_.getIDForHandle(handle), layer_, currpos_backup, pyuserarg_);

	// 如果达到目的地则返回true
	if(!ret)
	{
		return !requestMoveOver(handle, currpos_backup);
	}

	return true;
}
Пример #14
0
ff::RectInt OptimizedTextureInfo::FindPlacement(ff::PointInt size)
{
	ff::PointInt destPos(-1, -1);

	if (size.x > 0 && size.x <= _size.x &&
		size.y > 0 && size.y <= _size.y)
	{
		ff::PointInt cellSize(
			(size.x + s_gridSize - 1) / s_gridSize,
			(size.y + s_gridSize - 1) / s_gridSize);

		for (int y = 0; y + cellSize.y <= _size.y / s_gridSize; y++)
		{
			for (int attempt = 0; attempt < 2; attempt++)
			{
				// Try to put the sprite as far left as possible in each row
				int x;
				
				if (attempt)
				{
					x = _rowRight[y];

					if (x)
					{
						// don't touch the previous sprite
						x++;
					}
				}
				else
				{
					x = _rowLeft[y];
					x -= cellSize.x + 1;
				}

				if (x >= 0 && x + cellSize.x <= _size.x / s_gridSize)
				{
					bool found = true;

					// Look for intersection with another sprite
					for (int checkY = y + cellSize.y; checkY >= y - 1; checkY--)
					{
						if (checkY >= 0 &&
							checkY < _size.y / s_gridSize &&
							checkY < _countof(_rowRight) &&
							_rowRight[checkY] &&
							_rowRight[checkY] + 1 > x &&
							x + cellSize.x + 1 > _rowLeft[checkY])
						{
							found = false;
							break;
						}
					}

					// Prefer positions further to the left
					if (found && (destPos.x == -1 || destPos.x > x * s_gridSize))
					{
						destPos.SetPoint(x * s_gridSize, y * s_gridSize);
					}
				}
			}
		}
	}

	return (destPos.x == -1)
		? ff::RectInt(0, 0, 0, 0)
		: ff::RectInt(destPos.x, destPos.y, destPos.x + size.x, destPos.y + size.y);
}