Beispiel #1
0
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // Private Methods

    private void instanceObjects(int object_id, int object_idx, HoudiniProgressBar progress_bar)
    {
        HAPI_ObjectInfo  object_info = prObjects[object_idx];
        HoudiniInstancer instancer   = null;

        Transform old_instancer_transform = transform.Find(object_info.name);

        if (old_instancer_transform && old_instancer_transform.gameObject.GetComponent <HoudiniInstancer>())
        {
            instancer = old_instancer_transform.gameObject.GetComponent <HoudiniInstancer>();
        }
        else
        {
            if (gameObject.GetComponent <HoudiniInstancerManager>() == null)
            {
                gameObject.AddComponent <HoudiniInstancerManager>();
            }

            GameObject main_object = new GameObject(object_info.name);
            main_object.transform.parent = transform;

            main_object.AddComponent <HoudiniInstancer>();
            prGameObjects[object_idx] = main_object;
            instancer = main_object.GetComponent <HoudiniInstancer>();

            HoudiniInstancerManager instancer_manager = gameObject.GetComponent <HoudiniInstancerManager>();
            instancer_manager.updateInstancerData(instancer);
        }

        instancer.prAsset    = this;
        instancer.prObjectId = object_id;

        instancer.instanceObjects(progress_bar);
    }
Beispiel #2
0
    private void cacheNumInstances()
    {
        HAPI_ObjectInfo object_info = prAsset.prObjects[prObjectId];

        // Get Detail info.
        HAPI_GeoInfo geo_info = new HAPI_GeoInfo();

        HoudiniHost.getGeoInfo(prAsset.prAssetId, prObjectId, 0, out geo_info);
        if (geo_info.partCount == 0)
        {
            return;
        }

        HAPI_PartInfo part_info = new HAPI_PartInfo();

        HoudiniHost.getPartInfo(prAsset.prAssetId, prObjectId, 0, 0, out part_info);
        if (prAsset.prEnableLogging)
        {
            Debug.Log("Instancer #" + prObjectId + " (" + object_info.name + "): "
                      + "points: " + part_info.pointCount);
        }

        if (part_info.pointCount > 65000)
        {
            throw new HoudiniError("Point count (" + part_info.pointCount + ") above limit (" + 65000 + ")!");
        }

        myNumInstances = part_info.pointCount;
    }
Beispiel #3
0
    private void cacheNumInstances()
    {
        var             obj_idx     = prAsset.findObjectByNodeId(prObjectId);
        HAPI_ObjectInfo object_info = prAsset.prObjects[obj_idx];

        // Get Detail info.
        HAPI_GeoInfo geo_info = HoudiniHost.getDisplayGeoInfo(prObjectId);

        if (geo_info.partCount == 0)
        {
            return;
        }

        HAPI_PartInfo part_info = HoudiniHost.getPartInfo(geo_info.nodeId, 0);

        if (prAsset.prEnableLogging)
        {
            Debug.Log("Instancer #" + prObjectId + " (" + object_info.name + "): "
                      + "points: " + part_info.pointCount);
        }

        if (part_info.pointCount > 65000)
        {
            throw new HoudiniError("Point count (" + part_info.pointCount + ") above limit (" + 65000 + ")!");
        }

        myNumInstances = part_info.pointCount;
    }
    public void refresh(bool reload_asset, HAPI_ObjectInfo object_info)
    {
        if (reload_asset)
        {
            for (int i = 0; i < myGeos.Count; ++i)
            {
                HoudiniAssetUtility.destroyGameObject(myGeos[i]);
            }
            myGeos.Clear();
        }

        if (reload_asset || object_info.haveGeosChanged)
        {
            // Add new geos as needed.
            while (myGeos.Count < object_info.geoCount)
            {
                myGeos.Add(createGeo(myGeos.Count));
            }

            // Remove stale geos.
            while (myGeos.Count > object_info.geoCount)
            {
                HoudiniAssetUtility.destroyGameObject(myGeos[object_info.geoCount]);
                myGeos.RemoveAt(object_info.geoCount);
            }

            // Refresh all geos.
            for (int i = 0; i < myGeos.Count; ++i)
            {
                myGeos[i].GetComponent <HoudiniGeoControl>().refresh(reload_asset);
            }
        }
    }
    public override void reset()
    {
        base.reset();

        // Please keep these in the same order and grouping as their declarations at the top.

        myObjectId          = -1;
        myObjectName        = "object_name";
        myObjectVisible     = false;
        myObjectInfo        = new HAPI_ObjectInfo();
        myObjectInfo.nodeId = -1;

        myGeos = new List <GameObject>(0);
    }
