From 82554e9a89e4ca39c1522d539862f9fd6a2f2a7e Mon Sep 17 00:00:00 2001 From: dahlia Date: Mon, 2 Nov 2009 22:24:58 -0800 Subject: [PATCH] Delete depricated extrusion methods and redirect to universal extrude method. Sync with PrimMesher.cs r47 on forge. --- OpenSim/Region/Physics/Meshing/PrimMesher.cs | 843 +------------------ 1 file changed, 10 insertions(+), 833 deletions(-) diff --git a/OpenSim/Region/Physics/Meshing/PrimMesher.cs b/OpenSim/Region/Physics/Meshing/PrimMesher.cs index 47ce615224..c7c9160fad 100644 --- a/OpenSim/Region/Physics/Meshing/PrimMesher.cs +++ b/OpenSim/Region/Physics/Meshing/PrimMesher.cs @@ -67,11 +67,6 @@ namespace PrimMesher Normalize(); } - public Quat Identity() - { - return new Quat(0.0f, 0.0f, 0.0f, 1.0f); - } - public float Length() { return (float)Math.Sqrt(X * X + Y * Y + Z * Z + W * W); @@ -660,7 +655,7 @@ namespace PrimMesher this.faceNumbers = new List(); Coord center = new Coord(0.0f, 0.0f, 0.0f); - bool hasCenter = false; + //bool hasCenter = false; List hollowCoords = new List(); List hollowNormals = new List(); @@ -727,7 +722,7 @@ namespace PrimMesher else if (!simpleFace) { this.coords.Add(center); - hasCenter = true; + //hasCenter = true; if (this.calcVertexNormals) this.vertexNormals.Add(new Coord(0.0f, 0.0f, 1.0f)); this.us.Add(0.0f); @@ -1541,7 +1536,7 @@ namespace PrimMesher } /// - /// Extrudes a profile along a straight line path. Used for prim types box, cylinder, and prism. + /// Extrudes a profile along a path. /// public void Extrude(PathType pathType) { @@ -1557,7 +1552,6 @@ namespace PrimMesher if (this.calcVertexNormals) this.normals = new List(); - //int step = 0; int steps = 1; float length = this.pathCutEnd - this.pathCutBegin; @@ -1579,20 +1573,6 @@ namespace PrimMesher if (twistTotalAbs > 0.01f) steps += (int)(twistTotalAbs * 3.66); // dahlia's magic number - //float start = -0.5f; - //float stepSize = length / (float)steps; - //float percentOfPathMultiplier = stepSize; - //float xProfileScale = 1.0f; - //float yProfileScale = 1.0f; - //float xOffset = 0.0f; - //float yOffset = 0.0f; - //float zOffset = start; - //float xOffsetStepIncrement = this.topShearX / steps; - //float yOffsetStepIncrement = this.topShearY / steps; - - //float percentOfPath = this.pathCutBegin; - //zOffset += percentOfPath; - float hollow = this.hollow; // sanity checks @@ -1662,7 +1642,6 @@ namespace PrimMesher cut2Vert = hasHollow ? profile.numOuterVerts - 1 : profile.numOuterVerts; } - if (initialProfileRot != 0.0f) { profile.AddRot(new Quat(new Coord(0.0f, 0.0f, 1.0f), initialProfileRot)); @@ -1693,24 +1672,6 @@ namespace PrimMesher path.stepsPerRevolution = stepsPerRevolution; path.Create(pathType, steps); - /* - public int twistBegin = 0; - public int twistEnd = 0; - public float topShearX = 0.0f; - public float topShearY = 0.0f; - public float pathCutBegin = 0.0f; - public float pathCutEnd = 1.0f; - public float dimpleBegin = 0.0f; - public float dimpleEnd = 1.0f; - public float skew = 0.0f; - public float holeSizeX = 1.0f; // called pathScaleX in pbs - public float holeSizeY = 0.25f; - public float taperX = 0.0f; - public float taperY = 0.0f; - public float radius = 0.0f; - public float revolutions = 1.0f; - public int stepsPerRevolution = 24; - */ bool needEndFaces = false; if (pathType == PathType.Circular) @@ -1796,7 +1757,6 @@ namespace PrimMesher int numVerts = newLayer.coords.Count; Face newFace = new Face(); - //if (step > 0) if (nodeIndex > 0) { int startVert = coordsLen + 1; @@ -1812,7 +1772,6 @@ namespace PrimMesher iNext = startVert; int whichVert = i - startVert; - //int whichVert2 = i - lastCoordsLen; newFace.v1 = i; newFace.v2 = i - numVerts; @@ -1982,809 +1941,27 @@ namespace PrimMesher /// + /// DEPRICATED - use Extrude(PathType.Linear) instead /// Extrudes a profile along a straight line path. Used for prim types box, cylinder, and prism. /// + /// public void ExtrudeLinear() { - this.coords = new List(); - this.faces = new List(); - - if (this.viewerMode) - { - this.viewerFaces = new List(); - this.calcVertexNormals = true; - } - - if (this.calcVertexNormals) - this.normals = new List(); - - int step = 0; - int steps = 1; - - float length = this.pathCutEnd - this.pathCutBegin; - normalsProcessed = false; - - if (this.viewerMode && this.sides == 3) - { - // prisms don't taper well so add some vertical resolution - // other prims may benefit from this but just do prisms for now - if (Math.Abs(this.taperX) > 0.01 || Math.Abs(this.taperY) > 0.01) - steps = (int)(steps * 4.5 * length); - } - - - float twistBegin = this.twistBegin / 360.0f * twoPi; - float twistEnd = this.twistEnd / 360.0f * twoPi; - float twistTotal = twistEnd - twistBegin; - float twistTotalAbs = Math.Abs(twistTotal); - if (twistTotalAbs > 0.01f) - steps += (int)(twistTotalAbs * 3.66); // dahlia's magic number - - float start = -0.5f; - float stepSize = length / (float)steps; - float percentOfPathMultiplier = stepSize; - float xProfileScale = 1.0f; - float yProfileScale = 1.0f; - float xOffset = 0.0f; - float yOffset = 0.0f; - float zOffset = start; - float xOffsetStepIncrement = this.topShearX / steps; - float yOffsetStepIncrement = this.topShearY / steps; - - float percentOfPath = this.pathCutBegin; - zOffset += percentOfPath; - - float hollow = this.hollow; - - // sanity checks - float initialProfileRot = 0.0f; - if (this.sides == 3) - { - if (this.hollowSides == 4) - { - if (hollow > 0.7f) - hollow = 0.7f; - hollow *= 0.707f; - } - else hollow *= 0.5f; - } - else if (this.sides == 4) - { - initialProfileRot = 1.25f * (float)Math.PI; - if (this.hollowSides != 4) - hollow *= 0.707f; - } - else if (this.sides == 24 && this.hollowSides == 4) - hollow *= 1.414f; - - Profile profile = new Profile(this.sides, this.profileStart, this.profileEnd, hollow, this.hollowSides, true, calcVertexNormals); - this.errorMessage = profile.errorMessage; - - this.numPrimFaces = profile.numPrimFaces; - - int cut1Vert = -1; - int cut2Vert = -1; - if (hasProfileCut) - { - cut1Vert = hasHollow ? profile.coords.Count - 1 : 0; - cut2Vert = hasHollow ? profile.numOuterVerts - 1 : profile.numOuterVerts; - } - - if (initialProfileRot != 0.0f) - { - profile.AddRot(new Quat(new Coord(0.0f, 0.0f, 1.0f), initialProfileRot)); - if (viewerMode) - profile.MakeFaceUVs(); - } - - Coord lastCutNormal1 = new Coord(); - Coord lastCutNormal2 = new Coord(); - float lastV = 1.0f; - - bool done = false; - while (!done) - { - Profile newLayer = profile.Copy(); - - if (this.taperX == 0.0f) - xProfileScale = 1.0f; - else if (this.taperX > 0.0f) - xProfileScale = 1.0f - percentOfPath * this.taperX; - else xProfileScale = 1.0f + (1.0f - percentOfPath) * this.taperX; - - if (this.taperY == 0.0f) - yProfileScale = 1.0f; - else if (this.taperY > 0.0f) - yProfileScale = 1.0f - percentOfPath * this.taperY; - else yProfileScale = 1.0f + (1.0f - percentOfPath) * this.taperY; - - if (xProfileScale != 1.0f || yProfileScale != 1.0f) - newLayer.Scale(xProfileScale, yProfileScale); - - float twist = twistBegin + twistTotal * percentOfPath; - if (twist != 0.0f) - newLayer.AddRot(new Quat(new Coord(0.0f, 0.0f, 1.0f), twist)); - - newLayer.AddPos(xOffset, yOffset, zOffset); - - if (step == 0) - { - newLayer.FlipNormals(); - - // add the top faces to the viewerFaces list here - if (this.viewerMode) - { - Coord faceNormal = newLayer.faceNormal; - ViewerFace newViewerFace = new ViewerFace(profile.bottomFaceNumber); - int numFaces = newLayer.faces.Count; - List faces = newLayer.faces; - - for (int i = 0; i < numFaces; i++) - { - Face face = faces[i]; - newViewerFace.v1 = newLayer.coords[face.v1]; - newViewerFace.v2 = newLayer.coords[face.v2]; - newViewerFace.v3 = newLayer.coords[face.v3]; - - newViewerFace.coordIndex1 = face.v1; - newViewerFace.coordIndex2 = face.v2; - newViewerFace.coordIndex3 = face.v3; - - newViewerFace.n1 = faceNormal; - newViewerFace.n2 = faceNormal; - newViewerFace.n3 = faceNormal; - - newViewerFace.uv1 = newLayer.faceUVs[face.v1]; - newViewerFace.uv2 = newLayer.faceUVs[face.v2]; - newViewerFace.uv3 = newLayer.faceUVs[face.v3]; - - this.viewerFaces.Add(newViewerFace); - } - } - } - - // append this layer - - int coordsLen = this.coords.Count; - int lastCoordsLen = coordsLen; - newLayer.AddValue2FaceVertexIndices(coordsLen); - - this.coords.AddRange(newLayer.coords); - - if (this.calcVertexNormals) - { - newLayer.AddValue2FaceNormalIndices(this.normals.Count); - this.normals.AddRange(newLayer.vertexNormals); - } - - if (percentOfPath < this.pathCutBegin + 0.01f || percentOfPath > this.pathCutEnd - 0.01f) - this.faces.AddRange(newLayer.faces); - - // fill faces between layers - - int numVerts = newLayer.coords.Count; - Face newFace = new Face(); - - if (step > 0) - { - int startVert = coordsLen + 1; - int endVert = this.coords.Count; - - if (sides < 5 || this.hasProfileCut || hollow > 0.0f) - startVert--; - - for (int i = startVert; i < endVert; i++) - { - int iNext = i + 1; - if (i == endVert - 1) - iNext = startVert; - - int whichVert = i - startVert; - //int whichVert2 = i - lastCoordsLen; - - newFace.v1 = i; - newFace.v2 = i - numVerts; - newFace.v3 = iNext - numVerts; - this.faces.Add(newFace); - - newFace.v2 = iNext - numVerts; - newFace.v3 = iNext; - this.faces.Add(newFace); - - if (this.viewerMode) - { - // add the side faces to the list of viewerFaces here - //int primFaceNum = 1; - //if (whichVert >= sides) - // primFaceNum = 2; - int primFaceNum = profile.faceNumbers[whichVert]; - - ViewerFace newViewerFace1 = new ViewerFace(primFaceNum); - ViewerFace newViewerFace2 = new ViewerFace(primFaceNum); - - float u1 = newLayer.us[whichVert]; - float u2 = 1.0f; - if (whichVert < newLayer.us.Count - 1) - u2 = newLayer.us[whichVert + 1]; - - if (whichVert == cut1Vert || whichVert == cut2Vert) - { - u1 = 0.0f; - u2 = 1.0f; - } - else if (sides < 5) - { // boxes and prisms have one texture face per side of the prim, so the U values have to be scaled - // to reflect the entire texture width - u1 *= sides; - u2 *= sides; - u2 -= (int)u1; - u1 -= (int)u1; - if (u2 < 0.1f) - u2 = 1.0f; - - //newViewerFace2.primFaceNumber = newViewerFace1.primFaceNumber = whichVert + 1; - } - - newViewerFace1.uv1.U = u1; - newViewerFace1.uv2.U = u1; - newViewerFace1.uv3.U = u2; - - newViewerFace1.uv1.V = 1.0f - percentOfPath; - newViewerFace1.uv2.V = lastV; - newViewerFace1.uv3.V = lastV; - - newViewerFace2.uv1.U = u1; - newViewerFace2.uv2.U = u2; - newViewerFace2.uv3.U = u2; - - newViewerFace2.uv1.V = 1.0f - percentOfPath; - newViewerFace2.uv2.V = lastV; - newViewerFace2.uv3.V = 1.0f - percentOfPath; - - newViewerFace1.v1 = this.coords[i]; - newViewerFace1.v2 = this.coords[i - numVerts]; - newViewerFace1.v3 = this.coords[iNext - numVerts]; - - newViewerFace2.v1 = this.coords[i]; - newViewerFace2.v2 = this.coords[iNext - numVerts]; - newViewerFace2.v3 = this.coords[iNext]; - - newViewerFace1.coordIndex1 = i; - newViewerFace1.coordIndex2 = i - numVerts; - newViewerFace1.coordIndex3 = iNext - numVerts; - - newViewerFace2.coordIndex1 = i; - newViewerFace2.coordIndex2 = iNext - numVerts; - newViewerFace2.coordIndex3 = iNext; - - // profile cut faces - if (whichVert == cut1Vert) - { - newViewerFace1.n1 = newLayer.cutNormal1; - newViewerFace1.n2 = newViewerFace1.n3 = lastCutNormal1; - - newViewerFace2.n1 = newViewerFace2.n3 = newLayer.cutNormal1; - newViewerFace2.n2 = lastCutNormal1; - } - else if (whichVert == cut2Vert) - { - newViewerFace1.n1 = newLayer.cutNormal2; - newViewerFace1.n2 = newViewerFace1.n3 = lastCutNormal2; - - newViewerFace2.n1 = newViewerFace2.n3 = newLayer.cutNormal2; - newViewerFace2.n2 = lastCutNormal2; - } - - else // outer and hollow faces - { - if ((sides < 5 && whichVert < newLayer.numOuterVerts) || (hollowSides < 5 && whichVert >= newLayer.numOuterVerts)) - { - newViewerFace1.CalcSurfaceNormal(); - newViewerFace2.CalcSurfaceNormal(); - } - else - { - newViewerFace1.n1 = this.normals[i]; - newViewerFace1.n2 = this.normals[i - numVerts]; - newViewerFace1.n3 = this.normals[iNext - numVerts]; - - newViewerFace2.n1 = this.normals[i]; - newViewerFace2.n2 = this.normals[iNext - numVerts]; - newViewerFace2.n3 = this.normals[iNext]; - } - } - - //newViewerFace2.primFaceNumber = newViewerFace1.primFaceNumber = newLayer.faceNumbers[whichVert]; - - this.viewerFaces.Add(newViewerFace1); - this.viewerFaces.Add(newViewerFace2); - - } - } - } - - lastCutNormal1 = newLayer.cutNormal1; - lastCutNormal2 = newLayer.cutNormal2; - lastV = 1.0f - percentOfPath; - - // calc the step for the next iteration of the loop - - if (step < steps) - { - step += 1; - percentOfPath += percentOfPathMultiplier; - xOffset += xOffsetStepIncrement; - yOffset += yOffsetStepIncrement; - zOffset += stepSize; - if (percentOfPath > this.pathCutEnd) - done = true; - } - else done = true; - - if (done && viewerMode) - { - // add the top faces to the viewerFaces list here - Coord faceNormal = newLayer.faceNormal; - ViewerFace newViewerFace = new ViewerFace(); - newViewerFace.primFaceNumber = 0; - int numFaces = newLayer.faces.Count; - List faces = newLayer.faces; - - for (int i = 0; i < numFaces; i++) - { - Face face = faces[i]; - newViewerFace.v1 = newLayer.coords[face.v1 - coordsLen]; - newViewerFace.v2 = newLayer.coords[face.v2 - coordsLen]; - newViewerFace.v3 = newLayer.coords[face.v3 - coordsLen]; - - newViewerFace.coordIndex1 = face.v1 - coordsLen; - newViewerFace.coordIndex2 = face.v2 - coordsLen; - newViewerFace.coordIndex3 = face.v3 - coordsLen; - - newViewerFace.n1 = faceNormal; - newViewerFace.n2 = faceNormal; - newViewerFace.n3 = faceNormal; - - newViewerFace.uv1 = newLayer.faceUVs[face.v1 - coordsLen]; - newViewerFace.uv2 = newLayer.faceUVs[face.v2 - coordsLen]; - newViewerFace.uv3 = newLayer.faceUVs[face.v3 - coordsLen]; - - this.viewerFaces.Add(newViewerFace); - } - } - } + this.Extrude(PathType.Linear); } /// + /// DEPRICATED - use Extrude(PathType.Circular) instead /// Extrude a profile into a circular path prim mesh. Used for prim types torus, tube, and ring. /// + /// public void ExtrudeCircular() { - this.coords = new List(); - this.faces = new List(); - - if (this.viewerMode) - { - this.viewerFaces = new List(); - this.calcVertexNormals = true; - } - - if (this.calcVertexNormals) - this.normals = new List(); - - int step = 0; - int steps = 24; - - normalsProcessed = false; - - float twistBegin = this.twistBegin / 360.0f * twoPi; - float twistEnd = this.twistEnd / 360.0f * twoPi; - float twistTotal = twistEnd - twistBegin; - - // 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); - if (twistTotalAbs > 0.01f) - { - if (twistTotalAbs > Math.PI * 1.5f) - steps *= 2; - if (twistTotalAbs > Math.PI * 3.0f) - steps *= 2; - } - - float yPathScale = this.holeSizeY * 0.5f; - float pathLength = this.pathCutEnd - this.pathCutBegin; - float totalSkew = this.skew * 2.0f * pathLength; - float skewStart = this.pathCutBegin * 2.0f * this.skew - this.skew; - float xOffsetTopShearXFactor = this.topShearX * (0.25f + 0.5f * (0.5f - this.holeSizeY)); - float yShearCompensation = 1.0f + Math.Abs(this.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 - // to calculate the sine for generating the path radius appears to approximate it's effects there - // too, but there are some subtle differences in the radius which are noticeable as the prim size - // increases and it may affect megaprims quite a bit. The effect of the Y top shear parameter on - // the meshes generated with this technique appear nearly identical in shape to the same prims when - // displayed by the viewer. - - float startAngle = (twoPi * this.pathCutBegin * this.revolutions) - this.topShearY * 0.9f; - float endAngle = (twoPi * this.pathCutEnd * this.revolutions) - this.topShearY * 0.9f; - float stepSize = twoPi / this.stepsPerRevolution; - - step = (int)(startAngle / stepSize); - int firstStep = step; - float angle = startAngle; - float hollow = this.hollow; - - // sanity checks - float initialProfileRot = 0.0f; - if (this.sides == 3) - { - initialProfileRot = (float)Math.PI; - if (this.hollowSides == 4) - { - if (hollow > 0.7f) - hollow = 0.7f; - hollow *= 0.707f; - } - else hollow *= 0.5f; - } - else if (this.sides == 4) - { - initialProfileRot = 0.25f * (float)Math.PI; - if (this.hollowSides != 4) - hollow *= 0.707f; - } - else if (this.sides > 4) - { - initialProfileRot = (float)Math.PI; - if (this.hollowSides == 4) - { - if (hollow > 0.7f) - hollow = 0.7f; - hollow /= 0.7f; - } - } - - bool needEndFaces = false; - if (this.pathCutBegin != 0.0f || this.pathCutEnd != 1.0f) - needEndFaces = true; - else if (this.taperX != 0.0f || this.taperY != 0.0f) - needEndFaces = true; - else if (this.skew != 0.0f) - needEndFaces = true; - else if (twistTotal != 0.0f) - needEndFaces = true; - else if (this.radius != 0.0f) - needEndFaces = true; - - Profile profile = new Profile(this.sides, this.profileStart, this.profileEnd, hollow, this.hollowSides, needEndFaces, calcVertexNormals); - this.errorMessage = profile.errorMessage; - - this.numPrimFaces = profile.numPrimFaces; - - int cut1Vert = -1; - int cut2Vert = -1; - if (hasProfileCut) - { - cut1Vert = hasHollow ? profile.coords.Count - 1 : 0; - cut2Vert = hasHollow ? profile.numOuterVerts - 1 : profile.numOuterVerts; - } - - if (initialProfileRot != 0.0f) - { - profile.AddRot(new Quat(new Coord(0.0f, 0.0f, 1.0f), initialProfileRot)); - if (viewerMode) - profile.MakeFaceUVs(); - } - - Coord lastCutNormal1 = new Coord(); - Coord lastCutNormal2 = new Coord(); - float lastV = 1.0f; - - bool done = false; - while (!done) // loop through the length of the path and add the layers - { - bool isEndLayer = false; - if (angle <= startAngle + .01f || angle >= endAngle - .01f) - isEndLayer = true; - - Profile newLayer = profile.Copy(); - - float xProfileScale = (1.0f - Math.Abs(this.skew)) * this.holeSizeX; - float yProfileScale = this.holeSizeY; - - float percentOfPath = angle / (twoPi * this.revolutions); - float percentOfAngles = (angle - startAngle) / (endAngle - startAngle); - - if (this.taperX > 0.01f) - xProfileScale *= 1.0f - percentOfPath * this.taperX; - else if (this.taperX < -0.01f) - xProfileScale *= 1.0f + (1.0f - percentOfPath) * this.taperX; - - if (this.taperY > 0.01f) - yProfileScale *= 1.0f - percentOfPath * this.taperY; - else if (this.taperY < -0.01f) - yProfileScale *= 1.0f + (1.0f - percentOfPath) * this.taperY; - - if (xProfileScale != 1.0f || yProfileScale != 1.0f) - newLayer.Scale(xProfileScale, yProfileScale); - - float radiusScale = 1.0f; - if (this.radius > 0.001f) - radiusScale = 1.0f - this.radius * percentOfPath; - else if (this.radius < 0.001f) - radiusScale = 1.0f + this.radius * (1.0f - percentOfPath); - - float twist = twistBegin + twistTotal * percentOfPath; - - float xOffset = 0.5f * (skewStart + totalSkew * percentOfAngles); - xOffset += (float)Math.Sin(angle) * xOffsetTopShearXFactor; - - float yOffset = yShearCompensation * (float)Math.Cos(angle) * (0.5f - yPathScale) * radiusScale; - - float zOffset = (float)Math.Sin(angle + this.topShearY) * (0.5f - yPathScale) * radiusScale; - - // next apply twist rotation to the profile layer - if (twistTotal != 0.0f || twistBegin != 0.0f) - newLayer.AddRot(new Quat(new Coord(0.0f, 0.0f, 1.0f), twist)); - - // now orient the rotation of the profile layer relative to it's position on the path - // adding taperY to the angle used to generate the quat appears to approximate the viewer - newLayer.AddRot(new Quat(new Coord(1.0f, 0.0f, 0.0f), angle + this.topShearY)); - newLayer.AddPos(xOffset, yOffset, zOffset); - - if (isEndLayer && angle <= startAngle + .01f) - { - newLayer.FlipNormals(); - - // add the top faces to the viewerFaces list here - if (this.viewerMode && needEndFaces) - { - Coord faceNormal = newLayer.faceNormal; - ViewerFace newViewerFace = new ViewerFace(); - newViewerFace.primFaceNumber = 0; - foreach (Face face in newLayer.faces) - { - newViewerFace.v1 = newLayer.coords[face.v1]; - newViewerFace.v2 = newLayer.coords[face.v2]; - newViewerFace.v3 = newLayer.coords[face.v3]; - - newViewerFace.coordIndex1 = face.v1; - newViewerFace.coordIndex2 = face.v2; - newViewerFace.coordIndex3 = face.v3; - - newViewerFace.n1 = faceNormal; - newViewerFace.n2 = faceNormal; - newViewerFace.n3 = faceNormal; - - newViewerFace.uv1 = newLayer.faceUVs[face.v1]; - newViewerFace.uv2 = newLayer.faceUVs[face.v2]; - newViewerFace.uv3 = newLayer.faceUVs[face.v3]; - - this.viewerFaces.Add(newViewerFace); - } - } - } - - // append the layer and fill in the sides - - int coordsLen = this.coords.Count; - newLayer.AddValue2FaceVertexIndices(coordsLen); - - this.coords.AddRange(newLayer.coords); - - if (this.calcVertexNormals) - { - newLayer.AddValue2FaceNormalIndices(this.normals.Count); - this.normals.AddRange(newLayer.vertexNormals); - } - - if (isEndLayer) - this.faces.AddRange(newLayer.faces); - - // fill faces between layers - - int numVerts = newLayer.coords.Count; - Face newFace = new Face(); - if (step > firstStep) - { - int startVert = coordsLen + 1; - int endVert = this.coords.Count; - - if (sides < 5 || this.hasProfileCut || hollow > 0.0f) - startVert--; - - for (int i = startVert; i < endVert; i++) - { - int iNext = i + 1; - if (i == endVert - 1) - iNext = startVert; - - int whichVert = i - startVert; - - newFace.v1 = i; - newFace.v2 = i - numVerts; - newFace.v3 = iNext - numVerts; - this.faces.Add(newFace); - - newFace.v2 = iNext - numVerts; - newFace.v3 = iNext; - this.faces.Add(newFace); - - if (this.viewerMode) - { - int primFaceNumber = profile.faceNumbers[whichVert]; - if (!needEndFaces) - primFaceNumber -= 1; - - // add the side faces to the list of viewerFaces here - ViewerFace newViewerFace1 = new ViewerFace(primFaceNumber); - ViewerFace newViewerFace2 = new ViewerFace(primFaceNumber); - float u1 = newLayer.us[whichVert]; - float u2 = 1.0f; - if (whichVert < newLayer.us.Count - 1) - u2 = newLayer.us[whichVert + 1]; - - if (whichVert == cut1Vert || whichVert == cut2Vert) - { - u1 = 0.0f; - u2 = 1.0f; - } - else if (sides < 5) - { // boxes and prisms have one texture face per side of the prim, so the U values have to be scaled - // to reflect the entire texture width - u1 *= sides; - u2 *= sides; - u2 -= (int)u1; - u1 -= (int)u1; - if (u2 < 0.1f) - u2 = 1.0f; - - //newViewerFace2.primFaceNumber = newViewerFace1.primFaceNumber = whichVert + 1; - } - - newViewerFace1.uv1.U = u1; - newViewerFace1.uv2.U = u1; - newViewerFace1.uv3.U = u2; - - newViewerFace1.uv1.V = 1.0f - percentOfPath; - newViewerFace1.uv2.V = lastV; - newViewerFace1.uv3.V = lastV; - - newViewerFace2.uv1.U = u1; - newViewerFace2.uv2.U = u2; - newViewerFace2.uv3.U = u2; - - newViewerFace2.uv1.V = 1.0f - percentOfPath; - newViewerFace2.uv2.V = lastV; - newViewerFace2.uv3.V = 1.0f - percentOfPath; - - newViewerFace1.v1 = this.coords[i]; - newViewerFace1.v2 = this.coords[i - numVerts]; - newViewerFace1.v3 = this.coords[iNext - numVerts]; - - newViewerFace2.v1 = this.coords[i]; - newViewerFace2.v2 = this.coords[iNext - numVerts]; - newViewerFace2.v3 = this.coords[iNext]; - - newViewerFace1.coordIndex1 = i; - newViewerFace1.coordIndex2 = i - numVerts; - newViewerFace1.coordIndex3 = iNext - numVerts; - - newViewerFace2.coordIndex1 = i; - newViewerFace2.coordIndex2 = iNext - numVerts; - newViewerFace2.coordIndex3 = iNext; - - // profile cut faces - if (whichVert == cut1Vert) - { - newViewerFace1.n1 = newLayer.cutNormal1; - newViewerFace1.n2 = newViewerFace1.n3 = lastCutNormal1; - - newViewerFace2.n1 = newViewerFace2.n3 = newLayer.cutNormal1; - newViewerFace2.n2 = lastCutNormal1; - } - else if (whichVert == cut2Vert) - { - newViewerFace1.n1 = newLayer.cutNormal2; - newViewerFace1.n2 = newViewerFace1.n3 = lastCutNormal2; - - newViewerFace2.n1 = newViewerFace2.n3 = newLayer.cutNormal2; - newViewerFace2.n2 = lastCutNormal2; - } - else // periphery faces - { - if (sides < 5 && whichVert < newLayer.numOuterVerts) - { - newViewerFace1.n1 = this.normals[i]; - newViewerFace1.n2 = this.normals[i - numVerts]; - newViewerFace1.n3 = this.normals[i - numVerts]; - - newViewerFace2.n1 = this.normals[i]; - newViewerFace2.n2 = this.normals[i - numVerts]; - newViewerFace2.n3 = this.normals[i]; - } - else if (hollowSides < 5 && whichVert >= newLayer.numOuterVerts) - { - newViewerFace1.n1 = this.normals[iNext]; - newViewerFace1.n2 = this.normals[iNext - numVerts]; - newViewerFace1.n3 = this.normals[iNext - numVerts]; - - newViewerFace2.n1 = this.normals[iNext]; - newViewerFace2.n2 = this.normals[iNext - numVerts]; - newViewerFace2.n3 = this.normals[iNext]; - } - else - { - newViewerFace1.n1 = this.normals[i]; - newViewerFace1.n2 = this.normals[i - numVerts]; - newViewerFace1.n3 = this.normals[iNext - numVerts]; - - newViewerFace2.n1 = this.normals[i]; - newViewerFace2.n2 = this.normals[iNext - numVerts]; - newViewerFace2.n3 = this.normals[iNext]; - } - } - - //newViewerFace1.primFaceNumber = newViewerFace2.primFaceNumber = newLayer.faceNumbers[whichVert]; - this.viewerFaces.Add(newViewerFace1); - this.viewerFaces.Add(newViewerFace2); - - } - } - } - - lastCutNormal1 = newLayer.cutNormal1; - lastCutNormal2 = newLayer.cutNormal2; - lastV = 1.0f - percentOfPath; - - // calculate terms for next iteration - // calculate the angle for the next iteration of the loop - - if (angle >= endAngle - 0.01) - done = true; - else - { - step += 1; - angle = stepSize * step; - if (angle > endAngle) - angle = endAngle; - } - - if (done && viewerMode && needEndFaces) - { - // add the bottom faces to the viewerFaces list here - Coord faceNormal = newLayer.faceNormal; - ViewerFace newViewerFace = new ViewerFace(); - //newViewerFace.primFaceNumber = newLayer.bottomFaceNumber + 1; - newViewerFace.primFaceNumber = newLayer.bottomFaceNumber; - foreach (Face face in newLayer.faces) - { - newViewerFace.v1 = newLayer.coords[face.v1 - coordsLen]; - newViewerFace.v2 = newLayer.coords[face.v2 - coordsLen]; - newViewerFace.v3 = newLayer.coords[face.v3 - coordsLen]; - - newViewerFace.coordIndex1 = face.v1 - coordsLen; - newViewerFace.coordIndex2 = face.v2 - coordsLen; - newViewerFace.coordIndex3 = face.v3 - coordsLen; - - newViewerFace.n1 = faceNormal; - newViewerFace.n2 = faceNormal; - newViewerFace.n3 = faceNormal; - - newViewerFace.uv1 = newLayer.faceUVs[face.v1 - coordsLen]; - newViewerFace.uv2 = newLayer.faceUVs[face.v2 - coordsLen]; - newViewerFace.uv3 = newLayer.faceUVs[face.v3 - coordsLen]; - - this.viewerFaces.Add(newViewerFace); - } - } - } + this.Extrude(PathType.Circular); } + private Coord SurfaceNormal(Coord c1, Coord c2, Coord c3) { Coord edge1 = new Coord(c2.X - c1.X, c2.Y - c1.Y, c2.Z - c1.Z);