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