FreeCAD

Форк
0
/
SoQTQuarterAdaptor.cpp 
799 строк · 28.2 Кб
1
/*
2
 * <one line to give the library's name and an idea of what it does.>
3
 * Copyright (C) 2014  Stefan Tröger <stefantroeger@gmx.net>
4
 *
5
 * This library is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU Lesser General Public
7
 * License as published by the Free Software Foundation; either
8
 * version 2.1 of the License, or (at your option) any later version.
9
 *
10
 * This library is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
 * Lesser General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU Lesser General Public
16
 * License along with this library; if not, write to the Free Software
17
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
18
 *
19
 */
20

21
#include "PreCompiled.h"
22

23
#include <Base/Console.h>
24
#include <Inventor/SbLine.h>
25
#include <Inventor/SbPlane.h>
26
#include <Inventor/SoEventManager.h>
27
#include <Inventor/SoPickedPoint.h>
28
#include <Inventor/actions/SoHandleEventAction.h>
29
#include <Inventor/actions/SoRayPickAction.h>
30
#include <Inventor/actions/SoSearchAction.h>
31
#include <Inventor/events/SoEvents.h>
32
#include <Inventor/nodes/SoLocateHighlight.h>
33
#include <Inventor/nodes/SoOrthographicCamera.h>
34
#include <Inventor/nodes/SoPerspectiveCamera.h>
35
#include <Inventor/nodes/SoSeparator.h>
36

37
#if !defined(FC_OS_MACOSX)
38
# include <GL/gl.h>
39
# include <GL/glu.h>
40
# include <GL/glext.h>
41
#endif
42

43
#include "SoQTQuarterAdaptor.h"
44

