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; }
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; }
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. var part_name = part_info.name; if ( prAsset.prOmitPartNameEnumeration ) part_name = part_name.Substring( 0, part_name.LastIndexOf( '_' ) ); part_node.name = part_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; } } } // 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(); }
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); } } } }
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 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(); }
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; } // Clean up first. destoryChildrenWithComponent <BoxCollider>(); destoryChildrenWithComponent <SphereCollider>(); GameObject part_node = gameObject; // Get Part info. HAPI_PartInfo part_info = HoudiniHost.getPartInfo(prGeoId, prPartId); myPartType = part_info.type; bool is_empty = part_info.vertexCount <= 0 && part_info.pointCount <= 0; bool is_mesh = (part_info.vertexCount > 0); bool is_collision_geo = (part_info.name.Contains(HoudiniHost.prCollisionGroupName)); bool is_rendered_collision_geo = (part_info.name.Contains(HoudiniHost.prRenderedCollisionGroupName)); if (is_rendered_collision_geo) { is_collision_geo = false; } // 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. var part_name = part_info.name; if (prAsset.prOmitPartNameEnumeration) { part_name = part_name.Substring(0, part_name.LastIndexOf('_')); } part_node.name = part_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. bool has_visible_geometry = false; try { has_visible_geometry = HoudiniAssetUtility.getMesh( this, part_mesh, prAsset.prGenerateUVs, prAsset.prGenerateLightmapUV2s, prAsset.prGenerateTangents, prAsset.prSplitPointsByVertexAttribute); } 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 (prAsset.prSplitGeosByGroup) { if (is_rendered_collision_geo || is_collision_geo) { getOrCreateComponent <MeshRenderer>(); // For simple prim collider (Box / Sphere), recreating the Box/Sphere collider // will use the mesh renderer to position/size it properly // Unfortunately for now, the returned part infos can have transform issue for box/sphere prim // Create the box collider if one exists. if (myPartType == HAPI_PartType.HAPI_PARTTYPE_BOX) { //createBoxCollider( part_info ); removeComponent <BoxCollider>(); BoxCollider mesh_collider = getOrCreateComponent <BoxCollider>(); mesh_collider.enabled = false; mesh_collider.enabled = true; } else if (myPartType == HAPI_PartType.HAPI_PARTTYPE_SPHERE) { //createSphereCollider( part_info ); removeComponent <SphereCollider>(); SphereCollider mesh_collider = getOrCreateComponent <SphereCollider>(); mesh_collider.enabled = false; mesh_collider.enabled = true; } else { MeshCollider mesh_collider = getOrCreateComponent <MeshCollider>(); mesh_collider.enabled = false; mesh_collider.enabled = true; } if (is_collision_geo) { // We're not a rendered collision geo so we dont need a renderer removeComponent <MeshRenderer>(); } } else { getOrCreateComponent <MeshRenderer>(); // We're not a collision geo so we dont need a collider removeComponent <MeshCollider>(); removeComponent <BoxCollider>(); removeComponent <SphereCollider>(); } } else if (!prAsset.prSplitGeosByGroup && has_visible_geometry) { getOrCreateComponent <MeshRenderer>(); } // TODO: Intermediate mesh editing currently not supported when not splitting by group. if (prAsset.prSplitGeosByGroup) { 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; } } } /* * 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; } // Do we need to enable the colliders? bool enable_colliders = is_visible && (is_collision_geo || is_rendered_collision_geo); if (gameObject.GetComponent <MeshCollider>()) { gameObject.GetComponent <MeshCollider>().enabled = enable_colliders; } if (gameObject.GetComponent <BoxCollider>()) { gameObject.GetComponent <BoxCollider>().enabled = enable_colliders; } if (gameObject.GetComponent <SphereCollider>()) { gameObject.GetComponent <SphereCollider>().enabled = enable_colliders; } // Do we need to enable the mesh renderer ? bool enable_renderers = is_visible && !is_collision_geo; if (gameObject.GetComponent <MeshRenderer>()) { gameObject.GetComponent <MeshRenderer>().enabled = enable_renderers; } } // Assign materials. HoudiniAssetUtility.assignMaterial(this, prAsset, reload_asset); // Assign unity tag. assignUnityTag(); }