Beispiel #6
0
    private bool createObject(int object_id, bool reload_asset)
    {
        bool needs_recook = false;
        HoudiniObjectControl object_control = null;
        HAPI_ObjectInfo      object_info    = prObjects[object_id];

        // Create main underling.
        if (prGameObjects[object_id] == null)
        {
            prGameObjects[object_id] = new GameObject(object_info.name);
            prGameObjects[object_id].transform.parent = transform;
            prGameObjects[object_id].isStatic         = gameObject.isStatic;

            object_control = prGameObjects[object_id].AddComponent <HoudiniObjectControl>();
            object_control.init(
                prAssetId, object_info.nodeId, prAsset, object_info.nodeId, object_info.name, object_info.isVisible);
        }
        else
        {
            object_control = prGameObjects[object_id].GetComponent <HoudiniObjectControl>();
        }
        GameObject main_child = prGameObjects[object_id];

        try
        {
            needs_recook |= object_control.refresh(reload_asset, object_info);

            if (reload_asset || object_info.hasTransformChanged)
            {
                // Get transforms.
                HAPI_Transform trans = prObjectTransforms[object_id];
                HoudiniAssetUtility.applyTransform(trans, main_child.transform);
            }
        }
        catch (HoudiniError error)
        {
            DestroyImmediate(main_child);
            prGameObjects[object_id] = null;
            error.addMessagePrefix("Obj(id: " + object_info.nodeId + ", name: " + object_info.name + ")");
            error.addMessageDetail("Object Path: " + object_info.objectInstancePath);
            throw;
        }

        return(needs_recook);
    }
    public bool refresh(bool reload_asset, HAPI_ObjectInfo object_info)
    {
        bool needs_recook = false;

        if (reload_asset)
        {
            for (int i = 0; i < myGeos.Count; ++i)
            {
                if (myGeos[i])
                {
                    HoudiniAssetUtility.destroyGameObject(myGeos[i]);
                }
            }
            myGeos.Clear();
        }

        if (reload_asset || object_info.haveGeosChanged)
        {
            // TODO: Add back support for templated geos and curve SOPs.
            HAPI_GeoInfo geo_info = HoudiniHost.getDisplayGeoInfo(prObjectId);
            object_info.geoCount = 1;

            // Add new geos as needed.
            while (myGeos.Count < object_info.geoCount)
            {
                myGeos.Add(createGeo(geo_info.nodeId));
            }

            // Remove stale geos.
            while (myGeos.Count > object_info.geoCount)
            {
                HoudiniAssetUtility.destroyGameObject(myGeos[object_info.geoCount]);
                myGeos.RemoveAt(object_info.geoCount);
            }

            // Refresh all geos.
            for (int i = 0; i < myGeos.Count; ++i)
            {
                needs_recook |= myGeos[i].GetComponent <HoudiniGeoControl>().refresh(reload_asset);
            }
        }

        return(needs_recook);
    }
Beispiel #8
0
    protected override bool buildCreateObjects(bool reload_asset, ref HoudiniProgressBar progress_bar)
    {
        bool needs_recook = false;

        for (int object_index = 0; object_index < prObjectCount; ++object_index)
        {
            progress_bar.incrementProgressBar();
            try
            {
                if (!prObjects[object_index].isInstancer &&
                    (reload_asset || prObjects[object_index].hasTransformChanged ||
                     prObjects[object_index].haveGeosChanged))
                {
                    needs_recook |= createObject(object_index, reload_asset);
                }
            }
            catch (HoudiniError error)
            {
                // Per-object errors are not re-thrown so that the rest of the asset has a chance to load.
                Debug.LogWarning(error.ToString());
            }
        }

        // Processing instancers.
        for (int object_index = 0; object_index < prObjectCount; ++object_index)
        {
            HAPI_ObjectInfo object_info = prObjects[object_index];
            if (object_info.isInstancer)
            {
                try
                {
                    if (object_info.objectToInstanceId >= 0)
                    {
                        int instanced_object_index = findObjectByNodeId(object_info.objectToInstanceId);
                        if (instanced_object_index >= 0)
                        {
                            needs_recook |= createObject(instanced_object_index, reload_asset);
                        }
                    }

                    if (reload_asset || object_info.haveGeosChanged)
                    {
                        instanceObjects(object_info.nodeId, object_index, progress_bar);
                    }
                }
                catch (HoudiniError error)
                {
                    // Per-object errors are not re-thrown so that the rest of the asset has a chance to load.
                    Debug.LogWarning(error.ToString());
                }
            }
        }

        if (prObjectCount <= 0)
        {
            bool needs_init = prObjectInfo.nodeId < 0 || reload_asset;

            if (prNodeInfo.type == HAPI_NodeType.HAPI_NODETYPE_OBJ)
            {
                prObjectInfo = HoudiniHost.getObjectInfo(prAssetId);
            }
            else if (prNodeInfo.type == HAPI_NodeType.HAPI_NODETYPE_SOP)
            {
                prObjectInfo = HoudiniHost.getObjectInfo(prNodeInfo.parentId);
            }
            else
            {
                Debug.LogError("Unsupported asset type!");
                return(needs_recook);
            }

            if (needs_init)
            {
                init(
                    prAssetId, prNodeId, prAsset,
                    prObjectInfo.nodeId, prObjectInfo.name, prObjectInfo.isVisible);
            }

            needs_recook = refresh(reload_asset, prObjectInfo);
        }

        // Enumerate edit and paint geos.
        HoudiniGeoControl[] geo_controls = gameObject.GetComponentsInChildren <HoudiniGeoControl>();
        prEditPaintGeos.Clear();
        foreach (HoudiniGeoControl geo_control in geo_controls)
        {
            if (geo_control.prGeoType == HAPI_GeoType.HAPI_GEOTYPE_INTERMEDIATE &&
                geo_control.GetType() == typeof(HoudiniGeoControl))
            {
                prEditPaintGeos.Add(geo_control);
            }
        }
        if (prEditPaintGeos.Count > 0 && prActiveAttributeManager == null)
        {
            prActiveAttributeManager = prEditPaintGeos[0].prGeoAttributeManager;
        }

        return(needs_recook);
    }