45
// NOLINTBEGIN
46
// clang-format off
47
static unsigned char fps2dfont[][12] = {
48
    {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0 }, //
49
    {  0,  0, 12, 12,  0,  8, 12, 12, 12, 12, 12,  0 }, // !
50
    {  0,  0,  0,  0,  0,  0,  0,  0,  0, 20, 20, 20 }, // \"
51
    {  0,  0, 18, 18, 18, 63, 18, 18, 63, 18, 18,  0 }, // #
52
    {  0,  8, 28, 42, 10, 10, 12, 24, 40, 42, 28,  8 }, // $
53
    {  0,  0,  6, 73, 41, 22,  8, 52, 74, 73, 48,  0 }, // %
54
    {  0, 12, 18, 18, 12, 25, 37, 34, 34, 29,  0,  0 }, // &
55
    { 12, 12, 24,  0,  0,  0,  0,  0,  0,  0,  0,  0 }, // '
56
    {  0,  6,  8,  8, 16, 16, 16, 16, 16,  8,  8,  6 }, // (
57
    {  0, 48,  8,  8,  4,  4,  4,  4,  4,  8,  8, 48 }, //)
58
    {  0,  0,  0,  0,  0,  0,  8, 42, 20, 42,  8,  0 }, // *
59
    {  0,  0,  0,  8,  8,  8,127,  8,  8,  8,  0,  0 }, // +
60
    {  0, 24, 12, 12,  0,  0,  0,  0,  0,  0,  0,  0 }, // ,
61
    {  0,  0,  0,  0,  0,  0,127,  0,  0,  0,  0,  0 }, // -
62
    {  0,  0, 24, 24,  0,  0,  0,  0,  0,  0,  0,  0 }, // .
63
    {  0, 32, 32, 16, 16,  8,  8,  8,  4,  4,  2,  2 }, // /
64
    {  0,  0, 28, 34, 34, 34, 34, 34, 34, 34, 28,  0 }, // 0
65
    {  0,  0,  8,  8,  8,  8,  8,  8, 40, 24,  8,  0 }, // 1
66
    {  0,  0, 62, 32, 16,  8,  4,  2,  2, 34, 28,  0 }, // 2
67
    {  0,  0, 28, 34,  2,  2, 12,  2,  2, 34, 28,  0 }, // 3
68
    {  0,  0,  4,  4,  4,126, 68, 36, 20, 12,  4,  0 }, // 4
69
    {  0,  0, 28, 34,  2,  2,  2, 60, 32, 32, 62,  0 }, // 5
70
    {  0,  0, 28, 34, 34, 34, 60, 32, 32, 34, 28,  0 }, // 6
71
    {  0,  0, 16, 16, 16,  8,  8,  4,  2,  2, 62,  0 }, // 7
72
    {  0,  0, 28, 34, 34, 34, 28, 34, 34, 34, 28,  0 }, // 8
73
    {  0,  0, 28, 34,  2,  2, 30, 34, 34, 34, 28,  0 }, // 9
74
    {  0,  0, 24, 24,  0,  0,  0, 24, 24,  0,  0,  0 }, // :
75
    {  0, 48, 24, 24,  0,  0,  0, 24, 24,  0,  0,  0 }, // ;
76
    {  0,  0,  0,  2,  4,  8, 16,  8,  4,  2,  0,  0 }, // <
77
    {  0,  0,  0,  0,  0,127,  0,127,  0,  0,  0,  0 }, // =
78
    {  0,  0,  0, 16,  8,  4,  2,  4,  8, 16,  0,  0 }, // >
79
    {  0,  0, 16, 16,  0, 16, 28,  2,  2,  2, 60,  0 }, // ?
80
    {  0,  0, 28, 32, 73, 86, 82, 82, 78, 34, 28,  0 }, // @
81
    {  0,  0, 33, 33, 33, 63, 18, 18, 18, 12, 12,  0 }, // A
82
    {  0,  0, 60, 34, 34, 34, 60, 34, 34, 34, 60,  0 }, // B
83
    {  0,  0, 14, 16, 32, 32, 32, 32, 32, 18, 14,  0 }, // C
84
    {  0,  0, 56, 36, 34, 34, 34, 34, 34, 36, 56,  0 }, // D
85
    {  0,  0, 62, 32, 32, 32, 60, 32, 32, 32, 62,  0 }, // E
86
    {  0,  0, 16, 16, 16, 16, 30, 16, 16, 16, 30,  0 }, // F
87
    {  0,  0, 14, 18, 34, 34, 32, 32, 32, 18, 14,  0 }, // G
88
    {  0,  0, 34, 34, 34, 34, 62, 34, 34, 34, 34,  0 }, // H
89
    {  0,  0, 62,  8,  8,  8,  8,  8,  8,  8, 62,  0 }, // I
90
    {  0,  0,112,  8,  8,  8,  8,  8,  8,  8, 62,  0 }, // J
91
    {  0,  0, 33, 33, 34, 36, 56, 40, 36, 34, 33,  0 }, // K
92
    {  0,  0, 30, 16, 16, 16, 16, 16, 16, 16, 16,  0 }, // L
93
    {  0,  0, 33, 33, 33, 45, 45, 45, 51, 51, 33,  0 }, // M
94
    {  0,  0, 34, 34, 38, 38, 42, 42, 50, 50, 34,  0 }, // N
95
    {  0,  0, 12, 18, 33, 33, 33, 33, 33, 18, 12,  0 }, // O
96
    {  0,  0, 32, 32, 32, 60, 34, 34, 34, 34, 60,  0 }, // P
97
    {  3,  6, 12, 18, 33, 33, 33, 33, 33, 18, 12,  0 }, // Q
98
    {  0,  0, 34, 34, 34, 36, 60, 34, 34, 34, 60,  0 }, // R
99
    {  0,  0, 60,  2,  2,  6, 28, 48, 32, 32, 30,  0 }, // S
100
    {  0,  0,  8,  8,  8,  8,  8,  8,  8,  8,127,  0 }, // T
101
    {  0,  0, 28, 34, 34, 34, 34, 34, 34, 34, 34,  0 }, // U
102
    {  0,  0, 12, 12, 18, 18, 18, 33, 33, 33, 33,  0 }, // V
103
    {  0,  0, 34, 34, 34, 54, 85, 73, 73, 73, 65,  0 }, // W
104
    {  0,  0, 34, 34, 20, 20,  8, 20, 20, 34, 34,  0 }, // X
105
    {  0,  0,  8,  8,  8,  8, 20, 20, 34, 34, 34,  0 }, // Y
106
    {  0,  0, 62, 32, 16, 16,  8,  4,  4,  2, 62,  0 }, // Z
107
    {  0, 14,  8,  8,  8,  8,  8,  8,  8,  8,  8, 14 }, // [
108
    {  0,  2,  2,  4,  4,  8,  8,  8, 16, 16, 32, 32 }, // [backslash]
109
    {  0, 56,  8,  8,  8,  8,  8,  8,  8,  8,  8, 56 }, // ]
110
    {  0,  0,  0,  0,  0, 34, 34, 20, 20,  8,  8,  0 }, // ^
111
    {  0,127,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0 }, // _
112
    {  0,  0,  0,  0,  0,  0,  0,  0,  0, 24, 24, 12 }, // `
113
    {  0,  0, 29, 34, 34, 30,  2, 34, 28,  0,  0,  0 }, // a
114
    {  0,  0, 60, 34, 34, 34, 34, 50, 44, 32, 32, 32 }, // b
115
    {  0,  0, 14, 16, 32, 32, 32, 16, 14,  0,  0,  0 }, // c
116
    {  0,  0, 26, 38, 34, 34, 34, 34, 30,  2,  2,  2 }, // d
117
    {  0,  0, 28, 34, 32, 62, 34, 34, 28,  0,  0,  0 }, // e
118
    {  0,  0, 16, 16, 16, 16, 16, 16, 62, 16, 16, 14 }, // f
119
    { 28,  2,  2, 26, 38, 34, 34, 34, 30,  0,  0,  0 }, // g
120
    {  0,  0, 34, 34, 34, 34, 34, 50, 44, 32, 32, 32 }, // h
121
    {  0,  0,  8,  8,  8,  8,  8,  8, 56,  0,  8,  8 }, // i
122
    { 56,  4,  4,  4,  4,  4,  4,  4, 60,  0,  4,  4 }, // j
123
    {  0,  0, 33, 34, 36, 56, 40, 36, 34, 32, 32, 32 }, // k
124
    {  0,  0,  8,  8,  8,  8,  8,  8,  8,  8,  8, 56 }, // l
125
    {  0,  0, 73, 73, 73, 73, 73,109, 82,  0,  0,  0 }, // m
126
    {  0,  0, 34, 34, 34, 34, 34, 50, 44,  0,  0,  0 }, // n
127
    {  0,  0, 28, 34, 34, 34, 34, 34, 28,  0,  0,  0 }, // o
128
    { 32, 32, 60, 34, 34, 34, 34, 50, 44,  0,  0,  0 }, // p
129
    {  2,  2, 26, 38, 34, 34, 34, 34, 30,  0,  0,  0 }, // q
130
    {  0,  0, 16, 16, 16, 16, 16, 24, 22,  0,  0,  0 }, // r
131
    {  0,  0, 60,  2,  2, 28, 32, 32, 30,  0,  0,  0 }, // s
132
    {  0,  0, 14, 16, 16, 16, 16, 16, 62, 16, 16,  0 }, // t
133
    {  0,  0, 26, 38, 34, 34, 34, 34, 34,  0,  0,  0 }, // u
134
    {  0,  0,  8,  8, 20, 20, 34, 34, 34,  0,  0,  0 }, // v
135
    {  0,  0, 34, 34, 34, 85, 73, 73, 65,  0,  0,  0 }, // w
136
    {  0,  0, 34, 34, 20,  8, 20, 34, 34,  0,  0,  0 }, // x
137
    { 48, 16,  8,  8, 20, 20, 34, 34, 34,  0,  0,  0 }, // y
138
    {  0,  0, 62, 32, 16,  8,  4,  2, 62,  0,  0,  0 }, // z
139
    {  0,  6,  8,  8,  8,  4, 24,  4,  8,  8,  8,  6 }, // {
140
    {  0,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8 }, // |
141
    {  0, 48,  8,  8,  8, 16, 12, 16,  8,  8,  8, 48 }, // }
142
    {  0,  0,  0,  0,  0,  0, 78, 57,  0,  0,  0,  0 }  // ~
143
};
144
// clang-format on
145
// NOLINTEND
146

