示例#1
0
    private void Initialize()
    {
        _meshInstance = GetNode <MeshInstance>("Mesh");
        PlaneMesh initialMesh = (PlaneMesh)_meshInstance.Mesh;

        _resX = initialMesh.SubdivideWidth + 1;
        _resZ = initialMesh.SubdivideDepth + 1;

        _noise = new OpenSimplexNoise();
        UpdateNoiseSettings();

        _surfaceTool  = new SurfaceTool();
        _meshDataTool = new MeshDataTool();

        Control HUD = GetNode <Control>("../HUD");

        HUD.Connect("UpdateSeed", this, nameof(_On_Seed_Updated));
        HUD.Connect("UpdateOctaves", this, nameof(_On_Octaves_Updated));
        HUD.Connect("UpdateAmplitude", this, nameof(_On_Amplitude_Updated));
        HUD.Connect("UpdatePeriod", this, nameof(_On_Period_Updated));
        HUD.Connect("UpdateLacunarity", this, nameof(_On_Lacunarity_Updated));
        HUD.Connect("UpdatePersistence", this, nameof(_On_Persistence_Updated));

        _initialized = true;
    }
        /**
         *  Create surface for overlay
         */
        public ArrayMesh createSurfaceOverlay(ArrayMesh mesh, string slotName, string urlPath, string overlayName, List <UMAReciepeBindPose> origBindPoses)
        {
            var file     = ResourceLoader.Load <PackedScene>(urlPath);
            var instance = file.Instance();
            var meshes   = new List <MeshInstance>();

            if (instance is Spatial)
            {
                foreach (var child in (instance as Spatial).GetChildren())
                {
                    if (child is MeshInstance)
                    {
                        meshes.Add(child as MeshInstance);
                    }
                }
            }

            if (instance is MeshInstance)
            {
                meshes.Add(instance as MeshInstance);
            }

            var mdt = new MeshDataTool();
            var idx = mesh.SurfaceFindByName(slotName);

            mdt.CreateFromSurface(mesh, idx);


            int totalSurfaces = 0;

            foreach (var mi in meshes)
            {
                var newMesh = (mi as MeshInstance).Mesh;
                var newSkin = (mi as MeshInstance).Skin;

                for (int surface = 0; surface < newMesh.GetSurfaceCount(); surface++)
                {
                    mesh.AddSurfaceFromArrays(Mesh.PrimitiveType.Triangles, createSurfaceByBones(newMesh as ArrayMesh, surface, newSkin, origBindPoses));
                    var lastId = mesh.GetSurfaceCount() - 1;

                    var mat = newMesh.SurfaceGetMaterial(surface);
                    mat.ResourceLocalToScene = true;

                    if (mat is SpatialMaterial)
                    {
                        (mat as SpatialMaterial).ParamsGrow       = true;
                        (mat as SpatialMaterial).ParamsGrowAmount = 0.005f;
                    }

                    mesh.SurfaceSetMaterial(lastId, mat);
                    mesh.SurfaceSetName(lastId, (totalSurfaces == 0) ? overlayName : overlayName + "/" + totalSurfaces);
                    totalSurfaces++;
                }

                changes++;
            }


            return(mesh);
        }
示例#3
0
    public static ArrayMesh AddNoiseToMesh(PlaneMesh plane, float[,] noiseMap, int chunkSize, int heightMultiplier, Curve heightCurve)
    {
        SurfaceTool st = new SurfaceTool();

        st.CreateFrom(plane, 0);
        ArrayMesh    mesh = new ArrayMesh();
        MeshDataTool dt   = new MeshDataTool();

        mesh = st.Commit();
        dt.CreateFromSurface(mesh, 0);
        for (int y = 0; y < chunkSize; y++)
        {
            for (int x = 0; x < chunkSize; x++)
            {
                int     z           = y;
                int     vertexIndex = z * chunkSize + x;
                Vector3 vertex      = dt.GetVertex(vertexIndex);
                vertex.y = heightCurve.Interpolate(noiseMap[chunkSize - x - 1, chunkSize - z - 1]) * heightMultiplier;
                dt.SetVertex(vertexIndex, vertex);
            }
        }
        for (int surface = 0; surface < mesh.GetSurfaceCount(); surface++)
        {
            mesh.SurfaceRemove(surface);
        }
        dt.CommitToSurface(mesh);
        st.Begin(Mesh.PrimitiveType.Triangles);
        st.CreateFrom(mesh, 0);
        st.Index();
        st.GenerateNormals();
        return(st.Commit());
    }
示例#4
0
    /// <summary>
    /// 4th attempt:  set color by most linked, not by color
    /// </summary>
    /// <param name="mdt"></param>
    public static void _SetVertexColorToBarycentric(MeshDataTool mdt)
    {
        //store info about our verticies into an array
        var vertStorage = new VertexInfo[mdt.GetVertexCount()];

        for (var vertIdx = 0; vertIdx < vertStorage.Length; vertIdx++)
        {
            vertStorage[vertIdx] = new VertexInfo(vertIdx, mdt, vertStorage);
            //set vert color to alphaBlack
            mdt.SetVertexColor(vertIdx, Colors.Transparent);
        }

        //sort verticies by degree (number of edges).   defaults to highest first
        var sortedVerts = new List <VertexInfo>(vertStorage);

        sortedVerts.Sort();

        //color channels used for verticies.  3 is ideal, but aprox 10% of verts wont be colored.
        var colorChoices = new Color[] {
            //encode 5 channels as 20% red each.
            new Color(0.2f, 0, 0, 0),
            new Color(0.4f, 0, 0, 0),
            new Color(0.6f, 0, 0, 0),
            new Color(0.8f, 0, 0, 0),
            new Color(1f, 0, 0, 0)
        };


        //////////////  various algorithm choices.   best is _WELSH_POWELL_ADJUSTED
        //_GREEDY_FACE(sortedVerts, colorChoices, mdt);
        //_GREEDY_BASIC(sortedVerts, colorChoices, mdt);
        //_CYBERREALITY(sortedVerts, colorChoices, mdt);
        //_CYBERREALITY_EDIT(sortedVerts, colorChoices, mdt);
        _WELSH_POWELL_ADJUSTED(sortedVerts, colorChoices, mdt);
    }
