/// <summary> /// Generates a basic mesh structure from a primitive /// </summary> /// <param name="prim">Primitive to generate the mesh from</param> /// <param name="lod">Level of detail to generate the mesh at</param> /// <returns>The generated mesh or null on failure</returns> public OMVR.SimpleMesh GenerateSimpleMesh(OMV.Primitive prim, OMVR.DetailLevel lod) { PrimMesher.PrimMesh newPrim = GeneratePrimMesh(prim, lod, false); if (newPrim == null) return null; SimpleMesh mesh = new SimpleMesh(); mesh.Path = new Path(); mesh.Prim = prim; mesh.Profile = new Profile(); mesh.Vertices = new List<Vertex>(newPrim.coords.Count); for (int i = 0; i < newPrim.coords.Count; i++) { PrimMesher.Coord c = newPrim.coords[i]; mesh.Vertices.Add(new Vertex { Position = new Vector3(c.X, c.Y, c.Z) }); } mesh.Indices = new List<ushort>(newPrim.faces.Count * 3); for (int i = 0; i < newPrim.faces.Count; i++) { PrimMesher.Face face = newPrim.faces[i]; mesh.Indices.Add((ushort)face.v1); mesh.Indices.Add((ushort)face.v2); mesh.Indices.Add((ushort)face.v3); } return mesh; }
/// <summary> /// Generates a basic mesh structure from a sculpted primitive /// </summary> /// <param name="prim">Sculpted primitive to generate the mesh from</param> /// <param name="sculptTexture">Sculpt texture</param> /// <param name="lod">Level of detail to generate the mesh at</param> /// <returns>The generated mesh or null on failure</returns> public OMVR.SimpleMesh GenerateSimpleSculptMesh(OMV.Primitive prim, System.Drawing.Bitmap sculptTexture, OMVR.DetailLevel lod) { OMVR.FacetedMesh faceted = GenerateFacetedSculptMesh(prim, sculptTexture, lod); if (faceted != null && faceted.Faces.Count == 1) { Face face = faceted.Faces[0]; SimpleMesh mesh = new SimpleMesh(); mesh.Indices = face.Indices; mesh.Vertices = face.Vertices; mesh.Path = faceted.Path; mesh.Prim = prim; mesh.Profile = faceted.Profile; mesh.Vertices = face.Vertices; return mesh; } return null; }
/// <summary> /// Create a sculpty faceted mesh. The actual scuplt texture is fetched and passed to this /// routine since all the context for finding teh texture is elsewhere. /// </summary> /// <returns>The faceted mesh or null if can't do it</returns> public OMVR.FacetedMesh GenerateFacetedSculptMesh(OMV.Primitive prim, System.Drawing.Bitmap scupltTexture, OMVR.DetailLevel lod) { PrimMesher.SculptMesh.SculptType smSculptType; switch (prim.Sculpt.Type) { case OpenMetaverse.SculptType.Cylinder: smSculptType = PrimMesher.SculptMesh.SculptType.cylinder; break; case OpenMetaverse.SculptType.Plane: smSculptType = PrimMesher.SculptMesh.SculptType.plane; break; case OpenMetaverse.SculptType.Sphere: smSculptType = PrimMesher.SculptMesh.SculptType.sphere; break; case OpenMetaverse.SculptType.Torus: smSculptType = PrimMesher.SculptMesh.SculptType.torus; break; default: smSculptType = PrimMesher.SculptMesh.SculptType.plane; break; } // The lod for sculpties is the resolution of the texture passed. // The first guess is 1:1 then lower resolutions after that // int mesherLod = (int)Math.Sqrt(scupltTexture.Width * scupltTexture.Height); int mesherLod = 32; // number used in Idealist viewer switch (lod) { case OMVR.DetailLevel.Highest: break; case OMVR.DetailLevel.High: break; case OMVR.DetailLevel.Medium: mesherLod /= 2; break; case OMVR.DetailLevel.Low: mesherLod /= 4; break; } PrimMesher.SculptMesh newMesh = new PrimMesher.SculptMesh(scupltTexture, smSculptType, mesherLod, true, prim.Sculpt.Mirror, prim.Sculpt.Invert); int numPrimFaces = 1; // a scuplty has only one face // copy the vertex information into OMVR.IRendering structures OMVR.FacetedMesh omvrmesh = new OMVR.FacetedMesh(); omvrmesh.Faces = new List<OMVR.Face>(); omvrmesh.Prim = prim; omvrmesh.Profile = new OMVR.Profile(); omvrmesh.Profile.Faces = new List<OMVR.ProfileFace>(); omvrmesh.Profile.Positions = new List<OMV.Vector3>(); omvrmesh.Path = new OMVR.Path(); omvrmesh.Path.Points = new List<OMVR.PathPoint>(); Dictionary<OMVR.Vertex, int> vertexAccount = new Dictionary<OMVR.Vertex, int>(); for (int ii = 0; ii < numPrimFaces; ii++) { vertexAccount.Clear(); OMVR.Face oface = new OMVR.Face(); oface.Vertices = new List<OMVR.Vertex>(); oface.Indices = new List<ushort>(); oface.TextureFace = prim.Textures.GetFace((uint)ii); int faceVertices = newMesh.coords.Count; OMVR.Vertex vert; for (int j = 0; j < faceVertices; j++) { vert = new OMVR.Vertex(); vert.Position = new Vector3(newMesh.coords[j].X, newMesh.coords[j].Y, newMesh.coords[j].Z); vert.Normal = new Vector3(newMesh.normals[j].X, newMesh.normals[j].Y, newMesh.normals[j].Z); vert.TexCoord = new Vector2(newMesh.uvs[j].U, newMesh.uvs[j].V); oface.Vertices.Add(vert); } for (int j = 0; j < newMesh.faces.Count; j++) { oface.Indices.Add((ushort)newMesh.faces[j].v1); oface.Indices.Add((ushort)newMesh.faces[j].v2); oface.Indices.Add((ushort)newMesh.faces[j].v3); } if (faceVertices > 0) { oface.TextureFace = prim.Textures.FaceTextures[ii]; if (oface.TextureFace == null) { oface.TextureFace = prim.Textures.DefaultTexture; } oface.ID = ii; omvrmesh.Faces.Add(oface); } } return omvrmesh; }
/// <summary> /// Generates a a series of faces, each face containing a mesh and /// metadata /// </summary> /// <param name="prim">Primitive to generate the mesh from</param> /// <param name="lod">Level of detail to generate the mesh at</param> /// <returns>The generated mesh</returns > public OMVR.FacetedMesh GenerateFacetedMesh(OMV.Primitive prim, OMVR.DetailLevel lod) { bool isSphere = ((OMV.ProfileCurve)(prim.PrimData.profileCurve & 0x07) == OMV.ProfileCurve.HalfCircle); PrimMesher.PrimMesh newPrim = GeneratePrimMesh(prim, lod, true); if (newPrim == null) return null; int numViewerFaces = newPrim.viewerFaces.Count; int numPrimFaces = newPrim.numPrimFaces; for (uint i = 0; i < numViewerFaces; i++) { PrimMesher.ViewerFace vf = newPrim.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; } } // copy the vertex information into OMVR.IRendering structures OMVR.FacetedMesh omvrmesh = new OMVR.FacetedMesh(); omvrmesh.Faces = new List<OMVR.Face>(); omvrmesh.Prim = prim; omvrmesh.Profile = new OMVR.Profile(); omvrmesh.Profile.Faces = new List<OMVR.ProfileFace>(); omvrmesh.Profile.Positions = new List<OMV.Vector3>(); omvrmesh.Path = new OMVR.Path(); omvrmesh.Path.Points = new List<OMVR.PathPoint>(); Dictionary<OMV.Vector3, int> vertexAccount = new Dictionary<OMV.Vector3, int>(); for (int ii = 0; ii < numPrimFaces; ii++) { OMVR.Face oface = new OMVR.Face(); oface.Vertices = new List<OMVR.Vertex>(); oface.Indices = new List<ushort>(); oface.TextureFace = prim.Textures.GetFace((uint)ii); int faceVertices = 0; vertexAccount.Clear(); OMV.Vector3 pos; int indx; OMVR.Vertex vert; foreach (PrimMesher.ViewerFace vface in newPrim.viewerFaces) { if (vface.primFaceNumber == ii) { faceVertices++; pos = new OMV.Vector3(vface.v1.X, vface.v1.Y, vface.v1.Z); if (vertexAccount.ContainsKey(pos)) { // we aleady have this vertex in the list. Just point the index at it oface.Indices.Add((ushort)vertexAccount[pos]); } else { // the vertex is not in the list. Add it and the new index. vert = new OMVR.Vertex(); vert.Position = pos; vert.TexCoord = new OMV.Vector2(vface.uv1.U, 1.0f - vface.uv1.V); vert.Normal = new OMV.Vector3(vface.n1.X, vface.n1.Y, vface.n1.Z); oface.Vertices.Add(vert); indx = oface.Vertices.Count - 1; vertexAccount.Add(pos, indx); oface.Indices.Add((ushort)indx); } pos = new OMV.Vector3(vface.v2.X, vface.v2.Y, vface.v2.Z); if (vertexAccount.ContainsKey(pos)) { oface.Indices.Add((ushort)vertexAccount[pos]); } else { vert = new OMVR.Vertex(); vert.Position = pos; vert.TexCoord = new OMV.Vector2(vface.uv2.U, 1.0f - vface.uv2.V); vert.Normal = new OMV.Vector3(vface.n2.X, vface.n2.Y, vface.n2.Z); oface.Vertices.Add(vert); indx = oface.Vertices.Count - 1; vertexAccount.Add(pos, indx); oface.Indices.Add((ushort)indx); } pos = new OMV.Vector3(vface.v3.X, vface.v3.Y, vface.v3.Z); if (vertexAccount.ContainsKey(pos)) { oface.Indices.Add((ushort)vertexAccount[pos]); } else { vert = new OMVR.Vertex(); vert.Position = pos; vert.TexCoord = new OMV.Vector2(vface.uv3.U, 1.0f - vface.uv3.V); vert.Normal = new OMV.Vector3(vface.n3.X, vface.n3.Y, vface.n3.Z); oface.Vertices.Add(vert); indx = oface.Vertices.Count - 1; vertexAccount.Add(pos, indx); oface.Indices.Add((ushort)indx); } } } if (faceVertices > 0) { oface.TextureFace = prim.Textures.FaceTextures[ii]; if (oface.TextureFace == null) { oface.TextureFace = prim.Textures.DefaultTexture; } oface.ID = ii; omvrmesh.Faces.Add(oface); } } return omvrmesh; }
/// <summary> /// Generates a a series of faces, each face containing a mesh and /// metadata /// </summary> /// <param name="prim">Primitive to generate the mesh from</param> /// <param name="lod">Level of detail to generate the mesh at</param> /// <returns>The generated mesh</returns > public OMVR.FacetedMesh GenerateFacetedMesh(OMV.Primitive prim, OMVR.DetailLevel lod) { bool isSphere = ((OMV.ProfileCurve)(prim.PrimData.profileCurve & 0x07) == OMV.ProfileCurve.HalfCircle); PrimMesher.PrimMesh newPrim = GeneratePrimMesh(prim, lod, true); if (newPrim == null) return null; // copy the vertex information into OMVR.IRendering structures OMVR.FacetedMesh omvrmesh = new OMVR.FacetedMesh(); omvrmesh.Faces = new List<OMVR.Face>(); omvrmesh.Prim = prim; omvrmesh.Profile = new OMVR.Profile(); omvrmesh.Profile.Faces = new List<OMVR.ProfileFace>(); omvrmesh.Profile.Positions = new List<OMV.Vector3>(); omvrmesh.Path = new OMVR.Path(); omvrmesh.Path.Points = new List<OMVR.PathPoint>(); var indexer = newPrim.GetVertexIndexer(); for (int i = 0; i < indexer.numPrimFaces; i++) { OMVR.Face oface = new OMVR.Face(); oface.Vertices = new List<OMVR.Vertex>(); oface.Indices = new List<ushort>(); oface.TextureFace = prim.Textures.GetFace((uint)i); for (int j = 0; j < indexer.viewerVertices[i].Count; j++) { var vert = new OMVR.Vertex(); var m = indexer.viewerVertices[i][j]; vert.Position = new Vector3(m.v.X, m.v.Y, m.v.Z); vert.Normal = new Vector3(m.n.X, m.n.Y, m.n.Z); vert.TexCoord = new OMV.Vector2(m.uv.U, 1.0f - m.uv.V); oface.Vertices.Add(vert); } for (int j = 0; j < indexer.viewerPolygons[i].Count; j++) { var p = indexer.viewerPolygons[i][j]; // Skip "degenerate faces" where the same vertex appears twice in the same tri if (p.v1 == p.v2 || p.v1 == p.v2 || p.v2 == p.v3) continue; oface.Indices.Add((ushort)p.v1); oface.Indices.Add((ushort)p.v2); oface.Indices.Add((ushort)p.v3); } omvrmesh.Faces.Add(oface); } return omvrmesh; }
/// <summary> /// Create a sculpty faceted mesh. The actual scuplt texture is fetched and passed to this /// routine since all the context for finding teh texture is elsewhere. /// </summary> /// <returns>The faceted mesh or null if can't do it</returns> public OMVR.FacetedMesh GenerateFacetedSculptMesh(OMV.Primitive prim, System.Drawing.Bitmap scupltTexture, OMVR.DetailLevel lod) { byte sculptType = (byte)prim.Sculpt.Type; bool mirror = ((sculptType & 128) != 0); bool invert = ((sculptType & 64) != 0); // mirror = false; // TODO: libomv doesn't support these and letting them flop around causes problems // invert = false; OMV.SculptType omSculptType = (OMV.SculptType)(sculptType & 0x07); PrimMesher.SculptMesh.SculptType smSculptType; switch (omSculptType) { case OpenMetaverse.SculptType.Cylinder: smSculptType = PrimMesher.SculptMesh.SculptType.cylinder; break; case OpenMetaverse.SculptType.Plane: smSculptType = PrimMesher.SculptMesh.SculptType.plane; break; case OpenMetaverse.SculptType.Sphere: smSculptType = PrimMesher.SculptMesh.SculptType.sphere; break; case OpenMetaverse.SculptType.Torus: smSculptType = PrimMesher.SculptMesh.SculptType.torus; break; default: smSculptType = PrimMesher.SculptMesh.SculptType.plane; break; } // The lod for sculpties is the resolution of the texture passed. // The first guess is 1:1 then lower resolutions after that // int mesherLod = (int)Math.Sqrt(scupltTexture.Width * scupltTexture.Height); int mesherLod = 32; // number used in Idealist viewer switch (lod) { case OMVR.DetailLevel.Highest: break; case OMVR.DetailLevel.High: break; case OMVR.DetailLevel.Medium: mesherLod /= 2; break; case OMVR.DetailLevel.Low: mesherLod /= 4; break; } PrimMesher.SculptMesh newMesh = new PrimMesher.SculptMesh(scupltTexture, smSculptType, mesherLod, true, mirror, invert); int numPrimFaces = 1; // a scuplty has only one face // copy the vertex information into OMVR.IRendering structures OMVR.FacetedMesh omvrmesh = new OMVR.FacetedMesh(); omvrmesh.Faces = new List<OMVR.Face>(); omvrmesh.Prim = prim; omvrmesh.Profile = new OMVR.Profile(); omvrmesh.Profile.Faces = new List<OMVR.ProfileFace>(); omvrmesh.Profile.Positions = new List<OMV.Vector3>(); omvrmesh.Path = new OMVR.Path(); omvrmesh.Path.Points = new List<OMVR.PathPoint>(); for (int ii = 0; ii < numPrimFaces; ii++) { OMVR.Face oface = new OMVR.Face(); oface.Vertices = new List<OMVR.Vertex>(); oface.Indices = new List<ushort>(); oface.TextureFace = prim.Textures.GetFace((uint)ii); int faceVertices = 0; foreach (PrimMesher.ViewerFace vface in newMesh.viewerFaces) { OMVR.Vertex vert = new OMVR.Vertex(); vert.Position = new OMV.Vector3(vface.v1.X, vface.v1.Y, vface.v1.Z); vert.TexCoord = new OMV.Vector2(vface.uv1.U, 1.0f - vface.uv1.V); vert.Normal = new OMV.Vector3(vface.n1.X, vface.n1.Y, vface.n1.Z); oface.Vertices.Add(vert); vert = new OMVR.Vertex(); vert.Position = new OMV.Vector3(vface.v2.X, vface.v2.Y, vface.v2.Z); vert.TexCoord = new OMV.Vector2(vface.uv2.U, 1.0f - vface.uv2.V); vert.Normal = new OMV.Vector3(vface.n2.X, vface.n2.Y, vface.n2.Z); oface.Vertices.Add(vert); vert = new OMVR.Vertex(); vert.Position = new OMV.Vector3(vface.v3.X, vface.v3.Y, vface.v3.Z); vert.TexCoord = new OMV.Vector2(vface.uv3.U, 1.0f - vface.uv3.V); vert.Normal = new OMV.Vector3(vface.n3.X, vface.n3.Y, vface.n3.Z); oface.Vertices.Add(vert); oface.Indices.Add((ushort)(faceVertices * 3 + 0)); oface.Indices.Add((ushort)(faceVertices * 3 + 1)); oface.Indices.Add((ushort)(faceVertices * 3 + 2)); faceVertices++; } if (faceVertices > 0) { oface.TextureFace = prim.Textures.FaceTextures[ii]; if (oface.TextureFace == null) { oface.TextureFace = prim.Textures.DefaultTexture; } oface.ID = ii; omvrmesh.Faces.Add(oface); } } return omvrmesh; }
private PrimMesher.PrimMesh GeneratePrimMesh(OMV.Primitive prim, OMVR.DetailLevel lod, bool viewerMode) { OMV.Primitive.ConstructionData primData = prim.PrimData; int sides = 4; int hollowsides = 4; float profileBegin = primData.ProfileBegin; float profileEnd = primData.ProfileEnd; if ((OMV.ProfileCurve)(primData.profileCurve & 0x07) == OMV.ProfileCurve.Circle) { switch (lod) { case OMVR.DetailLevel.Low: sides = 6; break; case OMVR.DetailLevel.Medium: sides = 12; break; default: sides = 24; break; } } else if ((OMV.ProfileCurve)(primData.profileCurve & 0x07) == OMV.ProfileCurve.EqualTriangle) sides = 3; else if ((OMV.ProfileCurve)(primData.profileCurve & 0x07) == OMV.ProfileCurve.HalfCircle) { // half circle, prim is a sphere switch (lod) { case OMVR.DetailLevel.Low: sides = 6; break; case OMVR.DetailLevel.Medium: sides = 12; break; default: sides = 24; break; } profileBegin = 0.5f * profileBegin + 0.5f; profileEnd = 0.5f * profileEnd + 0.5f; } if ((OMV.HoleType)primData.ProfileHole == OMV.HoleType.Same) hollowsides = sides; else if ((OMV.HoleType)primData.ProfileHole == OMV.HoleType.Circle) { switch (lod) { case OMVR.DetailLevel.Low: hollowsides = 6; break; case OMVR.DetailLevel.Medium: hollowsides = 12; break; default: hollowsides = 24; break; } } else if ((OMV.HoleType)primData.ProfileHole == OMV.HoleType.Triangle) hollowsides = 3; PrimMesher.PrimMesh newPrim = new PrimMesher.PrimMesh(sides, profileBegin, profileEnd, (float)primData.ProfileHollow, hollowsides); newPrim.viewerMode = viewerMode; newPrim.holeSizeX = primData.PathScaleX; newPrim.holeSizeY = primData.PathScaleY; newPrim.pathCutBegin = primData.PathBegin; newPrim.pathCutEnd = primData.PathEnd; newPrim.topShearX = primData.PathShearX; newPrim.topShearY = primData.PathShearY; newPrim.radius = primData.PathRadiusOffset; newPrim.revolutions = primData.PathRevolutions; newPrim.skew = primData.PathSkew; switch (lod) { case OMVR.DetailLevel.Low: newPrim.stepsPerRevolution = 6; break; case OMVR.DetailLevel.Medium: newPrim.stepsPerRevolution = 12; break; default: newPrim.stepsPerRevolution = 24; break; } if ((primData.PathCurve == OMV.PathCurve.Line) || (primData.PathCurve == OMV.PathCurve.Flexible)) { newPrim.taperX = 1.0f - primData.PathScaleX; newPrim.taperY = 1.0f - primData.PathScaleY; newPrim.twistBegin = (int)(180 * primData.PathTwistBegin); newPrim.twistEnd = (int)(180 * primData.PathTwist); newPrim.ExtrudeLinear(); } else { newPrim.taperX = primData.PathTaperX; newPrim.taperY = primData.PathTaperY; newPrim.twistBegin = (int)(360 * primData.PathTwistBegin); newPrim.twistEnd = (int)(360 * primData.PathTwist); newPrim.ExtrudeCircular(); } return newPrim; }
/// <summary> /// Generates a sculpt mesh structure from a primitive /// </summary> /// <param name="prim">Primitive to generate the mesh from</param> /// <param name="lod">Level of detail to generate the mesh at</param> /// <returns>The generated mesh</returns> public OMVR.SimpleMesh GenerateSimpleSculptMesh(OMV.Primitive prim, Bitmap bits, OMVR.DetailLevel lod) { OMVR.FacetedMesh faceted = GenerateFacetedSculptMesh(prim, bits, lod); if (faceted != null && faceted.Faces.Count == 1) { OMVR.Face face = faceted.Faces[0]; OMVR.SimpleMesh mesh = new OMVR.SimpleMesh(); mesh.Indices = face.Indices; mesh.Vertices = face.Vertices; mesh.Path = faceted.Path; mesh.Prim = prim; mesh.Profile = faceted.Profile; mesh.Vertices = face.Vertices; return mesh; } return null; }
/// <summary> /// Create a sculpty faceted mesh. The actual scuplt texture is fetched and passed to this /// routine since all the context for finding teh texture is elsewhere. /// </summary> /// <param name="scupltTexture"></param> /// <param name="prim"></param> /// <param name="lod"></param> /// <returns>the faceted mesh or null if can't do it</returns> public OMVR.FacetedMesh GenerateSculptMesh(System.Drawing.Bitmap scupltTexture, OMV.Primitive prim, OMVR.DetailLevel lod) { try { byte sculptType = (byte)prim.Sculpt.Type; bool mirror = ((sculptType & 128) != 0); bool invert = ((sculptType & 64) != 0); // bool mirror = false; // TODO: libomv doesn't support these and letting them flop around causes problems // bool invert = false; OMV.SculptType omSculptType = (OMV.SculptType)(sculptType & 0x07); PrimMesher.SculptMesh.SculptType smSculptType; switch (omSculptType) { case OpenMetaverse.SculptType.Cylinder: smSculptType = PrimMesher.SculptMesh.SculptType.cylinder; break; case OpenMetaverse.SculptType.Plane: smSculptType = PrimMesher.SculptMesh.SculptType.plane; break; case OpenMetaverse.SculptType.Sphere: smSculptType = PrimMesher.SculptMesh.SculptType.sphere; break; case OpenMetaverse.SculptType.Torus: smSculptType = PrimMesher.SculptMesh.SculptType.torus; break; default: smSculptType = PrimMesher.SculptMesh.SculptType.plane; break; } // The lod for sculpties is the resolution of the texture passed. // The first guess is 1:1 then lower resolutions after that // int mesherLod = (int)Math.Sqrt(scupltTexture.Width * scupltTexture.Height); int mesherLod = 32; // number used in Idealist viewer switch (lod) { case OMVR.DetailLevel.Highest: break; case OMVR.DetailLevel.High: break; case OMVR.DetailLevel.Medium: mesherLod /= 2; break; case OMVR.DetailLevel.Low: mesherLod /= 4; break; } PrimMesher.SculptMesh newMesh = new PrimMesher.SculptMesh(scupltTexture, smSculptType, mesherLod, true, mirror, invert); if (ShouldScaleMesh) { newMesh.Scale(prim.Scale.X, prim.Scale.Y, prim.Scale.Z); } int numPrimFaces = 1; // a scuplty has only one face return GenerateIRendererMesh(numPrimFaces, prim, newMesh.viewerFaces); } catch { // don't know why we're here but tell the caller nothing was meshed return null; } }
/// <summary> /// Generates a basic mesh structure from a primitive /// </summary> /// <param name="prim">Primitive to generate the mesh from</param> /// <param name="lod">Level of detail to generate the mesh at</param> /// <returns>The generated mesh or null on failure</returns> public OMVR.SimpleMesh GenerateSimpleMesh(OMV.Primitive prim, OMVR.DetailLevel lod) { // FIXME: Implement this return null; }
/// <summary> /// Generates a a series of faces, each face containing a mesh and /// metadata /// </summary> /// <param name="prim">Primitive to generate the mesh from</param> /// <param name="lod">Level of detail to generate the mesh at</param> /// <returns>The generated mesh</returns > public OMVR.FacetedMesh GenerateFacetedMesh(OMV.Primitive prim, OMVR.DetailLevel lod) { OMV.Primitive.ConstructionData primData = prim.PrimData; int sides = 4; int hollowsides = 4; float profileBegin = primData.ProfileBegin; float profileEnd = primData.ProfileEnd; bool isSphere = false; if ((OMV.ProfileCurve)(primData.profileCurve & 0x07) == OMV.ProfileCurve.Circle) { switch (lod) { case OMVR.DetailLevel.Low: sides = 6; break; case OMVR.DetailLevel.Medium: sides = 12; break; default: sides = 24; break; } } else if ((OMV.ProfileCurve)(primData.profileCurve & 0x07) == OMV.ProfileCurve.EqualTriangle) sides = 3; else if ((OMV.ProfileCurve)(primData.profileCurve & 0x07) == OMV.ProfileCurve.HalfCircle) { // half circle, prim is a sphere isSphere = true; switch (lod) { case OMVR.DetailLevel.Low: sides = 6; break; case OMVR.DetailLevel.Medium: sides = 12; break; default: sides = 24; break; } profileBegin = 0.5f * profileBegin + 0.5f; profileEnd = 0.5f * profileEnd + 0.5f; } if ((OMV.HoleType)primData.ProfileHole == OMV.HoleType.Same) hollowsides = sides; else if ((OMV.HoleType)primData.ProfileHole == OMV.HoleType.Circle) { switch (lod) { case OMVR.DetailLevel.Low: hollowsides = 6; break; case OMVR.DetailLevel.Medium: hollowsides = 12; break; default: hollowsides = 24; break; } } else if ((OMV.HoleType)primData.ProfileHole == OMV.HoleType.Triangle) hollowsides = 3; PrimMesher.PrimMesh newPrim = new PrimMesher.PrimMesh(sides, profileBegin, profileEnd, (float)primData.ProfileHollow, hollowsides); newPrim.viewerMode = true; newPrim.holeSizeX = primData.PathScaleX; newPrim.holeSizeY = primData.PathScaleY; newPrim.pathCutBegin = primData.PathBegin; newPrim.pathCutEnd = primData.PathEnd; newPrim.topShearX = primData.PathShearX; newPrim.topShearY = primData.PathShearY; newPrim.radius = primData.PathRadiusOffset; newPrim.revolutions = primData.PathRevolutions; newPrim.skew = primData.PathSkew; switch (lod) { case OMVR.DetailLevel.Low: newPrim.stepsPerRevolution = 6; break; case OMVR.DetailLevel.Medium: newPrim.stepsPerRevolution = 12; break; default: newPrim.stepsPerRevolution = 24; break; } if ((primData.PathCurve == OMV.PathCurve.Line) || (primData.PathCurve == OMV.PathCurve.Flexible)) { newPrim.taperX = 1.0f - primData.PathScaleX; newPrim.taperY = 1.0f - primData.PathScaleY; newPrim.twistBegin = (int)(180 * primData.PathTwistBegin); newPrim.twistEnd = (int)(180 * primData.PathTwist); newPrim.ExtrudeLinear(); } else { newPrim.taperX = primData.PathTaperX; newPrim.taperY = primData.PathTaperY; newPrim.twistBegin = (int)(360 * primData.PathTwistBegin); newPrim.twistEnd = (int)(360 * primData.PathTwist); newPrim.ExtrudeCircular(); } int numViewerFaces = newPrim.viewerFaces.Count; int numPrimFaces = newPrim.numPrimFaces; for (uint i = 0; i < numViewerFaces; i++) { PrimMesher.ViewerFace vf = newPrim.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; } } if (m_shouldScale) { newPrim.Scale(prim.Scale.X, prim.Scale.Y, prim.Scale.Z); } // copy the vertex information into OMVR.IRendering structures OMVR.FacetedMesh omvrmesh = new OMVR.FacetedMesh(); omvrmesh.Faces = new List<OMVR.Face>(); omvrmesh.Prim = prim; omvrmesh.Profile = new OMVR.Profile(); omvrmesh.Profile.Faces = new List<OMVR.ProfileFace>(); omvrmesh.Profile.Positions = new List<OMV.Vector3>(); omvrmesh.Path = new OMVR.Path(); omvrmesh.Path.Points = new List<OMVR.PathPoint>(); Dictionary<OMV.Vector3, int> vertexAccount = new Dictionary<OMV.Vector3, int>(); for (int ii = 0; ii < numPrimFaces; ii++) { OMVR.Face oface = new OMVR.Face(); oface.Vertices = new List<OMVR.Vertex>(); oface.Indices = new List<ushort>(); oface.TextureFace = prim.Textures.GetFace((uint)ii); int faceVertices = 0; vertexAccount.Clear(); OMV.Vector3 pos; int indx; OMVR.Vertex vert; foreach (PrimMesher.ViewerFace vface in newPrim.viewerFaces) { if (vface.primFaceNumber == ii) { faceVertices++; pos = new OMV.Vector3(vface.v1.X, vface.v1.Y, vface.v1.Z); if (vertexAccount.ContainsKey(pos)) { // we aleady have this vertex in the list. Just point the index at it oface.Indices.Add((ushort)vertexAccount[pos]); } else { // the vertex is not in the list. Add it and the new index. vert = new OMVR.Vertex(); vert.Position = pos; vert.TexCoord = new OMV.Vector2(vface.uv1.U, 1.0f - vface.uv1.V); vert.Normal = new OMV.Vector3(vface.n1.X, vface.n1.Y, vface.n1.Z); oface.Vertices.Add(vert); indx = oface.Vertices.Count - 1; vertexAccount.Add(pos, indx); oface.Indices.Add((ushort)indx); } pos = new OMV.Vector3(vface.v2.X, vface.v2.Y, vface.v2.Z); if (vertexAccount.ContainsKey(pos)) { oface.Indices.Add((ushort)vertexAccount[pos]); } else { vert = new OMVR.Vertex(); vert.Position = pos; vert.TexCoord = new OMV.Vector2(vface.uv2.U, 1.0f - vface.uv2.V); vert.Normal = new OMV.Vector3(vface.n2.X, vface.n2.Y, vface.n2.Z); oface.Vertices.Add(vert); indx = oface.Vertices.Count - 1; vertexAccount.Add(pos, indx); oface.Indices.Add((ushort)indx); } pos = new OMV.Vector3(vface.v3.X, vface.v3.Y, vface.v3.Z); if (vertexAccount.ContainsKey(pos)) { oface.Indices.Add((ushort)vertexAccount[pos]); } else { vert = new OMVR.Vertex(); vert.Position = pos; vert.TexCoord = new OMV.Vector2(vface.uv3.U, 1.0f - vface.uv3.V); vert.Normal = new OMV.Vector3(vface.n3.X, vface.n3.Y, vface.n3.Z); oface.Vertices.Add(vert); indx = oface.Vertices.Count - 1; vertexAccount.Add(pos, indx); oface.Indices.Add((ushort)indx); } } } if (faceVertices > 0) { oface.TextureFace = prim.Textures.FaceTextures[ii]; if (oface.TextureFace == null) { oface.TextureFace = prim.Textures.DefaultTexture; } oface.ID = ii; omvrmesh.Faces.Add(oface); } } return omvrmesh; }
/// <summary> /// Generates a basic mesh structure from a primitive /// </summary> /// <param name="prim">Primitive to generate the mesh from</param> /// <param name="lod">Level of detail to generate the mesh at</param> /// <returns>The generated mesh</returns> public OMVR.SimpleMesh GenerateSimpleMesh(OMV.Primitive prim, OMVR.DetailLevel lod) { return null; }