147
constexpr const int defaultSize = 100;
148

149
// NOLINTBEGIN(readability-implicit-bool-conversion)
150
SIM::Coin3D::Quarter::SoQTQuarterAdaptor::SoQTQuarterAdaptor(QWidget* parent,
151
                                                             const QtGLWidget* sharewidget,
152
                                                             Qt::WindowFlags flags)
153
    : QuarterWidget(parent, sharewidget, flags)
154
    , matrixaction(SbViewportRegion(defaultSize, defaultSize))
155
{
156
    init();
157
}
158

159
SIM::Coin3D::Quarter::SoQTQuarterAdaptor::SoQTQuarterAdaptor(const QtGLFormat& format,
160
                                                             QWidget* parent,
161
                                                             const QtGLWidget* shareWidget,
162
                                                             Qt::WindowFlags flags)
163
    : QuarterWidget(format, parent, shareWidget, flags)
164
    , matrixaction(SbViewportRegion(defaultSize, defaultSize))
165
{
166
    init();
167
}
168

169
SIM::Coin3D::Quarter::SoQTQuarterAdaptor::SoQTQuarterAdaptor(QtGLContext* context,
170
                                                             QWidget* parent,
171
                                                             const QtGLWidget* sharewidget,
172
                                                             Qt::WindowFlags flags)
173
    : QuarterWidget(context, parent, sharewidget, flags)
174
    , matrixaction(SbViewportRegion(defaultSize, defaultSize))
175
{
176
    init();
177
}
178

179
SIM::Coin3D::Quarter::SoQTQuarterAdaptor::~SoQTQuarterAdaptor()
180
{
181
    delete m_seeksensor;
182
}
183

184
void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::init()
185
{
186
    // NOLINTBEGIN
187
    m_interactionnesting = 0;
188
    m_seekdistance = 50.0F;
189
    m_seekdistanceabs = false;
190
    m_seekperiod = 2.0F;
191
    m_inseekmode = false;
192
    m_storedcamera = nullptr;
193
    m_viewingflag = false;
194
    pickRadius = 5.0;
195

196
    m_seeksensor = new SoTimerSensor(SoQTQuarterAdaptor::seeksensorCB, (void*)this);
197
    getSoEventManager()->setNavigationState(SoEventManager::NO_NAVIGATION);
198

199
    resetFrameCounter();
200
    // NOLINTEND
201
}
202

