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