From 0289011442e0c4ed3974c903d7c8738a8ccd6889 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sun, 23 Oct 2022 21:10:36 +0100 Subject: [PATCH] cosmetics on ubder meshing --- .../PhysicsModules/SharedBase/PhysicsActor.cs | 13 +- .../ubOdeMeshing/Meshmerizer.cs | 724 +++++++++--------- .../PhysicsModules/ubOdeMeshing/PrimMesher.cs | 291 ++++--- 3 files changed, 484 insertions(+), 544 deletions(-) diff --git a/OpenSim/Region/PhysicsModules/SharedBase/PhysicsActor.cs b/OpenSim/Region/PhysicsModules/SharedBase/PhysicsActor.cs index 9dc372fe72..f5aa958a4e 100644 --- a/OpenSim/Region/PhysicsModules/SharedBase/PhysicsActor.cs +++ b/OpenSim/Region/PhysicsModules/SharedBase/PhysicsActor.cs @@ -632,16 +632,11 @@ namespace OpenSim.Region.PhysicsModules.SharedBase get { return (int)m_actorType; } set { ActorTypes type = (ActorTypes)value; - switch (type) + m_actorType = type switch { - case ActorTypes.Ground: - case ActorTypes.Water: - m_actorType = type; - break; - default: - m_actorType = ActorTypes.Unknown; - break; - } + ActorTypes.Ground or ActorTypes.Water => type, + _ => ActorTypes.Unknown, + }; } } diff --git a/OpenSim/Region/PhysicsModules/ubOdeMeshing/Meshmerizer.cs b/OpenSim/Region/PhysicsModules/ubOdeMeshing/Meshmerizer.cs index 4c9a2cb853..4210528fb7 100644 --- a/OpenSim/Region/PhysicsModules/ubOdeMeshing/Meshmerizer.cs +++ b/OpenSim/Region/PhysicsModules/ubOdeMeshing/Meshmerizer.cs @@ -56,11 +56,11 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing // Setting baseDir to a path will enable the dumping of raw files // raw files can be imported by blender so a visual inspection of the results can be done - const float floatPI = (float)Math.PI; - private static string cacheControlFilename = "cntr"; + const float floatPI = MathF.PI; + private readonly static string cacheControlFilename = "cntr"; private bool m_Enabled = false; - public static object diskLock = new object(); + public static object diskLock = new(); public bool doMeshFileCache = true; public bool doCacheExpire = true; @@ -74,8 +74,8 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing private bool doConvexPrims = true; private bool doConvexSculpts = true; - private Dictionary m_uniqueMeshes = new Dictionary(); - private Dictionary m_uniqueReleasedMeshes = new Dictionary(); + private readonly Dictionary m_uniqueMeshes = new(); + private readonly Dictionary m_uniqueReleasedMeshes = new (); #region INonSharedRegionModule public string Name @@ -196,7 +196,7 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing { posRange = ((OSDMap)tmp)["Max"].AsVector3(); posMin = ((OSDMap)tmp)["Min"].AsVector3(); - posRange = posRange - posMin; + posRange -= posMin; posRange *= invMaxU16; } else @@ -240,7 +240,7 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing ptr += 2; int v3 = Utils.BytesToUInt16(ptr) + faceIndexOffset; ptr += 2; - Face f = new Face(v1, v2, v3); + Face f = new (v1, v2, v3); faces.Add(f); } } @@ -323,14 +323,11 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing if(needsConvexProcessing) { - List convexcoords; - List convexfaces; - if(CreateBoundingHull(coords, out convexcoords, out convexfaces) && convexcoords != null && convexfaces != null) + if(CreateBoundingHull(coords, out List convexcoords, out List convexfaces) && convexcoords != null && convexfaces != null) { coords.Clear(); coords = convexcoords; - numCoords = coords.Count; - + faces.Clear(); faces = convexfaces; numFaces = faces.Count; @@ -339,7 +336,7 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing m_log.ErrorFormat("[ubMESH]: failed to create convex for {0} using normal mesh", primName); } - Mesh mesh = new Mesh(true); + Mesh mesh = new(true); // Add the corresponding triangles to the mesh for (int i = 0; i < numFaces; i++) { @@ -385,200 +382,168 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing coords = new List(); faces = new List(); - OSD meshOsd = null; if (primShape.SculptData == null || primShape.SculptData.Length <= 0) { // m_log.InfoFormat("[MESH]: asset data for {0} is zero length", primName); return false; } - + OSD osd; long start = 0; - using (MemoryStream data = new MemoryStream(primShape.SculptData)) + using (MemoryStream data = new(primShape.SculptData)) { try { - OSD osd = OSDParser.DeserializeLLSDBinary(data); - if (osd is OSDMap) - meshOsd = (OSDMap)osd; - else - { - m_log.WarnFormat("[Mesh}: unable to cast mesh asset to OSDMap prim: {0} asset {1}",primName, primShape.SculptTexture); - return false; - } + osd = OSDParser.DeserializeLLSDBinary(data); } catch (Exception e) { - m_log.ErrorFormat("[MESH]: Error deserializing mesh asset header: {0} in Prim '{1}' asset {2}", e.Message, primName, primShape.SculptTexture); + m_log.Error($"[MESH]: Error deserializing mesh asset header: {e.Message} in Prim '{primName}' asset {primShape.SculptTexture}"); return false; } start = data.Position; } - if (meshOsd is OSDMap) + if (osd is not OSDMap map) { - OSDMap physicsParms = null; - OSDMap map = (OSDMap)meshOsd; + m_log.Warn($"[Mesh]: unable to cast mesh asset to OSDMap prim: {primName} asset {primShape.SculptTexture}"); + return false; + } - if (!convex) + OSDMap physicsParms = null; + + if (!convex) + { + if (map.TryGetValue("physics_shape", out OSD pso)) + physicsParms = (OSDMap)pso; // old asset format + else if (map.TryGetValue("physics_mesh", out OSD pm)) + physicsParms = (OSDMap)pm; // new asset format + + if (physicsParms != null) + usemesh = true; + } + + if(!usemesh && map.TryGetValue("physics_convex",out OSD pc)) + physicsParms = (OSDMap)pc; + + if (physicsParms == null) + { + //m_log.WarnFormat("[MESH]: unknown mesh type for prim {0}",primName); + return false; + } + + int physOffset = physicsParms["offset"].AsInteger() + (int)start; + int physSize = physicsParms["size"].AsInteger(); + + if (physOffset < 0 || physSize == 0) + return false; // no mesh data in asset + + OSD decodedMeshOsd = new(); + try + { + using (MemoryStream outMs = new(4 * physSize)) { - if (map.ContainsKey("physics_shape")) - physicsParms = (OSDMap)map["physics_shape"]; // old asset format - else if (map.ContainsKey("physics_mesh")) - physicsParms = (OSDMap)map["physics_mesh"]; // new asset format - - if (physicsParms != null) - usemesh = true; - } - - if(!usemesh && (map.ContainsKey("physics_convex"))) - physicsParms = (OSDMap)map["physics_convex"]; - - if (physicsParms == null) - { - //m_log.WarnFormat("[MESH]: unknown mesh type for prim {0}",primName); - return false; - } - - int physOffset = physicsParms["offset"].AsInteger() + (int)start; - int physSize = physicsParms["size"].AsInteger(); - - if (physOffset < 0 || physSize == 0) - return false; // no mesh data in asset - - OSD decodedMeshOsd = new OSD(); - try - { - using (MemoryStream outMs = new MemoryStream(4 * physSize)) + using (MemoryStream inMs = new(primShape.SculptData, physOffset, physSize)) { - using (MemoryStream inMs = new MemoryStream(primShape.SculptData, physOffset, physSize)) + using (DeflateStream decompressionStream = new(inMs, CompressionMode.Decompress)) { - using (DeflateStream decompressionStream = new DeflateStream(inMs, CompressionMode.Decompress)) - { - byte[] readBuffer = new byte[8192]; - inMs.Read(readBuffer, 0, 2); // skip first 2 bytes in header - int readLen = 0; + byte[] readBuffer = new byte[8192]; + inMs.Read(readBuffer, 0, 2); // skip first 2 bytes in header + int readLen = 0; - while ((readLen = decompressionStream.Read(readBuffer, 0, readBuffer.Length)) > 0) - outMs.Write(readBuffer, 0, readLen); - } - } - outMs.Seek(0, SeekOrigin.Begin); - decodedMeshOsd = OSDParser.DeserializeLLSDBinary(outMs); - } - } - catch (Exception e) - { - m_log.Error("[MESH]: exception decoding physical mesh prim " + primName +" : " + e.ToString()); - return false; - } - - if (usemesh) - { - OSDArray decodedMeshOsdArray = null; - - // physics_shape is an array of OSDMaps, one for each submesh - if (decodedMeshOsd is OSDArray) - { -// Console.WriteLine("decodedMeshOsd for {0} - {1}", primName, Util.GetFormattedXml(decodedMeshOsd)); - - decodedMeshOsdArray = (OSDArray)decodedMeshOsd; - foreach (OSD subMeshOsd in decodedMeshOsdArray) - { - if (subMeshOsd is OSDMap) - AddSubMesh(subMeshOsd as OSDMap, coords, faces); + while ((readLen = decompressionStream.Read(readBuffer, 0, readBuffer.Length)) > 0) + outMs.Write(readBuffer, 0, readLen); } } + outMs.Seek(0, SeekOrigin.Begin); + decodedMeshOsd = OSDParser.DeserializeLLSDBinary(outMs); } + } + catch (Exception e) + { + m_log.Error("[MESH]: exception decoding physical mesh prim " + primName +" : " + e.ToString()); + return false; + } + + if (usemesh) + { + // physics_shape is an array of OSDMaps, one for each submesh + if (decodedMeshOsd is OSDArray decodedMeshOsdArray) + { + //Console.WriteLine("decodedMeshOsd for {0} - {1}", primName, Util.GetFormattedXml(decodedMeshOsd)); + foreach (OSD subMeshOsd in decodedMeshOsdArray) + { + if (subMeshOsd is OSDMap subm) + AddSubMesh(subm, coords, faces); + } + } + return true; + } + else if(decodedMeshOsd is OSDMap cmap) + { + byte[] data; + + List vs = new(); + PHullResult hullr = new(); + float3 f3; + Vector3 range; + Vector3 min; + + const float invMaxU16 = 1.0f / 65535f; + int t1; + int t2; + int t3; + int i; + int nverts; + int nindexs; + + if (cmap.ContainsKey("Max")) + range = cmap["Max"].AsVector3(); else + range = new Vector3(0.5f, 0.5f, 0.5f); + + if (cmap.ContainsKey("Min")) + min = cmap["Min"].AsVector3(); + else + min = new Vector3(-0.5f, -0.5f, -0.5f); + + range -= min; + range *= invMaxU16; + + if(!convex) { - OSDMap cmap = (OSDMap)decodedMeshOsd; - if (cmap == null) - return false; - - byte[] data; - - List vs = new List(); - PHullResult hullr = new PHullResult(); - float3 f3; - Vector3 range; - Vector3 min; - - const float invMaxU16 = 1.0f / 65535f; - int t1; - int t2; - int t3; - int i; - int nverts; - int nindexs; - - if (cmap.ContainsKey("Max")) - range = cmap["Max"].AsVector3(); - else - range = new Vector3(0.5f, 0.5f, 0.5f); - - if (cmap.ContainsKey("Min")) - min = cmap["Min"].AsVector3(); - else - min = new Vector3(-0.5f, -0.5f, -0.5f); - - range = range - min; - range *= invMaxU16; - - if(!convex) + // if mesh data not present and not convex then we need convex decomposition data + if (cmap.ContainsKey("HullList") && cmap.ContainsKey("Positions")) { - // if mesh data not present and not convex then we need convex decomposition data - if (cmap.ContainsKey("HullList") && cmap.ContainsKey("Positions")) + List hsizes = new(); + int totalpoints = 0; + data = cmap["HullList"].AsBinary(); + for (i = 0; i < data.Length; i++) { - List hsizes = new List(); - int totalpoints = 0; - data = cmap["HullList"].AsBinary(); - for (i = 0; i < data.Length; i++) + t1 = data[i]; + if (t1 == 0) + t1 = 256; + totalpoints += t1; + hsizes.Add(t1); + } + + data = cmap["Positions"].AsBinary(); + fixed(byte* ptrstart = data) + { + byte* ptr = ptrstart; + + int vertsoffset = 0; + + if (totalpoints == data.Length / 6) // 2 bytes per coord, 3 coords per point { - t1 = data[i]; - if (t1 == 0) - t1 = 256; - totalpoints += t1; - hsizes.Add(t1); - } - - data = cmap["Positions"].AsBinary(); - fixed(byte* ptrstart = data) - { - byte* ptr = ptrstart; - - int vertsoffset = 0; - - if (totalpoints == data.Length / 6) // 2 bytes per coord, 3 coords per point + foreach (int hullsize in hsizes) { - foreach (int hullsize in hsizes) + if (hullsize < 4) { - if (hullsize < 4) + if (hullsize < 3) { - if (hullsize < 3) - { - ptr += 6 * hullsize; - continue; - } - - for (i = 0; i < hullsize; i++) - { - t1 = Utils.BytesToUInt16(ptr); ptr += 2; - t2 = Utils.BytesToUInt16(ptr); ptr += 2; - t3 = Utils.BytesToUInt16(ptr); ptr += 2; - - coords.Add(new Coord( - t1 * range.X + min.X, - t2 * range.Y + min.Y, - t3 * range.Z + min.Z) - ); - - } - - faces.Add(new Face(vertsoffset, vertsoffset + 1, vertsoffset + 2)); - - vertsoffset += hullsize; + ptr += 6 * hullsize; continue; } @@ -588,134 +553,149 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing t2 = Utils.BytesToUInt16(ptr); ptr += 2; t3 = Utils.BytesToUInt16(ptr); ptr += 2; - f3 = new float3(t1 * range.X + min.X, + coords.Add(new Coord( + t1 * range.X + min.X, t2 * range.Y + min.Y, - t3 * range.Z + min.Z); - vs.Add(f3); + t3 * range.Z + min.Z) + ); + } - List indices; - if (!HullUtils.ComputeHull(vs, out indices)) - { - vs.Clear(); - continue; - } + faces.Add(new Face(vertsoffset, vertsoffset + 1, vertsoffset + 2)); - nverts = vs.Count; - nindexs = indices.Count; - - if (nindexs % 3 != 0) - { - vs.Clear(); - continue; - } - - for (i = 0; i < vs.Count; i++) - coords.Add(new Coord(vs[i].x, vs[i].y, vs[i].z)); - - for (i = 0; i < indices.Count; i += 3) - { - t1 = indices[i]; - if (t1 > nverts) - break; - t2 = indices[i + 1]; - if (t2 > nverts) - break; - t3 = indices[i + 2]; - if (t3 > nverts) - break; - faces.Add(new Face(vertsoffset + t1, vertsoffset + t2, vertsoffset + t3)); - } - vertsoffset += nverts; - vs.Clear(); + vertsoffset += hullsize; + continue; } + + for (i = 0; i < hullsize; i++) + { + t1 = Utils.BytesToUInt16(ptr); ptr += 2; + t2 = Utils.BytesToUInt16(ptr); ptr += 2; + t3 = Utils.BytesToUInt16(ptr); ptr += 2; + + f3 = new float3(t1 * range.X + min.X, + t2 * range.Y + min.Y, + t3 * range.Z + min.Z); + vs.Add(f3); + } + + if (!HullUtils.ComputeHull(vs, out List indices)) + { + vs.Clear(); + continue; + } + + nverts = vs.Count; + nindexs = indices.Count; + + if (nindexs % 3 != 0) + { + vs.Clear(); + continue; + } + + for (i = 0; i < vs.Count; i++) + coords.Add(new Coord(vs[i].x, vs[i].y, vs[i].z)); + + for (i = 0; i < indices.Count; i += 3) + { + t1 = indices[i]; + if (t1 > nverts) + break; + t2 = indices[i + 1]; + if (t2 > nverts) + break; + t3 = indices[i + 2]; + if (t3 > nverts) + break; + faces.Add(new Face(vertsoffset + t1, vertsoffset + t2, vertsoffset + t3)); + } + vertsoffset += nverts; + vs.Clear(); } } - if (coords.Count > 0 && faces.Count > 0) - return true; } - else - { - // if neither mesh or decomposition present, warn and use convex - //m_log.WarnFormat("[MESH]: Data for PRIM shape type ( mesh or decomposition) not found for prim {0}",primName); - } - } - vs.Clear(); - - if (cmap.TryGetValue("BoundingVerts", out OSD odata)) - { - data = odata.AsBinary(); - if (data.Length < 3 * 6) - { - vs.Clear(); - return false; - } - - fixed (byte* ptrstart = data) - { - byte* end = ptrstart + data.Length; - byte* ptr = ptrstart; - while(ptr < end) - { - t1 = Utils.BytesToUInt16(ptr); ptr += 2; - t2 = Utils.BytesToUInt16(ptr); ptr += 2; - t3 = Utils.BytesToUInt16(ptr); ptr += 2; - - f3 = new float3((t1 * range.X + min.X), - (t2 * range.Y + min.Y), - (t3 * range.Z + min.Z)); - vs.Add(f3); - } - } - - nverts = vs.Count; - - if (nverts < 4) - { - for (i = 0; i < vs.Count; i++) - coords.Add(new Coord(vs[i].x, vs[i].y, vs[i].z)); - - faces.Add(new Face(0, 1, 2)); - - vs.Clear(); - return true; - } - - List indices; - if (!HullUtils.ComputeHull(vs, out indices)) - return false; - - nindexs = indices.Count; - - if (nindexs % 3 != 0) - return false; - - for (i = 0; i < vs.Count; i++) - coords.Add(new Coord(vs[i].x, vs[i].y, vs[i].z)); - - for (i = 0; i < indices.Count; i += 3) - { - t1 = indices[i]; - if (t1 > nverts) - break; - t2 = indices[i + 1]; - if (t2 > nverts) - break; - t3 = indices[i + 2]; - if (t3 > nverts) - break; - - faces.Add(new Face(t1, t2, t3)); - } - vs.Clear(); if (coords.Count > 0 && faces.Count > 0) return true; } - return false; + else + { + // if neither mesh or decomposition present, warn and use convex + //m_log.WarnFormat("[MESH]: Data for PRIM shape type ( mesh or decomposition) not found for prim {0}",primName); + } + } + vs.Clear(); + + if (cmap.TryGetValue("BoundingVerts", out OSD odata)) + { + data = odata.AsBinary(); + if (data.Length < 3 * 6) + { + vs.Clear(); + return false; + } + + fixed (byte* ptrstart = data) + { + byte* end = ptrstart + data.Length; + byte* ptr = ptrstart; + while(ptr < end) + { + t1 = Utils.BytesToUInt16(ptr); ptr += 2; + t2 = Utils.BytesToUInt16(ptr); ptr += 2; + t3 = Utils.BytesToUInt16(ptr); ptr += 2; + + f3 = new float3((t1 * range.X + min.X), + (t2 * range.Y + min.Y), + (t3 * range.Z + min.Z)); + vs.Add(f3); + } + } + + nverts = vs.Count; + + if (nverts < 4) + { + for (i = 0; i < vs.Count; i++) + coords.Add(new Coord(vs[i].x, vs[i].y, vs[i].z)); + + faces.Add(new Face(0, 1, 2)); + + vs.Clear(); + return true; + } + + if (!HullUtils.ComputeHull(vs, out List indices)) + return false; + + nindexs = indices.Count; + + if (nindexs % 3 != 0) + return false; + + for (i = 0; i < vs.Count; i++) + coords.Add(new Coord(vs[i].x, vs[i].y, vs[i].z)); + + for (i = 0; i < indices.Count; i += 3) + { + t1 = indices[i]; + if (t1 > nverts) + break; + t2 = indices[i + 1]; + if (t2 > nverts) + break; + t3 = indices[i + 2]; + if (t3 > nverts) + break; + + faces.Add(new Face(t1, t2, t3)); + } + vs.Clear(); + if (coords.Count > 0 && faces.Count > 0) + return true; } } - - return true; + return false; } /// @@ -728,70 +708,56 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing /// Coords are added to this list by the method. /// Faces are added to this list by the method. /// true if coords and faces were successfully generated, false if not - private bool GenerateCoordsAndFacesFromPrimSculptData( + private static bool GenerateCoordsAndFacesFromPrimSculptData( string primName, PrimitiveBaseShape primShape, float lod, out List coords, out List faces) { coords = new List(); faces = new List(); PrimMesher.SculptMesh sculptMesh; - Image idata = null; + Image idata; - if (primShape.SculptData == null || primShape.SculptData.Length == 0) - return false; + if (primShape.SculptData == null || primShape.SculptData.Length == 0) + return false; - try + try + { + OpenMetaverse.Imaging.OpenJPEG.DecodeToImage(primShape.SculptData, out OpenMetaverse.Imaging.ManagedImage unusedData, out idata); + + unusedData = null; + + if (idata == null) { - OpenMetaverse.Imaging.ManagedImage unusedData; - OpenMetaverse.Imaging.OpenJPEG.DecodeToImage(primShape.SculptData, out unusedData, out idata); - - unusedData = null; - - if (idata == null) - { - // In some cases it seems that the decode can return a null bitmap without throwing - // an exception - m_log.WarnFormat("[PHYSICS]: OpenJPEG decoded sculpt data for {0} to a null bitmap. Ignoring.", primName); - return false; - } - } - catch (DllNotFoundException) - { - m_log.Error("[PHYSICS]: OpenJpeg is not installed correctly on this system. Physics Proxy generation failed. Often times this is because of an old version of GLIBC. You must have version 2.4 or above!"); + // In some cases it seems that the decode can return a null bitmap without throwing + // an exception + m_log.WarnFormat("[PHYSICS]: OpenJPEG decoded sculpt data for {0} to a null bitmap. Ignoring.", primName); return false; } - catch (IndexOutOfRangeException) - { - m_log.Error("[PHYSICS]: OpenJpeg was unable to decode this. Physics Proxy generation failed"); - return false; - } - catch (Exception ex) - { - m_log.Error("[PHYSICS]: Unable to generate a Sculpty physics proxy. Sculpty texture decode failed: " + ex.Message); - return false; - } - - PrimMesher.SculptMesh.SculptType sculptType; + } + catch (DllNotFoundException) + { + m_log.Error("[PHYSICS]: OpenJpeg is not installed correctly on this system. Physics Proxy generation failed. Often times this is because of an old version of GLIBC. You must have version 2.4 or above!"); + return false; + } + catch (IndexOutOfRangeException) + { + m_log.Error("[PHYSICS]: OpenJpeg was unable to decode this. Physics Proxy generation failed"); + return false; + } + catch (Exception ex) + { + m_log.Error("[PHYSICS]: Unable to generate a Sculpty physics proxy. Sculpty texture decode failed: " + ex.Message); + return false; + } // remove mirror and invert bits OpenMetaverse.SculptType pbsSculptType = ((OpenMetaverse.SculptType)(primShape.SculptType & 0x3f)); - switch (pbsSculptType) + var sculptType = pbsSculptType switch { - case OpenMetaverse.SculptType.Cylinder: - sculptType = PrimMesher.SculptMesh.SculptType.cylinder; - break; - case OpenMetaverse.SculptType.Plane: - sculptType = PrimMesher.SculptMesh.SculptType.plane; - break; - case OpenMetaverse.SculptType.Torus: - sculptType = PrimMesher.SculptMesh.SculptType.torus; - break; - case OpenMetaverse.SculptType.Sphere: - sculptType = PrimMesher.SculptMesh.SculptType.sphere; - break; - default: - sculptType = PrimMesher.SculptMesh.SculptType.plane; - break; - } - + OpenMetaverse.SculptType.Cylinder => PrimMesher.SculptMesh.SculptType.cylinder, + OpenMetaverse.SculptType.Plane => PrimMesher.SculptMesh.SculptType.plane, + OpenMetaverse.SculptType.Torus => PrimMesher.SculptMesh.SculptType.torus, + OpenMetaverse.SculptType.Sphere => PrimMesher.SculptMesh.SculptType.sphere, + _ => PrimMesher.SculptMesh.SculptType.plane, + }; bool mirror = ((primShape.SculptType & 128) != 0); bool invert = ((primShape.SculptType & 64) != 0); @@ -861,26 +827,25 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing sides = 3; else if (profshape == (byte)ProfileShape.Circle) { - switch (iLOD) + sides = iLOD switch { - case LevelOfDetail.High: sides = 24; break; - case LevelOfDetail.Medium: sides = 12; break; - case LevelOfDetail.Low: sides = 6; break; - case LevelOfDetail.VeryLow: sides = 3; break; - default: sides = 24; break; - } + LevelOfDetail.High => 24, + LevelOfDetail.Medium => 12, + LevelOfDetail.Low => 6, + LevelOfDetail.VeryLow => 3, + _ => 24, + }; } else if (profshape == (byte)ProfileShape.HalfCircle) { // half circle, prim is a sphere - switch (iLOD) + sides = iLOD switch { - case LevelOfDetail.High: sides = 24; break; - case LevelOfDetail.Medium: sides = 12; break; - case LevelOfDetail.Low: sides = 6; break; - case LevelOfDetail.VeryLow: sides = 3; break; - default: sides = 24; break; - } - + LevelOfDetail.High => 24, + LevelOfDetail.Medium => 12, + LevelOfDetail.Low => 6, + LevelOfDetail.VeryLow => 3, + _ => 24, + }; profileBegin = 0.5f * profileBegin + 0.5f; profileEnd = 0.5f * profileEnd + 0.5f; } @@ -888,14 +853,14 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing int hollowSides = sides; if (primShape.HollowShape == HollowShape.Circle) { - switch (iLOD) + hollowSides = iLOD switch { - case LevelOfDetail.High: hollowSides = 24; break; - case LevelOfDetail.Medium: hollowSides = 12; break; - case LevelOfDetail.Low: hollowSides = 6; break; - case LevelOfDetail.VeryLow: hollowSides = 3; break; - default: hollowSides = 24; break; - } + LevelOfDetail.High => 24, + LevelOfDetail.Medium => 12, + LevelOfDetail.Low => 6, + LevelOfDetail.VeryLow => 3, + _ => 24, + }; } else if (primShape.HollowShape == HollowShape.Square) hollowSides = 4; @@ -980,9 +945,9 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing return true; } - public AMeshKey GetMeshUniqueKey(PrimitiveBaseShape primShape, Vector3 size, byte lod, bool convex) + public static AMeshKey GetMeshUniqueKey(PrimitiveBaseShape primShape, Vector3 size, byte lod, bool convex) { - AMeshKey key = new AMeshKey(); + AMeshKey key = new(); Byte[] someBytes; key.hashB = 5181; @@ -1028,7 +993,7 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing if (size == m_MeshUnitSize) { - hash = hash << 8; + hash <<= 8; hash |= 8; } else @@ -1036,7 +1001,7 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing someBytes = size.GetBytes(); for (int i = 0; i < someBytes.Length; i++) hash = mdjb2(hash, someBytes[i]); - hash = hash << 8; + hash <<= 8; } if (convex) @@ -1054,15 +1019,17 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing return key; } - private ulong mdjb2(ulong hash, byte c) + private static ulong mdjb2(ulong hash, byte c) { - return ((hash << 5) + hash) + (ulong)c; + //return ((hash << 5) + hash) + (ulong)c; + return 33 * hash + c; } - private ulong mdjb2(ulong hash, ushort c) + private static ulong mdjb2(ulong hash, ushort c) { - hash = ((hash << 5) + hash) + (ulong)((byte)c); - return ((hash << 5) + hash) + (ulong)(c >> 8); + //hash = ((hash << 5) + hash) + (ulong)((byte)c); + //return ((hash << 5) + hash) + (ulong)(c >> 8); + return 33 * hash + c; } public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod) @@ -1119,7 +1086,7 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing return null; } - private static Vector3 m_MeshUnitSize = new Vector3(1.0f, 1.0f, 1.0f); + private static Vector3 m_MeshUnitSize = new(1.0f, 1.0f, 1.0f); public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex, bool forOde) { @@ -1264,7 +1231,7 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing if (m_uniqueReleasedMeshes.Count == 0) return; - List meshstodelete = new List(); + List meshstodelete = new(); int refcntr; lock (m_uniqueReleasedMeshes) @@ -1291,7 +1258,7 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing public void FileNames(AMeshKey key, out string dir, out string fullFileName) { string id = key.ToString(); - string init = id.Substring(0, 1); + string init = id[..1]; dir = System.IO.Path.Combine(cachePath, init); fullFileName = System.IO.Path.Combine(dir, id); } @@ -1299,7 +1266,7 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing public string FullFileName(AMeshKey key) { string id = key.ToString(); - string init = id.Substring(0,1); + string init = id[..1]; id = System.IO.Path.Combine(init, id); id = System.IO.Path.Combine(cachePath, id); return id; @@ -1354,10 +1321,7 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing bool ok = false; // Make sure the target cache directory exists - string dir = String.Empty; - string filename = String.Empty; - - FileNames(key, out dir, out filename); + FileNames(key, out string dir, out string filename); lock (diskLock) { @@ -1537,17 +1501,17 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing } } - public bool CreateBoundingHull(List inputVertices, out List convexcoords, out List newfaces) + public static bool CreateBoundingHull(List inputVertices, out List convexcoords, out List newfaces) { convexcoords = null; newfaces = null; - HullDesc desc = new HullDesc(); - HullResult result = new HullResult(); + HullDesc desc = new(); + HullResult result = new(); int nInputVerts = inputVertices.Count; int i; - List vs = new List(nInputVerts); + List vs = new(nInputVerts); float3 f3; //useless copy diff --git a/OpenSim/Region/PhysicsModules/ubOdeMeshing/PrimMesher.cs b/OpenSim/Region/PhysicsModules/ubOdeMeshing/PrimMesher.cs index f3a57d365c..7645183913 100644 --- a/OpenSim/Region/PhysicsModules/ubOdeMeshing/PrimMesher.cs +++ b/OpenSim/Region/PhysicsModules/ubOdeMeshing/PrimMesher.cs @@ -29,6 +29,7 @@ using System; using System.Collections.Generic; using System.Text; using System.IO; +using System.Xml.XPath; namespace PrimMesher { @@ -60,27 +61,25 @@ namespace PrimMesher public Quat(MainAxis BaseAxis, float angle) { - angle *= 0.5f; - double c = Math.Cos(angle); - float s = (float)Math.Sqrt(1.0 - c * c); - - W = (float)c; switch (BaseAxis) { case MainAxis.X: - X = s; + W = MathF.Cos(0.5f * angle); + X = MathF.Sqrt(1.0f - W * W); Y = 0; Z = 0; break; case MainAxis.Y: + W = MathF.Cos(0.5f * angle); + Y = MathF.Sqrt(1.0f - W * W); X = 0; - Y = s; Z = 0; break; case MainAxis.Z: + W = MathF.Cos(0.5f * angle); + Z = MathF.Sqrt(1.0f - W * W); X = 0; Y = 0; - Z = s; break; default: //error X = 0; @@ -93,18 +92,18 @@ namespace PrimMesher public float Length() { - return (float)Math.Sqrt(X * X + Y * Y + Z * Z + W * W); + return MathF.Sqrt(X * X + Y * Y + Z * Z + W * W); } public Quat Normalize() { const float MAG_THRESHOLD = 0.0000001f; - float mag = Length(); + float mag = (X * X + Y * Y + Z * Z + W * W); // Catch very small rounding errors when normalizing if (mag > MAG_THRESHOLD) { - float oomag = 1f / mag; + float oomag = 1f / MathF.Sqrt(mag); X *= oomag; Y *= oomag; Z *= oomag; @@ -151,7 +150,7 @@ namespace PrimMesher public float Length() { - return (float)Math.Sqrt(X * X + Y * Y + Z * Z); + return MathF.Sqrt(X * X + Y * Y + Z * Z); } public Coord Invert() @@ -280,7 +279,7 @@ namespace PrimMesher { private float iX, iY; // intersection point - private static Angle[] angles3 = + private static readonly Angle[] angles3 = { new Angle(0.0f, 1.0f, 0.0f), new Angle(0.33333333333333333f, -0.5f, 0.86602540378443871f), @@ -288,7 +287,7 @@ namespace PrimMesher new Angle(1.0f, 1.0f, 0.0f) }; - private static Angle[] angles4 = + private static readonly Angle[] angles4 = { new Angle(0.0f, 1.0f, 0.0f), new Angle(0.25f, 0.0f, 1.0f), @@ -297,7 +296,7 @@ namespace PrimMesher new Angle(1.0f, 1.0f, 0.0f) }; - private static Angle[] angles6 = + private static readonly Angle[] angles6 = { new Angle(0.0f, 1.0f, 0.0f), new Angle(0.16666666666666667f, 0.5f, 0.8660254037844386f), @@ -308,7 +307,7 @@ namespace PrimMesher new Angle(1.0f, 1.0f, 0.0f) }; - private static Angle[] angles12 = + private static readonly Angle[] angles12 = { new Angle(0.0f, 1.0f, 0.0f), new Angle(0.083333333333333329f, 0.86602540378443871f, 0.5f), @@ -325,7 +324,7 @@ namespace PrimMesher new Angle(1.0f, 1.0f, 0.0f) }; - private static Angle[] angles24 = + private static readonly Angle[] angles24 = { new Angle(0.0f, 1.0f, 0.0f), new Angle(0.041666666666666664f, 0.96592582628906831f, 0.25881904510252074f), @@ -354,7 +353,7 @@ namespace PrimMesher new Angle(1.0f, 1.0f, 0.0f) }; - private Angle interpolatePoints(float newPoint, Angle p1, Angle p2) + private static Angle interpolatePoints(float newPoint, Angle p1, Angle p2) { float m = (newPoint - p1.angle) / (p2.angle - p1.angle); return new Angle(newPoint, p1.X + m * (p2.X - p1.X), p1.Y + m * (p2.Y - p1.Y)); @@ -379,8 +378,8 @@ namespace PrimMesher { angles = new List(); - const float twoPi = 2.0f * (float)Math.PI; - const float twoPiInv = 0.5f / (float)Math.PI; + const float twoPi = 2.0f * MathF.PI; + const float twoPiInv = 0.5f / MathF.PI; if (sides < 1) throw new Exception("number of sides not greater than zero"); @@ -391,27 +390,14 @@ namespace PrimMesher { startAngle *= twoPiInv; stopAngle *= twoPiInv; - - Angle[] sourceAngles; - switch (sides) + Angle[] sourceAngles = sides switch { - case 3: - sourceAngles = angles3; - break; - case 4: - sourceAngles = angles4; - break; - case 6: - sourceAngles = angles6; - break; - case 12: - sourceAngles = angles12; - break; - default: - sourceAngles = angles24; - break; - } - + 3 => angles3, + 4 => angles4, + 6 => angles6, + 12 => angles12, + _ => angles24, + }; int startAngleIndex = (int)(startAngle * sides); int endAngleIndex = sourceAngles.Length - 1; @@ -447,7 +433,7 @@ namespace PrimMesher double stepSize = twoPi / sides; int startStep = (int)(startAngle / stepSize); - double angle = stepSize * startStep; + float angle = (float)stepSize * startStep; int step = startStep; double stopAngleTest = stopAngle; if (stopAngle < twoPi) @@ -462,18 +448,18 @@ namespace PrimMesher while (angle <= stopAngleTest) { Angle newAngle; - newAngle.angle = (float)angle; - newAngle.X = (float)System.Math.Cos(angle); - newAngle.Y = (float)System.Math.Sin(angle); + newAngle.angle = angle; + newAngle.X = MathF.Cos(angle); + newAngle.Y = MathF.Sin(angle); angles.Add(newAngle); step += 1; - angle = stepSize * step; + angle = (float)(stepSize * step); } if (startAngle > angles[0].angle) { Angle newAngle; - intersection(angles[0].X, angles[0].Y, angles[1].X, angles[1].Y, 0.0f, 0.0f, (float)Math.Cos(startAngle), (float)Math.Sin(startAngle)); + intersection(angles[0].X, angles[0].Y, angles[1].X, angles[1].Y, 0.0f, 0.0f, MathF.Cos(startAngle), MathF.Sin(startAngle)); newAngle.angle = startAngle; newAngle.X = iX; newAngle.Y = iY; @@ -484,7 +470,7 @@ namespace PrimMesher if (stopAngle < angles[index].angle) { Angle newAngle; - intersection(angles[index - 1].X, angles[index - 1].Y, angles[index].X, angles[index].Y, 0.0f, 0.0f, (float)Math.Cos(stopAngle), (float)Math.Sin(stopAngle)); + intersection(angles[index - 1].X, angles[index - 1].Y, angles[index].X, angles[index].Y, 0.0f, 0.0f, MathF.Cos(stopAngle), MathF.Sin(stopAngle)); newAngle.angle = stopAngle; newAngle.X = iX; newAngle.Y = iY; @@ -499,7 +485,7 @@ namespace PrimMesher /// public class Profile { - private const float twoPi = 2.0f * (float)Math.PI; + private const float twoPi = 2.0f * MathF.PI; public string errorMessage = null; @@ -532,12 +518,12 @@ namespace PrimMesher coords = new List(); faces = new List(); - List hollowCoords = new List(); + List hollowCoords = new(); bool hasHollow = (hollow > 0.0f); - AngleList angles = new AngleList(); - AngleList hollowAngles = new AngleList(); + AngleList angles = new(); + AngleList hollowAngles = new(); float xScale = 0.5f; float yScale = 0.5f; @@ -562,7 +548,7 @@ namespace PrimMesher numOuterVerts = angles.angles.Count; Angle angle; - Coord newVert = new Coord(); + Coord newVert = new(); // flag to create as few triangles as possible for 3 or 4 side profile bool simpleFace = (sides < 5 && !hasHollow && !hasProfileCut); @@ -597,7 +583,7 @@ namespace PrimMesher } else if (!simpleFace) { - Coord center = new Coord(0.0f, 0.0f, 0.0f); + Coord center = new(0.0f, 0.0f, 0.0f); this.coords.Add(center); } @@ -630,7 +616,7 @@ namespace PrimMesher if (numOuterVerts == numHollowVerts) { - Face newFace = new Face(); + Face newFace = new(); for (int coordIndex = 0; coordIndex < numOuterVerts - 1; coordIndex++) { @@ -659,7 +645,7 @@ namespace PrimMesher } else if (numOuterVerts < numHollowVerts) { - Face newFace = new Face(); + Face newFace = new(); int j = 0; // j is the index for outer vertices int i; int maxJ = numOuterVerts - 1; @@ -730,7 +716,7 @@ namespace PrimMesher } else // numHollowVerts < numOuterVerts { - Face newFace = new Face(); + Face newFace = new(); int j = 0; // j is the index for inner vertices int maxJ = numHollowVerts - 1; for (int i = 0; i < numOuterVerts; i++) @@ -793,24 +779,26 @@ namespace PrimMesher { for (int i = 1; i < numAngles ; i++) { - Face newFace = new Face(); - newFace.v1 = 0; - newFace.v2 = i; - newFace.v3 = i + 1; + Face newFace = new() + { + v1 = 0, + v2 = i, + v3 = i + 1 + }; faces.Add(newFace); } if (!hasProfileCut) { - Face newFace = new Face(); - newFace.v1 = 0; - newFace.v2 = numAngles; - newFace.v3 = 1; + Face newFace = new() + { + v1 = 0, + v2 = numAngles, + v3 = 1 + }; faces.Add(newFace); } } } - - hollowCoords = null; } @@ -821,7 +809,7 @@ namespace PrimMesher public Profile Copy(bool needFaces) { - Profile copy = new Profile(); + Profile copy = new(); copy.coords.AddRange(coords); @@ -874,9 +862,9 @@ namespace PrimMesher { vert = coords[i]; vert.X *= x; - vert.X = (float)Math.Round(vert.X,5); + vert.X = MathF.Round(vert.X,5); vert.Y *= y; - vert.Y = (float)Math.Round(vert.Y,5); + vert.Y = MathF.Round(vert.Y,5); coords[i] = vert; } @@ -930,17 +918,12 @@ namespace PrimMesher { if (path == null) return; - String fileName = name + "_" + title + ".raw"; - String completePath = System.IO.Path.Combine(path, fileName); - StreamWriter sw = new StreamWriter(completePath); + string completePath = System.IO.Path.Combine(path, $"{name}_{title}.raw"); + using StreamWriter sw = new(completePath); for (int i = 0; i < faces.Count; i++) { - string s = coords[faces[i].v1].ToString(); - s += " " + coords[faces[i].v2].ToString(); - s += " " + coords[faces[i].v3].ToString(); - - sw.WriteLine(s); + sw.WriteLine($"{coords[faces[i].v1]} {coords[faces[i].v3]} {coords[faces[i].v3]}"); } sw.Close(); @@ -960,7 +943,7 @@ namespace PrimMesher public class Path { - public List pathNodes = new List(); + public List pathNodes = new(); public float twistBegin = 0.0f; public float twistEnd = 0.0f; @@ -979,7 +962,7 @@ namespace PrimMesher public float revolutions = 1.0f; public int stepsPerRevolution = 24; - private const float twoPi = 2.0f * (float)Math.PI; + private const float twoPi = 2.0f * MathF.PI; public void Create(PathType pathType, int steps) { @@ -998,7 +981,7 @@ namespace PrimMesher float length = pathCutEnd - pathCutBegin; float twistTotal = twistEnd - twistBegin; - float twistTotalAbs = Math.Abs(twistTotal); + float twistTotalAbs = MathF.Abs(twistTotal); if (twistTotalAbs > 0.01f) steps += (int)(twistTotalAbs * 3.66); // dahlia's magic number @@ -1020,7 +1003,7 @@ namespace PrimMesher while (!done) { - PathNode newNode = new PathNode(); + PathNode newNode = new(); newNode.xScale = 1.0f; if (taperX > 0.0f) @@ -1063,12 +1046,12 @@ namespace PrimMesher // if the profile has a lot of twist, add more layers otherwise the layers may overlap // and the resulting mesh may be quite inaccurate. This method is arbitrary and doesn't // accurately match the viewer - float twistTotalAbs = Math.Abs(twistTotal); + float twistTotalAbs = MathF.Abs(twistTotal); if (twistTotalAbs > 0.01f) { - if (twistTotalAbs > Math.PI * 1.5f) + if (twistTotalAbs > MathF.PI * 1.5f) steps *= 2; - if (twistTotalAbs > Math.PI * 3.0f) + if (twistTotalAbs > MathF.PI * 3.0f) steps *= 2; } @@ -1077,7 +1060,7 @@ namespace PrimMesher float totalSkew = skew * 2.0f * pathLength; float skewStart = pathCutBegin * 2.0f * skew - skew; float xOffsetTopShearXFactor = topShearX * (0.25f + 0.5f * (0.5f - holeSizeY)); - float yShearCompensation = 1.0f + Math.Abs(topShearY) * 0.25f; + float yShearCompensation = 1.0f + MathF.Abs(topShearY) * 0.25f; // It's not quite clear what pushY (Y top shear) does, but subtracting it from the start and end // angles appears to approximate it's effects on path cut. Likewise, adding it to the angle used @@ -1097,9 +1080,9 @@ namespace PrimMesher bool done = false; while (!done) // loop through the length of the path and add the layers { - PathNode newNode = new PathNode(); + PathNode newNode = new(); - float xProfileScale = (1.0f - Math.Abs(skew)) * holeSizeX; + float xProfileScale = (1.0f - MathF.Abs(skew)) * holeSizeX; float yProfileScale = holeSizeY; float percentOfPath = angle / (twoPi * revolutions); @@ -1127,11 +1110,11 @@ namespace PrimMesher float twist = twistBegin + twistTotal * percentOfPath; float xOffset = 0.5f * (skewStart + totalSkew * percentOfAngles); - xOffset += (float)Math.Sin(angle) * xOffsetTopShearXFactor; + xOffset += MathF.Sin(angle) * xOffsetTopShearXFactor; - float yOffset = yShearCompensation * (float)Math.Cos(angle) * (0.5f - yPathScale) * radiusScale; + float yOffset = yShearCompensation * MathF.Cos(angle) * (0.5f - yPathScale) * radiusScale; - float zOffset = (float)Math.Sin(angle + topShearY) * (0.5f - yPathScale) * radiusScale; + float zOffset = MathF.Sin(angle + topShearY) * (0.5f - yPathScale) * radiusScale; newNode.position = new Coord(xOffset, yOffset, zOffset); @@ -1168,8 +1151,6 @@ namespace PrimMesher public class PrimMesh { public string errorMessage = ""; - private const float twoPi = 2.0f * (float)Math.PI; - public List coords; // public List normals; public List faces; @@ -1289,19 +1270,19 @@ namespace PrimMesher /// public void Extrude(PathType pathType) { - bool needEndFaces = false; + bool needEndFaces; coords = new List(); faces = new List(); int steps = 1; - float length = pathCutEnd - pathCutBegin; + //float length = pathCutEnd - pathCutBegin; hasProfileCut = profileEnd - profileStart < 0.9999f; float twistTotal = twistEnd - twistBegin; - float twistTotalAbs = Math.Abs(twistTotal); + float twistTotalAbs = MathF.Abs(twistTotal); if (twistTotalAbs > 0.01f) steps += (int)(twistTotalAbs * 3.66); // dahlia's magic number @@ -1330,7 +1311,7 @@ namespace PrimMesher { if (sides == 3) { - initialProfileRot = (float)Math.PI; + initialProfileRot = MathF.PI; if (hollowSides == 4) { if (hollow > 0.7f) @@ -1341,13 +1322,13 @@ namespace PrimMesher } else if (sides == 4) { - initialProfileRot = 0.25f * (float)Math.PI; + initialProfileRot = 0.25f * MathF.PI; if (hollowSides != 4) hollow *= 0.707f; } else if (sides > 4) { - initialProfileRot = (float)Math.PI; + initialProfileRot = MathF.PI; if (hollowSides == 4) { if (hollow > 0.7f) @@ -1370,7 +1351,7 @@ namespace PrimMesher } else if (sides == 4) { - initialProfileRot = 1.25f * (float)Math.PI; + initialProfileRot = 1.25f * MathF.PI; if (hollowSides != 4) hollow *= 0.707f; } @@ -1378,8 +1359,7 @@ namespace PrimMesher hollow *= 1.414f; } - Profile profile = new Profile(sides, profileStart, profileEnd, hollow, hollowSides, - HasProfileCut,true); + Profile profile = new(sides, profileStart, profileEnd, hollow, hollowSides, HasProfileCut, true); errorMessage = profile.errorMessage; numPrimFaces = profile.numPrimFaces; @@ -1389,23 +1369,25 @@ namespace PrimMesher profile.AddRot(new Quat(Quat.MainAxis.Z, initialProfileRot)); } - Path path = new Path(); - path.twistBegin = twistBegin; - path.twistEnd = twistEnd; - path.topShearX = topShearX; - path.topShearY = topShearY; - path.pathCutBegin = pathCutBegin; - path.pathCutEnd = pathCutEnd; - path.dimpleBegin = dimpleBegin; - path.dimpleEnd = dimpleEnd; - path.skew = skew; - path.holeSizeX = holeSizeX; - path.holeSizeY = holeSizeY; - path.taperX = taperX; - path.taperY = taperY; - path.radius = radius; - path.revolutions = revolutions; - path.stepsPerRevolution = stepsPerRevolution; + Path path = new() + { + twistBegin = twistBegin, + twistEnd = twistEnd, + topShearX = topShearX, + topShearY = topShearY, + pathCutBegin = pathCutBegin, + pathCutEnd = pathCutEnd, + dimpleBegin = dimpleBegin, + dimpleEnd = dimpleEnd, + skew = skew, + holeSizeX = holeSizeX, + holeSizeY = holeSizeY, + taperX = taperX, + taperY = taperY, + radius = radius, + revolutions = revolutions, + stepsPerRevolution = stepsPerRevolution + }; path.Create(pathType, steps); @@ -1433,10 +1415,10 @@ namespace PrimMesher // fill faces between layers - List linkfaces = new List(); + List linkfaces = new(); int numVerts = newLayer.coords.Count; - Face newFace1 = new Face(); - Face newFace2 = new Face(); + Face newFace1 = new(); + Face newFace2 = new(); if (nodeIndex > 0) { @@ -1533,10 +1515,10 @@ namespace PrimMesher // more cleanup will be done at Meshmerizer.cs } - private Coord SurfaceNormal(Coord c1, Coord c2, Coord c3) + private static Coord SurfaceNormal(Coord c1, Coord c2, Coord c3) { - Coord edge1 = new Coord(c2.X - c1.X, c2.Y - c1.Y, c2.Z - c1.Z); - Coord edge2 = new Coord(c3.X - c1.X, c3.Y - c1.Y, c3.Z - c1.Z); + Coord edge1 = new(c2.X - c1.X, c2.Y - c1.Y, c2.Z - c1.Z); + Coord edge2 = new(c3.X - c1.X, c3.Y - c1.Y, c3.Z - c1.Z); Coord normal = Coord.Cross(edge1, edge2); @@ -1570,29 +1552,31 @@ namespace PrimMesher /// public PrimMesh Copy() { - PrimMesh copy = new PrimMesh(sides, profileStart, profileEnd, hollow, hollowSides); - copy.twistBegin = twistBegin; - copy.twistEnd = twistEnd; - copy.topShearX = topShearX; - copy.topShearY = topShearY; - copy.pathCutBegin = pathCutBegin; - copy.pathCutEnd = pathCutEnd; - copy.dimpleBegin = dimpleBegin; - copy.dimpleEnd = dimpleEnd; - copy.skew = skew; - copy.holeSizeX = holeSizeX; - copy.holeSizeY = holeSizeY; - copy.taperX = taperX; - copy.taperY = taperY; - copy.radius = radius; - copy.revolutions = revolutions; - copy.stepsPerRevolution = stepsPerRevolution; + PrimMesh copy = new(sides, profileStart, profileEnd, hollow, hollowSides) + { + twistBegin = twistBegin, + twistEnd = twistEnd, + topShearX = topShearX, + topShearY = topShearY, + pathCutBegin = pathCutBegin, + pathCutEnd = pathCutEnd, + dimpleBegin = dimpleBegin, + dimpleEnd = dimpleEnd, + skew = skew, + holeSizeX = holeSizeX, + holeSizeY = holeSizeY, + taperX = taperX, + taperY = taperY, + radius = radius, + revolutions = revolutions, + stepsPerRevolution = stepsPerRevolution, - copy.numPrimFaces = numPrimFaces; - copy.errorMessage = errorMessage; + numPrimFaces = numPrimFaces, + errorMessage = errorMessage, - copy.coords = new List(coords); - copy.faces = new List(faces); + coords = new List(coords), + faces = new List(faces) + }; return copy; } @@ -1644,7 +1628,7 @@ namespace PrimMesher int numVerts = this.coords.Count; //Coord vert; - Coord m = new Coord(x, y, z); + Coord m = new(x, y, z); for (i = 0; i < numVerts; i++) coords[i] *= m; } @@ -1659,16 +1643,13 @@ namespace PrimMesher { if (path == null) return; - String fileName = name + "_" + title + ".raw"; - String completePath = System.IO.Path.Combine(path, fileName); - using (StreamWriter sw = new StreamWriter(completePath)) + string completePath = System.IO.Path.Combine(path, $"{name}_{title}.raw"); + using StreamWriter sw = new(completePath); + for (int i = 0; i < this.faces.Count; i++) { - for (int i = 0; i < this.faces.Count; i++) - { - sw.Write(coords[faces[i].v1].ToString()); - sw.Write(coords[faces[i].v2].ToString()); - sw.WriteLine(coords[faces[i].v3].ToString()); - } + sw.Write(coords[faces[i].v1].ToString()); + sw.Write(coords[faces[i].v2].ToString()); + sw.WriteLine(coords[faces[i].v3].ToString()); } } }