203

204
QWidget* SIM::Coin3D::Quarter::SoQTQuarterAdaptor::getWidget()
205
{
206
    //we keep the function from SoQt as we want to introduce the QGraphicsView and then the GLWidget
207
    //is separated from the Widget used in layouts again
208
    return this;
209
}
210

211
QWidget* SIM::Coin3D::Quarter::SoQTQuarterAdaptor::getGLWidget()
212
{
213
    return viewport();
214
}
215

216
QWidget* SIM::Coin3D::Quarter::SoQTQuarterAdaptor::getWidget() const
217
{
218
    //we keep the function from SoQt as we want to introduce the QGraphicsView and then the GLWidget
219
    //is separated from the Widget used in layouts again
220
    return const_cast<SoQTQuarterAdaptor*>(this);  // NOLINT
221
}
222

223
QWidget* SIM::Coin3D::Quarter::SoQTQuarterAdaptor::getGLWidget() const
224
{
225
    return viewport();
226
}
227

228
void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::setCameraType(SoType type)
229
{
230
    SoCamera* cam = getSoRenderManager()->getCamera();
231
    if (cam && !cam->isOfType(SoPerspectiveCamera::getClassTypeId()) &&
232
               !cam->isOfType(SoOrthographicCamera::getClassTypeId())) {
233
        Base::Console().Warning("Quarter::setCameraType",
234
                                "Only SoPerspectiveCamera and SoOrthographicCamera is supported.");
235
        return;
236
    }
237

238

239
    SoType perspectivetype = SoPerspectiveCamera::getClassTypeId();
240
    SbBool oldisperspective = cam ? cam->getTypeId().isDerivedFrom(perspectivetype) : false;
241
    SbBool newisperspective = type.isDerivedFrom(perspectivetype);
242

243
    // Same old, same old..
244
    if (oldisperspective == newisperspective) {
245
        return;
246
    }
247

248
    SoCamera* currentcam = getSoRenderManager()->getCamera();
249
    SoCamera* newcamera = static_cast<SoCamera*>(type.createInstance());  // NOLINT
250

251
    // Transfer and convert values from one camera type to the other.
252
    if(newisperspective) {
253
        convertOrtho2Perspective(dynamic_cast<SoOrthographicCamera*>(currentcam),
254
                                 dynamic_cast<SoPerspectiveCamera*>(newcamera));
255
    }
256
    else {
257
        convertPerspective2Ortho(dynamic_cast<SoPerspectiveCamera*>(currentcam),
258
                                 dynamic_cast<SoOrthographicCamera*>(newcamera));
259
    }
260

261
    getSoRenderManager()->setCamera(newcamera);
262
    getSoEventManager()->setCamera(newcamera);
263

264
    //if the superscene has a camera we need to replace it too
265
    auto superscene = dynamic_cast<SoSeparator*>(getSoRenderManager()->getSceneGraph());
266
    SoSearchAction sa;
267
    sa.setInterest(SoSearchAction::FIRST);
268
    sa.setType(SoCamera::getClassTypeId());
269
    sa.apply(superscene);
270

271
    if (sa.getPath()) {
272
        SoNode* node = sa.getPath()->getTail();
273
        SoGroup* parent = static_cast<SoGroup*>(sa.getPath()->getNodeFromTail(1)); //  NOLINT
274

275
        if (node && node->isOfType(SoCamera::getClassTypeId())) {
276
            parent->replaceChild(node, newcamera);
277
        }
278
    }
279
}
280

281
void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::convertOrtho2Perspective(const SoOrthographicCamera* in,
282
        SoPerspectiveCamera* out)
283
{
284
    if (!in || !out) {
285
        Base::Console().Log("Quarter::convertOrtho2Perspective",
286
                            "Cannot convert camera settings due to wrong input.");
287
        return;
288
    }
289
    out->aspectRatio.setValue(in->aspectRatio.getValue());
290
    out->focalDistance.setValue(in->focalDistance.getValue());
291
    out->orientation.setValue(in->orientation.getValue());
292
    out->position.setValue(in->position.getValue());
293
    out->viewportMapping.setValue(in->viewportMapping.getValue());
294

295
    SbRotation camrot = in->orientation.getValue();
296

297
    float focaldist = float(in->height.getValue() / (2.0*tan(M_PI / 8.0)));  // NOLINT
298

299
    SbVec3f offset(0,0,focaldist-in->focalDistance.getValue());
300

301
    camrot.multVec(offset,offset);
302
    out->position.setValue(offset+in->position.getValue());
303

304
    out->focalDistance.setValue(focaldist);
305

306
    // 45° is the default value of this field in SoPerspectiveCamera.
307
    out->heightAngle = (float)(M_PI / 4.0);  // NOLINT
308
}
309

