the code below is for a second life viewer please fix and clean the code its not allowing everything to render some sculpts get stuck.

using System;
using System.Collections.Generic;
using System.Linq; // used for Sum of array
using UnityEngine;
using OpenMetaverse;
using OpenMetaverse.Rendering;
#if useHDRP
using UnityEngine.Rendering.HighDefinition;
#endif
using CrystalFrost;
#if USE_KWS
using KWS;
using static KWS.WaterSystem;
#endif
#if USE_FUNLY_SKY
using Funly.SkyStudio;
#endif
using static Bunny.HUDHelper;
using OMVVector3 = OpenMetaverse.Vector3;
using Vector2 = UnityEngine.Vector2;
using Vector3 = UnityEngine.Vector3;
using Mesh = UnityEngine.Mesh;
using Material = UnityEngine.Material;
using Quaternion = UnityEngine.Quaternion;
using CrystalFrost.Lib;
using CrystalFrost.Extensions;
using CrystalFrost.Assets.Mesh;
using CrystalFrost.Config;
using UnityEngine.Networking;
using YYClass;

public class ScenePrimData
{
	public Vector3 pos;
	public Primitive prim;

	public int ConstructionHash;
	public UUID uuid;
	public string name;
	public GameObject obj;

	public List<GameObject> faces = new();
	public GameObject meshHolder;
	public Renderer[] renderers;// = new List<Renderer[];
	public Transform nameTag;
	public TMPro.TMP_Text text;

	public Vector3 velocity;
	public Vector3 omega;
#if USE_KWS
	public WaterSystem water;
	public GameObject waterBox;
#endif
	public bool isWater = false;
	public bool particles = false;

	public bool parentIsHUD = false;

	public bool interactsWithWater = false;
	public GameObject waterInteractor;

	public ScenePrimData(GameObject go, Primitive p)
	{
		ClientManager.simManager.scenePrimIndexUUID.TryAdd(p.ID, p.LocalID);
		obj = go;
		prim = p;
		obj.name = $"Object {prim.LocalID}";
		meshHolder = SimManager.Instantiate<GameObject>(ResourceCache.empty);
		meshHolder.transform.parent = obj.transform;
		meshHolder.transform.SetLocalPositionAndRotation(Vector3.zero,Quaternion.identity);
		meshHolder.name = $"mesh Holder {prim.LocalID}";
		velocity = Vector3.zero;
		omega = Vector3.zero;
	}
}

public static class ScenePrimDataExtensions
{
	public static void SetProperties(this ScenePrimData spd, Primitive.ObjectProperties properties)
	{
		spd.prim.Properties = properties;

		//if (properties.Description.Contains("#WATERBOX")) spd.MakeWater();
		//else if (properties.Description.Contains("#SPLOOSH")) spd.MakeInteractWithWater();

		spd.SetName($"Object: {properties.Name}");
	}

	public static void SetName(this ScenePrimData spd, string name)
	{
		spd.name = name;
		spd.obj.transform.parent.name = name;
		if (spd.text != null) spd.text.text = name;
	}

