| 804 | } |
| 805 | |
| 806 | void Patch::scaleTextureNaturally() |
| 807 | { |
| 808 | // Save the undo memento |
| 809 | undoSave(); |
| 810 | |
| 811 | // Retrieve the default scale from the registry |
| 812 | auto defaultScale = registry::getValue<float>("user/ui/textures/defaultTextureScale"); |
| 813 | |
| 814 | // Cycles through all the patch columns and assigns s/t coordinates. |
| 815 | // During each column or row cycle, the highest world distance between columns or rows |
| 816 | // determines the distance in UV space (longest distance is taken). |
| 817 | // World distances are scaled to UV space with the actual texture width/height, |
| 818 | // scaled by the value in the registry. |
| 819 | |
| 820 | auto horizScale = 1.0f / (static_cast<float>(_shader.getWidth()) * defaultScale); |
| 821 | |
| 822 | double texcoordX = 0; |
| 823 | |
| 824 | // Cycle through the patch width, |
| 825 | for (std::size_t w = 0; w < _width; w++) |
| 826 | { |
| 827 | // Apply the currently active <tex> value to the control point texture coordinates. |
| 828 | for (std::size_t h = 0; h < _height; h++) |
| 829 | { |
| 830 | // Set the x-coord (or better s-coord?) of the texture to tex. |
| 831 | // For the first width cycle this is tex=0, so the texture is not shifted at the first vertex |
| 832 | ctrlAt(h, w).texcoord[0] = texcoordX; |
| 833 | } |
| 834 | |
| 835 | // If we reached the last row (_width - 1) we are finished (all coordinates are applied) |
| 836 | if (w + 1 == _width) break; |
| 837 | |
| 838 | // Determine the texcoord of the next column |
| 839 | double highestNextTexCoord = 0; |
| 840 | |
| 841 | // Determine the longest distance to the next column. |
| 842 | // Again, cycle through the current column |
| 843 | for (std::size_t h = 0; h < _height; h++) |
| 844 | { |
| 845 | // v is the vector pointing from one control point to the next neighbour |
| 846 | auto worldDistance = ctrlAt(h, w).vertex - ctrlAt(h, w + 1).vertex; |
| 847 | |
| 848 | // Scale the distance in world coordinates into texture coords |
| 849 | double nextTexcoordX = texcoordX + worldDistance.getLength() * horizScale; |
| 850 | |
| 851 | // Use the farthest extrapolated texture cooord |
| 852 | highestNextTexCoord = std::max(highestNextTexCoord, nextTexcoordX); |
| 853 | } |
| 854 | |
| 855 | // Remember the highest found texcoord, assign it to the next column |
| 856 | texcoordX = highestNextTexCoord; |
| 857 | } |
| 858 | |
| 859 | // Now the same goes for the texture height, cycle through all the rows |
| 860 | // and calculate the longest distances, convert them to texture coordinates |
| 861 | // and apply them to the according texture coordinates. |
| 862 | auto vertScale = 1.0f / (static_cast<float>(_shader.getHeight()) * defaultScale); |
| 863 |
no test coverage detected