public void Initialize(HEU_GeoNode ownerNode, int tileIndex)
		{
			_ownerNode = ownerNode;
			_geoName = ownerNode.GeoName;
			_objName = ownerNode.ObjectNode.ObjectName;
			_tileIndex = tileIndex;
			_terrainData = null;
			_scatterTrees = null;
		}
		public void ResetParameters()
		{
			_terrainData = null;
			_scatterTrees = null;

			HEU_VolumeLayer defaultLayer = new HEU_VolumeLayer();

			foreach (HEU_VolumeLayer layer in _layers)
			{
				CopyLayer(defaultLayer, layer);
			}
		}
		/// <summary>
		/// Apply the cached scatter prototypes and instances to the given TerrainData.
		/// </summary>
		public static void ApplyScatterTrees(TerrainData terrainData, HEU_VolumeScatterTrees scatterTrees)
		{
#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);

					//Debug.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)
				{
					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];
					treeInstances[i].prototypeIndex = scatterTrees._prototypeIndices[i];
					treeInstances[i].rotation = scatterTrees._rotations[i];
					treeInstances[i].widthScale = scatterTrees._widthScales != null ? scatterTrees._widthScales[i] : 1f;
				}

				terrainData.SetTreeInstances(treeInstances, true);
			}
#endif
		}
		public void UpdateLayerFromPart(HEU_SessionBase session, HEU_PartData part)
		{
			HEU_GeoNode geoNode = part.ParentGeoNode;

			HAPI_VolumeInfo volumeInfo = new HAPI_VolumeInfo();
			bool bResult = session.GetVolumeInfo(geoNode.GeoID, part.PartID, ref volumeInfo);
			if (!bResult || volumeInfo.tupleSize != 1 || volumeInfo.zLength != 1 || volumeInfo.storage != HAPI_StorageType.HAPI_STORAGETYPE_FLOAT)
			{
				return;
			}

			string volumeName = HEU_SessionManager.GetString(volumeInfo.nameSH, session);
			part.SetVolumeLayerName(volumeName);

			//Debug.LogFormat("Part name: {0}, GeoName: {1}, Volume Name: {2}, Display: {3}", part.PartName, geoNode.GeoName, volumeName, geoNode.Displayable);

			bool bHeightPart = volumeName.Equals(HEU_Defines.HAPI_HEIGHTFIELD_LAYERNAME_HEIGHT);
			bool bMaskPart = volumeName.Equals(HEU_Defines.HAPI_HEIGHTFIELD_LAYERNAME_MASK);

			HEU_VolumeLayer layer = GetLayer(volumeName);
			if (layer == null)
			{
				layer = new HEU_VolumeLayer();
				layer._layerName = volumeName;

				if (bHeightPart)
				{
					_layers.Insert(0, layer);
				}
				else if(!bMaskPart)
				{
					_layers.Add(layer);
				}
			}

			layer._part = part;
			layer._xLength = volumeInfo.xLength;
			layer._yLength = volumeInfo.yLength;

			if (!bMaskPart)
			{
				GetPartLayerAttributes(session, geoNode.GeoID, part.PartID, layer);
			}

			if (!bHeightPart)
			{
				// Non-height parts don't have any outputs as they are simply layers carrying info
				part.DestroyAllData();
			}
			else
			{
				// Height part

				List<HEU_TreePrototypeInfo> treePrototypeInfos = HEU_TerrainUtility.GetTreePrototypeInfosFromPart(session, geoNode.GeoID, part.PartID);
				if (treePrototypeInfos != null)
				{
					if (_scatterTrees == null)
					{
						_scatterTrees = new HEU_VolumeScatterTrees();
					}
					_scatterTrees._treePrototypInfos = treePrototypeInfos;
				}
			}

			if (!_updatedLayers.Contains(layer))
			{
				if (bHeightPart)
				{
					_updatedLayers.Insert(0, layer);
				}
				else if (!bMaskPart)
				{
					_updatedLayers.Add(layer);
				}
			}
		}
		/// <summary>
		/// Grab the scatter data for the given part.
		/// This finds the properties of TreeInstances via attributes.
		/// </summary>
		/// <param name="session">Houdini session</param>
		/// <param name="geoID">Geometry ID</param>
		/// <param name="partID">Part (volume layer) ID</param>
		/// <param name="pointCount">Number of expected scatter points</param>
		public static void PopulateScatterTrees(HEU_SessionBase session, HAPI_NodeId geoID, HAPI_PartId partID, int pointCount,
			ref HEU_VolumeScatterTrees scatterTrees)
		{
			// The HEU_VolumeScatterTrees might already have been created when the volumecache was queried.
			// The "height" layer might have had prototype data which is set in _scatterTrees.
			if (scatterTrees == null)
			{
				scatterTrees = new HEU_VolumeScatterTrees();
			}

			// Get prototype indices. These indices refer to _scatterTrees._treePrototypes.
			HAPI_AttributeInfo indicesAttrInfo = new HAPI_AttributeInfo();
			int[] indices = new int[0];
			if (HEU_GeneralUtility.GetAttribute(session, geoID, partID, HEU_Defines.HEIGHTFIELD_TREEINSTANCE_PROTOTYPEINDEX, ref indicesAttrInfo, ref indices, session.GetAttributeIntData))
			{
				if (indices != null && indices.Length == pointCount)
				{
					scatterTrees._prototypeIndices = indices;
				}
				else
				{
					Debug.LogWarningFormat("Scatter instance index count for attribute {0} is not valid. Expected {1} but got {2}",
						HEU_Defines.HEIGHTFIELD_TREEINSTANCE_PROTOTYPEINDEX, pointCount, (indices != null ? indices.Length : 0));
				}
			}

			// Using the UVs as position of the instances, since they are properly mapped to the terrain tile.
			// Also getting other attributes for the TreeInstances, if they are set.
			HAPI_AttributeInfo uvAttrInfo = new HAPI_AttributeInfo();
			float[] uvs = new float[0];
			if (!HEU_GeneralUtility.GetAttribute(session, geoID, partID, HEU_Defines.HAPI_ATTRIB_UV, ref uvAttrInfo, ref uvs, session.GetAttributeFloatData))
			{
				Debug.LogWarning("UVs for scatter instances not found or valid.");
			}

			if (uvs != null && uvs.Length == (pointCount * uvAttrInfo.tupleSize))
			{
				// Get height scales
				HAPI_AttributeInfo heightAttrInfo = new HAPI_AttributeInfo();
				float[] heightscales = new float[0];
				HEU_GeneralUtility.GetAttribute(session, geoID, partID, HEU_Defines.HEIGHTFIELD_TREEINSTANCE_HEIGHTSCALE, ref heightAttrInfo, ref heightscales, session.GetAttributeFloatData);

				// Get width scales
				HAPI_AttributeInfo widthAttrInfo = new HAPI_AttributeInfo();
				float[] widthscales = new float[0];
				HEU_GeneralUtility.GetAttribute(session, geoID, partID, HEU_Defines.HEIGHTFIELD_TREEINSTANCE_WIDTHSCALE, ref widthAttrInfo, ref widthscales, session.GetAttributeFloatData);

				// Get orientation
				HAPI_AttributeInfo orientAttrInfo = new HAPI_AttributeInfo();
				float[] orients = new float[0];
				HEU_GeneralUtility.GetAttribute(session, geoID, partID, HEU_Defines.HAPI_ATTRIB_ORIENT, ref orientAttrInfo, ref orients, session.GetAttributeFloatData);

				// Get color
				HAPI_AttributeInfo colorAttrInfo = new HAPI_AttributeInfo();
				float[] colors = new float[0];
				HEU_GeneralUtility.GetAttribute(session, geoID, partID, HEU_Defines.HAPI_ATTRIB_COLOR, ref colorAttrInfo, ref colors, session.GetAttributeFloatData);

				// Get lightmap color
				HAPI_AttributeInfo lightmapColorAttrInfo = new HAPI_AttributeInfo();
				float[] lightmapColors = new float[0];
				HEU_GeneralUtility.GetAttribute(session, geoID, partID, HEU_Defines.HEIGHTFIELD_TREEINSTANCE_LIGHTMAPCOLOR, ref lightmapColorAttrInfo, ref lightmapColors, session.GetAttributeFloatData);

				scatterTrees._positions = new Vector3[pointCount];

				if (heightAttrInfo.exists && (heightscales.Length == pointCount))
				{
					scatterTrees._heightScales = heightscales;
				}

				if (widthAttrInfo.exists && (widthscales.Length == pointCount))
				{
					scatterTrees._widthScales = widthscales;
				}

				if (orientAttrInfo.exists && (orients.Length == orientAttrInfo.tupleSize * pointCount))
				{
					scatterTrees._rotations = new float[pointCount];
				}

				if (colorAttrInfo.exists && (colors.Length == colorAttrInfo.tupleSize * pointCount))
				{
					scatterTrees._colors = new Color32[pointCount];
				}

				if (lightmapColorAttrInfo.exists && (lightmapColors.Length == lightmapColorAttrInfo.tupleSize * pointCount))
				{
					scatterTrees._lightmapColors = new Color32[pointCount];
				}

				for (int i = 0; i < pointCount; ++i)
				{
					scatterTrees._positions[i] = new Vector3(1.0f - uvs[i * uvAttrInfo.tupleSize + 1],
																	 0,
																	 uvs[i * uvAttrInfo.tupleSize + 0]);

					if (scatterTrees._colors != null)
					{
						scatterTrees._colors[i] =
							new Color32((byte)(colors[i * colorAttrInfo.tupleSize + 0] * 255),
										(byte)(colors[i * colorAttrInfo.tupleSize + 1] * 255),
										(byte)(colors[i * colorAttrInfo.tupleSize + 2] * 255),
										(byte)(colors[i * colorAttrInfo.tupleSize + 3] * 255));
					}

					if (scatterTrees._lightmapColors != null)
					{
						scatterTrees._lightmapColors[i] =
							new Color32((byte)(lightmapColors[i * lightmapColorAttrInfo.tupleSize + 0] * 255),
										(byte)(lightmapColors[i * lightmapColorAttrInfo.tupleSize + 1] * 255),
										(byte)(lightmapColors[i * lightmapColorAttrInfo.tupleSize + 2] * 255),
										(byte)(lightmapColors[i * lightmapColorAttrInfo.tupleSize + 3] * 255));
					}

					if (scatterTrees._rotations != null)
					{
						Quaternion quaternion = new Quaternion(
							orients[i * orientAttrInfo.tupleSize + 0], 
							orients[i * orientAttrInfo.tupleSize + 1], 
							orients[i * orientAttrInfo.tupleSize + 2], 
							orients[i * orientAttrInfo.tupleSize + 3]);
						Vector3 euler = quaternion.eulerAngles;
						euler.y = -euler.y;
						euler.z = -euler.z;
						scatterTrees._rotations[i] = euler.y * Mathf.Deg2Rad;
					}
				}
			}
		}