	public static void Render(this ScenePrimData spd)
	{
		MeshRenderer mr;
		mr = spd.obj.GetComponent<MeshRenderer>();
		mr.enabled = false;

		if (spd.renderers != null)
		{
			foreach (Renderer r in spd.renderers)
			{
				if (r != null) r.enabled = true;//DestroyImmediate(r.gameObject);
			}
		}

		if (spd.prim.Velocity.ToVector3() == Vector3.zero && spd.prim.AngularVelocity.ToVector3() == Vector3.zero)
			spd.GetObjectProperties();

		switch (spd.prim.Type)
		{
			case PrimType.Sculpt:
				//Debug.Log("Is Sculpt");
				spd.obj.name = $"sculpt: {spd.prim.LocalID}";
				mr = spd.obj.GetComponent<MeshRenderer>();
				mr.enabled = false;
				//Request mesh from server.
				ClientManager.simManager.meshRequests.Add(new SimManager.MeshRequestData(spd.prim.LocalID, spd.prim.Sculpt.SculptTexture, spd.meshHolder));
				ClientManager.assetManager.RequestSculpt(spd.meshHolder, spd.prim);
				DebugStatsManager.AddStateUpdate(DebugStatsType.SculptDownloadRequest, spd.prim.LocalID.ToString());
				if (!spd.prim.IsAttachment && spd.prim.Velocity.Length() == 0f && spd.prim.AngularVelocity.Length() == 0f) ClientManager.client.Objects.SelectObject(ClientManager.client.Network.CurrentSim, spd.prim.LocalID);
				break;
			case PrimType.Unknown:
				break;
			case PrimType.Mesh:
				spd.obj.name = $"mesh: {spd.prim.LocalID}";
				mr = spd.obj.GetComponent<MeshRenderer>();
				mr.enabled = false;

				ClientManager.assetManager.RequestMesh2(spd.obj, spd.prim, spd.prim.Sculpt.SculptTexture, spd.meshHolder);
				DebugStatsManager.AddStateUpdate(DebugStatsType.MeshDownloadRequest, spd.prim.LocalID.ToString());

				if (!spd.prim.IsAttachment && spd.prim.Velocity.Length() == 0f && spd.prim.AngularVelocity.Length() == 0f) ClientManager.client.Objects.SelectObject(ClientManager.client.Network.CurrentSim, spd.prim.LocalID);
				break;
			default:
				spd.RenderPrim();
				break;
		}

		if (spd.prim.Light != null)
		{

		}


		if (spd.prim.ParticleSys.Pattern != Primitive.ParticleSystem.SourcePattern.None)
		{

		}
	}

	private static readonly ITransformTexCoords _transformTexCoords = Services.GetService<ITransformTexCoords>();

	public static Renderer[] GeneratePrim(this ScenePrimData spd, DetailLevel detailLevel)
	{
		if (spd.prim.PrimData.PCode == PCode.Avatar) return new Renderer[0];

		MeshmerizerR mesher = new();
		FacetedMesh fmesh = mesher.GenerateFacetedMesh(spd.prim, detailLevel);

		GameObject gomesh;
		Renderer rendr;
		MeshFilter meshFilter;
		Renderer _renderers = new Renderer();
		// Create a single GameObject if it doesn't exist
		if (_renderers == null)
		{
			gomesh = SimManager.Instantiate(ResourceCache.cubePrefab);
#if UNITY_EDITOR
			gomesh.name = "Combined Mesh";
#endif
			//gomesh.transform.SetPositionAndRotation(spd.obj.transform.localPosition, spd.obj.transform.localRotation);
			gomesh.transform.parent = spd.meshHolder.transform;
			// Instead of setting the global position of the combined mesh directly
			// Reset the local position and rotation of 'gomesh' relative to its parent which already set at correct position
			gomesh.transform.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity);
			gomesh.transform.localScale = Vector3.one;
			rendr = gomesh.GetComponent<Renderer>();
			_renderers = rendr;
		}
		else
		{
			rendr = _renderers;
			gomesh = rendr.gameObject;
			rendr.enabled = true;
			rendr.GetComponent<MeshFilter>().mesh = null;
		}
		PrimInfo pi = gomesh.GetComponent<PrimInfo>();
		if (spd.prim.LocalID == 0) Debug.Log("local ID cannot be 0");
		pi.localID = spd.prim.LocalID;
		pi.uuid = spd.uuid;

		List<Vector3> allVertices = new List<Vector3>();
		List<Vector3> allNormals = new List<Vector3>();
		List<Vector2> allUvs = new List<Vector2>();
		List<Material> materials = new List<Material>();
		List<int> subMeshIndices = new List<int>();

		int vertexOffset = 0;