Beispiel #9
0
    public void instanceObjects(HoudiniProgressBar progress_bar)
    {
        try
        {
            destroyChildren();

            HAPI_ObjectInfo object_info = HoudiniHost.getObjectInfo(prObjectId);

            // Get Detail info.
            HAPI_GeoInfo geo_info = HoudiniHost.getDisplayGeoInfo(prObjectId);
            if (geo_info.partCount == 0)
            {
                return;
            }

            cacheNumInstances();

            HAPI_Transform[] instance_transforms = new HAPI_Transform[myNumInstances];
            Utility.getArray2Id(
                geo_info.nodeId, HAPI_RSTOrder.HAPI_SRT,
                HoudiniHost.getInstanceTransforms, instance_transforms, myNumInstances);

            // Get scale point attributes.
            HAPI_AttributeInfo scale_attr_info = new HAPI_AttributeInfo("scale");
            float[]            scale_attr      = new float[0];
            Utility.getAttribute(
                geo_info.nodeId, 0, "scale", ref scale_attr_info, ref scale_attr, HoudiniHost.getAttributeFloatData);

            if (scale_attr_info.exists && scale_attr_info.owner != HAPI_AttributeOwner.HAPI_ATTROWNER_POINT)
            {
                throw new HoudiniErrorIgnorable("I only understand scale as point attributes!");
            }

            if (scale_attr_info.exists && scale_attr.Length != myNumInstances * 3)
            {
                throw new HoudiniError(
                          "Unexpected scale array length found for asset: " + prAsset.prAssetId + "!\n" +
                          "Expected length of: " + myNumInstances * 3 + " but given: " + scale_attr.Length);
            }

            HAPI_AttributeInfo script_attr_info = new HAPI_AttributeInfo("Unity_Script");
            int[] script_attr = new int[0];
            Utility.getAttribute(
                geo_info.nodeId, 0, "Unity_Script", ref script_attr_info,
                ref script_attr, HoudiniHost.getAttributeStringData);

            if (script_attr_info.exists && script_attr_info.owner != HAPI_AttributeOwner.HAPI_ATTROWNER_POINT)
            {
                throw new HoudiniErrorIgnorable("I only understand Unity_Script as point attributes!");
            }

            if (script_attr_info.exists && script_attr.Length != myNumInstances)
            {
                throw new HoudiniError("Unexpected Unity_Script array length found for asset: " + prAsset.prAssetId + "!");
            }

            int[] instance_attr = null;
            int[] name_attr     = null;
            getInstanceAndNameAttrs(out instance_attr, out name_attr);

            progress_bar.prTotal = myNumInstances;

            List <int> exclusion_list = new List <int>();
            instanceOverriddenObjects(myNumInstances, exclusion_list);

            List <string> unique_instantiated_names        = new List <string>();
            HoudiniInstancerPersistentData persistent_data = prPersistentData;
            if (persistent_data.variationChoice.Count != myNumInstances)
            {
                if (myNumInstances > persistent_data.variationChoice.Count)
                {
                    int difference = myNumInstances - persistent_data.variationChoice.Count;
                    for (int ii = 0; ii < difference; ii++)
                    {
                        persistent_data.variationChoice.Add(-1);
                    }
                }
                else
                {
                    int difference = persistent_data.variationChoice.Count - myNumInstances;
                    persistent_data.variationChoice.RemoveRange(
                        persistent_data.variationChoice.Count - difference, difference);
                }
            }

            bool liveTransformPropagationSetting = false;
            bool syncAssetTransformSetting       = false;
            bool enableCooking = true;
            for (int i = 0; i < myNumInstances; ++i)
            {
                if (exclusion_list.Contains(i))
                {
                    continue;
                }

                GameObject obj_to_instance = null;

                if (instance_attr.Length > 0 || name_attr.Length > 0)
                {
                    if (name_attr.Length > 0)
                    {
                        string obj_name     = HoudiniHost.getString(name_attr[i]);
                        int    object_index = prAsset.findObjectByName(obj_name);

                        if (object_index >= 0)
                        {
                            obj_to_instance = prAsset.prGameObjects[object_index];
                        }
                        else
                        {
                            obj_to_instance = prAsset.findPartByName(obj_name, true);
                        }

                        if (obj_to_instance == null)
                        {
                            obj_to_instance = GameObject.Find(obj_name);
                        }
                    }
                    else
                    {
                        string    instanceObjectPath = HoudiniHost.getString(instance_attr[i]);
                        string [] pathItems          = instanceObjectPath.Split('/');
                        string    instanceObjectName = pathItems[pathItems.Length - 1];

                        int objectIndex = prAsset.findObjectByName(instanceObjectName);
                        if (objectIndex >= 0)
                        {
                            obj_to_instance = prAsset.prGameObjects[objectIndex];
                        }
                        else
                        {
                            obj_to_instance = GameObject.Find(instanceObjectName);
                        }
                    }

                    if (obj_to_instance != null)
                    {
                        HoudiniAsset hapi_asset = obj_to_instance.GetComponent <HoudiniAsset>();
                        if (hapi_asset != null)
                        {
                            liveTransformPropagationSetting = hapi_asset.prTransformChangeTriggersCooks;
                            syncAssetTransformSetting       = hapi_asset.prPushUnityTransformToHoudini;
                            enableCooking = hapi_asset.prEnableCooking;
                            hapi_asset.prTransformChangeTriggersCooks = false;
                            hapi_asset.prPushUnityTransformToHoudini  = false;
                            hapi_asset.prEnableCooking = false;
                        }
                    }
                }
                else if (object_info.objectToInstanceId >= 0)
                {
                    int object_to_instance_idx = prAsset.findObjectByNodeId(object_info.objectToInstanceId);
                    if (object_to_instance_idx >= 0)
                    {
                        obj_to_instance = prAsset.prGameObjects[object_to_instance_idx];
                    }
                }

                if (obj_to_instance != null)
                {
                    // Set progress bar information.
                    progress_bar.prCurrentValue = i;
                    progress_bar.prMessage      = "Instancing: " + obj_to_instance.name + " (" + i + " of " + myNumInstances + ")";
                    progress_bar.displayProgressBar();

                    if (!unique_instantiated_names.Contains(obj_to_instance.name))
                    {
                        unique_instantiated_names.Add(obj_to_instance.name);
                    }

                    Vector3 pos = new Vector3();

                    // Apply object transforms.
                    //
                    // Axis and Rotation conversions:
                    // Note that Houdini's X axis points in the opposite direction that Unity's does.  Also, Houdini's
                    // rotation is right handed, whereas Unity is left handed.  To account for this, we need to invert
                    // the x coordinate of the translation, and do the same for the rotations (except for the x rotation,
                    // which doesn't need to be flipped because the change in handedness AND direction of the left x axis
                    // causes a double negative - yeah, I know).

                    pos[0] = -instance_transforms[i].position[0];
                    pos[1] = instance_transforms[i].position[1];
                    pos[2] = instance_transforms[i].position[2];

                    Quaternion quat = new Quaternion(instance_transforms[i].rotationQuaternion[0],
                                                     instance_transforms[i].rotationQuaternion[1],
                                                     instance_transforms[i].rotationQuaternion[2],
                                                     instance_transforms[i].rotationQuaternion[3]);

                    Vector3 euler = quat.eulerAngles;
                    euler.y = -euler.y;
                    euler.z = -euler.z;

                    Vector3 scale = new Vector3(instance_transforms[i].scale[0],
                                                instance_transforms[i].scale[1],
                                                instance_transforms[i].scale[2]);



                    Matrix4x4 local_mat = new Matrix4x4();
                    local_mat.SetTRS(pos, Quaternion.Euler(euler), scale);

                    // TODO: Now this *should* be the transform.localToWorldMatrix
                    // but for some reason, after a scene load, we pick up compensating
                    // factors in the local transform that cancel out the transform on the
                    // asset.  For now just use the asset's transform as the parent matrix.
                    Matrix4x4 parent_mat = prAsset.transform.localToWorldMatrix;
                    Matrix4x4 global_mat = parent_mat * local_mat;


                    euler = HoudiniAssetUtility.getQuaternion(global_mat).eulerAngles;
                    pos   = HoudiniAssetUtility.getPosition(global_mat);
                    scale = HoudiniAssetUtility.getScale(global_mat);


                    //mat.SetTRS( pos,

                    string script_to_attach = "";
                    if (script_attr_info.exists)
                    {
                        script_to_attach = HoudiniHost.getString(script_attr[i]);
                    }
                    instanceObject(obj_to_instance,
                                   pos,
                                   euler,
                                   i,
                                   scale_attr_info.exists,
                                   scale,
                                   script_attr_info.exists,
                                   script_to_attach);


                    HoudiniAsset hapi_asset = obj_to_instance.GetComponent <HoudiniAsset>();
                    if (hapi_asset != null)
                    {
                        hapi_asset.prTransformChangeTriggersCooks = liveTransformPropagationSetting;
                        hapi_asset.prPushUnityTransformToHoudini  = syncAssetTransformSetting;
                        hapi_asset.prEnableCooking = enableCooking;
                    }
                }
            }

            updateUniqueInstantiatedNames(unique_instantiated_names);
        }
        catch (HoudiniError error)
        {
            Debug.LogWarning(error.ToString());
            return;
        }
    }
