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