示例#6
0
	public void UpdateLayerFromPart(HEU_SessionBase session, HEU_PartData part)
	{
	    HEU_GeoNode geoNode = part.ParentGeoNode;

	    HAPI_VolumeInfo volumeInfo = new HAPI_VolumeInfo();
	    bool bResult = session.GetVolumeInfo(geoNode.GeoID, part.PartID, ref volumeInfo);
	    if (!bResult || volumeInfo.tupleSize != 1 || volumeInfo.zLength != 1 || volumeInfo.storage != HAPI_StorageType.HAPI_STORAGETYPE_FLOAT)
	    {
		return;
	    }

	    string volumeName = HEU_SessionManager.GetString(volumeInfo.nameSH, session);
	    part.SetVolumeLayerName(volumeName);

	    //Debug.LogFormat("Part name: {0}, GeoName: {1}, Volume Name: {2}, Display: {3}", part.PartName, geoNode.GeoName, volumeName, geoNode.Displayable);

	    HFLayerType layerType = HEU_TerrainUtility.GetHeightfieldLayerType(session, geoNode.GeoID, part.PartID, volumeName);

	    HEU_VolumeLayer layer = GetLayer(volumeName);
	    if (layer == null)
	    {
		layer = new HEU_VolumeLayer();
		layer._layerName = volumeName;

		if (layerType == HFLayerType.HEIGHT)
		{
		    _layers.Insert(0, layer);
		}
		else if (layerType != HFLayerType.MASK)
		{
		    _layers.Add(layer);
		}
	    }

	    layer._part = part;
	    layer._xLength = volumeInfo.xLength;
	    layer._yLength = volumeInfo.yLength;
	    layer._layerType = layerType;

	    if (layerType != HFLayerType.MASK)
	    {
		GetPartLayerAttributes(session, geoNode.GeoID, part.PartID, layer);
	    }

	    if (layerType != HFLayerType.HEIGHT)
	    {
		// Non-height parts don't have any outputs as they are simply layers carrying info
		part.DestroyAllData();
	    }
	    else
	    {
		// Height part
		// Might contain terrain properties via attributes (i.e. not layer specific, but for entire terrain)

		// Scatter Tree Prototypes
		List<HEU_TreePrototypeInfo> treePrototypeInfos = HEU_TerrainUtility.GetTreePrototypeInfosFromPart(session, geoNode.GeoID, part.PartID);
		if (treePrototypeInfos != null)
		{
		    if (_scatterTrees == null)
		    {
			_scatterTrees = new HEU_VolumeScatterTrees();
		    }
		    _scatterTrees._treePrototypInfos = treePrototypeInfos;
		}

		HEU_TerrainUtility.PopulateDetailProperties(session, geoNode.GeoID,
			part.PartID, ref _detailProperties);
	    }

	    if (!_updatedLayers.Contains(layer))
	    {
		if (layerType == HFLayerType.HEIGHT)
		{
		    _updatedLayers.Insert(0, layer);
		}
		else if (layerType != HFLayerType.MASK)
		{
		    _updatedLayers.Add(layer);
		}
	    }
	}
