/// <summary> /// frees up the source mesh data to minimize memory - call this method after calling get*Locked() functions /// </summary> public void releaseSourceMeshData() { triangles = null; vertices = null; primMesh = null; }
// from IdealistViewer.PrimMesherG.cs public PrimMesh ConstructionDataToPrimMesh(Primitive.ConstructionData primData, LevelOfDetail detail, float detailMult) { this.sides = 4; this.hollowsides = 4; float profileBegin = primData.ProfileBegin; float profileEnd = primData.ProfileEnd; bool isSphere = false; if ((ProfileCurve)(primData.profileCurve & 0x07) == ProfileCurve.Circle) { switch (detail) { case LevelOfDetail.Low: sides = 6; break; case LevelOfDetail.Medium: sides = 12; break; default: sides = 24; break; } } else if ((ProfileCurve)(primData.profileCurve & 0x07) == ProfileCurve.EqualTriangle) sides = 3; else if ((ProfileCurve)(primData.profileCurve & 0x07) == ProfileCurve.HalfCircle) { // half circle, prim is a sphere isSphere = true; switch (detail) { case LevelOfDetail.Low: sides = 6; break; case LevelOfDetail.Medium: sides = 12; break; default: sides = 24; break; } profileBegin = 0.5f * profileBegin + 0.5f; profileEnd = 0.5f * profileEnd + 0.5f; } if ((HoleType)primData.ProfileHole == HoleType.Same) hollowsides = sides; else if ((HoleType)primData.ProfileHole == HoleType.Circle) { switch (detail) { case LevelOfDetail.Low: hollowsides = 6; break; case LevelOfDetail.Medium: hollowsides = 12; break; default: hollowsides = 24; break; } } else if ((HoleType)primData.ProfileHole == HoleType.Triangle) hollowsides = 3; // if (UseExtremeDetail) { sides = (int)(sides * detailMult); hollowsides = (int)(hollowsides * detailMult); } PrimMesh primMesh = new PrimMesh(sides, profileBegin, profileEnd, (float)primData.ProfileHollow, hollowsides); primMesh.viewerMode = UseViewerMode; primMesh.holeSizeX = primData.PathScaleX; primMesh.holeSizeY = primData.PathScaleY; primMesh.pathCutBegin = primData.PathBegin; primMesh.pathCutEnd = primData.PathEnd; primMesh.topShearX = primData.PathShearX; primMesh.topShearY = primData.PathShearY; primMesh.radius = primData.PathRadiusOffset; primMesh.revolutions = primData.PathRevolutions; primMesh.skew = primData.PathSkew; switch (detail) { case LevelOfDetail.Low: primMesh.stepsPerRevolution = 6; break; case LevelOfDetail.Medium: primMesh.stepsPerRevolution = 12; break; default: primMesh.stepsPerRevolution = 24; break; } //if (UseExtremeDetail) { primMesh.stepsPerRevolution = (int)(primMesh.stepsPerRevolution * detailMult); } if (primData.PathCurve == PathCurve.Line) { primMesh.taperX = 1.0f - primData.PathScaleX; primMesh.taperY = 1.0f - primData.PathScaleY; primMesh.twistBegin = (int)(180 * primData.PathTwistBegin); primMesh.twistEnd = (int)(180 * primData.PathTwist); primMesh.ExtrudeLinear(); } else { primMesh.taperX = primData.PathTaperX; primMesh.taperY = primData.PathTaperY; primMesh.twistBegin = (int)(360 * primData.PathTwistBegin); primMesh.twistEnd = (int)(360 * primData.PathTwist); primMesh.ExtrudeCircular(); } if (UseViewerMode) { int numViewerFaces = primMesh.viewerFaces.Count; for (uint i = 0; i < numViewerFaces; i++) { ViewerFace vf = primMesh.viewerFaces[(int)i]; if (isSphere) { vf.uv1.U = (vf.uv1.U - 0.5f) * 2.0f; vf.uv2.U = (vf.uv2.U - 0.5f) * 2.0f; vf.uv3.U = (vf.uv3.U - 0.5f) * 2.0f; } } } return primMesh; }
/// <summary> /// Duplicates a PrimMesh object. All object properties are copied by value, including lists. /// </summary> /// <returns></returns> public PrimMesh Copy() { PrimMesh copy = new PrimMesh(this.sides, this.profileStart, this.profileEnd, this.hollow, this.hollowSides); copy.twistBegin = this.twistBegin; copy.twistEnd = this.twistEnd; copy.topShearX = this.topShearX; copy.topShearY = this.topShearY; copy.pathCutBegin = this.pathCutBegin; copy.pathCutEnd = this.pathCutEnd; copy.dimpleBegin = this.dimpleBegin; copy.dimpleEnd = this.dimpleEnd; copy.skew = this.skew; copy.holeSizeX = this.holeSizeX; copy.holeSizeY = this.holeSizeY; copy.taperX = this.taperX; copy.taperY = this.taperY; copy.radius = this.radius; copy.revolutions = this.revolutions; copy.stepsPerRevolution = this.stepsPerRevolution; copy.calcVertexNormals = this.calcVertexNormals; copy.normalsProcessed = this.normalsProcessed; copy.viewerMode = this.viewerMode; copy.numPrimFaces = this.numPrimFaces; copy.errorMessage = this.errorMessage; copy.coords = new List<Coord>(this.coords); copy.faces = new List<Face>(this.faces); copy.viewerFaces = new List<ViewerFace>(this.viewerFaces); copy.normals = new List<Coord>(this.normals); return copy; }
/// <summary> /// Convert a PrimMesher.PrimMesh to OpenSim.Region.Physics.Meshing.Mesh /// </summary> /// <param name="meshIn"></param> /// <returns></returns> public static Mesh PrimMeshToMesh(PrimMesh meshIn) { Mesh mesh = new Mesh(); #if COLLIDER_ODE mesh.PBS = meshIn.PBS #endif mesh.primMesh = meshIn; { List<Coord> coords = meshIn.coords; List<Face> faces = meshIn.faces; int numCoords = coords.Count; int numFaces = faces.Count; for (int i = 0; i < numCoords; i++) { Coord c = coords[i]; mesh.vertices.Add(new Vertex(c.X, c.Y, c.Z)); } List<Vertex> vertices = mesh.vertices; for (int i = 0; i < numFaces; i++) { Face f = faces[i]; mesh.triangles.Add(new Triangle(vertices[f.v1], vertices[f.v2], vertices[f.v3])); } } return mesh; }
public VertexIndexer(PrimMesh primMesh) { int numPrimFaces = primMesh.numPrimFaces; int maxPrimFaceNumber = 0; foreach (ViewerFace vf in primMesh.viewerFaces) if (maxPrimFaceNumber < vf.primFaceNumber) maxPrimFaceNumber = vf.primFaceNumber; if (numPrimFaces < maxPrimFaceNumber + 1) numPrimFaces = maxPrimFaceNumber + 1; int[] numViewerVerts = new int[numPrimFaces]; int[] numVertsPerPrimFace = new int[numPrimFaces]; for (int i = 0; i < numPrimFaces; i++) { numViewerVerts[i] = 0; numVertsPerPrimFace[i] = 0; } foreach (ViewerFace vf in primMesh.viewerFaces) numVertsPerPrimFace[vf.primFaceNumber] += 3; this.viewerVertices = new List<List<ViewerVertex>>(numPrimFaces); this.viewerPolygons = new List<List<ViewerPolygon>>(numPrimFaces); this.viewerVertIndices = new int[numPrimFaces][]; // create index lists for (int primFaceNumber = 0; primFaceNumber < numPrimFaces; primFaceNumber++) { //set all indices to -1 to indicate an invalid index int[] vertIndices = new int[primMesh.coords.Count]; for (int i = 0; i < primMesh.coords.Count; i++) vertIndices[i] = -1; viewerVertIndices[primFaceNumber] = vertIndices; viewerVertices.Add(new List<ViewerVertex>(numVertsPerPrimFace[primFaceNumber])); viewerPolygons.Add(new List<ViewerPolygon>()); } // populate the index lists foreach (ViewerFace vf in primMesh.viewerFaces) { int v1, v2, v3; int[] vertIndices = viewerVertIndices[vf.primFaceNumber]; List<ViewerVertex> viewerVerts = viewerVertices[vf.primFaceNumber]; // add the vertices if (vertIndices[vf.coordIndex1] < 0) { viewerVerts.Add(new ViewerVertex(vf.v1, vf.n1, vf.uv1)); v1 = viewerVerts.Count - 1; vertIndices[vf.coordIndex1] = v1; } else v1 = vertIndices[vf.coordIndex1]; if (vertIndices[vf.coordIndex2] < 0) { viewerVerts.Add(new ViewerVertex(vf.v2, vf.n2, vf.uv2)); v2 = viewerVerts.Count - 1; vertIndices[vf.coordIndex2] = v2; } else v2 = vertIndices[vf.coordIndex2]; if (vertIndices[vf.coordIndex3] < 0) { viewerVerts.Add(new ViewerVertex(vf.v3, vf.n3, vf.uv3)); v3 = viewerVerts.Count - 1; vertIndices[vf.coordIndex3] = v3; } else v3 = vertIndices[vf.coordIndex3]; viewerPolygons[vf.primFaceNumber].Add(new ViewerPolygon(v1, v2, v3)); } }