Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <svx/viewpt3d.hxx>
30 : : #include <svx/volume3d.hxx>
31 : :
32 : 736 : Viewport3D::Viewport3D() :
33 : : aVRP(0, 0, 5),
34 : : aVPN(0, 0, 1),
35 : : aVUV(0, 1, 1),
36 : : aPRP(0, 0, 2),
37 : : fVPD(-3),
38 : : fNearClipDist (0.0),
39 : : fFarClipDist (0.0),
40 : : eProjection(PR_PERSPECTIVE),
41 : : eAspectMapping(AS_NO_MAPPING),
42 : : aDeviceRect(Point(0,0), Size(-1,-1)),
43 : : aViewPoint (0, 0, 5000),
44 : : bTfValid(0),
45 : : fWRatio (1.0),
46 [ + - ]: 736 : fHRatio (1.0)
47 : : {
48 : 736 : aViewWin.X = -1; aViewWin.Y = -1;
49 : 736 : aViewWin.W = 2; aViewWin.H = 2;
50 : 736 : }
51 : :
52 : : // Set ViewWindow (in View coordinates)
53 : :
54 : 1472 : void Viewport3D::SetViewWindow(double fX, double fY, double fW, double fH)
55 : : {
56 : 1472 : aViewWin.X = fX;
57 : 1472 : aViewWin.Y = fY;
58 [ + - ]: 1472 : if ( fW > 0 ) aViewWin.W = fW;
59 : 0 : else aViewWin.W = 1.0;
60 [ + - ]: 1472 : if ( fH > 0 ) aViewWin.H = fH;
61 : 0 : else aViewWin.H = 1.0;
62 : :
63 : 1472 : fWRatio = aDeviceRect.GetWidth() / aViewWin.W;
64 : 1472 : fHRatio = aDeviceRect.GetHeight() / aViewWin.H;
65 : 1472 : }
66 : :
67 : : // Returns observer position (PRP) in world coordinates
68 : :
69 : 761 : const basegfx::B3DPoint& Viewport3D::GetViewPoint()
70 : : {
71 : 761 : MakeTransform();
72 : :
73 : 761 : return aViewPoint;
74 : : }
75 : :
76 : : // Calculate View transformations matrix
77 : :
78 : 761 : void Viewport3D::MakeTransform(void)
79 : : {
80 [ + - ]: 761 : if ( !bTfValid )
81 : : {
82 : : double fV, fXupVp, fYupVp;
83 : 761 : aViewPoint = aVRP + aVPN * aPRP.getZ();
84 : :
85 : : // Reset to Identity matrix
86 : 761 : aViewTf.identity();
87 : :
88 : : // shift in the origin
89 : 761 : aViewTf.translate(-aVRP.getX(), -aVRP.getY(), -aVRP.getZ());
90 : :
91 : : // fV = Length of the projection of aVPN on the yz plane:
92 : 761 : fV = aVPN.getYZLength();
93 : :
94 [ + - ]: 761 : if ( fV != 0 )
95 : : {
96 [ + - ]: 761 : basegfx::B3DHomMatrix aTemp;
97 : 761 : const double fSin(aVPN.getY() / fV);
98 : 761 : const double fCos(aVPN.getZ() / fV);
99 [ + - ]: 761 : aTemp.set(2, 2, fCos);
100 [ + - ]: 761 : aTemp.set(1, 1, fCos);
101 [ + - ]: 761 : aTemp.set(2, 1, fSin);
102 [ + - ]: 761 : aTemp.set(1, 2, -fSin);
103 [ + - ][ + - ]: 761 : aViewTf *= aTemp;
104 : : }
105 : :
106 : : {
107 [ + - ]: 761 : basegfx::B3DHomMatrix aTemp;
108 : 761 : const double fSin(-aVPN.getX());
109 : 761 : const double fCos(fV);
110 [ + - ]: 761 : aTemp.set(2, 2, fCos);
111 [ + - ]: 761 : aTemp.set(0, 0, fCos);
112 [ + - ]: 761 : aTemp.set(0, 2, fSin);
113 [ + - ]: 761 : aTemp.set(2, 0, -fSin);
114 [ + - ][ + - ]: 761 : aViewTf *= aTemp;
115 : : }
116 : :
117 : : // Convert X- and Y- coordinates of the view up vector to the
118 : : // (preliminary) view coordinate system.
119 : 761 : fXupVp = aViewTf.get(0, 0) * aVUV.getX() + aViewTf.get(0, 1) * aVUV.getY() + aViewTf.get(0, 2) * aVUV.getZ();
120 : 761 : fYupVp = aViewTf.get(1, 0) * aVUV.getX() + aViewTf.get(1, 1) * aVUV.getY() + aViewTf.get(1, 2) * aVUV.getZ();
121 : 761 : fV = sqrt(fXupVp * fXupVp + fYupVp * fYupVp);
122 : :
123 [ + - ]: 761 : if ( fV != 0 )
124 : : {
125 [ + - ]: 761 : basegfx::B3DHomMatrix aTemp;
126 : 761 : const double fSin(fXupVp / fV);
127 : 761 : const double fCos(fYupVp / fV);
128 [ + - ]: 761 : aTemp.set(1, 1, fCos);
129 [ + - ]: 761 : aTemp.set(0, 0, fCos);
130 [ + - ]: 761 : aTemp.set(1, 0, fSin);
131 [ + - ]: 761 : aTemp.set(0, 1, -fSin);
132 [ + - ][ + - ]: 761 : aViewTf *= aTemp;
133 : : }
134 : :
135 : 761 : bTfValid = sal_True;
136 : : }
137 : 761 : }
138 : :
139 : 2365 : void Viewport3D::SetDeviceWindow(const Rectangle& rRect)
140 : : {
141 : 2365 : long nNewW = rRect.GetWidth();
142 : 2365 : long nNewH = rRect.GetHeight();
143 : 2365 : long nOldW = aDeviceRect.GetWidth();
144 : 2365 : long nOldH = aDeviceRect.GetHeight();
145 : :
146 [ - - - + ]: 2365 : switch ( eAspectMapping )
147 : : {
148 : : double fRatio, fTmp;
149 : :
150 : : // Mapping, without changing the real size of the objects in the
151 : : // Device Window
152 : : case AS_HOLD_SIZE:
153 : : // When the Device is invalid (w, h = -1), adapt the View
154 : : // with AsHoldX
155 [ # # ][ # # ]: 0 : if ( nOldW > 0 && nOldH > 0 )
156 : : {
157 : 0 : fRatio = (double) nNewW / nOldW;
158 : 0 : aViewWin.X *= fRatio;
159 : 0 : aViewWin.W *= fRatio;
160 : 0 : fRatio = (double) nNewH / nOldH;
161 : 0 : aViewWin.Y *= fRatio;
162 : 0 : aViewWin.H *= fRatio;
163 : 0 : break;
164 : : }
165 : : case AS_HOLD_X:
166 : : // Adapt view height to view width
167 : 0 : fRatio = (double) nNewH / nNewW;
168 : 0 : fTmp = aViewWin.H;
169 : 0 : aViewWin.H = aViewWin.W * fRatio;
170 : 0 : aViewWin.Y = aViewWin.Y * aViewWin.H / fTmp;
171 : 0 : break;
172 : :
173 : : case AS_HOLD_Y:
174 : : // Adapt view width to view height
175 : 0 : fRatio = (double) nNewW / nNewH;
176 : 0 : fTmp = aViewWin.W;
177 : 0 : aViewWin.W = aViewWin.H * fRatio;
178 : 0 : aViewWin.X = aViewWin.X * aViewWin.W / fTmp;
179 : 0 : break;
180 : 2365 : default: break;
181 : : }
182 : 2365 : fWRatio = nNewW / aViewWin.W;
183 : 2365 : fHRatio = nNewH / aViewWin.H;
184 : :
185 : 2365 : aDeviceRect = rRect;
186 : 2365 : }
187 : :
188 : : // Set View Reference Point
189 : :
190 : 2222 : void Viewport3D::SetVRP(const basegfx::B3DPoint& rNewVRP)
191 : : {
192 : 2222 : aVRP = rNewVRP;
193 : 2222 : bTfValid = sal_False;
194 : 2222 : }
195 : :
196 : : // Set View Plane Normal
197 : :
198 : 2222 : void Viewport3D::SetVPN(const basegfx::B3DVector& rNewVPN)
199 : : {
200 : 2222 : aVPN = rNewVPN;
201 : 2222 : aVPN.normalize();
202 : 2222 : bTfValid = sal_False;
203 : 2222 : }
204 : :
205 : : // Set View Up Vector
206 : :
207 : 2222 : void Viewport3D::SetVUV(const basegfx::B3DVector& rNewVUV)
208 : : {
209 : 2222 : aVUV = rNewVUV;
210 : 2222 : bTfValid = sal_False;
211 : 2222 : }
212 : :
213 : : // Set Center Of Projection
214 : :
215 : 2944 : void Viewport3D::SetPRP(const basegfx::B3DPoint& rNewPRP)
216 : : {
217 : 2944 : aPRP = rNewPRP;
218 : 2944 : aPRP.setX(0.0);
219 : 2944 : aPRP.setY(0.0);
220 : 2944 : bTfValid = sal_False;
221 : 2944 : }
222 : :
223 : : // Set View Plane Distance
224 : :
225 : 736 : void Viewport3D::SetVPD(double fNewVPD)
226 : : {
227 : 736 : fVPD = fNewVPD;
228 : 736 : bTfValid = sal_False;
229 : 736 : }
230 : :
231 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|