示例#5
0
        public VertexInfo(int idx, MeshDataTool mdt, VertexInfo[] storage)
        {
            this.storage = storage;
            this.vertIdx = idx;
            this.mdt     = mdt;
            edges        = mdt.GetVertexEdges(idx);
            faces        = mdt.GetVertexFaces(idx);
            this.pos     = mdt.GetVertex(idx);

            adjacentVerticies = new int[edges.Length];
            for (var i = 0; i < edges.Length; i++)
            {
                var edgeIdx   = edges[i];
                var edgeVert0 = mdt.GetEdgeVertex(edgeIdx, 0);
                var edgeVert1 = mdt.GetEdgeVertex(edgeIdx, 1);
                var adjacent  = edgeVert0 != idx ? edgeVert0 : edgeVert1;
                adjacentVerticies[i] = adjacent;
            }

            //better heuristic for sorting (vert with most adjcent faces)
            foreach (var faceIdx in faces)
            {
                //adjadj++;
                for (var i = 0; i < 3; i++)
                {
                    var faceVertIdx = mdt.GetFaceVertex(faceIdx, i);
                    adjadj += mdt.GetVertexFaces(faceVertIdx).Length;
                }
            }
        }
示例#6
0
    public override UnifiedObject Mirror()
    {
        StaticObject clone = (StaticObject)this.Clone();

        ArrayMesh originalMesh         = (ArrayMesh)this.m_meshInstance.Mesh;
        int       originalSurfaceCount = originalMesh.GetSurfaceCount();

        ArrayMesh newMesh = new ArrayMesh();

        for (int i = 0; i < originalSurfaceCount; i++)
        {
            MeshDataTool mdt = new MeshDataTool();
            mdt.CreateFromSurface(originalMesh, i);

            for (int j = 0; j < mdt.GetVertexCount(); j++)
            {
                Vector3 vert = mdt.GetVertex(j);
                vert.x *= -1;
                mdt.SetVertex(j, vert);
            }
            mdt.CommitToSurface(newMesh);
        }

        clone.ObjectMeshInstance.Mesh = newMesh;

        return(clone);
    }
示例#7
0
    public void Generate()
    {
        planeMesh                = new PlaneMesh();
        planeMesh.Size           = new Vector2(chunkSize, chunkSize);
        planeMesh.SubdivideDepth = Mathf.RoundToInt(chunkSize * 0.5f);
        planeMesh.SubdivideWidth = Mathf.RoundToInt(chunkSize * 0.5f);

        surfaceTool  = new SurfaceTool();
        meshDataTool = new MeshDataTool();
        surfaceTool.CreateFrom(planeMesh, 0);
        arrayPlane = surfaceTool.Commit();
        meshDataTool.CreateFromSurface(arrayPlane, 0);

        for (int i = 0; i < meshDataTool.GetVertexCount(); i++)
        {
            Vector3 vertex = meshDataTool.GetVertex(i);
            vertex.y = noise.GetNoise3d(
                vertex.x + position.x,
                vertex.y,
                vertex.z + position.z) * References.steepness;

            meshDataTool.SetVertex(i, vertex);
            avgHeight += vertex.y;
        }
        avgHeight /= meshDataTool.GetVertexCount();

        for (int i = 0; i < arrayPlane.GetSurfaceCount(); i++)
        {
            arrayPlane.SurfaceRemove(i);
        }

        for (int i = 0; i < meshDataTool.GetFaceCount(); i++)
        {
            Vector3 A      = meshDataTool.GetVertex(meshDataTool.GetFaceVertex(i, 0));
            Vector3 B      = meshDataTool.GetVertex(meshDataTool.GetFaceVertex(i, 1));
            Vector3 C      = meshDataTool.GetVertex(meshDataTool.GetFaceVertex(i, 2));
            Vector3 face   = (A + B + C) / 3 + position;
            Vector3 normal = meshDataTool.GetFaceNormal(i);
            slope += Maths.Angle(Vector3.Up, normal);
        }
        slope /= meshDataTool.GetFaceCount();

        meshDataTool.CommitToSurface(arrayPlane);
        surfaceTool.Begin(Mesh.PrimitiveType.Triangles);
        surfaceTool.CreateFrom(arrayPlane, 0);
        surfaceTool.GenerateNormals();

        meshInstance      = new MeshInstance();
        meshInstance.Mesh = surfaceTool.Commit();
        meshInstance.SetSurfaceMaterial(0, (Material)ResourceLoader.Load("res://Assets/Shader/Terrain.material"));
        meshInstance.CreateTrimeshCollision();
        meshInstance.CastShadow = GeometryInstance.ShadowCastingSetting.On;
        AddChild(meshInstance);
    }
    private void Deform()
    {
        var sn = new OpenSimplexNoise();

        sn.Period      = Period;
        sn.Octaves     = Octaves;
        sn.Seed        = Seed;
        sn.Persistence = Persistence;
        sn.Lacunarity  = Lacunarity;

        var mesh = sphere.Mesh;
        var st   = new SurfaceTool();

        st.CreateFrom(mesh, 0);

        var array = st.Commit();

        var dt = new MeshDataTool();

        dt.CreateFromSurface(array, 0);

        var count  = dt.GetVertexCount();
        var origin = Vector3.Zero;

        for (int i = 0; i < count; i++)
        {
            var vertex = dt.GetVertex(i);
            var n      = -vertex.DirectionTo(origin);
            var noise  = sn.GetNoise3d(vertex.x, vertex.y, vertex.z);
            noise   = Mathf.Clamp(noise, -1f, 1f);
            vertex += n * noise * MoveFactor;
            dt.SetVertex(i, vertex);
        }
        var surfCount = array.GetSurfaceCount();

        for (int i = 0; i < surfCount; i++)
        {
            array.SurfaceRemove(i);
        }

        dt.CommitToSurface(array);
        st.Begin(Mesh.PrimitiveType.Triangles);
        st.CreateFrom(array, 0);
        st.GenerateNormals();

        sphere.Mesh = st.Commit();

        UpdateMaterial();
    }