Beispiel #10
0
	public virtual bool build( bool reload_asset, bool unload_asset_first,
							   bool serialization_recovery_only,
							   bool force_reconnect,
							   bool is_duplication,
							   bool cook_downstream_assets,
							   bool use_delay_for_progress_bar )
	{
		// We can only build or do anything if we can link to our libraries.
#if !( UNITY_STANDALONE_WIN || UNITY_STANDALONE_OSX || ( UNITY_METRO && UNITY_EDITOR ) )
		return false;
		#pragma warning disable 0162
#endif // !( UNITY_STANDALONE_WIN || UNITY_STANDALONE_OSX || ( UNITY_METRO && UNITY_EDITOR ) )

		if ( !HoudiniHost.isInstallationOk() )
			return false;

		if ( !prEnableCooking )
			return false;

		if ( isPrefabInstance() )
			processParentPrefab();

		// Run post-cook hook.
		foreach ( var asset_hook in prAssetHooks )
			asset_hook.preCook( this );

		HoudiniProgressBar progress_bar = new HoudiniProgressBar();
		progress_bar.prUseDelay = use_delay_for_progress_bar;
		progress_bar.prAsset = this;

		try
		{
			progress_bar.prStartTime = System.DateTime.Now;
			
			bool is_first_time_build = false;
			
			// restore asset id and asset validation id from the backup whenever
			// reverting a prefab instance
			bool is_reverting_prefab_instance = isRevertingPrefabInstance();
			if ( is_reverting_prefab_instance )
			{
				prAssetId = prBackupAssetId;
				prAssetValidationId = prBackupAssetValidationId;
			}
			
			if ( reload_asset ) 
			{	
				if ( unload_asset_first )
				{
					// There's no reason to abort the whole rebuild process because we can't unload
					// the asset first as that would leave the user with no options other than
					// to delete this HAPI asset and create a new one for this OTL.
					try
					{
						HoudiniHost.destroyAsset( prAssetId );
					}
					catch ( HoudiniError ) {}

					// Once an asset is unloaded its id will is obviously no longer valid, so reset it here.
					prAssetId = -1;
					
					// Need to reset the parms as well.
					prParms.reset();
				}

				try
				{
					int asset_id = 0;

					if ( prAssetId < 0 )
						is_first_time_build = true;

					if ( unload_asset_first )
						asset_id = buildCreateAsset( progress_bar );
					else
						asset_id = prAssetId;

					// We need to update the prAssetId in case the cook is aborted/fails 
					// and we need to clean up (unload the asset) in the catch.
					prAssetId = asset_id;

					prAssetInfo = HoudiniHost.getAssetInfo( asset_id );
					HAPI_NodeInfo node_info = HoudiniHost.getNodeInfo( prAssetInfo.nodeId );
					
					if ( reload_asset )
						Debug.Log( 
							"Houdini Engine: Asset Loaded - ID: " + prAssetInfo.id + "\n" +
							"    Full Name: " + prAssetInfo.fullOpName + "\n" +
							"    Version: " + prAssetInfo.version + "\n" + 
							"    Unique Node Id: " + node_info.uniqueHoudiniNodeId + "\n" +
							"    Internal Node Path: " + node_info.internalNodePath + "\n" +
							"    Asset Library File: " + prAssetInfo.filePath + "\n" );
				}
				catch ( HoudiniError error )
				{
					Debug.LogError( "Asset not loaded: " + error.ToString() );
					// Nothing to build since the load failed.

					// Try to unload the asset so it doesn't dangle.
					if ( is_first_time_build )
					{
						try
						{
							HoudiniHost.destroyAsset( prAssetId );
						}
						catch ( HoudiniError ) {}
					}
					
					// Clean up.
					reset();

					// If in play mode, disable live cooks.
#if UNITY_EDITOR
					if ( EditorApplication.isPlaying )
#endif // UNITY_EDITOR
					{
						prPlaymodePerFrameCooking = false;
					}
					
					return false; // false for failed :(
				}
				
			}
			
			prAssetInfo = HoudiniHost.getAssetInfo( prAssetId );
			
			// For convenience we copy some asset info properties locally (since they are constant anyway).
			// More imporantly, structs are not serialized and therefore putting them into their own
			// variables is required in order to maintain state between serialization cycles.
			prAssetId 					= prAssetInfo.id;
			prBackupAssetId				= prAssetId;
			prAssetValidationId			= prAssetInfo.validationId;
			prBackupAssetValidationId 	= prAssetValidationId;
			prNodeId					= prAssetInfo.nodeId;
			prObjectNodeId				= prAssetInfo.objectNodeId;
			prObjectCount 				= prAssetInfo.objectCount;
			prHandleCount 				= prAssetInfo.handleCount;

			prAssetName					= prAssetInfo.name;
			prAssetOpName				= prAssetInfo.fullOpName;
			prAssetHelp					= prAssetInfo.helpText;
			prHAPIAssetType				= prAssetInfo.type;
			prTransformInputCount		= prAssetInfo.transformInputCount;
			prGeoInputCount				= prAssetInfo.geoInputCount;

#if UNITY_EDITOR
			if ( isPrefab() )
			{
				string prefab_path = AssetDatabase.GetAssetPath( GetInstanceID() );
				HoudiniHost.myCleanUpPrefabAssets[ prefab_path ] = prAssetId;
			}
#endif // UNITY_EDITOR

			// Try to load presets.
			if ( ( reload_asset && ( unload_asset_first || is_reverting_prefab_instance ) )
#if UNITY_EDITOR
				// Only load presets during serialization recovery if we really need to.
				// The only such case is when we made changes DURING playmode and Unity
				// restores the parameter values from before going into playmode.
				// We only save presets while NOT in playmode which means to restore
				// the Houdini state to before playmode state we need to loadPreset()
				// with the last saved preset. In all other cases, like going INTO
				// playmode, we should avoid this step because loadPreset() WILL
				// cause a cook regardless if the parameters have changed or not which
				// is terrible for large assets.
				|| ( serialization_recovery_only && 
					!EditorApplication.isPlayingOrWillChangePlaymode &&
					!prParms.prValuesEqualToHoudini )
#endif // UNITY_EDITOR
				)
			{
				loadPreset();
				progress_bar.statusCheckLoop();
				
				// Transform may not have been saved as part of the presets so we have to rely 
				// on the serialized value.
				if ( myLastLocalToWorld != Matrix4x4.zero && !isPrefab() )
				{
					// If this is a prefab instance being reverted we don't want to use the 
					// serialized value so don't change transform. 
					if ( !is_reverting_prefab_instance )
					{
						Matrix4x4 world_to_local = Matrix4x4.identity;
						if ( transform.parent )
							world_to_local = transform.parent.worldToLocalMatrix;
						Matrix4x4 local = myLastLocalToWorld * world_to_local;

						transform.localPosition = HoudiniAssetUtility.getPosition( local );
						transform.localRotation = HoudiniAssetUtility.getQuaternion( local );

						Vector3 scale = HoudiniAssetUtility.getScale( local );
						if ( !( Mathf.Approximately( 0.0f, scale.x )
							&& Mathf.Approximately( 0.0f, scale.y )
							&& Mathf.Approximately( 0.0f, scale.z ) ) )
						{
							transform.localScale = HoudiniAssetUtility.getScale( local );
						}
					}
					
					if ( prPushUnityTransformToHoudini )
					{
						pushAssetTransformToHoudini();
					}
				}
			}

			if ( reload_asset )
			{
				progress_bar.prCurrentValue			= 0;
				progress_bar.prTotal				= prObjectCount + prHandleCount;
				
				progress_bar.displayProgressBar();
				myProgressBarJustUsed = true;

				// Add input fields.
				if ( is_first_time_build || !force_reconnect )
					initAssetConnections();
				
				// Clean up.
				destroyChildren( transform );
				prGameObjects = new GameObject[ prObjectCount ];
			}
				
			if ( reload_asset || serialization_recovery_only )
			{
				// Need to re-acquire all the params for all the child controls that have parms exposed.
				prParms.getParameterValues();
				foreach ( HoudiniParms parms in GetComponentsInChildren< HoudiniParms >() )
					parms.getParameterValues();

				// Custom work during a full build (custom to each subclass).
				buildFullBuildCustomWork( ref progress_bar, is_duplication );
			}
			
			if ( !reload_asset && !serialization_recovery_only )
			{
				progress_bar.displayProgressBar();
				updateParameters( progress_bar );
			}

			// Create local object info caches (transforms need to be stored in a parallel array).
			if ( prObjects == null || prObjects.Length != prObjectCount )
				prObjects = new HAPI_ObjectInfo[ prObjectCount ];
			
			if ( prObjectTransforms == null || prObjectTransforms.Length != prObjectCount )
				prObjectTransforms = new HAPI_Transform[ prObjectCount ];
			
			// Refresh object info arrays as they are lost after serialization.
			HoudiniAssetUtility.getArray1Id( prAssetId, HoudiniHost.getObjects, prObjects, prObjectCount );
			HoudiniAssetUtility.getArray2Id( prAssetId, HAPI_RSTOrder.HAPI_SRT, HoudiniHost.getObjectTransforms, 
					 			 prObjectTransforms, prObjectCount );

			bool objects_need_recook = false;
			if ( !serialization_recovery_only )
			{
				// Set asset's transform.
				if ( prPushUnityTransformToHoudini )
					HoudiniAssetUtility.getHoudiniTransformAndApply( prAssetId, prAssetName, transform );
			
				progress_bar.prMessage = "Loading and composing objects...";

				// Destroy/copy non-copiable but still serialized member data.
				if ( is_duplication )
				{
					myAssetOTLUndoInfo = null;
					if ( myGeoAttributeManagerMap != null )
					{
						myGeoAttributeManagerMap = myGeoAttributeManagerMap.copy();
						myGeoAttributeManagerMap.name = prAssetName + "_GeoAttributeManagerMap";
					}
					if ( myPresetsMap != null )
					{
						myPresetsMap = myPresetsMap.clone();
						myPresetsMap.name = prAssetName + "_PresetMap";
					}
				}
			
				// Custom way to load objects (custom to each subclass).
				objects_need_recook = buildCreateObjects( reload_asset, ref progress_bar );
			
				// Process dependent assets.
				if ( cook_downstream_assets )
					processDependentAssets(
						serialization_recovery_only,
						force_reconnect,
						is_duplication,
						use_delay_for_progress_bar );
			}

			// This tells Unity that values have been overridden for this prefab instance 
			// (eg. asset id, validation id, node id, etc). 
#if UNITY_EDITOR
			if ( isPrefabInstance() )
				PrefabUtility.RecordPrefabInstancePropertyModifications( this );
#endif // UNITY_EDITOR

			// A bit of a hack (but not terrible). If we have presets for other child controls
			// they set their presets by now so we need to rebuild with the new presets.
			if ( objects_need_recook )
			{
				build(
					false,	// reload_asset
					false,	// unload_asset_first
					false,	// serializatin_recovery_only
					false,	// force_reconnect
					false,	// is_duplication
					false,	// cook_downstream_assets
					true	// use_delay_for_progress_bar
				);
			}
		}
		catch ( HoudiniErrorIgnorable ) {}
		catch ( HoudiniErrorProgressCancelled error )
		{
			// If in play mode, disable live cooks.
#if UNITY_EDITOR
			if ( EditorApplication.isPlaying )
#endif // UNITY_EDITOR
			{
				prPlaymodePerFrameCooking = false;
			}

			Debug.LogError( error.ToString() + "\nSource: " + error.Source );
		}
		catch ( HoudiniError error )
		{
			Debug.LogError( error.ToString() + "\nSource: " + error.Source );
		}
		catch ( System.Exception error )
		{
			Debug.LogError( error.ToString() + "\nSource: " + error.Source );
		}
		finally
		{
			progress_bar.clearProgressBar();

			myProgressBarJustUsed = false;

			// Run post-cook hook.
			foreach ( var asset_hook in prAssetHooks )
				asset_hook.postCook( this );
		}

		// We can only build or do anything if we can link to our libraries.
#if !( UNITY_STANDALONE_WIN || UNITY_STANDALONE_OSX || ( UNITY_METRO && UNITY_EDITOR ) )
		#pragma warning restore 0162
#endif // !( UNITY_STANDALONE_WIN || UNITY_STANDALONE_OSX || ( UNITY_METRO && UNITY_EDITOR ) )
		
		return true;
	}
