public override void OnInspectorGUI() { HoudiniInstancer[] instancers = myAssetOTL.gameObject.GetComponentsInChildren< HoudiniInstancer >(); if( !myAssetOTL.isPrefab() && instancers.Length > 0 ) { generateAssetInstanceControls(); } Event current_event = Event.current; if ( current_event.type == EventType.ValidateCommand && current_event.commandName == "UndoRedoPerformed" ) { foreach( HoudiniInstancer instancer in instancers ) { HoudiniProgressBar progress_bar = new HoudiniProgressBar(); instancer.instanceObjects( progress_bar ); progress_bar.clearProgressBar(); } Repaint(); } }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Private private void generateAssetBakeControls() { // Start Time { float value = myAsset.prBakeStartTime; bool changed = HoudiniGUI.floatField( "bake_start_time", "Start Time", ref value, myUndoInfo, ref myUndoInfo.bakeStartTime); if (changed) { myAsset.prBakeStartTime = value; } } // End Time { float value = myAsset.prBakeEndTime; bool changed = HoudiniGUI.floatField( "bake_end_time", "End Time", ref value, myUndoInfo, ref myUndoInfo.bakeEndTime); if (changed) { myAsset.prBakeEndTime = value; } } // Samples per second { int value = myAsset.prBakeSamplesPerSecond; bool changed = HoudiniGUI.intField( "bake_samples_per_second", "Samples Per Second", ref value, 1, 120, myUndoInfo, ref myUndoInfo.bakeSamplesPerSecond); if (changed) { myAsset.prBakeSamplesPerSecond = value; } } if (GUILayout.Button("Bake Animation")) { HoudiniProgressBar progress_bar = new HoudiniProgressBar(); progress_bar.prUseDelay = false; myAsset.bakeAnimations( myAsset.prBakeStartTime, myAsset.prBakeEndTime, myAsset.prBakeSamplesPerSecond, myAsset.gameObject, progress_bar); progress_bar.clearProgressBar(); } }
public override void OnInspectorGUI() { HoudiniInstancer[] instancers = myAssetOTL.gameObject.GetComponentsInChildren <HoudiniInstancer>(); if (instancers.Length > 0) { generateAssetInstanceControls(); } Event current_event = Event.current; if ( current_event.type == EventType.ValidateCommand && current_event.commandName == "UndoRedoPerformed") { foreach (HoudiniInstancer instancer in instancers) { HoudiniProgressBar progress_bar = new HoudiniProgressBar(); instancer.instanceObjects(progress_bar); progress_bar.clearProgressBar(); } Repaint(); } }
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; }
public override void onParmChange() { base.onParmChange(); if ( isPrefab() ) { if ( prParms.prLastChangedParmId != HoudiniConstants.HAPI_INVALID_PARM_ID ) { HAPI_ParmInfo parm_info = prParms.findParm( prParms.prLastChangedParmId ); prUpdatePrefabInstanceParmNames.Add( parm_info.name ); } HoudiniProgressBar progress_bar = new HoudiniProgressBar(); try { // only need to update parameters for prefab updateParameters( progress_bar ); } catch {} finally { progress_bar.clearProgressBar(); } #if UNITY_EDITOR EditorUtility.SetDirty( this ); #endif // UNITY_EDITOR } else { build( false, // reload_asset false, // unload_asset_first false, // serializatin_recovery_only false, // force_reconnect false, // is_duplication prCookingTriggersDownCooks, true // use_delay_for_progress_bar ); } // To keep things consistent with Unity workflow, we should not save parameter changes // while in Play mode. #if UNITY_EDITOR if ( !EditorApplication.isPlaying ) savePreset(); #endif // UNITY_EDITOR }
private void generateAssetInstanceControls() { HoudiniInstancerManager instancer_manager = myAssetOTL.gameObject.GetComponent <HoudiniInstancerManager>(); if (instancer_manager == null) { return; } List <HoudiniInstancerPersistentData> instancer_persistent_data = instancer_manager.prInstancerPersistentData; HoudiniInstancer[] instancers = myAssetOTL.gameObject.GetComponentsInChildren <HoudiniInstancer>(); foreach (HoudiniInstancer instancer in instancers) { HoudiniInstancerPersistentData persistent_data = null; for (int ii = 0; ii < instancer_persistent_data.Count; ii++) { HoudiniInstancerPersistentData data = instancer_persistent_data[ii]; if (data.instancerName == instancer.name) { persistent_data = data; break; } } if (persistent_data == null) { Debug.LogError("Can't find persistent data for instancer: " + instancer.name); continue; } Undo.RecordObject(persistent_data, "Houdini Instancer Change"); persistent_data.showInstancerGUI = HoudiniGUI.foldout( persistent_data.instancerName, persistent_data.showInstancerGUI, true); if (persistent_data.showInstancerGUI) { bool changed = false; { Vector3 dummy = new Vector3(); changed |= HoudiniGUI.floatField( "RotationOffset", "Rotation Offset", ref persistent_data.rotationalOffset, null, ref dummy); changed |= HoudiniGUI.floatField( "ScaleOffset", "Scale Offset", ref persistent_data.scaleOffset, null, ref dummy); List <string> unique_names = persistent_data.uniqueNames; for (int ii = 0; ii < unique_names.Count; ii++) { string instanced_name = unique_names[ii]; int base_index = persistent_data.baseIndex(ii); for (int jj = 0; jj < persistent_data.numObjsToInstantiate[ii]; jj++) { Object obj = (Object)persistent_data.objsToInstantiate[base_index + jj]; GUILayout.BeginHorizontal(); string label = ""; if (jj == 0) { label = instanced_name; } changed |= HoudiniGUI.objectField( "object_to_instantiate", label, ref obj, typeof(GameObject)); if (changed) { persistent_data.objsToInstantiate[base_index + jj] = (GameObject)obj; } if (GUILayout.Button("+")) { persistent_data.objsToInstantiate.Insert (base_index + jj, null); persistent_data.numObjsToInstantiate[ii]++; persistent_data.recalculateVariations[ii] = true; changed = true; break; } if (GUILayout.Button("-")) { if (persistent_data.numObjsToInstantiate[ii] == 1) { persistent_data.objsToInstantiate[base_index] = null; } else { persistent_data.objsToInstantiate.RemoveAt(base_index + jj); persistent_data.numObjsToInstantiate[ii]--; } persistent_data.recalculateVariations[ii] = true; changed = true; break; } GUILayout.EndHorizontal(); } } if (GUILayout.Button("Recalculate Variations")) { for (int ii = 0; ii < unique_names.Count; ii++) { persistent_data.recalculateVariations[ii] = true; } changed = true; } } if (instancer.hasOverriddenInstances()) { if (GUILayout.Button("UnPin All Instances")) { instancer.unPinAllInstances(); changed = true; } } if (changed) { HoudiniProgressBar progress_bar = new HoudiniProgressBar(); instancer.instanceObjects(progress_bar); progress_bar.clearProgressBar(); for (int ii = 0; ii < persistent_data.recalculateVariations.Count; ii++) { persistent_data.recalculateVariations[ii] = false; } } } EditorGUILayout.Separator(); } }
private void generateAssetInstanceControls() { HoudiniInstancerManager instancer_manager = myAssetOTL.gameObject.GetComponent< HoudiniInstancerManager >(); if( instancer_manager == null ) return; List< HoudiniInstancerPersistentData > instancer_persistent_data = instancer_manager.prInstancerPersistentData; HoudiniInstancer[] instancers = myAssetOTL.gameObject.GetComponentsInChildren< HoudiniInstancer >(); foreach( HoudiniInstancer instancer in instancers ) { HoudiniInstancerPersistentData persistent_data = null; for( int ii = 0; ii < instancer_persistent_data.Count; ii++ ) { HoudiniInstancerPersistentData data = instancer_persistent_data[ ii ]; if( data.instancerName == instancer.name ) { persistent_data = data; break; } } if( persistent_data == null ) { Debug.LogError("Can't find persistent data for instancer: " + instancer.name ); continue; } Undo.RecordObject( persistent_data, "Houdini Instancer Change" ); persistent_data.showInstancerGUI = HoudiniGUI.foldout( persistent_data.instancerName, persistent_data.showInstancerGUI, true ); if ( persistent_data.showInstancerGUI ) { bool changed = false; { Vector3 dummy = new Vector3(); changed |= HoudiniGUI.floatField( "RotationOffset", "Rotation Offset", ref persistent_data.rotationalOffset, null, ref dummy ); changed |= HoudiniGUI.floatField( "ScaleOffset", "Scale Offset", ref persistent_data.scaleOffset, null, ref dummy ); List< string > unique_names = persistent_data.uniqueNames; for ( int ii = 0; ii < unique_names.Count; ii++ ) { string instanced_name = unique_names[ ii ]; int base_index = persistent_data.baseIndex( ii ); for ( int jj = 0; jj < persistent_data.numObjsToInstantiate[ ii ]; jj++ ) { Object obj = (Object) persistent_data.objsToInstantiate[ base_index + jj ]; GUILayout.BeginHorizontal(); string label = ""; if ( jj == 0 ) label = instanced_name; changed |= HoudiniGUI.objectField( "object_to_instantiate", label, ref obj, typeof( GameObject ) ); if ( changed ) { persistent_data.objsToInstantiate[ base_index + jj ] = (GameObject) obj; } if ( GUILayout.Button( "+" ) ) { persistent_data.objsToInstantiate.Insert ( base_index + jj, null ); persistent_data.numObjsToInstantiate[ ii ]++; persistent_data.recalculateVariations[ ii ] = true; changed = true; break; } if ( GUILayout.Button( "-" ) ) { if ( persistent_data.numObjsToInstantiate[ ii ] == 1 ) { persistent_data.objsToInstantiate[ base_index ] = null; } else { persistent_data.objsToInstantiate.RemoveAt( base_index + jj ); persistent_data.numObjsToInstantiate[ ii ]--; } persistent_data.recalculateVariations[ ii ] = true; changed = true; break; } GUILayout.EndHorizontal(); } } if ( GUILayout.Button( "Recalculate Variations" ) ) { for( int ii = 0; ii < unique_names.Count; ii++ ) { persistent_data.recalculateVariations[ ii ] = true; } changed = true; } } if ( instancer.hasOverriddenInstances() ) { if ( GUILayout.Button( "UnPin All Instances" ) ) { instancer.unPinAllInstances(); changed = true; } } if ( changed ) { HoudiniProgressBar progress_bar = new HoudiniProgressBar(); instancer.instanceObjects( progress_bar ); progress_bar.clearProgressBar(); for( int ii = 0; ii < persistent_data.recalculateVariations.Count; ii++ ) { persistent_data.recalculateVariations[ ii ] = false; } } } EditorGUILayout.Separator(); } }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Private private void generateAssetBakeControls() { // Start Time { float value = myAsset.prBakeStartTime; bool changed = HoudiniGUI.floatField( "bake_start_time", "Start Time", ref value, myUndoInfo, ref myUndoInfo.bakeStartTime ); if ( changed ) myAsset.prBakeStartTime = value; } // End Time { float value = myAsset.prBakeEndTime; bool changed = HoudiniGUI.floatField( "bake_end_time", "End Time", ref value, myUndoInfo, ref myUndoInfo.bakeEndTime ); if ( changed ) myAsset.prBakeEndTime = value; } // Samples per second { int value = myAsset.prBakeSamplesPerSecond; bool changed = HoudiniGUI.intField( "bake_samples_per_second", "Samples Per Second", ref value, 1, 120, myUndoInfo, ref myUndoInfo.bakeSamplesPerSecond ); if ( changed ) myAsset.prBakeSamplesPerSecond = value; } if ( GUILayout.Button( "Bake Animation" ) ) { HoudiniProgressBar progress_bar = new HoudiniProgressBar(); progress_bar.prUseDelay = false; myAsset.bakeAnimations( myAsset.prBakeStartTime, myAsset.prBakeEndTime, myAsset.prBakeSamplesPerSecond, myAsset.gameObject, progress_bar ); progress_bar.clearProgressBar(); } }