예제 #1
0
		public void SetupMeshAndMaterials(HEU_HoudiniAsset asset, HAPI_PartType partType, GameObject outputGameObject)
		{
			_outputMesh = null;
			_outputGameObject = null;

			if (HEU_HAPIUtility.IsSupportedPolygonType(partType))
			{
				// Get the generated mesh. If mesh is missing, nothing we can do.
				MeshFilter meshFilter = outputGameObject.GetComponent<MeshFilter>();
				if (meshFilter != null && meshFilter.sharedMesh != null)
				{
					_outputMesh = meshFilter.sharedMesh;
				}
				else
				{
					// Without a valid mesh, we won't be able to paint so nothing else to do
					return;
				}

				_outputGameObject = outputGameObject;

				if (_localMaterial == null)
				{
					MeshRenderer meshRenderer = _outputGameObject.GetComponent<MeshRenderer>();
					if(meshRenderer != null)
					{
						_localMaterial = HEU_MaterialFactory.GetNewMaterialWithShader(null, HEU_MaterialFactory.GetHoudiniShaderPath(HEU_Defines.DEFAULT_VERTEXCOLOR_SHADER), HEU_Defines.EDITABLE_MATERIAL, false);
					}
				}
			}
		}
        /// <summary>
        /// Process the part at the given index, creating its data (geometry),
        /// and adding it to the list of parts.
        /// </summary>
        /// <param name="session"></param>
        /// <param name="partID"></param>
        /// <returns>A valid HEU_PartData if it has been successfully processed.</returns>
        private void ProcessPart(HEU_SessionBase session, int partID, ref HAPI_PartInfo partInfo, ref HEU_PartData partData)
        {
            HEU_HoudiniAsset parentAsset = ParentAsset;
            bool             bResult     = true;

            //Debug.LogFormat("Part: name={0}, id={1}, type={2}, instanced={3}, instance count={4}, instance part count={5}", HEU_SessionManager.GetString(partInfo.nameSH, session), partID, partInfo.type, partInfo.isInstanced, partInfo.instanceCount, partInfo.instancedPartCount);

#if HEU_PROFILER_ON
            float processPartStartTime = Time.realtimeSinceStartup;
#endif

            bool isPartEditable    = IsIntermediateOrEditable();
            bool isAttribInstancer = false;

            if (IsGeoInputType())
            {
                // Setup for input node to accept inputs
                if (_inputNode == null)
                {
                    string partName = HEU_SessionManager.GetString(partInfo.nameSH, session);
                    _inputNode = HEU_InputNode.CreateSetupInput(GeoID, 0, partName, HEU_InputNode.InputNodeType.NODE, ParentAsset);
                    if (_inputNode != null)
                    {
                        ParentAsset.AddInputNode(_inputNode);
                    }
                }

                if (HEU_HAPIUtility.IsSupportedPolygonType(partInfo.type) && partInfo.vertexCount == 0)
                {
                    // No geometry for input asset

                    if (partData != null)
                    {
                        // Clean up existing part
                        HEU_PartData.DestroyPart(partData);
                        partData = null;
                    }

                    // No need to process further since we don't have geometry
                    return;
                }
            }
            else
            {
                // Preliminary check for attribute instancing (mesh type with no verts but has points with instances)
                if (HEU_HAPIUtility.IsSupportedPolygonType(partInfo.type) && partInfo.vertexCount == 0 && partInfo.pointCount > 0)
                {
                    HAPI_AttributeInfo instanceAttrInfo = new HAPI_AttributeInfo();
                    HEU_GeneralUtility.GetAttributeInfo(session, GeoID, partID, HEU_PluginSettings.UnityInstanceAttr, ref instanceAttrInfo);
                    if (instanceAttrInfo.exists && instanceAttrInfo.count > 0)
                    {
                        isAttribInstancer = true;
                    }
                }
            }

            if (partInfo.type == HAPI_PartType.HAPI_PARTTYPE_INVALID)
            {
                // Clean up invalid parts
                if (partData != null)
                {
                    HEU_PartData.DestroyPart(partData);
                    partData = null;
                }
            }
            else if (partInfo.type < HAPI_PartType.HAPI_PARTTYPE_MAX)
            {
                // Process the part based on type. Keep or ignore.

                // We treat parts of type curve as curves, along with geo nodes that are editable and type curves
                if (partInfo.type == HAPI_PartType.HAPI_PARTTYPE_CURVE)
                {
                    if (partData == null)
                    {
                        partData = ScriptableObject.CreateInstance <HEU_PartData>();
                    }

                    partData.Initialize(session, partID, GeoID, _containerObjectNode.ObjectID, this, ref partInfo,
                                        HEU_PartData.PartOutputType.CURVE, isPartEditable, _containerObjectNode.IsInstancer(), false);
                    SetupGameObjectAndTransform(partData, parentAsset);
                    partData.ProcessCurvePart(session);
                }
                else if (partInfo.type == HAPI_PartType.HAPI_PARTTYPE_VOLUME)
                {
                    // We only process "height" volume parts. Other volume parts are ignored for now.

#if TERRAIN_SUPPORTED
                    HAPI_VolumeInfo volumeInfo = new HAPI_VolumeInfo();
                    bResult = session.GetVolumeInfo(GeoID, partID, ref volumeInfo);
                    if (!bResult)
                    {
                        Debug.LogErrorFormat("Unable to get volume info for geo node {0} and part {1} ", GeoID, partID);
                    }
                    else
                    {
                        if (Displayable && !IsIntermediateOrEditable())
                        {
                            if (partData == null)
                            {
                                partData = ScriptableObject.CreateInstance <HEU_PartData>();
                            }
                            else
                            {
                                // Clear volume data (case where switching from polygonal mesh to volume output)
                                partData.ClearGeneratedMeshOutput();
                            }

                            partData.Initialize(session, partID, GeoID, _containerObjectNode.ObjectID, this, ref partInfo,
                                                HEU_PartData.PartOutputType.VOLUME, isPartEditable, _containerObjectNode.IsInstancer(), false);
                            SetupGameObjectAndTransform(partData, ParentAsset);
                        }
                    }
#else
                    Debug.LogWarningFormat("Terrain (heightfield volume) is not yet supported.");
#endif
                }
                else if (partInfo.type == HAPI_PartType.HAPI_PARTTYPE_INSTANCER || isAttribInstancer)
                {
                    if (partData == null)
                    {
                        partData = ScriptableObject.CreateInstance <HEU_PartData>();
                    }
                    else
                    {
                        partData.ClearGeneratedMeshOutput();
                        partData.ClearGeneratedVolumeOutput();
                    }

                    partData.Initialize(session, partID, GeoID, _containerObjectNode.ObjectID, this, ref partInfo,
                                        HEU_PartData.PartOutputType.INSTANCER, isPartEditable, _containerObjectNode.IsInstancer(), isAttribInstancer);
                    SetupGameObjectAndTransform(partData, parentAsset);
                }
                else if (HEU_HAPIUtility.IsSupportedPolygonType(partInfo.type))
                {
                    if (partData == null)
                    {
                        partData = ScriptableObject.CreateInstance <HEU_PartData>();
                    }
                    else
                    {
                        // Clear volume data (case where switching from something other output to mesh)
                        partData.ClearGeneratedVolumeOutput();
                    }

                    partData.Initialize(session, partID, GeoID, _containerObjectNode.ObjectID, this, ref partInfo,
                                        HEU_PartData.PartOutputType.MESH, isPartEditable, _containerObjectNode.IsInstancer(), false);

                    // This check allows to ignore editable non-display nodes by default, but commented out to allow
                    // them for now. Users can also ignore them by turning on IgnoreNonDisplayNodes
                    //if (Displayable || (Editable && ParentAsset.EditableNodesToolsEnabled))
                    {
                        SetupGameObjectAndTransform(partData, parentAsset);
                    }
                }
                else
                {
                    Debug.LogWarningFormat("Unsupported part type {0}", partInfo.type);
                }

                if (partData != null)
                {
                    // Success!
                    _parts.Add(partData);

                    // Set unique name for the part
                    string partName = HEU_PluginSettings.UseFullPathNamesForOutput ? GeneratePartFullName(partData.PartName) : partData.PartName;
                    partData.SetGameObjectName(partName);

                    // For intermediate or default-type editable nodes, setup the HEU_AttributeStore
                    if (isPartEditable)
                    {
                        partData.SyncAttributesStore(session, _geoInfo.nodeId, ref partInfo);
                    }
                    else
                    {
                        // Remove attributes store if it has it
                        partData.DestroyAttributesStore();
                    }
                }
            }

#if HEU_PROFILER_ON
            Debug.LogFormat("PART PROCESS TIME:: NAME={0}, TIME={1}", HEU_SessionManager.GetString(partInfo.nameSH, session), (Time.realtimeSinceStartup - processPartStartTime));
#endif
        }
