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_tools.hxx" 30 #include <tools/b3dtrans.hxx> 31 #include <tools/debug.hxx> 32 33 /************************************************************************* 34 |* 35 |* Transformationen fuer alle 3D Ausgaben 36 |* 37 \************************************************************************/ 38 39 B3dTransformationSet::B3dTransformationSet() 40 { 41 Reset(); 42 } 43 44 B3dTransformationSet::~B3dTransformationSet() 45 { 46 } 47 48 void B3dTransformationSet::Orientation(basegfx::B3DHomMatrix& rTarget, basegfx::B3DPoint aVRP, basegfx::B3DVector aVPN, basegfx::B3DVector aVUP) 49 { 50 rTarget.translate( -aVRP.getX(), -aVRP.getY(), -aVRP.getZ()); 51 aVUP.normalize(); 52 aVPN.normalize(); 53 basegfx::B3DVector aRx(aVUP); 54 basegfx::B3DVector aRy(aVPN); 55 aRx = aRx.getPerpendicular(aRy); 56 aRx.normalize(); 57 aRy = aRy.getPerpendicular(aRx); 58 aRy.normalize(); 59 basegfx::B3DHomMatrix aTemp; 60 aTemp.set(0, 0, aRx.getX()); 61 aTemp.set(0, 1, aRx.getY()); 62 aTemp.set(0, 2, aRx.getZ()); 63 aTemp.set(1, 0, aRy.getX()); 64 aTemp.set(1, 1, aRy.getY()); 65 aTemp.set(1, 2, aRy.getZ()); 66 aTemp.set(2, 0, aVPN.getX()); 67 aTemp.set(2, 1, aVPN.getY()); 68 aTemp.set(2, 2, aVPN.getZ()); 69 rTarget *= aTemp; 70 } 71 72 void B3dTransformationSet::Frustum(basegfx::B3DHomMatrix& rTarget, double fLeft, double fRight, double fBottom, double fTop, double fNear, double fFar) 73 { 74 if(!(fNear > 0.0)) 75 { 76 fNear = 0.001; 77 } 78 if(!(fFar > 0.0)) 79 { 80 fFar = 1.0; 81 } 82 if(fNear == fFar) 83 { 84 fFar = fNear + 1.0; 85 } 86 if(fLeft == fRight) 87 { 88 fLeft -= 1.0; 89 fRight += 1.0; 90 } 91 if(fTop == fBottom) 92 { 93 fBottom -= 1.0; 94 fTop += 1.0; 95 } 96 basegfx::B3DHomMatrix aTemp; 97 98 aTemp.set(0, 0, 2.0 * fNear / (fRight - fLeft)); 99 aTemp.set(1, 1, 2.0 * fNear / (fTop - fBottom)); 100 aTemp.set(0, 2, (fRight + fLeft) / (fRight - fLeft)); 101 aTemp.set(1, 2, (fTop + fBottom) / (fTop - fBottom)); 102 aTemp.set(2, 2, -1.0 * ((fFar + fNear) / (fFar - fNear))); 103 aTemp.set(3, 2, -1.0); 104 aTemp.set(2, 3, -1.0 * ((2.0 * fFar * fNear) / (fFar - fNear))); 105 aTemp.set(3, 3, 0.0); 106 107 rTarget *= aTemp; 108 } 109 110 void B3dTransformationSet::Ortho(basegfx::B3DHomMatrix& rTarget, double fLeft, double fRight, double fBottom, double fTop, double fNear, double fFar) 111 { 112 if(fNear == fFar) 113 { 114 DBG_ERROR("Near and far clipping plane in Ortho definition are identical"); 115 fFar = fNear + 1.0; 116 } 117 if(fLeft == fRight) 118 { 119 DBG_ERROR("Left and right in Ortho definition are identical"); 120 fLeft -= 1.0; 121 fRight += 1.0; 122 } 123 if(fTop == fBottom) 124 { 125 DBG_ERROR("Top and bottom in Ortho definition are identical"); 126 fBottom -= 1.0; 127 fTop += 1.0; 128 } 129 basegfx::B3DHomMatrix aTemp; 130 131 aTemp.set(0, 0, 2.0 / (fRight - fLeft)); 132 aTemp.set(1, 1, 2.0 / (fTop - fBottom)); 133 aTemp.set(2, 2, -1.0 * (2.0 / (fFar - fNear))); 134 aTemp.set(0, 3, -1.0 * ((fRight + fLeft) / (fRight - fLeft))); 135 aTemp.set(1, 3, -1.0 * ((fTop + fBottom) / (fTop - fBottom))); 136 aTemp.set(2, 3, -1.0 * ((fFar + fNear) / (fFar - fNear))); 137 138 rTarget *= aTemp; 139 } 140 141 /************************************************************************* 142 |* 143 |* Reset der Werte 144 |* 145 \************************************************************************/ 146 147 void B3dTransformationSet::Reset() 148 { 149 // Matritzen auf Einheitsmatritzen 150 maObjectTrans.identity(); 151 PostSetObjectTrans(); 152 153 Orientation(maOrientation); 154 PostSetOrientation(); 155 156 maTexture.identity(); 157 158 mfLeftBound = mfBottomBound = -1.0; 159 mfRightBound = mfTopBound = 1.0; 160 mfNearBound = 0.001; 161 mfFarBound = 1.001; 162 163 meRatio = Base3DRatioGrow; 164 mfRatio = 0.0; 165 166 maViewportRectangle = Rectangle(-1, -1, 2, 2); 167 maVisibleRectangle = maViewportRectangle; 168 169 mbPerspective = sal_True; 170 171 mbProjectionValid = sal_False; 172 mbObjectToDeviceValid = sal_False; 173 mbWorldToViewValid = sal_False; 174 175 CalcViewport(); 176 } 177 178 /************************************************************************* 179 |* 180 |* Objekttransformation 181 |* 182 \************************************************************************/ 183 184 void B3dTransformationSet::SetObjectTrans(const basegfx::B3DHomMatrix& rObj) 185 { 186 maObjectTrans = rObj; 187 188 mbObjectToDeviceValid = sal_False; 189 mbInvTransObjectToEyeValid = sal_False; 190 191 PostSetObjectTrans(); 192 } 193 194 void B3dTransformationSet::PostSetObjectTrans() 195 { 196 // Zuweisen und Inverse bestimmen 197 maInvObjectTrans = maObjectTrans; 198 maInvObjectTrans.invert(); 199 } 200 201 /************************************************************************* 202 |* 203 |* Orientierungstransformation 204 |* 205 \************************************************************************/ 206 207 void B3dTransformationSet::SetOrientation( basegfx::B3DPoint aVRP, basegfx::B3DVector aVPN, basegfx::B3DVector aVUP) 208 { 209 maOrientation.identity(); 210 Orientation(maOrientation, aVRP, aVPN, aVUP); 211 212 mbInvTransObjectToEyeValid = sal_False; 213 mbObjectToDeviceValid = sal_False; 214 mbWorldToViewValid = sal_False; 215 216 PostSetOrientation(); 217 } 218 219 void B3dTransformationSet::SetOrientation(basegfx::B3DHomMatrix& mOrient) 220 { 221 maOrientation = mOrient; 222 223 mbInvTransObjectToEyeValid = sal_False; 224 mbObjectToDeviceValid = sal_False; 225 mbWorldToViewValid = sal_False; 226 227 PostSetOrientation(); 228 } 229 230 void B3dTransformationSet::PostSetOrientation() 231 { 232 // Zuweisen und Inverse bestimmen 233 maInvOrientation = maOrientation; 234 maInvOrientation.invert(); 235 } 236 237 /************************************************************************* 238 |* 239 |* Projektionstransformation 240 |* 241 \************************************************************************/ 242 243 void B3dTransformationSet::SetProjection(const basegfx::B3DHomMatrix& mProject) 244 { 245 maProjection = mProject; 246 PostSetProjection(); 247 } 248 249 const basegfx::B3DHomMatrix& B3dTransformationSet::GetProjection() 250 { 251 if(!mbProjectionValid) 252 CalcViewport(); 253 return maProjection; 254 } 255 256 const basegfx::B3DHomMatrix& B3dTransformationSet::GetInvProjection() 257 { 258 if(!mbProjectionValid) 259 CalcViewport(); 260 return maInvProjection; 261 } 262 263 void B3dTransformationSet::PostSetProjection() 264 { 265 // Zuweisen und Inverse bestimmen 266 maInvProjection = GetProjection(); 267 maInvProjection.invert(); 268 269 // Abhaengige Matritzen invalidieren 270 mbObjectToDeviceValid = sal_False; 271 mbWorldToViewValid = sal_False; 272 } 273 274 /************************************************************************* 275 |* 276 |* Texturtransformation 277 |* 278 \************************************************************************/ 279 280 void B3dTransformationSet::SetTexture(const basegfx::B2DHomMatrix& rTxt) 281 { 282 maTexture = rTxt; 283 PostSetTexture(); 284 } 285 286 void B3dTransformationSet::PostSetTexture() 287 { 288 } 289 290 /************************************************************************* 291 |* 292 |* Viewport-Transformation 293 |* 294 \************************************************************************/ 295 296 void B3dTransformationSet::CalcViewport() 297 { 298 // Faktoren fuer die Projektion 299 double fLeft(mfLeftBound); 300 double fRight(mfRightBound); 301 double fBottom(mfBottomBound); 302 double fTop(mfTopBound); 303 304 // Soll das Seitenverhaeltnis Beachtung finden? 305 // Falls ja, Bereich der Projektion an Seitenverhaeltnis anpassen 306 if(GetRatio() != 0.0) 307 { 308 // Berechne aktuelles Seitenverhaeltnis der Bounds 309 double fBoundWidth = (double)(maViewportRectangle.GetWidth() + 1); 310 double fBoundHeight = (double)(maViewportRectangle.GetHeight() + 1); 311 double fActRatio = 1; 312 double fFactor; 313 314 if(fBoundWidth != 0.0) 315 fActRatio = fBoundHeight / fBoundWidth; 316 // FIXME else in this case has a lot of problems, should this return. 317 318 switch(meRatio) 319 { 320 case Base3DRatioShrink : 321 { 322 // Kleineren Teil vergroessern 323 if(fActRatio > mfRatio) 324 { 325 // X vergroessern 326 fFactor = 1.0 / fActRatio; 327 fRight *= fFactor; 328 fLeft *= fFactor; 329 } 330 else 331 { 332 // Y vergroessern 333 fFactor = fActRatio; 334 fTop *= fFactor; 335 fBottom *= fFactor; 336 } 337 break; 338 } 339 case Base3DRatioGrow : 340 { 341 // GroesserenTeil verkleinern 342 if(fActRatio > mfRatio) 343 { 344 // Y verkleinern 345 fFactor = fActRatio; 346 fTop *= fFactor; 347 fBottom *= fFactor; 348 } 349 else 350 { 351 // X verkleinern 352 fFactor = 1.0 / fActRatio; 353 fRight *= fFactor; 354 fLeft *= fFactor; 355 } 356 break; 357 } 358 case Base3DRatioMiddle : 359 { 360 // Mitteln 361 fFactor = ((1.0 / fActRatio) + 1.0) / 2.0; 362 fRight *= fFactor; 363 fLeft *= fFactor; 364 fFactor = (fActRatio + 1.0) / 2.0; 365 fTop *= fFactor; 366 fBottom *= fFactor; 367 break; 368 } 369 } 370 } 371 372 // Ueberschneiden sich Darstellungsflaeche und Objektflaeche? 373 maSetBound = maViewportRectangle; 374 375 // Mit den neuen Werten Projektion und ViewPort setzen 376 basegfx::B3DHomMatrix aNewProjection; 377 378 // #i36281# 379 // OpenGL needs a little more rough additional size to not let 380 // the front face vanish. Changed from SMALL_DVALUE to 0.000001, 381 // which is 1/10000th, comared with 1/tenth of a million from SMALL_DVALUE. 382 const double fDistPart((mfFarBound - mfNearBound) * 0.0001); 383 384 // Near, Far etwas grosszuegiger setzen, um falsches, 385 // zu kritisches clippen zu verhindern 386 if(mbPerspective) 387 { 388 Frustum(aNewProjection, fLeft, fRight, fBottom, fTop, mfNearBound - fDistPart, mfFarBound + fDistPart); 389 } 390 else 391 { 392 Ortho(aNewProjection, fLeft, fRight, fBottom, fTop, mfNearBound - fDistPart, mfFarBound + fDistPart); 393 } 394 395 // jetzt schon auf gueltig setzen um Endlosschleife zu vermeiden 396 mbProjectionValid = sal_True; 397 398 // Neue Projektion setzen 399 SetProjection(aNewProjection); 400 401 // fill parameters for ViewportTransformation 402 // Translation 403 maTranslate.setX((double)maSetBound.Left() + ((maSetBound.GetWidth() - 1L) / 2.0)); 404 maTranslate.setY((double)maSetBound.Top() + ((maSetBound.GetHeight() - 1L) / 2.0)); 405 maTranslate.setZ(ZBUFFER_DEPTH_RANGE / 2.0); 406 407 // Skalierung 408 maScale.setX((maSetBound.GetWidth() - 1L) / 2.0); 409 maScale.setY((maSetBound.GetHeight() - 1L) / -2.0); 410 maScale.setZ(ZBUFFER_DEPTH_RANGE / 2.0); 411 412 // Auf Veraenderung des ViewPorts reagieren 413 PostSetViewport(); 414 } 415 416 void B3dTransformationSet::SetRatio(double fNew) 417 { 418 if(mfRatio != fNew) 419 { 420 mfRatio = fNew; 421 mbProjectionValid = sal_False; 422 mbObjectToDeviceValid = sal_False; 423 mbWorldToViewValid = sal_False; 424 } 425 } 426 427 void B3dTransformationSet::SetRatioMode(Base3DRatio eNew) 428 { 429 if(meRatio != eNew) 430 { 431 meRatio = eNew; 432 mbProjectionValid = sal_False; 433 mbObjectToDeviceValid = sal_False; 434 mbWorldToViewValid = sal_False; 435 } 436 } 437 438 void B3dTransformationSet::SetDeviceRectangle(double fL, double fR, double fB, double fT, 439 sal_Bool bBroadCastChange) 440 { 441 if(fL != mfLeftBound || fR != mfRightBound || fB != mfBottomBound || fT != mfTopBound) 442 { 443 mfLeftBound = fL; 444 mfRightBound = fR; 445 mfBottomBound = fB; 446 mfTopBound = fT; 447 448 mbProjectionValid = sal_False; 449 mbObjectToDeviceValid = sal_False; 450 mbWorldToViewValid = sal_False; 451 452 // Aenderung bekanntmachen 453 if(bBroadCastChange) 454 DeviceRectangleChange(); 455 } 456 } 457 458 void B3dTransformationSet::SetDeviceVolume(const basegfx::B3DRange& rVol, sal_Bool bBroadCastChange) 459 { 460 SetDeviceRectangle(rVol.getMinX(), rVol.getMaxX(), rVol.getMinY(), rVol.getMaxY(), bBroadCastChange); 461 SetFrontClippingPlane(rVol.getMinZ()); 462 SetBackClippingPlane(rVol.getMaxZ()); 463 } 464 465 void B3dTransformationSet::DeviceRectangleChange() 466 { 467 } 468 469 void B3dTransformationSet::GetDeviceRectangle(double &fL, double &fR, double& fB, double& fT) 470 { 471 fL = mfLeftBound; 472 fR = mfRightBound; 473 fB = mfBottomBound; 474 fT = mfTopBound; 475 476 mbProjectionValid = sal_False; 477 mbObjectToDeviceValid = sal_False; 478 mbWorldToViewValid = sal_False; 479 } 480 481 basegfx::B3DRange B3dTransformationSet::GetDeviceVolume() 482 { 483 basegfx::B3DRange aRet; 484 485 aRet.expand(basegfx::B3DTuple(mfLeftBound, mfBottomBound, mfNearBound)); 486 aRet.expand(basegfx::B3DTuple(mfRightBound, mfTopBound, mfFarBound)); 487 488 return aRet; 489 } 490 491 void B3dTransformationSet::SetFrontClippingPlane(double fF) 492 { 493 if(mfNearBound != fF) 494 { 495 mfNearBound = fF; 496 mbProjectionValid = sal_False; 497 mbObjectToDeviceValid = sal_False; 498 mbWorldToViewValid = sal_False; 499 } 500 } 501 502 void B3dTransformationSet::SetBackClippingPlane(double fB) 503 { 504 if(mfFarBound != fB) 505 { 506 mfFarBound = fB; 507 mbProjectionValid = sal_False; 508 mbObjectToDeviceValid = sal_False; 509 mbWorldToViewValid = sal_False; 510 } 511 } 512 513 void B3dTransformationSet::SetPerspective(sal_Bool bNew) 514 { 515 if(mbPerspective != bNew) 516 { 517 mbPerspective = bNew; 518 mbProjectionValid = sal_False; 519 mbObjectToDeviceValid = sal_False; 520 mbWorldToViewValid = sal_False; 521 } 522 } 523 524 void B3dTransformationSet::SetViewportRectangle(Rectangle& rRect, Rectangle& rVisible) 525 { 526 if(rRect != maViewportRectangle || rVisible != maVisibleRectangle) 527 { 528 maViewportRectangle = rRect; 529 maVisibleRectangle = rVisible; 530 531 mbProjectionValid = sal_False; 532 mbObjectToDeviceValid = sal_False; 533 mbWorldToViewValid = sal_False; 534 } 535 } 536 537 void B3dTransformationSet::PostSetViewport() 538 { 539 } 540 541 const Rectangle& B3dTransformationSet::GetLogicalViewportBounds() 542 { 543 if(!mbProjectionValid) 544 CalcViewport(); 545 return maSetBound; 546 } 547 548 const basegfx::B3DVector& B3dTransformationSet::GetScale() 549 { 550 if(!mbProjectionValid) 551 CalcViewport(); 552 return maScale; 553 } 554 555 const basegfx::B3DVector& B3dTransformationSet::GetTranslate() 556 { 557 if(!mbProjectionValid) 558 CalcViewport(); 559 return maTranslate; 560 } 561 562 /************************************************************************* 563 |* 564 |* Hilfsmatrixberechnungsroutinen 565 |* 566 \************************************************************************/ 567 568 void B3dTransformationSet::CalcMatObjectToDevice() 569 { 570 // ObjectToDevice berechnen (Orientation * Projection * Object) 571 maObjectToDevice = maObjectTrans; 572 maObjectToDevice *= maOrientation; 573 maObjectToDevice *= GetProjection(); 574 575 // auf gueltig setzen 576 mbObjectToDeviceValid = sal_True; 577 } 578 579 const basegfx::B3DHomMatrix& B3dTransformationSet::GetObjectToDevice() 580 { 581 if(!mbObjectToDeviceValid) 582 CalcMatObjectToDevice(); 583 return maObjectToDevice; 584 } 585 586 void B3dTransformationSet::CalcMatInvTransObjectToEye() 587 { 588 maInvTransObjectToEye = maObjectTrans; 589 maInvTransObjectToEye *= maOrientation; 590 maInvTransObjectToEye.invert(); 591 maInvTransObjectToEye.transpose(); 592 593 // eventuelle Translationen rausschmeissen, da diese 594 // Matrix nur zur Transformation von Vektoren gedacht ist 595 maInvTransObjectToEye.set(3, 0, 0.0); 596 maInvTransObjectToEye.set(3, 1, 0.0); 597 maInvTransObjectToEye.set(3, 2, 0.0); 598 maInvTransObjectToEye.set(3, 3, 1.0); 599 600 // auf gueltig setzen 601 mbInvTransObjectToEyeValid = sal_True; 602 } 603 604 const basegfx::B3DHomMatrix& B3dTransformationSet::GetInvTransObjectToEye() 605 { 606 if(!mbInvTransObjectToEyeValid) 607 CalcMatInvTransObjectToEye(); 608 return maInvTransObjectToEye; 609 } 610 611 basegfx::B3DHomMatrix B3dTransformationSet::GetMatFromObjectToView() 612 { 613 basegfx::B3DHomMatrix aFromObjectToView = GetObjectToDevice(); 614 615 const basegfx::B3DVector& rScale(GetScale()); 616 aFromObjectToView.scale(rScale.getX(), rScale.getY(), rScale.getZ()); 617 const basegfx::B3DVector& rTranslate(GetTranslate()); 618 aFromObjectToView.translate(rTranslate.getX(), rTranslate.getY(), rTranslate.getZ()); 619 620 return aFromObjectToView; 621 } 622 623 void B3dTransformationSet::CalcMatFromWorldToView() 624 { 625 maMatFromWorldToView = maOrientation; 626 maMatFromWorldToView *= GetProjection(); 627 const basegfx::B3DVector& rScale(GetScale()); 628 maMatFromWorldToView.scale(rScale.getX(), rScale.getY(), rScale.getZ()); 629 const basegfx::B3DVector& rTranslate(GetTranslate()); 630 maMatFromWorldToView.translate(rTranslate.getX(), rTranslate.getY(), rTranslate.getZ()); 631 maInvMatFromWorldToView = maMatFromWorldToView; 632 maInvMatFromWorldToView.invert(); 633 634 // gueltig setzen 635 mbWorldToViewValid = sal_True; 636 } 637 638 const basegfx::B3DHomMatrix& B3dTransformationSet::GetMatFromWorldToView() 639 { 640 if(!mbWorldToViewValid) 641 CalcMatFromWorldToView(); 642 return maMatFromWorldToView; 643 } 644 645 const basegfx::B3DHomMatrix& B3dTransformationSet::GetInvMatFromWorldToView() 646 { 647 if(!mbWorldToViewValid) 648 CalcMatFromWorldToView(); 649 return maInvMatFromWorldToView; 650 } 651 652 /************************************************************************* 653 |* 654 |* Direkter Zugriff auf verschiedene Transformationen 655 |* 656 \************************************************************************/ 657 658 const basegfx::B3DPoint B3dTransformationSet::WorldToEyeCoor(const basegfx::B3DPoint& rVec) 659 { 660 basegfx::B3DPoint aVec(rVec); 661 aVec *= GetOrientation(); 662 return aVec; 663 } 664 665 const basegfx::B3DPoint B3dTransformationSet::EyeToWorldCoor(const basegfx::B3DPoint& rVec) 666 { 667 basegfx::B3DPoint aVec(rVec); 668 aVec *= GetInvOrientation(); 669 return aVec; 670 } 671 672 const basegfx::B3DPoint B3dTransformationSet::EyeToViewCoor(const basegfx::B3DPoint& rVec) 673 { 674 basegfx::B3DPoint aVec(rVec); 675 aVec *= GetProjection(); 676 aVec *= GetScale(); 677 aVec += GetTranslate(); 678 return aVec; 679 } 680 681 const basegfx::B3DPoint B3dTransformationSet::ViewToEyeCoor(const basegfx::B3DPoint& rVec) 682 { 683 basegfx::B3DPoint aVec(rVec); 684 aVec -= GetTranslate(); 685 aVec = aVec / GetScale(); 686 aVec *= GetInvProjection(); 687 return aVec; 688 } 689 690 const basegfx::B3DPoint B3dTransformationSet::WorldToViewCoor(const basegfx::B3DPoint& rVec) 691 { 692 basegfx::B3DPoint aVec(rVec); 693 aVec *= GetMatFromWorldToView(); 694 return aVec; 695 } 696 697 const basegfx::B3DPoint B3dTransformationSet::ViewToWorldCoor(const basegfx::B3DPoint& rVec) 698 { 699 basegfx::B3DPoint aVec(rVec); 700 aVec *= GetInvMatFromWorldToView(); 701 return aVec; 702 } 703 704 const basegfx::B3DPoint B3dTransformationSet::DeviceToViewCoor(const basegfx::B3DPoint& rVec) 705 { 706 basegfx::B3DPoint aVec(rVec); 707 aVec *= GetScale(); 708 aVec += GetTranslate(); 709 return aVec; 710 } 711 712 const basegfx::B3DPoint B3dTransformationSet::ViewToDeviceCoor(const basegfx::B3DPoint& rVec) 713 { 714 basegfx::B3DPoint aVec(rVec); 715 aVec -= GetTranslate(); 716 aVec = aVec / GetScale(); 717 return aVec; 718 } 719 720 const basegfx::B3DPoint B3dTransformationSet::ObjectToWorldCoor(const basegfx::B3DPoint& rVec) 721 { 722 basegfx::B3DPoint aVec(rVec); 723 aVec *= GetObjectTrans(); 724 return aVec; 725 } 726 727 const basegfx::B3DPoint B3dTransformationSet::WorldToObjectCoor(const basegfx::B3DPoint& rVec) 728 { 729 basegfx::B3DPoint aVec(rVec); 730 aVec *= GetInvObjectTrans(); 731 return aVec; 732 } 733 734 const basegfx::B3DPoint B3dTransformationSet::ObjectToViewCoor(const basegfx::B3DPoint& rVec) 735 { 736 basegfx::B3DPoint aVec(rVec); 737 aVec *= GetObjectTrans(); 738 aVec *= GetMatFromWorldToView(); 739 return aVec; 740 } 741 742 const basegfx::B3DPoint B3dTransformationSet::ViewToObjectCoor(const basegfx::B3DPoint& rVec) 743 { 744 basegfx::B3DPoint aVec(rVec); 745 aVec *= GetInvMatFromWorldToView(); 746 aVec *= GetInvObjectTrans(); 747 return aVec; 748 } 749 750 const basegfx::B3DPoint B3dTransformationSet::ObjectToEyeCoor(const basegfx::B3DPoint& rVec) 751 { 752 basegfx::B3DPoint aVec(rVec); 753 aVec *= GetObjectTrans(); 754 aVec *= GetOrientation(); 755 return aVec; 756 } 757 758 const basegfx::B3DPoint B3dTransformationSet::EyeToObjectCoor(const basegfx::B3DPoint& rVec) 759 { 760 basegfx::B3DPoint aVec(rVec); 761 aVec *= GetInvOrientation(); 762 aVec *= GetInvObjectTrans(); 763 return aVec; 764 } 765 766 const basegfx::B3DPoint B3dTransformationSet::DeviceToEyeCoor(const basegfx::B3DPoint& rVec) 767 { 768 basegfx::B3DPoint aVec(rVec); 769 aVec *= GetInvProjection(); 770 return aVec; 771 } 772 773 const basegfx::B3DPoint B3dTransformationSet::EyeToDeviceCoor(const basegfx::B3DPoint& rVec) 774 { 775 basegfx::B3DPoint aVec(rVec); 776 aVec *= GetProjection(); 777 return aVec; 778 } 779 780 const basegfx::B3DPoint B3dTransformationSet::InvTransObjectToEye(const basegfx::B3DPoint& rVec) 781 { 782 basegfx::B3DPoint aVec(rVec); 783 aVec *= GetInvTransObjectToEye(); 784 return aVec; 785 } 786 787 const basegfx::B2DPoint B3dTransformationSet::TransTextureCoor(const basegfx::B2DPoint& rVec) 788 { 789 basegfx::B2DPoint aVec(rVec); 790 aVec *= GetTexture(); 791 return aVec; 792 } 793 794 /************************************************************************* 795 |* 796 |* Konstruktor B3dViewport 797 |* 798 \************************************************************************/ 799 800 B3dViewport::B3dViewport() 801 : B3dTransformationSet(), 802 aVRP(0, 0, 0), 803 aVPN(0, 0, 1), 804 aVUV(0, 1, 0) 805 { 806 CalcOrientation(); 807 } 808 809 B3dViewport::~B3dViewport() 810 { 811 } 812 813 void B3dViewport::SetVRP(const basegfx::B3DPoint& rNewVRP) 814 { 815 aVRP = rNewVRP; 816 CalcOrientation(); 817 } 818 819 void B3dViewport::SetVPN(const basegfx::B3DVector& rNewVPN) 820 { 821 aVPN = rNewVPN; 822 CalcOrientation(); 823 } 824 825 void B3dViewport::SetVUV(const basegfx::B3DVector& rNewVUV) 826 { 827 aVUV = rNewVUV; 828 CalcOrientation(); 829 } 830 831 void B3dViewport::SetViewportValues( 832 const basegfx::B3DPoint& rNewVRP, 833 const basegfx::B3DVector& rNewVPN, 834 const basegfx::B3DVector& rNewVUV) 835 { 836 aVRP = rNewVRP; 837 aVPN = rNewVPN; 838 aVUV = rNewVUV; 839 CalcOrientation(); 840 } 841 842 void B3dViewport::CalcOrientation() 843 { 844 SetOrientation(aVRP, aVPN, aVUV); 845 } 846 847 /************************************************************************* 848 |* 849 |* Konstruktor B3dViewport 850 |* 851 \************************************************************************/ 852 853 B3dCamera::B3dCamera( 854 const basegfx::B3DPoint& rPos, const basegfx::B3DVector& rLkAt, 855 double fFocLen, double fBnkAng, sal_Bool bUseFocLen) 856 : B3dViewport(), 857 aPosition(rPos), 858 aCorrectedPosition(rPos), 859 aLookAt(rLkAt), 860 fFocalLength(fFocLen), 861 fBankAngle(fBnkAng), 862 bUseFocalLength(bUseFocLen) 863 { 864 CalcNewViewportValues(); 865 } 866 867 B3dCamera::~B3dCamera() 868 { 869 } 870 871 void B3dCamera::SetPosition(const basegfx::B3DPoint& rNewPos) 872 { 873 if(rNewPos != aPosition) 874 { 875 // Zuweisen 876 aCorrectedPosition = aPosition = rNewPos; 877 878 // Neuberechnung 879 CalcNewViewportValues(); 880 } 881 } 882 883 void B3dCamera::SetLookAt(const basegfx::B3DVector& rNewLookAt) 884 { 885 if(rNewLookAt != aLookAt) 886 { 887 // Zuweisen 888 aLookAt = rNewLookAt; 889 890 // Neuberechnung 891 CalcNewViewportValues(); 892 } 893 } 894 895 void B3dCamera::SetPositionAndLookAt(const basegfx::B3DPoint& rNewPos, const basegfx::B3DVector& rNewLookAt) 896 { 897 if(rNewPos != aPosition || rNewLookAt != aLookAt) 898 { 899 // Zuweisen 900 aPosition = rNewPos; 901 aLookAt = rNewLookAt; 902 903 // Neuberechnung 904 CalcNewViewportValues(); 905 } 906 } 907 908 void B3dCamera::SetFocalLength(double fLen) 909 { 910 if(fLen != fFocalLength) 911 { 912 // Zuweisen 913 if(fLen < 5.0) 914 fLen = 5.0; 915 fFocalLength = fLen; 916 917 // Neuberechnung 918 CalcNewViewportValues(); 919 } 920 } 921 922 void B3dCamera::SetBankAngle(double fAngle) 923 { 924 if(fAngle != fBankAngle) 925 { 926 // Zuweisen 927 fBankAngle = fAngle; 928 929 // Neuberechnung 930 CalcNewViewportValues(); 931 } 932 } 933 934 void B3dCamera::SetUseFocalLength(sal_Bool bNew) 935 { 936 if(bNew != (sal_Bool)bUseFocalLength) 937 { 938 // Zuweisen 939 bUseFocalLength = bNew; 940 941 // Neuberechnung 942 CalcNewViewportValues(); 943 } 944 } 945 946 void B3dCamera::DeviceRectangleChange() 947 { 948 // call parent 949 B3dViewport::DeviceRectangleChange(); 950 951 // Auf Aenderung reagieren 952 CalcNewViewportValues(); 953 } 954 955 void B3dCamera::CalcNewViewportValues() 956 { 957 basegfx::B3DVector aViewVector(aPosition - aLookAt); 958 basegfx::B3DVector aNewVPN(aViewVector); 959 960 basegfx::B3DVector aNewVUV(0.0, 1.0, 0.0); 961 if(aNewVPN.getLength() < aNewVPN.getY()) 962 aNewVUV.setX(0.5); 963 964 aNewVUV.normalize(); 965 aNewVPN.normalize(); 966 967 basegfx::B3DVector aNewToTheRight = aNewVPN; 968 aNewToTheRight = aNewToTheRight.getPerpendicular(aNewVUV); 969 aNewToTheRight.normalize(); 970 aNewVUV = aNewToTheRight.getPerpendicular(aNewVPN); 971 aNewVUV.normalize(); 972 973 SetViewportValues(aPosition, aNewVPN, aNewVUV); 974 if(CalcFocalLength()) 975 SetViewportValues(aCorrectedPosition, aNewVPN, aNewVUV); 976 977 if(fBankAngle != 0.0) 978 { 979 basegfx::B3DHomMatrix aRotMat; 980 aRotMat.rotate(0.0, 0.0, fBankAngle); 981 basegfx::B3DVector aUp(0.0, 1.0, 0.0); 982 aUp *= aRotMat; 983 aUp = EyeToWorldCoor(aUp); 984 aUp.normalize(); 985 SetVUV(aUp); 986 } 987 } 988 989 sal_Bool B3dCamera::CalcFocalLength() 990 { 991 double fWidth = GetDeviceRectangleWidth(); 992 sal_Bool bRetval = sal_False; 993 994 if(bUseFocalLength) 995 { 996 // Position aufgrund der FocalLength korrigieren 997 aCorrectedPosition = basegfx::B3DPoint(0.0, 0.0, fFocalLength * fWidth / 35.0); 998 aCorrectedPosition = EyeToWorldCoor(aCorrectedPosition); 999 bRetval = sal_True; 1000 } 1001 else 1002 { 1003 // FocalLength anhand der Position anpassen 1004 basegfx::B3DPoint aOldPosition; 1005 aOldPosition = WorldToEyeCoor(aOldPosition); 1006 if(fWidth != 0.0) 1007 fFocalLength = aOldPosition.getZ() / fWidth * 35.0; 1008 if(fFocalLength < 5.0) 1009 fFocalLength = 5.0; 1010 } 1011 return bRetval; 1012 } 1013 1014 // eof 1015