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/camera3d.hxx> 31 #include <tools/stream.hxx> 32 33 /************************************************************************* 34 |* 35 |* Konstruktor 36 |* 37 \************************************************************************/ 38 39 Camera3D::Camera3D(const basegfx::B3DPoint& rPos, const basegfx::B3DPoint& rLookAt, 40 double fFocalLen, double fBankAng) : 41 aResetPos(rPos), 42 aResetLookAt(rLookAt), 43 fResetFocalLength(fFocalLen), 44 fResetBankAngle(fBankAng), 45 fBankAngle(fBankAng), 46 bAutoAdjustProjection(sal_True) 47 { 48 SetVPD(0); 49 SetPosition(rPos); 50 SetLookAt(rLookAt); 51 SetFocalLength(fFocalLen); 52 } 53 54 /************************************************************************* 55 |* 56 |* Default-Konstruktor 57 |* 58 \************************************************************************/ 59 60 Camera3D::Camera3D() 61 { 62 basegfx::B3DPoint aVector3D(0.0 ,0.0 ,1.0); 63 Camera3D(aVector3D, basegfx::B3DPoint()); 64 } 65 66 /************************************************************************* 67 |* 68 |* Konstruktor 69 |* 70 \************************************************************************/ 71 72 void Camera3D::Reset() 73 { 74 SetVPD(0); 75 fBankAngle = fResetBankAngle; 76 SetPosition(aResetPos); 77 SetLookAt(aResetLookAt); 78 SetFocalLength(fResetFocalLength); 79 } 80 81 /************************************************************************* 82 |* 83 |* Defaultwerte fuer Reset setzen 84 |* 85 \************************************************************************/ 86 87 void Camera3D::SetDefaults(const basegfx::B3DPoint& rPos, const basegfx::B3DPoint& rLookAt, 88 double fFocalLen, double fBankAng) 89 { 90 aResetPos = rPos; 91 aResetLookAt = rLookAt; 92 fResetFocalLength = fFocalLen; 93 fResetBankAngle = fBankAng; 94 } 95 96 /************************************************************************* 97 |* 98 |* ViewWindow setzen und PRP anpassen 99 |* 100 \************************************************************************/ 101 102 void Camera3D::SetViewWindow(double fX, double fY, double fW, double fH) 103 { 104 Viewport3D::SetViewWindow(fX, fY, fW, fH); 105 if ( bAutoAdjustProjection ) 106 SetFocalLength(fFocalLength); 107 } 108 109 /************************************************************************* 110 |* 111 |* Kameraposition setzen 112 |* 113 \************************************************************************/ 114 115 void Camera3D::SetPosition(const basegfx::B3DPoint& rNewPos) 116 { 117 if ( rNewPos != aPosition ) 118 { 119 aPosition = rNewPos; 120 SetVRP(aPosition); 121 SetVPN(aPosition - aLookAt); 122 SetBankAngle(fBankAngle); 123 } 124 } 125 126 /************************************************************************* 127 |* 128 |* Blickpunkt setzen 129 |* 130 \************************************************************************/ 131 132 void Camera3D::SetLookAt(const basegfx::B3DPoint& rNewLookAt) 133 { 134 if ( rNewLookAt != aLookAt ) 135 { 136 aLookAt = rNewLookAt; 137 SetVPN(aPosition - aLookAt); 138 SetBankAngle(fBankAngle); 139 } 140 } 141 142 /************************************************************************* 143 |* 144 |* Position und Blickpunkt setzen 145 |* 146 \************************************************************************/ 147 148 void Camera3D::SetPosAndLookAt(const basegfx::B3DPoint& rNewPos, 149 const basegfx::B3DPoint& rNewLookAt) 150 { 151 if ( rNewPos != aPosition || rNewLookAt != aLookAt ) 152 { 153 aPosition = rNewPos; 154 aLookAt = rNewLookAt; 155 156 SetVRP(aPosition); 157 SetVPN(aPosition - aLookAt); 158 SetBankAngle(fBankAngle); 159 } 160 } 161 162 /************************************************************************* 163 |* 164 |* seitlichen Neigungswinkel setzen 165 |* 166 \************************************************************************/ 167 168 void Camera3D::SetBankAngle(double fAngle) 169 { 170 basegfx::B3DVector aDiff(aPosition - aLookAt); 171 basegfx::B3DVector aPrj(aDiff); 172 fBankAngle = fAngle; 173 174 if ( aDiff.getY() == 0 ) 175 { 176 aPrj.setY(-1.0); 177 } 178 else 179 { // aPrj = Projektion von aDiff auf die XZ-Ebene 180 aPrj.setY(0.0); 181 182 if ( aDiff.getY() < 0.0 ) 183 { 184 aPrj = -aPrj; 185 } 186 } 187 188 // von aDiff nach oben zeigenden View-Up-Vektor berechnen 189 aPrj = aPrj.getPerpendicular(aDiff); 190 aPrj = aPrj.getPerpendicular(aDiff); 191 aDiff.normalize(); 192 193 // auf Z-Achse rotieren, dort um BankAngle drehen und zurueck 194 basegfx::B3DHomMatrix aTf; 195 const double fV(sqrt(aDiff.getY() * aDiff.getY() + aDiff.getZ() * aDiff.getZ())); 196 197 if ( fV != 0.0 ) 198 { 199 basegfx::B3DHomMatrix aTemp; 200 const double fSin(aDiff.getY() / fV); 201 const double fCos(aDiff.getZ() / fV); 202 203 aTemp.set(1, 1, fCos); 204 aTemp.set(2, 2, fCos); 205 aTemp.set(2, 1, fSin); 206 aTemp.set(1, 2, -fSin); 207 208 aTf *= aTemp; 209 } 210 211 { 212 basegfx::B3DHomMatrix aTemp; 213 const double fSin(-aDiff.getX()); 214 const double fCos(fV); 215 216 aTemp.set(0, 0, fCos); 217 aTemp.set(2, 2, fCos); 218 aTemp.set(0, 2, fSin); 219 aTemp.set(2, 0, -fSin); 220 221 aTf *= aTemp; 222 } 223 224 aTf.rotate(0.0, 0.0, fBankAngle); 225 226 { 227 basegfx::B3DHomMatrix aTemp; 228 const double fSin(aDiff.getX()); 229 const double fCos(fV); 230 231 aTemp.set(0, 0, fCos); 232 aTemp.set(2, 2, fCos); 233 aTemp.set(0, 2, fSin); 234 aTemp.set(2, 0, -fSin); 235 236 aTf *= aTemp; 237 } 238 239 if ( fV != 0.0 ) 240 { 241 basegfx::B3DHomMatrix aTemp; 242 const double fSin(-aDiff.getY() / fV); 243 const double fCos(aDiff.getZ() / fV); 244 245 aTemp.set(1, 1, fCos); 246 aTemp.set(2, 2, fCos); 247 aTemp.set(2, 1, fSin); 248 aTemp.set(1, 2, -fSin); 249 250 aTf *= aTemp; 251 } 252 253 SetVUV(aTf * aPrj); 254 } 255 256 /************************************************************************* 257 |* 258 |* Brennweite setzen 259 |* 260 \************************************************************************/ 261 262 void Camera3D::SetFocalLength(double fLen) 263 { 264 if ( fLen < 5 ) 265 fLen = 5; 266 SetPRP(basegfx::B3DPoint(0.0, 0.0, fLen / 35.0 * aViewWin.W)); 267 fFocalLength = fLen; 268 } 269 270 /************************************************************************* 271 |* 272 |* Um die Kameraposition drehen, LookAt wird dabei veraendert 273 |* 274 \************************************************************************/ 275 276 void Camera3D::Rotate(double fHAngle, double fVAngle) 277 { 278 basegfx::B3DHomMatrix aTf; 279 basegfx::B3DVector aDiff(aLookAt - aPosition); 280 const double fV(sqrt(aDiff.getX() * aDiff.getX() + aDiff.getZ() * aDiff.getZ())); 281 282 if ( fV != 0.0 ) 283 { 284 basegfx::B3DHomMatrix aTemp; 285 const double fSin(aDiff.getZ() / fV); 286 const double fCos(aDiff.getX() / fV); 287 288 aTemp.set(0, 0, fCos); 289 aTemp.set(2, 2, fCos); 290 aTemp.set(0, 2, fSin); 291 aTemp.set(2, 0, -fSin); 292 293 aTf *= aTemp; 294 } 295 296 { 297 aTf.rotate(0.0, 0.0, fVAngle); 298 } 299 300 if ( fV != 0.0 ) 301 { 302 basegfx::B3DHomMatrix aTemp; 303 const double fSin(-aDiff.getZ() / fV); 304 const double fCos(aDiff.getX() / fV); 305 306 aTemp.set(0, 0, fCos); 307 aTemp.set(2, 2, fCos); 308 aTemp.set(0, 2, fSin); 309 aTemp.set(2, 0, -fSin); 310 311 aTf *= aTemp; 312 } 313 314 { 315 aTf.rotate(0.0, fHAngle, 0.0); 316 } 317 318 aDiff *= aTf; 319 SetLookAt(aPosition + aDiff); 320 } 321 322 323 /************************************************************************* 324 |* 325 |* Um den Blickpunkt drehen, Position wird dabei veraendert 326 |* 327 \************************************************************************/ 328 329 void Camera3D::RotateAroundLookAt(double fHAngle, double fVAngle) 330 { 331 basegfx::B3DHomMatrix aTf; 332 basegfx::B3DVector aDiff(aPosition - aLookAt); 333 const double fV(sqrt(aDiff.getX() * aDiff.getX() + aDiff.getZ() * aDiff.getZ())); 334 335 if ( fV != 0.0 ) 336 { 337 basegfx::B3DHomMatrix aTemp; 338 const double fSin(aDiff.getZ() / fV); 339 const double fCos(aDiff.getX() / fV); 340 341 aTemp.set(0, 0, fCos); 342 aTemp.set(2, 2, fCos); 343 aTemp.set(0, 2, fSin); 344 aTemp.set(2, 0, -fSin); 345 346 aTf *= aTemp; 347 } 348 349 { 350 aTf.rotate(0.0, 0.0, fVAngle); 351 } 352 353 if ( fV != 0.0 ) 354 { 355 basegfx::B3DHomMatrix aTemp; 356 const double fSin(-aDiff.getZ() / fV); 357 const double fCos(aDiff.getX() / fV); 358 359 aTemp.set(0, 0, fCos); 360 aTemp.set(2, 2, fCos); 361 aTemp.set(0, 2, fSin); 362 aTemp.set(2, 0, -fSin); 363 364 aTf *= aTemp; 365 } 366 367 { 368 aTf.rotate(0.0, fHAngle, 0.0); 369 } 370 371 aDiff *= aTf; 372 SetPosition(aLookAt + aDiff); 373 } 374 375 /************************************************************************* 376 |* 377 |* FG: ??? Setzt wohl die Projektionsebene in eine bestimmte Tiefe 378 |* 379 \************************************************************************/ 380 381 void Camera3D::SetFocalLengthWithCorrect(double fLen) 382 { 383 if ( fLen < 5.0 ) 384 { 385 fLen = 5.0; 386 } 387 388 SetPRP(basegfx::B3DPoint(0.0, 0.0, aPRP.getZ() * fLen / fFocalLength)); 389 fFocalLength = fLen; 390 } 391 392 // eof 393