Beispiel #11
0
	public override void reset()
	{
		base.reset();

		// Please keep these in the same order and grouping as their declarations at the top.
		
		// Assets ---------------------------------------------------------------------------------------------------
		
		prAsset							= this;
		prAssetInfo 					= new HAPI_AssetInfo();
		prPreset 						= null;
		prAssetValidationId				= -1;
		prAssetName						= "ASSET_NAME";
		prAssetOpName					= "ASSET_OP_NAME";
		prAssetHelp						= "ASSET_HELP";
		prAssetType						= AssetType.TYPE_INVALID;
		prHAPIAssetType 				= HAPI_AssetType.HAPI_ASSETTYPE_INVALID;
		prAssetSubType 					= 0;

		// Parameters -----------------------------------------------------------------------------------------------

		prPresetsMap					= null;

		// Inputs ---------------------------------------------------------------------------------------------------
		
		prTransformInputCount 			= 0;
		prGeoInputCount 				= 0;
		
		prDownStreamTransformAssets		= new List< HoudiniAsset >();
		prUpStreamTransformAssets 		= new List< HoudiniAsset >();
		prUpStreamTransformObjects 		= new List< GameObject >();
		
		prDownStreamGeoAssets 			= new List< HoudiniAsset >();
		prUpStreamGeoAssets 			= new List< HoudiniAsset >();
		prUpStreamGeoObjects 			= new List< GameObject >();
		prUpStreamGeoInputAssetIds		= new List< int >();
		myUpStreamGeoInputAssetValidationIds = new List< int >();

		// Objects --------------------------------------------------------------------------------------------------
		
		prObjectCount 					= 0;
		prHandleCount 					= 0;
		
		prObjects 						= new HAPI_ObjectInfo[ 0 ];
		
		prGameObjects 					= new GameObject[ 0 ];
		prObjectTransforms 				= new HAPI_Transform[ 0 ];

		// Geos -----------------------------------------------------------------------------------------------------

		prGeoAttributeManagerMap		= null;
		
		// Baking ---------------------------------------------------------------------------------------------------
		
		prBakeStartTime					= 0.0f;
		prBakeEndTime					= 1.0f;
		prBakeSamplesPerSecond			= 30;
		
		// GUI ------------------------------------------------------------------------------------------------------
		
		prShowHoudiniControls 			= true;
		prShowCookLog					= false;
		prShowHelp						= false;
		prShowAssetSettings				= true;
		prShowBakeOptions				= false;
		prShowPaintTools				= false;
		prShowInputControls 			= true;
		prAssetSettingsCategory			= 0;

		prIsGeoVisible					= true;
		prShowPinnedInstances			= true;
		prAutoSelectAssetRootNode 		= HoudiniHost.myDefaultAutoSelectAssetRootNode;

		prShowOnlyVertexColours			= false;

		prGenerateUVs					= false;
		prGenerateLightmapUV2s			= false;
		prGenerateTangents				= true;

		prEnableCooking					= HoudiniHost.myDefaultEnableCooking;
		prCookingTriggersDownCooks		= HoudiniHost.myDefaultCookingTriggersDownCooks;
		prPlaymodePerFrameCooking		= false;
		prPushUnityTransformToHoudini	= HoudiniHost.myDefaultPushUnityTransformToHoudini;
		prTransformChangeTriggersCooks	= HoudiniHost.myDefaultTransformChangeTriggersCooks;
		prImportTemplatedGeos 			= HoudiniHost.myDefaultImportTemplatedGeos;
		prSplitGeosByGroupOverride		= false;
		prSplitGeosByGroup				= HoudiniHost.myDefaultSplitGeosByGroup;

		prEnableLogging					= false;

		prTransInputNames				= new List< string >();
		prGeoInputNames					= new List< string >();
		
		myProgressBarJustUsed 			= false;
		
		// Prefabs ------------------------------------------------------------------------------------------------------
		
		prBackupAssetId					= -1;
		prBackupAssetValidationId		= -1;
		prReloadPrefabOnPlaymodeChange 	= false;
		prUpdatePrefabInstanceParmNames	= new List< string >();
	}