310
void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::convertPerspective2Ortho(const SoPerspectiveCamera* in,
311
        SoOrthographicCamera* out)
312
{
313
    out->aspectRatio.setValue(in->aspectRatio.getValue());
314
    out->focalDistance.setValue(in->focalDistance.getValue());
315
    out->orientation.setValue(in->orientation.getValue());
316
    out->position.setValue(in->position.getValue());
317
    out->viewportMapping.setValue(in->viewportMapping.getValue());
318

319
    float focaldist = in->focalDistance.getValue();
320

321
    out->height = 2.0F * focaldist * (float)tan(in->heightAngle.getValue() / 2.0);  // NOLINT
322
}
323

324
SoCamera* SIM::Coin3D::Quarter::SoQTQuarterAdaptor::getCamera() const
325
{
326
    return getSoRenderManager()->getCamera();
327
}
328

329
const SbViewportRegion & SIM::Coin3D::Quarter::SoQTQuarterAdaptor::getViewportRegion() const
330
{
331
    return getSoRenderManager()->getViewportRegion();
332
}
333

334
void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::setViewing(bool enable)
335
{
336
    m_viewingflag = enable;
337

338
    // Turn off the selection indicators when we go back from picking
339
    // mode into viewing mode.
340
    if (m_viewingflag) {
341
        SoGLRenderAction* action = getSoRenderManager()->getGLRenderAction();
342

343
        if (action) {
344
            SoLocateHighlight::turnOffCurrentHighlight(action);
345
        }
346
    }
347
}
348

349
bool SIM::Coin3D::Quarter::SoQTQuarterAdaptor::isViewing() const
350
{
351
    return m_viewingflag;
352
}
353

354
void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::interactiveCountInc()
355
{
356
    // Catch problems with missing interactiveCountDec() calls.
357
    assert(m_interactionnesting < 100);
358

359
    if (++m_interactionnesting == 1) {
360
        m_interactionStartCallback.invokeCallbacks(this);
361
    }
362
}
363

364
void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::interactiveCountDec()
365
{
366
    if (--m_interactionnesting <= 0) {
367
        m_interactionEndCallback.invokeCallbacks(this);
368
        m_interactionnesting = 0;
369
    }
370
}
371

372
int SIM::Coin3D::Quarter::SoQTQuarterAdaptor::getInteractiveCount() const
373
{
374
    return m_interactionnesting;
375
}
376

377
// clang-format off
378
void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::addStartCallback(SIM::Coin3D::Quarter::SoQTQuarterAdaptorCB* func, void* data)
379
{
380
    m_interactionStartCallback.addCallback((SoCallbackListCB*)func, data);  // NOLINT
381
}
382

383
void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::removeStartCallback(SIM::Coin3D::Quarter::SoQTQuarterAdaptorCB* func, void* data)
384
{
385
    m_interactionStartCallback.removeCallback((SoCallbackListCB*)func, data);  // NOLINT
386
}
387

388
void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::addFinishCallback(SIM::Coin3D::Quarter::SoQTQuarterAdaptorCB* func, void* data)
389
{
390
    m_interactionEndCallback.addCallback((SoCallbackListCB*)func, data);  // NOLINT
391
}
392

393
void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::removeFinishCallback(SIM::Coin3D::Quarter::SoQTQuarterAdaptorCB* func, void* data)
394
{
395
    m_interactionEndCallback.removeCallback((SoCallbackListCB*)func, data);  // NOLINT
396
}
397
// clang-format on
398

399
float SIM::Coin3D::Quarter::SoQTQuarterAdaptor::getSeekDistance() const
400
{
401
    return m_seekdistance;
402
}
403

404
float SIM::Coin3D::Quarter::SoQTQuarterAdaptor::getSeekTime() const
405
{
406
    return m_seekperiod;
407
}
408

409
bool SIM::Coin3D::Quarter::SoQTQuarterAdaptor::isSeekMode() const
410
{
411
    return m_inseekmode;
412
}
413

414
bool SIM::Coin3D::Quarter::SoQTQuarterAdaptor::isSeekValuePercentage() const
415
{
416
    return !m_seekdistanceabs;
417
}
418

419
void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::setPickRadius(float pickRadius)
420
{
421
    this->pickRadius = pickRadius;
422
    SoEventManager* evm = this->getSoEventManager();
423
    if (evm){
424
        SoHandleEventAction* hea = evm->getHandleEventAction();
425
        if (hea){
426
            hea->setPickRadius(pickRadius);
427
        }
428
    }
429
}
430

