void CCameraSceneNode::recalculateViewArea()
{
	ViewArea.cameraPosition = getAbsolutePosition();
	ViewArea.setFrom ( ViewArea.Matrices [ SViewFrustum::ETS_VIEW_PROJECTION_3 ] );
/*
	video::IVideoDriver* driver = SceneManager->getVideoDriver();
	if ( driver)
	{
		driver->setTransform(video::ETS_PROJECTION, ViewArea.Matrices [ video::ETS_PROJECTION ] );
		driver->setTransform(video::ETS_VIEW, ViewArea.Matrices [ video::ETS_VIEW ] );
	}
*/
}
Beispiel #2
0
void eVideoWidget::updatePosition(int disable)
{
    if (!disable)
        m_state |= 4;

    if (disable && !(m_state & 4))
    {
        return;
    }

    if ((m_state & 2) != 2)
    {
        return;
    }

    eRect pos(0,0,0,0);
    if (!disable)
        pos = eRect(getAbsolutePosition(), size());
    else
        m_state &= ~4;

    if (!disable && m_state & 8 && pos == m_user_rect)
    {
        return;
    }

    if (!(m_state & 1))
    {
        m_user_rect = pos;
        m_state |= 1;
    }

    int left = pos.left() * 720 / m_fb_size.width();
    int top = pos.top() * 576 / m_fb_size.height();
    int width = pos.width() * 720 / m_fb_size.width();
    int height = pos.height() * 576 / m_fb_size.height();

    if (!disable)
    {
        setPosition(m_decoder, left, top, width, height);
        pendingFullsize &= ~(1 << m_decoder);
        m_state |= 8;
    }
    else
    {
        m_state &= ~8;
        pendingFullsize |= (1 << m_decoder);
        fullsizeTimer->start(100, true);
    }
}
Beispiel #3
0
// this should be renamed moveAbsoluteDistance
void Object::moveAbsoluteDistance(Vector2 delta)
{
    m_physicsObject->SetTransform( (getAbsolutePosition() + delta).toBulletVector() , m_physicsObject->GetAngle() );

    // set position and target positions for children objects
    for (unsigned i = 0; i < m_children.size(); ++i)
    {
        Object* child = m_children.at(i);
        if (!child->m_independent)
        {
            child->moveAbsoluteDistance(delta);
        }
    }
}
Beispiel #4
0
gPainter *eWidget::getPainter(eRect area)
{
	eRect myclip=eRect(getAbsolutePosition(), size);
	if (parent)
		myclip&=parent->clientclip;

	eWidget *r=this;
	while (r && r->parent && !r->target)
		r = r->parent;

	ASSERT(r);
//	ASSERT(r->target);
	if (!r->target)	// if target is 0, device is locked.
		return 0;

	gPainter *p=new gPainter(*r->target, myclip);
	p->setLogicalZero(getAbsolutePosition());
	if (!area.isNull())
		p->clip(area);
	p->setForegroundColor(foregroundColor);
	p->setBackgroundColor(backgroundColor);
	return p;
}
Beispiel #5
0
void Slider::render()
{
	if (m_visible)
	{
		Vector2 pos = getAbsolutePosition();
		float selectorPos = ((m_barSize - m_imgSelector->GetWidth()) * m_actualValue / m_maxValue); //calculamos en el que posicion se pinta la imagen del selector

		//barrita en posicion... x: tamaño del boton + espaciado + posicion global / y: posicion absoluta + mitad tamaño imagen del boton - mitad imagen de la propia barrita
		Renderer::Instance().DrawTiledImage(m_imgBar, m_btnLeft->getSize().x + pos.x + m_spaceControls, pos.y + (m_btnLeft->getSize().y / 2) - (m_imgBar->GetHeight() / 2), m_barSize ,m_imgBar->GetHeight());	
		//selector en posicion... x: tamaño del boton + espaciado + posicion calculada / y: posicion absoluta + mitad tamaño imagen del boton - mitad imagen del selector
		Renderer::Instance().DrawImage(m_imgSelector,pos.x + m_btnLeft->getSize().x + m_spaceControls + selectorPos , pos.y + (m_btnLeft->getSize().y / 2) - (m_imgSelector->GetHeight() / 2));
	}
	
}
Beispiel #6
0
// --- is called upon creation ---
void CLensFlareSceneNode::OnRegisterSceneNode() {
    if(IsVisible) {
        core::position2d<s32> pm = SceneManager->
			getSceneCollisionManager()->
			getScreenCoordinatesFrom3DPosition(
			getAbsolutePosition(),
				SceneManager->getActiveCamera() );

        if(core::rect<s32>(core::position2d<s32>(0,0), screensize).isPointInside(pm)) {
            SceneManager->registerNodeForRendering(this, scene::ESNRP_TRANSPARENT);

            ISceneNode::OnRegisterSceneNode();
        }
    }
}
// QC:P
void GLFramebuffer::renderGraphics() {
#ifdef GPU_IMAGEPROCESS
	if(oglShadersSupport && !mipmaps) {
		OGLImageProcess* process = (OGLImageProcess*) objectEffects.getPostProcess();
		if(process && process->use_mipmaps) {
			glBindTexture(GL_TEXTURE_2D, textureSlots[0]);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 6);
			glGenerateMipmapEXT(GL_TEXTURE_2D);
			mipmaps = true;
		}
	}