示例#9
0
    /// <summary>
    /// 3rd attempt:  after researching a bit I realized this is a "graph coloring" problem: https://en.wikipedia.org/wiki/Graph_coloring
    /// nice overview of some here: https://github.com/Ajaypal91/Graph_Coloring_Algorithms_Implementation
    /// here we implement welsh-powell algorithm:  https://www.youtube.com/watch?v=CQIW2mLfG04
    /// </summary>
    /// <param name="mdt"></param>
    private static void _SetVertexColorToBarycentric_WP(MeshDataTool mdt)
    {
        //store info about our verticies into an array
        var vertStorage = new VertexInfo[mdt.GetVertexCount()];

        for (var vertIdx = 0; vertIdx < vertStorage.Length; vertIdx++)
        {
            vertStorage[vertIdx] = new VertexInfo(vertIdx, mdt, vertStorage);
            //set vert color to black
            mdt.SetVertexColor(vertIdx, Colors.Transparent);
        }

        //sort verticies by degree (number of edges).   defaults to highest first
        var sortedVerts = new List <VertexInfo>(vertStorage);

        sortedVerts.Sort();
        //verts.CopyTo(sortedVerts,0);
        //Array.Sort(sortedVerts);

        var colorChoices = new Color[] { Colors.Red, Colors.Green, Colors.Blue };

        foreach (var color in colorChoices)
        {
            //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--)
            {
                var vertInfo = sortedVerts[i];
                if (vertInfo.TrySetAvailableColor(color))
                {
                    sortedVerts.RemoveAt(i);
                }
            }
        }

        //any remaining verts are uncolored!  bad.
        GD.Print($"Done building mesh.  Verticies uncolored count={sortedVerts.Count} / {mdt.GetVertexCount()}");

        //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);
        }
    }
示例#10
0
    public void RebuildOutputMesh()
    {
        GD.Print("REBUILDING COLOR MESH");

        var inputNode  = FindNode("Input") as MeshInstance;
        var outputNode = FindNode("Output") as MeshInstance;
        var mesh       = inputNode.Mesh as ArrayMesh;

        if (mesh == null)
        {
            GD.Print("no mesh found on input node.   aborting");
            return;
        }

        var surfaceCount = mesh.GetSurfaceCount();
        var surfaceQueue = new Queue <MeshDataTool>();

        for (var i = 0; i < surfaceCount; i++)
        {
            var mdt = new MeshDataTool();
            mdt.CreateFromSurface(mesh, 0);

            BarycentricProcessor._SetVertexColorToBarycentric(mdt);
            mesh.SurfaceRemove(0);
            surfaceQueue.Enqueue(mdt);
        }

        //replace our mesh with modified version
        while (surfaceQueue.Count > 0)
        {
            var mdt = surfaceQueue.Dequeue();
            mdt.CommitToSurface(mesh);
            mdt.Dispose();
        }

        outputNode.Mesh = mesh;
    }
