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