#endif

	glEngine->drawWithProcessing(textureSlots, width, height, getAbsolutePosition(), getFinalEffects());
}
Beispiel #8
0
void Popup::setLocationRelativeTo(gcn::Widget *widget)
{
    if (!widget)
        return;

    int wx, wy;
    int x, y;

    widget->getAbsolutePosition(wx, wy);
    getAbsolutePosition(x, y);

    setPosition(getX() + (wx + (widget->getWidth() - getWidth()) / 2 - x),
                getY() + (wy + (widget->getHeight() - getHeight()) / 2 - y));
    mRedraw = true;
}
void VesselSceneNode::snap(OrbiterDockingPort& ourPort, OrbiterDockingPort& theirPort)
{

	ISceneNode* ourNode = ourPort.portNode;
	ISceneNode* theirNode = theirPort.portNode;

	theirNode->updateAbsolutePosition();
	ourNode->updateAbsolutePosition();

	//absolute rotation of the target port
	core::matrix4 theirMatrix = theirNode->getAbsoluteTransformation();

	//Origin up and facing (inversed) of the target port
	core::vector3df theirDir = core::vector3df(0, 0, -1);
	core::vector3df theirRot = core::vector3df(0, 1, 0);

	//get absolute inversed facing and up direction of the target port
	theirMatrix.rotateVect(theirDir);
	theirMatrix.rotateVect(theirRot);
	theirDir.normalize();
	theirRot.normalize();

	//build rotation matrix to rotate from the ORIGIN of the source port to their ports current alignement
	core::matrix4 ourPortToTheirPort;
	ourPortToTheirPort.buildCameraLookAtMatrixLH(core::vector3df(0, 0, 0), theirDir, theirRot).makeInverse();

	//get inverted source port rotation relative to its vessel
	core::matrix4 ourVesselToOurPort = ourNode->getRelativeTransformation();
	ourVesselToOurPort.makeInverse();

	//multiply the rotation from our vessel origin to our port and from our port origin to the target to get the total transformation for the vessel
	core::matrix4 ourVesselToTheirPort = ourPortToTheirPort * ourVesselToOurPort;

	//apply the whole brouhaha
	setRotation(ourVesselToTheirPort.getRotationDegrees());

	//we MUST update positions for getAbsolutePosition to reflect the rotation we just did.
	//also, we MUST update the position of the parent before the child, or the child still won't reflect the changes
	//we also MUST update the child seperately, it doesn't get updated by the parent
	updateAbsolutePosition();
	ourNode->updateAbsolutePosition();

	//position the vessel so the docking ports touch
	core::vector3df pos = ourNode->getAbsolutePosition() - getAbsolutePosition();
	setPosition(theirNode->getAbsolutePosition() - pos);
	//update the new position, in case there's a vessel being snapped to this right next
	updateAbsolutePosition();				
}
Beispiel #10
0
void Object::syncWithParent()
{
    float   deltaRotation = m_parent->getAbsoluteRotation() - parentPrimalRotation;
    Vector2 deltaPosition = m_parent->getAbsolutePosition() - parentPrimalPosition;

    setAbsoluteRotation(getAbsoluteRotation() + deltaRotation);

    // the rotation will affect the position
    Vector2 rotatedPosition = getAbsolutePosition() + deltaPosition;
    rotatedPosition.rotateAround(deltaRotation,m_parent->getAbsolutePosition());

    setAbsolutePosition(rotatedPosition);

    parentPrimalRotation = m_parent->getAbsoluteRotation();
    parentPrimalPosition = m_parent->getAbsolutePosition();
}
Beispiel #11
0
void Player::shootPlayer()
{
    float percent = power / 100.f;
    float speed = maxSpeed * percent;
    currentSpeed = speed;

    Vector2 vel(maxSpeed,0);
    vel.rotate(angle);
    vel.setMagnitude(speed);

    setLinearVelocity(vel);
    trail.addPoint( getAbsolutePosition() );
    trail.length = MAX_TAIL_LENGTH * (vel.getMagnitude() / maxSpeed);

    gdata.audio->playSound("shoot",true);
}
Beispiel #12
0
void Label::display(void) {
   static FontTahoma *font = FontTahoma::getInstance();
   static ComponentTexture *cTexture = font->getTexture();
   static ColorScheme *scheme = ColorScheme::getInstance();

   int strLength = 0;
   Point currPosition = getAbsolutePosition();

   cTexture->enable();
   scheme->applyColor(ColorScheme::FONT);
   for (int i = 0; i < getString().size(); i++) {
      cTexture->display(currPosition.x + strLength, currPosition.y, getString()[i] * font->getWidth(), 0, 8, 15);
      strLength += font->getCharWidth(getString()[i]);
   }
   cTexture->disable();
}
Beispiel #13
0
void Label::render()
{
	if (m_visible)
	{
		Vector2 pos = getAbsolutePosition();
		String text = String(m_text.c_str());
	
		if (!m_pushed)
			Renderer::Instance().SetColor(m_r, m_g, m_b, 255);
		else
			Renderer::Instance().SetColor((uint8)WrapValue (m_r - 50,255), (uint8)WrapValue (m_g - 50,255), (uint8)WrapValue (m_b - 50,255), 255);
	
		m_font->Render(text,pos.x, pos.y);
		Renderer::Instance().SetColor(255, 255, 255, 255);
	}
}
Beispiel #14
0
void Button::display(void) {
   static Kernel *kernel = Kernel::getInstance();
   static Scissor *scissor = Scissor::getInstance();
   static ColorScheme *scheme = ColorScheme::getInstance();
   static FontFreeType *freeType = FontFreeType::getInstance();

   if (_cTexture == NULL || _isVisible == false) return;

   Point currPosition = getAbsolutePosition();

   _cTexture->enable();
      scheme->applyColor(ColorScheme::MAINCOMPONENTS);
      // middle
      _cTexture->display(currPosition.x + 1, currPosition.y + 1, 4, getWidth() - 2, getHeight() - 2);

      if (isHolded()) {
         scheme->applyColor(ColorScheme::HOLDCOMPONENTS);
         _cTexture->display(currPosition.x + 1, currPosition.y + 1, 6, getWidth() - 2, getHeight() - 2);
      } else if (isOvered()) {
         scheme->applyColor(ColorScheme::OVERCOMPONENTS);
         _cTexture->display(currPosition.x + 1, currPosition.y + 1, 5, getWidth() - 2, getHeight() - 2);
      }

      scheme->applyColor(ColorScheme::MAINCOMPONENTS);
      // horizontal lines
      _cTexture->display(currPosition.x + 2, currPosition.y, 7, getWidth() - 4, 2);
      _cTexture->display(currPosition.x + 2, currPosition.y + getHeight() - 2, 8, getWidth() - 4, 2);

      // vertical lines
      _cTexture->display(currPosition.x, currPosition.y + 2, 9, 2, getHeight() - 4);
      _cTexture->display(currPosition.x + getWidth() - 2, currPosition.y + 2, 10, 2, getHeight() - 4);

      // corners
      _cTexture->display(currPosition, 0);
      _cTexture->display(currPosition.x + getWidth() - 3, currPosition.y, 1);
      _cTexture->display(currPosition.x, currPosition.y + getHeight()- 3, 2);
      _cTexture->display(currPosition.x + getWidth() - 3, currPosition.y + getHeight() - 3, 3);

   _cTexture->disable();

   scissor->pushScissor(Scissor::Info(currPosition.x + 3, kernel->getHeight() - (getHeight() + currPosition.y), getWidth() - 6, getHeight()));

   StaticLabel::display(currPosition.x + getWidth() / 2 - freeType->getStringLength(Label::getString()) / 2 , currPosition.y + getHeight() / 2 - 6, Label::getString());

   scissor->popScissor();
}
Beispiel #15
0
 void Circle::render()
 {
     bool retina = Manager::instance().isRetinaDisplay();
     Vec2f absolute = getAbsolutePosition();
     absolute = native::worldToGLPixels(absolute);
     
     prerender();
     assert(_positions.submit());
     
     glUniform2f(_centerUniformLocation, absolute.x, absolute.y);
     glUniform1f(_radiusUniformLocation, retina ? _radius * 2.0 : _radius);
     glUniform1f(_edgeWidthUniformLocation, retina ? edgeWidth * 2.0 : edgeWidth);
     glUniform4f(_fillColorUniformLocation, fill.r, fill.g, fill.b, fill.a);
     glUniform4f(_edgeColorUniformLocation, edge.r, edge.g, edge.b, edge.a);
     
     glDrawArrays(GL_TRIANGLE_STRIP, 0, _positions.getCount());
 }