示例#11
0
    private static void _SetVertexColorToBarycentric_old(MeshDataTool mdt)
    {
        //try looping verticies
        {
            // var marked = new System.Collections.Generic.Dictionary<string, Color>();
            // var markFailCount = 0;
            // var markIndex = 0;
            // float vertexCount = mdt.GetVertexCount();

            // for (var i = 0; i < vertexCount; i++)
            // {
            //  var vertex = mdt.GetVertex(i);
            //  var vertId = vertex.ToString("F2");
            //  // if (marked.TryGetValue(vertId, out var markedColor))
            //  // {
            //  //  GD.Print($"MARK FAIL!  {vertId}");
            //  //  mdt.SetVertexColor(i, markedColor);
            //  //  markFailCount++;
            //  //  continue;
            //  // }

            //  var channel = markIndex % 3;
            //  var color = new Color(0, 0, 0, 1);
            //  switch (channel)
            //  {
            //      case 0:
            //          color.r = 1;
            //          break;
            //      case 1:
            //          color.g = 1;
            //          break;
            //      case 2:
            //          color.b = 1;
            //          break;
            //      case 3:
            //          color.r = 1;
            //          color.g = 1;
            //          break;
            //      case 4:
            //          color.r = 1;
            //          color.b = 1;
            //          break;
            //      case 5:
            //          color.b = 1;
            //          color.g = 1;
            //          break;
            //      case 6:
            //          color.r = 1;
            //          color.g = 1;
            //          color.b = 1;
            //          break;
            //      case 7:
            //          color.r = 0;
            //          color.g = 0;
            //          color.b = 0;
            //          break;

            //  }
            //  color = new Color(0, 0, 0, 1);
            //  //marked.Add(vertId, color);
            //  markIndex++;
            //  mdt.SetVertexColor(i, color);
            // }
        }

        //private helper, gets the name of a color (assumes R,G,B, or Black)
        string _getColorName(Color color)
        {
            switch (color)
            {
            case Color c when c == Colors.Red:
                return("Red");

                break;

            case Color c when c == Colors.Green:
                return("Green");

                break;

            case Color c when c == Colors.Blue:
                return("Blue");

                break;

            case Color c when c == Colors.Black:
                return("Black");

                break;

            default:
                throw new Exception($"getColorName, unknown color={color}.  This helper function supports only Red, Green,Blue, or Black.");
            }
        }

        {
        }



        //loop all faces, assigning colors to each of it's 3 verticies.
        {
            //var faceCount = mdt.GetFaceCount();
            //var faceColorChoices = new List<string>();
            //var vertClusterColors = new Dictionary<string, string>(); //key = vertex.toString(), value = color name

            ////preprocess verticies of the mesh.
            ////reset vertex color to black.  we do this in case the model already uses R,G, or B for vertex color, which can mess up our color assigning algorithm below (we check the color of the vertex to see if it's been set)
            //var vertexCount = mdt.GetVertexCount();
            //for (var vertIdx = 0; vertIdx < vertexCount; vertIdx++)
            //{
            //	mdt.SetVertexColor(vertIdx, Colors.Black);
            //}

            ////first loop through all faces, assign red to the vertex with the most linked faces, black to others.
            ////this is to reduce chance of the green or blue colors "running out" due to other verticies being shared by faces.
            //for (var faceIdx = 0; faceIdx < faceCount; faceIdx++)
            //{
            //	//break;

            //	//the colors this faces' verticies will use.
            //	faceColorChoices.Clear();
            //	faceColorChoices.Add("Green");
            //	faceColorChoices.Add("Blue");
            //	faceColorChoices.Add("Red");


            //	//sort verts by number of linked faces, and remove any used colors
            //	var mostFacedVertFaces = 0;
            //	var mostFacedVertIdx = -1;
            //	//var sortedButUncoloredVerts = new SortedS<int, int>(); //key = faceCount, value = vertIdx
            //	// { int faces; int vertIdx } tp;// = { faces = 1, vertIdx = -1 };

            //	for (var faceVert = 0; faceVert < 3; faceVert++)
            //	{
            //		var vertIdx = mdt.GetFaceVertex(faceIdx, faceVert);
            //		var faces = mdt.GetVertexFaces(vertIdx);
            //		var vertColor = mdt.GetVertexColor(vertIdx);
            //		var vertColorName = _getColorName(vertColor);



            //		switch (vertColorName)
            //		{
            //			case "Black":
            //				//no color assigned to the vertex
            //				if (faces.Length > mostFacedVertFaces)
            //				{
            //					mostFacedVertFaces = faces.Length;
            //					mostFacedVertIdx = vertIdx;
            //				}
            //				//sortedButUncoloredVerts.Add(faces.Length, vertIdx);  //only add the vert if it's uncolored
            //				break;
            //			default:
            //				//remove the vertex's color from our choices (so the next loop through the faces's verticies wont pick it)
            //				var result = faceColorChoices.Remove(vertColorName);
            //				if (!result)
            //				{
            //					//color used twice in the vertex!  bad
            //					GD.Print($"failed, vert color used twice!!!!!  color={vertColorName} vertIdx={vertIdx}");
            //					//throw new Exception($"failed to set the faces vertex color properly.  color is used twice on the face.");
            //				}
            //				break;
            //		}
            //	}
            //	//assign color to our top uncolored vert
            //	{
            //		//var vertIdx = sortedButUncoloredVerts.
            //		if (mostFacedVertFaces > 2)
            //		{

            //			var vert = mdt.GetVertex(mostFacedVertIdx);
            //			var vertName = vert.ToString("F5");

            //			var colorChoice = faceColorChoices[0];
            //			faceColorChoices.RemoveAt(0);
            //			mdt.SetVertexColor(mostFacedVertIdx, Color.ColorN(colorChoice));
            //			if (!vertClusterColors.ContainsKey(vertName))
            //			{
            //				vertClusterColors[vertName] = colorChoice;
            //			}
            //		}
            //	}



            //	//	var mostFacedVertFaces = 0;
            //	//var mostFacedVert = -1;
            //	//var isRedAssigned = false;
            //	//var isBlueAssigned = false;
            //	//for (var faceVert = 0; faceVert < 3; faceVert++)
            //	//{
            //	//	var vertIdx = mdt.GetFaceVertex(faceIdx, faceVert);
            //	//	var vertColor = mdt.GetVertexColor(vertIdx);
            //	//	var vertColorName = _getColorName(vertColor);
            //	//	switch (vertColorName)
            //	//	{
            //	//		case "Red":
            //	//			isRedAssigned = true;
            //	//			break;
            //	//		case "Blue":
            //	//			isBlueAssigned = true;
            //	//			break;
            //	//	}

            //	//	var faces = mdt.GetVertexFaces(vertIdx);
            //	//	if (mostFacedVertFaces >= faces.Length)
            //	//	{
            //	//		continue;
            //	//	}
            //	//	mostFacedVertFaces = faces.Length;
            //	//	mostFacedVert = faceVert;
            //	//}



            //}


            //for (var faceIdx = 0; faceIdx < faceCount; faceIdx++)
            //{
            //	//the colors this faces' verticies will use.
            //	faceColorChoices.Clear();
            //	faceColorChoices.Add("Red");
            //	faceColorChoices.Add("Green");
            //	faceColorChoices.Add("Blue");


            //	//loop through all the faces' verticies and removed any colors already used.
            //	for (var faceVert = 0; faceVert < 3; faceVert++)
            //	{
            //		var vertIdx = mdt.GetFaceVertex(faceIdx, faceVert);
            //		//var vert = mdt.GetVertex(vertIdx);
            //		//var vertName = vert.ToString("F5");
            //		var vertColor = mdt.GetVertexColor(vertIdx);
            //		var vertColorName = _getColorName(vertColor);
            //		switch (vertColorName)
            //		{
            //			case "Black":
            //				//no color assigned to the vertex
            //				break;
            //			default:
            //				//remove the vertex's color from our choices (so the next loop through the faces's verticies wont pick it)
            //				var result = faceColorChoices.Remove(vertColorName);
            //				if (!result)
            //				{
            //					//color used twice in the vertex!  bad
            //					GD.Print($"failed, vert color used twice!!!!!  color={vertColorName} vertIdx={vertIdx}");
            //					//throw new Exception($"failed to set the faces vertex color properly.  color is used twice on the face.");
            //				}
            //				break;
            //		}
            //	}



            //	//loop through all the faces' verticies and assign color used by the vertCluster
            //	for (var faceVert = 0; faceVert < 3; faceVert++)
            //	{
            //		var vertIdx = mdt.GetFaceVertex(faceIdx, faceVert);
            //		var vert = mdt.GetVertex(vertIdx);
            //		var vertName = vert.ToString("F5");
            //		var vertColor = mdt.GetVertexColor(vertIdx);
            //		var vertColorName = _getColorName(vertColor);
            //		switch (vertColorName)
            //		{
            //			case "Black":
            //				//no color assigned to the vertex
            //				//so check if another another vertex with same location has this color, so use it too.
            //				if (vertClusterColors.TryGetValue(vertName, out var _tempVertCol))
            //				{
            //					if (faceColorChoices.Remove(_tempVertCol))
            //					{
            //						mdt.SetVertexColor(vertIdx, Color.ColorN(_tempVertCol));
            //					}
            //				}
            //				break;
            //			default:
            //				//vert already colored
            //				break;
            //		}
            //	}



            //	//this pass, assign all black verticies our remaining colors
            //	for (var faceVert = 0; faceVert < 3; faceVert++)
            //	{
            //		var vertIdx = mdt.GetFaceVertex(faceIdx, faceVert);
            //		var vert = mdt.GetVertex(vertIdx);
            //		var vertName = vert.ToString("F5");
            //		var vertColor = mdt.GetVertexColor(vertIdx);
            //		var vertColorName = _getColorName(vertColor);
            //		switch (vertColorName)
            //		{
            //			case "Black":
            //				//assign the vertex a color from our remaining color options for this vertex,
            //				//but we prefer using a color that other verticies at the same location are already using.

            //				string colorChoice = null;
            //				if (vertClusterColors.TryGetValue(vertName, out var _tempVertCol))
            //				{
            //					if (faceColorChoices.Remove(_tempVertCol))
            //					{
            //						//another vertex with same location has this color, so use it too.
            //						colorChoice = _tempVertCol;
            //					}
            //					else
            //					{
            //						//color already in use by another vertex, so do our "normal" color pick
            //					}
            //				}

            //				if (colorChoice is null)
            //				{
            //					//
            //					colorChoice = faceColorChoices[0];
            //					faceColorChoices.RemoveAt(0);
            //				}


            //				mdt.SetVertexColor(vertIdx, Color.ColorN(colorChoice));
            //				if (!vertClusterColors.ContainsKey(vertName))
            //				{
            //					vertClusterColors[vertName] = colorChoice;
            //				}


            //				break;
            //			default:
            //				//vertex already has a color assigned
            //				break;
            //		}


            //		//switch (faceVert)
            //		//{
            //		//	case 0:
            //		//		vertColor.r = 1;
            //		//		break;
            //		//	case 1:
            //		//		vertColor.g = 1;
            //		//		break;
            //		//	case 2:
            //		//		vertColor.b = 1;
            //		//		break;
            //		//}
            //		//mdt.SetVertexColor(vertIdx, vertColor);



            //		//if (vertColors.TryGetValue(vertName, out var _tempVertCol))
            //		//{
            //		//	mdt.getvertexc
            //		//	//if this vertex already has a color assigned to it
            //		//	vertColor = _tempVertCol;
            //		//}
            //		//else
            //		//{
            //		//	switch (priorVertColor)
            //		//	{
            //		//		case Color c when c == Colors.Black || c == Colors.Blue:
            //		//			vertColor = Colors.Red;
            //		//			break;
            //		//		case Color c when c == Colors.Red:
            //		//			vertColor = Colors.Green;
            //		//			break;
            //		//		case Color c when c == Colors.Green:
            //		//			vertColor = Colors.Blue;
            //		//			break;
            //		//	}

            //		//	mdt.SetVertexColor(vert0Idx, Colors.Red);
            //		//	lastVertCol = Colors.Red;
            //		//}

            //		////verify that color isn't already used for a vert of this face.
            //		//switch (vertColor)
            //		//{
            //		//	case Color c when c == Colors.Red:
            //		//		if (redUsed)
            //		//		{
            //		//			throw new Exception("red already used");
            //		//		}
            //		//		redUsed = true;
            //		//		break;
            //		//	case Color c when c == Colors.Green:
            //		//		if (greenUsed)
            //		//		{
            //		//			throw new Exception("green already used");
            //		//		}
            //		//		greenUsed = true;
            //		//		break;
            //		//	case Color c when c == Colors.Blue:
            //		//		if (blueUsed)
            //		//		{
            //		//			throw new Exception("blue already used");
            //		//		}
            //		//		blueUsed = true;
            //		//		break;
            //		//}

            //	}

            //}
        }
    }