Beispiel #12
0
    protected override bool buildCreateObjects(bool reload_asset, ref HoudiniProgressBar progress_bar)
    {
        bool needs_recook = false;

        for (int object_index = 0; object_index < prObjectCount; ++object_index)
        {
            progress_bar.incrementProgressBar();
            try
            {
                if (!prObjects[object_index].isInstancer &&
                    (reload_asset || prObjects[object_index].hasTransformChanged ||
                     prObjects[object_index].haveGeosChanged))
                {
                    needs_recook |= createObject(object_index, reload_asset);
                }
            }
            catch (HoudiniError error)
            {
                // Per-object errors are not re-thrown so that the rest of the asset has a chance to load.
                Debug.LogWarning(error.ToString());
            }
        }

        // Processing instancers.
        for (int object_index = 0; object_index < prObjectCount; ++object_index)
        {
            HAPI_ObjectInfo object_info = prObjects[object_index];
            if (object_info.isInstancer)
            {
                try
                {
                    if (object_info.objectToInstanceId >= 0 &&
                        prGameObjects[object_info.objectToInstanceId] == null)
                    {
                        needs_recook |= createObject(object_info.objectToInstanceId, reload_asset);
                    }

                    if (reload_asset || object_info.haveGeosChanged)
                    {
                        instanceObjects(object_index, progress_bar);
                    }
                }
                catch (HoudiniError error)
                {
                    // Per-object errors are not re-thrown so that the rest of the asset has a chance to load.
                    Debug.LogWarning(error.ToString());
                }
            }
        }

        // Enumerate edit and paint geos.
        HoudiniGeoControl[] geo_controls = gameObject.GetComponentsInChildren <HoudiniGeoControl>();
        prEditPaintGeos.Clear();
        foreach (HoudiniGeoControl geo_control in geo_controls)
        {
            if (geo_control.prGeoType == HAPI_GeoType.HAPI_GEOTYPE_INTERMEDIATE &&
                geo_control.GetType() == typeof(HoudiniGeoControl))
            {
                prEditPaintGeos.Add(geo_control);
            }
        }
        if (prEditPaintGeos.Count > 0 && prActiveAttributeManager == null)
        {
            prActiveAttributeManager = prEditPaintGeos[0].prGeoAttributeManager;
        }

        return(needs_recook);
    }
