예제 #1
0
        /// <summary>
        /// will set the color if our vertex color is black (IE: not already set), and no adjacent verticies are using that color
        /// if color already set to the same color, will also return true
        /// </summary>
        /// <param name="c"></param>
        /// <returns></returns>
        public bool TrySetAvailableColor(Color c, bool force = false)
        {
            if (force == true)
            {
                mdt.SetVertexColor(vertIdx, c);
                return(true);
            }
            var currentColor = mdt.GetVertexColor(vertIdx);

            if (currentColor == c)
            {
                return(true);
            }
            //
            if (currentColor != Colors.Transparent)
            {
                return(false);
            }
            foreach (var adjIdx in adjacentVerticies)
            {
                var adjColor = mdt.GetVertexColor(adjIdx);
                if (adjColor == c)
                {
                    return(false);
                }
            }
            mdt.SetVertexColor(vertIdx, c);
            return(true);
        }
        private Godot.Collections.Array createSurfaceByBones(ArrayMesh mesh, int surface, Skin newSkin, List <UMAReciepeBindPose> origBindPoses)
        {
            var mdt = new MeshDataTool();

            mdt.CreateFromSurface(mesh, surface);

            var st = new SurfaceTool();

            st.Begin(Mesh.PrimitiveType.Triangles);

            var newBindPoses = new List <UMAReciepeBindPose>();

            if (newSkin != null)
            {
                for (int i = 0; i < newSkin.GetBindCount(); i++)
                {
                    newBindPoses.Add(new UMAReciepeBindPose
                    {
                        boneName  = newSkin.GetBindName(i),
                        transform = newSkin.GetBindPose(i),
                        boneIndex = newSkin.GetBindBone(i)
                    });
                }
            }

            var boneAmount = 0;

            for (int i = 0; i < mdt.GetVertexCount(); i++)
            {
                var oldVer  = mdt.GetVertex(i);
                var oldNorm = mdt.GetVertexNormal(i);

                var newVer  = new Vector3();
                var newNorm = new Vector3();

                var indexes = mdt.GetVertexBones(i);

                //  st.AddTangent(mdt.GetVertexTangent(i));
                st.AddBones(mdt.GetVertexBones(i));
                st.AddWeights(mdt.GetVertexWeights(i));

                int boneId = 0;
                foreach (var weight in mdt.GetVertexWeights(i))
                {
                    if (newBindPoses.Count >= indexes[boneId] && origBindPoses.Count >= indexes[boneId])
                    {
                        var restBoneNew      = newBindPoses[indexes[boneId]];
                        var restBoneTemplate = origBindPoses[indexes[boneId]];

                        var dataup    = restBoneNew.transform.Xform(Vector3.Up);
                        var dataright = restBoneNew.transform.Xform(Vector3.Right);

                        var templateup    = restBoneTemplate.transform.Xform(Vector3.Up);
                        var templateright = restBoneTemplate.transform.Xform(Vector3.Right);

                        if (Mathf.Abs(dataup.AngleTo(templateup)) > 1 || Mathf.Abs(dataright.AngleTo(templateright)) > 1)
                        {
                            Transform convertMatrix = restBoneTemplate.transform.Inverse() * restBoneNew.transform;

                            newVer  += convertMatrix.Xform(oldVer) * weight;
                            newNorm += convertMatrix.basis.Xform(oldNorm) * weight;
                        }
                        else
                        {
                            newVer  += oldVer * weight;
                            newNorm += oldNorm * weight;
                        }
                    }
                    else
                    {
                        newVer  += oldVer * weight;
                        newNorm += oldNorm * weight;
                    }

                    boneId++;
                }


                st.AddUv(mdt.GetVertexUv(i));

                if (mdt.GetVertexColor(i) != null)
                {
                    st.AddColor(mdt.GetVertexColor(i));
                }

                if (mdt.GetVertexUv2(i) != null)
                {
                    st.AddUv2(mdt.GetVertexUv2(i));
                }

                st.AddNormal(newNorm);
                st.AddVertex(newVer);

                boneAmount += mdt.GetVertexBones(i).Length;
            }

            //creating indexes
            for (int face = 0; face < mdt.GetFaceCount(); face++)
            {
                for (int faceI = 0; faceI < 3; faceI++)
                {
                    var ind = mdt.GetFaceVertex(face, faceI);
                    st.AddIndex(ind);
                }
            }

            st.GenerateTangents();
            return(st.CommitToArrays());
        }