Beispiel #16
0
void Object::rotate(float angle)
{
    float rot = getRotation();
    float fullAngle = (rot + angle);

    setRotation(fullAngle);

    for (unsigned i = 0; i < m_children.size(); ++i)
    {
        Object* child = m_children.at(i);

        if (!child->m_independent)
        {
            if (!child->m_lockRotation) {child->rotate(angle);}
            if (!child->m_lockPosition) {child->rotateAround(angle,getAbsolutePosition());}
        }
    }
}
Beispiel #17
0
void Slider::render()
{
	if( isVisible() )
	{
		if( !isEnabled() )
		{
			int x =1;
		}
		else
		{
			Vector2 pos = getAbsolutePosition();

			Renderer::Instance().SetBlendMode( Renderer::BlendMode::ALPHA );
			Renderer::Instance().DrawImage( m_bar, pos.x, pos.y );

		}
	}
}
Beispiel #18
0
void Object::addChild(Object* child)
{
    if (child->m_physicsObject->GetType() != b2_dynamicBody)
    {
        bool alreadyChild = false;
        for (unsigned i = 0; i < m_children.size(); ++i)
        {
            Object* object = m_children.at(i);
            if (object == child) {alreadyChild = true;}
        }

        if (!alreadyChild)
        {
            child->m_parent = this;
            m_children.push_back(child);

            child->parentPrimalRotation = getAbsoluteRotation();
            child->parentPrimalPosition = getAbsolutePosition();
        }
    }
}
Beispiel #19
0
void Window::widgetShown(const gcn::Event& event)
{
    mVisible = true;

    requestMoveToTop();
    requestFocus();

    int widgetX, widgetY;
    getAbsolutePosition(widgetX, widgetY);

    widgetX = gui->getMouseX() - widgetX;
    widgetY = gui->getMouseY() - widgetY;

    if (getChildrenArea().isPointInRect(widgetX, widgetY))
    {
        gcn::MouseEvent mouseEvent(this, false, false, false, false,
                                   gcn::MouseEvent::MOVED, 0, widgetX, widgetY, 0);

        mouseMoved(mouseEvent);
    }
}
void CLightSceneNode::doLightRecalc()
{
	if ((LightData.Type == video::ELT_SPOT) || (LightData.Type == video::ELT_DIRECTIONAL))
	{
		LightData.Direction = core::vector3df(.0f,.0f,1.0f);
		getAbsoluteTransformation().rotateVect(LightData.Direction);
		LightData.Direction.normalize();
	}
	if ((LightData.Type == video::ELT_SPOT) || (LightData.Type == video::ELT_POINT))
	{
		const f32 r = LightData.Radius * LightData.Radius * 0.5f;
		BBox.MaxEdge.set( r, r, r );
		BBox.MinEdge.set( -r, -r, -r );
		setAutomaticCulling( scene::EAC_BOX );
		LightData.Position = getAbsolutePosition();
	}
	if (LightData.Type == video::ELT_DIRECTIONAL)
	{
		BBox.reset( 0, 0, 0 );
		setAutomaticCulling( scene::EAC_OFF );
	}
}
//! update
void CCameraSceneNode::updateMatrices()
{
	core::vector3df pos = getAbsolutePosition();
	core::vector3df tgtv = Target - pos;
	tgtv.normalize();

	// if upvector and vector to the target are the same, we have a
	// problem. so solve this problem:
	core::vector3df up = UpVector;
	up.normalize();

	f32 dp = tgtv.dotProduct(up);

	if ( core::equals(core::abs_<f32>(dp), 1.f) )
	{
		up.X += 0.5f;
	}

	ViewArea.getTransform(video::ETS_VIEW).buildCameraLookAtMatrixLH(pos, Target, up);
	ViewArea.getTransform(video::ETS_VIEW) *= Affector;
	recalculateViewArea();
}
Beispiel #22
0
void Player::onEnterCollision(CollisionData cd)
{

    if (cd.points.size() > 0)
    {
        if (cd.objectB->m_type != PARTICLE)
        {
            if (m_type != GHOST_PLAYER) {++gdata.bounce_counter;}
            emitter.spawn = true;
            emitter.pos = cd.points.at(0);
            trail.addPoint(getAbsolutePosition());

            if (gdata.bounce_counter == 100 && !gdata.replay_level)
            {
                AchievementBar* a = new AchievementBar;
                a->init();
                a->setText("Get 100 bounces in any level");
                gdata.achieves.push_back(a);
            }
        }
    }
}
Beispiel #23
0
void Window::widgetHidden(const gcn::Event& event)
{
    mVisible = false;

    WidgetListIterator it;

    for (it = mWidgets.begin(); it != mWidgets.end(); it++)
    {
        if (mFocusHandler->isFocused(*it))
            mFocusHandler->focusNone();
    }

    int widgetX, widgetY;
    getAbsolutePosition(widgetX, widgetY);

    widgetX = gui->getMouseX() - widgetX;
    widgetY = gui->getMouseY() - widgetY;

    gcn::MouseEvent mouseEvent(this, false, false, false, false,
                               gcn::MouseEvent::EXITED, 0, widgetX, widgetY, 0);

    mouseExited(mouseEvent);
}
Beispiel #24
0
void ColorPicker::display(void) {
   static ColorScheme *scheme = ColorScheme::getInstance();

   if (_cpTexture == NULL || _isVisible == false) return;

   Panel::display();

   Point currPosition = getAbsolutePosition();

   refreshColor();

   _cpTexture->enable();
   scheme->applyDefaultModulate();

      // colorful area
      _cpTexture->display(currPosition.x, currPosition.y,0, MatrixTemplate<ColorRGBA>::getWidth(), MatrixTemplate<ColorRGBA>::getHeight());

      // selected color
      glColor3f(_currentColor[0]/255.f, _currentColor[1]/255.f, _currentColor[2]/255.f);
      _cpTexture->display(currPosition.x + 5, currPosition.y + 130, 1, MatrixTemplate<ColorRGBA>::getWidth() - 11, 20);

   _cpTexture->disable();
}
Beispiel #25
0
void Object::moveDistance(Vector2 delta)
{
    float angle = 0;
    if (m_parent != nullptr)
    {
        angle = m_parent->getAbsoluteRotation();
    }

    //delta.rotateAround(angle,Vector2(0,0));
    Vector2 absoluteDelta = delta;
    absoluteDelta.rotateAround(angle,0,0);

    m_physicsObject->SetTransform( (getAbsolutePosition() + absoluteDelta).toBulletVector() , m_physicsObject->GetAngle() );

    for (unsigned i = 0; i < m_children.size(); ++i)
    {
        Object* child = m_children.at(i);
        if (!child->m_independent)
        {
            child->moveAbsoluteDistance(delta);
        }
    }
}
//! prerender
void CCameraSceneNode::OnPreRender()
{
	video::IVideoDriver* driver = SceneManager->getVideoDriver();
	if (!driver)
		return;

	if (SceneManager->getActiveCamera() == this)
	{
		screenDim.Width = (f32)driver->getScreenSize().Width;
		screenDim.Height = (f32)driver->getScreenSize().Height;

		driver->setTransform(video::ETS_PROJECTION, Projection);

		// if upvector and vector to the target are the same, we have a
		// problem. so solve this problem:

		core::vector3df pos = getAbsolutePosition();
		core::vector3df tgtv = Target - pos;
		tgtv.normalize();

		core::vector3df up = UpVector;
		up.normalize();

		f32 dp = tgtv.dotProduct(up);
		if ((dp > -1.0001f && dp < -0.9999f) ||
			(dp < 1.0001f && dp > 0.9999f))
			up.X += 1.0f;

		View.buildCameraLookAtMatrixLH(pos, Target, up);
		recalculateViewArea();

		SceneManager->registerNodeForRendering(this, ESNRP_LIGHT_AND_CAMERA);
	}

	if (IsVisible)
		ISceneNode::OnPreRender();
}
Beispiel #27
0
void Pallete::display(void) {
   static scv::Kernel *kernel = scv::Kernel::getInstance();
   static scv::Scissor *scissor = scv::Scissor::getInstance();
   static scv::ColorScheme *scheme = scv::ColorScheme::getInstance();

   if (_cTexture == NULL || _isVisible == false) return;

   scv::Point currPosition = getAbsolutePosition();

   scissor->pushScissor(getScissor());

   _cTexture->enable();
   scv::ColorScheme::getInstance()->applyColor(scv::ColorScheme::MENUBAR);

   // middle
   _cTexture->display(currPosition.x + 1, currPosition.y + 1, 0, getWidth() - 2, getHeight() - 2);

   // corners
   _cTexture->display(currPosition.x, currPosition.y + 1, 0, 1, getHeight() - 2);
   _cTexture->display(currPosition.x + getWidth() - 1, currPosition.y + 1, 0, 1, getHeight() - 2);
   _cTexture->display(currPosition.x + 1, currPosition.y, 0, getWidth() - 2, 1);
   _cTexture->display(currPosition.x + 1, currPosition.y + getHeight() - 1, 0, getWidth() - 2, 1);

   _cTexture->disable();

   if (_layout != NULL) {
      _layout->layoutContainer();
   }

   for (List::const_iterator iter = getChildren().begin(); iter != getChildren().end(); ++iter) {
      if (kernel->willAppearOnScreen(*iter))
         (*iter)->display();
   }

   scissor->popScissor();
}
Beispiel #28
0
	void VScroll::notifyMousePressed(Widget* _sender, int _left, int _top, MouseButton _id)
	{
		// диспечерезируем нажатие своих детей как свое
		eventMouseButtonPressed(this, _left, _top, _id);

		if (MouseButton::Left != _id) return;

		if (mMoveToClick && mWidgetTrack != _sender)
		{
			mPreActionOffset = InputManager::getInstance().getLastLeftPressed();
			const IntPoint& point = InputManager::getInstance().getMousePositionByLayer() - getAbsolutePosition();

			TrackMove(point.left, point.top);

		}
		else if (_sender == mWidgetStart)
		{
			// минимальное значение
			if (mScrollPosition == 0) return;

			// расчитываем следующее положение
			if (mScrollPosition > mScrollPage) mScrollPosition -= mScrollPage;
			else mScrollPosition = 0;

			// оповещаем
			eventScrollChangePosition(this, (int)mScrollPosition);
			updateTrack();

		}
		else if (_sender == mWidgetEnd)
		{
			// максимальное значение
			if ( (mScrollRange < 2) || (mScrollPosition >= (mScrollRange - 1)) ) return;

			// расчитываем следующее положение
			if ((mScrollPosition + mScrollPage) < (mScrollRange - 1)) mScrollPosition += mScrollPage;
			else mScrollPosition = mScrollRange - 1;

			// оповещаем
			eventScrollChangePosition(this, (int)mScrollPosition);
			updateTrack();

		}
		else if (_sender == mWidgetFirstPart)
		{
			// минимальное значение
			if (mScrollPosition == 0) return;

			// расчитываем следующее положение
			if (mScrollPosition > mScrollViewPage) mScrollPosition -= mScrollViewPage;
			else mScrollPosition = 0;

			// оповещаем
			eventScrollChangePosition(this, (int)mScrollPosition);
			updateTrack();

		}
		else if (_sender == mWidgetSecondPart)
		{
			// максимальное значение
			if ( (mScrollRange < 2) || (mScrollPosition >= (mScrollRange - 1)) ) return;

			// расчитываем следующее положение
			if ((mScrollPosition + mScrollViewPage) < (mScrollRange - 1)) mScrollPosition += mScrollViewPage;
			else mScrollPosition = mScrollRange - 1;

			// оповещаем
			eventScrollChangePosition(this, (int)mScrollPosition);
			updateTrack();

		}
		else if (_sender == mWidgetTrack)
		{
			mPreActionOffset.left = _sender->getLeft();
			mPreActionOffset.top = _sender->getTop();
		}
	}
