Example #1
0
        /// Compute corner normals based on polygon normal and point location attributes
        /// Results are stored in internally stored attribute map named "corner_normals".
        public void SmoothNormalize(
            string cornerAttribute,
            string polygonAttribute,
            float maxSmoothingAngleRadians
            )
        {
            var cornerAttributes  = CornerAttributes.FindOrCreate <Vector3>(cornerAttribute /*"corner_normals"*/);
            var polygonAttributes = PolygonAttributes.Find <Vector3>(polygonAttribute /*"polygon_normals"*/);
            var polygonNormals    = PolygonAttributes.Find <Vector3>("polygon_normals");

            float cosMaxSmoothingAngle = (float)System.Math.Cos((double)maxSmoothingAngleRadians);

            cornerAttributes.Clear();
            foreach (Polygon polygon in Polygons)
            {
                if (maxSmoothingAngleRadians == 0)
                {
                    polygon.CopyToCorners(
                        cornerAttributes,
                        polygonAttributes
                        );
                }
                else
                {
                    polygon.SmoothNormalize(
                        cornerAttributes,
                        polygonAttributes,
                        polygonNormals,
                        cosMaxSmoothingAngle
                        );
                }
            }
        }
 public static dynamic GetTSObject(PolygonAttributes dynObject)
 {
     if (dynObject is null)
     {
         return(null);
     }
     return(dynObject.teklaObject);
 }
Example #3
0
        /// Compute polygon centroids based on point position attributes
        /// Results are stored in internally stored attribute map named "polygon_centroids".
        public void ComputePolygonCentroids()
        {
            var polygonCentroids = PolygonAttributes.FindOrCreate <Vector3>("polygon_centroids");
            var pointLocations   = PointAttributes.Find <Vector3>("point_locations");

            polygonCentroids.Clear();
            foreach (Polygon polygon in Polygons)
            {
                polygon.ComputeCentroid(polygonCentroids, pointLocations);
            }
        }
Example #4
0
        /// Compute polygon normals based on point position attributes.
        /// Results are stored in internally stored attribute map named "polygon_normals".
        public void ComputePolygonNormals()
        {
            var polygonNormals = PolygonAttributes.FindOrCreate <Vector3>("polygon_normals");
            var pointLocations = PointAttributes.Find <Vector3>("point_locations");

            polygonNormals.Clear();
            foreach (Polygon polygon in Polygons)
            {
                polygon.ComputeNormal(polygonNormals, pointLocations);
            }
        }
Example #5
0
        public Wall(Vertex[] vertex1, string name, OpenGL gl)
        {
            DepthBufferAttributes depthBufferAttributes = new DepthBufferAttributes();

            depthBufferAttributes.DepthFunction   = DepthFunction.LessThanOrEqual;
            depthBufferAttributes.EnableDepthTest = true;

            Name = name;

            // ==== Fill polygon ===
            PolygonAttributes polygonFillAttributes = new PolygonAttributes();

            polygonFillAttributes.PolygonMode    = PolygonMode.Filled;
            polygonFillAttributes.CullFaces      = FaceMode.Back;
            polygonFillAttributes.EnableCullFace = true;

            polygonFillAttributes.OffsetFactor     = 0f;
            polygonFillAttributes.OffsetBias       = 0;
            polygonFillAttributes.EnableOffsetFill = true;

            OpenGLAttributesEffect polyFillEffect = new OpenGLAttributesEffect();

            polyFillEffect.PolygonAttributes = polygonFillAttributes;
            //polyFillEffect.DepthBufferAttributes = depthBufferAttributes;

            SharpGL.SceneGraph.Primitives.Polygon polyFill = new Polygon(this.Name, vertex1);
            polyFill.Material = Materials.Pink(gl);
            polyFill.AddEffect(polyFillEffect);
            this.Children.Add(polyFill);

            // ==== Border polygon ===
            PolygonAttributes polygonBorderAttributes = new PolygonAttributes();

            polygonBorderAttributes.PolygonMode      = PolygonMode.Lines;
            polygonBorderAttributes.OffsetFactor     = -.5f;
            polygonBorderAttributes.OffsetBias       = -.5f;
            polygonBorderAttributes.EnableOffsetLine = true;
            polygonBorderAttributes.CullFaces        = FaceMode.Back;
            polygonBorderAttributes.EnableCullFace   = true;

            OpenGLAttributesEffect polyBorderEffect = new OpenGLAttributesEffect();

            polyBorderEffect.PolygonAttributes = polygonBorderAttributes;
            //polyBorderEffect.DepthBufferAttributes = depthBufferAttributes;

            SharpGL.SceneGraph.Primitives.Polygon polyBorder = new Polygon(this.Name, vertex1);
            polyBorder.Material = Materials.DarkGrey(gl);
            polyBorder.AddEffect(polyBorderEffect);
            this.Children.Add(polyBorder);

            this.polyFill = polyFill;
        }