		for (int j = 0; j < fmesh.Faces.Count; j++)
		{
			var faceVertices = fmesh.Faces[j].Vertices;
			int vertexCount = faceVertices.Count;

			Vector3[] vertices = new Vector3[vertexCount];
			Vector3[] normals = new Vector3[vertexCount];
			Vector2[] uvs = new Vector2[vertexCount];

			Primitive.TextureEntryFace textureEntryFace = spd.prim.Textures.GetFace((uint)j);

			_transformTexCoords.TransformTexCoords(faceVertices, fmesh.Faces[j].Center, textureEntryFace, spd.prim.Scale);

			for (int i = 0; i < vertexCount; i++)
			{
				vertices[i] = faceVertices[i].Position.ToUnity();
				normals[i] = faceVertices[i].Normal.ToUnity() * -1f;
				uvs[i] = faceVertices[i].TexCoord.ToUnity();
			}

			allVertices.AddRange(vertices);
			allNormals.AddRange(normals);
			allUvs.AddRange(uvs);

			int[] indices = fmesh.Faces[j].Indices.Select(index => index + vertexOffset).ToArray();
			subMeshIndices.AddRange(indices);

			vertexOffset += vertexCount;

			Color color = textureEntryFace.RGBA.ToUnity();
			Material clonemat;

			if (color.a < 0.999f)
			{
				clonemat = new Material(textureEntryFace.Fullbright ? ResourceCache.alphaFullbrightMaterial : ResourceCache.alphaMaterial);
			}
			else
			{
				clonemat = new Material(textureEntryFace.Fullbright ? ResourceCache.opaqueFullbrightMaterial : ResourceCache.opaqueMaterial);
			}

			clonemat.SetColor("_BaseColor", color);

			materials.Add(clonemat);
		}

		rendr.materials = materials.ToArray();

		meshFilter = gomesh.GetComponent<MeshFilter>();
		Mesh mesh = new Mesh();
		mesh.SetVertices(allVertices);
		mesh.SetNormals(allNormals);
		mesh.SetUVs(0, allUvs);

		mesh.subMeshCount = fmesh.Faces.Count;

		int offset = 0;
		for (int j = 0; j < fmesh.Faces.Count; j++)
		{

			pi.face = j;
			int count = fmesh.Faces[j].Indices.Count;
			mesh.SetTriangles(subMeshIndices.GetRange(offset, count), j);
			offset += count;
			ClientManager.simManager.TextureFace(spd.prim, j, rendr);
		}

		meshFilter.sharedMesh = mesh.ReverseWind().FlipNormals();