示例#12
0
    /// <summary>
    /// cyberality's technique.  needs some optimization for use with big meshes.
    /// </summary>
    /// <param name="sortedVerts"></param>
    /// <param name="colorChoices"></param>
    /// <param name="mdt"></param>
    private static void _CYBERREALITY(List <VertexInfo> sortedVerts, Color[] colorChoices, MeshDataTool mdt)
    {
        var done       = new Dictionary <int, bool>();  //vertidx/isDone
        var bary       = new Dictionary <int, Color>(); //vertidx/color
        var rand       = new Random(0);
        var rand_color = new Color((float)rand.NextDouble(), (float)rand.NextDouble(), (float)rand.NextDouble());
        var nors       = new Dictionary <int, (Vector3 normal, Color color)>();  //normalIdx/normal

        for (var j = 0; j < mdt.GetFaceCount(); j++)
        {
            var fid    = mdt.GetFaceVertex(j, 0);
            var nor    = mdt.GetVertexNormal(fid);
            var coords = new List <Color>()
            {
                Colors.Red, Colors.Green, Colors.Blue
            };
            foreach (var n in nors.Keys)
            {
                var dot = nor.Dot(nors[n].normal);
                if (dot == 1)
                {
                    rand_color = nors[n].color;
                }
                else
                {
                    rand_color = new Color((float)rand.NextDouble(), (float)rand.NextDouble(), (float)rand.NextDouble());
                }
            }
            nors[fid] = (normal : nor, color : rand_color);
            for (var k = 0; k < 3; k++)
            {
                var vid = mdt.GetFaceVertex(j, k);
                if (bary.ContainsKey(vid))
                {
                    coords.Remove(bary[vid]);
                }
            }
            for (var i = 0; i < 3; i++)
            {
                var vid = mdt.GetFaceVertex(j, i);
                if (!done.ContainsKey(vid) || done[vid] != true)
                {
                    done[vid] = true;
                    var removal = Colors.Black;

                    var vert_0 = mdt.GetFaceVertex(j, 0);
                    var vert_1 = mdt.GetFaceVertex(j, 1);
                    var vert_2 = mdt.GetFaceVertex(j, 2);
                    var edge_a = mdt.GetVertex(vert_2).DirectionTo(mdt.GetVertex(vert_0));
                    var edge_b = mdt.GetVertex(vert_0).DirectionTo(mdt.GetVertex(vert_1));
                    var edge_c = mdt.GetVertex(vert_1).DirectionTo(mdt.GetVertex(vert_2));

                    if ((edge_a > edge_b) && (edge_a > edge_c))
                    {
                        removal.g = 1;
                    }
                    else if ((edge_b > edge_c) && (edge_b > edge_a))
                    {
                        removal.r = 1;
                    }
                    else
                    {
                        removal.b = 1;
                    }

                    if (coords.Count > 0)
                    {
                        var next = coords[0]; coords.RemoveAt(0);
                        bary[vid] = next + removal;
                    }
                    else
                    {
                        var coords2 = new List <Color>()
                        {
                            Colors.Red, Colors.Green, Colors.Blue
                        };

                        for (var m = 0; m < 3; m++)
                        {
                            if (m == i)
                            {
                                continue;
                            }
                            var vid2 = mdt.GetFaceVertex(j, m);
                            if (bary.ContainsKey(vid2))
                            {
                                coords2.Remove(bary[vid2]);
                            }
                            bary[vid] = coords2[0] + removal;                             //BUG?  coords was  checked to not have any....  maybe means coords2
                            coords2.RemoveAt(0);
                        }
                    }
                    mdt.SetVertexColor(vid, bary[vid]);
                }
            }
        }
    }