예제 #3
0
    /// <summary>
    ///
    /// </summary>
    /// <param name="sortedVerts"></param>
    /// <param name="colorChoices"></param>
    /// <param name="mdt"></param>
    private static void _WELSH_POWELL_ADJUSTED(List <VertexInfo> sortedVerts, Color[] colorChoices, MeshDataTool mdt)
    {
        for (var h = 0; h < colorChoices.Length; h++)
        {
            var color = colorChoices[h];


            //enumerate in reverse so we inspect our verticies with highest degree first (most edges)
            //and also lets us remove from the list directly
            for (int i = sortedVerts.Count - 1; i >= 0; i--)
            {
                //if we remove too many, reset our index.   this means we might invoke this loop on an element more than once.
                //but that's ok as it doesn't have negative consiquences.
                if (i >= sortedVerts.Count)
                {
                    i = sortedVerts.Count - 1;
                }


                var vertInfo = sortedVerts[i];
                if (vertInfo.TrySetAvailableColor(color))
                {
                    sortedVerts.RemoveAt(i);

                    //preemptively try to set adjacent and adjadj with related colors
                    foreach (var adj0Vert in vertInfo.GetAdjacentVertInfo())
                    {
                        //JASON OPTIMIZATION: reduces non-colored by aprox 8% on sibnek 100k vert mesh.
                        foreach (var adj1Vert in adj0Vert.GetAdjacentVertInfo())
                        {
                            if (adj1Vert.adjacentVerticies.Length > vertInfo.adjacentVerticies.Length * 0.75)
                            {
                                adj1Vert.TrySetAvailableColor(color);
                            }
                        }
                    }
                }
            }
        }
        //any remaining verts are uncolored!  bad.
        GD.Print($"Done building mesh.  Verticies uncolored count={sortedVerts.Count} / {mdt.GetVertexCount()}");

        //loop through all faces, finding the vertex for the longest edge,
        //and encode that into green channel = 0.1;
        //may be used by the shader to remove interrior edges
        var faceCount = mdt.GetFaceCount();

        for (var faceIdx = 0; faceIdx < faceCount; faceIdx++)
        {
            var vertIdx0 = mdt.GetFaceVertex(faceIdx, 0);
            var vertIdx1 = mdt.GetFaceVertex(faceIdx, 1);
            var vertIdx2 = mdt.GetFaceVertex(faceIdx, 2);
            var vert0    = mdt.GetVertex(vertIdx0);
            var vert1    = mdt.GetVertex(vertIdx1);
            var vert2    = mdt.GetVertex(vertIdx2);

            var edgeLen1 = vert0.DistanceTo(vert1);
            var edgeLen2 = vert0.DistanceTo(vert2);
            var edgeLen3 = vert1.DistanceTo(vert2);

            int longestEdgeVertIdx = -1;
            if (edgeLen1 > edgeLen2 && edgeLen1 > edgeLen3)
            {
                longestEdgeVertIdx = vertIdx2;
            }
            if (edgeLen2 > edgeLen1 && edgeLen2 > edgeLen3)
            {
                longestEdgeVertIdx = vertIdx1;
            }
            if (edgeLen3 > edgeLen1 && edgeLen3 > edgeLen2)
            {
                longestEdgeVertIdx = vertIdx0;
            }
            if (longestEdgeVertIdx != -1)
            {
                var curCol = mdt.GetVertexColor(longestEdgeVertIdx);
                //encode that this vertext has longest edge (used in shader code)
                curCol.g += 0.1f;
                mdt.SetVertexColor(longestEdgeVertIdx, curCol);
            }
        }



        ////for any remaining verticies color alpha
        //var alphaBlack = new Color(0, 0, 0, 0);
        //for (int i = sortedVerts.Count - 1; i >= 0; i--)
        //{
        //	var vertInfo = sortedVerts[i];
        //	mdt.SetVertexColor(vertInfo.vertIdx, alphaBlack);
        //	//vertInfo.TrySetAvailableColor(Colors.White, true);
        //}
    }