Beispiel #13
0
    public void createObject(int object_id, int geo_id)
    {
        HAPI_ObjectInfo object_info = prControl.prAsset.prObjects[object_id];

        try
        {
            // Get position attributes (this is all we get for the curve's geometry).
            HAPI_AttributeInfo pos_attr_info = new HAPI_AttributeInfo(HoudiniConstants.HAPI_ATTRIB_POSITION);
            float[]            pos_attr      = new float[0];
            HoudiniAssetUtility.getAttribute(prControl.prAsset.prAssetId, object_id, geo_id, 0, HoudiniConstants.HAPI_ATTRIB_POSITION,
                                             ref pos_attr_info, ref pos_attr, HoudiniHost.getAttributeFloatData);
            if (!pos_attr_info.exists)
            {
                throw new HoudiniError("No position attribute found.");
            }

            int vertex_count = pos_attr_info.count;

            // Add vertices to the vertices array for guides.
            prVertices = new Vector3[vertex_count];
            for (int i = 0; i < vertex_count; ++i)
            {
                for (int j = 0; j < 3; ++j)
                {
                    prVertices[i][j] = pos_attr[i * 3 + j];
                }
                prVertices[i].x = -prVertices[i].x;
            }

            // Set the Mesh Filter.
            if (gameObject.GetComponent <MeshFilter>() == null)
            {
                MeshFilter mesh_filter = gameObject.AddComponent <MeshFilter>();
                mesh_filter.sharedMesh = new Mesh();
            }

            // Set the Mesh Renderer.
            if (gameObject.GetComponent <MeshRenderer>() == null)
            {
                MeshRenderer mesh_renderer = gameObject.AddComponent <MeshRenderer>();
                // This prevents curve from appearing in game (applies to entire game object).
                // Need this because the HAPI line shader doesn't work when building.
                mesh_renderer.tag = "EditorOnly";

                // Set generic texture so it's not pink.
                Material line_material = new Material(Shader.Find("Houdini/Line"));
                mesh_renderer.material = line_material;
            }

            // Create guide and selection meshes.
            buildDummyMesh();

#if UNITY_EDITOR
            AssetDatabase.Refresh();
#endif // UNITY_EDITOR
        }
        catch (HoudiniError error)
        {
            error.addMessagePrefix("Obj(id: " + object_info.id + ", name: " + object_info.name + ")");
            error.addMessageDetail("Object Path: " + object_info.objectInstancePath);
            throw;
        }
    }
	public bool refresh( bool reload_asset, HAPI_ObjectInfo object_info )
	{
		bool needs_recook = false;

		if ( reload_asset )
		{
			for ( int i = 0; i < myGeos.Count; ++i )
				HoudiniAssetUtility.destroyGameObject( myGeos[ i ] );
			myGeos.Clear();
		}

		if ( reload_asset || object_info.haveGeosChanged )
		{
			// Add new geos as needed.
			while ( myGeos.Count < object_info.geoCount )
				myGeos.Add( createGeo( myGeos.Count ) );

			// Remove stale geos.
			while ( myGeos.Count > object_info.geoCount )
			{
				HoudiniAssetUtility.destroyGameObject( myGeos[ object_info.geoCount ] );
				myGeos.RemoveAt( object_info.geoCount );
			}

			// Refresh all geos.
			for ( int i = 0; i < myGeos.Count; ++i )
				needs_recook |= myGeos[ i ].GetComponent< HoudiniGeoControl >().refresh( reload_asset );
		}

		return needs_recook;
	}
    public bool refresh(bool reload_asset, HAPI_ObjectInfo object_info)
    {
        bool needs_recook = false;

        if (reload_asset)
        {
            for (int i = 0; i < myGeos.Count; ++i)
            {
                if (myGeos[i])
                {
                    HoudiniAssetUtility.destroyGameObject(myGeos[i]);
                }
            }
            myGeos.Clear();
        }

        if (reload_asset || object_info.haveGeosChanged)
        {
            // Get the GeoInfos of the display geo node
            HAPI_GeoInfo display_geo_info = HoudiniHost.getDisplayGeoInfo(prObjectId);
            int          GeoCount         = object_info.geoCount = 1;

            // Add new geos as needed.
            while (myGeos.Count < GeoCount)
            {
                myGeos.Add(createGeo(display_geo_info.nodeId));
            }

            int node_id = object_info.nodeId;
            if (prAsset.prNodeInfo.type == HAPI_NodeType.HAPI_NODETYPE_SOP)
            {
                node_id = display_geo_info.nodeId;
            }

            // Look for editable nodes inside the network/the object
            const bool recursive         = true;
            int[]      editable_networks = HoudiniHost.getChildNodeList(
                node_id,
                (int)HAPI_NodeType.HAPI_NODETYPE_SOP,
                (int)HAPI_NodeFlags.HAPI_NODEFLAGS_EDITABLE,
                recursive);

            // Add the editable nodes to it
            for (int n = 0; n < editable_networks.Length; n++)
            {
                // The editable node has to be cooked first
                HoudiniHost.cookNode(editable_networks[n]);

                HAPI_GeoInfo editGeoInfo = HoudiniHost.getGeoInfo(editable_networks[n]);
                myGeos.Add(createGeo(editGeoInfo.nodeId));
                GeoCount++;
            }

            // Remove stale geos.
            while (myGeos.Count > GeoCount)
            {
                HoudiniAssetUtility.destroyGameObject(myGeos[GeoCount]);
                myGeos.RemoveAt(GeoCount);
            }

            // Refresh all geos.
            for (int i = 0; i < myGeos.Count; ++i)
            {
                needs_recook |= myGeos[i].GetComponent <HoudiniGeoControl>().refresh(reload_asset);
            }
        }

        return(needs_recook);
    }