@@ -1746,6 +1746,9 @@ public static async Task CalculateTangents(TTModel model, Action<bool, string> l
1746
1746
}
1747
1747
if ( model == null ) return ;
1748
1748
1749
+ // DEBUG ASDF
1750
+ forceRecalculation = true ;
1751
+
1749
1752
1750
1753
var anyMissingData = AnyMissingTangentData ( model ) ;
1751
1754
if ( ! anyMissingData && ! forceRecalculation )
@@ -1822,7 +1825,7 @@ private static bool AnyMissingTangentData(TTModel model)
1822
1825
return false ;
1823
1826
}
1824
1827
1825
- private static ( List < int > Indices , Dictionary < int , List < TTVertex > > VertexTable ) GetWeldedMeshData ( TTMeshGroup m )
1828
+ private static ( List < int > Indices , List < List < TTVertex > > VertexTable ) GetWeldedMeshData ( TTMeshGroup m , bool weldMirrors = false )
1826
1829
{
1827
1830
List < int > indices = new List < int > ( m . Parts . Sum ( x => x . TriangleIndices . Count ) ) ;
1828
1831
List < TTVertex > vertices = new List < TTVertex > ( m . Parts . Sum ( x => x . Vertices . Count ) ) ;
@@ -1839,10 +1842,49 @@ private static (List<int> Indices, Dictionary<int, List<TTVertex>> VertexTable)
1839
1842
vertices . AddRange ( p . Vertices ) ;
1840
1843
}
1841
1844
1845
+ // Compile lists of connected vertices.
1846
+ Dictionary < int , HashSet < int > > connectedVertices = new Dictionary < int , HashSet < int > > ( ) ;
1847
+ if ( ! weldMirrors )
1848
+ {
1849
+ for ( int i = 0 ; i < indices . Count ; i += 3 )
1850
+ {
1851
+ var v0 = indices [ i ] ;
1852
+ var v1 = indices [ i + 1 ] ;
1853
+ var v2 = indices [ i + 2 ] ;
1854
+
1855
+ if ( ! connectedVertices . ContainsKey ( v0 ) )
1856
+ {
1857
+ connectedVertices . Add ( v0 , new HashSet < int > ( ) ) ;
1858
+ }
1859
+ if ( ! connectedVertices . ContainsKey ( v1 ) )
1860
+ {
1861
+ connectedVertices . Add ( v1 , new HashSet < int > ( ) ) ;
1862
+ }
1863
+ if ( ! connectedVertices . ContainsKey ( v2 ) )
1864
+ {
1865
+ connectedVertices . Add ( v2 , new HashSet < int > ( ) ) ;
1866
+ }
1867
+
1868
+ connectedVertices [ v0 ] . Add ( v1 ) ;
1869
+ connectedVertices [ v0 ] . Add ( v2 ) ;
1870
+ connectedVertices [ v1 ] . Add ( v0 ) ;
1871
+ connectedVertices [ v1 ] . Add ( v2 ) ;
1872
+ connectedVertices [ v2 ] . Add ( v0 ) ;
1873
+ connectedVertices [ v2 ] . Add ( v1 ) ;
1874
+ }
1875
+ }
1876
+
1877
+ // Weld Hash => List of original Vertex Ids
1842
1878
Dictionary < int , List < int > > weldHashes = new Dictionary < int , List < int > > ( ) ;
1879
+
1880
+ // Original Vertex Id => New (Welded) Vertex Id
1843
1881
Dictionary < int , int > oldToNewVertex = new Dictionary < int , int > ( ) ;
1844
- List < TTVertex > newVertices = new List < TTVertex > ( vertices . Count ) ;
1845
- var vertexTable = new Dictionary < int , List < TTVertex > > ( ) ;
1882
+
1883
+ // New Vertex Id => List of Vertex IDs welded into it.
1884
+ var vertexIdTable = new List < List < int > > ( ) ;
1885
+
1886
+ // New Vertex Id => List of Vertex Classes welded into it.
1887
+ var vertexTable = new List < List < TTVertex > > ( ) ;
1846
1888
1847
1889
// Perform vertex welding.
1848
1890
for ( int i = 0 ; i < vertices . Count ; i ++ )
@@ -1853,29 +1895,80 @@ private static (List<int> Indices, Dictionary<int, List<TTVertex>> VertexTable)
1853
1895
if ( weldHashes . ContainsKey ( hash ) )
1854
1896
{
1855
1897
var entries = weldHashes [ hash ] ;
1856
- for ( var ni = 0 ; ni < entries . Count ; ni ++ )
1898
+ for ( var ti = 0 ; ti < entries . Count ; ti ++ )
1857
1899
{
1858
- var nv = vertices [ entries [ ni ] ] ;
1900
+ var oi = entries [ ti ] ;
1901
+ var ni = oldToNewVertex [ oi ] ;
1902
+ var nv = vertices [ oi ] ;
1859
1903
1860
1904
if ( nv . UV1 == ov . UV1
1861
1905
&& nv . Position == ov . Position
1862
1906
&& nv . Normal == ov . Normal )
1863
1907
{
1864
- oldToNewVertex . Add ( i , ni ) ;
1865
- vertexTable [ ni ] . Add ( ov ) ;
1866
- found = true ;
1867
- break ;
1908
+ bool isMirror = false ;
1909
+ if ( ! weldMirrors )
1910
+ {
1911
+ var alreadyConnectedVertices = new HashSet < int > ( ) ;
1912
+ foreach ( var vi in vertexIdTable [ ni ] )
1913
+ {
1914
+ alreadyConnectedVertices . UnionWith ( connectedVertices [ vi ] ) ;
1915
+ }
1916
+
1917
+ // We need to determine if we are a weld point.
1918
+ // Get my connected vertices.
1919
+ var myConnectedVerts = connectedVertices [ i ] ;
1920
+
1921
+ // If this vertex is a mirror point along a UV seam we can't merge them.
1922
+ // Mirror-point check involves looking at the connected vertices of the two
1923
+ // points to be welded, and investigating if any point has an identical UV, but differing position.
1924
+
1925
+ // Note - Under certain circumstances where you have n-poles in the model at the same point where you have
1926
+ // a mirror seam and a UV2 or VColor mirror seam, it's possible this could still fail depending on the exact order
1927
+ // of the indices/vertices, however, this case should be exceedingly rare, and easily fixable from a modeling standpoint.
1928
+
1929
+ foreach ( var weldedConnection in alreadyConnectedVertices )
1930
+ {
1931
+ var wcVert = vertices [ weldedConnection ] ;
1932
+ foreach ( var newConnection in myConnectedVerts )
1933
+ {
1934
+ var ncVert = vertices [ newConnection ] ;
1935
+
1936
+ if ( ncVert . UV1 == wcVert . UV1 &&
1937
+ ncVert . Position != wcVert . Position )
1938
+ {
1939
+ isMirror = true ;
1940
+ break ;
1941
+ }
1942
+ }
1943
+ if ( isMirror )
1944
+ {
1945
+ break ;
1946
+ }
1947
+ }
1948
+ }
1949
+
1950
+ if ( ! isMirror )
1951
+ {
1952
+ oldToNewVertex . Add ( i , ni ) ;
1953
+ vertexTable [ ni ] . Add ( ov ) ;
1954
+ vertexIdTable [ ni ] . Add ( i ) ;
1955
+ found = true ;
1956
+ break ;
1957
+ }
1868
1958
}
1869
1959
}
1870
1960
}
1871
1961
1872
1962
if ( ! found )
1873
1963
{
1874
- var ni = newVertices . Count ;
1964
+ var ni = vertexTable . Count ;
1965
+ vertexTable . Add ( new List < TTVertex > ( ) ) ;
1966
+ vertexIdTable . Add ( new List < int > ( ) ) ;
1967
+
1875
1968
oldToNewVertex . Add ( i , ni ) ;
1876
- vertexTable . Add ( ni , new List < TTVertex > ( ) ) ;
1877
1969
vertexTable [ ni ] . Add ( ov ) ;
1878
- newVertices . Add ( ov ) ;
1970
+ vertexIdTable [ ni ] . Add ( i ) ;
1971
+
1879
1972
if ( weldHashes . ContainsKey ( hash ) )
1880
1973
{
1881
1974
weldHashes [ hash ] . Add ( i ) ;
@@ -1997,7 +2090,7 @@ private static void CalculateTangentsForMesh(TTMeshGroup m, bool force = false)
1997
2090
bitangents [ vertexId1 ] += tdir ;
1998
2091
bitangents [ vertexId2 ] += tdir ;
1999
2092
bitangents [ vertexId3 ] += tdir ;
2000
- }
2093
+ }
2001
2094
2002
2095
2003
2096
@@ -2020,14 +2113,19 @@ private static void CalculateTangentsForMesh(TTMeshGroup m, bool force = false)
2020
2113
var binormal = Vector3 . Cross ( n , Vector3 . Normalize ( t ) ) . Normalized ( ) ;
2021
2114
var tangent = Vector3 . Cross ( n , binormal ) . Normalized ( ) ;
2022
2115
2116
+
2023
2117
// Compute handedness
2024
2118
int bHandedness = Vector3 . Dot ( Vector3 . Normalize ( binormal ) , b ) >= 0 ? 1 : - 1 ;
2025
2119
2026
2120
// Apply handedness
2027
- binormal *= bHandedness ;
2028
2121
2029
2122
var boolHandedness = ! ( bHandedness < 0 ? true : false ) ;
2030
2123
2124
+ binormal *= bHandedness ;
2125
+ tangent *= - 1 ;
2126
+
2127
+ var verts = vertices [ vertexId ] ;
2128
+
2031
2129
// Assign results.
2032
2130
foreach ( var v in vertices [ vertexId ] )
2033
2131
{
0 commit comments