Example #6
0
        public Vector3 ComputePointNormal(Point point)
        {
            var polygonNormals = PolygonAttributes.Find <Vector3>("polygon_normals");

            Vector3 normalSum = new Vector3(0.0f, 0.0f, 0.0f);

            foreach (Corner corner in point.Corners)
            {
                normalSum += polygonNormals[corner.Polygon];
            }
            Vector3 averageNormal = normalSum / (float)point.Corners.Count;

            return(averageNormal);
        }
Example #7
0
        public void ComputePointNormals(string mapName)
        {
            var pointNormals   = PointAttributes.FindOrCreate <Vector3>(mapName);
            var polygonNormals = PolygonAttributes.Find <Vector3>("polygon_normals");

            pointNormals.Clear();
            foreach (Point point in Points)
            {
                Vector3 normalSum = new Vector3(0.0f, 0.0f, 0.0f);
                foreach (Corner corner in point.Corners)
                {
                    normalSum += polygonNormals[corner.Polygon];
                }
                Vector3 averageNormal = normalSum / (float)point.Corners.Count;
                pointNormals[point] = averageNormal;
            }
        }
Example #8
0
        public void Transform(Matrix4 transform)
        {
            Matrix4 inverseTransposeTransform = Matrix4.Transpose(Matrix4.Invert(transform));

            //  Check.. Did I forget something?
            //  \todo Mark each attributemap how they should be transformed
            var polygonCentroids = PolygonAttributes.FindOrNull <Vector3>("polygon_centroids");
            var polygonNormals   = PolygonAttributes.FindOrNull <Vector3>("polygon_normals");
            var pointLocations   = PointAttributes.FindOrNull <Vector3>("point_locations");
            var pointNormals     = PointAttributes.FindOrNull <Vector3>("point_normals");
            var cornerNormals    = CornerAttributes.FindOrNull <Vector3>("corner_normals");

            //  Make copies of old points
            foreach (Point point in Points)
            {
                if (pointLocations != null && pointLocations.ContainsKey(point))
                {
                    pointLocations[point] = transform.TransformPoint(pointLocations[point]);
                }
                if (pointNormals != null && pointNormals.ContainsKey(point))
                {
                    pointNormals[point] = inverseTransposeTransform.TransformDirection(pointNormals[point]);
                }
            }
            foreach (Polygon polygon in Polygons)
            {
                if (polygonCentroids != null && polygonCentroids.ContainsKey(polygon))
                {
                    polygonCentroids[polygon] = transform.TransformPoint(polygonCentroids[polygon]);
                }
                if (polygonNormals != null && polygonNormals.ContainsKey(polygon))
                {
                    polygonNormals[polygon] = inverseTransposeTransform.TransformDirection(polygonNormals[polygon]);
                }
                if (cornerNormals != null)
                {
                    foreach (Corner corner in polygon.Corners)
                    {
                        if (cornerNormals.ContainsKey(corner))
                        {
                            cornerNormals[corner] = inverseTransposeTransform.TransformDirection(cornerNormals[corner]);
                        }
                    }
                }
            }
        }
Example #9
0
        public void AddSymbol(Circle circle, OpenGL gl)
        {
            DepthBufferAttributes depthBufferAttributes = new DepthBufferAttributes();

            depthBufferAttributes.DepthFunction   = DepthFunction.LessThanOrEqual;
            depthBufferAttributes.EnableDepthTest = true;

            PolygonAttributes polygonBorderAttributes = new PolygonAttributes();

            polygonBorderAttributes.PolygonMode = PolygonMode.Lines;

            polygonBorderAttributes.EnableOffsetLine = true;
            polygonBorderAttributes.OffsetFactor     = -3f;
            polygonBorderAttributes.OffsetBias       = -3f;

            OpenGLAttributesEffect polyBorderEffect = new OpenGLAttributesEffect();

            polyBorderEffect.PolygonAttributes     = polygonBorderAttributes;
            polyBorderEffect.DepthBufferAttributes = depthBufferAttributes;

            circle.Material = Materials.DarkGrey(gl);
            circle.AddEffect(polyBorderEffect);
            this.Children.Add(circle);
        }
Example #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
        }
