Point Scatter and Tree Instance Scatter

   1616   1   0
User Avatar
Member
14 posts
Joined: 6月 2022
Offline
Hi,

I'm having trouble when outputting point data to unity through session sync. To use the tree instance scatter, I need to apply the attribute to points:
unity_hf_treeinstance_prototypeindex - Set the index (Integer) of the TreePrototype to use (starting at 0)

When scattering points to place other objects (in this case rocks), I apply the unity_instance attribute.

The problem is that the default unity_hf_tree_instance_prototypeindex is 0, which is also applied to each point with the unity_instance for my rock scatter, causing trees to be scattered at each rock location.

Is there an ignore attribute I need to add to non tree points, or a different way of combining the data than a merge node, which sets the default tree index to 0 for all points?

I've tried modifying the start index for trees to 1 so that when points are merged the default (0) index isn't used, but I'm still seeing trees instanced on the terrain through the tree system at the location of all points:

	public static List<HEU_TreePrototypeInfo> GetTreePrototypeInfosFromPart(HEU_SessionBase session, HAPI_NodeId geoID, HAPI_PartId partID)
	{
	    List<HEU_TreePrototypeInfo> treePrototypes = new List<HEU_TreePrototypeInfo>();

	    // Each TreePrototype data is stored as a string attribute, under the 'HEU_Defines.HEIGHTFIELD_TREEPROTOTYPE + index'
	    // name. So check and parse until no more valid attributes found.

		// CHANGED START INDEX 0 -> 1
	    int index = 1;
	    while (true)
	    {
            // Does this attribute exist?
            string attrName = HEU_Defines.HEIGHTFIELD_TREEPROTOTYPE + index.ToString();
            if (!HEU_GeneralUtility.HasAttribute(session, geoID, partID, attrName, HAPI_AttributeOwner.HAPI_ATTROWNER_PRIM))
            {
                break;
            }

            index++;

            // Get the string value
            HAPI_AttributeInfo treeAttrInfo = new HAPI_AttributeInfo();
            string[] protoAttrString = HEU_GeneralUtility.GetAttributeStringData(session, geoID, partID,
                attrName, ref treeAttrInfo);
            if (protoAttrString == null || protoAttrString.Length == 0 || string.IsNullOrEmpty(protoAttrString[0]))
            {
                break;
            }

            // Parse the attribute string value:
            // Only expecting a single element here, comma-separated for the asset path and bend factor:
            // => asset_path,bend_factor
            string[] properties = protoAttrString[0].Split(',');
            if (properties.Length > 0 && !string.IsNullOrEmpty(properties[0]))
            {
                HEU_TreePrototypeInfo prototype = new HEU_TreePrototypeInfo();
                prototype._prefabPath = properties[0];
                if (properties.Length >= 2)
                {
                float.TryParse(properties[1], out prototype._bendfactor);
                }

                treePrototypes.Add(prototype);
            }
	    }

	    return treePrototypes.Count > 0 ? treePrototypes : null;
	}
Edited by Monumental - 2022年9月15日 12:55:31

Attachments:
point_data.png (315.4 KB)
prim_data.png (34.1 KB)
unity_tree_instance.png (59.9 KB)

User Avatar
Member
14 posts
Joined: 6月 2022
Offline
I had to also make the following changes to use an index starting at 1:


public static void ApplyScatterTrees(TerrainData terrainData, HEU_VolumeScatterTrees scatterTrees, int tileIndex)
	{
#if UNITY_2019_1_OR_NEWER
	    if (scatterTrees == null || scatterTrees._treePrototypInfos == null || scatterTrees._treePrototypInfos.Count == 0)
	    {
		return;
	    }

	    // Load and set TreePrototypes
	    GameObject prefabGO;
	    List<TreePrototype> treePrototypes = new List<TreePrototype>();
	    for (int i = 0; i < scatterTrees._treePrototypInfos.Count; ++i)
	    {
		prefabGO = HEU_AssetDatabase.LoadAssetAtPath(scatterTrees._treePrototypInfos[i]._prefabPath, typeof(GameObject)) as GameObject;
		if (prefabGO != null)
		{
		    TreePrototype prototype = new TreePrototype();
		    prototype.prefab = prefabGO;
		    prototype.bendFactor = scatterTrees._treePrototypInfos[i]._bendfactor;
		    treePrototypes.Add(prototype);

		    //HEU_Logger.LogFormat("Added Tree Prototype: {0} - {1}", scatterTrees._treePrototypInfos[i]._prefabPath, scatterTrees._treePrototypInfos[i]._bendfactor);
		}
	    }
	    terrainData.treePrototypes = treePrototypes.ToArray();
	    terrainData.RefreshPrototypes();

	    if (scatterTrees._positions != null && scatterTrees._positions.Length > 0
		    && scatterTrees._prototypeIndices != null && scatterTrees._prototypeIndices.Length == scatterTrees._positions.Length)
	    {
		TreeInstance[] treeInstances = new TreeInstance[scatterTrees._positions.Length];

		for (int i = 0; i < scatterTrees._positions.Length; ++i)
		{

            // skip tree index 0
            if( scatterTrees._prototypeIndices[i] < 1 )
                continue;

		    if (scatterTrees._terrainTiles != null && i < scatterTrees._terrainTiles.Length && scatterTrees._terrainTiles[i] != -1 && scatterTrees._terrainTiles[i] != tileIndex)
		    {
		        continue;
		    }

		    treeInstances[i] = new TreeInstance();
		    treeInstances[i].color = scatterTrees._colors != null ? scatterTrees._colors[i] : new Color32(255, 255, 255, 255);
		    treeInstances[i].heightScale = scatterTrees._heightScales != null ? scatterTrees._heightScales[i] : 1f;
		    treeInstances[i].lightmapColor = scatterTrees._lightmapColors != null ? scatterTrees._lightmapColors[i] : new Color32(255, 255, 255, 255);
		    treeInstances[i].position = scatterTrees._positions[i];

                    // use correct index, which now start at 1
		    treeInstances[i].prototypeIndex = scatterTrees._prototypeIndices[i] - 1;

		    treeInstances[i].rotation = scatterTrees._rotations[i];
		    treeInstances[i].widthScale = scatterTrees._widthScales != null ? scatterTrees._widthScales[i] : 1f;
		}

		terrainData.SetTreeInstances(treeInstances, true);
	    }
#endif
	}


While doing this I noticed that the tree scattering makes the assumption that the height layer is the first layer.
Edited by Monumental - 2022年9月15日 16:10:36
  • Quick Links