//! pre render event
void CBillboardTextSceneNode::OnAnimate(u32 timeMs)
{
	if (!IsVisible || !Font || !Mesh)
		return;

	ICameraSceneNode* camera = SceneManager->getActiveCamera();
	if (!camera)
		return;

	// get text width
	f32 textLength = 0.f;
	u32 i;
	for(i=0; i!=Symbol.size(); ++i)
	{
		SSymbolInfo &info = Symbol[i];
		textLength += info.Kerning + info.Width;
	}
	if (textLength<0.0f)
		textLength=1.0f;

	//const core::matrix4 &m = camera->getViewFrustum()->Matrices[ video::ETS_VIEW ];

	// make billboard look to camera
	core::vector3df pos = getAbsolutePosition();

	core::vector3df campos = camera->getAbsolutePosition();
	core::vector3df target = camera->getTarget();
	core::vector3df up = camera->getUpVector();
	core::vector3df view = target - campos;
	view.normalize();

	core::vector3df horizontal = up.crossProduct(view);
	if ( horizontal.getLength() == 0 )
	{
		horizontal.set(up.Y,up.X,up.Z);
	}

	horizontal.normalize();
	core::vector3df space = horizontal;

	horizontal *= 0.5f * Size.Width;

	core::vector3df vertical = horizontal.crossProduct(view);
	vertical.normalize();
	vertical *= 0.5f * Size.Height;

	view *= -1.0f;

	// center text
	pos += space * (Size.Width * -0.5f);

	for ( i = 0; i!= Symbol.size(); ++i )
	{
		SSymbolInfo &info = Symbol[i];
		f32 infw = info.Width / textLength;
		f32 infk = info.Kerning / textLength;
		f32 w = (Size.Width * infw * 0.5f);
		pos += space * w;

		SMeshBuffer* buf = (SMeshBuffer*)Mesh->getMeshBuffer(info.bufNo);

		buf->Vertices[info.firstVert+0].Normal = view;
		buf->Vertices[info.firstVert+1].Normal = view;
		buf->Vertices[info.firstVert+2].Normal = view;
		buf->Vertices[info.firstVert+3].Normal = view;

		buf->Vertices[info.firstVert+0].Pos = pos + (space * w) + vertical;
		buf->Vertices[info.firstVert+1].Pos = pos + (space * w) - vertical;
		buf->Vertices[info.firstVert+2].Pos = pos - (space * w) - vertical;
		buf->Vertices[info.firstVert+3].Pos = pos - (space * w) + vertical;

		pos += space * (Size.Width*infk + w);
	}

	// make bounding box

	for (i=0; i< Mesh->getMeshBufferCount() ; ++i)
		Mesh->getMeshBuffer(i)->recalculateBoundingBox();
	Mesh->recalculateBoundingBox();

	BBox = Mesh->getBoundingBox();
	core::matrix4 mat( getAbsoluteTransformation(), core::matrix4::EM4CONST_INVERSE );
	mat.transformBoxEx(BBox);
}
//! render
void CBillboardSceneNode::render()
{
	video::IVideoDriver* driver = SceneManager->getVideoDriver();
	ICameraSceneNode* camera = SceneManager->getActiveCamera();

	if (!camera || !driver)
		return;

	// make billboard look to camera

	core::vector3df pos = getAbsolutePosition();

	core::vector3df campos = camera->getAbsolutePosition();
	core::vector3df target = camera->getTarget();
	core::vector3df up = camera->getUpVector();
	core::vector3df view = target - campos;
	view.normalize();

	core::vector3df horizontal = up.crossProduct(view);
	if ( horizontal.getLength() == 0 )
	{
		horizontal.set(up.Y,up.X,up.Z);
	}
	horizontal.normalize();
	core::vector3df topHorizontal = horizontal * 0.5f * TopEdgeWidth;
	horizontal *= 0.5f * Size.Width;

	// pointing down!
	core::vector3df vertical = horizontal.crossProduct(view);
	vertical.normalize();
	vertical *= 0.5f * Size.Height;

	view *= -1.0f;

	for (s32 i=0; i<4; ++i)
		vertices[i].Normal = view;

	/* Vertices are:
	2--1
	|\ |
	| \|
	3--0
	*/
	vertices[0].Pos = pos + horizontal + vertical;
	vertices[1].Pos = pos + topHorizontal - vertical;
	vertices[2].Pos = pos - topHorizontal - vertical;
	vertices[3].Pos = pos - horizontal + vertical;

	// draw

	if (DebugDataVisible & scene::EDS_BBOX)
	{
		driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
		video::SMaterial m;
		m.Lighting = false;
		driver->setMaterial(m);
		driver->draw3DBox(BBox, video::SColor(0,208,195,152));
	}

	driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);

	driver->setMaterial(Material);

	driver->drawIndexedTriangleList(vertices, 4, indices, 2);
}