@ -1,4 +1,5 @@
using System.Collections.Generic ;
using System ;
using System.Collections.Generic ;
using UnityEngine ;
using UnityEngine.Rendering ;
@ -38,7 +39,7 @@ public class BrushModel
var headNode = subModels [ modelIdx ] . GetHeadNode ( model ) ;
var surfaceGroups = new Dictionary < ( string , int ) , List < QSurface > > ( ) ;
var surfaceGroups = new Dictionary < ( IntPtr , int ) , List < QSurface > > ( ) ;
GroupSurfaces ( headNode , surfaces , surfaceGroups ) ;
foreach ( var group in surfaceGroups )
@ -51,8 +52,18 @@ public class BrushModel
}
}
}
public void Dispose ( )
{
foreach ( var mesh in meshes )
{
UnityEngine . Object . Destroy ( mesh ) ;
}
meshes . Clear ( ) ;
}
private void GroupSurfaces ( QNode node , QSurface [ ] surfaces , Dictionary < ( string , int ) , List < QSurface > > surfaceGroups )
private void GroupSurfaces ( QNode node , QSurface [ ] surfaces , Dictionary < ( IntPtr , int ) , List < QSurface > > surfaceGroups )
{
if ( node . contents < 0 ) // Leaf node
return ;
@ -61,9 +72,9 @@ public class BrushModel
{
var surface = surfaces [ node . firstSurface + surfIdx ] ;
string texName = surface . TextureInfo . Texture . nam e;
IntPtr texPtr = surface . TextureInfo . textur e;
int lightNum = surface . lightmapTextureNum ;
var key = ( texName , lightNum ) ;
var key = ( texPtr , lightNum ) ;
if ( ! surfaceGroups . ContainsKey ( key ) )
surfaceGroups [ key ] = new List < QSurface > ( ) ;
@ -77,64 +88,6 @@ public class BrushModel
}
}
private void CreateNodeMeshes ( QNode node , QSurface [ ] surfaces , GameObject parentGO )
{
if ( node . contents < 0 ) // Leaf node
return ;
var nodeGO = new GameObject ( "Node" ) ;
nodeGO . transform . SetParent ( parentGO . transform ) ;
for ( int surfIdx = 0 ; surfIdx < node . numSurfaces ; + + surfIdx )
{
var surface = surfaces [ node . firstSurface + surfIdx ] ;
CreateSurfaceMeshes ( surface , $"{node.firstSurface + surfIdx}" , nodeGO ) ;
}
foreach ( var childNode in node . Children )
{
CreateNodeMeshes ( childNode , surfaces , nodeGO ) ;
}
}
private void CreateSurfaceMeshes ( QSurface surface , string key , GameObject nodeGO )
{
foreach ( var polyVerts in surface . GetPolygons ( ) )
{
tempVertices . Clear ( ) ;
tempTextureUVs . Clear ( ) ;
tempLightmapUVs . Clear ( ) ;
tempIndices . Clear ( ) ;
for ( int vertIdx = 0 ; vertIdx < polyVerts . Length ; + + vertIdx )
{
tempVertices . Add ( polyVerts [ vertIdx ] . position . ToVector3 ( ) . ToUnity ( ) ) ;
tempTextureUVs . Add ( polyVerts [ vertIdx ] . textureUV . ToVector2 ( ) ) ;
tempLightmapUVs . Add ( polyVerts [ vertIdx ] . lightmapUV . ToVector2 ( ) ) ;
}
// Reconstruct triangle fan
for ( ushort index = 2 ; index < polyVerts . Length ; + + index )
{
tempIndices . Add ( 0 ) ;
tempIndices . Add ( ( ushort ) ( index - 1 ) ) ;
tempIndices . Add ( index ) ;
}
Mesh mesh = new Mesh ( ) ;
mesh . name = $"Surface_{key}" ;
mesh . SetVertices ( tempVertices ) ;
mesh . SetUVs ( 0 , tempTextureUVs ) ;
mesh . SetUVs ( 1 , tempLightmapUVs ) ;
mesh . SetIndices ( tempIndices , MeshTopology . Triangles , 0 ) ;
mesh . RecalculateNormals ( ) ;
mesh . UploadMeshData ( true ) ;
meshes . Add ( mesh ) ;
CreateMeshObject ( mesh , nodeGO ) ;
}
}
private void CreateMeshFromSurfaces ( List < QSurface > surfaces , string key , GameObject parentGO )
{
tempVertices . Clear ( ) ;
@ -182,13 +135,10 @@ public class BrushModel
private void CreateMeshObject ( Mesh mesh , GameObject parentGO )
{
var meshGO = new GameObject ( mesh . name ) ;
meshGO . transform . SetParent ( parentGO . transform ) ;
var mf = meshGO . AddComponent < MeshFilter > ( ) ;
var mf = parentGO . AddComponent < MeshFilter > ( ) ;
mf . sharedMesh = mesh ;
var mr = mesh GO. AddComponent < MeshRenderer > ( ) ;
var mr = parentGO . AddComponent < MeshRenderer > ( ) ;
mr . sharedMaterial = debugMaterial ;
mr . shadowCastingMode = ShadowCastingMode . Off ;
mr . receiveShadows = false ;