LCOV - code coverage report
Current view: top level - chart2/source/view/charttypes - GL3DBarChart.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 0 854 0.0 %
Date: 2015-06-13 12:38:46 Functions: 0 69 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  */
       9             : 
      10             : #include <GL3DBarChart.hxx>
      11             : 
      12             : #include <GL/glew.h>
      13             : 
      14             : #include <glm/glm.hpp>
      15             : #include <glm/gtx/transform.hpp>
      16             : 
      17             : #include "3DChartObjects.hxx"
      18             : #include "GL3DRenderer.hxx"
      19             : #include <ExplicitCategoriesProvider.hxx>
      20             : #include <DataSeriesHelper.hxx>
      21             : 
      22             : #include <osl/time.h>
      23             : #ifdef WNT
      24             : #include <windows.h>
      25             : #endif
      26             : 
      27             : #define CALC_POS_EVENT_ID 1
      28             : #define SHAPE_START_ID 10
      29             : #define FPS_TIME 500
      30             : #define DATAUPDATE_FPS_TIME 1000
      31             : #define HISTORY_NUM 51
      32             : #define COLUMNSIZE 25
      33             : #define SHOW_VALUE_COUNT 15
      34             : #define SHOW_SCROLL_TEXT_DISTANCE 1000
      35             : #define FLY_THRESHOLD 20
      36             : #define DISPLAY_BARS_NUM 3
      37             : 
      38             : 
      39             : using namespace com::sun::star;
      40             : 
      41             : namespace chart {
      42             : 
      43             : const size_t STEPS = 200;
      44             : const size_t STEPS_UPDATE = 100;
      45             : namespace {
      46             : 
      47             : const float TEXT_HEIGHT = 10.0f;
      48             : float DEFAULT_CAMERA_HEIGHT = 500.0f;
      49             : const sal_uInt32 ID_STEP = 10;
      50             : 
      51             : #if 0
      52             : const float BAR_SIZE_X = 15.0f;
      53             : const float BAR_SIZE_Y = 15.0f;
      54             : #else
      55             : const float BAR_SIZE_X = 30.0f;
      56             : const float BAR_SIZE_Y = 5.0f;
      57             : #endif
      58             : const float BAR_DISTANCE_X = 5.0f;
      59             : const float BAR_DISTANCE_Y = 5.0;
      60             : 
      61           0 : float calculateTextWidth(const OUString& rText)
      62             : {
      63           0 :     return rText.getLength() * 10;
      64             : }
      65             : 
      66           0 : double findMaxValue(const boost::ptr_vector<VDataSeries>& rDataSeriesContainer)
      67             : {
      68           0 :     double nMax = 0.0;
      69           0 :     for (boost::ptr_vector<VDataSeries>::const_iterator itr = rDataSeriesContainer.begin(),
      70           0 :             itrEnd = rDataSeriesContainer.end(); itr != itrEnd; ++itr)
      71             :     {
      72           0 :         const VDataSeries& rDataSeries = *itr;
      73           0 :         sal_Int32 nPointCount = rDataSeries.getTotalPointCount();
      74           0 :         for(sal_Int32 nIndex = 0; nIndex < nPointCount; ++nIndex)
      75             :         {
      76           0 :             double nVal = rDataSeries.getYValue(nIndex);
      77           0 :             nMax = std::max(nMax, nVal);
      78             :         }
      79             :     }
      80           0 :     return nMax;
      81             : }
      82             : 
      83             : class SharedResourceAccess
      84             : {
      85             : private:
      86             :     osl::Condition& mrCond1;
      87             :     osl::Condition& mrCond2;
      88             : 
      89             : public:
      90             : 
      91           0 :     SharedResourceAccess(osl::Condition& rCond1, osl::Condition& rCond2):
      92             :         mrCond1(rCond1),
      93           0 :         mrCond2(rCond2)
      94             :     {
      95           0 :         mrCond1.set();
      96           0 :     }
      97             : 
      98           0 :     ~SharedResourceAccess()
      99             :     {
     100           0 :         mrCond2.set();
     101           0 :     }
     102             : };
     103             : 
     104             : }
     105             : 
     106           0 : class RenderThread : public salhelper::Thread
     107             : {
     108             : public:
     109             :     explicit RenderThread(GL3DBarChart* pChart);
     110             : 
     111             : protected:
     112             : 
     113             :     void renderFrame();
     114             :     GL3DBarChart* mpChart;
     115             : };
     116             : 
     117           0 : RenderThread::RenderThread(GL3DBarChart* pChart):
     118             :     salhelper::Thread("RenderThread"),
     119           0 :     mpChart(pChart)
     120             : {
     121           0 : }
     122             : 
     123           0 : void RenderThread::renderFrame()
     124             : {
     125           0 :     if(!mpChart->mbValidContext)
     126           0 :         return;
     127             : 
     128           0 :     mpChart->mpWindow->getContext().makeCurrent();
     129           0 :     mpChart->renderFrame();
     130             :     // FIXME: SwapBuffers can take a considerable time, it'd be
     131             :     // nice if we didn't hold the chart mutex while doing that.
     132           0 :     mpChart->mpWindow->getContext().swapBuffers();
     133           0 :     mpChart->mpWindow->getContext().resetCurrent();
     134             : }
     135             : 
     136           0 : class RenderOneFrameThread : public RenderThread
     137             : {
     138             : public:
     139           0 :     explicit RenderOneFrameThread(GL3DBarChart* pChart):
     140           0 :         RenderThread(pChart)
     141           0 :     {}
     142             : 
     143             : protected:
     144             : 
     145             :     virtual void execute() SAL_OVERRIDE;
     146             : };
     147             : 
     148           0 : void RenderOneFrameThread::execute()
     149             : {
     150           0 :     osl::MutexGuard aGuard(mpChart->maMutex);
     151           0 :     renderFrame();
     152           0 : }
     153             : 
     154           0 : class RenderAnimationThread : public RenderThread
     155             : {
     156             : public:
     157           0 :     RenderAnimationThread(GL3DBarChart* pChart, const glm::vec3& rStartPos, const glm::vec3& rEndPos,
     158             :             const sal_Int32 nSteps = STEPS):
     159             :         RenderThread(pChart),
     160             :         maStartPos(rStartPos),
     161             :         maEndPos(rEndPos),
     162           0 :         mnSteps(nSteps)
     163             :     {
     164           0 :     }
     165             : 
     166             : protected:
     167             : 
     168             :     virtual void execute() SAL_OVERRIDE;
     169             : 
     170             : private:
     171             :     glm::vec3 maStartPos;
     172             :     glm::vec3 maEndPos;
     173             :     sal_Int32 mnSteps;
     174             : 
     175             : };
     176             : 
     177           0 : void RenderAnimationThread::execute()
     178             : {
     179           0 :     osl::MutexGuard aGuard(mpChart->maMutex);
     180           0 :     glm::vec3 aStep = (maEndPos - maStartPos)/(float)mnSteps;
     181           0 :     for(sal_Int32 i = 0; i < mnSteps; ++i)
     182             :     {
     183           0 :         mpChart->maCameraPosition += aStep;
     184           0 :         mpChart->mpCamera->setPosition(mpChart->maCameraPosition);
     185             :         /*
     186             :         mpChart->maCameraDirection += mpChart->maStepDirection;
     187             :         mpChart->mpCamera->setDirection(mpChart->maCameraDirection);
     188             :         */
     189           0 :         renderFrame();
     190             :     }
     191           0 :     mpChart->mpRenderer->ReleaseScreenTextShapes();
     192           0 : }
     193             : 
     194           0 : class RenderBenchMarkThread : public RenderThread
     195             : {
     196             : public:
     197           0 :     explicit RenderBenchMarkThread(GL3DBarChart * pChart)
     198             :         : RenderThread(pChart)
     199             :         , mbAutoFlyExecuting(false)
     200             :         , mbExecuting(false)
     201             :         , mbNeedFlyBack(false)
     202             :         , mnStep(0)
     203           0 :         , mnStepsTotal(0)
     204             :     {
     205           0 :         osl_getSystemTime(&maClickFlyBackStartTime);
     206           0 :         osl_getSystemTime(&maClickFlyBackEndTime);
     207           0 :     }
     208             : protected:
     209             :     virtual void execute() SAL_OVERRIDE;
     210             : private:
     211             :     void ProcessMouseEvent();
     212             :     void MoveCamera();
     213             :     void MoveCameraToBar();
     214             :     void MoveToBar();
     215             :     void MoveToSelectedBar();
     216             :     void MoveToDefault();
     217             :     void MoveToCorner();
     218             :     void ProcessScroll();
     219             :     void UpdateScreenText();
     220             :     void ProcessClickFlyBack();
     221             :     void AutoMoveToBar();
     222             : private:
     223             :     glm::vec3 maStartPos;
     224             :     glm::vec3 maEndPos;
     225             :     bool mbAutoFlyExecuting;
     226             :     bool mbExecuting;
     227             :     bool mbNeedFlyBack;
     228             :     glm::vec3 maStep;
     229             :     glm::vec3 maStepDirection;
     230             :     glm::mat4 maMatrixStep;
     231             :     size_t mnStep;
     232             :     size_t mnStepsTotal;
     233             :     TimeValue maClickFlyBackStartTime;
     234             :     TimeValue maClickFlyBackEndTime;
     235             :     glm::vec3 maTargetPosition;
     236             :     glm::vec3 maTargetDirection;
     237             : };
     238             : 
     239           0 : void RenderBenchMarkThread::MoveCamera()
     240             : {
     241           0 :     if(mnStep < mnStepsTotal)
     242             :     {
     243           0 :         ++mnStep;
     244           0 :         mpChart->maCameraPosition += maStep;
     245           0 :         mpChart->mpCamera->setPosition(mpChart->maCameraPosition);
     246           0 :         mpChart->maCameraDirection += maStepDirection;
     247           0 :         mpChart->mpCamera->setDirection(mpChart->maCameraDirection);
     248             :     }
     249             :     else
     250             :     {
     251           0 :         mnStep = 0;
     252           0 :         mbExecuting = false;
     253           0 :         mbAutoFlyExecuting = false;
     254           0 :         mbNeedFlyBack = false;
     255           0 :         mpChart->maRenderEvent = EVENT_NONE;
     256             :     }
     257           0 : }
     258             : 
     259           0 : void RenderBenchMarkThread::MoveCameraToBar()
     260             : {
     261           0 :     if(mnStep < mnStepsTotal)
     262             :     {
     263           0 :         ++mnStep;
     264           0 :         mpChart->mpRenderer->AddMatrixDiff(maMatrixStep);
     265             :     }
     266             :     else
     267             :     {
     268           0 :         mpChart->maCameraPosition = maTargetPosition;
     269           0 :         mpChart->maCameraDirection = maTargetDirection;
     270           0 :         mpChart->mpCamera->setPosition(maTargetPosition);
     271           0 :         mpChart->mpCamera->setDirection(maTargetDirection);
     272           0 :         mpChart->mpRenderer->ResetMatrixDiff();
     273           0 :         mnStep = 0;
     274           0 :         mbExecuting = false;
     275           0 :         mbAutoFlyExecuting = false;
     276           0 :         mbNeedFlyBack = true;
     277           0 :         osl_getSystemTime(&maClickFlyBackStartTime);
     278           0 :         osl_getSystemTime(&maClickFlyBackEndTime);
     279           0 :         mpChart->maRenderEvent = EVENT_SHOW_SELECT;
     280             :     }
     281           0 : }
     282             : 
     283             : 
     284           0 : void RenderBenchMarkThread::MoveToDefault()
     285             : {
     286           0 :     if ((mpChart->maCameraPosition == mpChart->maDefaultCameraDirection) &&
     287           0 :         (mpChart->maCameraDirection == mpChart->maDefaultCameraDirection))
     288             :     {
     289           0 :         mnStep = 0;
     290           0 :         mbExecuting = false;
     291           0 :         mpChart->maRenderEvent = EVENT_NONE;
     292           0 :         return;
     293             :     }
     294           0 :     if (!mbExecuting)
     295             :     {
     296           0 :         mpChart->mpRenderer->EndClick();
     297           0 :         mnStep = 0;
     298           0 :         mnStepsTotal = STEPS;
     299           0 :         maStep = (mpChart->maDefaultCameraPosition - mpChart->maCameraPosition)/((float)mnStepsTotal);
     300           0 :         maStepDirection = (mpChart->maDefaultCameraDirection - mpChart->maCameraDirection)/((float)mnStepsTotal);
     301           0 :         mbExecuting = true;
     302             :     }
     303           0 :     MoveCamera();
     304             : }
     305             : 
     306           0 : void RenderBenchMarkThread::MoveToBar()
     307             : {
     308           0 :     if (!mbExecuting)
     309             :     {
     310           0 :         mpChart->mnSelectBarId = mpChart->barIdAtPosition(mpChart->maClickPos);
     311             : 
     312           0 :         std::map<sal_uInt32, const GL3DBarChart::BarInformation>::const_iterator itr = mpChart->maBarMap.find(mpChart->mnSelectBarId);
     313           0 :         if(itr == mpChart->maBarMap.end())
     314             :         {
     315           0 :             mpChart->mnSelectBarId = mpChart->mnPreSelectBarId;
     316           0 :             mpChart->maRenderEvent = mpChart->maPreRenderEvent;
     317           0 :             mpChart->maClickCond.set();
     318           0 :             return;
     319             :         }
     320           0 :         mpChart->mpRenderer->EndClick();
     321           0 :         const GL3DBarChart::BarInformation& rBarInfo = itr->second;
     322           0 :         mnStep = 0;
     323           0 :         mnStepsTotal = STEPS;
     324           0 :         maTargetPosition = rBarInfo.maPos;
     325           0 :         maTargetPosition.z += 240;
     326           0 :         maTargetPosition.x += BAR_SIZE_X / 2.0f;
     327           0 :         maTargetDirection = rBarInfo.maPos;
     328           0 :         maTargetDirection.x += BAR_SIZE_X / 2.0f;
     329           0 :         maTargetDirection.y += BAR_SIZE_Y / 2.0f;
     330           0 :         maTargetPosition.y = maTargetDirection.y - 240;
     331           0 :         maMatrixStep = mpChart->mpRenderer->GetDiffOfTwoCameras(mpChart->maCameraPosition, maTargetPosition, mpChart->maCameraDirection, maTargetDirection)/((float)mnStepsTotal);
     332           0 :         mpChart->maClickCond.set();
     333           0 :         mbExecuting = true;
     334           0 :         mbNeedFlyBack = false;
     335           0 :         mpChart->mpRenderer->StartClick(mpChart->mnSelectBarId);
     336             :     }
     337           0 :     MoveCameraToBar();
     338             : }
     339             : 
     340           0 : void RenderBenchMarkThread::MoveToSelectedBar()
     341             : {
     342           0 :     mpChart->mnSelectBarId = mpChart->mnUpdateBarId;
     343           0 :     std::map<sal_uInt32, const GL3DBarChart::BarInformation>::const_iterator itr = mpChart->maBarMap.find(mpChart->mnSelectBarId);
     344           0 :     if(itr == mpChart->maBarMap.end())
     345             :     {
     346           0 :         mpChart->mnSelectBarId = mpChart->mnPreSelectBarId;
     347           0 :         mpChart->maRenderEvent = mpChart->maPreRenderEvent;
     348           0 :         mpChart->maClickCond.set();
     349           0 :         return;
     350             :     }
     351           0 :     mpChart->mpRenderer->EndClick();
     352           0 :     const GL3DBarChart::BarInformation& rBarInfo = itr->second;
     353           0 :     mnStep = 0;
     354           0 :     mnStepsTotal = STEPS_UPDATE;
     355           0 :     maTargetPosition = rBarInfo.maPos;
     356           0 :     maTargetPosition.z += 240;
     357           0 :     maTargetPosition.x += BAR_SIZE_X / 2.0f;
     358           0 :     maTargetDirection = rBarInfo.maPos;
     359           0 :     maTargetDirection.x += BAR_SIZE_X / 2.0f;
     360           0 :     maTargetDirection.y += BAR_SIZE_Y / 2.0f;
     361           0 :     maTargetPosition.y = maTargetDirection.y - 240;
     362           0 :     maMatrixStep = mpChart->mpRenderer->GetDiffOfTwoCameras( maTargetPosition,  maTargetDirection)/((float)mnStepsTotal);
     363           0 :     mpChart->maClickCond.set();
     364           0 :     mbExecuting = true;
     365           0 :     mbNeedFlyBack = false;
     366           0 :     mpChart->mpRenderer->StartClick(mpChart->mnSelectBarId);
     367           0 :     mpChart->maRenderEvent = EVENT_CLICK;
     368             : }
     369             : 
     370           0 : void RenderBenchMarkThread::AutoMoveToBar()
     371             : {
     372           0 :     if (!mbAutoFlyExecuting)
     373             :     {
     374           0 :         mpChart->mpRenderer->EndClick();
     375           0 :         std::map<sal_uInt32, const GL3DBarChart::BarInformation>::const_iterator itr = mpChart->maBarMap.find(mpChart->mnSelectBarId);
     376           0 :         if(itr == mpChart->maBarMap.end())
     377             :         {
     378           0 :             mpChart->maRenderEvent = EVENT_NONE;
     379           0 :             return;
     380             :         }
     381           0 :         const GL3DBarChart::BarInformation& rBarInfo = itr->second;
     382           0 :         mnStep = 0;
     383           0 :         mnStepsTotal = STEPS;
     384           0 :          maTargetPosition = rBarInfo.maPos;
     385           0 :         maTargetPosition.z += 240;
     386           0 :         maTargetPosition.x += BAR_SIZE_X / 2.0f;
     387           0 :         maTargetDirection = rBarInfo.maPos;
     388           0 :         maTargetDirection.x += BAR_SIZE_X / 2.0f;
     389           0 :         maTargetDirection.y += BAR_SIZE_Y / 2.0f;
     390           0 :         maTargetPosition.y = maTargetDirection.y - 240;
     391           0 :         maMatrixStep = mpChart->mpRenderer->GetDiffOfTwoCameras(mpChart->maCameraPosition, maTargetPosition, mpChart->maCameraDirection, maTargetDirection)/((float)mnStepsTotal);
     392           0 :         mpChart->mpRenderer->StartClick(mpChart->mnSelectBarId);
     393           0 :         mbAutoFlyExecuting = true;
     394           0 :         mbNeedFlyBack = false;
     395             :     }
     396           0 :     MoveCameraToBar();
     397             : }
     398             : 
     399           0 : void RenderBenchMarkThread::MoveToCorner()
     400             : {
     401           0 :     if (!mbExecuting)
     402             :     {
     403           0 :         mpChart->mpRenderer->EndClick();
     404           0 :         mnStep = 0;
     405           0 :         mnStepsTotal = STEPS;
     406           0 :         maStep = (mpChart->getCornerPosition(mpChart->mnCornerId) - mpChart->maCameraPosition) / float(mnStepsTotal);
     407           0 :         maStepDirection = (glm::vec3(mpChart->mnMaxX/2.0f, mpChart->mnMaxY/2.0f, 0) - mpChart->maCameraDirection)/ float(mnStepsTotal);
     408           0 :         mbExecuting = true;
     409             :     }
     410           0 :     MoveCamera();
     411           0 : }
     412             : 
     413           0 : void RenderBenchMarkThread::ProcessScroll()
     414             : {
     415             :     //will add other process later
     416           0 :     mpChart->mpRenderer->EndClick();
     417           0 :     mnStep = 0;
     418           0 :     mnStepsTotal = STEPS;
     419           0 :     mpChart->maRenderEvent = EVENT_SHOW_SCROLL;
     420           0 : }
     421             : 
     422           0 : void RenderBenchMarkThread::ProcessClickFlyBack()
     423             : {
     424           0 :     if (!mbNeedFlyBack)
     425           0 :         return;
     426           0 :     osl_getSystemTime(&maClickFlyBackEndTime);
     427           0 :     int nDeltaMs = GL3DBarChart::calcTimeInterval(maClickFlyBackStartTime, maClickFlyBackEndTime);
     428           0 :     if(nDeltaMs >= 10000)
     429             :     {
     430           0 :         mpChart->maRenderEvent = EVENT_MOVE_TO_DEFAULT;
     431             :     }
     432             : }
     433             : 
     434           0 : void RenderBenchMarkThread::ProcessMouseEvent()
     435             : {
     436           0 :     ProcessClickFlyBack();
     437           0 :     if (mpChart->maRenderEvent == EVENT_SELECTBAR_UPDEDATE)
     438             :     {
     439           0 :         MoveToSelectedBar();
     440             :     }
     441           0 :     else if (mpChart->maRenderEvent == EVENT_CLICK)
     442             :     {
     443           0 :         MoveToBar();
     444             :     }
     445           0 :     else if (mpChart->maRenderEvent == EVENT_MOVE_TO_DEFAULT)
     446             :     {
     447           0 :         MoveToDefault();
     448             :     }
     449           0 :     else if ((mpChart->maRenderEvent == EVENT_DRAG_LEFT) || (mpChart->maRenderEvent == EVENT_DRAG_RIGHT))
     450             :     {
     451           0 :         MoveToCorner();
     452             :     }
     453           0 :     else if (mpChart->maRenderEvent == EVENT_SCROLL)
     454             :     {
     455           0 :         ProcessScroll();
     456             :     }
     457           0 :     else if (mpChart->maRenderEvent == EVENT_AUTO_FLY)
     458             :     {
     459           0 :         AutoMoveToBar();
     460             :     }
     461             : 
     462           0 : }
     463             : 
     464           0 : void RenderBenchMarkThread::UpdateScreenText()
     465             : {
     466           0 :     if (mpChart->mbScreenTextNewRender)
     467             :     {
     468           0 :         mpChart->mpWindow->getContext().makeCurrent();
     469           0 :         mpChart->mpRenderer->ReleaseScreenTextTexture();
     470           0 :         for(boost::ptr_vector<opengl3D::Renderable3DObject>::iterator itr = mpChart->maScreenTextShapes.begin(),
     471           0 :                 itrEnd = mpChart->maScreenTextShapes.end(); itr != itrEnd; ++itr)
     472             :         {
     473           0 :             itr->render();
     474             :         }
     475           0 :         mpChart->mbScreenTextNewRender = false;
     476           0 :         mpChart->mpWindow->getContext().resetCurrent();
     477             :     }
     478           0 : }
     479             : 
     480           0 : void RenderBenchMarkThread::execute()
     481             : {
     482             :     while (true)
     483             :     {
     484             :         {
     485           0 :             osl::MutexGuard aGuard(mpChart->maMutex);
     486           0 :             mpChart->maCond2.reset();
     487           0 :             if (mpChart->mbRenderDie)
     488           0 :                 break;
     489           0 :             UpdateScreenText();
     490           0 :             ProcessMouseEvent();
     491           0 :             renderFrame();
     492           0 :             mpChart->miFrameCount++;
     493             :         }
     494           0 :         if (mpChart->maCond1.check())
     495             :         {
     496           0 :             mpChart->maCond1.reset();
     497           0 :             mpChart->maCond2.wait();
     498             :         }
     499           0 :     }
     500           0 : }
     501             : 
     502           0 : GL3DBarChart::GL3DBarChart(
     503             :     const css::uno::Reference<css::chart2::XChartType>& xChartType,
     504             :     OpenGLWindow* pWindow) :
     505             :     mxChartType(xChartType),
     506           0 :     mpRenderer(new opengl3D::OpenGL3DRenderer()),
     507             :     mpWindow(pWindow),
     508             :     mpCamera(NULL),
     509             :     mbValidContext(true),
     510           0 :     mpTextCache(new opengl3D::TextCache()),
     511             :     mnMaxX(0),
     512             :     mnMaxY(0),
     513             :     mnDistance(0.0),
     514             :     mnCornerId(0),
     515             :     mbNeedsNewRender(true),
     516             :     mbCameraInit(false),
     517             :     mbRenderDie(false),
     518             :     maRenderEvent(EVENT_NONE),
     519             :     maPreRenderEvent(EVENT_NONE),
     520             :     mnSelectBarId(0),
     521             :     mnPreSelectBarId(0),
     522             :     miScrollRate(0),
     523             :     mbScrollFlg(false),
     524             :     mbScreenTextNewRender(false),
     525             :     maFPS(OUString("Render FPS: 0")),
     526             :     maDataUpdateFPS(OUString("Data Update FPS: 0")),
     527             :     miFrameCount(0),
     528             :     miDataUpdateCounter(0),
     529             :     mnColorRate(0),
     530             :     mbBenchMarkMode(false),
     531             :     mnHistoryCounter(0),
     532             :     mnBarsInRow(0),
     533             :     mbAutoFly(false),
     534           0 :     mnUpdateBarId(0)
     535             : {
     536           0 :     maFPSRenderStartTime.Seconds = maFPSRenderStartTime.Nanosec = 0;
     537           0 :     maFPSRenderEndTime.Seconds = maFPSRenderEndTime.Nanosec = 0;
     538           0 :     maDataUpdateStartTime.Seconds = maDataUpdateStartTime.Nanosec = 0;
     539           0 :     maDataUpdateEndTime.Seconds = maDataUpdateEndTime.Nanosec = 0;
     540             : 
     541           0 :     static const char *aBenchMark = getenv("UNLOCK_FPS_MODE");
     542           0 :     if (aBenchMark)
     543             :     {
     544           0 :         mbBenchMarkMode = atoi(aBenchMark);
     545             :     }
     546           0 :     if (mbBenchMarkMode)
     547             :     {
     548           0 :         static const char *scrollFrame = getenv("SCROLL_RATE");
     549           0 :         if (scrollFrame)
     550             :         {
     551           0 :             miScrollRate = atoi(scrollFrame);
     552           0 :             if (miScrollRate > 0)
     553             :             {
     554           0 :                 mbScrollFlg = true;
     555           0 :                 mpRenderer->SetScroll();
     556             :             }
     557             :         }
     558           0 :         char *aAutoFly = getenv("AUTO_FLY");
     559           0 :         if (aAutoFly)
     560             :         {
     561           0 :             mbAutoFly = atoi(aAutoFly);
     562             :         }
     563           0 :         maIdle.SetPriority(SchedulerPriority::REPAINT);
     564           0 :         maIdle.SetIdleHdl(LINK(this, GL3DBarChart, UpdateTimerHdl));
     565           0 :         maIdle.Start();
     566           0 :         osl_getSystemTime(&maFPSRenderStartTime);
     567           0 :         osl_getSystemTime(&maFPSRenderEndTime);
     568           0 :         osl_getSystemTime(&maDataUpdateStartTime);
     569           0 :         osl_getSystemTime(&maDataUpdateEndTime);
     570             :     }
     571           0 :     Size aSize = mpWindow->GetSizePixel();
     572           0 :     mpRenderer->SetSize(aSize);
     573           0 :     mpWindow->setRenderer(this);
     574           0 :     mpWindow->getContext().makeCurrent();
     575           0 :     mpRenderer->init();
     576           0 :     mpWindow->getContext().resetCurrent();
     577           0 : }
     578             : 
     579           0 : GL3DBarChart::BarInformation::BarInformation(const glm::vec3& rPos, float nVal,
     580             :         sal_Int32 nIndex, sal_Int32 nSeriesIndex):
     581             :     maPos(rPos),
     582             :     mnVal(nVal),
     583             :     mnIndex(nIndex),
     584           0 :     mnSeriesIndex(nSeriesIndex)
     585             : {
     586           0 : }
     587             : 
     588           0 : GL3DBarChart::~GL3DBarChart()
     589             : {
     590           0 :     if (mbBenchMarkMode)
     591             :     {
     592           0 :         SharedResourceAccess aResGuard(maCond1, maCond2);
     593           0 :         osl::MutexGuard aGuard(maMutex);
     594           0 :         mbRenderDie = true;
     595             :     }
     596             : 
     597           0 :     joinRenderThread();
     598             : 
     599           0 :     if(mbValidContext)
     600           0 :         mpWindow->setRenderer(NULL);
     601           0 : }
     602             : 
     603           0 : void GL3DBarChart::create3DShapes(const boost::ptr_vector<VDataSeries>& rDataSeriesContainer,
     604             :         ExplicitCategoriesProvider& rCatProvider)
     605             : {
     606           0 :     SharedResourceAccess aResGuard(maCond1, maCond2);
     607           0 :     osl::MutexGuard aGuard(maMutex);
     608           0 :     if(mnSelectBarId)
     609             :     {
     610           0 :         int nSelectBarId = mnSelectBarId;
     611           0 :         int nPreSelectBarId = nSelectBarId;
     612           0 :         nSelectBarId -= 10;
     613           0 :         sal_uInt32 nSelectRow = (nSelectBarId - SHAPE_START_ID) / ID_STEP / (mnBarsInRow + 1);
     614           0 :         sal_uInt32 nPreSelectRow = (nPreSelectBarId - SHAPE_START_ID) / ID_STEP / (mnBarsInRow + 1);
     615           0 :         if(nSelectRow == nPreSelectRow)
     616             :         {
     617           0 :             std::map<sal_uInt32, const GL3DBarChart::BarInformation>::const_iterator itr = maBarMap.find(nSelectBarId);
     618           0 :             if((maRenderEvent == EVENT_CLICK || maRenderEvent == EVENT_SHOW_SELECT || maRenderEvent == EVENT_AUTO_FLY)&&(itr != maBarMap.end()))
     619             :             {
     620           0 :                 mnUpdateBarId = nSelectBarId;
     621           0 :                 maRenderEvent = EVENT_SELECTBAR_UPDEDATE;
     622             :             }
     623             :         }
     624             :     }
     625           0 :     mpRenderer->ReleaseShapes();
     626             :     // Each series of data flows from left to right, and multiple series are
     627             :     // stacked vertically along y axis.
     628             : 
     629           0 :     sal_uInt32 nId = SHAPE_START_ID;
     630           0 :     float nXEnd = 0.0;
     631           0 :     float nYPos = 0.0;
     632             : 
     633             :     const Color aSeriesColor[] = {
     634             :         COL_RED, COL_GREEN, COL_YELLOW, COL_BROWN, COL_BLUE
     635           0 :     };
     636             : 
     637           0 :     maCategories.clear();
     638           0 :     maSeriesNames.clear();
     639           0 :     maSeriesNames.reserve(rDataSeriesContainer.size());
     640           0 :     maBarMap.clear();
     641           0 :     maShapes.clear();
     642           0 :     if (mbBenchMarkMode)
     643             :     {
     644           0 :         mnColorRate = 0;
     645             :     }
     646           0 :     maShapes.push_back(new opengl3D::Camera(mpRenderer.get()));
     647           0 :     mpCamera = static_cast<opengl3D::Camera*>(&maShapes.back());
     648             : 
     649           0 :     sal_Int32 nSeriesIndex = 0;
     650           0 :     sal_Int32 nMaxPointCount = 0;
     651           0 :     double nMaxVal = findMaxValue(rDataSeriesContainer)/100;
     652           0 :     if (rDataSeriesContainer.empty())
     653             :     {
     654           0 :         mnBarsInRow = 0;
     655             :     }
     656             :     else
     657             :     {
     658           0 :         const VDataSeries& rFirstRow = *(rDataSeriesContainer.begin());
     659           0 :         mnBarsInRow = rFirstRow.getTotalPointCount();
     660             :     }
     661           0 :     for (boost::ptr_vector<VDataSeries>::const_iterator itr = rDataSeriesContainer.begin(),
     662           0 :             itrEnd = rDataSeriesContainer.end(); itr != itrEnd; ++itr)
     663             :     {
     664           0 :         nYPos = nSeriesIndex * (BAR_SIZE_Y + BAR_DISTANCE_Y) + BAR_DISTANCE_Y;
     665             : 
     666           0 :         const VDataSeries& rDataSeries = *itr;
     667           0 :         sal_Int32 nPointCount = rDataSeries.getTotalPointCount();
     668           0 :         nMaxPointCount = std::max(nMaxPointCount, nPointCount);
     669             : 
     670           0 :         bool bMappedFillProperty = rDataSeries.hasPropertyMapping("FillColor");
     671             : 
     672             :         // Create series name text object.
     673             :         OUString aSeriesName =
     674             :             DataSeriesHelper::getDataSeriesLabel(
     675           0 :                 rDataSeries.getModel(), mxChartType->getRoleOfSequenceForSeriesLabel());
     676             : 
     677           0 :         maSeriesNames.push_back(aSeriesName);
     678             : 
     679           0 :         if(!aSeriesName.isEmpty())
     680             :         {
     681           0 :             maShapes.push_back(new opengl3D::Text(mpRenderer.get(),
     682           0 :                         *mpTextCache, aSeriesName, nId));
     683           0 :             nId += ID_STEP;
     684           0 :             opengl3D::Text* p = static_cast<opengl3D::Text*>(&maShapes.back());
     685           0 :             glm::vec3 aTopLeft, aTopRight, aBottomRight;
     686           0 :             aTopRight.x = -BAR_DISTANCE_Y;
     687           0 :             aTopRight.y = nYPos + BAR_DISTANCE_Y;
     688           0 :             aTopLeft.x = calculateTextWidth(aSeriesName) * -1.0 - BAR_DISTANCE_Y;
     689           0 :             aTopLeft.y = nYPos + BAR_DISTANCE_Y;
     690           0 :             aBottomRight = aTopRight;
     691           0 :             aBottomRight.y -= TEXT_HEIGHT;
     692           0 :             p->setPosition(aTopLeft, aTopRight, aBottomRight);
     693             :         }
     694             : 
     695           0 :         sal_Int32 nColor = aSeriesColor[nSeriesIndex % SAL_N_ELEMENTS(aSeriesColor)].GetColor();
     696           0 :         for(sal_Int32 nIndex = 0; nIndex < nPointCount; ++nIndex)
     697             :         {
     698           0 :             if(bMappedFillProperty)
     699             :             {
     700           0 :                 double nPropVal = rDataSeries.getValueByProperty(nIndex, "FillColor");
     701           0 :                 if(!rtl::math::isNan(nPropVal))
     702           0 :                     nColor = static_cast<sal_uInt32>(nPropVal);
     703             :             }
     704             : 
     705           0 :             float nVal = rDataSeries.getYValue(nIndex);
     706           0 :             if (rtl::math::isNan(nVal))
     707           0 :                 continue;
     708             : 
     709           0 :             float nXPos = nIndex * (BAR_SIZE_X + BAR_DISTANCE_X) + BAR_DISTANCE_X;
     710             : 
     711           0 :             glm::mat4 aScaleMatrix = glm::scale(glm::vec3(BAR_SIZE_X, BAR_SIZE_Y, float(nVal/nMaxVal)));
     712           0 :             glm::mat4 aTranslationMatrix = glm::translate(glm::vec3(nXPos, nYPos, 0.0f));
     713           0 :             glm::mat4 aBarPosition = aTranslationMatrix * aScaleMatrix;
     714             : 
     715             :             maBarMap.insert(std::pair<sal_uInt32, BarInformation>(nId,
     716           0 :                         BarInformation(glm::vec3(nXPos, nYPos, float(nVal/nMaxVal)),
     717           0 :                             nVal, nIndex, nSeriesIndex)));
     718           0 :             recordBarHistory(nId, nVal);
     719           0 :             if (mbBenchMarkMode)
     720             :             {
     721           0 :                 std::map<sal_uInt32, sal_uInt32>::const_iterator it = maBarColorMap.find(nId);
     722           0 :                 if (it == maBarColorMap.end())
     723             :                 {
     724           0 :                     maBarColorMap[nId] = nColor;
     725             :                 }
     726             :                 else
     727             :                 {
     728           0 :                     if(mbAutoFly)
     729           0 :                         processAutoFly(nId, nColor);
     730             :                 }
     731             :             }
     732           0 :             maShapes.push_back(new opengl3D::Bar(mpRenderer.get(), aBarPosition, nColor, nId));
     733           0 :             nId += ID_STEP;
     734             :         }
     735             : 
     736           0 :         float nThisXEnd = nPointCount * (BAR_SIZE_X + BAR_DISTANCE_X);
     737           0 :         if (nXEnd < nThisXEnd)
     738           0 :             nXEnd = nThisXEnd;
     739             : 
     740           0 :         ++nSeriesIndex;
     741           0 :     }
     742             : 
     743           0 :     nYPos += BAR_SIZE_Y + BAR_DISTANCE_Y;
     744             : 
     745             :     // X axis
     746           0 :     maShapes.push_back(new opengl3D::Line(mpRenderer.get(), nId));
     747           0 :     nId += ID_STEP;
     748           0 :     opengl3D::Line* pAxis = static_cast<opengl3D::Line*>(&maShapes.back());
     749           0 :     glm::vec3 aBegin;
     750           0 :     aBegin.y = nYPos;
     751           0 :     glm::vec3 aEnd = aBegin;
     752           0 :     aEnd.x = mbBenchMarkMode ? (mbScrollFlg ? nXEnd - BAR_SIZE_X : nXEnd) : nXEnd;
     753           0 :     pAxis->setPosition(aBegin, aEnd);
     754           0 :     pAxis->setLineColor(COL_BLUE);
     755             : 
     756             :     // Y axis
     757           0 :     maShapes.push_back(new opengl3D::Line(mpRenderer.get(), nId));
     758           0 :     nId += ID_STEP;
     759           0 :     pAxis = static_cast<opengl3D::Line*>(&maShapes.back());
     760           0 :     aBegin.x = aBegin.y = 0;
     761           0 :     aEnd = aBegin;
     762           0 :     aEnd.y = nYPos;
     763           0 :     pAxis->setPosition(aBegin, aEnd);
     764           0 :     pAxis->setLineColor(COL_BLUE);
     765             : 
     766             :     // Chart background.
     767           0 :     maShapes.push_back(new opengl3D::Rectangle(mpRenderer.get(), nId));
     768           0 :     nId += ID_STEP;
     769           0 :     opengl3D::Rectangle* pRect = static_cast<opengl3D::Rectangle*>(&maShapes.back());
     770           0 :     glm::vec3 aTopLeft;
     771           0 :     glm::vec3 aTopRight = aTopLeft;
     772           0 :     aTopRight.x = mbBenchMarkMode ? (mbScrollFlg ? nXEnd - BAR_SIZE_X : nXEnd + 2 * BAR_DISTANCE_X) : (nXEnd + 2 * BAR_DISTANCE_X);
     773           0 :     glm::vec3 aBottomRight = aTopRight;
     774           0 :     aBottomRight.y = nYPos;
     775           0 :     pRect->setPosition(aTopLeft, aTopRight, aBottomRight);
     776           0 :     pRect->setFillColor(COL_BLACK);
     777           0 :     pRect->setLineColor(COL_BLUE);
     778           0 :     if (mbScrollFlg)
     779           0 :         mpRenderer->SetSceneEdge(BAR_DISTANCE_X - 0.001f, aTopRight.x - BAR_DISTANCE_X);
     780             :     else
     781           0 :         mpRenderer->SetSceneEdge(-0.001f, aTopRight.x);
     782             :     // Create category texts along X-axis at the bottom.
     783           0 :     uno::Sequence<OUString> aCats = rCatProvider.getSimpleCategories();
     784           0 :     for (sal_Int32 i = 0; i < aCats.getLength(); ++i)
     785             :     {
     786           0 :         if (mbBenchMarkMode && mbScrollFlg && (i + 1 == aCats.getLength()))
     787           0 :             break;
     788           0 :         maCategories.push_back(aCats[i]);
     789           0 :         if(aCats[i].isEmpty())
     790           0 :             continue;
     791             : 
     792           0 :         float nXPos = i * (BAR_SIZE_X + BAR_DISTANCE_X);
     793             : 
     794           0 :         maShapes.push_back(new opengl3D::Text(mpRenderer.get(), *mpTextCache,
     795           0 :                     aCats[i], nId));
     796           0 :         nId += ID_STEP;
     797           0 :         opengl3D::Text* p = static_cast<opengl3D::Text*>(&maShapes.back());
     798           0 :         aTopLeft.x = nXPos + TEXT_HEIGHT + 0.5 * BAR_SIZE_X;
     799           0 :         aTopLeft.y = nYPos + calculateTextWidth(aCats[i]) + 0.5 * BAR_DISTANCE_Y;
     800           0 :         aTopRight = aTopLeft;
     801           0 :         aTopRight.y = nYPos + 0.5* BAR_DISTANCE_Y;
     802           0 :         aBottomRight.x = nXPos;
     803           0 :         aBottomRight.y = nYPos + 0.5 * BAR_DISTANCE_Y;
     804           0 :         p->setPosition(aTopLeft, aTopRight, aBottomRight);
     805             : 
     806             :         // create shapes on other side as well
     807             : 
     808           0 :         maShapes.push_back(new opengl3D::Text(mpRenderer.get(), *mpTextCache,
     809           0 :                     aCats[i], nId));
     810           0 :         nId += ID_STEP;
     811           0 :         p = static_cast<opengl3D::Text*>(&maShapes.back());
     812           0 :         aTopLeft.x = nXPos + TEXT_HEIGHT + 0.5 * BAR_SIZE_X;
     813           0 :         aTopLeft.y =  - 0.5 * BAR_DISTANCE_Y;
     814           0 :         aTopRight = aTopLeft;
     815           0 :         aTopRight.y = -calculateTextWidth(aCats[i]) - 0.5* BAR_DISTANCE_Y;
     816           0 :         aBottomRight.x = nXPos;
     817           0 :         aBottomRight.y = -calculateTextWidth(aCats[i]) - 0.5 * BAR_DISTANCE_Y;
     818           0 :         p->setPosition(aTopLeft, aTopRight, aBottomRight);
     819             :     }
     820             : 
     821           0 :     mnMaxX = nMaxPointCount * (BAR_SIZE_X + BAR_DISTANCE_X) + 40;
     822           0 :     mnMaxY = nSeriesIndex * (BAR_SIZE_Y + BAR_DISTANCE_Y) + 40;
     823           0 :     if (!mbCameraInit)
     824             :     {
     825           0 :         mnDistance = sqrt(mnMaxX * mnMaxX + mnMaxY * mnMaxY + DEFAULT_CAMERA_HEIGHT * DEFAULT_CAMERA_HEIGHT);
     826           0 :         maDefaultCameraDirection = glm::vec3(mnMaxX * 0.4, mnMaxY * 0.35, 0);
     827           0 :         maDefaultCameraPosition = glm::vec3(maDefaultCameraDirection.x, maDefaultCameraDirection.y - mnDistance, DEFAULT_CAMERA_HEIGHT * 2);
     828           0 :         mnCornerId = 0;
     829           0 :         mbCameraInit = true;
     830           0 :         float pi = 3.1415926f;
     831           0 :         float nAngleX = -pi / 6.5f;
     832           0 :         float nAngleZ = -pi / 8.0f;
     833           0 :         glm::mat4 aDefaultRotateMatrix = glm::eulerAngleYXZ(0.0f, nAngleX, nAngleZ);
     834           0 :         maDefaultCameraPosition = glm::vec3(aDefaultRotateMatrix * glm::vec4(maDefaultCameraPosition, 1.0f));
     835           0 :         maCameraPosition = maDefaultCameraPosition;
     836           0 :         maCameraDirection = maDefaultCameraDirection;
     837           0 :         mpCamera->setPosition(maCameraPosition);
     838           0 :         mpCamera->setDirection(maCameraDirection);
     839             :     }
     840             :     else
     841             :     {
     842           0 :         mpCamera->setPosition(maCameraPosition);
     843           0 :         mpCamera->setDirection(maCameraDirection);
     844             :     }
     845           0 :     if (mbBenchMarkMode && (!mpRenderThread.is()))
     846             :     {
     847             :         //if scroll the bars, set the speed and distance first
     848           0 :         if (mbScrollFlg)
     849             :         {
     850           0 :             mpRenderer->SetScrollSpeed((float)(BAR_SIZE_X + BAR_DISTANCE_X) / (float)miScrollRate);
     851           0 :             mpRenderer->SetScrollDistance((float)(BAR_SIZE_X + BAR_DISTANCE_X));
     852             :         }
     853           0 :         spawnRenderThread(new RenderBenchMarkThread(this));
     854             :     }
     855           0 :     miDataUpdateCounter++;
     856           0 :     mnHistoryCounter++;
     857           0 :     mbNeedsNewRender = true;
     858           0 : }
     859             : 
     860           0 : void GL3DBarChart::joinRenderThread()
     861             : {
     862           0 :     if(mpRenderThread.is())
     863             :     {
     864             :         // FIXME: badly want to assert that we don't
     865             :         // hold the mutex here ... but can't API-wise.
     866           0 :         mpRenderThread->join();
     867             :     }
     868           0 : }
     869             : 
     870           0 : void GL3DBarChart::spawnRenderThread(RenderThread *pThread)
     871             : {
     872           0 :     joinRenderThread(); // not holding maMutex
     873             : 
     874           0 :     osl::MutexGuard aGuard(maMutex);
     875             : 
     876           0 :     Size aSize = mpWindow->GetSizePixel();
     877           0 :     mpWindow->getContext().setWinSize(aSize);
     878           0 :     mpRenderThread = rtl::Reference<RenderThread>(pThread);
     879           0 :     mpWindow->getContext().resetCurrent();
     880           0 :     mpRenderThread->launch();
     881           0 : }
     882             : 
     883           0 : void GL3DBarChart::update()
     884             : {
     885           0 :     if (mbBenchMarkMode)
     886           0 :         return;
     887           0 :     spawnRenderThread(new RenderOneFrameThread(this));
     888             : }
     889             : 
     890           0 : void GL3DBarChart::moveToDefault()
     891             : {
     892           0 :     if(mbBenchMarkMode)
     893             :     {
     894             :         // add correct handling here!!
     895           0 :         if ((maRenderEvent != EVENT_NONE) && (maRenderEvent != EVENT_SHOW_SCROLL) &&
     896           0 :             (maRenderEvent != EVENT_AUTO_FLY) && (maRenderEvent != EVENT_SHOW_SELECT))
     897           0 :             return;
     898             : 
     899             :         {
     900           0 :             SharedResourceAccess aResGuard(maCond1, maCond2);
     901           0 :             osl::MutexGuard aGuard(maMutex);
     902           0 :             maRenderEvent = EVENT_MOVE_TO_DEFAULT;
     903             :         }
     904           0 :         return;
     905             :     }
     906             : 
     907           0 :     spawnRenderThread(new RenderAnimationThread(this, maCameraPosition, maDefaultCameraPosition, STEPS));
     908             : 
     909             :     /*
     910             :      * TODO: moggi: add to thread
     911             :     glm::vec3 maTargetDirection = maDefaultCameraDirection;
     912             :     maStepDirection = (maTargetDirection - maCameraDirection)/((float)mnStepsTotal);
     913             :     */
     914             : }
     915             : 
     916           0 : sal_uInt32 GL3DBarChart::barIdAtPosition(const Point& rPos)
     917             : {
     918           0 :     sal_uInt32 nId = 5;
     919             :     {
     920           0 :         osl::MutexGuard aGuard(maMutex);
     921           0 :         mpWindow->getContext().makeCurrent();
     922           0 :         mpRenderer->SetPickingMode(true);
     923           0 :         renderFrame();
     924           0 :         nId = mpRenderer->GetPixelColorFromPoint(rPos.X(), rPos.Y());
     925           0 :         mpRenderer->SetPickingMode(false);
     926           0 :         mpWindow->getContext().resetCurrent();
     927             :     }
     928           0 :     return nId;
     929             : }
     930             : 
     931           0 : void GL3DBarChart::clickedAt(const Point& rPos, sal_uInt16 nButtons)
     932             : {
     933           0 :     if (nButtons == MOUSE_RIGHT)
     934             :     {
     935           0 :         moveToDefault();
     936           0 :         return;
     937             :     }
     938             : 
     939           0 :     if(nButtons != MOUSE_LEFT)
     940           0 :         return;
     941             : 
     942           0 :     if (mbBenchMarkMode)
     943             :     {
     944             :         // add correct handling here !!
     945           0 :         if ((maRenderEvent != EVENT_NONE) && (maRenderEvent != EVENT_SHOW_SCROLL) &&
     946           0 :             (maRenderEvent != EVENT_AUTO_FLY) && (maRenderEvent != EVENT_SHOW_SELECT))
     947           0 :             return;
     948             : 
     949             :         {
     950           0 :             SharedResourceAccess aResGuard(maCond1, maCond2);
     951           0 :             osl::MutexGuard aGuard(maMutex);
     952           0 :             maClickPos = rPos;
     953           0 :             mnPreSelectBarId = mnSelectBarId;
     954           0 :             maPreRenderEvent = maRenderEvent;
     955           0 :             maRenderEvent = EVENT_CLICK;
     956           0 :             maClickCond.reset();
     957             :         }
     958           0 :         maClickCond.wait();
     959           0 :         return;
     960             :     }
     961             : 
     962           0 :     sal_uInt32 nId = barIdAtPosition(rPos);
     963             : 
     964             :     std::map<sal_uInt32, const BarInformation>::const_iterator itr =
     965           0 :         maBarMap.find(nId);
     966             : 
     967           0 :     if(itr == maBarMap.end())
     968           0 :         return;
     969             : 
     970           0 :     const BarInformation& rBarInfo = itr->second;
     971             : 
     972             :     {
     973           0 :         osl::MutexGuard aGuard(maMutex);
     974           0 :         mpWindow->getContext().makeCurrent();
     975           0 :         glm::vec3 aTextPos = glm::vec3(rBarInfo.maPos.x + BAR_SIZE_X / 2.0f,
     976           0 :                 rBarInfo.maPos.y + BAR_SIZE_Y / 2.0f,
     977           0 :                 rBarInfo.maPos.z);
     978           0 :         maShapes.push_back(new opengl3D::ScreenText(mpRenderer.get(), *mpTextCache,
     979           0 :                     "Value: " + OUString::number(rBarInfo.mnVal), glm::vec4(0.0f, 0.0f, 1.0f, 1.0f), CALC_POS_EVENT_ID));
     980           0 :         opengl3D::ScreenText* pScreenText = static_cast<opengl3D::ScreenText*>(&maShapes.back());
     981           0 :         pScreenText->setPosition(glm::vec2(-0.9f, 0.9f), glm::vec2(-0.6f, 0.8f), aTextPos);
     982           0 :         pScreenText->render();
     983           0 :         mpWindow->getContext().resetCurrent();
     984             :     }
     985             : 
     986           0 :     glm::vec3 aTargetPosition = rBarInfo.maPos;
     987           0 :     aTargetPosition.z += 240;
     988           0 :     aTargetPosition.y += BAR_SIZE_Y / 2.0f;
     989             : 
     990             :     spawnRenderThread(new RenderAnimationThread(this, maCameraPosition,
     991           0 :                                                 aTargetPosition, STEPS));
     992             : 
     993             :     /*
     994             :      * TODO: moggi: add to thread
     995             :     glm::vec3 maTargetDirection = rBarInfo.maPos;
     996             :     maTargetDirection.x += BAR_SIZE_X / 2.0f;
     997             :     maTargetDirection.y += BAR_SIZE_Y / 2.0f;
     998             : 
     999             :     maStepDirection = (maTargetDirection - maCameraDirection)/((float)mnStepsTotal);
    1000             :     */
    1001             : }
    1002             : 
    1003           0 : void GL3DBarChart::render()
    1004             : {
    1005           0 :     if (mbBenchMarkMode)
    1006           0 :         return;
    1007             : 
    1008           0 :     update();
    1009             : }
    1010             : 
    1011           0 : void GL3DBarChart::renderFrame()
    1012             : {
    1013           0 :     Size aSize = mpWindow->GetSizePixel();
    1014           0 :     mpRenderer->SetSize(aSize);
    1015           0 :     if(mbNeedsNewRender)
    1016             :     {
    1017           0 :         mpRenderer->ReleaseTextTexture();
    1018           0 :         for(boost::ptr_vector<opengl3D::Renderable3DObject>::iterator itr = maShapes.begin(),
    1019           0 :                 itrEnd = maShapes.end(); itr != itrEnd; ++itr)
    1020             :         {
    1021           0 :             itr->render();
    1022             :         }
    1023             :     }
    1024             :     else
    1025             :     {
    1026           0 :         mpCamera->render();
    1027             :     }
    1028           0 :     mpRenderer->ProcessUnrenderedShape(mbNeedsNewRender);
    1029           0 :     mbNeedsNewRender = false;
    1030           0 : }
    1031             : 
    1032           0 : void GL3DBarChart::mouseDragMove(const Point& rStartPos, const Point& rEndPos, sal_uInt16 )
    1033             : {
    1034           0 :     long nDirection = rEndPos.X() - rStartPos.X();
    1035           0 :     SharedResourceAccess aResGuard(maCond1, maCond2);
    1036           0 :     osl::ClearableGuard<osl::Mutex> aGuard(maMutex);
    1037           0 :     if ((maRenderEvent == EVENT_NONE) || (maRenderEvent == EVENT_SHOW_SCROLL) ||
    1038           0 :         (maRenderEvent == EVENT_AUTO_FLY) || (maRenderEvent == EVENT_SHOW_SELECT))
    1039           0 :         maRenderEvent = nDirection > 0 ? EVENT_DRAG_RIGHT : EVENT_DRAG_LEFT;
    1040           0 :     bool bMove = false;
    1041           0 :     if(nDirection < 0)
    1042             :     {
    1043           0 :         mnCornerId = (mnCornerId + 1) % 4;
    1044           0 :         bMove = true;
    1045             :     }
    1046           0 :     else if(nDirection > 0)
    1047             :     {
    1048           0 :         mnCornerId = mnCornerId - 1;
    1049           0 :         if(mnCornerId < 0)
    1050           0 :             mnCornerId = 3;
    1051           0 :         bMove = true;
    1052             :     }
    1053             : 
    1054           0 :     if (bMove)
    1055             :     {
    1056           0 :         aGuard.clear();
    1057           0 :         moveToCorner();
    1058           0 :     }
    1059           0 : }
    1060             : 
    1061           0 : glm::vec3 GL3DBarChart::getCornerPosition(sal_Int8 nId)
    1062             : {
    1063           0 :     float pi = 3.1415926f;
    1064           0 :     switch(nId)
    1065             :     {
    1066             :         case 0:
    1067             :         {
    1068           0 :             return glm::vec3(mnMaxX / 2 - mnDistance * sin(pi / 4), mnMaxY / 2 - mnDistance * cos(pi / 4), DEFAULT_CAMERA_HEIGHT * 2);
    1069             :         }
    1070             :         break;
    1071             :         case 1:
    1072             :         {
    1073           0 :             return glm::vec3(mnMaxX / 2 + mnDistance * sin(pi / 4), mnMaxY / 2 - mnDistance * cos(pi / 4), DEFAULT_CAMERA_HEIGHT * 2);
    1074             :         }
    1075             :         break;
    1076             :         case 2:
    1077             :         {
    1078           0 :             return glm::vec3(mnMaxX / 2 + mnDistance * sin(pi / 4), mnMaxY / 2 + mnDistance * cos(pi / 4), DEFAULT_CAMERA_HEIGHT * 2);
    1079             :         }
    1080             :         break;
    1081             :         case 3:
    1082             :         {
    1083           0 :             return glm::vec3(mnMaxX / 2 - mnDistance * sin(pi / 4), mnMaxY / 2 + mnDistance * cos(pi / 4), DEFAULT_CAMERA_HEIGHT * 2);
    1084             :         }
    1085             :         break;
    1086             :         default:
    1087             :             assert(false);
    1088             :     }
    1089           0 :     return maDefaultCameraPosition;
    1090             : }
    1091             : 
    1092           0 : void GL3DBarChart::moveToCorner()
    1093             : {
    1094           0 :     if(mbBenchMarkMode)
    1095             :     {
    1096             :         // add correct handling here!!
    1097           0 :         return;
    1098             :     }
    1099             : 
    1100             :     spawnRenderThread(new RenderAnimationThread(this, maCameraPosition,
    1101           0 :                                                 getCornerPosition(mnCornerId), STEPS));
    1102             : 
    1103             :     // TODO: moggi: add to thread
    1104             :     // maStepDirection = (glm::vec3(mnMaxX/2.0f, mnMaxY/2.0f, 0) - maCameraDirection)/ float(mnStepsTotal);
    1105             : }
    1106             : 
    1107           0 : void GL3DBarChart::scroll(long nDelta)
    1108             : {
    1109             :     {
    1110           0 :         SharedResourceAccess aResGuard(maCond1, maCond2);
    1111           0 :         osl::MutexGuard aGuard(maMutex);
    1112           0 :         if ((maRenderEvent != EVENT_NONE) && (maRenderEvent != EVENT_SHOW_SCROLL) &&
    1113           0 :             (maRenderEvent != EVENT_AUTO_FLY) && (maRenderEvent != EVENT_SHOW_SELECT))
    1114           0 :             return;
    1115           0 :         glm::vec3 maDir = glm::normalize(maCameraPosition - maCameraDirection);
    1116           0 :         maCameraPosition -= ((float)nDelta/10) * maDir;
    1117           0 :         mpCamera->setPosition(maCameraPosition);
    1118           0 :         if(mbBenchMarkMode)
    1119             :         {
    1120           0 :             maVectorNearest.clear();
    1121           0 :             getNearestBars(maVectorNearest);
    1122           0 :             maRenderEvent = EVENT_SCROLL;
    1123           0 :         }
    1124             :     }
    1125             : 
    1126           0 :     update();
    1127             : }
    1128             : 
    1129           0 : void GL3DBarChart::contextDestroyed()
    1130             : {
    1131           0 :     SharedResourceAccess aResGuard(maCond1, maCond2);
    1132           0 :     osl::MutexGuard aGuard(maMutex);
    1133           0 :     mbValidContext = false;
    1134           0 : }
    1135             : 
    1136           0 : float GL3DBarChart::addScreenTextShape(OUString &nStr, const glm::vec2& rLeftOrRightTop, float nTextHeight, bool bLeftTopFlag,
    1137             :                                             const glm::vec4& rColor, const glm::vec3& rPos, sal_uInt32 nEvent)
    1138             : {
    1139           0 :     maScreenTextShapes.push_back(new opengl3D::ScreenText(mpRenderer.get(), *mpTextCache, nStr, rColor, nEvent));
    1140           0 :     const opengl3D::TextCacheItem& rTextCache = mpTextCache->getText(nStr);
    1141           0 :     float nRectWidth = (float)rTextCache.maSize.Width() / (float)rTextCache.maSize.Height() * nTextHeight / 2.0f;
    1142           0 :     opengl3D::ScreenText* pScreenText = static_cast<opengl3D::ScreenText*>(&maScreenTextShapes.back());
    1143           0 :     if (bLeftTopFlag)
    1144           0 :         pScreenText->setPosition(rLeftOrRightTop, glm::vec2(rLeftOrRightTop.x + nRectWidth, rLeftOrRightTop.y - nTextHeight), rPos);
    1145             :     else
    1146           0 :         pScreenText->setPosition(glm::vec2(rLeftOrRightTop.x - nRectWidth, rLeftOrRightTop.y), glm::vec2(rLeftOrRightTop.x, rLeftOrRightTop.y - nTextHeight), rPos);
    1147           0 :     return nRectWidth;
    1148             : }
    1149             : 
    1150           0 : void GL3DBarChart::updateRenderFPS()
    1151             : {
    1152           0 :     int nDeltaMs = calcTimeInterval(maFPSRenderStartTime, maFPSRenderEndTime);
    1153           0 :     if(nDeltaMs >= FPS_TIME)
    1154             :     {
    1155           0 :         osl_getSystemTime(&maFPSRenderEndTime);
    1156           0 :         nDeltaMs = calcTimeInterval(maFPSRenderStartTime, maFPSRenderEndTime);
    1157           0 :         int iFPS = miFrameCount * 1000 / nDeltaMs;
    1158           0 :         maFPS =  OUString::number(iFPS);
    1159           0 :         miFrameCount = 0;
    1160           0 :         osl_getSystemTime(&maFPSRenderStartTime);
    1161             :     }
    1162           0 :     osl_getSystemTime(&maFPSRenderEndTime);
    1163           0 :     OUString aFPS = OUString("Render FPS: ");
    1164           0 :     addScreenTextShape(aFPS, glm::vec2(-0.77f, 0.99f), 0.07f, false, glm::vec4(0.0f, 1.0f, 1.0f, 0.0f));
    1165             :     addScreenTextShape(maFPS, glm::vec2(-0.77f, 0.99f), 0.07f, true,
    1166           0 :                        glm::vec4(1.0f, 0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 0.0f));
    1167           0 : }
    1168             : 
    1169           0 : int GL3DBarChart::calcTimeInterval(TimeValue &startTime, TimeValue &endTime)
    1170             : {
    1171             :     TimeValue aTime;
    1172           0 :     aTime.Seconds = endTime.Seconds - startTime.Seconds - 1;
    1173           0 :     aTime.Nanosec = 1000000000 + endTime.Nanosec - startTime.Nanosec;
    1174           0 :     aTime.Seconds += aTime.Nanosec / 1000000000;
    1175           0 :     aTime.Nanosec %= 1000000000;
    1176           0 :     return aTime.Seconds * 1000+aTime.Nanosec / 1000000;
    1177             : }
    1178             : 
    1179           0 : void GL3DBarChart::updateScreenText()
    1180             : {
    1181           0 :     SharedResourceAccess aResGuard(maCond1, maCond2);
    1182           0 :     osl::MutexGuard aGuard(maMutex);
    1183           0 :     maScreenTextShapes.clear();
    1184           0 :     mpRenderer->ReleaseScreenTextShapes();
    1185           0 :     updateRenderFPS();
    1186           0 :     updateDataUpdateFPS();
    1187           0 :     updateClickEvent();
    1188           0 :     updateScroll();
    1189           0 :     mbScreenTextNewRender = true;
    1190           0 : }
    1191             : 
    1192           0 : void GL3DBarChart::updateDataUpdateFPS()
    1193             : {
    1194           0 :     int nDeltaMs = calcTimeInterval(maDataUpdateStartTime, maDataUpdateEndTime);
    1195           0 :     if(nDeltaMs >= DATAUPDATE_FPS_TIME)
    1196             :     {
    1197           0 :         int iFPS = miDataUpdateCounter * 1000 / nDeltaMs;
    1198           0 :         if (iFPS)
    1199             :         {
    1200           0 :             maDataUpdateFPS = OUString::number(iFPS);
    1201             :         }
    1202             :         else
    1203             :         {
    1204           0 :             float fFPS = (float)miDataUpdateCounter * 1000 / (float)nDeltaMs;
    1205           0 :             maDataUpdateFPS = OUString::number(fFPS);
    1206             :         }
    1207           0 :         miDataUpdateCounter = 0;
    1208           0 :         osl_getSystemTime(&maDataUpdateStartTime);
    1209             :     }
    1210           0 :     osl_getSystemTime(&maDataUpdateEndTime);
    1211           0 :     OUString aDataUpdateFPS = OUString("Data Update Rate: ");
    1212           0 :     addScreenTextShape(aDataUpdateFPS, glm::vec2(-0.77, 0.92f), 0.07f, false, glm::vec4(0.0f, 1.0f, 1.0f, 0.0f));
    1213           0 :     addScreenTextShape(maDataUpdateFPS, glm::vec2(-0.77f, 0.92f), 0.07f, true, glm::vec4(1.0f, 0.0f, 0.0f, 0.0f));
    1214           0 : }
    1215             : 
    1216           0 : void GL3DBarChart::recordBarHistory(sal_uInt32 &nBarID, float &nVal)
    1217             : {
    1218           0 :     std::list<float>& aList = maBarHistory[nBarID];
    1219           0 :     if(aList.size() == HISTORY_NUM)
    1220           0 :         aList.pop_front();
    1221           0 :     aList.push_back(nVal);
    1222           0 : }
    1223             : 
    1224           0 : void GL3DBarChart::getNeighborBarID(sal_uInt32 nSelectBarId, sal_uInt32 *pNeighborBarId)
    1225             : {
    1226           0 :     sal_uInt32 nSelectRow = (nSelectBarId - SHAPE_START_ID) / ID_STEP / (mnBarsInRow + 1);
    1227           0 :     for (sal_Int32 i = 0; i < DISPLAY_BARS_NUM; i++)
    1228             :     {
    1229           0 :         pNeighborBarId[i] = nSelectBarId + (i - DISPLAY_BARS_NUM / 2) * ID_STEP;
    1230           0 :         if (pNeighborBarId[i] == nSelectBarId)
    1231           0 :             continue;
    1232           0 :         if ((pNeighborBarId[i] - SHAPE_START_ID) / ID_STEP / (mnBarsInRow + 1) != nSelectRow)
    1233           0 :             pNeighborBarId[i] = 0;
    1234             :     }
    1235           0 : }
    1236             : 
    1237           0 : void GL3DBarChart::addMovementScreenText(sal_uInt32 nBarId)
    1238             : {
    1239           0 :     if (nBarId == 0)
    1240           0 :         return;
    1241           0 :     std::map<sal_uInt32, const BarInformation>::const_iterator itr = maBarMap.find(nBarId);
    1242           0 :     if (itr == maBarMap.end())
    1243           0 :         return;
    1244           0 :     const BarInformation& rBarInfo = itr->second;
    1245           0 :     glm::vec3 aTextPos = glm::vec3(rBarInfo.maPos.x + BAR_SIZE_X / 2.0f,
    1246           0 :                                   rBarInfo.maPos.y + BAR_SIZE_Y / 2.0f,
    1247           0 :                                   rBarInfo.maPos.z);
    1248           0 :     OUString aBarValue = "Value: " + OUString::number(rBarInfo.mnVal);
    1249           0 :     maScreenTextShapes.push_back(new opengl3D::ScreenText(mpRenderer.get(), *mpTextCache, aBarValue, glm::vec4(0.0f, 0.0f, 1.0f, 0.0f), CALC_POS_EVENT_ID, true));
    1250           0 :     const opengl3D::TextCacheItem& rTextCache = mpTextCache->getText(aBarValue);
    1251           0 :     float nRectWidth = (float)rTextCache.maSize.Width() / (float)rTextCache.maSize.Height() * 0.024;
    1252           0 :     opengl3D::ScreenText* pScreenText = static_cast<opengl3D::ScreenText*>(&maScreenTextShapes.back());
    1253           0 :     pScreenText->setPosition(glm::vec2(-nRectWidth / 2, 0.03f), glm::vec2(nRectWidth / 2, -0.03f), aTextPos);
    1254             : }
    1255             : 
    1256           0 : void GL3DBarChart::updateClickEvent()
    1257             : {
    1258           0 :     if (maRenderEvent == EVENT_CLICK || maRenderEvent == EVENT_AUTO_FLY || maRenderEvent == EVENT_SHOW_SELECT)
    1259             :     {
    1260           0 :         std::list<float>& aList = maBarHistory[mnSelectBarId];
    1261           0 :         sal_uInt32 nIdex = 0;
    1262           0 :         sal_uInt32 nBarIdArray[DISPLAY_BARS_NUM] = {0};
    1263           0 :         OUString aTitle;
    1264           0 :         OUString aBarValue;
    1265           0 :         float nXCoordStart, nYCoordStart, nTextWidth, nMaxXCoord = 0.0f, nMinXCoord = 1.0f, nMaxHight = 0.0f;
    1266             :         //write title
    1267           0 :         if (aList.size() > 1)
    1268             :         {
    1269           0 :             aTitle = "Time      ";
    1270           0 :             nTextWidth = addScreenTextShape(aTitle, glm::vec2(0.875, 0.99f), 0.07f, false, glm::vec4(0.0f, 1.0f, 1.0f, 0.5f));
    1271           0 :             nMinXCoord = std::min(nMinXCoord, 0.875f - nTextWidth);
    1272           0 :             aTitle = "   Value";
    1273           0 :             nTextWidth = addScreenTextShape(aTitle, glm::vec2(0.875f, 0.99f), 0.07f, true, glm::vec4(0.0f, 1.0f, 1.0f, 0.5f));
    1274           0 :             nMaxXCoord = std::max(nMaxXCoord, 0.875f + nTextWidth);
    1275             :         }
    1276           0 :         if (aList.size() > COLUMNSIZE)
    1277             :         {
    1278           0 :             aTitle = "Time      ";
    1279           0 :             nTextWidth = addScreenTextShape(aTitle, glm::vec2(0.55f, 0.99f), 0.07f, false, glm::vec4(0.0f, 1.0f, 1.0f, 0.5f));
    1280           0 :             nMinXCoord = std::min(nMinXCoord, 0.55f - nTextWidth);
    1281           0 :             aTitle = "   Value";
    1282           0 :             nTextWidth = addScreenTextShape(aTitle, glm::vec2(0.55f, 0.99f), 0.07f, true, glm::vec4(0.0f, 1.0f, 1.0f, 0.5f));
    1283           0 :             nMaxXCoord = std::max(nMaxXCoord, 0.55f + nTextWidth);
    1284             :         }
    1285           0 :         getNeighborBarID(mnSelectBarId, nBarIdArray);
    1286           0 :         for (std::list<float>::iterator it = aList.begin();it != aList.end();++it)
    1287             :         {
    1288           0 :             if (nIdex + 1 < aList.size())
    1289             :             {
    1290           0 :                 aTitle = "[Time:" + OUString::number((mnHistoryCounter - aList.size() + nIdex)) + "]: ";
    1291           0 :                 if (nIdex == 0)
    1292             :                 {
    1293           0 :                     aTitle = "Most Recent" + aTitle;
    1294             :                 }
    1295           0 :                 if (aList.size() <= COLUMNSIZE)
    1296             :                 {
    1297           0 :                     nXCoordStart = 0.875f;
    1298           0 :                     nYCoordStart = (nIdex + 1) * 0.07f;
    1299             :                 }
    1300             :                 else
    1301             :                 {
    1302           0 :                     nXCoordStart = nIdex < COLUMNSIZE ? 0.55f : 0.875f;
    1303           0 :                     nYCoordStart = nIdex < COLUMNSIZE ? (nIdex + 1) * 0.07f : (nIdex - 24) * 0.07f;
    1304             :                 }
    1305           0 :                 nMaxHight = std::max(nMaxHight, nYCoordStart + 0.07f);
    1306           0 :                 nTextWidth = addScreenTextShape(aTitle, glm::vec2(nXCoordStart, 0.99f - nYCoordStart), 0.07f, false, glm::vec4(0.0f, 1.0f, 1.0f, 0.5f));
    1307           0 :                 nMinXCoord = std::min(nMinXCoord, nXCoordStart - nTextWidth);
    1308           0 :                 aBarValue = OUString::number(*it);
    1309           0 :                 nTextWidth = addScreenTextShape(aBarValue, glm::vec2(nXCoordStart, 0.99f - nYCoordStart), 0.07f, true, glm::vec4(0.0f, 1.0f, 1.0f, 0.5f));
    1310           0 :                 nMaxXCoord = std::max(nMaxXCoord, nXCoordStart + nTextWidth);
    1311             :             }
    1312           0 :             nIdex++;
    1313             :         }
    1314           0 :         for (sal_uInt32 i = 0; i < DISPLAY_BARS_NUM; i++)
    1315             :         {
    1316           0 :             addMovementScreenText(nBarIdArray[i]);
    1317             :         }
    1318             :         //add translucent back ground
    1319           0 :         aTitle = " ";
    1320           0 :         maScreenTextShapes.push_back(new opengl3D::ScreenText(mpRenderer.get(), *mpTextCache, aTitle, glm::vec4(0.0f, 0.0f, 0.0f, 0.5f), 0));
    1321           0 :         opengl3D::ScreenText* pScreenText = static_cast<opengl3D::ScreenText*>(&maScreenTextShapes.back());
    1322           0 :         pScreenText->setPosition(glm::vec2(nMinXCoord, 0.99f), glm::vec2(nMaxXCoord, 0.99f - nMaxHight));
    1323             :     }
    1324           0 : }
    1325             : 
    1326           0 : float GL3DBarChart::calcScrollDistance(const glm::mat4& rMVP, const glm::vec3& rPos)
    1327             : {
    1328           0 :     glm::vec4 aScreenPos = rMVP * glm::vec4(rPos, 1.0);
    1329           0 :     glm::vec3 aActualPos = glm::vec3(aScreenPos.x / aScreenPos.w, aScreenPos.y / aScreenPos.w, 0.0);
    1330           0 :     return glm::length(aActualPos);
    1331             : }
    1332             : 
    1333           0 : void GL3DBarChart::calcDistance(std::vector<sal_uInt32> & rVectorNearest)
    1334             : {
    1335           0 :     int i =0;
    1336           0 :     glm::mat4 aProjection = mpRenderer->GetProjectionMatrix();
    1337           0 :     glm::mat4 aView = mpRenderer->GetViewMatrix();
    1338           0 :     glm::mat4 aScale = mpRenderer->GetGlobalScaleMatrix();
    1339           0 :     glm::mat4 aMVP = aProjection * aView * aScale;
    1340           0 :     std::map<sal_uInt32, const BarInformation>::iterator it;
    1341           0 :     for(it= maBarMap.begin(); it!= maBarMap.end(); ++it)
    1342             :     {
    1343           0 :         sal_uInt32 nId = it->first;
    1344           0 :         if(i < SHOW_VALUE_COUNT)
    1345             :         {
    1346           0 :             rVectorNearest.push_back(nId);
    1347           0 :             i++;
    1348             :         }
    1349           0 :         maDistanceMap[nId] = calcScrollDistance(aMVP, glm::vec3(it->second.maPos.x + BAR_SIZE_X / 2.0f,
    1350           0 :                                                                it->second.maPos.y + BAR_SIZE_Y / 2.0f,
    1351           0 :                                                                it->second.maPos.z));
    1352             :     }
    1353           0 : }
    1354             : 
    1355           0 : void GL3DBarChart::initDistanceHeap(std::vector<sal_uInt32> &rVectorNearest)
    1356             : {
    1357           0 :     for(int i= (rVectorNearest.size()-2)/2; i>= 0; i--)
    1358             :     {
    1359           0 :         keepHeap(rVectorNearest, i);
    1360             :     }
    1361           0 : }
    1362             : 
    1363           0 : void GL3DBarChart::keepHeap(std::vector<sal_uInt32> &rVectorNearest, int nIndex)
    1364             : {
    1365           0 :     size_t nParentIndex = nIndex;
    1366           0 :     while(nParentIndex < rVectorNearest.size())
    1367             :     {
    1368           0 :         size_t nLeftIndex = nParentIndex * 2 + 1;
    1369           0 :         size_t nRightIndex = nLeftIndex +1;
    1370           0 :         if(nLeftIndex >= rVectorNearest.size())
    1371           0 :             break;
    1372           0 :         size_t nFarthestIndex = nLeftIndex;
    1373           0 :         float nFarthest = maDistanceMap[rVectorNearest[nLeftIndex]];
    1374           0 :         if(nRightIndex < rVectorNearest.size())
    1375             :         {
    1376           0 :             float nRight = maDistanceMap[rVectorNearest[nRightIndex]];
    1377           0 :             if(nRight > nFarthest)
    1378             :             {
    1379           0 :                 nFarthest = nRight;
    1380           0 :                 nFarthestIndex = nRightIndex;
    1381             :             }
    1382             :         }
    1383           0 :         float nParent = maDistanceMap[rVectorNearest[nParentIndex]];
    1384           0 :         if(nParent >= nFarthest)
    1385           0 :             break;
    1386             :         else
    1387             :         {
    1388           0 :             swapVector(nParentIndex , nFarthestIndex, rVectorNearest);
    1389           0 :             nParentIndex = nFarthestIndex;
    1390             :         }
    1391             :     }
    1392             : 
    1393           0 : }
    1394             : 
    1395           0 : void GL3DBarChart::swapVector(int i, int j, std::vector<sal_uInt32> &rVectorNearest)
    1396             : {
    1397           0 :     sal_uInt32 nTmp = rVectorNearest[i];
    1398           0 :     rVectorNearest[i] = rVectorNearest[j];
    1399           0 :     rVectorNearest[j] = nTmp;
    1400           0 : }
    1401             : 
    1402           0 : void GL3DBarChart::getNearestBars(std::vector<sal_uInt32> &rVectorNearest)
    1403             : {
    1404           0 :     calcDistance(rVectorNearest);
    1405           0 :     initDistanceHeap(rVectorNearest);
    1406           0 :     std::map<sal_uInt32, float>::iterator it;
    1407           0 :     int i = 0;
    1408           0 :     for(it= maDistanceMap.begin(); it!= maDistanceMap.end(); ++it)
    1409             :     {
    1410           0 :         i++;
    1411           0 :         if(i <= SHOW_VALUE_COUNT)
    1412           0 :             continue;
    1413           0 :         float nDistance = it->second;
    1414           0 :         float nHeaphead = maDistanceMap[rVectorNearest[0]];
    1415           0 :         if(nDistance < nHeaphead)
    1416             :         {
    1417           0 :             rVectorNearest[0] = it->first;
    1418           0 :             keepHeap(rVectorNearest, 0);
    1419             :         }
    1420             :     }
    1421           0 : }
    1422             : 
    1423           0 : void GL3DBarChart::updateScroll()
    1424             : {
    1425           0 :     if ((maRenderEvent == EVENT_SCROLL) || (maRenderEvent == EVENT_SHOW_SCROLL))
    1426             :     {
    1427           0 :         float fMinDistance = 0.0f;
    1428           0 :         std::vector<BarInformation> aBarInfoList;
    1429           0 :         for(size_t i= 0;i < maVectorNearest.size(); i++)
    1430             :         {
    1431             :             //get bar height position
    1432           0 :             std::map<sal_uInt32, const BarInformation>::const_iterator itr = maBarMap.find(maVectorNearest[i]);
    1433           0 :             const BarInformation& rBarInfo = itr->second;
    1434           0 :             aBarInfoList.push_back(rBarInfo);
    1435           0 :             glm::vec3 aPos = rBarInfo.maPos;
    1436           0 :             fMinDistance = (fMinDistance == 0.0f) ? glm::length(aPos - maCameraPosition) :
    1437           0 :                                  std::min(glm::length(aPos - maCameraPosition), fMinDistance);
    1438             :         }
    1439             : 
    1440           0 :         if (fMinDistance <= SHOW_SCROLL_TEXT_DISTANCE)
    1441             :         {
    1442             :             //update scroll value
    1443           0 :             for(size_t i = 0; i < aBarInfoList.size(); i++)
    1444             :             {
    1445           0 :                 OUString aBarValue = "Value: " + OUString::number(aBarInfoList[i].mnVal);
    1446           0 :                 maScreenTextShapes.push_back(new opengl3D::ScreenText(mpRenderer.get(), *mpTextCache, aBarValue, glm::vec4(0.0f, 0.0f, 1.0f, 0.0f), CALC_POS_EVENT_ID, true));
    1447           0 :                 const opengl3D::TextCacheItem& rTextCache = mpTextCache->getText(aBarValue);
    1448           0 :                 float nRectWidth = (float)rTextCache.maSize.Width() / (float)rTextCache.maSize.Height() * 0.024;
    1449           0 :                 glm::vec3 aTextPos = glm::vec3(aBarInfoList[i].maPos.x + BAR_SIZE_X / 2.0f,
    1450           0 :                                       aBarInfoList[i].maPos.y + BAR_SIZE_Y / 2.0f,
    1451           0 :                                       aBarInfoList[i].maPos.z);
    1452           0 :                 opengl3D::ScreenText* pScreenText = static_cast<opengl3D::ScreenText*>(&maScreenTextShapes.back());
    1453           0 :                 pScreenText->setPosition(glm::vec2(-nRectWidth / 2, 0.03f), glm::vec2(nRectWidth / 2, -0.03f), aTextPos);
    1454           0 :             }
    1455           0 :         }
    1456             :     }
    1457           0 : }
    1458             : 
    1459           0 : void GL3DBarChart::processAutoFly(sal_uInt32 nId, sal_uInt32 nColor)
    1460             : {
    1461             :     //record the color
    1462           0 :     sal_uInt32 nPreColor = maBarColorMap[nId];
    1463           0 :     maBarColorMap[nId] = nColor;
    1464             :     //if has manul event, just record the color and process manul event first
    1465           0 :     if ((maRenderEvent != EVENT_NONE))
    1466             :     {
    1467           0 :         return;
    1468             :     }
    1469             :     //calc the percentage of color change
    1470           0 :     int nColorRate = (nColor - nPreColor) * 100 / nPreColor;
    1471           0 :     nColorRate = abs(nColorRate);
    1472           0 :     if (nColorRate >= FLY_THRESHOLD)
    1473             :     {
    1474           0 :         maRenderEvent = EVENT_AUTO_FLY;
    1475           0 :         mnSelectBarId = nColorRate > mnColorRate ? nId : mnSelectBarId;
    1476           0 :         mnPreSelectBarId = mnSelectBarId;
    1477           0 :         mnColorRate = nColorRate > mnColorRate ? nColorRate : mnColorRate;
    1478             :     }
    1479             : }
    1480             : 
    1481           0 : IMPL_LINK_NOARG_TYPED(GL3DBarChart, UpdateTimerHdl, Idle *, void)
    1482             : {
    1483           0 :     updateScreenText();
    1484           0 :     maIdle.Start();
    1485           0 : }
    1486             : 
    1487           0 : void GL3DBarChart::setOpenGLWindow(OpenGLWindow* pWindow)
    1488             : {
    1489           0 :     if (mpWindow.get() != pWindow)
    1490             :     {
    1491           0 :         mpWindow = pWindow;
    1492           0 :         Size aSize = mpWindow->GetSizePixel();
    1493           0 :         mpRenderer->SetSize(aSize);
    1494           0 :         mpWindow->setRenderer(this);
    1495           0 :         mpWindow->getContext().makeCurrent();
    1496           0 :         mpRenderer->init();
    1497           0 :         mpWindow->getContext().resetCurrent();
    1498           0 :         mbValidContext = true;
    1499             :     }
    1500           0 : }
    1501             : 
    1502             : }
    1503             : 
    1504             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11