示例#13
0
    /// <summary>
    /// my edited version of Cyberality's technique.
    /// faster performance, about as good coverage as "greedy" algo.
    /// </summary>
    /// <param name="sortedVerts"></param>
    /// <param name="_colorChoices"></param>
    /// <param name="mdt"></param>
    private static void _CYBERREALITY_EDIT(List <VertexInfo> sortedVerts, Color[] _colorChoices, MeshDataTool mdt)
    {
        var done              = new Dictionary <int, bool>();  //vertidx/isDone
        var vertColorStorage  = new Dictionary <int, Color>(); //vertidx/color
        var rand              = new Random(0);
        var rand_color        = new Color((float)rand.NextDouble(), (float)rand.NextDouble(), (float)rand.NextDouble());
        var faceVert0MetaInfo = new Dictionary <int, (Vector3 normal, Color color)>();        //normalIdx/normal

        for (var faceIdx = 0; faceIdx < mdt.GetFaceCount(); faceIdx++)
        {
            var faceVert0Idx  = mdt.GetFaceVertex(faceIdx, 0);
            var faceVert0Norm = mdt.GetVertexNormal(faceVert0Idx);
            var colorChoices  = new List <Color>()
            {
                Colors.Red, Colors.Green, Colors.Blue
            };
            //////JASON CLEANUP:  this code block isn't actually used in the algo...
            ////foreach (var n in faceVert0MetaInfo.Keys)
            ////{
            ////	var dot = faceVert0Norm.Dot(faceVert0MetaInfo[n].normal);
            ////	if (dot == 1)
            ////	{
            ////		rand_color = faceVert0MetaInfo[n].color;
            ////	}
            ////	else
            ////	{
            ////		rand_color = new Color((float)rand.NextDouble(), (float)rand.NextDouble(), (float)rand.NextDouble());
            ////	}
            ////}
            ////faceVert0MetaInfo[faceVert0Idx] = (normal: faceVert0Norm, color: rand_color);


            //loop through all verts for the face, and remove colors from our colorChoices if a vert is already using it
            for (var faceVertId = 0; faceVertId < 3; faceVertId++)
            {
                var vertIdx = mdt.GetFaceVertex(faceIdx, faceVertId);
                if (vertColorStorage.ContainsKey(vertIdx))
                {
                    colorChoices.Remove(vertColorStorage[vertIdx]);
                }
            }


            for (var faceVertId = 0; faceVertId < 3; faceVertId++)
            {
                var vertIdx = mdt.GetFaceVertex(faceIdx, faceVertId);
                if (!done.ContainsKey(vertIdx) || done[vertIdx] != true)
                {
                    done[vertIdx] = true;
                    var removal = Colors.Black;

                    var vert_0 = mdt.GetFaceVertex(faceIdx, 0);
                    var vert_1 = mdt.GetFaceVertex(faceIdx, 1);
                    var vert_2 = mdt.GetFaceVertex(faceIdx, 2);
                    var edge_a = mdt.GetVertex(vert_2).DirectionTo(mdt.GetVertex(vert_0));
                    var edge_b = mdt.GetVertex(vert_0).DirectionTo(mdt.GetVertex(vert_1));
                    var edge_c = mdt.GetVertex(vert_1).DirectionTo(mdt.GetVertex(vert_2));

                    if ((edge_a > edge_b) && (edge_a > edge_c))
                    {
                        removal.g = 1;
                    }
                    else if ((edge_b > edge_c) && (edge_b > edge_a))
                    {
                        removal.r = 1;
                    }
                    else
                    {
                        removal.b = 1;
                    }

                    if (colorChoices.Count > 0)
                    {
                        var next = colorChoices[0]; colorChoices.RemoveAt(0);
                        vertColorStorage[vertIdx] = next + removal;
                    }
                    //JASON CLEANUP:  this else will never trigger, as there are only 3 verticies
                    else
                    {
                        GD.Print("in else!");
                        var coords2 = new List <Color>()
                        {
                            Colors.Red, Colors.Green, Colors.Blue
                        };

                        for (var m = 0; m < 3; m++)
                        {
                            if (m == faceVertId)
                            {
                                continue;
                            }
                            var vid2 = mdt.GetFaceVertex(faceIdx, m);
                            if (vertColorStorage.ContainsKey(vid2))
                            {
                                coords2.Remove(vertColorStorage[vid2]);
                            }
                            vertColorStorage[vertIdx] = coords2[0] + removal;                             //BUG?  coords was  checked to not have any....  maybe means coords2
                            coords2.RemoveAt(0);
                        }
                    }
                    mdt.SetVertexColor(vertIdx, vertColorStorage[vertIdx]);
                }
            }
        }
    }
示例#14
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);
        //}
    }
        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());
        }