Example #11
0
        public RoundColumn(OpenGL gl, string name, Circle circle, float bottomPoint, float topPoint) : base()
        {
            this.Name        = name;
            this.circle      = circle;
            this.bottomPoint = bottomPoint;
            this.topPoint    = topPoint;

            boundingVolumeHelper = new BoundingVolumeHelper();

            Vertex startPoint  = circle.StartPoint;
            Vertex secondPoint = circle.SecondPoint;
            Vertex endPoint    = circle.EndPoint;

            // ==== Create bottom circle of column ====
            startPoint.Z  = bottomPoint;
            secondPoint.Z = bottomPoint;
            endPoint.Z    = bottomPoint;


            DepthBufferAttributes depthBufferAttributes = new DepthBufferAttributes();

            depthBufferAttributes.DepthFunction   = DepthFunction.LessThanOrEqual;
            depthBufferAttributes.EnableDepthTest = true;

            PolygonAttributes polygonAttributes = new PolygonAttributes();

            polygonAttributes.PolygonMode = PolygonMode.Lines;

            polygonAttributes.EnableOffsetLine = true;
            polygonAttributes.OffsetFactor     = -.9f;
            polygonAttributes.OffsetBias       = -.9f;

            OpenGLAttributesEffect openGLAttributesEffect = new OpenGLAttributesEffect();

            openGLAttributesEffect.PolygonAttributes = polygonAttributes;
            //openGLAttributesEffect.DepthBufferAttributes = depthBufferAttributes;

            Circle bottomCircle = new Circle(new Vertex(startPoint), new Vertex(secondPoint), new Vertex(endPoint));

            bottomCircle.Material = Materials.DarkGrey(gl);
            bottomCircle.AddEffect(openGLAttributesEffect);
            AddChild(bottomCircle);

            // ==== Create top circle of column ====
            startPoint.Z  = topPoint;
            secondPoint.Z = topPoint;
            endPoint.Z    = topPoint;

            Circle topCircle = new Circle(new Vertex(startPoint), new Vertex(secondPoint), new Vertex(endPoint));

            topCircle.Material = Materials.DarkGrey(gl);
            topCircle.AddEffect(openGLAttributesEffect);
            AddChild(topCircle);

            // ==== Create column body ====
            // Create the display list.

            this.Material = Materials.Purple(gl);

            displayList = new DisplayList();

            // Generate the display list and
            displayList.Generate(gl);

            displayList.New(gl, DisplayList.DisplayListMode.CompileAndExecute);


            gl.PolygonMode(OpenGL.GL_FRONT_AND_BACK, OpenGL.GL_FILL);
            gl.Begin(BeginMode.QuadStrip);
            double angle = 0;

            while (angle <= 2 * Math.PI * 1.01)
            {
                double xTmp = circle.Radius * Math.Cos(angle);
                double yTmp = circle.Radius * Math.Sin(angle);

                gl.Vertex(circle.Center.X + xTmp, circle.Center.Y + yTmp, bottomPoint);
                gl.Vertex(circle.Center.X + xTmp, circle.Center.Y + yTmp, topPoint);
                angle += 0.1;
            }
            gl.End();

            // End the display list.
            displayList.End(gl);
        }
Example #12
0
        public void Geodesate(float radius)
        {
            float rInv             = 1.0f / radius;
            var   polygonCentroids = PolygonAttributes.FindOrNull <Vector3>("polygon_centroids");
            var   polygonNormals   = PolygonAttributes.FindOrNull <Vector3>("polygon_normals");
            var   pointLocations   = PointAttributes.FindOrNull <Vector3>("point_locations");
            var   pointNormals     = PointAttributes.FindOrNull <Vector3>("point_normals");
            var   cornerNormals    = CornerAttributes.FindOrNull <Vector3>("corner_normals");

            //  Make copies of old points
            foreach (Point point in Points)
            {
                if (
                    (pointLocations != null) &&
                    pointLocations.ContainsKey(point)
                    )
                {
                    Vector3 newNormal = Vector3.Normalize(pointLocations[point]);
                    pointLocations[point] = radius * newNormal;
                    if (
                        (pointNormals != null) &&
                        pointNormals.ContainsKey(point)
                        )
                    {
                        pointNormals[point] = newNormal;
                    }
                }
            }
            foreach (Polygon polygon in Polygons)
            {
                if (
                    (polygonCentroids != null) &&
                    polygonCentroids.ContainsKey(polygon)
                    )
                {
                    Vector3 newNormalizedCentroid = Vector3.Normalize(polygonCentroids[polygon]);
                    polygonCentroids[polygon] = radius * newNormalizedCentroid;
                    if (
                        (polygonNormals != null) &&
                        polygonNormals.ContainsKey(polygon)
                        )
                    {
                        polygonNormals[polygon] = newNormalizedCentroid;
                    }
                }
                if (cornerNormals != null)
                {
                    foreach (Corner corner in polygon.Corners)
                    {
                        if (
                            cornerNormals.ContainsKey(corner)
                            )
                        {
                            if (pointNormals.ContainsKey(corner.Point))
                            {
                                cornerNormals[corner] = pointNormals[corner.Point];
                            }
                            else if (pointLocations.ContainsKey(corner.Point))
                            {
                                cornerNormals[corner] = pointLocations[corner.Point] * rInv;
                            }
                        }
                    }
                }
            }
        }
Example #13
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();
        }
Example #14
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();
        }
Example #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();
        }