Пример #1
0
        /// <inheritdoc />
        public override Vector3 GetPositionAt(Vector2 uv)
        {
            float v = uv.Y;

            Vector3 translation = CenterCurve.GetPositionAt(v);
            float   radius      = Radius.GetValueAt(uv);

            return(translation + radius * GetNormalAt(uv));
        }
Пример #2
0
        /// <inheritdoc />
        public override dvec3 GetPositionAt(dvec2 uv)
        {
            DebugUtil.AssertAllFinite(uv, nameof(uv));
            double v = uv.y;

            dvec3  translation = CenterCurve.GetPositionAt(v);
            double radius      = Radius.GetValueAt(uv);

            return(translation + radius * GetNormalAt(uv));
        }
Пример #3
0
        /// <inheritdoc />
        public override List <Vertex> GenerateVertexList(int resolutionU, int resolutionV)
        {
            // If asked to sample at zero points, return an empty list.
            if (resolutionU <= 0 || resolutionV <= 0)
            {
                return(new List <Vertex>());
            }
            var roughs = ParallelEnumerable.Range(0, resolutionV + 1).AsOrdered().SelectMany((j =>
            {
                double v = (double)j / (double)resolutionV;

                // Find the values at each ring:
                dvec3 curveTangent = CenterCurve.GetTangentAt(v).Normalized;
                dvec3 curveNormal = CenterCurve.GetNormalAt(v).Normalized;
                dvec3 curveBinormal = dvec3.Cross(curveTangent, curveNormal);

                dvec3 translation = CenterCurve.GetPositionAt(v);

                double startAngle = StartAngle.GetValueAt(v);
                double endAngle = EndAngle.GetValueAt(v);

                return(Enumerable.Range(0, resolutionU).Select((i) =>
                {
                    double u = startAngle + (endAngle - startAngle) * (double)i / (double)resolutionU;

                    double radius = Radius.GetValueAt(new dvec2(u, v));

                    // Calculate the position of the rings of vertices:
                    dvec3 surfaceNormal = (double)Math.Cos(u) * curveNormal + (double)Math.Sin(u) * curveBinormal;
                    dvec3 surfacePosition = translation + radius * surfaceNormal;
                    return new Vertex((vec3)surfacePosition, (vec3)surfaceNormal);
                }));
            }));

            List <Vertex> output = roughs.ToList();

            // Recalculate the surface normal after deformation:
            for (int j = 1; j < resolutionV; j++)
            {
                for (int i = 0; i < (resolutionU - 1); i++)
                {
                    dvec3 surfacePosition = output[(j - 1) * resolutionU + i].Position;
                    dvec3 du = surfacePosition - output[(j - 1) * resolutionU + i + 1].Position;
                    dvec3 dv = surfacePosition - output[(j) * resolutionU + i].Position;

                    // Calculate the position of the rings of vertices:
                    dvec3 surfaceNormal = dvec3.Cross(du.Normalized, dv.Normalized);

                    output[(j - 1) * resolutionU + i] = new Vertex((vec3)surfacePosition, (vec3)surfaceNormal);
                }

                // Stitch the end of the triangles:
                dvec3 surfacePosition2 = output[(j - 1) * resolutionU + resolutionU - 1].Position;
                dvec3 du2 = surfacePosition2 - output[(j - 1) * resolutionU].Position;
                dvec3 dv2 = surfacePosition2 - output[(j) * resolutionU + resolutionU - 1].Position;

                // Calculate the position of the rings of vertices:
                dvec3 surfaceNormal2 = dvec3.Cross(du2.Normalized, dv2.Normalized);

                output[(j - 1) * resolutionU + resolutionU - 1] = new Vertex((vec3)surfacePosition2, (vec3)surfaceNormal2);
            }

            return(output);
        }
Пример #4
0
        /// <inheritdoc />
        public override List <Vertex> GenerateVertexList(int resolutionU, int resolutionV)
        {
            List <Vertex> output = new List <Vertex>(CalculateVertexCount(resolutionU, resolutionV));

            for (int j = 0; j < (resolutionV + 1); j++)
            {
                float v = (float)j / (float)resolutionV;

                // Find the values at each ring:
                Vector3 curveTangent  = Vector3.Normalize(CenterCurve.GetTangentAt(v));
                Vector3 curveNormal   = Vector3.Normalize(CenterCurve.GetNormalAt(v));
                Vector3 curveBinormal = Vector3.Cross(curveTangent, curveNormal);

                Vector3 translation = CenterCurve.GetPositionAt(v);

                float startAngle = StartAngle.GetValueAt(v);
                float endAngle   = EndAngle.GetValueAt(v);

                for (int i = 0; i < resolutionU; i++)
                {
                    // First find the normalized uv-coordinates, u = [0, 2pi], v = [0, 1]:
                    float u = startAngle + (endAngle - startAngle) * (float)i / (float)resolutionU;

                    float radius = Radius.GetValueAt(new Vector2(u, v));

                    // Calculate the position of the rings of vertices:
                    Vector3 surfaceNormal   = (float)Math.Cos(u) * curveNormal + (float)Math.Sin(u) * curveBinormal;
                    Vector3 surfacePosition = translation + radius * surfaceNormal;

                    output.Add(new Vertex(surfacePosition, surfaceNormal));
                }
            }

            // Recalculate the surface normal after deformation:
            for (int j = 1; j < resolutionV; j++)
            {
                for (int i = 0; i < (resolutionU - 1); i++)
                {
                    Vector3 surfacePosition = output[(j - 1) * resolutionU + i].Position;
                    Vector3 du = surfacePosition - output[(j - 1) * resolutionU + i + 1].Position;
                    Vector3 dv = surfacePosition - output[(j) * resolutionU + i].Position;

                    // Calculate the position of the rings of vertices:
                    Vector3 surfaceNormal = Vector3.Cross(Vector3.Normalize(du), Vector3.Normalize(dv));

                    output[(j - 1) * resolutionU + i] = new Vertex(surfacePosition, surfaceNormal);
                }

                // Stitch the end of the triangles:
                Vector3 surfacePosition2 = output[(j - 1) * resolutionU + resolutionU - 1].Position;
                Vector3 du2 = surfacePosition2 - output[(j - 1) * resolutionU].Position;
                Vector3 dv2 = surfacePosition2 - output[(j) * resolutionU + resolutionU - 1].Position;

                // Calculate the position of the rings of vertices:
                Vector3 surfaceNormal2 = Vector3.Cross(Vector3.Normalize(du2), Vector3.Normalize(dv2));

                output[(j - 1) * resolutionU + resolutionU - 1] = new Vertex(surfacePosition2, surfaceNormal2);
            }

            return(output);
        }