示例#16
0
    // Declare member variables here. Examples:
    // private int a = 2;
    // private string b = "text";

    // Called when the node enters the scene tree for the first time.
    public override void _Ready()
    {
        var orig   = GetNode <MeshInstance>("orig");
        var tights = GetNode <MeshInstance>("tights");
        var result = GetNode <MeshInstance>("result");

        var tmpMesh     = new ArrayMesh();
        var surfaceTool = new SurfaceTool();

        surfaceTool.Begin(Mesh.PrimitiveType.Triangles);

        var tool = new MeshDataTool();

        tool.CreateFromSurface((ArrayMesh)tights.Mesh, 0);

        var tool2 = new MeshDataTool();

        tool2.CreateFromSurface((ArrayMesh)orig.Mesh, 0);

        List <Vector3> vertices = new List <Vector3>();

        for (int v = 0; v < tool2.GetVertexCount(); v++)
        {
            vertices.Add(tool2.GetVertex(v));
        }

        for (int v = 0; v < tool.GetVertexCount(); v++)
        {
            //  surfaceTool.AddNormal(tool.GetVertexNormal(v));
            //  surfaceTool.AddColor(tool.GetVertexColor(v));
            // surfaceTool.AddUv(tool.GetVertexUv(v));
            //  surfaceTool.AddUv2(tool.GetVertexUv2(v));
            //  surfaceTool.AddTangent(tool.GetVertexTangent(v));

            var newVer  = tool.GetVertex(v);
            var replace = vertices.OrderBy(df => newVer.DistanceTo(df)).FirstOrDefault();

            if (replace != null && replace != Vector3.Zero && replace.DistanceTo(newVer) > 0.03f)
            {
                GD.Print("replace" + newVer + " by dist " + replace.DistanceTo(newVer));
                surfaceTool.AddVertex(replace);
            }
            else
            {
                surfaceTool.AddVertex(newVer);
            }
        }

        for (int fc = 0; fc < tool.GetFaceCount(); fc++)
        {
            for (var i = 0; i <= 2; i++)
            {
                var ind = tool.GetFaceVertex(fc, i);
                surfaceTool.AddIndex(ind);
            }
        }


        surfaceTool.Commit(tmpMesh);
        result.Mesh = tmpMesh;
    }
示例#17
0
    /// <summary>
    /// experimental greedy mesh technique.
    /// </summary>
    /// <param name="sortedVerts"></param>
    /// <param name="colorChoices"></param>
    /// <param name="mdt"></param>
    private static void _GREEDY_FACE(List <VertexInfo> sortedVerts, Color[] colorChoices, MeshDataTool mdt)
    {
        List <VertexInfo> noColor = new List <VertexInfo>();

        for (int i = sortedVerts.Count - 1; i >= 0; i--)
        {
            var removed  = false;
            var vertInfo = sortedVerts[i];

            for (var h = 0; h < colorChoices.Length; h++)
            {
                var color = colorChoices[h];
                if (vertInfo.TrySetAvailableColor(color))
                {
                    sortedVerts.RemoveAt(i);
                    removed = true;

                    foreach (var adj0Vert in vertInfo.GetAdjacentVertInfo())
                    {
                        if (h < colorChoices.Length - 2 && adj0Vert.adjacentVerticies.Length >= 3                         //vertInfo.adjacentVerticies.Length
                            )
                        {
                            if (adj0Vert.TrySetAvailableColor(colorChoices[h + 1]))
                            {
                                ;
                            }
                        }
                        if (h < colorChoices.Length - 3 && adj0Vert.adjacentVerticies.Length >= 3                         //vertInfo.adjacentVerticies.Length
                            )
                        {
                            adj0Vert.TrySetAvailableColor(colorChoices[h + 2]);
                        }

                        foreach (var adj1Vert in adj0Vert.GetAdjacentVertInfo())
                        {
                            if (adj1Vert.adjacentVerticies.Length >= 3)                             //vertInfo.adjacentVerticies.Length)
                            //if (adj1Vert.adjacentVerticies.Length >= vertInfo.adjacentVerticies.Length)
                            {
                                adj1Vert.TrySetAvailableColor(color);
                            }
                        }
                    }


                    break;
                }
            }
            if (removed == false)
            {
                noColor.Add(vertInfo);
                //var alphaBlack = new Color(0, 0, 0, 0);
                vertInfo.TrySetAvailableColor(Colors.White, true);
                sortedVerts.RemoveAt(i);
            }
        }

        GD.Print($"_GREEDY_FACE uncolored count={noColor.Count} / {mdt.GetVertexCount()}");
    }
示例#18
0
    /// <summary>
    /// experimental greedy mesh technique.
    /// </summary>
    /// <param name="sortedVerts"></param>
    /// <param name="colorChoices"></param>
    /// <param name="mdt"></param>
    private static void _GREEDY_BASIC(List <VertexInfo> sortedVerts, Color[] colorChoices, MeshDataTool mdt)
    {
        bool TrySetAdjAdj(VertexInfo _current, Color c, List <VertexInfo> _store)
        {
            if (_store.Contains(_current) == false)
            {
                return(true);
            }
            if (_current.TrySetAvailableColor(c))
            {
                _store.Remove(_current);
                foreach (var adj0Vert in _current.GetAdjacentVertInfo())
                {
                    foreach (var adj1Vert in adj0Vert.GetAdjacentVertInfo())
                    {
                        TrySetAdjAdj(adj1Vert, c, _store);
                    }
                }
                return(true);
            }
            return(false);
        }

        List <VertexInfo> problems = new List <VertexInfo>();

        while (sortedVerts.Count > 0)
        {
            var vertInfo = sortedVerts[sortedVerts.Count - 1];
            //sortedVerts.RemoveAt(sortedVerts.Count - 1);

            for (var h = 0; h < colorChoices.Length; h++)
            {
                var color = colorChoices[h];

                //TrySetAdjAdj(vertInfo, color, sortedVerts);



                if (vertInfo.TrySetAvailableColor(color))
                {
                    sortedVerts.Remove(vertInfo);

                    //preemptively try to set adjacent and adjadj with related colors
                    foreach (var adj0Vert in vertInfo.GetAdjacentVertInfo())
                    {
                        if (h < colorChoices.Length - 2                         // && adj0Vert.adjacentVerticies.Length >= vertInfo.adjacentVerticies.Length
                            )
                        {
                            if (adj0Vert.TrySetAvailableColor(colorChoices[h + 1]))
                            {
                                ;
                            }
                        }
                        if (h < colorChoices.Length - 3                         //&& adj0Vert.adjacentVerticies.Length >= vertInfo.adjacentVerticies.Length
                            )
                        {
                            adj0Vert.TrySetAvailableColor(colorChoices[h + 2]);
                        }

                        foreach (var adj1Vert in adj0Vert.GetAdjacentVertInfo())
                        {
                            //if (adj1Vert.adjacentVerticies.Length >= vertInfo.adjacentVerticies.Length)
                            {
                                adj1Vert.TrySetAvailableColor(color);
                            }
                        }
                    }
                    break;
                }
            }
            if (sortedVerts.Contains(vertInfo))
            {
                problems.Add(vertInfo);
                vertInfo.TrySetAvailableColor(Colors.White, true);
                sortedVerts.Remove(vertInfo);
            }
        }
        GD.Print($"_GREEDY_BASIC uncolored count={problems.Count} / {mdt.GetVertexCount()}");
    }