431
bool SIM::Coin3D::Quarter::SoQTQuarterAdaptor::seekToPoint(const SbVec2s& screenpos)
432
{
433

434
    SoRayPickAction rpaction(getSoRenderManager()->getViewportRegion());
435
    rpaction.setPoint(screenpos);
436
    rpaction.setRadius(pickRadius);
437
    rpaction.apply(getSoRenderManager()->getSceneGraph());
438

439
    SoPickedPoint* picked = rpaction.getPickedPoint();
440

441
    if (!picked) {
442
        this->interactiveCountInc(); // decremented in setSeekMode(false)
443
        this->setSeekMode(false);
444
        return false;
445
    }
446

447
    SbVec3f hitpoint;
448
    hitpoint = picked->getPoint();
449

450
    this->seekToPoint(hitpoint);
451
    return true;
452
}
453

454
void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::seekToPoint(const SbVec3f& scenepos)
455
{
456
    SbVec3f hitpoint(scenepos);
457

458
    m_camerastartposition = getSoRenderManager()->getCamera()->position.getValue();
459
    m_camerastartorient = getSoRenderManager()->getCamera()->orientation.getValue();
460

461
    // move point to the camera coordinate system, consider
462
    // transformations before camera in the scene graph
463
    SbMatrix cameramatrix;
464
    SbMatrix camerainverse;
465
    getCameraCoordinateSystem(getSoRenderManager()->getCamera(),
466
                              getSceneGraph(),
467
                              cameramatrix,
468
                              camerainverse);
469
    camerainverse.multVecMatrix(hitpoint, hitpoint);
470

471
    float fd = m_seekdistance;
472

473
    if(!m_seekdistanceabs) {
474
        fd *= (hitpoint - getSoRenderManager()->getCamera()->position.getValue()).length()/100.0F;
475
    }
476

477
    getSoRenderManager()->getCamera()->focalDistance = fd;
478

479
    SbVec3f dir = hitpoint - m_camerastartposition;
480
    dir.normalize();
481

482
    // find a rotation that rotates current camera direction into new
483
    // camera direction.
484
    SbVec3f olddir;
485
    getSoRenderManager()->getCamera()->orientation.getValue().multVec(SbVec3f(0, 0, -1), olddir);
486
    SbRotation diffrot(olddir, dir);
487
    m_cameraendposition = hitpoint - fd * dir;
488
    m_cameraendorient = getSoRenderManager()->getCamera()->orientation.getValue() * diffrot;
489

490
    if(m_seeksensor->isScheduled()) {
491
        m_seeksensor->unschedule();
492
        interactiveCountDec();
493
    }
494

495
    m_seeksensor->setBaseTime(SbTime::getTimeOfDay());
496
    m_seeksensor->schedule();
497
    interactiveCountInc();
498
}
499

500
void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::setSeekDistance(const float distance)
501
{
502
    m_seekdistance = distance;
503
}
504

505
void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::setSeekMode(bool enable)
506
{
507
    if(!enable && m_seeksensor->isScheduled()) {
508
        m_seeksensor->unschedule();
509
        interactiveCountDec();
510
    }
511

512
    m_inseekmode = enable;
513
}
514

515
void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::setSeekTime(const float seconds)
516
{
517
    m_seekperiod = seconds;
518
}
519

520
void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::setSeekValueAsPercentage(bool on)
521
{
522
    m_seekdistanceabs = !on;
523
}
524

525
void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::getCameraCoordinateSystem(SoCamera* camera,
526
                                                                         SoNode* root,
527
                                                                         SbMatrix& matrix,
528
                                                                         SbMatrix& inverse)
529
{
530
    searchaction.reset();
531
    searchaction.setSearchingAll(true);
532
    searchaction.setInterest(SoSearchAction::FIRST);
533
    searchaction.setNode(camera);
534
    searchaction.apply(root);
535

536
    matrix = inverse = SbMatrix::identity();
537

538
    if(searchaction.getPath()) {
539
        matrixaction.apply(searchaction.getPath());
540
        matrix = matrixaction.getMatrix();
541
        inverse = matrixaction.getInverse();
542
    }
543

544
    searchaction.reset();
545
}
546

547
void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::seeksensorCB(void* data, SoSensor* sensor)
548
{
549
    SoQTQuarterAdaptor* thisp = static_cast<SoQTQuarterAdaptor*>(data);  // NOLINT
550
    SbTime currenttime = SbTime::getTimeOfDay();
551

552
    SoTimerSensor* timer = static_cast<SoTimerSensor*>(sensor);  // NOLINT
553

554
    float par = float((currenttime - timer->getBaseTime()).getValue()) / thisp->m_seekperiod;
555

556
    if ((par > 1.0F) || (par + timer->getInterval().getValue() > 1.0F)) {
557
        par = 1.0F;
558
    }
559

560
    bool end = (par == 1.0F);
561

562
    par = (float)((1.0 - cos(M_PI * par)) * 0.5);  // NOLINT
563

564
    thisp->getSoRenderManager()->getCamera()->position = thisp->m_camerastartposition +
565
            (thisp->m_cameraendposition - thisp->m_camerastartposition) * par;
566
    thisp->getSoRenderManager()->getCamera()->orientation =
567
        SbRotation::slerp(thisp->m_camerastartorient,
568
                          thisp->m_cameraendorient,
569
                          par);
570

571
    if (end) {
572
        thisp->setSeekMode(false);
573
    }
574
}
575

