Exemple #1
0
    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;
    }
Exemple #2
0
    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;
    }
Exemple #3
0
	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();
	}
Exemple #4
0
    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();
    }