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 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <svx/viewpt3d.hxx>
21 : #include <basegfx/range/b3drange.hxx>
22 : #include <o3tl/numeric.hxx>
23 :
24 1273 : Viewport3D::Viewport3D() :
25 : aVRP(0, 0, 5),
26 : aVPN(0, 0, 1),
27 : aVUV(0, 1, 1),
28 : aPRP(0, 0, 2),
29 : fVPD(-3),
30 : fNearClipDist (0.0),
31 : fFarClipDist (0.0),
32 : eProjection(PR_PERSPECTIVE),
33 : eAspectMapping(AS_NO_MAPPING),
34 : aDeviceRect(Point(0,0), Size(-1,-1)),
35 : aViewPoint (0, 0, 5000),
36 : bTfValid(false),
37 : fWRatio (1.0),
38 1273 : fHRatio (1.0)
39 : {
40 1273 : aViewWin.X = -1; aViewWin.Y = -1;
41 1273 : aViewWin.W = 2; aViewWin.H = 2;
42 1273 : }
43 :
44 : // Set ViewWindow (in View coordinates)
45 :
46 2546 : void Viewport3D::SetViewWindow(double fX, double fY, double fW, double fH)
47 : {
48 2546 : aViewWin.X = fX;
49 2546 : aViewWin.Y = fY;
50 2546 : if ( fW > 0 ) aViewWin.W = fW;
51 0 : else aViewWin.W = 1.0;
52 2546 : if ( fH > 0 ) aViewWin.H = fH;
53 0 : else aViewWin.H = 1.0;
54 :
55 2546 : fWRatio = aDeviceRect.GetWidth() / aViewWin.W;
56 2546 : fHRatio = aDeviceRect.GetHeight() / aViewWin.H;
57 2546 : }
58 :
59 : // Returns observer position (PRP) in world coordinates
60 :
61 1366 : const basegfx::B3DPoint& Viewport3D::GetViewPoint()
62 : {
63 1366 : MakeTransform();
64 :
65 1366 : return aViewPoint;
66 : }
67 :
68 : // Calculate View transformations matrix
69 :
70 1366 : void Viewport3D::MakeTransform()
71 : {
72 1366 : if ( !bTfValid )
73 : {
74 : double fV, fXupVp, fYupVp;
75 1366 : aViewPoint = aVRP + aVPN * aPRP.getZ();
76 :
77 : // Reset to Identity matrix
78 1366 : aViewTf.identity();
79 :
80 : // shift in the origin
81 1366 : aViewTf.translate(-aVRP.getX(), -aVRP.getY(), -aVRP.getZ());
82 :
83 : // fV = Length of the projection of aVPN on the yz plane:
84 1366 : fV = aVPN.getYZLength();
85 :
86 1366 : if ( fV != 0 )
87 : {
88 1366 : basegfx::B3DHomMatrix aTemp;
89 1366 : const double fSin(aVPN.getY() / fV);
90 1366 : const double fCos(aVPN.getZ() / fV);
91 1366 : aTemp.set(2, 2, fCos);
92 1366 : aTemp.set(1, 1, fCos);
93 1366 : aTemp.set(2, 1, fSin);
94 1366 : aTemp.set(1, 2, -fSin);
95 1366 : aViewTf *= aTemp;
96 : }
97 :
98 : {
99 1366 : basegfx::B3DHomMatrix aTemp;
100 1366 : const double fSin(-aVPN.getX());
101 1366 : const double fCos(fV);
102 1366 : aTemp.set(2, 2, fCos);
103 1366 : aTemp.set(0, 0, fCos);
104 1366 : aTemp.set(0, 2, fSin);
105 1366 : aTemp.set(2, 0, -fSin);
106 1366 : aViewTf *= aTemp;
107 : }
108 :
109 : // Convert X- and Y- coordinates of the view up vector to the
110 : // (preliminary) view coordinate system.
111 1366 : fXupVp = aViewTf.get(0, 0) * aVUV.getX() + aViewTf.get(0, 1) * aVUV.getY() + aViewTf.get(0, 2) * aVUV.getZ();
112 1366 : fYupVp = aViewTf.get(1, 0) * aVUV.getX() + aViewTf.get(1, 1) * aVUV.getY() + aViewTf.get(1, 2) * aVUV.getZ();
113 1366 : fV = sqrt(fXupVp * fXupVp + fYupVp * fYupVp);
114 :
115 1366 : if ( fV != 0 )
116 : {
117 1366 : basegfx::B3DHomMatrix aTemp;
118 1366 : const double fSin(fXupVp / fV);
119 1366 : const double fCos(fYupVp / fV);
120 1366 : aTemp.set(1, 1, fCos);
121 1366 : aTemp.set(0, 0, fCos);
122 1366 : aTemp.set(1, 0, fSin);
123 1366 : aTemp.set(0, 1, -fSin);
124 1366 : aViewTf *= aTemp;
125 : }
126 :
127 1366 : bTfValid = true;
128 : }
129 1366 : }
130 :
131 4497 : void Viewport3D::SetDeviceWindow(const Rectangle& rRect)
132 : {
133 4497 : long nNewW = rRect.GetWidth();
134 4497 : long nNewH = rRect.GetHeight();
135 4497 : long nOldW = aDeviceRect.GetWidth();
136 4497 : long nOldH = aDeviceRect.GetHeight();
137 :
138 4497 : switch ( eAspectMapping )
139 : {
140 : double fRatio, fTmp;
141 :
142 : // Mapping, without changing the real size of the objects in the
143 : // Device Window
144 : case AS_HOLD_SIZE:
145 : // When the Device is invalid (w, h = -1), adapt the View
146 : // with AsHoldX
147 0 : if ( nOldW > 0 && nOldH > 0 )
148 : {
149 0 : fRatio = (double) nNewW / nOldW;
150 0 : aViewWin.X *= fRatio;
151 0 : aViewWin.W *= fRatio;
152 0 : fRatio = (double) nNewH / nOldH;
153 0 : aViewWin.Y *= fRatio;
154 0 : aViewWin.H *= fRatio;
155 0 : break;
156 : }
157 : case AS_HOLD_X:
158 0 : if (nNewW == 0)
159 0 : throw o3tl::divide_by_zero();
160 : // Adapt view height to view width
161 0 : fRatio = (double) nNewH / nNewW;
162 0 : fTmp = aViewWin.H;
163 0 : aViewWin.H = aViewWin.W * fRatio;
164 0 : aViewWin.Y = aViewWin.Y * aViewWin.H / fTmp;
165 0 : break;
166 :
167 : case AS_HOLD_Y:
168 0 : if (nNewH == 0)
169 0 : throw o3tl::divide_by_zero();
170 : // Adapt view width to view height
171 0 : fRatio = (double) nNewW / nNewH;
172 0 : fTmp = aViewWin.W;
173 0 : aViewWin.W = aViewWin.H * fRatio;
174 0 : aViewWin.X = aViewWin.X * aViewWin.W / fTmp;
175 0 : break;
176 4497 : default: break;
177 : }
178 4497 : fWRatio = nNewW / aViewWin.W;
179 4497 : fHRatio = nNewH / aViewWin.H;
180 :
181 4497 : aDeviceRect = rRect;
182 4497 : }
183 :
184 : // Set View Reference Point
185 :
186 3874 : void Viewport3D::SetVRP(const basegfx::B3DPoint& rNewVRP)
187 : {
188 3874 : aVRP = rNewVRP;
189 3874 : bTfValid = false;
190 3874 : }
191 :
192 : // Set View Plane Normal
193 :
194 3874 : void Viewport3D::SetVPN(const basegfx::B3DVector& rNewVPN)
195 : {
196 3874 : aVPN = rNewVPN;
197 3874 : aVPN.normalize();
198 3874 : bTfValid = false;
199 3874 : }
200 :
201 : // Set View Up Vector
202 :
203 3874 : void Viewport3D::SetVUV(const basegfx::B3DVector& rNewVUV)
204 : {
205 3874 : aVUV = rNewVUV;
206 3874 : bTfValid = false;
207 3874 : }
208 :
209 : // Set Center Of Projection
210 :
211 5092 : void Viewport3D::SetPRP(const basegfx::B3DPoint& rNewPRP)
212 : {
213 5092 : aPRP = rNewPRP;
214 5092 : aPRP.setX(0.0);
215 5092 : aPRP.setY(0.0);
216 5092 : bTfValid = false;
217 5092 : }
218 :
219 : // Set View Plane Distance
220 :
221 1273 : void Viewport3D::SetVPD(double fNewVPD)
222 : {
223 1273 : fVPD = fNewVPD;
224 1273 : bTfValid = false;
225 1273 : }
226 :
227 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|