| 624 | } |
| 625 | |
| 626 | S32 TSShapeInstance::setDetailFromDistance( const SceneRenderState *state, F32 scaledDistance ) |
| 627 | { |
| 628 | PROFILE_SCOPE( TSShapeInstance_setDetailFromDistance ); |
| 629 | |
| 630 | // For debugging/metrics. |
| 631 | smLastScaledDistance = scaledDistance; |
| 632 | |
| 633 | // Shortcut if the distance is really close or negative. |
| 634 | if ( scaledDistance <= 0.0f ) |
| 635 | { |
| 636 | mShape->mDetailLevelLookup[0].get( mCurrentDetailLevel, mCurrentIntraDetailLevel ); |
| 637 | return mCurrentDetailLevel; |
| 638 | } |
| 639 | |
| 640 | // The pixel scale is used the linearly scale the lod |
| 641 | // selection based on the viewport size. |
| 642 | // |
| 643 | // The original calculation from TGEA was... |
| 644 | // |
| 645 | // pixelScale = viewport.extent.x * 1.6f / 640.0f; |
| 646 | // |
| 647 | // Since we now work on the viewport height, assuming |
| 648 | // 4:3 aspect ratio, we've changed the reference value |
| 649 | // to 300 to be more compatible with legacy shapes. |
| 650 | // |
| 651 | const F32 pixelScale = (state->getViewport().extent.x / state->getViewport().extent.y)*2; |
| 652 | |
| 653 | // This is legacy DTS support for older "multires" based |
| 654 | // meshes. The original crossbow weapon uses this. |
| 655 | // |
| 656 | // If we have more than one detail level and the maxError |
| 657 | // is non-negative then we do some sort of screen error |
| 658 | // metric for detail selection. |
| 659 | // |
| 660 | if ( mShape->mUseDetailFromScreenError ) |
| 661 | { |
| 662 | // The pixel size of 1 meter at the input distance. |
| 663 | F32 pixelRadius = state->projectRadius( scaledDistance, 1.0f ) * pixelScale; |
| 664 | static const F32 smScreenError = 5.0f; |
| 665 | return setDetailFromScreenError( smScreenError / pixelRadius ); |
| 666 | } |
| 667 | |
| 668 | // We're inlining SceneRenderState::projectRadius here to |
| 669 | // skip the unnessasary divide by zero protection. |
| 670 | F32 pixelRadius = ( mShape->mRadius / scaledDistance ) * state->getWorldToScreenScale().y * pixelScale; |
| 671 | F32 pixelSize = pixelRadius * smDetailAdjust; |
| 672 | |
| 673 | if ( pixelSize < smSmallestVisiblePixelSize ) { |
| 674 | mCurrentDetailLevel = -1; |
| 675 | return mCurrentDetailLevel; |
| 676 | } |
| 677 | |
| 678 | if ( pixelSize > smSmallestVisiblePixelSize && |
| 679 | pixelSize <= mShape->mSmallestVisibleSize ) |
| 680 | pixelSize = mShape->mSmallestVisibleSize + 0.01f; |
| 681 | |
| 682 | // For debugging/metrics. |
| 683 | smLastPixelSize = pixelSize; |
no test coverage detected