Exemple #1
0
        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);
        }
Exemple #2
0
        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);
        }
Exemple #3
0
        //  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);
        }
Exemple #4
0
        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);
        }
Exemple #6
0
        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);
        }
Exemple #7
0
        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);
        }
Exemple #8
0
        //  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);
        }
Exemple #9
0
        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);
        }
Exemple #10
0
        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
        }
Exemple #11
0
 private Point GetPoint(MakeInfo info, int slice, int stack)
 {
     return(info.points[new KeyValuePair <int, int>(slice, stack)]);
 }
Exemple #12
0
        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();
        }
Exemple #13
0
        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();
        }
Exemple #14
0
 Corner MakeCorner(MakeInfo info, Polygon polygon, int slice, int stack)
 {
     return(MakeCorner(info, polygon, slice, stack, false));
 }
Exemple #15
0
        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();
        }