1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_svx.hxx" 30 #include <svx/viewpt3d.hxx> 31 #include <svx/volume3d.hxx> 32 33 /************************************************************************* 34 |* 35 |* Konstruktor 36 |* 37 \************************************************************************/ 38 39 Viewport3D::Viewport3D() : 40 aVRP(0, 0, 5), 41 aVPN(0, 0, 1), 42 aVUV(0, 1, 1), 43 aPRP(0, 0, 2), 44 fVPD(-3), 45 fNearClipDist (0.0), 46 fFarClipDist (0.0), 47 eProjection(PR_PERSPECTIVE), 48 eAspectMapping(AS_NO_MAPPING), 49 aDeviceRect(Point(0,0), Size(-1,-1)), 50 aViewPoint (0, 0, 5000), 51 bTfValid(0), 52 fWRatio (1.0), 53 fHRatio (1.0) 54 { 55 aViewWin.X = -1; aViewWin.Y = -1; 56 aViewWin.W = 2; aViewWin.H = 2; 57 } 58 59 /************************************************************************* 60 |* 61 |* ViewWindow (in View-Koordinaten) setzen 62 |* 63 \************************************************************************/ 64 65 void Viewport3D::SetViewWindow(double fX, double fY, double fW, double fH) 66 { 67 aViewWin.X = fX; 68 aViewWin.Y = fY; 69 if ( fW > 0 ) aViewWin.W = fW; 70 else aViewWin.W = 1.0; 71 if ( fH > 0 ) aViewWin.H = fH; 72 else aViewWin.H = 1.0; 73 74 fWRatio = aDeviceRect.GetWidth() / aViewWin.W; 75 fHRatio = aDeviceRect.GetHeight() / aViewWin.H; 76 } 77 78 /************************************************************************* 79 |* 80 |* ViewWindow zurueckgeben 81 |* 82 \************************************************************************/ 83 84 void Viewport3D::GetViewWindow(double& rX, double& rY, 85 double& rW, double& rH) const 86 { 87 rX = aViewWin.X; 88 rY = aViewWin.Y; 89 rW = aViewWin.W; 90 rH = aViewWin.H; 91 } 92 93 /************************************************************************* 94 |* 95 |* Beobachterposition (PRP) in Weltkoordinaten zurueckgeben 96 |* 97 \************************************************************************/ 98 99 const basegfx::B3DPoint& Viewport3D::GetViewPoint() 100 { 101 MakeTransform(); 102 103 return aViewPoint; 104 } 105 106 /************************************************************************* 107 |* 108 |* Transformationsmatrix zurueckgeben 109 |* 110 \************************************************************************/ 111 112 const basegfx::B3DHomMatrix& Viewport3D::GetViewTransform() 113 { 114 MakeTransform(); 115 116 return aViewTf; 117 } 118 119 120 121 122 123 124 125 /************************************************************************* 126 |* 127 |* View-Transformationsmatrix berechnen 128 |* 129 \************************************************************************/ 130 131 void Viewport3D::MakeTransform(void) 132 { 133 if ( !bTfValid ) 134 { 135 double fV, fXupVp, fYupVp; 136 aViewPoint = aVRP + aVPN * aPRP.getZ(); 137 138 // auf Einheitsmatrix zuruecksetzen 139 aViewTf.identity(); 140 141 // in den Ursprung verschieben 142 aViewTf.translate(-aVRP.getX(), -aVRP.getY(), -aVRP.getZ()); 143 144 // fV = Laenge der Projektion von aVPN auf die yz-Ebene: 145 fV = aVPN.getYZLength(); 146 147 if ( fV != 0 ) 148 { 149 basegfx::B3DHomMatrix aTemp; 150 const double fSin(aVPN.getY() / fV); 151 const double fCos(aVPN.getZ() / fV); 152 aTemp.set(2, 2, fCos); 153 aTemp.set(1, 1, fCos); 154 aTemp.set(2, 1, fSin); 155 aTemp.set(1, 2, -fSin); 156 aViewTf *= aTemp; 157 } 158 159 { 160 basegfx::B3DHomMatrix aTemp; 161 const double fSin(-aVPN.getX()); 162 const double fCos(fV); 163 aTemp.set(2, 2, fCos); 164 aTemp.set(0, 0, fCos); 165 aTemp.set(0, 2, fSin); 166 aTemp.set(2, 0, -fSin); 167 aViewTf *= aTemp; 168 } 169 170 // X- und Y-Koordinaten des View Up Vektors in das (vorlaeufige) 171 // View-Koordinatensytem umrechnen 172 fXupVp = aViewTf.get(0, 0) * aVUV.getX() + aViewTf.get(0, 1) * aVUV.getY() + aViewTf.get(0, 2) * aVUV.getZ(); 173 fYupVp = aViewTf.get(1, 0) * aVUV.getX() + aViewTf.get(1, 1) * aVUV.getY() + aViewTf.get(1, 2) * aVUV.getZ(); 174 fV = sqrt(fXupVp * fXupVp + fYupVp * fYupVp); 175 176 if ( fV != 0 ) 177 { 178 basegfx::B3DHomMatrix aTemp; 179 const double fSin(fXupVp / fV); 180 const double fCos(fYupVp / fV); 181 aTemp.set(1, 1, fCos); 182 aTemp.set(0, 0, fCos); 183 aTemp.set(1, 0, fSin); 184 aTemp.set(0, 1, -fSin); 185 aViewTf *= aTemp; 186 } 187 188 bTfValid = sal_True; 189 } 190 } 191 192 /************************************************************************* 193 |* 194 |* DeviceWindow des Ausgabegeraetes setzen 195 |* 196 \************************************************************************/ 197 198 void Viewport3D::SetDeviceWindow(const Rectangle& rRect) 199 { 200 long nNewW = rRect.GetWidth(); 201 long nNewH = rRect.GetHeight(); 202 long nOldW = aDeviceRect.GetWidth(); 203 long nOldH = aDeviceRect.GetHeight(); 204 205 switch ( eAspectMapping ) 206 { 207 double fRatio, fTmp; 208 209 // Mapping, ohne die reale Groesse der Objekte im Device-Window 210 // zu aendern 211 case AS_HOLD_SIZE: 212 // Wenn Device ungueltig (w, h = -1), zunaechst 213 // View mit AsHoldX anpassen 214 if ( nOldW > 0 && nOldH > 0 ) 215 { 216 fRatio = (double) nNewW / nOldW; 217 aViewWin.X *= fRatio; 218 aViewWin.W *= fRatio; 219 fRatio = (double) nNewH / nOldH; 220 aViewWin.Y *= fRatio; 221 aViewWin.H *= fRatio; 222 break; 223 } 224 case AS_HOLD_X: 225 // View-Hoehe an -Breite anpassen 226 fRatio = (double) nNewH / nNewW; 227 fTmp = aViewWin.H; 228 aViewWin.H = aViewWin.W * fRatio; 229 aViewWin.Y = aViewWin.Y * aViewWin.H / fTmp; 230 break; 231 232 case AS_HOLD_Y: 233 // View-Breite an -Hoehe anpassen 234 fRatio = (double) nNewW / nNewH; 235 fTmp = aViewWin.W; 236 aViewWin.W = aViewWin.H * fRatio; 237 aViewWin.X = aViewWin.X * aViewWin.W / fTmp; 238 break; 239 default: break; 240 } 241 fWRatio = nNewW / aViewWin.W; 242 fHRatio = nNewH / aViewWin.H; 243 244 aDeviceRect = rRect; 245 } 246 247 248 249 250 251 252 253 254 255 256 /************************************************************************* 257 |* 258 |* 3D-Punkt auf Viewplane projizieren 259 |* 260 \************************************************************************/ 261 262 basegfx::B3DPoint Viewport3D::DoProjection(const basegfx::B3DPoint& rVec) const 263 { 264 basegfx::B3DPoint aVec(rVec); 265 266 if ( eProjection == PR_PERSPECTIVE ) 267 { 268 double fPrDist = fVPD - aPRP.getZ(); 269 270 if ( aPRP.getZ() == rVec.getZ() ) 271 { 272 aVec.setX(0.0); 273 aVec.setY(0.0); 274 } 275 else 276 { 277 // Das ist die Version fuer beliebigen PRP, wird aber 278 // aus Performancegruenden nicht verwendet 279 fPrDist /= aVec.getZ() - aPRP.getZ(); 280 aVec.setX(aVec.getX() * fPrDist); 281 aVec.setY(aVec.getY() * fPrDist); 282 } 283 } 284 285 return aVec; 286 } 287 288 /************************************************************************* 289 |* 290 |* 3D-Punkt auf Geraetekoordinaten mappen 291 |* 292 \************************************************************************/ 293 294 basegfx::B3DPoint Viewport3D::MapToDevice(const basegfx::B3DPoint& rVec) const 295 { 296 basegfx::B3DPoint aRetval; 297 298 // Y-Koordinate subtrahieren, da die Device-Y-Achse von oben 299 // nach unten verlaeuft 300 aRetval.setX((double)aDeviceRect.Left() + ((rVec.getX() - aViewWin.X) * fWRatio)); 301 aRetval.setY((double)aDeviceRect.Bottom() - ((rVec.getY() - aViewWin.Y) * fHRatio)); 302 aRetval.setZ(rVec.getZ()); 303 304 return aRetval; 305 } 306 307 /************************************************************************* 308 |* 309 |* View Reference Point setzen 310 |* 311 \************************************************************************/ 312 313 void Viewport3D::SetVRP(const basegfx::B3DPoint& rNewVRP) 314 { 315 aVRP = rNewVRP; 316 bTfValid = sal_False; 317 } 318 319 /************************************************************************* 320 |* 321 |* View Plane Normal setzen 322 |* 323 \************************************************************************/ 324 325 void Viewport3D::SetVPN(const basegfx::B3DVector& rNewVPN) 326 { 327 aVPN = rNewVPN; 328 aVPN.normalize(); 329 bTfValid = sal_False; 330 } 331 332 /************************************************************************* 333 |* 334 |* View Up Vector setzen 335 |* 336 \************************************************************************/ 337 338 void Viewport3D::SetVUV(const basegfx::B3DVector& rNewVUV) 339 { 340 aVUV = rNewVUV; 341 bTfValid = sal_False; 342 } 343 344 /************************************************************************* 345 |* 346 |* Center Of Projection setzen 347 |* 348 \************************************************************************/ 349 350 void Viewport3D::SetPRP(const basegfx::B3DPoint& rNewPRP) 351 { 352 aPRP = rNewPRP; 353 aPRP.setX(0.0); 354 aPRP.setY(0.0); 355 bTfValid = sal_False; 356 } 357 358 /************************************************************************* 359 |* 360 |* View Plane Distance setzen 361 |* 362 \************************************************************************/ 363 364 void Viewport3D::SetVPD(double fNewVPD) 365 { 366 fVPD = fNewVPD; 367 bTfValid = sal_False; 368 } 369 370 /************************************************************************* 371 |* 372 |* Abstand der vorderen Clippingebene setzen 373 |* 374 \************************************************************************/ 375 376 void Viewport3D::SetNearClipDist(double fNewNCD) 377 { 378 fNearClipDist = fNewNCD; 379 bTfValid = sal_False; 380 } 381 382 /************************************************************************* 383 |* 384 |* Abstand der hinteren Clippingebene setzen 385 |* 386 \************************************************************************/ 387 388 void Viewport3D::SetFarClipDist(double fNewFCD) 389 { 390 fFarClipDist = fNewFCD; 391 bTfValid = sal_False; 392 } 393 394 // eof 395