protected Point MakePoint(MakeInfo info, int x, int y, int z, Vector3 N, float s, float t) { long key = y * info.Div.X * 4 * info.Div.Z * 4 + x * info.Div.Z * 4 + z; if (info.Points.ContainsKey(key) == true) { return(info.Points[key]); } float relX = (float)x / (float)info.Div.X; float relY = (float)y / (float)info.Div.Y; float relZ = (float)z / (float)info.Div.Z; float relXP = SPow(relX, info.p); float relYP = SPow(relY, info.p); float relZP = SPow(relZ, info.p); float xP = relXP * info.Size.X; float yP = relYP * info.Size.Y; float zP = relZP * info.Size.Z; Point point = MakePoint(); bool discontinuity = (x == -info.Div.X) || (x == info.Div.X) || (y == -info.Div.Y) || (y == info.Div.Y) || (z == -info.Div.Z) || (z == info.Div.Z); info.pointLocations[point] = new Vector3(xP, yP, zP); if (discontinuity == false) { info.pointNormals[point] = N; info.pointTexcoords[point] = new Vector2(s, t); } info.Points[key] = point; return(point); }
Corner MakeCorner(MakeInfo info, Polygon polygon, int slice, int stack, bool cap) { double relSlice = (double)slice / (double)info.sliceCount; double relStack = (double)stack / (double)(info.stackDivision + 1); // centroid: double relSlice = ((double)slice + 0.5) / (double)info.sliceCount; //double relStack = -1.0 + (0.5 / (double)(info.stackDivision + 1)); bool sliceSeam = (slice == 0) || (slice == info.sliceCount); bool bottom = stack == -info.stackDivision - 1; bool top = stack == info.stackDivision + 1; bool uvDiscontinuity = sliceSeam || bottom || top; Point point; if (top && (info.topRadius == 0.0)) { point = info.top; } else if (bottom && (info.bottomRadius == 0.0)) { point = info.bottom; } else { if (slice == info.sliceCount) { point = info.points[new KeyValuePair <int, int>(0, stack)]; } else { point = info.points[new KeyValuePair <int, int>(slice, stack)]; } } Corner corner = polygon.MakeCorner(point); if (uvDiscontinuity) { float s = (float)(relSlice); float t = (float)(0.5 + 0.5 * relStack); info.cornerTexcoords[corner] = new Vector2(s, t); } if (cap && bottom && (info.bottomRadius != 0.0f) && info.useBottom) { info.cornerNormals[corner] = new Vector3(-1.0f, 0.0f, 0.0f); } if (cap && top && (info.topRadius != 0.0f) && info.useTop) { info.cornerNormals[corner] = new Vector3(1.0f, 0.0f, 0.0f); } return(corner); }
// relStackIn is in range -1..1 // relStack is in range 0..1 Point ConePoint(MakeInfo info, double relSlice, double relStackIn) { //var pointLocations = PointAttributes.FindOrCreate<Vector3>("point_locations"); //var pointNormals = PointAttributes.FindOrCreate<Vector3>("point_normals"); //var pointTexCoords = PointAttributes.FindOrCreate<Vector2>("point_texcoords"); double phi = System.Math.PI * 2.0 * relSlice; double sinPhi = System.Math.Sin(phi); double cosPhi = System.Math.Cos(phi); double relStack = 0.5 + 0.5 * relStackIn; double oneMinusRelStack = 1.0 - relStack; Vector3 position = new Vector3( (float)(oneMinusRelStack * (info.minX) + relStack * (info.maxX)), (float)(oneMinusRelStack * (info.bottomRadius * sinPhi) + relStack * (info.topRadius * sinPhi)), (float)(oneMinusRelStack * (info.bottomRadius * cosPhi) + relStack * (info.topRadius * cosPhi)) ); Vector3 bottom = new Vector3( (float)(info.minX), (float)(info.bottomRadius * sinPhi), (float)(info.bottomRadius * cosPhi) ); Vector3 top = new Vector3( (float)(info.maxX), (float)(info.topRadius * sinPhi), (float)(info.topRadius * cosPhi) ); Vector3 bitangent = Vector3.Normalize(top - bottom); /* generatrix */ Vector3 tangent = new Vector3( 0.0f, (float)System.Math.Sin(phi + (System.Math.PI * 0.5)), (float)System.Math.Cos(phi + (System.Math.PI * 0.5)) ); Vector3 normal = Vector3.Cross( bitangent, tangent ); normal = Vector3.Normalize(normal); double s = info.relSlice; double t = 0.5 + 0.5 * info.relStack; Point point = MakePoint(); info.pointLocations[point] = new Vector3((float)position.X, (float)position.Y, (float)position.Z); info.pointNormals [point] = new Vector3((float)normal.X, (float)normal.Y, (float)normal.Z); info.pointTexcoords[point] = new Vector2((float)s, (float)t); return(point); }
void MakeCorner(MakeInfo info, Polygon polygon, int slice, int stackBase0) { //int stack_base0 = stack + info.stackDivision; int stack = stackBase0 - info.stackDivision; double relSlice = (double)(slice) / (double)(info.sliceCount); double relStack = (double)(stack) / (double)(info.stackDivision + 1); bool sliceSeam = /*(slice == 0) ||*/ (slice == info.sliceCount); bool bottom = (stackBase0 == info.stackBase0Bottom); bool top = (stackBase0 == info.stackBase0Top); bool uvDiscontinuity = sliceSeam || bottom || top; Point point; if (top) { point = info.top; } else if (bottom) { point = info.bottom; } else { if (slice == info.sliceCount) { point = info.points[stackBase0]; } else { point = info.points[(slice * info.stackCount) + stackBase0]; } } Corner corner = polygon.MakeCorner(point); if (uvDiscontinuity) { float s = 1.0f - (float)(relSlice); float t = 1.0f - (float)(0.5 * (1.0 + relStack)); info.cornerTexcoords[corner] = new Vector2(s, t); } }
protected Point MakePoint(MakeInfo info, double relSlice, double relStack) { double phi = (System.Math.PI * 2.0 * relSlice); double sin_phi = System.Math.Sin(phi); double cos_phi = System.Math.Cos(phi); double theta = (System.Math.PI * 0.5 * relStack); double sin_theta = System.Math.Sin(theta); double cos_theta = System.Math.Cos(theta); double stack_radius = cos_theta; float xVN = (float)(stack_radius * cos_phi); float yVN = (float)(sin_theta); float zVN = (float)(stack_radius * sin_phi); float xP = (float)(info.radius.X * xVN); float yP = (float)(info.radius.Y * yVN); float zP = (float)(info.radius.Z * zVN); xVN /= info.radius.X; yVN /= info.radius.Y; zVN /= info.radius.Z; float s = 1.0f - (float)(relSlice); float t = 1.0f - (float)(0.5 * (1.0 + relStack)); Point point = MakePoint(); bool uvDiscontinuity = (relStack == -1.0) || (relStack == 1.0) || /*(relSlice == 0.0) ||*/ (relSlice == 1.0); info.pointLocations[point] = new Vector3(xP, yP, zP); info.pointNormals [point] = Vector3.Normalize(new Vector3(xVN, yVN, zVN)); if (uvDiscontinuity == false) { info.pointTexcoords[point] = new Vector2(s, t); } return(point); }
private Corner MakeCorner(MakeInfo info, Polygon polygon, int x, int y, int z, Vector3 N, float s, float t) { long key = y * info.Div.X * 4 * info.Div.Z * 4 + x * info.Div.Z * 4 + z; if (info.Points.ContainsKey(key) == false) { key = 0; } Point point = info.Points[key]; bool discontinuity = (x == -info.Div.X) || (x == info.Div.X) || (y == -info.Div.Y) || (y == info.Div.Y) || (z == -info.Div.Z) || (z == info.Div.Z); Corner corner = polygon.MakeCorner(point); if (discontinuity == true) { info.cornerNormals[corner] = N; info.cornerTexcoords[corner] = new Vector2(s, t); } info.Points[key] = point; return(corner); }
Corner MakeCorner(MakeInfo info, Polygon polygon, int slice, int stack) { double relSlice = (double)slice / (double)info.sliceCount; double relStack = (info.stackCount == 1) ? 1.0 : (double)stack / (double)(info.stackCount - 1); bool sliceSeam = (slice == 0) || (slice == info.sliceCount); bool center = (stack == 0) && (info.innerRadius == 0.0f); bool uvDiscontinuity = sliceSeam || center; Point point; if (center) { point = info.center; } else { if (slice == info.sliceCount) { point = info.points[new KeyValuePair <int, int>(0, stack)]; } else { point = info.points[new KeyValuePair <int, int>(slice, stack)]; } } Corner corner = polygon.MakeCorner(point); if (uvDiscontinuity) { float s = (float)(relSlice); float t = (float)(relStack); info.cornerTexcoords[corner] = new Vector2(s, t); } return(corner); }
// relStackIn is in range -1..1 // relStack is in range 0..1 Point MakePoint(MakeInfo info, double relSlice, double relStack) { double phi = System.Math.PI * 2.0 * relSlice; double sinPhi = System.Math.Sin(phi); double cosPhi = System.Math.Cos(phi); double oneMinusRelStack = 1.0 - relStack; Vector3 position = new Vector3( (float)(oneMinusRelStack * (info.outerRadius * cosPhi) + relStack * (info.innerRadius * cosPhi)), (float)(oneMinusRelStack * (info.outerRadius * sinPhi) + relStack * (info.innerRadius * sinPhi)), 0.0f ); double s = relSlice; double t = relStack; Point point = MakePoint(); info.pointLocations[point] = new Vector3((float)position.X, (float)position.Y, (float)position.Z); info.pointNormals [point] = Vector3.UnitZ; info.pointTexcoords[point] = new Vector2((float)s, (float)t); return(point); }
protected Point MakePoint(MakeInfo info, double relSlice, double relStack) { #if false double beta = (System.Math.PI * 2.0 * relSlice); double sinBeta = System.Math.Sin(beta); double cosBeta = System.Math.Cos(beta); double theta = (System.Math.PI * 0.5 * relStack); double sinTheta = System.Math.Sin(theta); double cosTheta = System.Math.Cos(theta); double ctn1 = System.Math.Sign(cosTheta) * System.Math.Pow(System.Math.Abs(cosTheta), info.n1); double xP = ctn1 * System.Math.Sign(cosBeta) * System.Math.Pow(System.Math.Abs(cosBeta), info.n2); double yP = ctn1 * System.Math.Sign(sinBeta) * System.Math.Pow(System.Math.Abs(sinBeta), info.n2); double zP = System.Math.Sign(sinTheta) * System.Math.Pow(System.Math.Abs(sinTheta), info.n1); double ct2mn1 = System.Math.Sign(cosTheta) * System.Math.Pow(System.Math.Abs(cosTheta), 2.0 - info.n1); double xVN = ct2mn1 * System.Math.Sign(cosBeta) * System.Math.Pow(System.Math.Abs(cosBeta), 2.0 - info.n2); double yVN = ct2mn1 * System.Math.Sign(sinBeta) * System.Math.Pow(System.Math.Abs(sinBeta), 2.0 - info.n2); double zVN = System.Math.Sign(sinTheta) * System.Math.Pow(System.Math.Abs(sinTheta), 2.0 - info.n1); #endif #if false double a1 = info.radius.X; double a2 = info.radius.Y; double a3 = info.radius.Z; double e1 = info.n1; double e2 = info.n2; double neta = (System.Math.PI * 0.5 * relStack); // -Pi / 2 .. Pi / 2 double omega = (System.Math.PI * 2.0 * relSlice); // -Pi .. Pi double cosNeta = System.Math.Cos(neta); double sinNeta = System.Math.Sin(neta); double cosOmega = System.Math.Cos(omega); double sinOmega = System.Math.Sin(omega); /* 2.10 */ double xP = a1 * SPow(cosNeta, e1) * SPow(cosOmega, e2); double yP = a2 * SPow(cosNeta, e1) * SPow(sinOmega, e2); double zP = a3 * SPow(sinNeta, e1); double a1Inv = 1.0 / info.radius.X; double a2Inv = 1.0 / info.radius.Y; double a3Inv = 1.0 / info.radius.Z; /* 2.39 */ double xVN = a1Inv * SPow(cosNeta, 2.0 - e1) * SPow(cosOmega, 2.0 - e2); double yVN = a2Inv * SPow(cosNeta, 2.0 - e1) * SPow(sinOmega, 2.0 - e2); double zVN = a3Inv * SPow(sinNeta, 2.0 - e1); #endif double phi = (System.Math.PI * 2.0 * relSlice); double sin_phi = System.Math.Sin(phi); double cos_phi = System.Math.Cos(phi); double theta = (System.Math.PI * 0.5 * relStack); double sin_theta = System.Math.Sin(theta); double cos_theta = System.Math.Cos(theta); double stack_radius = cos_theta; float xVN = (float)(stack_radius * cos_phi); float yVN = (float)(sin_theta); float zVN = (float)(stack_radius * sin_phi); float xP = (float)(info.radius.X * xVN); float yP = (float)(info.radius.Y * yVN); float zP = (float)(info.radius.Z * zVN); xP = (float)SPow((double)xP, info.n1); yP = (float)SPow((double)yP, info.n1 * info.n2); zP = (float)SPow((double)zP, info.n2); float s = 1.0f - (float)(relSlice); float t = 1.0f - (float)(0.5 * (1.0 + relStack)); Point point = MakePoint(); bool uvDiscontinuity = (relStack == -1.0) || (relStack == 1.0) || /*(relSlice == 0.0) ||*/ (relSlice == 1.0); info.pointLocations[point] = new Vector3(xP, yP, zP); info.pointNormals [point] = new Vector3(xVN, yVN, zVN); if (uvDiscontinuity == false) { info.pointTexcoords[point] = new Vector2(s, t); } return(point); }
public SuperEllipsoid(Vector3 radius, double n1, double n2, int sliceCount, int stackDivision) { MakeInfo info = new MakeInfo(radius, n1, n2, sliceCount, stackDivision); info.pointLocations = PointAttributes.FindOrCreate <Vector3>("point_locations"); info.pointNormals = PointAttributes.FindOrCreate <Vector3>("point_normals"); info.pointTexcoords = PointAttributes.FindOrCreate <Vector2>("point_texcoords"); info.polygonCentroids = PolygonAttributes.FindOrCreate <Vector3>("polygon_centroids"); info.polygonNormals = PolygonAttributes.FindOrCreate <Vector3>("polygon_normals"); info.cornerTexcoords = CornerAttributes.FindOrCreate <Vector2>("corner_texcoords"); int slice; int stack; for (slice = 0; slice < sliceCount; ++slice) { double relSlice = (double)(slice) / (double)(sliceCount); for (stack = -stackDivision; stack <= stackDivision; ++stack) { double relStack = (double)(stack) / (double)(stackDivision + 1); Point point = MakePoint(info, relSlice, relStack); info.points.Add(point); } } info.bottom = MakePoint(info, 0.5f, -1.0f); info.top = MakePoint(info, 0.5f, 1.0f); #region bottom fan { for (slice = 0; slice < sliceCount; ++slice) { int nextSlice = (slice + 1); int stackBase0 = 0; double relSlice = ((double)(slice) + 0.5) / (double)(sliceCount); double relStack = -1.0 + (0.5 / (double)(stackDivision + 1)); Point centroid = MakePoint(info, relSlice, relStack); var polygon = MakePolygon(); #if CCW MakeCorner(info, polygon, slice, stackBase0); MakeCorner(info, polygon, slice, info.stackBase0Bottom); MakeCorner(info, polygon, nextSlice, stackBase0); #else MakeCorner(info, polygon, nextSlice, stackBase0); MakeCorner(info, polygon, slice, info.stackBase0Bottom); MakeCorner(info, polygon, slice, stackBase0); #endif info.polygonCentroids[polygon] = info.pointLocations[centroid]; info.polygonNormals [polygon] = info.pointNormals [centroid]; } } #endregion #region middle quads, bottom up for ( stack = -stackDivision; stack < stackDivision; ++stack ) { int stackBase0 = stack + stackDivision; int nextStackBase0 = stackBase0 + 1; double relStack = ((double)(stack) + 0.5) / (double)(stackDivision + 1); for (slice = 0; slice < sliceCount; ++slice) { int nextSlice = (slice + 1); double relSlice = ((double)(slice) + 0.5) / (double)(sliceCount); Point centroid = MakePoint(info, relSlice, relStack); var polygon = MakePolygon(); #if CCW MakeCorner(info, polygon, nextSlice, nextStackBase0); MakeCorner(info, polygon, slice, nextStackBase0); MakeCorner(info, polygon, slice, stackBase0); MakeCorner(info, polygon, nextSlice, stackBase0); #else MakeCorner(info, polygon, nextSlice, stackBase0); MakeCorner(info, polygon, slice, stackBase0); MakeCorner(info, polygon, slice, nextStackBase0); MakeCorner(info, polygon, nextSlice, nextStackBase0); #endif info.polygonCentroids[polygon] = info.pointLocations[centroid]; info.polygonNormals [polygon] = info.pointNormals [centroid]; } } #endregion #region top fan for (slice = 0; slice < sliceCount; ++slice) { int nextSlice = (slice + 1); int stackBase0 = stackDivision + stackDivision; double relSlice = ((double)(slice) + 0.5) / (double)(sliceCount); double relStack = 1.0 - (0.5 / (double)(stackDivision + 1)); Point centroid = MakePoint(info, relSlice, relStack); var polygon = MakePolygon(); #if CCW MakeCorner(info, polygon, slice, info.stackBase0Top); MakeCorner(info, polygon, slice, stackBase0); MakeCorner(info, polygon, nextSlice, stackBase0); #else MakeCorner(info, polygon, nextSlice, stackBase0); MakeCorner(info, polygon, slice, stackBase0); MakeCorner(info, polygon, slice, info.stackBase0Top); #endif info.polygonCentroids[polygon] = info.pointLocations[centroid]; info.polygonNormals [polygon] = info.pointNormals [centroid]; } #endregion }
private Point GetPoint(MakeInfo info, int slice, int stack) { return(info.points[new KeyValuePair <int, int>(slice, stack)]); }
public Disc( double outerRadius, double innerRadius, int sliceCount, int stackCount ) { MakeInfo info = new MakeInfo(outerRadius, innerRadius, sliceCount, stackCount); info.pointLocations = PointAttributes.FindOrCreate <Vector3>("point_locations"); info.pointNormals = PointAttributes.FindOrCreate <Vector3>("point_normals"); info.pointTexcoords = PointAttributes.FindOrCreate <Vector2>("point_texcoords"); info.polygonCentroids = PolygonAttributes.FindOrCreate <Vector3>("polygon_centroids"); info.polygonNormals = PolygonAttributes.FindOrCreate <Vector3>("polygon_normals"); info.cornerNormals = CornerAttributes.FindOrCreate <Vector3>("corner_normals"); info.cornerTexcoords = CornerAttributes.FindOrCreate <Vector2>("corner_texcoords"); /* Make points */ for (int stack = 0; stack < stackCount; ++stack) { double relStack = (stackCount == 1) ? 1.0 : (double)stack / (double)(stackCount - 1); for (int slice = 0; slice <= sliceCount; ++slice) { double relSlice = (double)slice / (double)sliceCount; info.points[new KeyValuePair <int, int>(slice, stack)] = MakePoint(info, relSlice, relStack); } } /* Special case without center point */ if (stackCount == 1) { Polygon polygon = MakePolygon(); info.polygonCentroids[polygon] = Vector3.Zero; info.polygonNormals [polygon] = Vector3.UnitZ; for (int slice = sliceCount - 1; slice >= 0; --slice) { MakeCorner(info, polygon, slice, 0); } return; } /* Make center point if needed */ if (innerRadius == 0.0f) { info.center = MakePoint(0.0, 0.0, 0.0); } /* Quads/triangles */ for (int stack = 0; stack < stackCount - 1; ++stack) { double relStackCentroid = (stackCount == 1) ? 0.5 : (double)stack / (double)(stackCount - 1); for (int slice = 0; slice < sliceCount; ++slice) { double relSliceCentroid = ((double)(slice) + 0.5) / (double)(sliceCount); Point centroid = MakePoint(info, relSliceCentroid, relStackCentroid); Polygon polygon = MakePolygon(); info.polygonCentroids[polygon] = info.pointLocations[centroid]; info.polygonNormals [polygon] = Vector3.UnitZ; if ((stack == 0) && (innerRadius == 0.0)) { Corner tip = MakeCorner(info, polygon, slice, stack); MakeCorner(info, polygon, slice + 1, stack + 1); MakeCorner(info, polygon, slice, stack + 1); Vector2 t1 = info.pointTexcoords[GetPoint(info, slice, stack)]; Vector2 t2 = info.pointTexcoords[GetPoint(info, slice + 1, stack)]; Vector2 averageTexcoord = (t1 + t2) / 2.0f; info.cornerTexcoords[tip] = averageTexcoord; } else { MakeCorner(info, polygon, slice + 1, stack + 1); MakeCorner(info, polygon, slice, stack + 1); MakeCorner(info, polygon, slice, stack); MakeCorner(info, polygon, slice + 1, stack); } } } BuildEdges(); }
public Cone( double minX, double maxX, double bottomRadius, double topRadius, bool useBottom, bool useTop, int sliceCount, int stackDivision ) { MakeInfo info = new MakeInfo(minX, maxX, bottomRadius, topRadius, useBottom, useTop, sliceCount, stackDivision); info.pointLocations = PointAttributes.FindOrCreate <Vector3>("point_locations"); info.pointNormals = PointAttributes.FindOrCreate <Vector3>("point_normals"); info.pointTexcoords = PointAttributes.FindOrCreate <Vector2>("point_texcoords"); info.polygonCentroids = PolygonAttributes.FindOrCreate <Vector3>("polygon_centroids"); info.polygonNormals = PolygonAttributes.FindOrCreate <Vector3>("polygon_normals"); info.cornerNormals = CornerAttributes.FindOrCreate <Vector3>("corner_normals"); info.cornerTexcoords = CornerAttributes.FindOrCreate <Vector2>("corner_texcoords"); /* Other vertices */ for (int slice = 0; slice <= sliceCount; ++slice) { double relSlice = (double)slice / (double)sliceCount; for (int stack = -stackDivision - info.bottomNotSingular; stack <= stackDivision + info.topNotSingular; ++stack) { double relStack = (double)stack / (double)(stackDivision + 1); info.points[new KeyValuePair <int, int>(slice, stack)] = ConePoint(info, relSlice, relStack); } } /* Bottom parts */ if (bottomRadius == 0.0) { info.bottom = MakePoint(minX, 0.0, 0.0); /* apex */ for (int slice = 0; slice < sliceCount; ++slice) { int stack = -stackDivision; // second last stack, bottom is -stackDivision - 1 double relSliceCentroid = ((double)slice + 0.5) / (double)sliceCount; double relStackCentroid = -1.0 + (0.5 / (double)(stackDivision + 1)); Point centroid = ConePoint(info, relSliceCentroid, relStackCentroid); Polygon polygon = MakePolygon(); MakeCorner(info, polygon, slice + 1, stack); MakeCorner(info, polygon, slice, stack); Corner tip = MakeCorner(info, polygon, slice, -stackDivision - 1); Vector3 n1 = info.pointNormals[GetPoint(info, slice, stack)]; Vector3 n2 = info.pointNormals[GetPoint(info, slice + 1, stack)]; Vector3 averageNormal = Vector3.Normalize(n1 + n2); info.cornerNormals[tip] = averageNormal; Vector2 t1 = info.pointTexcoords[GetPoint(info, slice, stack)]; Vector2 t2 = info.pointTexcoords[GetPoint(info, slice + 1, stack)]; Vector2 averageTexCoord = (t1 + t2) / 2.0f; info.cornerTexcoords[tip] = averageTexCoord; info.polygonCentroids[polygon] = info.pointLocations[centroid]; info.polygonNormals [polygon] = info.pointNormals [centroid]; } } else { if (useBottom == true) { Polygon polygon = MakePolygon(); info.polygonCentroids[polygon] = new Vector3((float)minX, 0.0f, 0.0f); info.polygonNormals [polygon] = new Vector3(-1.0f, 0.0f, 0.0f); for (int slice = 0; slice < sliceCount; ++slice) { int reverseSlice = sliceCount - 1 - slice; MakeCorner(info, polygon, reverseSlice, -stackDivision - 1, true); } } } /* Middle quads, bottom up */ for ( int stack = -stackDivision - info.bottomNotSingular; stack < stackDivision + info.topNotSingular; ++stack ) { double relStackCentroid = ((double)stack + 0.5) / (double)(stackDivision + 1); for (int slice = 0; slice < sliceCount; ++slice) { double relSliceCentroid = ((double)(slice) + 0.5) / (double)(sliceCount); Point centroid = ConePoint(info, relSliceCentroid, relStackCentroid); Polygon polygon = MakePolygon(); MakeCorner(info, polygon, slice + 1, stack + 1); MakeCorner(info, polygon, slice, stack + 1); MakeCorner(info, polygon, slice, stack); MakeCorner(info, polygon, slice + 1, stack); info.polygonCentroids[polygon] = info.pointLocations[centroid]; info.polygonNormals [polygon] = info.pointNormals [centroid]; } } /* Top parts */ if (topRadius == 0.0) { info.top = MakePoint(maxX, 0.0, 0.0); /* apex */ for (int slice = 0; slice < sliceCount; ++slice) { int stack = stackDivision; double relSliceCentroid = ((double)(slice) + 0.5) / (double)(sliceCount); double relStackCentroid = 1.0 - (0.5 / (double)(stackDivision + 1)); Point centroid = ConePoint(info, relSliceCentroid, relStackCentroid); Polygon polygon = MakePolygon(); Corner tip = MakeCorner(info, polygon, slice, stackDivision + 1); MakeCorner(info, polygon, slice, stack); MakeCorner(info, polygon, slice + 1, stack); Vector3 n1 = info.pointNormals[GetPoint(info, slice, stack)]; Vector3 n2 = info.pointNormals[GetPoint(info, slice + 1, stack)]; Vector3 averageNormal = Vector3.Normalize(n1 + n2); info.cornerNormals[tip] = averageNormal; Vector2 t1 = info.pointTexcoords[GetPoint(info, slice, stack)]; Vector2 t2 = info.pointTexcoords[GetPoint(info, slice + 1, stack)]; Vector2 averageTexcoord = (t1 + t2) / 2.0f; info.cornerTexcoords[tip] = averageTexcoord; info.polygonCentroids[polygon] = info.pointLocations[centroid]; info.polygonNormals [polygon] = info.pointNormals [centroid]; } } else { if (useTop == true) { Polygon polygon = MakePolygon(); info.polygonCentroids[polygon] = new Vector3((float)maxX, 0.0f, 0.0f); info.polygonNormals [polygon] = new Vector3(1.0f, 0.0f, 0.0f); for (int slice = 0; slice < sliceCount; ++slice) { MakeCorner(info, polygon, slice, stackDivision + 1, true); } } } //MergePoints(); }
Corner MakeCorner(MakeInfo info, Polygon polygon, int slice, int stack) { return(MakeCorner(info, polygon, slice, stack, false)); }
public Cube(Vector3 size, IVector3 div, float p) { int x; int y; int z; MakeInfo info = new MakeInfo(0.5f * size, div, p); info.pointLocations = PointAttributes.FindOrCreate <Vector3>("point_locations"); info.pointNormals = PointAttributes.FindOrCreate <Vector3>("point_normals"); info.pointTexcoords = PointAttributes.FindOrCreate <Vector2>("point_texcoords"); info.cornerNormals = CornerAttributes.FindOrCreate <Vector3>("corner_normals"); info.cornerTexcoords = CornerAttributes.FindOrCreate <Vector2>("corner_texcoords"); info.polygonCentroids = PolygonAttributes.FindOrCreate <Vector3>("polygon_centroids"); info.polygonNormals = PolygonAttributes.FindOrCreate <Vector3>("polygon_normals"); // Generate vertices // Top and bottom for (x = -info.Div.X; x <= info.Div.X; x++) { float relX = 0.5f + (float)x / info.Size.X; for (z = -info.Div.Z; z <= info.Div.Z; z++) { float relZ = 0.5f + (float)z / info.Size.Z; MakePoint(info, x, info.Div.Y, z, Vector3.UnitY, relX, relZ); MakePoint(info, x, -info.Div.Y, z, -Vector3.UnitY, relX, relZ); } for (y = -info.Div.Y; y <= info.Div.Y; y++) { float relY = 0.5f + (float)y / info.Size.Y; MakePoint(info, x, y, info.Div.Z, Vector3.UnitZ, relX, relY); MakePoint(info, x, y, -info.Div.Z, -Vector3.UnitZ, relX, relY); } } // Left and right for (z = -info.Div.Z; z <= info.Div.Z; z++) { float relZ = 0.5f + (float)z / info.Size.Z; for (y = -info.Div.Y; y <= info.Div.Y; y++) { float relY = 0.5f + (float)y / info.Size.Y; MakePoint(info, info.Div.X, y, z, Vector3.UnitX, relY, relZ); MakePoint(info, -info.Div.X, y, z, -Vector3.UnitX, relY, relZ); } } // Generate quads // Top and bottom for (x = -info.Div.X; x < info.Div.X; x++) { float relX1 = 0.5f + (float)x / info.Size.X; float relX2 = 0.5f + (float)(x + 1) / info.Size.X; for (z = -info.Div.Z; z < info.Div.Z; z++) { float relZ1 = 0.5f + (float)z / info.Size.Z; float relZ2 = 0.5f + (float)(z + 1) / info.Size.Z; var top = MakePolygon(); MakeCorner(info, top, x + 1, info.Div.Y, z, Vector3.UnitY, relX2, relZ1); MakeCorner(info, top, x + 1, info.Div.Y, z + 1, Vector3.UnitY, relX2, relZ2); MakeCorner(info, top, x, info.Div.Y, z + 1, Vector3.UnitY, relX1, relZ2); MakeCorner(info, top, x, info.Div.Y, z, Vector3.UnitY, relX1, relZ1); var bottom = MakePolygon(); MakeCorner(info, bottom, x, -info.Div.Y, z, -Vector3.UnitY, relX1, relZ1); MakeCorner(info, bottom, x, -info.Div.Y, z + 1, -Vector3.UnitY, relX1, relZ2); MakeCorner(info, bottom, x + 1, -info.Div.Y, z + 1, -Vector3.UnitY, relX2, relZ2); MakeCorner(info, bottom, x + 1, -info.Div.Y, z, -Vector3.UnitY, relX2, relZ1); info.polygonNormals[top] = Vector3.UnitY; info.polygonNormals[bottom] = -Vector3.UnitY; } for (y = -info.Div.Y; y < info.Div.Y; y++) { float relY1 = 0.5f + (float)y / info.Size.Y; float relY2 = 0.5f + (float)(y + 1) / info.Size.Y; var back = MakePolygon(); MakeCorner(info, back, x, y, info.Div.Z, Vector3.UnitZ, relX1, relY1); MakeCorner(info, back, x, y + 1, info.Div.Z, Vector3.UnitZ, relX1, relY2); MakeCorner(info, back, x + 1, y + 1, info.Div.Z, Vector3.UnitZ, relX2, relY2); MakeCorner(info, back, x + 1, y, info.Div.Z, Vector3.UnitZ, relX2, relY1); var front = MakePolygon(); MakeCorner(info, front, x + 1, y, -info.Div.Z, -Vector3.UnitZ, relX2, relY1); MakeCorner(info, front, x + 1, y + 1, -info.Div.Z, -Vector3.UnitZ, relX2, relY2); MakeCorner(info, front, x, y + 1, -info.Div.Z, -Vector3.UnitZ, relX1, relY2); MakeCorner(info, front, x, y, -info.Div.Z, -Vector3.UnitZ, relX1, relY1); info.polygonNormals[back] = Vector3.UnitZ; info.polygonNormals[front] = -Vector3.UnitZ; } } // Left and right for (z = -info.Div.Z; z < info.Div.Z; z++) { float relZ1 = 0.5f + (float)z / info.Size.Z; float relZ2 = 0.5f + (float)(z + 1) / info.Size.Z; for (y = -info.Div.Y; y < info.Div.Y; y++) { float relY1 = 0.5f + (float)y / info.Size.Y; float relY2 = 0.5f + (float)(y + 1) / info.Size.Y; var right = MakePolygon(); MakeCorner(info, right, info.Div.X, y, z, Vector3.UnitX, relY1, relZ1); MakeCorner(info, right, info.Div.X, y, z + 1, Vector3.UnitX, relY1, relZ2); MakeCorner(info, right, info.Div.X, y + 1, z + 1, Vector3.UnitX, relY2, relZ2); MakeCorner(info, right, info.Div.X, y + 1, z, Vector3.UnitX, relY2, relZ1); var left = MakePolygon(); MakeCorner(info, left, -info.Div.X, y + 1, z, -Vector3.UnitX, relY2, relZ1); MakeCorner(info, left, -info.Div.X, y + 1, z + 1, -Vector3.UnitX, relY2, relZ2); MakeCorner(info, left, -info.Div.X, y, z + 1, -Vector3.UnitX, relY1, relZ2); MakeCorner(info, left, -info.Div.X, y, z, -Vector3.UnitX, relY1, relZ1); info.polygonNormals[right] = Vector3.UnitX; info.polygonNormals[left] = -Vector3.UnitX; } } ComputePolygonCentroids(); }