示例#19
0
    public override void _Ready()
    {
        var mesh = new PlaneMesh();

        mesh.Size           = new Vector2(size, size);
        mesh.SubdivideDepth = 3;
        mesh.SubdivideWidth = (int)position.x == 0 ? (int)size : 3;

        var surface_tool = new SurfaceTool();

        surface_tool.CreateFrom(mesh, 0);
        var mesh_tool = new MeshDataTool();

        mesh_tool.CreateFromSurface(surface_tool.Commit(), 0);

        var biome = GetBiome(/*hydro_noise.GetNoise2dv(position / size), */ heat_noise.GetNoise2d(position.x / size / 10.0f, position.y));

        for (int i = 0; i < mesh_tool.GetVertexCount(); ++i)
        {
            var vertex            = mesh_tool.GetVertex(i);
            var vertex_global_pos = position + new Vector2(vertex.x, vertex.z);

            var height_noise_val = height_noise.GetNoise2dv(vertex_global_pos);
            vertex.y = height_noise_val * 20;
            var color_factor = (height_noise_val + 1) / 2.0f;

            var hydro_val = (int)Math.Round(hydro_noise.GetNoise2dv(vertex_global_pos));

            if ((int)vertex.x == 0 && (int)position.x == 0)
            {
                mesh_tool.SetVertexColor(i, new Color(color_factor, color_factor / 2, 0.0f));
            }
            else if (hydro_val == -1)
            {
                mesh_tool.SetVertexColor(i, biome.dry_color * color_factor);
            }
            else if (hydro_val == 1)
            {
                mesh_tool.SetVertexColor(i, biome.humid_color * color_factor);
            }
            else
            {
                mesh_tool.SetVertexColor(i, biome.ground_color * color_factor);
            }
            mesh_tool.SetVertex(i, vertex);
        }

        /*if (base_tree_mesh == null && ResourceLoader.Exists("res://assets/tree.obj"))
         * {
         *      base_tree_mesh = ResourceLoader.Load<Mesh>("res://assets/tree.obj");
         * }
         * if (base_tree_material == null && ResourceLoader.Exists("res://assets/tree.tres"))
         * {
         *      Console.WriteLine("OK");
         *      base_tree_material = ResourceLoader.Load<SpatialMaterial>("res://assets/tree.tres");
         * }
         *
         * MultiMesh trees = new MultiMesh();
         * trees.Mesh = base_tree_mesh;
         * trees.TransformFormat = MultiMesh.TransformFormatEnum.Transform3d;
         *
         * if ((int)position.x == 0)
         * {
         *      var points1 = Utility.UniformPoissonDiskSampler.SampleRectangle(-new Vector2(size, size) / 2, new Vector2(-5, size / 2.0f), biome.tree_spacing);
         *      var points2 = Utility.UniformPoissonDiskSampler.SampleRectangle(new Vector2(5, 0), new Vector2(size, size) / 2, biome.tree_spacing);
         *      trees.InstanceCount = points1.Count + points2.Count;
         *
         *      int i = 0;
         *      foreach (var p in points1)
         *      {
         *              trees.SetInstanceTransform(i, Transform.Identity.Scaled(new Vector3(1, biome.tree_size, 1)).Translated(new Vector3(p.x, height_noise.GetNoise2dv(position + p) * 20, p.y)));
         ++i;
         *      }
         *
         *      foreach (var p in points2)
         *      {
         *              trees.SetInstanceTransform(i, Transform.Identity.Scaled(new Vector3(1, biome.tree_size, 1)).Translated(new Vector3(p.x, height_noise.GetNoise2dv(position + p) * 20, p.y)));
         ++i;
         *      }
         * }
         * else
         * {
         *      var points = Utility.UniformPoissonDiskSampler.SampleRectangle(-new Vector2(size, size) / 2, new Vector2(size, size) / 2, biome.tree_spacing);
         *      trees.InstanceCount = points.Count;
         *      int i = 0;
         *      foreach (var p in points)
         *      {
         *              trees.SetInstanceTransform(i, Transform.Identity.Scaled(new Vector3(1, biome.tree_size, 1)).Translated(new Vector3(p.x, height_noise.GetNoise2dv(position + p) * 20, p.y)));
         ++i;
         *      }
         * }
         *
         * MultiMeshInstance child = new MultiMeshInstance();
         * child.Multimesh = trees;
         * child.MaterialOverride = base_tree_material;
         * AddChild(child);*/

        var array = new ArrayMesh();

        mesh_tool.CommitToSurface(array);
        Mesh = array;

        if (base_shader == null && ResourceLoader.Exists("res://assets/chunk_shader.tres"))
        {
            base_shader = ResourceLoader.Load <ShaderMaterial>("res://assets/chunk_shader.tres");
        }
        var shader = base_shader;

        MaterialOverride = shader;
    }