public static void addAttribute( HAPI_AssetId asset_id, HAPI_ObjectId object_id, HAPI_GeoId geo_id, string name, ref HAPI_AttributeInfo attr_info ) { #if ( UNITY_STANDALONE_WIN || UNITY_STANDALONE_OSX || ( UNITY_METRO && UNITY_EDITOR ) ) HAPI_Result status_code = HAPI_AddAttribute( ref mySession, asset_id, object_id, geo_id, name, ref attr_info ); processStatusCode( status_code ); #else throw new HoudiniErrorUnsupportedPlatform(); #endif }
//[ MenuItem( HoudiniConstants.HAPI_PRODUCT_NAME + "/Create Two Curves and a Merge", false, 1000 ) ] private static void blah() { int curve1 = HoudiniHost.createInputAsset( "curve1" ); { HAPI_PartInfo new_part = new HAPI_PartInfo(); new_part.vertexCount = 3; new_part.pointCount = 3; new_part.faceCount = 2; new_part.type = HAPI_PartType.HAPI_PARTTYPE_CURVE; HoudiniHost.setPartInfo( curve1, 0, 0, ref new_part ); HAPI_AttributeInfo attrib_info = new HAPI_AttributeInfo( "P" ); attrib_info.exists = true; attrib_info.count = 3; // 3 points attrib_info.tupleSize = 3; // 3 floats per point (x, y, z) attrib_info.owner = HAPI_AttributeOwner.HAPI_ATTROWNER_POINT; attrib_info.storage = HAPI_StorageType.HAPI_STORAGETYPE_FLOAT; HoudiniHost.addAttribute( curve1, 0, 0, "P", ref attrib_info ); float[] positions = new float[ 9 ] { 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f }; HoudiniHost.setAttributeFloatData( curve1, 0, 0, "P", ref attrib_info, positions, 0, 3 ); int[] vertices = new int[ 3 ] { 0, 1, 2 }; HoudiniHost.setVertexList( curve1, 0, 0, vertices, 0, 3 ); int[] face_counts = new int[ 2 ] { 2, 2 }; // 3 edges for the first face (the only face) HoudiniHost.setFaceCounts( curve1, 0, 0, face_counts, 0, 2 ); HoudiniHost.commitGeo( curve1, 0, 0 ); } int curve2 = HoudiniHost.createInputAsset( "curve2" ); int merge = HoudiniHost.instantiateAsset( "SOP/merge", true ); int convert = HoudiniHost.instantiateAsset( "SOP/convert", true ); HoudiniHost.connectAssetGeometry( curve1, 0, merge, 0 ); HoudiniHost.connectAssetGeometry( curve2, 0, merge, 1 ); HoudiniHost.connectAssetGeometry( merge, 0, convert, 0 ); HAPI_AssetInfo convert_info = HoudiniHost.getAssetInfo( convert ); Debug.Log( HoudiniHost.getNodeInfo( HoudiniHost.getAssetInfo( merge ).nodeId ).parmCount ); int convert_to_parm_id = HoudiniHost.getParmIdFromName( convert_info.nodeId, "totype" ); //HAPI_ParmInfo[] convert_to_parm_info = new HAPI_ParmInfo[ 1 ]; int[] value_arr = new int[ 1 ]; value_arr[ 0 ] = 2; HoudiniHost.setParmIntValues( convert_info.nodeId, value_arr, convert_to_parm_id, 1 ); HoudiniHost.cookAsset( convert, true, false ); }
private static extern HAPI_Result HAPI_AddAttribute( ref HAPI_Session session, HAPI_AssetId asset_id, HAPI_ObjectId object_id, HAPI_GeoId geo_id, string name, ref HAPI_AttributeInfo attr_info );
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 bool refresh( bool reload_asset ) { bool needs_recook = false; if ( prObjectControl == null ) { Debug.LogError( "Why is my object control null on a refresh?" ); return needs_recook; } GameObject geo_node = gameObject; // Get Geo info. HAPI_GeoInfo geo_info = new HAPI_GeoInfo(); try { // If templated geos are off this will error out for templated // geos because they woudn't have cooked. But we still need to // get the geo info to see that this is a templated geo and skip it. HoudiniHost.getGeoInfo( prAssetId, prObjectId, prGeoId, out geo_info ); } catch ( HoudiniErrorInvalidArgument ) {} if ( geo_info.type == HAPI_GeoType.HAPI_GEOTYPE_INPUT ) return needs_recook; if ( geo_info.isTemplated && !prAsset.prImportTemplatedGeos && !geo_info.isEditable ) return needs_recook; if ( !reload_asset && !geo_info.hasGeoChanged && !geo_info.hasMaterialChanged ) return needs_recook; if ( reload_asset || geo_info.type == HAPI_GeoType.HAPI_GEOTYPE_CURVE ) { for ( int i = 0; i < myParts.Count; ++i ) HoudiniAssetUtility.destroyGameObject( myParts[ i ] ); myParts.Clear(); } if ( reload_asset || geo_info.hasGeoChanged ) { // Initialize our geo control. init( geo_info.nodeId, prGeoId, geo_info.name, (HAPI_GeoType) geo_info.type, geo_info.isEditable, geo_info.isDisplayGeo ); // Set node name. geo_node.name = prGeoName; } if ( !geo_info.isDisplayGeo && ( geo_info.type != HAPI_GeoType.HAPI_GEOTYPE_CURVE && !myObjectControl.prAsset.prImportTemplatedGeos && geo_info.isTemplated ) ) { return needs_recook; } if ( geo_info.type == HAPI_GeoType.HAPI_GEOTYPE_CURVE ) { createAndInitCurve( prNodeId, prObjectId, prGeoId, prIsEditable ); needs_recook = true; } else { if ( reload_asset || geo_info.hasGeoChanged ) { // Add new geos as needed. while ( myParts.Count < geo_info.partCount ) myParts.Add( createPart( myParts.Count ) ); // Remove stale geos. while ( myParts.Count > geo_info.partCount ) { HoudiniAssetUtility.destroyGameObject( myParts[ geo_info.partCount ] ); myParts.RemoveAt( geo_info.partCount ); } } // Refresh all geos. for ( int i = 0; i < myParts.Count; ++i ) myParts[ i ].GetComponent< HoudiniPartControl >().refresh( reload_asset, geo_info.hasGeoChanged, geo_info.hasMaterialChanged ); // Handle Edit/Paint Nodes if ( geo_info.type == HAPI_GeoType.HAPI_GEOTYPE_INTERMEDIATE ) { // Currently, we only support painting on the first part. const int part_id = 0; GameObject part_gameobject = myParts[ part_id ]; HoudiniPartControl part_control = part_gameobject.GetComponent< HoudiniPartControl >(); MeshFilter mesh_filter = part_control.getOrCreateComponent< MeshFilter >(); MeshRenderer mesh_renderer = part_control.getOrCreateComponent< MeshRenderer >(); MeshCollider mesh_collider = part_control.getOrCreateComponent< MeshCollider >(); Mesh mesh = mesh_filter.sharedMesh; // We are limited to using the first part, always. if ( myGeoAttributeManager == null && myParts.Count > 0 ) { if ( prAsset.prGeoAttributeManagerMap.contains( getRelativePath() ) ) { myGeoAttributeManager = prAsset.prGeoAttributeManagerMap.get( getRelativePath() ); myGeoAttributeManager.name = getAbsolutePath() + "/GeoAttributeManager"; myGeoAttributeManager.reInit( mesh, mesh_renderer, mesh_collider, part_gameobject.transform ); } else { myGeoAttributeManager = ScriptableObject.CreateInstance< HoudiniGeoAttributeManager >(); myGeoAttributeManager.name = getAbsolutePath() + "/GeoAttributeManager"; myGeoAttributeManager.init( mesh, mesh_renderer, mesh_collider, part_gameobject.transform ); prAsset.prGeoAttributeManagerMap.add( getRelativePath(), myGeoAttributeManager ); } // Sync the attributes and see if we need a recook. if ( myGeoAttributeManager.syncAttributes( prAssetId, prObjectId, prGeoId, part_id, mesh ) ) { HoudiniAssetUtility.setMesh( prAssetId, prObjectId, prGeoId, ref mesh, part_control, myGeoAttributeManager ); needs_recook = true; } } else { // Just sync the attributes but don't recook. Setting needs_recook to true here would // cause infinite cooking. myGeoAttributeManager.syncAttributes( prAssetId, prObjectId, prGeoId, part_id, mesh ); } } // Handle script attaching. if ( reload_asset && geo_info.partCount > 0 ) { HAPI_AttributeInfo script_attr_info = new HAPI_AttributeInfo( "Unity_Script" ); int[] script_attr = new int[ 0 ]; HoudiniAssetUtility.getAttribute( prAssetId, prObjectId, prGeoId, 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_DETAIL ) throw new HoudiniErrorIgnorable( "I only understand Unity_Script as detail attributes!" ); if ( script_attr_info.exists && script_attr.Length > 0 ) { string script_to_attach = HoudiniHost.getString( script_attr[ 0 ] ); HoudiniAssetUtility.attachScript( geo_node, script_to_attach ); } } } return needs_recook; }
public static HAPI_AttributeInfo getAttributeInfo( HAPI_AssetId asset_id, HAPI_ObjectId object_id, HAPI_GeoId geo_id, HAPI_PartId part_id, string name, HAPI_AttributeOwner owner ) { #if ( UNITY_STANDALONE_WIN || UNITY_STANDALONE_OSX || ( UNITY_METRO && UNITY_EDITOR ) ) HAPI_AttributeInfo info = new HAPI_AttributeInfo(); HAPI_Result status_code = HAPI_GetAttributeInfo( ref mySession, asset_id, object_id, geo_id, part_id, name, owner, ref info ); processStatusCode( status_code ); return info; #else throw new HoudiniErrorUnsupportedPlatform(); #endif }
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 void refresh(bool reload_asset, bool has_geo_changed, bool has_material_changed) { if (prGeoControl == null) { Debug.LogError("Why is my geo control null on a refresh?"); return; } GameObject part_node = gameObject; // Get Part info. HAPI_PartInfo part_info = new HAPI_PartInfo(); HoudiniHost.getPartInfo(prAssetId, prObjectId, prGeoId, prPartId, out part_info); bool is_empty = part_info.vertexCount <= 0 && part_info.pointCount <= 0; bool is_mesh = (part_info.vertexCount > 0); // For Debugging. #if false Debug.Log("ATTRIBS"); HoudiniAssetUtility.printAllAttributeNames(prAssetId, prObjectId, prGeoId, prPartId); Debug.Log("GROUPS"); HoudiniAssetUtility.printAllGroups(prAssetId, prObjectId, prGeoId, prPartId); Debug.Log("DONE"); Debug.Log(""); #endif // TODO: Make this info a permanent UI display. //if ( prEnableLogging && ( reload_asset || has_geo_changed || has_material_changed ) ) // Debug.Log( "Obj #" + part_control.prObjectId + " (" + part_control.prObjectName + "): " // + "verts: " + part_info.vertexCount + " faces: " + part_info.faceCount ); if (reload_asset || has_geo_changed) { // Initialize our part control. init(-1, part_info.id, part_info.name); // Overwrite name. part_node.name = part_info.name; if (is_empty) { // Add required components. MeshFilter mesh_filter = getOrCreateComponent <MeshFilter>(); // Get or create mesh. Mesh part_mesh = mesh_filter.sharedMesh; if (part_mesh == null) { mesh_filter.mesh = new Mesh(); part_mesh = mesh_filter.sharedMesh; } part_mesh.Clear(); } else if (is_mesh) // Valid mesh. { // Add required components. MeshFilter mesh_filter = getOrCreateComponent <MeshFilter>(); // Get or create mesh. Mesh part_mesh = mesh_filter.sharedMesh; if (part_mesh == null) { mesh_filter.mesh = new Mesh(); part_mesh = mesh_filter.sharedMesh; } part_mesh.Clear(); // Get mesh. try { HoudiniAssetUtility.getMesh( this, part_mesh, prAsset.prGenerateTangents && HoudiniHost.prGenerateTangents); } catch (HoudiniErrorIgnorable) {} catch (HoudiniError error) { Debug.LogWarning(error.ToString()); return; } // Add collider if group name matches. (Should be added after the mesh is set so that it // picks up the mesh automagically) if (part_info.name.Contains(HoudiniHost.prRenderedCollisionGroupName)) { MeshCollider mesh_collider = getOrCreateComponent <MeshCollider>(); getOrCreateComponent <MeshRenderer>(); mesh_collider.enabled = false; mesh_collider.enabled = true; } else if (part_info.name.Contains(HoudiniHost.prCollisionGroupName)) { MeshCollider mesh_collider = getOrCreateComponent <MeshCollider>(); mesh_collider.enabled = false; mesh_collider.enabled = true; } else { getOrCreateComponent <MeshRenderer>(); } #if !HAPI_PAINT_SUPPORT if (myGeoControl.prGeoType == HAPI_GeoType.HAPI_GEOTYPE_INTERMEDIATE) { MeshRenderer mesh_renderer = getOrCreateComponent <MeshRenderer>(); MeshCollider mesh_collider = getOrCreateComponent <MeshCollider>(); if (myGeoControl.prGeoAttributeManager) { myGeoControl.prGeoAttributeManager.reInit( part_mesh, mesh_renderer, mesh_collider, transform); } mesh_collider.enabled = false; mesh_collider.enabled = true; } #endif // !HAPI_PAINT_SUPPORT // Add Mesh-to-Prefab component. HoudiniMeshToPrefab mesh_saver = getOrCreateComponent <HoudiniMeshToPrefab>(); mesh_saver.prGameObject = part_node; mesh_saver.prMeshName = prAsset.prAssetName + "_" + part_node.name; } else if (HoudiniHost.prEnablePointsAsParticles && part_info.vertexCount <= 0 && part_info.pointCount > 0) // Particles? { // Get position attributes. HAPI_AttributeInfo pos_attr_info = new HAPI_AttributeInfo(HoudiniConstants.HAPI_ATTRIB_POSITION); float[] pos_attr = new float[0]; HoudiniAssetUtility.getAttribute( prAssetId, prObjectId, prGeoId, prPartId, 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."); } else if (pos_attr_info.owner != HAPI_AttributeOwner.HAPI_ATTROWNER_POINT) { throw new HoudiniErrorIgnorable("I only understand position as point attributes!"); } // Get colour attributes. HAPI_AttributeInfo colour_attr_info = new HAPI_AttributeInfo(HoudiniConstants.HAPI_ATTRIB_COLOR); float[] colour_attr = new float[0]; HoudiniAssetUtility.getAttribute( prAssetId, prObjectId, prGeoId, prPartId, HoudiniConstants.HAPI_ATTRIB_COLOR, ref colour_attr_info, ref colour_attr, HoudiniHost.getAttributeFloatData); ParticleEmitter particle_emitter = part_node.GetComponent <ParticleEmitter>(); if (particle_emitter == null) { #if UNITY_4_3 || UNITY_4_4 || UNITY_4_5 || UNITY_4_6 particle_emitter = part_node.AddComponent("EllipsoidParticleEmitter") as ParticleEmitter; #else particle_emitter = part_node.AddComponent <EllipsoidParticleEmitter>() as ParticleEmitter; #endif // UNITY_4_3 || UNITY_4_4 || UNITY_4_5 || UNITY_4_6 } particle_emitter.ClearParticles(); particle_emitter.emit = false; particle_emitter.useWorldSpace = true; particle_emitter.maxSize = 0.06f; particle_emitter.minSize = 0.02f; ParticleRenderer renderer = getOrCreateComponent <ParticleRenderer>(); Material mat = new Material(Shader.Find("Particles/Additive (Soft)")); int width = 20; int length = 20; Texture2D tex = new Texture2D(width, length, TextureFormat.RGBA32, false); for (int x = 0; x < width; ++x) { for (int y = 0; y < length; ++y) { float dist = (x - 10) * (x - 10) + (y - 10) * (y - 10); dist = Mathf.Sqrt(dist); float alpha_f = 1.0f - dist / 10.0f; Color col = new Color(0.8f, 0.8f, 0.8f, alpha_f); tex.SetPixel(x, y, col); } } tex.Apply(); mat.mainTexture = tex; mat.color = new Color(1.0f, 1.0f, 0.5f); renderer.material = mat; particle_emitter.Emit(part_info.pointCount); Particle[] particles = particle_emitter.particles; if (particle_emitter.particles.Length < part_info.pointCount) { Debug.LogWarning("Geo has too many particles. Expected less than " + particle_emitter.particles.Length + " but found " + part_info.pointCount + ". " + " Only using the first " + particle_emitter.particles.Length + "."); } for (int i = 0; i < particle_emitter.particles.Length; ++i) { particles[i].position = new Vector3(pos_attr[i * 3 + 0], pos_attr[i * 3 + 1], pos_attr[i * 3 + 2]); if (colour_attr_info.exists && colour_attr_info.owner == HAPI_AttributeOwner.HAPI_ATTROWNER_POINT) { float alpha = colour_attr_info.tupleSize == 4 ? colour_attr[i * colour_attr_info.tupleSize + 3] : 1.0f; particles[i].color = new Color(colour_attr[i * colour_attr_info.tupleSize + 0], colour_attr[i * colour_attr_info.tupleSize + 1], colour_attr[i * colour_attr_info.tupleSize + 2], alpha); } } particle_emitter.particles = particles; } if (part_info.hasVolume) { // Clear previous volume tiles. destroyChildren(part_node.transform); // If we have a volume, retrieve the volume info HAPI_VolumeInfo volume = new HAPI_VolumeInfo(); HoudiniHost.getVolumeInfo(prAssetId, prObjectId, prGeoId, prPartId, ref volume); // The volume.transform.scale is the voxel size. Both the particle // delta and the point size are affected by the voxel size. HoudiniAssetUtility.applyTransform(volume.transform, part_node.transform); float particle_delta = HoudiniConstants.HAPI_VOLUME_SURFACE_DELTA_MULT * Mathf.Max(Mathf.Max( volume.transform.scale[0], volume.transform.scale[1]), volume.transform.scale[2]); float point_size = HoudiniConstants.HAPI_VOLUME_SURFACE_PT_SIZE_MULT * particle_delta; List <Vector3> acc_vertices = new List <Vector3>(); List <Vector3> acc_normals = new List <Vector3>(); float[] values = new float[volume.tileSize * volume.tileSize * volume.tileSize]; int tile_index = 0; int current_container_particle_index = 0; // Iterate through the voxels and print out the data, for now. HAPI_VolumeTileInfo tile = new HAPI_VolumeTileInfo(); HoudiniHost.getFirstVolumeTile(prAssetId, prObjectId, prGeoId, prPartId, ref tile); while (tile.isValid) { for (int i = 0; i < values.Length; ++i) { values[i] = 0; } HoudiniHost.getVolumeTileFloatData( prAssetId, prObjectId, prGeoId, prPartId, ref tile, values); Vector3 tileMin = new Vector3(tile.minX, tile.minY, tile.minZ); int part_index = 0; for (int z = 0; z < volume.tileSize; ++z) { for (int y = 0; y < volume.tileSize; ++y) { for (int x = 0; x < volume.tileSize; ++x) { int index = z * volume.tileSize * volume.tileSize + y * volume.tileSize + x; if (values[index] > -particle_delta && values[index] < particle_delta) { // Make sure we have enough room in our arrays. if (current_container_particle_index > HoudiniConstants.HAPI_VOLUME_SURFACE_MAX_PT_PER_C) { createVolumeTilesObject( point_size, part_node.transform, acc_vertices, acc_normals); current_container_particle_index = 0; acc_vertices.Clear(); acc_normals.Clear(); } // Get particle position. Vector3 pos = new Vector3((float)x, (float)y, (float)z); pos = HoudiniConstants.HAPI_VOLUME_POSITION_MULT * (pos + tileMin); pos.x = -pos.x; acc_vertices.Add(part_node.transform.TransformPoint(pos)); // Get particle normal. int amount = 1; int sample_count = 0; Vector3 average_normal = Vector3.zero; for (int xi = -1; xi <= 1; ++xi) { for (int yi = -1; yi <= 1; ++yi) { for (int zi = -1; zi <= 1; ++zi) { if (xi == 0 && yi == 0 && zi == 0) { continue; } float result = getVolumeData( values, volume, particle_delta, x + xi * amount, y + yi * amount, z + zi * amount); Vector3 normal = Vector3.zero; if (result < -0.5f) { normal = new Vector3(-xi, -yi, -zi); } else if (result > 0.5f) { normal = new Vector3(xi, yi, zi); } else { continue; } average_normal += normal; sample_count++; } } } average_normal /= sample_count; average_normal.Normalize(); acc_normals.Add(average_normal); part_index++; current_container_particle_index++; } } } } HoudiniHost.getNextVolumeTile(prAssetId, prObjectId, prGeoId, prPartId, ref tile); tile_index++; } // tile iteration // If we have left-over particles in our arrays we need another container. createVolumeTilesObject(point_size, part_node.transform, acc_vertices, acc_normals); } // if has volume else // Restore part node if previously used to store volume. { // Clear previous volume tiles. destroyChildren(part_node.transform); part_node.transform.localScale = Vector3.one; part_node.transform.localPosition = Vector3.zero; part_node.transform.localRotation = Quaternion.identity; } } // Refresh enabled flags. if (gameObject.GetComponent <MeshCollider>()) { gameObject.GetComponent <MeshCollider>().enabled = prObjectVisible && (prAsset.prIsGeoVisible || prGeoType == HAPI_GeoType.HAPI_GEOTYPE_INTERMEDIATE); } if (gameObject.GetComponent <MeshRenderer>()) { gameObject.GetComponent <MeshRenderer>().enabled = prObjectVisible && (prAsset.prIsGeoVisible || prGeoType == HAPI_GeoType.HAPI_GEOTYPE_INTERMEDIATE); } // Assign materials. HoudiniAssetUtility.assignMaterial(this, prAsset, (reload_asset || has_material_changed)); // Assign unity tag. assignUnityTag(); }
private void assignUnityTag() { HAPI_AttributeInfo tag_attr_info = new HAPI_AttributeInfo( HoudiniHost.prUnityTagAttribName ); int[] tag_attr = new int[ 0 ]; HoudiniAssetUtility.getAttribute( prAssetId, prObjectId, prGeoId, prPartId, HoudiniHost.prUnityTagAttribName, ref tag_attr_info, ref tag_attr, HoudiniHost.getAttributeStringData ); if ( tag_attr_info.exists ) { string tag = HoudiniHost.getString( tag_attr[ 0 ] ); if ( tag != string.Empty ) { try { gameObject.tag = tag; } catch { Debug.LogWarning( "Unity Tag " + tag + " is not defined!" ); } } } }
HAPI_SetAttributeStringData( HAPI_AssetId asset_id, HAPI_ObjectId object_id, HAPI_GeoId geo_id, string name, ref HAPI_AttributeInfo attr_info, string[] data, int start, int length);
HAPI_AddAttribute( HAPI_AssetId asset_id, HAPI_ObjectId object_id, HAPI_GeoId geo_id, string name, ref HAPI_AttributeInfo attr_info);
HAPI_GetAttributeFloatData( HAPI_AssetId asset_id, HAPI_ObjectId object_id, HAPI_GeoId geo_id, HAPI_PartId part_id, string name, ref HAPI_AttributeInfo attr_info, [Out] float[] data, int start, int length);
HAPI_GetAttributeInfo( HAPI_AssetId asset_id, HAPI_ObjectId object_id, HAPI_GeoId geo_id, HAPI_PartId part_id, string name, HAPI_AttributeOwner owner, ref HAPI_AttributeInfo attr_info);
//[ MenuItem( HoudiniConstants.HAPI_PRODUCT_NAME + "/Create Simple Input Geo", false, 1000 ) ] private static void createSimpleInputGeo() { int asset_id = HoudiniHost.createInputAsset( "simple_input_geo_test" ); HoudiniHost.cookAsset( asset_id, HoudiniHost.prSplitGeosByGroup, HoudiniHost.prImportTemplatedGeos ); HAPI_PartInfo new_part = new HAPI_PartInfo(); new_part.vertexCount = 3; new_part.pointCount = 3; new_part.faceCount = 1; new_part.type = HAPI_PartType.HAPI_PARTTYPE_MESH; HoudiniHost.setPartInfo( asset_id, 0, 0, ref new_part ); HAPI_AttributeInfo attrib_info = new HAPI_AttributeInfo( "P" ); attrib_info.exists = true; attrib_info.count = 3; // 3 points attrib_info.tupleSize = 3; // 3 floats per point (x, y, z) attrib_info.owner = HAPI_AttributeOwner.HAPI_ATTROWNER_POINT; attrib_info.storage = HAPI_StorageType.HAPI_STORAGETYPE_FLOAT; HoudiniHost.addAttribute( asset_id, 0, 0, "P", ref attrib_info ); float[] positions = new float[ 9 ] { 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f }; HoudiniHost.setAttributeFloatData( asset_id, 0, 0, "P", ref attrib_info, positions, 0, 3 ); int[] vertices = new int[ 3 ] { 0, 1, 2 }; HoudiniHost.setVertexList( asset_id, 0, 0, vertices, 0, 3 ); int[] face_counts = new int[ 1 ] { 3 }; // 3 edges for the first face (the only face) HoudiniHost.setFaceCounts( asset_id, 0, 0, face_counts, 0, 1 ); bool[] point_group_mem = new bool[ 3 ] { true, true, false }; HoudiniHost.addGroup( asset_id, 0, 0, HAPI_GroupType.HAPI_GROUPTYPE_POINT, "test_pt_group" ); HoudiniHost.setGroupMembership( asset_id, 0, 0, HAPI_GroupType.HAPI_GROUPTYPE_POINT, "test_pt_group", point_group_mem, 3 ); bool[] prim_group_mem = new bool[ 1 ] { true }; HoudiniHost.addGroup( asset_id, 0, 0, HAPI_GroupType.HAPI_GROUPTYPE_PRIM, "test_prim_group" ); HoudiniHost.setGroupMembership( asset_id, 0, 0, HAPI_GroupType.HAPI_GROUPTYPE_PRIM, "test_prim_group", prim_group_mem, 1 ); HoudiniHost.commitGeo( asset_id, 0, 0 ); }
private static extern HAPI_Result HAPI_SetAttributeIntData( ref HAPI_Session session, HAPI_AssetId asset_id, HAPI_ObjectId object_id, HAPI_GeoId geo_id, string name, ref HAPI_AttributeInfo attr_info, int[] data_array, int start, int length );
///////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Public public void OnSceneGUI() { HoudiniPartControl control = target as HoudiniPartControl; if (control.prShowPointNumbers) { // Get position attributes. HAPI_AttributeInfo pos_attr_info = new HAPI_AttributeInfo(HoudiniConstants.HAPI_ATTRIB_POSITION); float[] pos_attr = new float[0]; HoudiniAssetUtility.getAttribute( myPartControl.prAssetId, myPartControl.prObjectId, myPartControl.prGeoId, myPartControl.prPartId, 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 point_count = pos_attr.Length / 3; // Determine which control point was pressed for modification. for (int i = 0; i < point_count; ++i) { Vector3 position = new Vector3( -pos_attr[i * 3 + 0], pos_attr[i * 3 + 1], pos_attr[i * 3 + 2]); position = myPartControl.transform.TransformPoint(position); Color original_color = GUI.color; GUIStyle style = new GUIStyle(GUI.skin.label); GUI.color = Color.yellow; style.fontStyle = FontStyle.Normal; style.fontSize = 12; Handles.Label(position, new GUIContent("" + i), style); GUI.color = original_color; } } /* * { * try * { * HAPI_AttributeInfo pos_attr_info = new HAPI_AttributeInfo( HoudiniConstants.HAPI_ATTRIB_POSITION ); * float[] pos_attr = new float[ 0 ]; * HoudiniAssetUtility.getAttribute( * myPartControl.prAssetId, myPartControl.prObjectId, myPartControl.prGeoId, * myPartControl.prPartId, 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." ); * * bool[] membership = HoudiniHost.getGroupMembership( * myPartControl.prAssetId, myPartControl.prObjectId, myPartControl.prGeoId, * myPartControl.prPartId, HAPI_GroupType.HAPI_GROUPTYPE_POINT, "exteriorPoints" ); * * int point_count = pos_attr.Length / 3; * * if ( membership.Length != point_count ) * Debug.LogError( "WTF" ); * * // Determine which control point was pressed for modification. * for ( int i = 0; i < point_count; ++i ) * { * if ( membership[ i ] ) * { * Vector3 position = new Vector3( -pos_attr[ i * 3 + 0 ], pos_attr[ i * 3 + 1 ], pos_attr[ i * 3 + 2 ] ); * Handles.Label( position, new GUIContent("" + i ) ); * } * } * } * catch * {} * * try * { * bool[] membership = HoudiniHost.getGroupMembership( * myPartControl.prAssetId, myPartControl.prObjectId, myPartControl.prGeoId, * myPartControl.prPartId, HAPI_GroupType.HAPI_GROUPTYPE_PRIM, "LG_4" ); * * Mesh mesh = myPartControl.GetComponent< MeshFilter >().sharedMesh; * if ( membership.Length != mesh.triangles.Length / 3 ) * Debug.LogError( "WTF" ); * * for ( int i = 0; i < mesh.triangles.Length / 3; ++i ) * { * if ( membership[ i ] ) * { * Vector3[] vects = new Vector3[ 4 ]; * vects[ 0 ] = mesh.vertices[ mesh.triangles[ i * 3 + 0 ] ]; * vects[ 1 ] = mesh.vertices[ mesh.triangles[ i * 3 + 0 ] ]; * vects[ 2 ] = mesh.vertices[ mesh.triangles[ i * 3 + 1 ] ]; * vects[ 3 ] = mesh.vertices[ mesh.triangles[ i * 3 + 2 ] ]; * Handles.DrawSolidRectangleWithOutline( vects, Color.red, Color.yellow ); * } * } * } * catch * {} * }*/ HoudiniInstance instance = findInstanceControlInParent(); if (instance == null) { return; } bool is_overridden = instance.prInstancer.isPointOverridden(instance.prInstancePointNumber); if (is_overridden) { instance.prInstancer.drawPin(instance.prInstancePointNumber); } Event curr_event = Event.current; if ( curr_event.isMouse && curr_event.type == EventType.MouseDown && HoudiniHost.prAutoPinInstances) { control.prTransformChanged = false; } else if ( curr_event.isMouse && curr_event.type == EventType.MouseUp && HoudiniHost.prAutoPinInstances && control.prTransformChanged) { instance.prInstancer.pinObject(control.gameObject, true); control.prTransformChanged = false; Repaint(); } }
public void refresh( bool reload_asset, bool has_geo_changed, bool has_material_changed ) { if ( prGeoControl == null ) { Debug.LogError( "Why is my geo control null on a refresh?" ); return; } GameObject part_node = gameObject; // Get Part info. HAPI_PartInfo part_info = new HAPI_PartInfo(); HoudiniHost.getPartInfo( prAssetId, prObjectId, prGeoId, prPartId, out part_info ); bool is_empty = part_info.vertexCount <= 0 && part_info.pointCount <= 0; bool is_mesh = ( part_info.vertexCount > 0 ); // For Debugging. #if false Debug.Log( "ATTRIBS" ); HoudiniAssetUtility.printAllAttributeNames( prAssetId, prObjectId, prGeoId, prPartId ); Debug.Log( "GROUPS" ); HoudiniAssetUtility.printAllGroups( prAssetId, prObjectId, prGeoId, prPartId ); Debug.Log( "DONE" ); Debug.Log( "" ); #endif // TODO: Make this info a permanent UI display. //if ( prEnableLogging && ( reload_asset || has_geo_changed || has_material_changed ) ) // Debug.Log( "Obj #" + part_control.prObjectId + " (" + part_control.prObjectName + "): " // + "verts: " + part_info.vertexCount + " faces: " + part_info.faceCount ); if ( reload_asset || has_geo_changed ) { // Initialize our part control. init( -1, part_info.id, part_info.name ); // Overwrite name. part_node.name = part_info.name; if ( is_empty ) { // Add required components. MeshFilter mesh_filter = getOrCreateComponent< MeshFilter >(); // Get or create mesh. Mesh part_mesh = mesh_filter.sharedMesh; if ( part_mesh == null ) { mesh_filter.mesh = new Mesh(); part_mesh = mesh_filter.sharedMesh; } part_mesh.Clear(); } else if ( is_mesh ) // Valid mesh. { // Add required components. MeshFilter mesh_filter = getOrCreateComponent< MeshFilter >(); // Get or create mesh. Mesh part_mesh = mesh_filter.sharedMesh; if ( part_mesh == null ) { mesh_filter.mesh = new Mesh(); part_mesh = mesh_filter.sharedMesh; part_mesh.name = getAbsolutePath() + "/Mesh"; } part_mesh.Clear(); // Get mesh. try { HoudiniAssetUtility.getMesh( this, part_mesh, prAsset.prGenerateUVs, prAsset.prGenerateLightmapUV2s, prAsset.prGenerateTangents ); } catch ( HoudiniErrorIgnorable ) {} catch ( HoudiniError error ) { Debug.LogWarning( error.ToString() ); return; } // Add collider if group name matches. (Should be added after the mesh is set so that it // picks up the mesh automagically) if ( part_info.name.Contains( HoudiniHost.prRenderedCollisionGroupName ) ) { MeshCollider mesh_collider = getOrCreateComponent< MeshCollider >(); getOrCreateComponent< MeshRenderer >(); mesh_collider.enabled = false; mesh_collider.enabled = true; } else if ( part_info.name.Contains( HoudiniHost.prCollisionGroupName ) ) { MeshCollider mesh_collider = getOrCreateComponent< MeshCollider >(); mesh_collider.enabled = false; mesh_collider.enabled = true; } else { getOrCreateComponent< MeshRenderer >(); } if ( myGeoControl.prGeoType == HAPI_GeoType.HAPI_GEOTYPE_INTERMEDIATE ) { MeshRenderer mesh_renderer = getOrCreateComponent< MeshRenderer >(); MeshCollider mesh_collider = getOrCreateComponent< MeshCollider >(); if ( myGeoControl.prGeoAttributeManager ) { myGeoControl.prGeoAttributeManager.reInit( part_mesh, mesh_renderer, mesh_collider, transform ); } mesh_collider.enabled = false; mesh_collider.enabled = true; } // Add Mesh-to-Prefab component. HoudiniMeshToPrefab mesh_saver = getOrCreateComponent< HoudiniMeshToPrefab >(); mesh_saver.prGameObject = part_node; mesh_saver.prMeshName = prAsset.prAssetName + "_" + part_node.name; } else if ( HoudiniHost.prEnablePointsAsParticles && part_info.vertexCount <= 0 && part_info.pointCount > 0 ) // Particles? { // Get position attributes. HAPI_AttributeInfo pos_attr_info = new HAPI_AttributeInfo( HoudiniConstants.HAPI_ATTRIB_POSITION ); float[] pos_attr = new float[ 0 ]; HoudiniAssetUtility.getAttribute( prAssetId, prObjectId, prGeoId, prPartId, 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." ); else if ( pos_attr_info.owner != HAPI_AttributeOwner.HAPI_ATTROWNER_POINT ) throw new HoudiniErrorIgnorable( "I only understand position as point attributes!" ); // Get colour attributes. HAPI_AttributeInfo colour_attr_info = new HAPI_AttributeInfo( HoudiniConstants.HAPI_ATTRIB_COLOR ); float[] colour_attr = new float[ 0 ]; HoudiniAssetUtility.getAttribute( prAssetId, prObjectId, prGeoId, prPartId, HoudiniConstants.HAPI_ATTRIB_COLOR, ref colour_attr_info, ref colour_attr, HoudiniHost.getAttributeFloatData ); ParticleEmitter particle_emitter = part_node.GetComponent< ParticleEmitter >(); if ( particle_emitter == null ) { #if UNITY_4_3 || UNITY_4_4 || UNITY_4_5 || UNITY_4_6 particle_emitter = part_node.AddComponent( "EllipsoidParticleEmitter" ) as ParticleEmitter; #else particle_emitter = part_node.AddComponent< EllipsoidParticleEmitter >() as ParticleEmitter; #endif // UNITY_4_3 || UNITY_4_4 || UNITY_4_5 || UNITY_4_6 } particle_emitter.ClearParticles(); particle_emitter.emit = false; particle_emitter.useWorldSpace = true; particle_emitter.maxSize = 0.06f; particle_emitter.minSize = 0.02f; ParticleRenderer renderer = getOrCreateComponent< ParticleRenderer >(); Material mat = new Material( Shader.Find( "Particles/Additive (Soft)" ) ); int width = 20; int length = 20; Texture2D tex = new Texture2D( width, length, TextureFormat.RGBA32, false ); for ( int x = 0; x < width; ++x ) { for ( int y = 0; y < length; ++y ) { float dist = (x - 10) * (x-10) + (y-10) * (y-10); dist = Mathf.Sqrt( dist ); float alpha_f = 1.0f - dist / 10.0f; Color col = new Color( 0.8f, 0.8f, 0.8f, alpha_f ); tex.SetPixel( x, y, col ); } } tex.Apply(); mat.mainTexture = tex; mat.color = new Color( 1.0f, 1.0f, 0.5f ); renderer.material = mat; particle_emitter.Emit( part_info.pointCount ); Particle[] particles = particle_emitter.particles; if ( particle_emitter.particles.Length < part_info.pointCount ) Debug.LogWarning( "Geo has too many particles. Expected less than " + particle_emitter.particles.Length + " but found " + part_info.pointCount + ". " + " Only using the first " + particle_emitter.particles.Length + "."); for ( int i = 0; i < particle_emitter.particles.Length; ++i ) { particles[ i ].position = new Vector3( pos_attr[ i * 3 + 0 ], pos_attr[ i * 3 + 1 ], pos_attr[ i * 3 + 2 ] ); if ( colour_attr_info.exists && colour_attr_info.owner == HAPI_AttributeOwner.HAPI_ATTROWNER_POINT ) { float alpha = colour_attr_info.tupleSize == 4 ? colour_attr[ i * colour_attr_info.tupleSize + 3 ] : 1.0f; particles[ i ].color = new Color( colour_attr[ i * colour_attr_info.tupleSize + 0 ], colour_attr[ i * colour_attr_info.tupleSize + 1 ], colour_attr[ i * colour_attr_info.tupleSize + 2 ], alpha ); } } particle_emitter.particles = particles; } if ( part_info.type == HAPI_PartType.HAPI_PARTTYPE_VOLUME ) { // Clear previous volume tiles. destroyChildren( part_node.transform ); // If we have a volume, retrieve the volume info HAPI_VolumeInfo volume = new HAPI_VolumeInfo(); HoudiniHost.getVolumeInfo( prAssetId, prObjectId, prGeoId, prPartId, ref volume ); // The volume.transform.scale is the voxel size. Both the particle // delta and the point size are affected by the voxel size. HoudiniAssetUtility.applyTransform( volume.transform, part_node.transform ); float particle_delta = HoudiniConstants.HAPI_VOLUME_SURFACE_DELTA_MULT * Mathf.Max( Mathf.Max( volume.transform.scale[ 0 ], volume.transform.scale[ 1 ] ), volume.transform.scale[ 2 ] ); float point_size = HoudiniConstants.HAPI_VOLUME_SURFACE_PT_SIZE_MULT * particle_delta; List< Vector3 > acc_vertices = new List< Vector3 >(); List< Vector3 > acc_normals = new List< Vector3 >(); float[] values = new float[ volume.tileSize * volume.tileSize * volume.tileSize ]; int tile_index = 0; int current_container_particle_index = 0; // Iterate through the voxels and print out the data, for now. HAPI_VolumeTileInfo tile = new HAPI_VolumeTileInfo(); HoudiniHost.getFirstVolumeTile( prAssetId, prObjectId, prGeoId, prPartId, ref tile ); while ( tile.isValid ) { for ( int i = 0; i < values.Length; ++i ) values[ i ] = 0; HoudiniHost.getVolumeTileFloatData( prAssetId, prObjectId, prGeoId, prPartId, ref tile, values ); Vector3 tileMin = new Vector3( tile.minX, tile.minY, tile.minZ ); int part_index = 0; for ( int z = 0; z < volume.tileSize; ++z ) for ( int y = 0; y < volume.tileSize; ++y ) for ( int x = 0; x < volume.tileSize; ++x ) { int index = z * volume.tileSize * volume.tileSize + y * volume.tileSize + x; if ( values[ index ] > -particle_delta && values[ index ] < particle_delta ) { // Make sure we have enough room in our arrays. if ( current_container_particle_index > HoudiniConstants.HAPI_VOLUME_SURFACE_MAX_PT_PER_C ) { createVolumeTilesObject( point_size, part_node.transform, acc_vertices, acc_normals ); current_container_particle_index = 0; acc_vertices.Clear(); acc_normals.Clear(); } // Get particle position. Vector3 pos = new Vector3( (float) x, (float) y, (float) z ); pos = HoudiniConstants.HAPI_VOLUME_POSITION_MULT * ( pos + tileMin ); pos.x = -pos.x; acc_vertices.Add( part_node.transform.TransformPoint( pos ) ); // Get particle normal. int amount = 1; int sample_count = 0; Vector3 average_normal = Vector3.zero; for ( int xi = -1; xi <= 1; ++xi ) for ( int yi = -1; yi <= 1; ++yi ) for ( int zi = -1; zi <= 1; ++zi ) { if ( xi == 0 && yi == 0 && zi == 0 ) continue; float result = getVolumeData( values, volume, particle_delta, x + xi * amount, y + yi * amount, z + zi * amount ); Vector3 normal = Vector3.zero; if ( result < -0.5f ) normal = new Vector3( -xi, -yi, -zi ); else if ( result > 0.5f ) normal = new Vector3( xi, yi, zi ); else continue; average_normal += normal; sample_count++; } average_normal /= sample_count; average_normal.Normalize(); acc_normals.Add( average_normal ); part_index++; current_container_particle_index++; } } HoudiniHost.getNextVolumeTile( prAssetId, prObjectId, prGeoId, prPartId, ref tile ); tile_index++; } // tile iteration // If we have left-over particles in our arrays we need another container. createVolumeTilesObject( point_size, part_node.transform, acc_vertices, acc_normals ); } // if has volume else // Restore part node if previously used to store volume. { // Clear previous volume tiles. destroyChildren( part_node.transform ); part_node.transform.localScale = Vector3.one; part_node.transform.localPosition = Vector3.zero; part_node.transform.localRotation = Quaternion.identity; } } // Refresh enabled flags. { bool is_visible = prObjectVisible; is_visible &= ( prAsset.prIsGeoVisible || prGeoType == HAPI_GeoType.HAPI_GEOTYPE_INTERMEDIATE ); if ( prGeoType == HAPI_GeoType.HAPI_GEOTYPE_INTERMEDIATE && myGeoControl.prGeoAttributeManager != null ) is_visible &= myGeoControl.prGeoAttributeManager.prCurrentMode != HoudiniGeoAttributeManager.Mode.NONE; if ( gameObject.GetComponent< MeshCollider >() ) gameObject.GetComponent< MeshCollider >().enabled = is_visible; if ( gameObject.GetComponent< MeshRenderer >() ) gameObject.GetComponent< MeshRenderer >().enabled = is_visible; } // Assign materials. HoudiniAssetUtility.assignMaterial( this, prAsset, reload_asset ); // Assign unity tag. assignUnityTag(); }
private void getInstanceAndNameAttrs(out int[] instance_attr,out int[] name_attr ) { instance_attr = new int[ 0 ]; name_attr = new int[ 0 ]; HAPI_AttributeInfo instance_attr_info = new HAPI_AttributeInfo( "instance" ); Utility.getAttribute( prAsset.prAssetId, prObjectId, 0, 0, "instance", ref instance_attr_info, ref instance_attr, HoudiniHost.getAttributeStringData ); if ( !instance_attr_info.exists ) return; if ( instance_attr_info.exists && instance_attr_info.owner != HAPI_AttributeOwner.HAPI_ATTROWNER_POINT ) throw new HoudiniErrorIgnorable( "I only understand instance as point attributes!" ); if ( instance_attr_info.exists && instance_attr.Length != myNumInstances ) throw new HoudiniError( "Unexpected instance_hint array length found for asset: " + prAsset.prAssetId + "!" ); HAPI_AttributeInfo name_attr_info = new HAPI_AttributeInfo( "name" ); Utility.getAttribute( prAsset.prAssetId, prObjectId, 0, 0, "name", ref name_attr_info, ref name_attr, HoudiniHost.getAttributeStringData ); if ( name_attr_info.exists && name_attr_info.owner != HAPI_AttributeOwner.HAPI_ATTROWNER_POINT ) throw new HoudiniErrorIgnorable( "I only understand name as point attributes!" ); if ( name_attr_info.exists && name_attr.Length != myNumInstances ) throw new HoudiniError( "Unexpected name array length found for asset: " + prAsset.prAssetId + "!" ); }
public bool sync( int asset_id, int object_id, int geo_id, int part_id, Mesh mesh, HAPI_AttributeInfo attribute_info ) { int tuple_size = attribute_info.tupleSize; prStorageType = attribute_info.storage; prTupleSize = tuple_size; myVertexCount = mesh.vertexCount; Type type = prType; if ( myInitializedVertexCount != mesh.vertexCount ) { int new_size = mesh.vertexCount * tuple_size; if ( type == Type.BOOL || type == Type.INT ) System.Array.Resize< int >( ref myIntData, new_size ); else if ( type == Type.FLOAT ) System.Array.Resize< float >( ref myFloatData, new_size ); else if ( type == Type.STRING ) System.Array.Resize< string >( ref myStringData, new_size ); } if ( myInitializedVertexCount < mesh.vertexCount ) { // Get Vertex list. HAPI_PartInfo part_info = new HAPI_PartInfo(); HoudiniHost.getPartInfo( asset_id, object_id, geo_id, part_id, out part_info ); int[] vertex_list = new int[ part_info.vertexCount ]; HoudiniAssetUtility.getArray4Id( asset_id, object_id, geo_id, part_id, HoudiniHost.getVertexList, vertex_list, part_info.vertexCount ); if ( type == Type.BOOL || type == Type.INT ) { int[] data = new int[ 0 ]; HoudiniAssetUtility.getAttribute( asset_id, object_id, geo_id, part_id, myName, ref attribute_info, ref data, HoudiniHost.getAttributeIntData ); for ( int i = myInitializedVertexCount; i < part_info.vertexCount; ++i ) for ( int tuple = 0; tuple < tuple_size; ++tuple ) prIntData[ i * tuple_size + tuple ] = data[ vertex_list[ i ] * tuple_size + tuple ]; } else if ( type == Type.FLOAT ) { float[] data = new float[ 0 ]; HoudiniAssetUtility.getAttribute( asset_id, object_id, geo_id, part_id, myName, ref attribute_info, ref data, HoudiniHost.getAttributeFloatData ); for ( int i = myInitializedVertexCount; i < part_info.vertexCount; ++i ) for ( int tuple = 0; tuple < tuple_size; ++tuple ) prFloatData[ i * tuple_size + tuple ] = data[ vertex_list[ i ] * tuple_size + tuple ]; } else if ( type == Type.STRING ) { int[] data = new int[ 0 ]; HoudiniAssetUtility.getAttribute( asset_id, object_id, geo_id, part_id, myName, ref attribute_info, ref data, HoudiniHost.getAttributeStringData ); for ( int i = myInitializedVertexCount; i < part_info.vertexCount; ++i ) for ( int tuple = 0; tuple < tuple_size; ++tuple ) prStringData[ i * tuple_size + tuple ] = HoudiniHost.getString( data[ vertex_list[ i ] * tuple_size + tuple ] ); } } // If some of the data was already bool needs_recook = myInitializedVertexCount > 0; myInitializedVertexCount = mesh.vertexCount; return needs_recook; }
public void instanceObjects( HoudiniProgressBar progress_bar ) { try { destroyChildren(); 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; cacheNumInstances(); HAPI_Transform[] instance_transforms = new HAPI_Transform[ myNumInstances ]; Utility.getArray4Id( prAsset.prAssetId, prObjectId, 0, 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( prAsset.prAssetId, prObjectId, 0, 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( prAsset.prAssetId, prObjectId, 0, 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 ii = 0; ii < myNumInstances; ++ii ) { if ( exclusion_list.Contains( ii ) ) continue; GameObject objToInstantiate = null; if ( instance_attr.Length > 0 || name_attr.Length > 0 ) { if( name_attr.Length > 0 ) { string obj_name = HoudiniHost.getString( name_attr[ ii ] ); int object_index = prAsset.findObjectByName( obj_name ); if ( object_index >= 0 ) { objToInstantiate = prAsset.prGameObjects[ object_index ]; } else { objToInstantiate = prAsset.findPartByName( obj_name, true ); } if( objToInstantiate == null ) { objToInstantiate = GameObject.Find( obj_name ); } } else { string instanceObjectPath = HoudiniHost.getString( instance_attr[ ii ] ); string[] pathItems = instanceObjectPath.Split('/'); string instanceObjectName = pathItems[ pathItems.Length - 1 ]; int objectIndex = prAsset.findObjectByName( instanceObjectName ); if ( objectIndex >= 0 ) objToInstantiate = prAsset.prGameObjects[ objectIndex ]; else objToInstantiate = GameObject.Find( instanceObjectName ); } if ( objToInstantiate != null ) { HoudiniAsset hapi_asset = objToInstantiate.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 ) objToInstantiate = prAsset.prGameObjects[ object_info.objectToInstanceId ]; if ( objToInstantiate != null ) { // Set progress bar information. progress_bar.prCurrentValue = ii; progress_bar.prMessage = "Instancing: " + objToInstantiate.name + " (" + ii + " of " + myNumInstances + ")"; progress_bar.displayProgressBar(); if ( !unique_instantiated_names.Contains( objToInstantiate.name ) ) { unique_instantiated_names.Add( objToInstantiate.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[ ii ].position[ 0 ]; pos[ 1 ] = instance_transforms[ ii ].position[ 1 ]; pos[ 2 ] = instance_transforms[ ii ].position[ 2 ]; Quaternion quat = new Quaternion( instance_transforms[ ii ].rotationQuaternion[ 0 ], instance_transforms[ ii ].rotationQuaternion[ 1 ], instance_transforms[ ii ].rotationQuaternion[ 2 ], instance_transforms[ ii ].rotationQuaternion[ 3 ] ); Vector3 euler = quat.eulerAngles; euler.y = -euler.y; euler.z = -euler.z; Vector3 scale = new Vector3 ( instance_transforms[ ii ].scale[ 0 ], instance_transforms[ ii ].scale[ 1 ], instance_transforms[ ii ].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[ ii ] ); instanceObject( objToInstantiate, pos, euler, ii, scale_attr_info.exists, scale, script_attr_info.exists, script_to_attach ); HoudiniAsset hapi_asset = objToInstantiate.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 bool sync( int asset_id, int object_id, int geo_id, int part_id, Mesh mesh, HAPI_AttributeInfo attribute_info) { int tuple_size = attribute_info.tupleSize; prStorageType = attribute_info.storage; prTupleSize = tuple_size; myVertexCount = mesh.vertexCount; Type type = prType; if (myInitializedVertexCount != mesh.vertexCount) { int new_size = mesh.vertexCount * tuple_size; if (type == Type.BOOL || type == Type.INT) { System.Array.Resize <int>(ref myIntData, new_size); } else if (type == Type.FLOAT) { System.Array.Resize <float>(ref myFloatData, new_size); } else if (type == Type.STRING) { System.Array.Resize <string>(ref myStringData, new_size); } } if (myInitializedVertexCount < mesh.vertexCount) { // Get Vertex list. HAPI_PartInfo part_info = new HAPI_PartInfo(); HoudiniHost.getPartInfo( asset_id, object_id, geo_id, part_id, out part_info); int[] vertex_list = new int[part_info.vertexCount]; HoudiniAssetUtility.getArray4Id( asset_id, object_id, geo_id, part_id, HoudiniHost.getVertexList, vertex_list, part_info.vertexCount); if (type == Type.BOOL || type == Type.INT) { int[] data = new int[0]; HoudiniAssetUtility.getAttribute( asset_id, object_id, geo_id, part_id, myName, ref attribute_info, ref data, HoudiniHost.getAttributeIntData); for (int i = myInitializedVertexCount; i < part_info.vertexCount; ++i) { for (int tuple = 0; tuple < tuple_size; ++tuple) { prIntData[i * tuple_size + tuple] = data[vertex_list[i] * tuple_size + tuple]; } } } else if (type == Type.FLOAT) { float[] data = new float[0]; HoudiniAssetUtility.getAttribute( asset_id, object_id, geo_id, part_id, myName, ref attribute_info, ref data, HoudiniHost.getAttributeFloatData); for (int i = myInitializedVertexCount; i < part_info.vertexCount; ++i) { for (int tuple = 0; tuple < tuple_size; ++tuple) { prFloatData[i * tuple_size + tuple] = data[vertex_list[i] * tuple_size + tuple]; } } } else if (type == Type.STRING) { int[] data = new int[0]; HoudiniAssetUtility.getAttribute( asset_id, object_id, geo_id, part_id, myName, ref attribute_info, ref data, HoudiniHost.getAttributeStringData); for (int i = myInitializedVertexCount; i < part_info.vertexCount; ++i) { for (int tuple = 0; tuple < tuple_size; ++tuple) { prStringData[i * tuple_size + tuple] = HoudiniHost.getString(data[vertex_list[i] * tuple_size + tuple]); } } } } // If some of the data was already bool needs_recook = myInitializedVertexCount > 0; myInitializedVertexCount = mesh.vertexCount; 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 static void setAttributeFloatData( HAPI_AssetId asset_id, HAPI_ObjectId object_id, HAPI_GeoId geo_id, string name, ref HAPI_AttributeInfo attr_info, float[] data, int start, int length ) { #if ( UNITY_STANDALONE_WIN || UNITY_STANDALONE_OSX || ( UNITY_METRO && UNITY_EDITOR ) ) HAPI_Result status_code = HAPI_SetAttributeFloatData( ref mySession, asset_id, object_id, geo_id, name, ref attr_info, data, start, length ); processStatusCode( status_code ); #else throw new HoudiniErrorUnsupportedPlatform(); #endif }
HAPI_GetAttributeInfo( ref HAPI_Session session, HAPI_AssetId asset_id, HAPI_ObjectId object_id, HAPI_GeoId geo_id, HAPI_PartId part_id, string name, HAPI_AttributeOwner owner, ref HAPI_AttributeInfo attr_info );
public bool syncAttributes(int asset_id, int object_id, int geo_id, int part_id, Mesh mesh) { bool needs_recook = false; // Fetch all point attributes. string[] point_attribute_names = HoudiniHost.getAttributeNames( geo_id, part_id, HAPI_AttributeOwner.HAPI_ATTROWNER_POINT); foreach (string point_attribute_name in point_attribute_names) { if (point_attribute_name == "P") { continue; } HAPI_AttributeInfo point_attribute_info = HoudiniHost.getAttributeInfo( geo_id, part_id, point_attribute_name, HAPI_AttributeOwner.HAPI_ATTROWNER_POINT); HoudiniGeoAttribute attribute = null; // If we already have an attribute with the same name, sync it with // the attribute in Houdini - trying to salvage any data even if the // attribute storage type, tuple size, or mesh point count has changed. if (hasAttribute(point_attribute_name)) { attribute = getAttribute(point_attribute_name); } else // Attribute not found. { HoudiniGeoAttribute.Type geo_attribute_type = HoudiniGeoAttribute.Type.UNDEFINED; switch (point_attribute_info.storage) { case HAPI_StorageType.HAPI_STORAGETYPE_INT: geo_attribute_type = HoudiniGeoAttribute.Type.INT; break; case HAPI_StorageType.HAPI_STORAGETYPE_FLOAT: geo_attribute_type = HoudiniGeoAttribute.Type.FLOAT; break; case HAPI_StorageType.HAPI_STORAGETYPE_STRING: geo_attribute_type = HoudiniGeoAttribute.Type.STRING; break; } attribute = createAttribute(point_attribute_name); attribute.init( mesh, point_attribute_name, geo_attribute_type, point_attribute_info.tupleSize); attribute.prOriginalAttributeOwner = HAPI_AttributeOwner.HAPI_ATTROWNER_POINT; } // Sync the values of the Unity attribute with the Houdini attribute. needs_recook |= attribute.sync(geo_id, part_id, mesh, point_attribute_info); // If the sync updated the values from the asset we need to refresh our mesh. if (needs_recook) { refreshMesh(); } } return(needs_recook); }
HAPI_GetAttributeFloatData( ref HAPI_Session session, HAPI_AssetId asset_id, HAPI_ObjectId object_id, HAPI_GeoId geo_id, HAPI_PartId part_id, string name, ref HAPI_AttributeInfo attr_info, [Out] float[] data_array, int start, int length );
///////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Public public void OnSceneGUI() { HoudiniPartControl control = target as HoudiniPartControl; control.selectParent(); if ( control.prShowPointNumbers ) { // Get position attributes. HAPI_AttributeInfo pos_attr_info = new HAPI_AttributeInfo( HoudiniConstants.HAPI_ATTRIB_POSITION ); float[] pos_attr = new float[ 0 ]; HoudiniAssetUtility.getAttribute( myPartControl.prAssetId, myPartControl.prObjectId, myPartControl.prGeoId, myPartControl.prPartId, 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 point_count = pos_attr.Length / 3; // Determine which control point was pressed for modification. for ( int i = 0; i < point_count; ++i ) { Vector3 position = new Vector3( -pos_attr[ i * 3 + 0 ], pos_attr[ i * 3 + 1 ], pos_attr[ i * 3 + 2 ] ); position = myPartControl.transform.TransformPoint( position ); Color original_color = GUI.color; GUIStyle style = new GUIStyle( GUI.skin.label ); GUI.color = Color.yellow; style.fontStyle = FontStyle.Normal; style.fontSize = 12; Handles.Label( position, new GUIContent( "" + i ), style ); GUI.color = original_color; } } /* { try { HAPI_AttributeInfo pos_attr_info = new HAPI_AttributeInfo( HoudiniConstants.HAPI_ATTRIB_POSITION ); float[] pos_attr = new float[ 0 ]; HoudiniAssetUtility.getAttribute( myPartControl.prAssetId, myPartControl.prObjectId, myPartControl.prGeoId, myPartControl.prPartId, 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." ); bool[] membership = HoudiniHost.getGroupMembership( myPartControl.prAssetId, myPartControl.prObjectId, myPartControl.prGeoId, myPartControl.prPartId, HAPI_GroupType.HAPI_GROUPTYPE_POINT, "exteriorPoints" ); int point_count = pos_attr.Length / 3; if ( membership.Length != point_count ) Debug.LogError( "WTF" ); // Determine which control point was pressed for modification. for ( int i = 0; i < point_count; ++i ) { if ( membership[ i ] ) { Vector3 position = new Vector3( -pos_attr[ i * 3 + 0 ], pos_attr[ i * 3 + 1 ], pos_attr[ i * 3 + 2 ] ); Handles.Label( position, new GUIContent("" + i ) ); } } } catch {} try { bool[] membership = HoudiniHost.getGroupMembership( myPartControl.prAssetId, myPartControl.prObjectId, myPartControl.prGeoId, myPartControl.prPartId, HAPI_GroupType.HAPI_GROUPTYPE_PRIM, "LG_4" ); Mesh mesh = myPartControl.GetComponent< MeshFilter >().sharedMesh; if ( membership.Length != mesh.triangles.Length / 3 ) Debug.LogError( "WTF" ); for ( int i = 0; i < mesh.triangles.Length / 3; ++i ) { if ( membership[ i ] ) { Vector3[] vects = new Vector3[ 4 ]; vects[ 0 ] = mesh.vertices[ mesh.triangles[ i * 3 + 0 ] ]; vects[ 1 ] = mesh.vertices[ mesh.triangles[ i * 3 + 0 ] ]; vects[ 2 ] = mesh.vertices[ mesh.triangles[ i * 3 + 1 ] ]; vects[ 3 ] = mesh.vertices[ mesh.triangles[ i * 3 + 2 ] ]; Handles.DrawSolidRectangleWithOutline( vects, Color.red, Color.yellow ); } } } catch {} }*/ HoudiniInstance instance = findInstanceControlInParent(); if ( instance == null ) return; bool is_overridden = instance.prInstancer.isPointOverridden( instance.prInstancePointNumber ); if ( is_overridden ) instance.prInstancer.drawPin( instance.prInstancePointNumber ); Event curr_event = Event.current; if ( curr_event.isMouse && curr_event.type == EventType.MouseDown && HoudiniHost.prAutoPinInstances ) { control.prTransformChanged = false; } else if ( curr_event.isMouse && curr_event.type == EventType.MouseUp && HoudiniHost.prAutoPinInstances && control.prTransformChanged ) { instance.prInstancer.pinObject( control.gameObject, true ); control.prTransformChanged = false; Repaint(); } }
HAPI_AddAttribute( ref HAPI_Session session, HAPI_AssetId asset_id, HAPI_ObjectId object_id, HAPI_GeoId geo_id, string name, ref HAPI_AttributeInfo attr_info );
public void refresh(bool reload_asset) { if (prObjectControl == null) { Debug.LogError("Why is my object control null on a refresh?"); return; } GameObject geo_node = gameObject; // Get Geo info. HAPI_GeoInfo geo_info = new HAPI_GeoInfo(); HoudiniHost.getGeoInfo(prAssetId, prObjectId, prGeoId, out geo_info); if (geo_info.type == HAPI_GeoType.HAPI_GEOTYPE_INPUT) { return; } if (!reload_asset && !geo_info.hasGeoChanged && !geo_info.hasMaterialChanged) { return; } if (reload_asset || geo_info.type == HAPI_GeoType.HAPI_GEOTYPE_CURVE) { for (int i = 0; i < myParts.Count; ++i) { HoudiniAssetUtility.destroyGameObject(myParts[i]); } myParts.Clear(); } if (reload_asset || geo_info.hasGeoChanged) { // Initialize our geo control. init( geo_info.nodeId, prGeoId, geo_info.name, (HAPI_GeoType)geo_info.type, geo_info.isEditable, geo_info.isDisplayGeo); // Set node name. geo_node.name = prGeoName; } if (!geo_info.isDisplayGeo && (geo_info.type != HAPI_GeoType.HAPI_GEOTYPE_CURVE && !myObjectControl.prAsset.prImportTemplatedGeos && geo_info.isTemplated)) { return; } if (geo_info.type == HAPI_GeoType.HAPI_GEOTYPE_CURVE) { createAndInitCurve(prNodeId, prObjectId, prGeoId, prIsEditable); } else { if (reload_asset || geo_info.hasGeoChanged) { // Add new geos as needed. while (myParts.Count < geo_info.partCount) { myParts.Add(createPart(myParts.Count)); } // Remove stale geos. while (myParts.Count > geo_info.partCount) { HoudiniAssetUtility.destroyGameObject(myParts[geo_info.partCount]); myParts.RemoveAt(geo_info.partCount); } } // Refresh all geos. for (int i = 0; i < myParts.Count; ++i) { myParts[i].GetComponent <HoudiniPartControl>().refresh( reload_asset, geo_info.hasGeoChanged, geo_info.hasMaterialChanged); } // Handle Edit/Paint Nodes #if !HAPI_PAINT_SUPPORT if (geo_info.type == HAPI_GeoType.HAPI_GEOTYPE_INTERMEDIATE) { // We are limited to using the first part, always. if (myGeoAttributeManager == null && myParts.Count > 0) { const int part_id = 0; GameObject part_gameobject = myParts[part_id]; HoudiniPartControl part_control = part_gameobject.GetComponent <HoudiniPartControl>(); MeshFilter mesh_filter = part_control.getOrCreateComponent <MeshFilter>(); MeshRenderer mesh_renderer = part_control.getOrCreateComponent <MeshRenderer>(); MeshCollider mesh_collider = part_control.getOrCreateComponent <MeshCollider>(); Mesh mesh = mesh_filter.sharedMesh; myGeoAttributeManager = ScriptableObject.CreateInstance <HoudiniGeoAttributeManager>(); myGeoAttributeManager.init(mesh, mesh_renderer, mesh_collider, part_gameobject.transform); // Fetch all point attributes. string[] point_attribute_names = HoudiniHost.getAttributeNames( prAssetId, prObjectId, prGeoId, part_id, HAPI_AttributeOwner.HAPI_ATTROWNER_POINT); foreach (string point_attribute_name in point_attribute_names) { if (point_attribute_name == "P") { continue; } HAPI_AttributeInfo point_attribute_info = HoudiniHost.getAttributeInfo( prAssetId, prObjectId, prGeoId, part_id, point_attribute_name, HAPI_AttributeOwner.HAPI_ATTROWNER_POINT); if (point_attribute_info.storage == HAPI_StorageType.HAPI_STORAGETYPE_INT) { int[] data = new int[0]; HoudiniAssetUtility.getAttribute( prAssetId, prObjectId, prGeoId, part_id, point_attribute_name, ref point_attribute_info, ref data, HoudiniHost.getAttributeIntData); HoudiniGeoAttribute attribute = myGeoAttributeManager.createAttribute(point_attribute_name); attribute.init( mesh, point_attribute_name, HoudiniGeoAttribute.Type.INT, point_attribute_info.tupleSize); attribute.prOriginalAttributeOwner = HAPI_AttributeOwner.HAPI_ATTROWNER_POINT; if (data.Length != attribute.prIntData.Length) { Debug.LogError("Size mis-match in paint tools."); } else { for (int i = 0; i < data.Length; ++i) { attribute.prIntData[i] = data[i]; } } } else if (point_attribute_info.storage == HAPI_StorageType.HAPI_STORAGETYPE_FLOAT) { int tuple_size = point_attribute_info.tupleSize; float[] data = new float[0]; HoudiniAssetUtility.getAttribute( prAssetId, prObjectId, prGeoId, part_id, point_attribute_name, ref point_attribute_info, ref data, HoudiniHost.getAttributeFloatData); HoudiniGeoAttribute attribute = myGeoAttributeManager.createAttribute(point_attribute_name); attribute.init( mesh, point_attribute_name, HoudiniGeoAttribute.Type.FLOAT, tuple_size); attribute.prOriginalAttributeOwner = HAPI_AttributeOwner.HAPI_ATTROWNER_POINT; // Get Vertex list. HAPI_PartInfo part_info = new HAPI_PartInfo(); HoudiniHost.getPartInfo( prAssetId, prObjectId, prGeoId, part_id, out part_info); int[] vertex_list = new int[part_info.vertexCount]; HoudiniAssetUtility.getArray4Id( prAssetId, prObjectId, prGeoId, part_id, HoudiniHost.getVertexList, vertex_list, part_info.vertexCount); if (part_info.vertexCount * tuple_size != attribute.prFloatData.Length) { Debug.LogError("Size mis-match in paint tools."); } else { for (int i = 0; i < part_info.vertexCount; ++i) { for (int tuple = 0; tuple < tuple_size; ++tuple) { attribute.prFloatData[i * tuple_size + tuple] = data[vertex_list[i] * tuple_size + tuple]; } } } } else if (point_attribute_info.storage == HAPI_StorageType.HAPI_STORAGETYPE_STRING) { } } } } #endif // !HAPI_PAINT_SUPPORT // Handle script attaching. if (reload_asset && geo_info.partCount > 0) { HAPI_AttributeInfo script_attr_info = new HAPI_AttributeInfo("Unity_Script"); int[] script_attr = new int[0]; HoudiniAssetUtility.getAttribute( prAssetId, prObjectId, prGeoId, 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_DETAIL) { throw new HoudiniErrorIgnorable("I only understand Unity_Script as detail attributes!"); } if (script_attr_info.exists && script_attr.Length > 0) { string script_to_attach = HoudiniHost.getString(script_attr[0]); HoudiniAssetUtility.attachScript(geo_node, script_to_attach); } } } }
HAPI_SetAttributeStringData( ref HAPI_Session session, HAPI_AssetId asset_id, HAPI_ObjectId object_id, HAPI_GeoId geo_id, string name, ref HAPI_AttributeInfo attr_info, string[] data_array, int start, int length );