Example #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));
        }
Example #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));
        }
Example #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);
        }
Example #4
0
        /// <inheritdoc />
        public override List <Vertex> GenerateVertexList(int resolutionU, int resolutionV)
        {
            List <Vertex> output = new List <Vertex>(CalculateVertexCount(resolutionU, resolutionV));

            // Load all required variables:
            dvec3 up = dvec3.UnitZ;

            dvec3 pointTangent  = Direction;
            dvec3 pointNormal   = Normal;
            dvec3 pointBinormal = Binormal;

            dvec3 translation = Center;

            // Get the radius at the top of the hemisphere:
            double topRadius = Radius.GetValueAt(new dvec2(0.0, 0.5 * Math.PI));

            // Generate the first point at the pole of the hemisphere:
            output.Add(new Vertex((vec3)(translation + topRadius * pointTangent), (vec3)pointTangent));

            // Generate rings of the other points:
            for (int j = 1; j < (resolutionV + 1); j++)
            {
                for (int i = 0; i < resolutionU; i++)
                {
                    // First find the normalized uv-coordinates, u = [0, 2pi], v = [0, 1/2pi]:
                    double u = i / (double)resolutionU * 2.0 * Math.PI;
                    double v = j / (double)resolutionV * 0.5 * Math.PI;

                    // Calculate the position of the rings of vertices:
                    double x = Math.Sin(v) * Math.Cos(u);
                    double y = Math.Sin(v) * Math.Sin(u);
                    double z = Math.Cos(v);

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

                    dvec3 surfaceNormal   = x * pointNormal + y * pointBinormal + z * pointTangent;
                    dvec3 surfacePosition = translation + radius * surfaceNormal;

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

            // 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 + 1].Position;
                    dvec3 du = surfacePosition - output[(j - 1) * resolutionU + i + 1 + 1].Position;
                    dvec3 dv = surfacePosition - output[(j) * resolutionU + i + 1].Position;

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

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

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

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

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

            return(output);
        }
Example #5
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);
        }
Example #6
0
        public override List <Vertex> GenerateVertexList(int resolutionU, int resolutionV)
        {
            List <Vertex> output = new List <Vertex>(CalculateVertexCount(resolutionU, resolutionV));

            Console.WriteLine(resolutionV);

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

                // Generate a rotation matrix to rotate each circle in the cylinder
                // to align with the tangent vector of the center curve. The matrix
                // rotates the 'up' vector onto the 'direction' vector, using
                // Rodrigues' Rotation Formula:
                Vector3 up = new Vector3(0.0f, 0.0f, 1.0f);

                // To prevent division by zero, flip the direction if facing the other way:
                float sign = 1.0f;
                if (Vector3.Dot(up, CenterCurve.GetTangentAt(v)) < 0.0f)
                {
                    sign = -1.0f;
                }

                Vector3 direction = Vector3.Normalize(CenterCurve.GetTangentAt(v));
                Vector3 k         = Vector3.Cross(sign * direction, up);

                Matrix4x4 identity = new Matrix4x4(1.0f, 0.0f, 0.0f, 0.0f,
                                                   0.0f, 1.0f, 0.0f, 0.0f,
                                                   0.0f, 0.0f, 1.0f, 0.0f,
                                                   0.0f, 0.0f, 0.0f, 1.0f);

                Matrix4x4 K = new Matrix4x4(0.0f, -k.Z, k.Y, 0.0f,
                                            k.Z, 0.0f, -k.X, 0.0f,
                                            -k.Y, k.X, 0.0f, 0.0f,
                                            0.0f, 0.0f, 0.0f, 0.0f);

                Matrix4x4 rotationMatrix = identity + K + K * K * (1.0f / (1.0f + Vector3.Dot(up, sign * direction)));

                Matrix4x4 transformationMatrix = rotationMatrix;
                transformationMatrix.Translation = CenterCurve.GetPositionAt(v);

                float radius = Radius.GetValueAt(v);

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

                    // Calculate the position of the rings of vertices:
                    float x = sign * (float)Math.Cos(u);
                    float y = sign * (float)Math.Sin(sign * u);
                    float z = 0;

                    Vector3 position = new Vector3(x, y, z);

                    // Rotate the vector to orient the hemisphere correctly:
                    Vector3 vertexPosition = Vector3.Transform(sign * radius * position, transformationMatrix);
                    Vector3 normal         = Vector3.Transform(sign * position, rotationMatrix);

                    output.Add(new Vertex(vertexPosition, normal));
                }
            }

            return(output);
        }