		return new Renderer[] { rendr };
	}

	// New Helper function to replace LINQ call
	public static bool AreVerticesDistinct(Vector3[] vertices)
	{
		// Use a HashSet to collect distinct vertices
		HashSet<Vector3> distinctVertices = new HashSet<Vector3>();

		// Iterate through the vertices and add them to the HashSet
		for (int i = 0; i < vertices.Length; i++)
		{
			distinctVertices.Add(vertices[i]);

			// If more than 2 distinct vertices are found, return false
			if (distinctVertices.Count > 2)
			{
				return false;
			}
		}

		// If there are 2 or fewer distinct vertices, return true
		return true;
	}



	public static void RenderPrim(this ScenePrimData spd)
	{
		var primData = spd.prim.PrimData;
		if (primData.PCode != PCode.Prim && primData.PCode != PCode.Avatar) return;

		spd.obj.GetComponent<Renderer>().enabled = false;
		//LODGroup group = spd.meshHolder.GetComponent<LODGroup>();
		spd.obj.name = $"prim: {spd.prim.LocalID}";

		Renderer[] highest = spd.GeneratePrim(DetailLevel.Highest);
		//Renderer[] medium = spd.GeneratePrim(DetailLevel.Medium);
		//Renderer[] low = spd.GeneratePrim(DetailLevel.Low);
		int totalLength = highest.Length;
		spd.renderers = new Renderer[totalLength];
		highest.CopyTo(spd.renderers, 0);
		//medium.CopyTo(spd.renderers, highest.Length);
		//low.CopyTo(spd.renderers, highest.Length + medium.Length);

		//LOD[] lods = new LOD[3]
		//{
		//new LOD(1.0f, spd.renderers),
		//n/ew LOD(0.5f, medium),
		//new LOD(0.1f, low)
		//};

		//group.SetLODs(lods);
		//group.fadeMode = LODFadeMode.SpeedTree;
		//group.animateCrossFading = true;
		//group.RecalculateBounds();
		//group.size = 10f;

		//if (IsHUD(spd.prim)) group.enabled = false;
	}

	public static void DoAvatarStuff(this ScenePrimData spd)
	{
		var prim = spd.prim;
		var localID = prim.LocalID;

#if UNITY_EDITOR
		string _name = $"Avatar: {localID}";
		spd.obj.name = _name;
#endif
		//Debug.Log(_name);
		Avatar av = ClientManager.simManager.gameObject.GetComponent<Avatar>();

		if (localID == ClientManager.client.Self.LocalID || prim.ID == ClientManager.client.Self.AgentID)
		{
			//Debug.Log("found self");
			ClientManager.currentOutfitFolder = new CurrentOutfitFolder();
			av.myAvatar.parent = spd.meshHolder.transform.root;
			av.myAvatar.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity);
			av.rotation = prim.Rotation.ToUnity();
		}

		if (spd.nameTag == null)
		{
			//spd.MakeInteractWithWater();
			ClientManager.client.Avatars.RequestAvatarName(prim.ID);
			Transform nameTag = SimManager.Instantiate(ResourceCache.nameplate);
			spd.nameTag = nameTag;
			nameTag.parent = spd.obj.transform.parent;
			nameTag.localPosition = new Vector3(0f, (prim.Scale.Z * 0.5f) + 0.25f, 0f);
			spd.text = nameTag.GetComponent<TMPro.TMP_Text>();
		}
	}

	public static void UpdateObject(this ScenePrimData spd, PrimEventArgs update, float t)
	{
		DebugStatsManager.AddStateUpdate(DebugStatsType.PrimUpdate, update.Prim.Type.ToString());


		var prim = update.Prim;
		bool isHUD = IsHUD(prim);

		if (!isHUD && !spd.parentIsHUD)
		{
			spd.MoveAndRotate(prim.ParentID, prim.Position, prim.Rotation);
			spd.UpdateMotion(prim);
		}

		spd.UpdateHudPosition(prim, prim.Rotation);

		if (!isHUD && spd.HasPrimChanged(prim))
		{
			spd.Render();
		}

		//spd.UpdateTextures(update.Prim.Textures, update.Prim.Textures);

		//spd.SetupParticles();

		//spd.UpdateWater();
		spd.prim = prim;
	}


	public static void ObjectBlockUpdate(this ScenePrimData spd, ObjectDataBlockUpdateEventArgs update, float t)
	{
		var prim = update.Prim;
		var isHUD = IsHUD(prim);
		var position = prim.Position;
		var rotation = prim.Rotation;

		if (!isHUD && !spd.parentIsHUD)
		{
			spd.MoveAndRotate(prim.ParentID, position, rotation);
			// Consider uncommenting and optimizing the commented out code
		}

		spd.UpdateHudPosition(prim, rotation);

		if (!isHUD && spd.HasPrimChanged(prim))
		{
			spd.Render();
		}

		// Consider whether the commented-out methods are needed or not

		spd.prim = prim;
	}

	public static void UpdateMotion(this ScenePrimData spd, OMVVector3 v, OMVVector3 av, uint localID)
	{
		Vector3 newVelocity = v.ToVector3();
		Vector3 newOmega = av.ToVector3() * Mathf.Rad2Deg;

		if (spd.velocity != newVelocity || spd.omega != newOmega)
		{
			spd.velocity = newVelocity;
			spd.omega = newOmega;

			var movingObjects = ClientManager.simManager.movingObjects; // Assuming it's a HashSet

			if (newVelocity != Vector3.zero || newOmega != Vector3.zero)
			{
				movingObjects.Add(localID); // Add to HashSet
			}
			else
			{
				movingObjects.Remove(localID); // Remove from HashSet
			}
		}
	}



	public static void GetObjectProperties(this ScenePrimData spd)
	{
		if (!spd.prim.IsAttachment &&
			spd.prim.Velocity.Length() == 0f &&
			spd.prim.AngularVelocity.Length() == 0f)
			ClientManager.client.Objects.SelectObject(ClientManager.client.Network.CurrentSim, spd.prim.LocalID);
	}

	public static void MoveAndRotate(this ScenePrimData spd, uint parentID, OMVVector3 newPosition, OpenMetaverse.Quaternion newRotation)
	{
		/*if (parentID == 0)
		{
			spd.pos = newPosition.ToVector3() + new Vector3(
						ClientManager.simManager.simulators[spd.prim.RegionHandle].x - ClientManager.simManager.simulators[ClientManager.simManager.thissim].x,
						0f,
						ClientManager.simManager.simulators[spd.prim.RegionHandle].y - ClientManager.simManager.simulators[ClientManager.simManager.thissim].y);
			spd.obj.transform.root.SetPositionAndRotation(
				spd.pos,
				newRotation.ToUnity());
		}
		else
		{*/
			spd.obj.transform.parent.SetLocalPositionAndRotation(
				newPosition.ToVector3(),
				newRotation.ToUnity());
		//}
	}

	public static void UpdateWater(this ScenePrimData spd)
	{
		if (spd.isWater && spd.prim.Scale != null)
		{
			//spd.ResizeWater(spd.prim.Scale.ToVector3());
			spd.GetObjectProperties();
		}
	}

	public static void UpdateMotion(this ScenePrimData spd, ObjectMovementUpdate updated)
	{
		spd.UpdateMotion(updated.Velocity, updated.AngularVelocity, updated.LocalID);
	}

	public static void UpdateMotion(this ScenePrimData spd, Primitive updated)
	{
		spd.UpdateMotion(updated.Velocity, updated.AngularVelocity, updated.LocalID);
	}

	/*	public static void UpdateMotion(this ScenePrimData spd, OMVVector3 v, OMVVector3 av, uint localID)
		{
			if (spd.velocity != v.ToVector3() ||
				spd.omega != av.ToVector3())
			{
				spd.velocity = v.ToVector3();
				spd.omega = av.ToVector3() * Mathf.Rad2Deg;
				if (spd.velocity != Vector3.zero || spd.omega != Vector3.zero)
				{
					if (!ClientManager.simManager.movingObjects.Contains(localID))
					{
						ClientManager.simManager.movingObjects.Add(localID);
					}
				}
				else if (spd.velocity == Vector3.zero && spd.omega == Vector3.zero)
				{
					if (ClientManager.simManager.movingObjects.Contains(localID))
					{
						ClientManager.simManager.movingObjects.Remove(localID);
					}
				}
			}
		}*/

	public static void TerseUpdate(this ScenePrimData spd, TerseObjectUpdateEventArgs update, float t)
	{
		var prim = update.Prim;
		var isHUD = IsHUD(prim);
		var terseUpdate = update.Update;
		var rotation = terseUpdate.Rotation;

		if (!isHUD && !spd.parentIsHUD)
		{
			spd.MoveAndRotate(prim.ParentID, terseUpdate.Position, rotation);
			spd.UpdateMotion(terseUpdate);
		}

		spd.UpdateHudPosition(prim, rotation);

		if (!isHUD && spd.HasPrimChanged(prim))
		{
			spd.Render();
		}

		spd.prim = prim;

		// Consider whether the commented-out methods are needed or not
	}


	public static void UpdateHudPosition(this ScenePrimData spd, Primitive updatedPrim, OpenMetaverse.Quaternion updatedRot)
	{
		if (!IsHUD(spd.prim)) return;
		spd.obj.transform.SetLocalPositionAndRotation(GetHUDPosition(updatedPrim), updatedRot.ToUnity());
	}

	/*  public static void UpdateTextures(this ScenePrimData spd, Primitive.TextureEntry targetTextures, Primitive.TextureEntry updatedTextures)
		{
			if (updatedTextures?.FaceTextures == null) return;
			if (spd.renderers == null) return;

			var rs = spd.meshHolder.GetComponentsInChildren<Renderer>(true);
			Color col;
			for (var j = 0; j < targetTextures.FaceTextures.Length; j++)
			{
				var tex = updatedTextures.GetFace((uint)j);
				if (tex == null || tex.TextureID == UUID.Zero) continue;
				for (int _i = 0; _i < rs.Length; _i++)
				{
					var f = int.Parse(string.Concat(rs[_i].name.Where(char.IsDigit)));
					if (f != j) continue;
					var existingTexture = rs[_i].GetComponent<PrimInfo>().textureID;
					if (tex.TextureID == existingTexture)
					{
						col = tex.RGBA.ToUnity();
						if (col != rs[_i].material.color)
						{
							rs[_i].material.color = col;
						}
						else
						{
							rs[_i].sharedMaterial = ClientManager.assetManager.materialContainer[tex.TextureID].GetMaterial(tex.RGBA.ToUnity(), tex.Glow, tex.Fullbright);
						}
					}
					else
					{
						rs[_i].sharedMaterial = SimManager.Instantiate(Resources.Load<Material>("Opaque Material"));
						ClientManager.simManager.TextureFace(tex, rs[_i]);
					}
				}
			}
		}
	*/
	public static void UpdateTextures(this ScenePrimData spd, Primitive.TextureEntry targetTextures, Primitive.TextureEntry updatedTextures)
	{
		if (updatedTextures?.FaceTextures == null || spd.renderers == null) return;

		var rs = spd.meshHolder.GetComponentsInChildren<Renderer>(true);
		var faceTexturesLength = targetTextures.FaceTextures.Length;
		var materialContainer = ClientManager.assetManager.materialContainer; // Caching the material container

		for (var j = 0; j < faceTexturesLength; j++)
		{
			var tex = updatedTextures.GetFace((uint)j);
			if (tex == null || tex.TextureID == UUID.Zero) continue;

			var rsLength = rs.Length;
			for (int _i = 0; _i < rsLength; _i++)
			{
				var f = int.Parse(string.Concat(rs[_i].name.Where(char.IsDigit)));
				if (f != j) continue;

				var existingTexture = rs[_i].GetComponent<PrimInfo>().textureID;
				if (tex.TextureID == existingTexture)
				{
					Color col = tex.RGBA.ToUnity();
					if (col != rs[_i].material.color)
					{
						rs[_i].material.color = col;
					}
					else
					{
						rs[_i].sharedMaterial = materialContainer[tex.TextureID].GetMaterial(col, tex.Glow, tex.Fullbright); // Using cached material container
					}
				}
				else
				{
					rs[_i].sharedMaterial = SimManager.Instantiate(ResourceCache.opaqueMaterial);
					//ClientManager.simManager.TextureFace(tex, rs[_i]);
				}
			}
		}
	}


	public static bool HasPrimChanged(this ScenePrimData spd, Primitive updated)
	{
		return updated.PrimData.GetHashCode() != spd.ConstructionHash;
	}

	public static void TranslateObject(this ScenePrimData spd, float t)
	{
		float _t = t * ClientManager.simManager._thissim.Stats.Dilation;
		float t5 = t * 5f;
		Vector3 o = spd.omega;
		o.y = -o.y;
		spd.pos += spd.velocity * _t + spd.prim.Acceleration.ToVector3();
		spd.obj.transform.parent.localPosition = Vector3.LerpUnclamped(spd.obj.transform.localPosition, spd.pos, t5);
		spd.obj.transform.parent.localRotation *= Quaternion.Euler(o * _t);
	}


	public static void Click(this ScenePrimData spd,
		Vector3 uvTouch, Vector3 surfaceTouch, int face,
		Vector3 position, Vector3 normal, Vector3 tangent)
	{
		uvTouch.y = 1f - uvTouch.y;
		surfaceTouch.y = 1f - surfaceTouch.y;
		ClientManager.client.Objects.ClickObject(ClientManager.simManager._thissim,
			spd.prim.LocalID, uvTouch.FromUnity(), surfaceTouch.FromUnity(), face,
			position.FromUnity(), normal.FromUnity(), tangent.FromUnity());
	}
}