public void SubdivideDetail(Vector origin, Vector forward, Vector up, double size)
        {
            var right = Vector.Cross(up, forward);
            Func <Vector, bool> isDetail = v =>
                                           GeoUtil.RectContains(GeoUtil.ProjectOnPlaneTransformed(v, origin, up, right), size);

            int triCount = TriangleCount;

            for (int i = 0; i < triCount; i++)
            {
                var n = normals[i];

                var v0 = vertices[i * 3 + 0];
                var v1 = vertices[i * 3 + 1];
                var v2 = vertices[i * 3 + 2];

                var dot = Vector.Dot(forward, n);

                bool shouldSubdivide = isDetail(v0) || isDetail(v1) || isDetail(v2);

                shouldSubdivide &= dot < -0.01;

                if (!shouldSubdivide)
                {
                    continue;
                }

                var v01 = (v0 + v1) * 0.5;
                var v12 = (v1 + v2) * 0.5;
                var v20 = (v2 + v0) * 0.5;

                vertices[i * 3 + 0] = v01;
                vertices[i * 3 + 1] = v1;
                vertices[i * 3 + 2] = v12;

                vertices.Add(v12);
                vertices.Add(v2);
                vertices.Add(v20);

                vertices.Add(v20);
                vertices.Add(v0);
                vertices.Add(v01);

                vertices.Add(v01);
                vertices.Add(v12);
                vertices.Add(v20);

                var normal = normals[i];
                normals.Add(normal);
                normals.Add(normal);
                normals.Add(normal);
            }
        }
Exemple #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="id">ID in base 10 to be converted and embedded onto the mesh</param>
        /// <param name="mesh">Mesh to be modified</param>
        /// <param name="size">Size of the largest dimension of the shape matrix, in input file's units</param>
        /// <param name="margin">Space between shape cells. (Closest distance between two crevice vertex minus thickness)</param>
        /// <param name="thickness">Thickness of crevices</param>
        /// <param name="displacement">Displacement of crevice vertices in the forward direction</param>
        /// <param name="origin">Origin of the projection plane</param>
        /// <param name="forward">Direction of the projection</param>
        /// <param name="up">Up direction of the projection plane to determine the matrix orientation</param>
        public void Embed(int id, Mesh mesh, double size, double margin, double thickness, double displacement,
                          Vector origin,
                          Vector forward, Vector up)
        {
            var right = Vector.Cross(up, forward);

            var encodedShapes = GetEncodedShapes(id);
            var lines         = ConstructMatrix(encodedShapes, size, thickness + margin);

            var vertices = mesh.vertices;
            var normals  = mesh.normals;

            for (var i = 0; i < vertices.Count; i++)
            {
                var v = vertices[i];
                var n = normals[i];

                if (Vector.Dot(forward, n) >= -0.01)
                {
                    // Not facing the projection plane, no need to continue further.
                    continue;
                }

                // TODO: Additional check to see if the face is facing the projection plane but occluded by other faces in the geometry.
                // Required for complex geometry.

                var vProj = GeoUtil.ProjectOnPlaneTransformed(v, origin, up, right);

                // Check for each line if the projected point lies inside it, with the thickness used as the threshold.
                foreach (var line in lines)
                {
                    var dist = GeoUtil.PointLineDistance(vProj, line);
                    if (dist < thickness * 0.5)
                    {
                        // Point inside a line, modify the vertex and early exit the loop, no need to check any other line.
                        bool smoothDisplacement = false;
                        if (smoothDisplacement)
                        {
                            vertices[i] = v + forward * displacement * Smoothstep(1 - dist / (thickness * 0.5));
                        }
                        else
                        {
                            vertices[i] = v + forward * displacement;
                        }

                        break;
                    }
                }
            }
        }