576
void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::saveHomePosition()
577
{
578
    SoCamera* cam = getSoRenderManager()->getCamera();
579
    if (!cam) {
580
        return;
581
    }
582

583
    SoType type = cam->getTypeId();
584
    assert(type.isDerivedFrom(SoNode::getClassTypeId()));
585
    assert(type.canCreateInstance());
586

587
    if(m_storedcamera) {
588
        m_storedcamera->unref();
589
    }
590

591
    m_storedcamera = static_cast<SoNode*>(type.createInstance());  // NOLINT
592
    m_storedcamera->ref();
593

594
    m_storedcamera->copyFieldValues(getSoRenderManager()->getCamera());
595
}
596

597
void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::resetToHomePosition()
598
{
599
    SoCamera* cam = getSoRenderManager()->getCamera();
600
    if (!cam) {
601
        return;
602
    }
603

604
    if(!m_storedcamera) {
605
        return;
606
    }
607

608
    SoType ttype = getSoRenderManager()->getCamera()->getTypeId();
609
    SoType stype = m_storedcamera->getTypeId();
610

611
    // most common case
612
    if (ttype == stype) {
613
        // We copy the field data directly, instead of using
614
        // SoFieldContainer::copyContents(), for the reason described in
615
        // detail in So@Gui@Viewer::saveHomePosition().
616
        getSoRenderManager()->getCamera()->copyFieldValues(m_storedcamera);
617
    }
618
    // handle common case #1
619
    else if(ttype == SoOrthographicCamera::getClassTypeId() &&
620
            stype == SoPerspectiveCamera::getClassTypeId()) {
621
        convertPerspective2Ortho(dynamic_cast<SoPerspectiveCamera*>(m_storedcamera),
622
                                 dynamic_cast<SoOrthographicCamera*>(getSoRenderManager()->getCamera()));
623
    }
624
    // handle common case #2
625
    else if(ttype == SoPerspectiveCamera::getClassTypeId() &&
626
            stype == SoOrthographicCamera::getClassTypeId()) {
627
        convertOrtho2Perspective(dynamic_cast<SoOrthographicCamera*>(m_storedcamera),
628
                                 dynamic_cast<SoPerspectiveCamera*>(getSoRenderManager()->getCamera()));
629
    }
630

631
    // otherwise, cameras have changed in ways we don't understand since
632
    // the last saveHomePosition() invocation, and so we're just going
633
    // to ignore the reset request
634
}
635

636

637
void
638
SIM::Coin3D::Quarter::SoQTQuarterAdaptor::draw2DString(const char* str,
639
                                                       SbVec2s glsize,
640
                                                       SbVec2f position)
641
{
642
    // Store GL state.
643
    glPushAttrib(GL_ENABLE_BIT|GL_CURRENT_BIT);
644

645
    glDisable(GL_LIGHTING);
646
    glDisable(GL_DEPTH_TEST);
647
    glDisable(GL_TEXTURE_2D);
648
    glDisable(GL_BLEND);
649

650
    glMatrixMode(GL_MODELVIEW);
651
    glPushMatrix();
652
    glLoadIdentity();
653

654
    glMatrixMode(GL_PROJECTION);
655
    glPushMatrix();
656
    glLoadIdentity();
657
    glOrtho(0.0, glsize[0], 0.0, glsize[1], -1, 1);
658

659
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
660

661
//   glColor3f(0.0, 0.0, 0.0);
662
//   glRasterPos2f(position[0] + 1, position[1]);
663
//   printString(str);
664
//   glRasterPos2f(position[0] - 1, position[1]);
665
//   printString(str);
666
//   glRasterPos2f(position[0], position[1] + 1);
667
//   printString(str);
668
//   glRasterPos2f(position[0], position[1] - 1);
669
//   printString(str);
670

671
    glColor3f(1.0, 1.0, 0.0);
672
    glRasterPos2f(position[0], position[1]);
673
    printString(str);
674

675
    glMatrixMode(GL_PROJECTION);
676
    glPopMatrix();
677
    glMatrixMode(GL_MODELVIEW);
678
    glPopMatrix();
679

680
    glPixelStorei(GL_UNPACK_ALIGNMENT, 4); // restore default value
681

682
    glPopAttrib();
683
}
684

