1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
10 #include <GL3DBarChart.hxx>
15 #include <glm/glm.hpp>
16 #include <glm/gtx/transform.hpp>
18 #include <3DChartObjects.hxx>
19 #include <GL3DRenderer.hxx>
20 #include <ExplicitCategoriesProvider.hxx>
21 #include <DataSeriesHelper.hxx>
25 #if !defined WIN32_LEAN_AND_MEAN
26 # define WIN32_LEAN_AND_MEAN
31 #include <o3tl/make_unique.hxx>
33 #define CALC_POS_EVENT_ID 1
34 #define SHAPE_START_ID 10
36 #define DATAUPDATE_FPS_TIME 1000
37 #define HISTORY_NUM 51
39 #define SHOW_VALUE_COUNT 15
40 #define SHOW_SCROLL_TEXT_DISTANCE 1000
41 #define FLY_THRESHOLD 20
42 #define DISPLAY_BARS_NUM 3
45 using namespace com::sun::star
;
49 const size_t STEPS
= 200;
50 const size_t STEPS_UPDATE
= 100;
53 const float TEXT_HEIGHT
= 10.0f
;
54 float DEFAULT_CAMERA_HEIGHT
= 500.0f
;
55 const sal_uInt32 ID_STEP
= 10;
57 const float BAR_SIZE_X
= 30.0f
;
58 const float BAR_SIZE_Y
= 5.0f
;
59 const float BAR_DISTANCE_X
= 5.0f
;
60 const float BAR_DISTANCE_Y
= 5.0;
62 float calculateTextWidth(const OUString
& rText
)
64 return rText
.getLength() * 10;
67 double findMaxValue(const std::vector
<std::unique_ptr
<VDataSeries
> >& rDataSeriesContainer
)
70 for (const std::unique_ptr
<VDataSeries
>& rDataSeries
: rDataSeriesContainer
)
72 sal_Int32 nPointCount
= rDataSeries
->getTotalPointCount();
73 for(sal_Int32 nIndex
= 0; nIndex
< nPointCount
; ++nIndex
)
75 double nVal
= rDataSeries
->getYValue(nIndex
);
76 nMax
= std::max(nMax
, nVal
);
82 class SharedResourceAccess
85 osl::Condition
& mrCond2
;
89 SharedResourceAccess(osl::Condition
& rCond1
, osl::Condition
& rCond2
):
95 ~SharedResourceAccess()
103 class RenderThread
: public salhelper::Thread
106 explicit RenderThread(GL3DBarChart
* pChart
);
111 GL3DBarChart
* mpChart
;
114 RenderThread::RenderThread(GL3DBarChart
* pChart
):
115 salhelper::Thread("RenderThread"),
120 void RenderThread::renderFrame()
122 if(!mpChart
->mbValidContext
)
125 mpChart
->mpWindow
->getContext().makeCurrent();
126 mpChart
->renderFrame();
127 // FIXME: SwapBuffers can take a considerable time, it'd be
128 // nice if we didn't hold the chart mutex while doing that.
129 mpChart
->mpWindow
->getContext().swapBuffers();
130 mpChart
->mpWindow
->getContext().resetCurrent();
133 class RenderOneFrameThread
: public RenderThread
136 explicit RenderOneFrameThread(GL3DBarChart
* pChart
):
142 virtual void execute() override
;
145 void RenderOneFrameThread::execute()
147 osl::MutexGuard
aGuard(mpChart
->maMutex
);
151 class RenderAnimationThread
: public RenderThread
154 RenderAnimationThread(GL3DBarChart
* pChart
, const glm::vec3
& rStartPos
, const glm::vec3
& rEndPos
,
155 const sal_Int32 nSteps
):
156 RenderThread(pChart
),
157 maStartPos(rStartPos
),
165 virtual void execute() override
;
168 glm::vec3 maStartPos
;
174 void RenderAnimationThread::execute()
176 osl::MutexGuard
aGuard(mpChart
->maMutex
);
177 glm::vec3 aStep
= (maEndPos
- maStartPos
)/static_cast<float>(mnSteps
);
178 for(sal_Int32 i
= 0; i
< mnSteps
; ++i
)
180 mpChart
->maCameraPosition
+= aStep
;
181 mpChart
->mpCamera
->setPosition(mpChart
->maCameraPosition
);
183 mpChart->maCameraDirection += mpChart->maStepDirection;
184 mpChart->mpCamera->setDirection(mpChart->maCameraDirection);
188 mpChart
->mpRenderer
->ReleaseScreenTextShapes();
191 class RenderBenchMarkThread
: public RenderThread
194 explicit RenderBenchMarkThread(GL3DBarChart
* pChart
)
195 : RenderThread(pChart
)
196 , mbAutoFlyExecuting(false)
198 , mbNeedFlyBack(false)
202 osl_getSystemTime(&maClickFlyBackStartTime
);
203 osl_getSystemTime(&maClickFlyBackEndTime
);
206 virtual void execute() override
;
208 void ProcessMouseEvent();
210 void MoveCameraToBar();
212 void MoveToSelectedBar();
213 void MoveToDefault();
215 void ProcessScroll();
216 void UpdateScreenText();
217 void ProcessClickFlyBack();
218 void AutoMoveToBar();
220 bool mbAutoFlyExecuting
;
224 glm::vec3 maStepDirection
;
225 glm::mat4 maMatrixStep
;
228 TimeValue maClickFlyBackStartTime
;
229 TimeValue maClickFlyBackEndTime
;
230 glm::vec3 maTargetPosition
;
231 glm::vec3 maTargetDirection
;
234 void RenderBenchMarkThread::MoveCamera()
236 if(mnStep
< mnStepsTotal
)
239 mpChart
->maCameraPosition
+= maStep
;
240 mpChart
->mpCamera
->setPosition(mpChart
->maCameraPosition
);
241 mpChart
->maCameraDirection
+= maStepDirection
;
242 mpChart
->mpCamera
->setDirection(mpChart
->maCameraDirection
);
248 mbAutoFlyExecuting
= false;
249 mbNeedFlyBack
= false;
250 mpChart
->maRenderEvent
= EVENT_NONE
;
254 void RenderBenchMarkThread::MoveCameraToBar()
256 if(mnStep
< mnStepsTotal
)
259 mpChart
->mpRenderer
->AddMatrixDiff(maMatrixStep
);
263 mpChart
->maCameraPosition
= maTargetPosition
;
264 mpChart
->maCameraDirection
= maTargetDirection
;
265 mpChart
->mpCamera
->setPosition(maTargetPosition
);
266 mpChart
->mpCamera
->setDirection(maTargetDirection
);
267 mpChart
->mpRenderer
->ResetMatrixDiff();
270 mbAutoFlyExecuting
= false;
271 mbNeedFlyBack
= true;
272 osl_getSystemTime(&maClickFlyBackStartTime
);
273 osl_getSystemTime(&maClickFlyBackEndTime
);
274 mpChart
->maRenderEvent
= EVENT_SHOW_SELECT
;
279 void RenderBenchMarkThread::MoveToDefault()
281 if ((mpChart
->maCameraPosition
== mpChart
->maDefaultCameraDirection
) &&
282 (mpChart
->maCameraDirection
== mpChart
->maDefaultCameraDirection
))
286 mpChart
->maRenderEvent
= EVENT_NONE
;
291 mpChart
->mpRenderer
->EndClick();
293 mnStepsTotal
= STEPS
;
294 maStep
= (mpChart
->maDefaultCameraPosition
- mpChart
->maCameraPosition
)/static_cast<float>(mnStepsTotal
);
295 maStepDirection
= (mpChart
->maDefaultCameraDirection
- mpChart
->maCameraDirection
)/static_cast<float>(mnStepsTotal
);
301 void RenderBenchMarkThread::MoveToBar()
305 mpChart
->mnSelectBarId
= mpChart
->barIdAtPosition(mpChart
->maClickPos
);
307 std::map
<sal_uInt32
, const GL3DBarChart::BarInformation
>::const_iterator itr
= mpChart
->maBarMap
.find(mpChart
->mnSelectBarId
);
308 if(itr
== mpChart
->maBarMap
.end())
310 mpChart
->mnSelectBarId
= mpChart
->mnPreSelectBarId
;
311 mpChart
->maRenderEvent
= mpChart
->maPreRenderEvent
;
312 mpChart
->maClickCond
.set();
315 mpChart
->mpRenderer
->EndClick();
316 const GL3DBarChart::BarInformation
& rBarInfo
= itr
->second
;
318 mnStepsTotal
= STEPS
;
319 maTargetPosition
= rBarInfo
.maPos
;
320 maTargetPosition
.z
+= 240;
321 maTargetPosition
.x
+= BAR_SIZE_X
/ 2.0f
;
322 maTargetDirection
= rBarInfo
.maPos
;
323 maTargetDirection
.x
+= BAR_SIZE_X
/ 2.0f
;
324 maTargetDirection
.y
+= BAR_SIZE_Y
/ 2.0f
;
325 maTargetPosition
.y
= maTargetDirection
.y
- 240;
326 maMatrixStep
= mpChart
->mpRenderer
->GetDiffOfTwoCameras(mpChart
->maCameraPosition
, maTargetPosition
, mpChart
->maCameraDirection
, maTargetDirection
)/static_cast<float>(mnStepsTotal
);
327 mpChart
->maClickCond
.set();
329 mbNeedFlyBack
= false;
330 mpChart
->mpRenderer
->StartClick(mpChart
->mnSelectBarId
);
335 void RenderBenchMarkThread::MoveToSelectedBar()
337 mpChart
->mnSelectBarId
= mpChart
->mnUpdateBarId
;
338 std::map
<sal_uInt32
, const GL3DBarChart::BarInformation
>::const_iterator itr
= mpChart
->maBarMap
.find(mpChart
->mnSelectBarId
);
339 if(itr
== mpChart
->maBarMap
.end())
341 mpChart
->mnSelectBarId
= mpChart
->mnPreSelectBarId
;
342 mpChart
->maRenderEvent
= mpChart
->maPreRenderEvent
;
343 mpChart
->maClickCond
.set();
346 mpChart
->mpRenderer
->EndClick();
347 const GL3DBarChart::BarInformation
& rBarInfo
= itr
->second
;
349 mnStepsTotal
= STEPS_UPDATE
;
350 maTargetPosition
= rBarInfo
.maPos
;
351 maTargetPosition
.z
+= 240;
352 maTargetPosition
.x
+= BAR_SIZE_X
/ 2.0f
;
353 maTargetDirection
= rBarInfo
.maPos
;
354 maTargetDirection
.x
+= BAR_SIZE_X
/ 2.0f
;
355 maTargetDirection
.y
+= BAR_SIZE_Y
/ 2.0f
;
356 maTargetPosition
.y
= maTargetDirection
.y
- 240;
357 maMatrixStep
= mpChart
->mpRenderer
->GetDiffOfTwoCameras( maTargetPosition
, maTargetDirection
)/static_cast<float>(mnStepsTotal
);
358 mpChart
->maClickCond
.set();
360 mbNeedFlyBack
= false;
361 mpChart
->mpRenderer
->StartClick(mpChart
->mnSelectBarId
);
362 mpChart
->maRenderEvent
= EVENT_CLICK
;
365 void RenderBenchMarkThread::AutoMoveToBar()
367 if (!mbAutoFlyExecuting
)
369 mpChart
->mpRenderer
->EndClick();
370 std::map
<sal_uInt32
, const GL3DBarChart::BarInformation
>::const_iterator itr
= mpChart
->maBarMap
.find(mpChart
->mnSelectBarId
);
371 if(itr
== mpChart
->maBarMap
.end())
373 mpChart
->maRenderEvent
= EVENT_NONE
;
376 const GL3DBarChart::BarInformation
& rBarInfo
= itr
->second
;
378 mnStepsTotal
= STEPS
;
379 maTargetPosition
= rBarInfo
.maPos
;
380 maTargetPosition
.z
+= 240;
381 maTargetPosition
.x
+= BAR_SIZE_X
/ 2.0f
;
382 maTargetDirection
= rBarInfo
.maPos
;
383 maTargetDirection
.x
+= BAR_SIZE_X
/ 2.0f
;
384 maTargetDirection
.y
+= BAR_SIZE_Y
/ 2.0f
;
385 maTargetPosition
.y
= maTargetDirection
.y
- 240;
386 maMatrixStep
= mpChart
->mpRenderer
->GetDiffOfTwoCameras(mpChart
->maCameraPosition
, maTargetPosition
, mpChart
->maCameraDirection
, maTargetDirection
)/static_cast<float>(mnStepsTotal
);
387 mpChart
->mpRenderer
->StartClick(mpChart
->mnSelectBarId
);
388 mbAutoFlyExecuting
= true;
389 mbNeedFlyBack
= false;
394 void RenderBenchMarkThread::MoveToCorner()
398 mpChart
->mpRenderer
->EndClick();
400 mnStepsTotal
= STEPS
;
401 maStep
= (mpChart
->getCornerPosition(mpChart
->mnCornerId
) - mpChart
->maCameraPosition
) / float(mnStepsTotal
);
402 maStepDirection
= (glm::vec3(mpChart
->mnMaxX
/2.0f
, mpChart
->mnMaxY
/2.0f
, 0) - mpChart
->maCameraDirection
)/ float(mnStepsTotal
);
408 void RenderBenchMarkThread::ProcessScroll()
410 //will add other process later
411 mpChart
->mpRenderer
->EndClick();
413 mnStepsTotal
= STEPS
;
414 mpChart
->maRenderEvent
= EVENT_SHOW_SCROLL
;
417 void RenderBenchMarkThread::ProcessClickFlyBack()
421 osl_getSystemTime(&maClickFlyBackEndTime
);
422 int nDeltaMs
= GL3DBarChart::calcTimeInterval(maClickFlyBackStartTime
, maClickFlyBackEndTime
);
423 if(nDeltaMs
>= 10000)
425 mpChart
->maRenderEvent
= EVENT_MOVE_TO_DEFAULT
;
429 void RenderBenchMarkThread::ProcessMouseEvent()
431 ProcessClickFlyBack();
432 if (mpChart
->maRenderEvent
== EVENT_SELECTBAR_UPDEDATE
)
436 else if (mpChart
->maRenderEvent
== EVENT_CLICK
)
440 else if (mpChart
->maRenderEvent
== EVENT_MOVE_TO_DEFAULT
)
444 else if ((mpChart
->maRenderEvent
== EVENT_DRAG_LEFT
) || (mpChart
->maRenderEvent
== EVENT_DRAG_RIGHT
))
448 else if (mpChart
->maRenderEvent
== EVENT_SCROLL
)
452 else if (mpChart
->maRenderEvent
== EVENT_AUTO_FLY
)
459 void RenderBenchMarkThread::UpdateScreenText()
461 if (mpChart
->mbScreenTextNewRender
)
463 mpChart
->mpWindow
->getContext().makeCurrent();
464 mpChart
->mpRenderer
->ReleaseScreenTextTexture();
465 for(std::unique_ptr
<opengl3D::Renderable3DObject
>& aObj
: mpChart
->maScreenTextShapes
)
469 mpChart
->mbScreenTextNewRender
= false;
470 mpChart
->mpWindow
->getContext().resetCurrent();
474 void RenderBenchMarkThread::execute()
479 osl::MutexGuard
aGuard(mpChart
->maMutex
);
480 mpChart
->maCond2
.reset();
481 if (mpChart
->mbRenderDie
)
486 mpChart
->miFrameCount
++;
488 if (mpChart
->maCond1
.check())
490 mpChart
->maCond1
.reset();
491 mpChart
->maCond2
.wait();
496 GL3DBarChart::GL3DBarChart(
497 const css::uno::Reference
<css::chart2::XChartType
>& xChartType
,
498 OpenGLWindow
* pWindow
) :
499 mxChartType(xChartType
),
500 mpRenderer(new opengl3D::OpenGL3DRenderer()),
503 mbValidContext(true),
504 mpTextCache(new opengl3D::TextCache
),
509 mbNeedsNewRender(true),
512 maRenderEvent(EVENT_NONE
),
513 maPreRenderEvent(EVENT_NONE
),
518 maIdle("chart2 view GL3DBarChart"),
519 mbScreenTextNewRender(false),
520 maFPS(OUString("Render FPS: 0")),
521 maDataUpdateFPS(OUString("Data Update FPS: 0")),
523 miDataUpdateCounter(0),
525 mbBenchMarkMode(false),
531 maFPSRenderStartTime
.Seconds
= maFPSRenderStartTime
.Nanosec
= 0;
532 maFPSRenderEndTime
.Seconds
= maFPSRenderEndTime
.Nanosec
= 0;
533 maDataUpdateStartTime
.Seconds
= maDataUpdateStartTime
.Nanosec
= 0;
534 maDataUpdateEndTime
.Seconds
= maDataUpdateEndTime
.Nanosec
= 0;
536 static const char *aBenchMark
= getenv("UNLOCK_FPS_MODE");
539 mbBenchMarkMode
= atoi(aBenchMark
);
543 static const char *scrollFrame
= getenv("SCROLL_RATE");
546 miScrollRate
= atoi(scrollFrame
);
547 if (miScrollRate
> 0)
550 mpRenderer
->SetScroll();
553 char *aAutoFly
= getenv("AUTO_FLY");
556 mbAutoFly
= atoi(aAutoFly
);
558 maIdle
.SetPriority(TaskPriority::REPAINT
);
559 maIdle
.SetInvokeHandler(LINK(this, GL3DBarChart
, UpdateTimerHdl
));
560 maIdle
.SetDebugName( "charttypes::GL3DBarChart maIdle" );
562 osl_getSystemTime(&maFPSRenderStartTime
);
563 osl_getSystemTime(&maFPSRenderEndTime
);
564 osl_getSystemTime(&maDataUpdateStartTime
);
565 osl_getSystemTime(&maDataUpdateEndTime
);
567 Size aSize
= mpWindow
->GetSizePixel();
568 mpRenderer
->SetSize(aSize
);
569 mpWindow
->setRenderer(this);
570 mpWindow
->getContext().makeCurrent();
572 mpWindow
->getContext().resetCurrent();
575 GL3DBarChart::BarInformation::BarInformation(const glm::vec3
& rPos
, float nVal
):
581 GL3DBarChart::~GL3DBarChart()
585 SharedResourceAccess
aResGuard(maCond1
, maCond2
);
586 osl::MutexGuard
aGuard(maMutex
);
594 mpWindow
->setRenderer(nullptr);
595 mpWindow
->getContext().makeCurrent();
597 mpWindow
->getContext().resetCurrent();
601 void GL3DBarChart::create3DShapes(const std::vector
<std::unique_ptr
<VDataSeries
> >& rDataSeriesContainer
,
602 ExplicitCategoriesProvider
& rCatProvider
)
604 SharedResourceAccess
aResGuard(maCond1
, maCond2
);
605 osl::MutexGuard
aGuard(maMutex
);
608 int nSelectBarId
= mnSelectBarId
;
609 int nPreSelectBarId
= nSelectBarId
;
611 sal_uInt32 nSelectRow
= (nSelectBarId
- SHAPE_START_ID
) / ID_STEP
/ (mnBarsInRow
+ 1);
612 sal_uInt32 nPreSelectRow
= (nPreSelectBarId
- SHAPE_START_ID
) / ID_STEP
/ (mnBarsInRow
+ 1);
613 if(nSelectRow
== nPreSelectRow
)
615 std::map
<sal_uInt32
, const GL3DBarChart::BarInformation
>::const_iterator itr
= maBarMap
.find(nSelectBarId
);
616 if((maRenderEvent
== EVENT_CLICK
|| maRenderEvent
== EVENT_SHOW_SELECT
|| maRenderEvent
== EVENT_AUTO_FLY
)&&(itr
!= maBarMap
.end()))
618 mnUpdateBarId
= nSelectBarId
;
619 maRenderEvent
= EVENT_SELECTBAR_UPDEDATE
;
623 mpRenderer
->ReleaseShapes();
624 // Each series of data flows from left to right, and multiple series are
625 // stacked vertically along y axis.
627 sal_uInt32 nId
= SHAPE_START_ID
;
631 const Color aSeriesColor
[] = {
632 COL_RED
, COL_GREEN
, COL_YELLOW
, COL_BROWN
, COL_BLUE
635 maCategories
.clear();
636 maSeriesNames
.clear();
637 maSeriesNames
.reserve(rDataSeriesContainer
.size());
644 maShapes
.push_back(o3tl::make_unique
<opengl3D::Camera
>(mpRenderer
.get()));
645 mpCamera
= static_cast<opengl3D::Camera
*>(maShapes
.back().get());
647 sal_Int32 nSeriesIndex
= 0;
648 sal_Int32 nMaxPointCount
= 0;
649 double nMaxVal
= findMaxValue(rDataSeriesContainer
)/100;
650 if (rDataSeriesContainer
.empty())
656 const VDataSeries
& rFirstRow
= *rDataSeriesContainer
.begin()->get();
657 mnBarsInRow
= rFirstRow
.getTotalPointCount();
659 for (const std::unique_ptr
<VDataSeries
>& rDataSeries
: rDataSeriesContainer
)
661 nYPos
= nSeriesIndex
* (BAR_SIZE_Y
+ BAR_DISTANCE_Y
) + BAR_DISTANCE_Y
;
663 sal_Int32 nPointCount
= rDataSeries
->getTotalPointCount();
664 nMaxPointCount
= std::max(nMaxPointCount
, nPointCount
);
666 bool bMappedFillProperty
= rDataSeries
->hasPropertyMapping("FillColor");
668 // Create series name text object.
669 OUString aSeriesName
=
670 DataSeriesHelper::getDataSeriesLabel(
671 rDataSeries
->getModel(), mxChartType
->getRoleOfSequenceForSeriesLabel());
673 maSeriesNames
.push_back(aSeriesName
);
675 if(!aSeriesName
.isEmpty())
677 maShapes
.push_back(o3tl::make_unique
<opengl3D::Text
>(mpRenderer
.get(),
678 *mpTextCache
, aSeriesName
, nId
));
680 opengl3D::Text
* p
= static_cast<opengl3D::Text
*>(maShapes
.back().get());
681 glm::vec3 aTopLeft
, aTopRight
, aBottomRight
;
682 aTopRight
.x
= -BAR_DISTANCE_Y
;
683 aTopRight
.y
= nYPos
+ BAR_DISTANCE_Y
;
684 aTopLeft
.x
= calculateTextWidth(aSeriesName
) * -1.0 - BAR_DISTANCE_Y
;
685 aTopLeft
.y
= nYPos
+ BAR_DISTANCE_Y
;
686 aBottomRight
= aTopRight
;
687 aBottomRight
.y
-= TEXT_HEIGHT
;
688 p
->setPosition(aTopLeft
, aTopRight
, aBottomRight
);
691 Color nColor
= aSeriesColor
[nSeriesIndex
% SAL_N_ELEMENTS(aSeriesColor
)];
692 for(sal_Int32 nIndex
= 0; nIndex
< nPointCount
; ++nIndex
)
694 if(bMappedFillProperty
)
696 double nPropVal
= rDataSeries
->getValueByProperty(nIndex
, "FillColor");
697 if(!rtl::math::isNan(nPropVal
))
698 nColor
= Color(static_cast<sal_uInt32
>(nPropVal
));
701 float nVal
= rDataSeries
->getYValue(nIndex
);
702 if (rtl::math::isNan(nVal
))
705 float nXPos
= nIndex
* (BAR_SIZE_X
+ BAR_DISTANCE_X
) + BAR_DISTANCE_X
;
707 glm::mat4 aScaleMatrix
= glm::scale(glm::vec3(BAR_SIZE_X
, BAR_SIZE_Y
, float(nVal
/nMaxVal
)));
708 glm::mat4 aTranslationMatrix
= glm::translate(glm::vec3(nXPos
, nYPos
, 0.0f
));
709 glm::mat4 aBarPosition
= aTranslationMatrix
* aScaleMatrix
;
711 maBarMap
.insert(std::pair
<sal_uInt32
, BarInformation
>(nId
,
712 BarInformation(glm::vec3(nXPos
, nYPos
, float(nVal
/nMaxVal
)),
714 recordBarHistory(nId
, nVal
);
717 auto it
= maBarColorMap
.find(nId
);
718 if (it
== maBarColorMap
.end())
720 maBarColorMap
[nId
] = nColor
;
725 processAutoFly(nId
, nColor
);
728 maShapes
.push_back(o3tl::make_unique
<opengl3D::Bar
>(mpRenderer
.get(), aBarPosition
, nColor
, nId
));
732 float nThisXEnd
= nPointCount
* (BAR_SIZE_X
+ BAR_DISTANCE_X
);
733 if (nXEnd
< nThisXEnd
)
739 nYPos
+= BAR_SIZE_Y
+ BAR_DISTANCE_Y
;
742 maShapes
.push_back(o3tl::make_unique
<opengl3D::Line
>(mpRenderer
.get(), nId
));
744 opengl3D::Line
* pAxis
= static_cast<opengl3D::Line
*>(maShapes
.back().get());
747 glm::vec3 aEnd
= aBegin
;
748 aEnd
.x
= mbBenchMarkMode
? (mbScrollFlg
? nXEnd
- BAR_SIZE_X
: nXEnd
) : nXEnd
;
749 pAxis
->setPosition(aBegin
, aEnd
);
750 pAxis
->setLineColor(COL_BLUE
);
753 maShapes
.push_back(o3tl::make_unique
<opengl3D::Line
>(mpRenderer
.get(), nId
));
755 pAxis
= static_cast<opengl3D::Line
*>(maShapes
.back().get());
756 aBegin
.x
= aBegin
.y
= 0;
759 pAxis
->setPosition(aBegin
, aEnd
);
760 pAxis
->setLineColor(COL_BLUE
);
763 maShapes
.push_back(o3tl::make_unique
<opengl3D::Rectangle
>(mpRenderer
.get(), nId
));
765 opengl3D::Rectangle
* pRect
= static_cast<opengl3D::Rectangle
*>(maShapes
.back().get());
767 glm::vec3 aTopRight
= aTopLeft
;
768 aTopRight
.x
= mbBenchMarkMode
? (mbScrollFlg
? nXEnd
- BAR_SIZE_X
: nXEnd
+ 2 * BAR_DISTANCE_X
) : (nXEnd
+ 2 * BAR_DISTANCE_X
);
769 glm::vec3 aBottomRight
= aTopRight
;
770 aBottomRight
.y
= nYPos
;
771 pRect
->setPosition(aTopLeft
, aTopRight
, aBottomRight
);
772 pRect
->setFillColor(COL_BLACK
);
773 pRect
->setLineColor(COL_BLUE
);
775 mpRenderer
->SetSceneEdge(BAR_DISTANCE_X
- 0.001f
, aTopRight
.x
- BAR_DISTANCE_X
);
777 mpRenderer
->SetSceneEdge(-0.001f
, aTopRight
.x
);
778 // Create category texts along X-axis at the bottom.
779 uno::Sequence
<OUString
> aCats
= rCatProvider
.getSimpleCategories();
780 for (sal_Int32 i
= 0; i
< aCats
.getLength(); ++i
)
782 if (mbBenchMarkMode
&& mbScrollFlg
&& (i
+ 1 == aCats
.getLength()))
784 maCategories
.push_back(aCats
[i
]);
785 if(aCats
[i
].isEmpty())
788 float nXPos
= i
* (BAR_SIZE_X
+ BAR_DISTANCE_X
);
790 maShapes
.push_back(o3tl::make_unique
<opengl3D::Text
>(mpRenderer
.get(), *mpTextCache
,
793 opengl3D::Text
* p
= static_cast<opengl3D::Text
*>(maShapes
.back().get());
794 aTopLeft
.x
= nXPos
+ TEXT_HEIGHT
+ 0.5 * BAR_SIZE_X
;
795 aTopLeft
.y
= nYPos
+ calculateTextWidth(aCats
[i
]) + 0.5 * BAR_DISTANCE_Y
;
796 aTopRight
= aTopLeft
;
797 aTopRight
.y
= nYPos
+ 0.5* BAR_DISTANCE_Y
;
798 aBottomRight
.x
= nXPos
;
799 aBottomRight
.y
= nYPos
+ 0.5 * BAR_DISTANCE_Y
;
800 p
->setPosition(aTopLeft
, aTopRight
, aBottomRight
);
802 // create shapes on other side as well
804 maShapes
.push_back(o3tl::make_unique
<opengl3D::Text
>(mpRenderer
.get(), *mpTextCache
,
807 p
= static_cast<opengl3D::Text
*>(maShapes
.back().get());
808 aTopLeft
.x
= nXPos
+ TEXT_HEIGHT
+ 0.5 * BAR_SIZE_X
;
809 aTopLeft
.y
= - 0.5 * BAR_DISTANCE_Y
;
810 aTopRight
= aTopLeft
;
811 aTopRight
.y
= -calculateTextWidth(aCats
[i
]) - 0.5* BAR_DISTANCE_Y
;
812 aBottomRight
.x
= nXPos
;
813 aBottomRight
.y
= -calculateTextWidth(aCats
[i
]) - 0.5 * BAR_DISTANCE_Y
;
814 p
->setPosition(aTopLeft
, aTopRight
, aBottomRight
);
817 mnMaxX
= nMaxPointCount
* (BAR_SIZE_X
+ BAR_DISTANCE_X
) + 40;
818 mnMaxY
= nSeriesIndex
* (BAR_SIZE_Y
+ BAR_DISTANCE_Y
) + 40;
821 mnDistance
= std::sqrt(mnMaxX
* mnMaxX
+ mnMaxY
* mnMaxY
+ DEFAULT_CAMERA_HEIGHT
* DEFAULT_CAMERA_HEIGHT
);
822 maDefaultCameraDirection
= glm::vec3(mnMaxX
* 0.4, mnMaxY
* 0.35, 0);
823 maDefaultCameraPosition
= glm::vec3(maDefaultCameraDirection
.x
, maDefaultCameraDirection
.y
- mnDistance
, DEFAULT_CAMERA_HEIGHT
* 2);
826 float pi
= 3.1415926f
;
827 float nAngleX
= -pi
/ 6.5f
;
828 float nAngleZ
= -pi
/ 8.0f
;
829 glm::mat4 aDefaultRotateMatrix
= glm::eulerAngleYXZ(0.0f
, nAngleX
, nAngleZ
);
830 maDefaultCameraPosition
= glm::vec3(aDefaultRotateMatrix
* glm::vec4(maDefaultCameraPosition
, 1.0f
));
831 maCameraPosition
= maDefaultCameraPosition
;
832 maCameraDirection
= maDefaultCameraDirection
;
833 mpCamera
->setPosition(maCameraPosition
);
834 mpCamera
->setDirection(maCameraDirection
);
838 mpCamera
->setPosition(maCameraPosition
);
839 mpCamera
->setDirection(maCameraDirection
);
841 if (mbBenchMarkMode
&& (!mpRenderThread
.is()))
843 //if scroll the bars, set the speed and distance first
846 mpRenderer
->SetScrollSpeed((BAR_SIZE_X
+ BAR_DISTANCE_X
) / static_cast<float>(miScrollRate
));
847 mpRenderer
->SetScrollDistance(BAR_SIZE_X
+ BAR_DISTANCE_X
);
849 spawnRenderThread(new RenderBenchMarkThread(this));
851 miDataUpdateCounter
++;
853 mbNeedsNewRender
= true;
856 void GL3DBarChart::joinRenderThread()
858 if(mpRenderThread
.is())
860 // FIXME: badly want to assert that we don't
861 // hold the mutex here ... but can't API-wise.
862 mpRenderThread
->join();
866 void GL3DBarChart::spawnRenderThread(RenderThread
*pThread
)
868 joinRenderThread(); // not holding maMutex
870 osl::MutexGuard
aGuard(maMutex
);
872 Size aSize
= mpWindow
->GetSizePixel();
873 mpWindow
->getContext().setWinSize(aSize
);
874 mpRenderThread
.set(pThread
);
875 mpWindow
->getContext().resetCurrent();
876 mpRenderThread
->launch();
879 void GL3DBarChart::update()
883 spawnRenderThread(new RenderOneFrameThread(this));
886 void GL3DBarChart::moveToDefault()
890 // add correct handling here!!
891 if ((maRenderEvent
!= EVENT_NONE
) && (maRenderEvent
!= EVENT_SHOW_SCROLL
) &&
892 (maRenderEvent
!= EVENT_AUTO_FLY
) && (maRenderEvent
!= EVENT_SHOW_SELECT
))
896 SharedResourceAccess
aResGuard(maCond1
, maCond2
);
897 osl::MutexGuard
aGuard(maMutex
);
898 maRenderEvent
= EVENT_MOVE_TO_DEFAULT
;
903 spawnRenderThread(new RenderAnimationThread(this, maCameraPosition
, maDefaultCameraPosition
, STEPS
));
906 * TODO: moggi: add to thread
907 glm::vec3 maTargetDirection = maDefaultCameraDirection;
908 maStepDirection = (maTargetDirection - maCameraDirection)/((float)mnStepsTotal);
912 sal_uInt32
GL3DBarChart::barIdAtPosition(const Point
& rPos
)
916 osl::MutexGuard
aGuard(maMutex
);
917 mpWindow
->getContext().makeCurrent();
918 mpRenderer
->SetPickingMode(true);
920 nId
= sal_uInt32(mpRenderer
->GetPixelColorFromPoint(rPos
.X(), rPos
.Y()));
921 mpRenderer
->SetPickingMode(false);
922 mpWindow
->getContext().resetCurrent();
927 void GL3DBarChart::clickedAt(const Point
& rPos
, sal_uInt16 nButtons
)
929 if (nButtons
== MOUSE_RIGHT
)
935 if(nButtons
!= MOUSE_LEFT
)
940 // add correct handling here !!
941 if ((maRenderEvent
!= EVENT_NONE
) && (maRenderEvent
!= EVENT_SHOW_SCROLL
) &&
942 (maRenderEvent
!= EVENT_AUTO_FLY
) && (maRenderEvent
!= EVENT_SHOW_SELECT
))
946 SharedResourceAccess
aResGuard(maCond1
, maCond2
);
947 osl::MutexGuard
aGuard(maMutex
);
949 mnPreSelectBarId
= mnSelectBarId
;
950 maPreRenderEvent
= maRenderEvent
;
951 maRenderEvent
= EVENT_CLICK
;
958 sal_uInt32 nId
= barIdAtPosition(rPos
);
960 std::map
<sal_uInt32
, const BarInformation
>::const_iterator itr
=
963 if(itr
== maBarMap
.end())
966 const BarInformation
& rBarInfo
= itr
->second
;
969 osl::MutexGuard
aGuard(maMutex
);
970 mpWindow
->getContext().makeCurrent();
971 glm::vec3 aTextPos
= glm::vec3(rBarInfo
.maPos
.x
+ BAR_SIZE_X
/ 2.0f
,
972 rBarInfo
.maPos
.y
+ BAR_SIZE_Y
/ 2.0f
,
974 maShapes
.push_back(o3tl::make_unique
<opengl3D::ScreenText
>(mpRenderer
.get(), *mpTextCache
,
975 "Value: " + OUString::number(rBarInfo
.mnVal
), glm::vec4(0.0f
, 0.0f
, 1.0f
, 1.0f
), CALC_POS_EVENT_ID
));
976 opengl3D::ScreenText
* pScreenText
= static_cast<opengl3D::ScreenText
*>(maShapes
.back().get());
977 pScreenText
->setPosition(glm::vec2(-0.9f
, 0.9f
), glm::vec2(-0.6f
, 0.8f
), aTextPos
);
978 pScreenText
->render();
979 mpWindow
->getContext().resetCurrent();
982 glm::vec3 aTargetPosition
= rBarInfo
.maPos
;
983 aTargetPosition
.z
+= 240;
984 aTargetPosition
.y
+= BAR_SIZE_Y
/ 2.0f
;
986 spawnRenderThread(new RenderAnimationThread(this, maCameraPosition
,
987 aTargetPosition
, STEPS
));
990 * TODO: moggi: add to thread
991 glm::vec3 maTargetDirection = rBarInfo.maPos;
992 maTargetDirection.x += BAR_SIZE_X / 2.0f;
993 maTargetDirection.y += BAR_SIZE_Y / 2.0f;
995 maStepDirection = (maTargetDirection - maCameraDirection)/((float)mnStepsTotal);
999 void GL3DBarChart::render()
1001 if (mbBenchMarkMode
)
1007 void GL3DBarChart::renderFrame()
1009 Size aSize
= mpWindow
->GetSizePixel();
1010 mpRenderer
->SetSize(aSize
);
1011 if(mbNeedsNewRender
)
1013 mpRenderer
->ReleaseTextTexture();
1014 for(std::unique_ptr
<opengl3D::Renderable3DObject
>& aObj
: maShapes
)
1023 mpRenderer
->ProcessUnrenderedShape(mbNeedsNewRender
);
1024 mbNeedsNewRender
= false;
1027 void GL3DBarChart::mouseDragMove(const Point
& rStartPos
, const Point
& rEndPos
, sal_uInt16
)
1029 long nDirection
= rEndPos
.X() - rStartPos
.X();
1030 SharedResourceAccess
aResGuard(maCond1
, maCond2
);
1031 osl::ClearableGuard
<osl::Mutex
> aGuard(maMutex
);
1032 if ((maRenderEvent
== EVENT_NONE
) || (maRenderEvent
== EVENT_SHOW_SCROLL
) ||
1033 (maRenderEvent
== EVENT_AUTO_FLY
) || (maRenderEvent
== EVENT_SHOW_SELECT
))
1034 maRenderEvent
= nDirection
> 0 ? EVENT_DRAG_RIGHT
: EVENT_DRAG_LEFT
;
1038 mnCornerId
= (mnCornerId
+ 1) % 4;
1041 else if(nDirection
> 0)
1043 mnCornerId
= mnCornerId
- 1;
1056 glm::vec3
GL3DBarChart::getCornerPosition(sal_Int8 nId
)
1058 float pi
= 3.1415926f
;
1063 return glm::vec3(mnMaxX
/ 2 - mnDistance
* std::sin(pi
/ 4), mnMaxY
/ 2 - mnDistance
* std::cos(pi
/ 4), DEFAULT_CAMERA_HEIGHT
* 2);
1068 return glm::vec3(mnMaxX
/ 2 + mnDistance
* std::sin(pi
/ 4), mnMaxY
/ 2 - mnDistance
* std::cos(pi
/ 4), DEFAULT_CAMERA_HEIGHT
* 2);
1073 return glm::vec3(mnMaxX
/ 2 + mnDistance
* std::sin(pi
/ 4), mnMaxY
/ 2 + mnDistance
* std::cos(pi
/ 4), DEFAULT_CAMERA_HEIGHT
* 2);
1078 return glm::vec3(mnMaxX
/ 2 - mnDistance
* std::sin(pi
/ 4), mnMaxY
/ 2 + mnDistance
* std::cos(pi
/ 4), DEFAULT_CAMERA_HEIGHT
* 2);
1084 return maDefaultCameraPosition
;
1087 void GL3DBarChart::moveToCorner()
1091 // add correct handling here!!
1095 spawnRenderThread(new RenderAnimationThread(this, maCameraPosition
,
1096 getCornerPosition(mnCornerId
), STEPS
));
1098 // TODO: moggi: add to thread
1099 // maStepDirection = (glm::vec3(mnMaxX/2.0f, mnMaxY/2.0f, 0) - maCameraDirection)/ float(mnStepsTotal);
1102 void GL3DBarChart::scroll(long nDelta
)
1105 SharedResourceAccess
aResGuard(maCond1
, maCond2
);
1106 osl::MutexGuard
aGuard(maMutex
);
1107 if ((maRenderEvent
!= EVENT_NONE
) && (maRenderEvent
!= EVENT_SHOW_SCROLL
) &&
1108 (maRenderEvent
!= EVENT_AUTO_FLY
) && (maRenderEvent
!= EVENT_SHOW_SELECT
))
1110 glm::vec3 aDir
= glm::normalize(maCameraPosition
- maCameraDirection
);
1111 maCameraPosition
-= (static_cast<float>(nDelta
)/10) * aDir
;
1112 mpCamera
->setPosition(maCameraPosition
);
1115 maVectorNearest
.clear();
1116 getNearestBars(maVectorNearest
);
1117 maRenderEvent
= EVENT_SCROLL
;
1124 void GL3DBarChart::contextDestroyed()
1126 SharedResourceAccess
aResGuard(maCond1
, maCond2
);
1127 osl::MutexGuard
aGuard(maMutex
);
1128 mpWindow
->getContext().makeCurrent();
1130 mpWindow
->getContext().resetCurrent();
1131 mbValidContext
= false;
1134 float GL3DBarChart::addScreenTextShape(OUString
&nStr
, const glm::vec2
& rLeftOrRightTop
, float nTextHeight
, bool bLeftTopFlag
,
1135 const glm::vec4
& rColor
, const glm::vec3
& rPos
, sal_uInt32 nEvent
)
1137 maScreenTextShapes
.push_back(o3tl::make_unique
<opengl3D::ScreenText
>(mpRenderer
.get(), *mpTextCache
, nStr
, rColor
, nEvent
));
1138 const opengl3D::TextCacheItem
& rTextCache
= mpTextCache
->getText(nStr
);
1139 float nRectWidth
= static_cast<float>(rTextCache
.maSize
.Width()) / static_cast<float>(rTextCache
.maSize
.Height()) * nTextHeight
/ 2.0f
;
1140 opengl3D::ScreenText
* pScreenText
= static_cast<opengl3D::ScreenText
*>(maScreenTextShapes
.back().get());
1142 pScreenText
->setPosition(rLeftOrRightTop
, glm::vec2(rLeftOrRightTop
.x
+ nRectWidth
, rLeftOrRightTop
.y
- nTextHeight
), rPos
);
1144 pScreenText
->setPosition(glm::vec2(rLeftOrRightTop
.x
- nRectWidth
, rLeftOrRightTop
.y
), glm::vec2(rLeftOrRightTop
.x
, rLeftOrRightTop
.y
- nTextHeight
), rPos
);
1148 void GL3DBarChart::updateRenderFPS()
1150 int nDeltaMs
= calcTimeInterval(maFPSRenderStartTime
, maFPSRenderEndTime
);
1151 if(nDeltaMs
>= FPS_TIME
)
1153 osl_getSystemTime(&maFPSRenderEndTime
);
1154 nDeltaMs
= calcTimeInterval(maFPSRenderStartTime
, maFPSRenderEndTime
);
1155 int iFPS
= miFrameCount
* 1000 / nDeltaMs
;
1156 maFPS
= OUString::number(iFPS
);
1158 osl_getSystemTime(&maFPSRenderStartTime
);
1160 osl_getSystemTime(&maFPSRenderEndTime
);
1161 OUString aFPS
= "Render FPS: ";
1162 addScreenTextShape(aFPS
, glm::vec2(-0.77f
, 0.99f
), 0.07f
, false, glm::vec4(0.0f
, 1.0f
, 1.0f
, 0.0f
));
1163 addScreenTextShape(maFPS
, glm::vec2(-0.77f
, 0.99f
), 0.07f
, true,
1164 glm::vec4(1.0f
, 0.0f
, 0.0f
, 0.0f
), glm::vec3(0.0f
, 0.0f
, 0.0f
));
1167 int GL3DBarChart::calcTimeInterval(TimeValue
const &startTime
, TimeValue
const &endTime
)
1170 aTime
.Seconds
= endTime
.Seconds
- startTime
.Seconds
- 1;
1171 aTime
.Nanosec
= 1000000000 + endTime
.Nanosec
- startTime
.Nanosec
;
1172 aTime
.Seconds
+= aTime
.Nanosec
/ 1000000000;
1173 aTime
.Nanosec
%= 1000000000;
1174 return aTime
.Seconds
* 1000+aTime
.Nanosec
/ 1000000;
1177 void GL3DBarChart::updateScreenText()
1179 SharedResourceAccess
aResGuard(maCond1
, maCond2
);
1180 osl::MutexGuard
aGuard(maMutex
);
1181 maScreenTextShapes
.clear();
1182 mpRenderer
->ReleaseScreenTextShapes();
1184 updateDataUpdateFPS();
1187 mbScreenTextNewRender
= true;
1190 void GL3DBarChart::updateDataUpdateFPS()
1192 int nDeltaMs
= calcTimeInterval(maDataUpdateStartTime
, maDataUpdateEndTime
);
1193 if(nDeltaMs
>= DATAUPDATE_FPS_TIME
)
1195 int iFPS
= miDataUpdateCounter
* 1000 / nDeltaMs
;
1198 maDataUpdateFPS
= OUString::number(iFPS
);
1202 float fFPS
= static_cast<float>(miDataUpdateCounter
) * 1000 / static_cast<float>(nDeltaMs
);
1203 maDataUpdateFPS
= OUString::number(fFPS
);
1205 miDataUpdateCounter
= 0;
1206 osl_getSystemTime(&maDataUpdateStartTime
);
1208 osl_getSystemTime(&maDataUpdateEndTime
);
1209 OUString aDataUpdateFPS
= "Data Update Rate: ";
1210 addScreenTextShape(aDataUpdateFPS
, glm::vec2(-0.77, 0.92f
), 0.07f
, false, glm::vec4(0.0f
, 1.0f
, 1.0f
, 0.0f
));
1211 addScreenTextShape(maDataUpdateFPS
, glm::vec2(-0.77f
, 0.92f
), 0.07f
, true, glm::vec4(1.0f
, 0.0f
, 0.0f
, 0.0f
));
1214 void GL3DBarChart::recordBarHistory(sal_uInt32 nBarID
, float nVal
)
1216 std::deque
<float>& aList
= maBarHistory
[nBarID
];
1217 if(aList
.size() == HISTORY_NUM
)
1219 aList
.push_back(nVal
);
1222 void GL3DBarChart::getNeighborBarID(sal_uInt32 nSelectBarId
, sal_uInt32
*pNeighborBarId
)
1224 sal_uInt32 nSelectRow
= (nSelectBarId
- SHAPE_START_ID
) / ID_STEP
/ (mnBarsInRow
+ 1);
1225 for (sal_Int32 i
= 0; i
< DISPLAY_BARS_NUM
; i
++)
1227 pNeighborBarId
[i
] = nSelectBarId
+ (i
- DISPLAY_BARS_NUM
/ 2) * ID_STEP
;
1228 if (pNeighborBarId
[i
] == nSelectBarId
)
1230 if ((pNeighborBarId
[i
] - SHAPE_START_ID
) / ID_STEP
/ (mnBarsInRow
+ 1) != nSelectRow
)
1231 pNeighborBarId
[i
] = 0;
1235 void GL3DBarChart::addMovementScreenText(sal_uInt32 nBarId
)
1239 std::map
<sal_uInt32
, const BarInformation
>::const_iterator itr
= maBarMap
.find(nBarId
);
1240 if (itr
== maBarMap
.end())
1242 const BarInformation
& rBarInfo
= itr
->second
;
1243 glm::vec3 aTextPos
= glm::vec3(rBarInfo
.maPos
.x
+ BAR_SIZE_X
/ 2.0f
,
1244 rBarInfo
.maPos
.y
+ BAR_SIZE_Y
/ 2.0f
,
1246 OUString aBarValue
= "Value: " + OUString::number(rBarInfo
.mnVal
);
1247 maScreenTextShapes
.push_back(o3tl::make_unique
<opengl3D::ScreenText
>(mpRenderer
.get(), *mpTextCache
, aBarValue
, glm::vec4(0.0f
, 0.0f
, 1.0f
, 0.0f
), CALC_POS_EVENT_ID
, true));
1248 const opengl3D::TextCacheItem
& rTextCache
= mpTextCache
->getText(aBarValue
);
1249 float nRectWidth
= static_cast<float>(rTextCache
.maSize
.Width()) / static_cast<float>(rTextCache
.maSize
.Height()) * 0.024;
1250 opengl3D::ScreenText
* pScreenText
= static_cast<opengl3D::ScreenText
*>(maScreenTextShapes
.back().get());
1251 pScreenText
->setPosition(glm::vec2(-nRectWidth
/ 2, 0.03f
), glm::vec2(nRectWidth
/ 2, -0.03f
), aTextPos
);
1254 void GL3DBarChart::updateClickEvent()
1256 if (maRenderEvent
== EVENT_CLICK
|| maRenderEvent
== EVENT_AUTO_FLY
|| maRenderEvent
== EVENT_SHOW_SELECT
)
1258 std::deque
<float>& aList
= maBarHistory
[mnSelectBarId
];
1259 sal_uInt32 nIdex
= 0;
1260 sal_uInt32 nBarIdArray
[DISPLAY_BARS_NUM
] = {0};
1263 float nXCoordStart
, nYCoordStart
, nTextWidth
, nMaxXCoord
= 0.0f
, nMinXCoord
= 1.0f
, nMaxHight
= 0.0f
;
1265 if (aList
.size() > 1)
1268 nTextWidth
= addScreenTextShape(aTitle
, glm::vec2(0.875, 0.99f
), 0.07f
, false, glm::vec4(0.0f
, 1.0f
, 1.0f
, 0.5f
));
1269 nMinXCoord
= std::min(nMinXCoord
, 0.875f
- nTextWidth
);
1271 nTextWidth
= addScreenTextShape(aTitle
, glm::vec2(0.875f
, 0.99f
), 0.07f
, true, glm::vec4(0.0f
, 1.0f
, 1.0f
, 0.5f
));
1272 nMaxXCoord
= std::max(nMaxXCoord
, 0.875f
+ nTextWidth
);
1274 if (aList
.size() > COLUMNSIZE
)
1277 nTextWidth
= addScreenTextShape(aTitle
, glm::vec2(0.55f
, 0.99f
), 0.07f
, false, glm::vec4(0.0f
, 1.0f
, 1.0f
, 0.5f
));
1278 nMinXCoord
= std::min(nMinXCoord
, 0.55f
- nTextWidth
);
1280 nTextWidth
= addScreenTextShape(aTitle
, glm::vec2(0.55f
, 0.99f
), 0.07f
, true, glm::vec4(0.0f
, 1.0f
, 1.0f
, 0.5f
));
1281 nMaxXCoord
= std::max(nMaxXCoord
, 0.55f
+ nTextWidth
);
1283 getNeighborBarID(mnSelectBarId
, nBarIdArray
);
1284 for (auto const& elem
: aList
)
1286 if (nIdex
+ 1 < aList
.size())
1288 aTitle
= "[Time:" + OUString::number((mnHistoryCounter
- aList
.size() + nIdex
)) + "]: ";
1291 aTitle
= "Most Recent" + aTitle
;
1293 if (aList
.size() <= COLUMNSIZE
)
1295 nXCoordStart
= 0.875f
;
1296 nYCoordStart
= (nIdex
+ 1) * 0.07f
;
1300 nXCoordStart
= nIdex
< COLUMNSIZE
? 0.55f
: 0.875f
;
1301 nYCoordStart
= nIdex
< COLUMNSIZE
? (nIdex
+ 1) * 0.07f
: (nIdex
- 24) * 0.07f
;
1303 nMaxHight
= std::max(nMaxHight
, nYCoordStart
+ 0.07f
);
1304 nTextWidth
= addScreenTextShape(aTitle
, glm::vec2(nXCoordStart
, 0.99f
- nYCoordStart
), 0.07f
, false, glm::vec4(0.0f
, 1.0f
, 1.0f
, 0.5f
));
1305 nMinXCoord
= std::min(nMinXCoord
, nXCoordStart
- nTextWidth
);
1306 aBarValue
= OUString::number(elem
);
1307 nTextWidth
= addScreenTextShape(aBarValue
, glm::vec2(nXCoordStart
, 0.99f
- nYCoordStart
), 0.07f
, true, glm::vec4(0.0f
, 1.0f
, 1.0f
, 0.5f
));
1308 nMaxXCoord
= std::max(nMaxXCoord
, nXCoordStart
+ nTextWidth
);
1312 for (unsigned int i
: nBarIdArray
)
1314 addMovementScreenText(i
);
1316 //add translucent back ground
1318 maScreenTextShapes
.push_back(o3tl::make_unique
<opengl3D::ScreenText
>(mpRenderer
.get(), *mpTextCache
, aTitle
, glm::vec4(0.0f
, 0.0f
, 0.0f
, 0.5f
), 0));
1319 opengl3D::ScreenText
* pScreenText
= static_cast<opengl3D::ScreenText
*>(maScreenTextShapes
.back().get());
1320 pScreenText
->setPosition(glm::vec2(nMinXCoord
, 0.99f
), glm::vec2(nMaxXCoord
, 0.99f
- nMaxHight
), glm::vec3(0.0, 0.0, 0.0));
1324 float GL3DBarChart::calcScrollDistance(const glm::mat4
& rMVP
, const glm::vec3
& rPos
)
1326 glm::vec4 aScreenPos
= rMVP
* glm::vec4(rPos
, 1.0);
1327 glm::vec3 aActualPos
= glm::vec3(aScreenPos
.x
/ aScreenPos
.w
, aScreenPos
.y
/ aScreenPos
.w
, 0.0);
1328 return glm::length(aActualPos
);
1331 void GL3DBarChart::calcDistance(std::vector
<sal_uInt32
> & rVectorNearest
)
1334 glm::mat4 aProjection
= mpRenderer
->GetProjectionMatrix();
1335 glm::mat4 aView
= mpRenderer
->GetViewMatrix();
1336 glm::mat4 aScale
= mpRenderer
->GetGlobalScaleMatrix();
1337 glm::mat4 aMVP
= aProjection
* aView
* aScale
;
1338 for (auto const& elem
: maBarMap
)
1340 sal_uInt32 nId
= elem
.first
;
1341 if(i
< SHOW_VALUE_COUNT
)
1343 rVectorNearest
.push_back(nId
);
1346 maDistanceMap
[nId
] = calcScrollDistance(aMVP
, glm::vec3(elem
.second
.maPos
.x
+ BAR_SIZE_X
/ 2.0f
,
1347 elem
.second
.maPos
.y
+ BAR_SIZE_Y
/ 2.0f
,
1348 elem
.second
.maPos
.z
));
1352 void GL3DBarChart::initDistanceHeap(std::vector
<sal_uInt32
> &rVectorNearest
)
1354 for(int i
= (rVectorNearest
.size()-2)/2; i
>= 0; i
--)
1356 keepHeap(rVectorNearest
, i
);
1360 void GL3DBarChart::keepHeap(std::vector
<sal_uInt32
> &rVectorNearest
, int nIndex
)
1362 size_t nParentIndex
= nIndex
;
1363 while(nParentIndex
< rVectorNearest
.size())
1365 size_t nLeftIndex
= nParentIndex
* 2 + 1;
1366 size_t nRightIndex
= nLeftIndex
+1;
1367 if(nLeftIndex
>= rVectorNearest
.size())
1369 size_t nFarthestIndex
= nLeftIndex
;
1370 float nFarthest
= maDistanceMap
[rVectorNearest
[nLeftIndex
]];
1371 if(nRightIndex
< rVectorNearest
.size())
1373 float nRight
= maDistanceMap
[rVectorNearest
[nRightIndex
]];
1374 if(nRight
> nFarthest
)
1377 nFarthestIndex
= nRightIndex
;
1380 float nParent
= maDistanceMap
[rVectorNearest
[nParentIndex
]];
1381 if(nParent
>= nFarthest
)
1385 swapVector(nParentIndex
, nFarthestIndex
, rVectorNearest
);
1386 nParentIndex
= nFarthestIndex
;
1392 void GL3DBarChart::swapVector(int i
, int j
, std::vector
<sal_uInt32
> &rVectorNearest
)
1394 sal_uInt32 nTmp
= rVectorNearest
[i
];
1395 rVectorNearest
[i
] = rVectorNearest
[j
];
1396 rVectorNearest
[j
] = nTmp
;
1399 void GL3DBarChart::getNearestBars(std::vector
<sal_uInt32
> &rVectorNearest
)
1401 calcDistance(rVectorNearest
);
1402 initDistanceHeap(rVectorNearest
);
1404 for (auto const& elem
: maDistanceMap
)
1407 if(i
<= SHOW_VALUE_COUNT
)
1409 float nDistance
= elem
.second
;
1410 float nHeaphead
= maDistanceMap
[rVectorNearest
[0]];
1411 if(nDistance
< nHeaphead
)
1413 rVectorNearest
[0] = elem
.first
;
1414 keepHeap(rVectorNearest
, 0);
1419 void GL3DBarChart::updateScroll()
1421 if ((maRenderEvent
== EVENT_SCROLL
) || (maRenderEvent
== EVENT_SHOW_SCROLL
))
1423 float fMinDistance
= 0.0f
;
1424 std::vector
<BarInformation
> aBarInfoList
;
1425 for(sal_uInt32 i
: maVectorNearest
)
1427 //get bar height position
1428 std::map
<sal_uInt32
, const BarInformation
>::const_iterator itr
= maBarMap
.find(i
);
1429 const BarInformation
& rBarInfo
= itr
->second
;
1430 aBarInfoList
.push_back(rBarInfo
);
1431 glm::vec3 aPos
= rBarInfo
.maPos
;
1432 fMinDistance
= (fMinDistance
== 0.0f
) ? glm::length(aPos
- maCameraPosition
) :
1433 std::min(glm::length(aPos
- maCameraPosition
), fMinDistance
);
1436 if (fMinDistance
<= SHOW_SCROLL_TEXT_DISTANCE
)
1438 //update scroll value
1439 for(BarInformation
& i
: aBarInfoList
)
1441 OUString aBarValue
= "Value: " + OUString::number(i
.mnVal
);
1442 maScreenTextShapes
.push_back(o3tl::make_unique
<opengl3D::ScreenText
>(mpRenderer
.get(), *mpTextCache
, aBarValue
, glm::vec4(0.0f
, 0.0f
, 1.0f
, 0.0f
), CALC_POS_EVENT_ID
, true));
1443 const opengl3D::TextCacheItem
& rTextCache
= mpTextCache
->getText(aBarValue
);
1444 float nRectWidth
= static_cast<float>(rTextCache
.maSize
.Width()) / static_cast<float>(rTextCache
.maSize
.Height()) * 0.024;
1445 glm::vec3 aTextPos
= glm::vec3(i
.maPos
.x
+ BAR_SIZE_X
/ 2.0f
,
1446 i
.maPos
.y
+ BAR_SIZE_Y
/ 2.0f
,
1448 opengl3D::ScreenText
* pScreenText
= static_cast<opengl3D::ScreenText
*>(maScreenTextShapes
.back().get());
1449 pScreenText
->setPosition(glm::vec2(-nRectWidth
/ 2, 0.03f
), glm::vec2(nRectWidth
/ 2, -0.03f
), aTextPos
);
1455 void GL3DBarChart::processAutoFly(sal_uInt32 nId
, Color nColor
)
1458 Color nPreColor
= maBarColorMap
[nId
];
1459 maBarColorMap
[nId
] = nColor
;
1460 //if has manul event, just record the color and process manul event first
1461 if (maRenderEvent
!= EVENT_NONE
)
1465 //calc the percentage of color change
1466 int nColorRate
= (sal_uInt32(nColor
) - sal_uInt32(nPreColor
)) * 100 / sal_uInt32(nPreColor
);
1467 nColorRate
= abs(nColorRate
);
1468 if (nColorRate
>= FLY_THRESHOLD
)
1470 maRenderEvent
= EVENT_AUTO_FLY
;
1471 mnSelectBarId
= nColorRate
> mnColorRate
? nId
: mnSelectBarId
;
1472 mnPreSelectBarId
= mnSelectBarId
;
1473 mnColorRate
= std::max(nColorRate
, mnColorRate
);
1477 IMPL_LINK_NOARG(GL3DBarChart
, UpdateTimerHdl
, Timer
*, void)
1483 void GL3DBarChart::setOpenGLWindow(OpenGLWindow
* pWindow
)
1485 if (mpWindow
.get() != pWindow
)
1488 Size aSize
= mpWindow
->GetSizePixel();
1489 mpRenderer
->SetSize(aSize
);
1490 mpWindow
->setRenderer(this);
1491 mpWindow
->getContext().makeCurrent();
1493 mpWindow
->getContext().resetCurrent();
1494 mbValidContext
= true;
1500 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */