///////////////////////////////////////////////////////////////////////////////////////////////////////////////// // 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); }
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; }
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); }
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); }
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); }
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; } }
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 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 >(); }
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); }
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); }