685
void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::printString(const char* str)
686
{
687
    // NOLINTBEGIN
688
    std::size_t len = strlen(str);
689

690
    for(std::size_t i = 0; i < len; i++) {
691
        glBitmap(8, 12, 0.0, 2.0, 10.0, 0.0, fps2dfont[str[i] - 32]);
692
    }
693
    // NOLINTEND
694
}
695

696
void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::moveCameraScreen(const SbVec2f& screenpos)
697
{
698
    SoCamera* cam = getSoRenderManager()->getCamera();
699
    assert(cam);
700

701

702
    SbViewVolume vv = cam->getViewVolume(getGLWidget()->width() / getGLWidget()->height());
703
    SbPlane panplane = vv.getPlane(cam->focalDistance.getValue());
704

705
    constexpr const float mid = 0.5F;
706
    SbLine line;
707
    vv.projectPointToLine(screenpos + SbVec2f(mid, mid), line);
708
    SbVec3f current_planept;
709
    panplane.intersect(line, current_planept);
710
    vv.projectPointToLine(SbVec2f(mid, mid), line);
711
    SbVec3f old_planept;
712
    panplane.intersect(line, old_planept);
713

714
    // Reposition camera according to the vector difference between the
715
    // projected points.
716
    cam->position = cam->position.getValue() - (current_planept - old_planept);
717
}
718

719
bool SIM::Coin3D::Quarter::SoQTQuarterAdaptor::processSoEvent(const SoEvent* event)
720
{
721
    const SoType type(event->getTypeId());
722

723
    constexpr const float delta = 0.1F;
724
    if(type.isDerivedFrom(SoKeyboardEvent::getClassTypeId())) {
725
        const SoKeyboardEvent* keyevent = static_cast<const SoKeyboardEvent*>(event);  // NOLINT
726

727
        if(keyevent->getState() == SoButtonEvent::DOWN) {
728
            switch(keyevent->getKey()) {
729

730
            case SoKeyboardEvent::LEFT_ARROW:
731
                moveCameraScreen(SbVec2f(-delta, 0.0F));
732
                return true;
733

734
            case SoKeyboardEvent::UP_ARROW:
735
                moveCameraScreen(SbVec2f(0.0F, delta));
736
                return true;
737

738
            case SoKeyboardEvent::RIGHT_ARROW:
739
                moveCameraScreen(SbVec2f(delta, 0.0F));
740
                return true;
741

742
            case SoKeyboardEvent::DOWN_ARROW:
743
                moveCameraScreen(SbVec2f(0.0F, -delta));
744
                return true;
745

746
            default:
747
                break;
748
            }
749
        }
750
    }
751

752
    return SIM::Coin3D::Quarter::QuarterWidget::processSoEvent(event);
753
}
754

755
/*!
756
  Overridden from QuarterWidget to render the scenegraph
757
*/
758
void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::paintEvent(QPaintEvent* event)
759
{
760
    double start = SbTime::getTimeOfDay().getValue();
761
    QuarterWidget::paintEvent(event);
762
    this->framesPerSecond = addFrametime(start);
763
}
764

765
void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::resetFrameCounter()
766
{
767
    this->framecount = 0;
768
    this->frametime = 0.0F;
769
    this->drawtime = 0.0F;
770
    this->starttime = SbTime::getTimeOfDay().getValue();
771
    this->framesPerSecond = SbVec2f(0, 0);
772
}
773

774
SbVec2f SIM::Coin3D::Quarter::SoQTQuarterAdaptor::addFrametime(double starttime)
775
{
776
    constexpr const double FPS_FACTOR = 0.7;
777
    constexpr const double FIVE_SECS = 5000.0;
778
    constexpr const float ONE_SEC = 1000.0F;
779

780
    this->framecount++;
781

782
    double timeofday = SbTime::getTimeOfDay().getValue();
783

784
    // draw time is the actual time spent on rendering
785
    double drawtime = timeofday - starttime;
786
    this->drawtime = (drawtime*FPS_FACTOR) + this->drawtime*(1.0 - FPS_FACTOR);
787

788
    // frame time is the time spent since the last frame. There could an
789
    // indefinite pause between the last frame because the scene is not
790
    // changing. So we limit the skew to 5 second.
791
    double frametime = std::min(timeofday-this->starttime, std::max(drawtime, FIVE_SECS));
792
    this->frametime = (frametime*FPS_FACTOR) + this->frametime*(1.0 - FPS_FACTOR);
793

794
    this->starttime = timeofday;
795
    return {ONE_SEC * float(this->drawtime), 1.0F / float(this->frametime)};
796
}
797
// NOLINTEND(readability-implicit-bool-conversion)
798

799
#include "moc_SoQTQuarterAdaptor.cpp"
800

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.