示例#7
0
		public void UpdateLayerFromPart(HEU_SessionBase session, HEU_PartData part)
		{
			HEU_GeoNode geoNode = part.ParentGeoNode;

			HAPI_VolumeInfo volumeInfo = new HAPI_VolumeInfo();
			bool bResult = session.GetVolumeInfo(geoNode.GeoID, part.PartID, ref volumeInfo);
			if (!bResult || volumeInfo.tupleSize != 1 || volumeInfo.zLength != 1 || volumeInfo.storage != HAPI_StorageType.HAPI_STORAGETYPE_FLOAT)
			{
				return;
			}

			string volumeName = HEU_SessionManager.GetString(volumeInfo.nameSH, session);
			part.SetVolumeLayerName(volumeName);

			//Debug.LogFormat("Part name: {0}, GeoName: {1}, Volume Name: {2}, Display: {3}", part.PartName, geoNode.GeoName, volumeName, geoNode.Displayable);

			HEU_VolumeLayer.HFLayerType layerType = GetHeightfieldLayerType(session, geoNode.GeoID, part.PartID, volumeName);

			HEU_VolumeLayer layer = GetLayer(volumeName);
			if (layer == null)
			{
				layer = new HEU_VolumeLayer();
				layer._layerName = volumeName;

				if (layerType == HEU_VolumeLayer.HFLayerType.HEIGHT)
				{
					_layers.Insert(0, layer);
				}
				else if(layerType != HEU_VolumeLayer.HFLayerType.MASK)
				{
					_layers.Add(layer);
				}
			}

			layer._part = part;
			layer._xLength = volumeInfo.xLength;
			layer._yLength = volumeInfo.yLength;
			layer._layerType = layerType;

			if (layerType != HEU_VolumeLayer.HFLayerType.MASK)
			{
				GetPartLayerAttributes(session, geoNode.GeoID, part.PartID, layer);
			}

			if (layerType != HEU_VolumeLayer.HFLayerType.HEIGHT)
			{
				// Non-height parts don't have any outputs as they are simply layers carrying info
				part.DestroyAllData();
			}
			else
			{
				// Height part
				// Might contain terrain properties via attributes (i.e. not layer specific, but for entire terrain)

				// Scatter Tree Prototypes
				List<HEU_TreePrototypeInfo> treePrototypeInfos = HEU_TerrainUtility.GetTreePrototypeInfosFromPart(session, geoNode.GeoID, part.PartID);
				if (treePrototypeInfos != null)
				{
					if (_scatterTrees == null)
					{
						_scatterTrees = new HEU_VolumeScatterTrees();
					}
					_scatterTrees._treePrototypInfos = treePrototypeInfos;
				}

				// Detail distance
				HAPI_AttributeInfo detailDistanceAttrInfo = new HAPI_AttributeInfo();
				int[] detailDistances = new int[0];
				HEU_GeneralUtility.GetAttribute(session, geoNode.GeoID, part.PartID, 
					HEU_Defines.HEIGHTFIELD_DETAIL_DISTANCE, ref detailDistanceAttrInfo, ref detailDistances, 
					session.GetAttributeIntData);

				// Scatter Detail Resolution Per Patch (note that Detail Resolution comes from HF layer size)
				HAPI_AttributeInfo resolutionPatchAttrInfo = new HAPI_AttributeInfo();
				int[] resolutionPatches = new int[0];
				HEU_GeneralUtility.GetAttribute(session, geoNode.GeoID, part.PartID, 
					HEU_Defines.HEIGHTFIELD_DETAIL_RESOLUTION_PER_PATCH, ref resolutionPatchAttrInfo, 
					ref resolutionPatches, session.GetAttributeIntData);


				if (_detailProperties == null)
				{
					_detailProperties = new HEU_DetailProperties();
				}

				// Unity only supports 1 set of detail resolution properties per terrain
				int arraySize = 1;

				if (detailDistanceAttrInfo.exists && detailDistances.Length >= arraySize)
				{
					_detailProperties._detailDistance = detailDistances[0];
				}

				if (resolutionPatchAttrInfo.exists && resolutionPatches.Length >= arraySize)
				{
					_detailProperties._detailResolutionPerPatch = resolutionPatches[0];
				}
			}

			if (!_updatedLayers.Contains(layer))
			{
				if (layerType == HEU_VolumeLayer.HFLayerType.HEIGHT)
				{
					_updatedLayers.Insert(0, layer);
				}
				else if (layerType != HEU_VolumeLayer.HFLayerType.MASK)
				{
					_updatedLayers.Add(layer);
				}
			}
		}