예제 #3
0
		/// <summary>
		/// Returns the various geometry types (parts) from the given node.
		/// Only part instancers and point instancers (via attributes) are returned.
		/// </summary>
		private bool QueryParts(HAPI_NodeId nodeID, ref List<HAPI_PartInfo> meshParts, ref List<HAPI_PartInfo> volumeParts,
			ref List<HAPI_PartInfo> instancerParts, ref List<HAPI_PartInfo> curveParts, ref List<HAPI_PartInfo> scatterInstancerParts)
		{
			// Get display geo info
			HAPI_GeoInfo geoInfo = new HAPI_GeoInfo();
			if (!_session.GetGeoInfo(nodeID, ref geoInfo))
			{
				return false;
			}

			//Debug.LogFormat("GeoNode name:{0}, type: {1}, isTemplated: {2}, isDisplayGeo: {3}, isEditable: {4}, parts: {5}",
			//	HEU_SessionManager.GetString(geoInfo.nameSH, _session),
			//	geoInfo.type, geoInfo.isTemplated,
			//	geoInfo.isDisplayGeo, geoInfo.isEditable, geoInfo.partCount);

			if (geoInfo.type == HAPI_GeoType.HAPI_GEOTYPE_DEFAULT)
			{
				int numParts = geoInfo.partCount;
				for(int i = 0; i < numParts; ++i)
				{
					HAPI_PartInfo partInfo = new HAPI_PartInfo();
					if (!_session.GetPartInfo(geoInfo.nodeId, i, ref partInfo))
					{
						return false;
					}

					bool isAttribInstancer = false;
					bool isScatterInstancer = false;
					// Preliminary check for attribute instancing (mesh type with no verts but has points with instances)
					if (HEU_HAPIUtility.IsSupportedPolygonType(partInfo.type) && partInfo.vertexCount == 0 && partInfo.pointCount > 0)
					{
						if (HEU_GeneralUtility.HasValidInstanceAttribute(_session, nodeID, partInfo.id, HEU_PluginSettings.UnityInstanceAttr))
						{
							isAttribInstancer = true;
						}
						else if (HEU_GeneralUtility.HasValidInstanceAttribute(_session, nodeID, partInfo.id, HEU_Defines.HEIGHTFIELD_TREEINSTANCE_PROTOTYPEINDEX))
						{
							isScatterInstancer = true;
						}
					}

					if (isScatterInstancer)
					{
						scatterInstancerParts.Add(partInfo);
					}
					else if (partInfo.type == HAPI_PartType.HAPI_PARTTYPE_VOLUME)
					{
						volumeParts.Add(partInfo);
					}
					else if (partInfo.type == HAPI_PartType.HAPI_PARTTYPE_INSTANCER || isAttribInstancer)
					{
						instancerParts.Add(partInfo);
					}
					else if (partInfo.type == HAPI_PartType.HAPI_PARTTYPE_CURVE)
					{
						curveParts.Add(partInfo);
					}
					else if(HEU_HAPIUtility.IsSupportedPolygonType(partInfo.type))
					{
						meshParts.Add(partInfo);
					}
					else
					{
						string partName = HEU_SessionManager.GetString(partInfo.nameSH, _session);
						SetLog(HEU_LoadData.LoadStatus.ERROR, string.Format("Part {0} with type {1} is not supported for GeoSync.", partName, partInfo.type));
					}
				}
			}
			else if(geoInfo.type == HAPI_GeoType.HAPI_GEOTYPE_CURVE)
			{
				SetLog(HEU_LoadData.LoadStatus.ERROR, string.Format("Currently {0} geo type is not implemented for threaded geo loading!", geoInfo.type));
			}

			return true;
		}
예제 #4
0
	public void SetupMeshAndMaterials(HEU_HoudiniAsset asset, HAPI_PartType partType, GameObject outputGameObject)
	{
	    Color[] oldColors = _outputMesh != null && _outputMesh.isReadable ? 
		_outputMesh.colors : null;

	    _outputMesh = null;
	    _outputGameObject = null;

	    if (HEU_HAPIUtility.IsSupportedPolygonType(partType))
	    {
		// Get the generated mesh. If mesh is missing, nothing we can do.
		MeshFilter meshFilter = outputGameObject.GetComponent<MeshFilter>();
		if (meshFilter != null && meshFilter.sharedMesh != null)
		{
		    _outputMesh = meshFilter.sharedMesh;

		    if (_outputMesh.isReadable)
		    {
			Color[] newColors = _outputMesh.colors;

			if (oldColors != null)
			{
			    // Restore old colors back to newly generated mesh so
			    // as to keep color "state" for visualization

			    int oldLen = oldColors.Length;

			    if (newColors == null || newColors.Length == 0)
			    {
				newColors = new Color[_outputMesh.vertices.Length];
			    }
			    int newLen = newColors.Length;

			    for (int i = 0; i < newLen && i < oldLen; ++i)
			    {
				newColors[i] = oldColors[i];
			    }
			    _outputMesh.colors = newColors;
			    _outputMesh.UploadMeshData(false);
			}
			else if (newColors == null || newColors.Length == 0)
			{
			    // Assign new default colors
			    int count = _outputMesh.vertices.Length;
			    newColors = new Color[count];
			    for (int i = 0; i < count; ++i)
			    {
				newColors[i] = new Color(0.3f, 0.06f, 0.62f);
			    }
			    _outputMesh.colors = newColors;
			    _outputMesh.UploadMeshData(false);
			}
		    }

		}
		else
		{
		    // Without a valid mesh, we won't be able to paint so nothing else to do
		    return;
		}

		_outputGameObject = outputGameObject;

		MeshRenderer meshRenderer = _outputGameObject.GetComponent<MeshRenderer>();
		if (meshRenderer != null)
		{
		    _outputMeshRendererInitiallyEnabled = meshRenderer.enabled;

		    if (_localMaterial == null)
		    {
			_localMaterial = HEU_MaterialFactory.GetNewMaterialWithShader(null, HEU_PluginSettings.DefaultVertexColorShader, HEU_Defines.EDITABLE_MATERIAL, false);
		    }
		}
	    }
	}