Esempio n. 1
0
    // Returns true if the Uni2DSprite data have been generated
    // for a given physic mode
    public bool AreDataGenerated(Uni2DEditorSpriteSettings a_rSpriteSettings)
    {
        bool bArePhysicsDataGenerated = true;

        if (a_rSpriteSettings.physicsMode != Uni2DSprite.PhysicsMode.NoPhysics)
        {
            if (a_rSpriteSettings.dimensionMode == Uni2DSprite.DimensionMode._2D)
            {
                                #if AFTER_UNITY_4_3
                bArePhysicsDataGenerated = polygonCollider2D != null && mesh2D != null;
                                #endif
            }
            else
            {
                bArePhysicsDataGenerated = (this.meshCollidersList != null &&
                                            this.meshCollidersList.Contains(null) == false &&
                                            this.meshColliderComponentsList != null &&
                                            this.meshColliderComponentsList.Contains(null) == false);
            }
        }


        return(this.renderMesh != null &&
               this.renderMeshMaterial != null &&
               bArePhysicsDataGenerated);
    }
    // Deep copy constructor
    public Uni2DEditorSpriteSettings(Uni2DEditorSpriteSettings a_rSpriteSettings)
    {
        this.textureContainer = new Texture2DContainer(a_rSpriteSettings.textureContainer);                     // Deep copy
        this.atlas            = a_rSpriteSettings.atlas;
        this.sharedMaterial   = a_rSpriteSettings.sharedMaterial;

        this.renderMesh             = a_rSpriteSettings.renderMesh;
        this.usePhysicBuildSettings = a_rSpriteSettings.usePhysicBuildSettings;

        this.spriteScale       = a_rSpriteSettings.spriteScale;
        this.pivotType         = a_rSpriteSettings.pivotType;
        this.pivotCustomCoords = a_rSpriteSettings.pivotCustomCoords;
        this.vertexColor       = a_rSpriteSettings.vertexColor;
        this.physicsMode       = a_rSpriteSettings.physicsMode;
        this.collisionType     = a_rSpriteSettings.collisionType;
        this.isKinematic       = a_rSpriteSettings.isKinematic;

        this.renderMeshAlphaCutOff            = a_rSpriteSettings.renderMeshAlphaCutOff;
        this.renderMeshPolygonizationAccuracy = a_rSpriteSettings.renderMeshPolygonizationAccuracy;
        this.renderMeshPolygonizeHoles        = a_rSpriteSettings.renderMeshPolygonizeHoles;

        this.alphaCutOff            = a_rSpriteSettings.alphaCutOff;
        this.extrusionDepth         = a_rSpriteSettings.extrusionDepth;
        this.polygonizationAccuracy = a_rSpriteSettings.polygonizationAccuracy;
        this.polygonizeHoles        = a_rSpriteSettings.polygonizeHoles;

        this.renderMeshGridHorizontalSubDivs = a_rSpriteSettings.renderMeshGridHorizontalSubDivs;
        this.renderMeshGridVerticalSubDivs   = a_rSpriteSettings.renderMeshGridVerticalSubDivs;

        this.skinQuality          = a_rSpriteSettings.skinQuality;
        this.boneInfluenceFalloff = a_rSpriteSettings.boneInfluenceFalloff;
    }
    public static void GenerateBoneWeightsFromSettings( Uni2DEditorSpriteSettings a_rNewSpriteSettings, Uni2DSprite a_rSprite )
    {
        a_rSprite.RestorePosePosition( );
        a_rSprite.UpdatePosing( );

        a_rSprite.SpriteSettings.boneInfluenceFalloff = a_rNewSpriteSettings.boneInfluenceFalloff;
        a_rSprite.SpriteSettings.skinQuality          = a_rNewSpriteSettings.skinQuality;
    }
Esempio n. 4
0
//	// Returns true if the given settings imply to rebuild the sprite quad
//	public bool DoNewSettingsImplyToRebuildQuad( Uni2DEditorSpriteSettings a_rSpriteSettings )
//	{
//		return this.InteractiveParametersEquals( a_rSpriteSettings ) == false
//			|| this.spriteTexture != a_rSpriteSettings.spriteTexture;
//	}

    // Returns true if the given settings imply to rebuild the sprite physic
    public bool DoNewSettingsImplyToRebuildPhysics(Uni2DEditorSpriteSettings a_rSpriteSettings)
    {
        return(this.NonInteractiveParametersEquals(a_rSpriteSettings) == false ||
               this.pivotType != a_rSpriteSettings.pivotType ||
               (this.pivotType == PivotType.Custom &&
                this.pivotCustomCoords != a_rSpriteSettings.pivotCustomCoords) ||
               this.SpriteScale != a_rSpriteSettings.SpriteScale);
    }
Esempio n. 5
0
    // Update the quad mesh size
    public static Mesh UpdateSpriteMeshSizeForAnim(Uni2DSprite a_rSprite, Mesh a_rSpriteMesh, float a_fWidth, float a_fHeight)
    {
        Uni2DEditorSpriteSettings rSpriteSettings = a_rSprite.SpriteSettings;
        Uni2DEditorSpriteData     rSpriteData     = a_rSprite.SpriteData;

        // Scale
        Vector2 fScale  = rSpriteData.Scale;
        float   fWidth  = fScale.x * a_fWidth;
        float   fHeight = fScale.y * a_fHeight;

        // Pivot
        Vector2 f2ScaledPivotCoords = ComputePivotCoords(a_fWidth, a_fHeight, rSpriteSettings.pivotType, rSpriteSettings.pivotCustomCoords);

        f2ScaledPivotCoords.x *= fScale.x;
        f2ScaledPivotCoords.y *= fScale.y;

        if (a_rSpriteMesh != null)
        {
            switch (rSpriteSettings.renderMesh)
            {
            case SpriteRenderMesh.Quad:
            {
                // Update vertices
                a_rSpriteMesh.vertices = GenerateQuadVertices(fWidth, fHeight, f2ScaledPivotCoords);
            }
            break;

            default:
            case SpriteRenderMesh.TextureToMesh:
            case SpriteRenderMesh.Grid:
            {
                // Resize the sprite mesh
                // From the saved original vertices Vo in ( 0; 0 ) base,
                // apply mesh dimensions ratio R = ( Wn; Hn ) / ( Wo; Ho )
                // and finally sub new pivot Pn to have Vn
                // Vo * R - Pn = Vn
                Vector3 f3Ratio             = new Vector3(a_fWidth / rSpriteData.spriteWidth, a_fHeight / rSpriteData.spriteHeight, 0.0f);
                Vector3 f3ScaledPivotCoords = f2ScaledPivotCoords;
                int     iVertexCount        = a_rSpriteMesh.vertexCount;

                Vector3[] oResizedVertices = new Vector3[iVertexCount];

                for (int iVertexIndex = 0; iVertexIndex < iVertexCount; ++iVertexIndex)
                {
                    oResizedVertices[iVertexIndex] = Vector3.Scale(rSpriteData.renderMeshVertices[iVertexIndex], f3Ratio) - f3ScaledPivotCoords;
                }

                a_rSpriteMesh.vertices = oResizedVertices;
            }
            break;
            }
            a_rSpriteMesh.RecalculateBounds( );
        }

        return(a_rSpriteMesh);
    }
 // Returns true if and only if a_rSpriteParameters is not null and if interactive parameters are equal
 public bool InteractiveParametersEquals(Uni2DEditorSpriteSettings a_rSpriteSettings)
 {
     return(a_rSpriteSettings != null &&
            this.usePhysicBuildSettings == a_rSpriteSettings.usePhysicBuildSettings &&
            this.pivotType == a_rSpriteSettings.pivotType &&
            this.pivotCustomCoords == a_rSpriteSettings.pivotCustomCoords &&
            this.spriteScale == a_rSpriteSettings.spriteScale &&
            this.extrusionDepth == a_rSpriteSettings.extrusionDepth &&
            this.atlas == a_rSpriteSettings.atlas &&
            this.sharedMaterial == a_rSpriteSettings.sharedMaterial &&
            this.vertexColor == a_rSpriteSettings.vertexColor &&
            this.isKinematic == a_rSpriteSettings.isKinematic &&
            this.skinQuality == a_rSpriteSettings.skinQuality &&
            this.boneInfluenceFalloff == a_rSpriteSettings.boneInfluenceFalloff);
 }
 // Returns true if and only if a_rSpriteSettings is not null and if non-interactive parameters are equal
 public bool NonInteractiveParametersEquals(Uni2DEditorSpriteSettings a_rSpriteSettings)
 {
     return(a_rSpriteSettings != null &&
            this.physicsMode == a_rSpriteSettings.physicsMode &&
            this.collisionType == a_rSpriteSettings.collisionType &&
            this.alphaCutOff == a_rSpriteSettings.alphaCutOff &&
            this.polygonizationAccuracy == a_rSpriteSettings.polygonizationAccuracy &&
            this.polygonizeHoles == a_rSpriteSettings.polygonizeHoles &&
            this.textureContainer == a_rSpriteSettings.textureContainer &&
            this.renderMesh == a_rSpriteSettings.renderMesh &&
            this.renderMeshAlphaCutOff == a_rSpriteSettings.renderMeshAlphaCutOff &&
            this.renderMeshPolygonizationAccuracy == a_rSpriteSettings.renderMeshPolygonizationAccuracy &&
            this.renderMeshPolygonizeHoles == a_rSpriteSettings.renderMeshPolygonizeHoles &&
            this.renderMeshGridHorizontalSubDivs == a_rSpriteSettings.renderMeshGridHorizontalSubDivs &&
            this.renderMeshGridVerticalSubDivs == a_rSpriteSettings.renderMeshGridVerticalSubDivs);
 }
	// NEW
	// Same as CreateSpriteFromSettings but updates instead of create if a_rSpriteToUpdate != null
	// Rebuild only if necessary but can be forced with a_bForceRebuild == true.
	public static GameObject GenerateSpriteFromSettings( Uni2DEditorSpriteSettings a_rNewSpriteSettings, Uni2DSprite a_rSprite = null, bool a_bForceRebuild = false, bool a_bInABatch = false )
	{
		// Are we updating or creating?
		bool bUpdating = ( a_rSprite != null );

		// Are we allowed to undo if updating
		bool bRegisterUpdateUndo = ms_bUndoEnabled && bUpdating;

		// Game object
		GameObject oSpriteGameObject = bUpdating
			? a_rSprite.gameObject
			: new GameObject( "Sprite_" + a_rNewSpriteSettings.textureContainer.Texture.name );

		// Sprite component
		Uni2DSprite rSprite = bUpdating
			? a_rSprite
			: Uni2DSprite.Create( oSpriteGameObject );
		
		if( a_bInABatch == false )
		{
			// Get texture importer...
			string oTexturePath = AssetDatabase.GetAssetPath( a_rNewSpriteSettings.textureContainer.Texture );
			TextureImporter rTextureImporter = TextureImporter.GetAtPath( oTexturePath ) as TextureImporter;
	
			// ...if any...
			if( rTextureImporter != null )
			{
				if( bRegisterUpdateUndo )
				{
					// Allow undo this update
					Undo.RegisterSceneUndo( "Update Uni2D sprite" );
				}
	
				TextureImporterSettings oTextureImporterSettings = Uni2DEditorSpriteBuilderUtils.TextureProcessingBegin( rTextureImporter );
	
				// Create/update sprite material
				GenerateSpriteMatFromSettings( a_rNewSpriteSettings, rSprite );
	
				// Create/update sprite mesh
				GenerateSpriteMeshFromSettings( a_rNewSpriteSettings, rSprite );
	
				// Create/update colliders
				GenerateCollidersFromSettings( a_rNewSpriteSettings, rSprite, a_bForceRebuild );
	
				// Post build operations
				rSprite.AfterBuild();
	
				Uni2DEditorSpriteBuilderUtils.TextureProcessingEnd( rTextureImporter, oTextureImporterSettings );
			}
	
			// Allow undo the creation (i.e. bUpdating == false)
			if( bUpdating == false && ms_bUndoEnabled )
			{
				Undo.RegisterCreatedObjectUndo( oSpriteGameObject, "Create Uni2D sprite" );
			}
		}
		else // Batching: no texture imports, no register undos...
		{
			// Create/update sprite material
			GenerateSpriteMatFromSettings( a_rNewSpriteSettings, rSprite );

			// Create/update sprite mesh
			GenerateSpriteMeshFromSettings( a_rNewSpriteSettings, rSprite );

			// Create/update colliders
			GenerateCollidersFromSettings( a_rNewSpriteSettings, rSprite, a_bForceRebuild );

			// Post build operations
			rSprite.AfterBuild();
		}

		return oSpriteGameObject;
	}
	// NEW
	// Creates/updates colliders according to given new settings
	public static GameObject GenerateCollidersFromSettings( Uni2DEditorSpriteSettings a_rNewSpriteSettings, Uni2DSprite a_rSprite, bool a_bForceRebuild )
	{
		Uni2DEditorSpriteSettings rCurrentSpriteSettings = a_rSprite.SpriteSettings;
		Uni2DEditorSpriteData rCurrentSpriteData = a_rSprite.SpriteData;

		GameObject rSpriteGameObject = a_rSprite.gameObject;

		// Is rebuilding needed?
		bool bRebuild = a_bForceRebuild
			|| a_rSprite.isPhysicsDirty
			|| rCurrentSpriteSettings.DoNewSettingsImplyToRebuildPhysics( a_rNewSpriteSettings );

		if( bRebuild )
		{
			// Clean the sprite (if needed)
			RemoveGeneratedColliders( a_rSprite );

			// Generate meshes
			List<Mesh> rMeshList = PolygonizeTextureToMeshColliderFromSettings( a_rNewSpriteSettings );
			
			if( rMeshList == null )
			{
				rMeshList = new List<Mesh>( );
			}

			List<MeshCollider> oMeshColliderComponentsList = new List<MeshCollider>( rMeshList.Count );

			// Add collider children
			// Attach a mesh collider collider to current game object
			// if collider is not compound
			GameObject oColliderParentGameObject = null;

			// Mesh collider triangle count
			int iMeshColliderTriangleCount = 0;

			// Components creation
			if( a_rNewSpriteSettings.physicsMode != Uni2DSprite.PhysicsMode.NoPhysics )
			{
				// Compound
				if( a_rNewSpriteSettings.collisionType == Uni2DSprite.CollisionType.Compound )
				{
					oColliderParentGameObject = new GameObject( "root_Colliders" );
		
					// Create a game object for each mesh collider and attach them to sprite game object
					for( int iColliderIndex = 0, iMeshCount = rMeshList.Count; iColliderIndex < iMeshCount; ++iColliderIndex )
					{
						GameObject oMeshColliderGameObject  = new GameObject( "mesh_Collider_" + iColliderIndex );
						MeshCollider oMeshColliderComponent = oMeshColliderGameObject.AddComponent<MeshCollider>( );
						oMeshColliderComponent.sharedMesh   = rMeshList[ iColliderIndex ];
						oMeshColliderComponent.convex       = true;
		
						oMeshColliderComponentsList.Add( oMeshColliderComponent );
		
						// Child -> parent attachment
						oMeshColliderGameObject.transform.parent = oColliderParentGameObject.transform;

						iMeshColliderTriangleCount += rMeshList[ iColliderIndex ].triangles.Length;
					}
					Transform rColliderParentTransform = oColliderParentGameObject.transform;
					rColliderParentTransform.parent        = rSpriteGameObject.transform;
					rColliderParentTransform.localPosition = Vector3.zero;
					rColliderParentTransform.localRotation = Quaternion.identity;
					rColliderParentTransform.localScale    = Vector3.one;
				}
				else // Static / Dynamic
				{
					MeshCollider oMeshColliderComponent = rSpriteGameObject.GetComponent<MeshCollider>( );
					if( oMeshColliderComponent == null )
					{
						oMeshColliderComponent = rSpriteGameObject.AddComponent<MeshCollider>( );
					}

					oMeshColliderComponent.sharedMesh = rMeshList[ 0 ];
					oMeshColliderComponentsList.Add( oMeshColliderComponent );

					// Set whether or not mesh collider is convex
					oMeshColliderComponent.convex = ( a_rNewSpriteSettings.collisionType == Uni2DSprite.CollisionType.Convex );
					iMeshColliderTriangleCount = rMeshList[ 0 ].triangles.Length;
				}

				// Add rigidbody to sprite game object if any dynamic mode is specified
				Uni2DEditorSpriteBuilderUtils.SetupRigidbodyFor2D( a_rSprite, a_rNewSpriteSettings );
			}

			// Settings
			rCurrentSpriteSettings.alphaCutOff            = a_rNewSpriteSettings.alphaCutOff;
			rCurrentSpriteSettings.collisionType          = a_rNewSpriteSettings.collisionType;
			rCurrentSpriteSettings.extrusionDepth         = a_rNewSpriteSettings.extrusionDepth;
			rCurrentSpriteSettings.isKinematic            = a_rNewSpriteSettings.isKinematic;
			rCurrentSpriteSettings.physicsMode            = a_rNewSpriteSettings.physicsMode;
			rCurrentSpriteSettings.pivotType              = a_rNewSpriteSettings.pivotType;
			rCurrentSpriteSettings.pivotCustomCoords      = a_rNewSpriteSettings.pivotCustomCoords;
			rCurrentSpriteSettings.polygonizationAccuracy = a_rNewSpriteSettings.polygonizationAccuracy;
			rCurrentSpriteSettings.polygonizeHoles        = a_rNewSpriteSettings.polygonizeHoles;

			// Generated data
			rCurrentSpriteData.meshColliderComponentsList  = oMeshColliderComponentsList;
			rCurrentSpriteData.meshCollidersList           = rMeshList;
			rCurrentSpriteData.meshCollidersRootGameObject = oColliderParentGameObject;
			rCurrentSpriteData.colliderTriangleCount       = ( iMeshColliderTriangleCount / 3 );
			rCurrentSpriteData.pivotCoords                 = a_rNewSpriteSettings.PivotCoords;

		}

		// Is up to date!
		a_rSprite.isPhysicsDirty = false;

		return rSpriteGameObject;
	}
	// Setup rigidbody 2d
	private static void SetupRigidbodyFor2D( Uni2DSprite a_rSprite, Uni2DEditorSpriteSettings a_rNewSettings = null )
	{
		Uni2DEditorSpriteSettings rCurrentSettings = a_rNewSettings == null ? a_rSprite.SpriteSettings : a_rNewSettings;
		Rigidbody rSpriteRigidbody = a_rSprite.GetComponent<Rigidbody>( );

		// Setup the rigidbody
		if( rCurrentSettings.physicsMode == Uni2DSprite.PhysicsMode.Dynamic )
		{
			// Add the rigidbody component
			if( rSpriteRigidbody == null )
			{
				rSpriteRigidbody = a_rSprite.gameObject.AddComponent<Rigidbody>( );
			}

			rSpriteRigidbody.constraints = RigidbodyConstraints.FreezePositionZ | RigidbodyConstraints.FreezeRotationX | RigidbodyConstraints.FreezeRotationY;
			rSpriteRigidbody.isKinematic = rCurrentSettings.isKinematic;
		}
		else if( rSpriteRigidbody != null ) // a rigidbody is not needed in the other modes
		{
			MonoBehaviour.DestroyImmediate( rSpriteRigidbody );
		}
	}
	// NEW
	// Creates/updates the quad mesh material of a sprite according to given new settings.
	public static GameObject GenerateSpriteMatFromSettings( Uni2DEditorSpriteSettings a_rNewSpriteSettings, Uni2DSprite a_rSprite )
	{
		Material oSpriteRendererMaterial;
		Material oSpriteMeshMaterial;

		Uni2DEditorSpriteData rCurrentSpriteData         = a_rSprite.SpriteData;
		Uni2DEditorSpriteSettings rCurrentSpriteSettings = a_rSprite.SpriteSettings;

		Texture2D rNewSpriteTexture = a_rNewSpriteSettings.textureContainer;

		GameObject rSpriteGameObject = a_rSprite.gameObject;
		
		// If a shared material is used with a texture different from the sprite texture
		// or if an atlas is used
		if(a_rNewSpriteSettings.ShouldUseAtlas( ) 
			|| (a_rNewSpriteSettings.sharedMaterial != null && a_rNewSpriteSettings.textureContainer.Texture != a_rNewSpriteSettings.sharedMaterial.mainTexture) )
		{
			// don't use the shared material
			a_rNewSpriteSettings.sharedMaterial = null;
		}
		
		Material rGeneratedMaterial = null;
		if(a_rNewSpriteSettings.sharedMaterial == null && a_rNewSpriteSettings.ShouldUseAtlas( ) == false)
		{
			// If the material doesn't exist yet, create it
			rGeneratedMaterial = rCurrentSpriteData.generatedMaterial;
			if( rGeneratedMaterial == null )
			{
				// create a new one
				rGeneratedMaterial = new Material( Shader.Find( mc_oSpriteDefaultShader ) );
	
				// Set mat name
				rGeneratedMaterial.name = "mat_Generated_Sprite_" + rNewSpriteTexture.name;
				
				rCurrentSpriteData.generatedMaterial = rGeneratedMaterial;
			}
		}
		rCurrentSpriteData.generatedMaterial = rGeneratedMaterial;
		
		Material rSharedMaterial = a_rNewSpriteSettings.sharedMaterial;
		if(rSharedMaterial == null)
		{
			oSpriteMeshMaterial = rGeneratedMaterial;
		}
		else
		{
			oSpriteMeshMaterial = rSharedMaterial;
		}
		
		// If no atlas...
		if( a_rNewSpriteSettings.ShouldUseAtlas( ) == false )
		{
			oSpriteRendererMaterial = oSpriteMeshMaterial;
			a_rNewSpriteSettings.atlas = null;
			
			// Set mat texture
			oSpriteMeshMaterial.mainTexture = rNewSpriteTexture;
		}
		else
		{
			oSpriteRendererMaterial = a_rNewSpriteSettings.atlas.GetMaterial( rNewSpriteTexture );
			oSpriteMeshMaterial = oSpriteRendererMaterial;
		}
		
		// Init. rendering component
		// Add it if not created
		Renderer rSpriteMeshRendererComponent = a_rSprite.renderer;// a_rSprite.GetComponent<MeshRenderer>( );

		if( rSpriteMeshRendererComponent == null )
		{
			if( a_rSprite.Bones.Length > 0 )
			{
				rSpriteMeshRendererComponent = rSpriteGameObject.AddComponent<SkinnedMeshRenderer>( );
			}
			else
			{
				rSpriteMeshRendererComponent = rSpriteGameObject.AddComponent<MeshRenderer>( );
			}
		}

		// Set new material to mesh renderer
		rSpriteMeshRendererComponent.sharedMaterial = oSpriteRendererMaterial;

		// Update sprite settings
		rCurrentSpriteSettings.textureContainer = new Texture2DContainer( rNewSpriteTexture, a_rNewSpriteSettings.atlas == null );
		rCurrentSpriteSettings.atlas            = a_rNewSpriteSettings.atlas;

		// Update sprite generated data
		rCurrentSpriteData.renderMeshMaterial   = oSpriteMeshMaterial;

		return rSpriteGameObject;
	}
	// NEW
	// Removes the generated physic colliders attached to a sprite
	private static void RemoveGeneratedComponents(Uni2DSprite a_rSpriteToClean, Uni2DEditorSpriteSettings a_rNewSpriteSettings)
	{
		if(a_rSpriteToClean != null)
		{
			// 3D
			
			// Colliders
			
			// Retrieve the generated data of the sprite to clean
			Uni2DEditorSpriteData rSpriteData = a_rSpriteToClean.SpriteData;
			
			// Delete resources
			// Delete game objects in excess
			if(rSpriteData.meshColliderComponentsList != null)
			{
				for(int i = rSpriteData.meshColliderComponentsList.Count - 1; i >= 0; --i)
				{
					MeshCollider rMeshColliderComponent = rSpriteData.meshColliderComponentsList[i];
					
					bool bRemove = false;
					if( rMeshColliderComponent != null )
					{
						// If the mesh collider component is attached to another game object
						// than the sprite itself, we destroy it too (because that component was its unique purpose)
						if( rMeshColliderComponent.gameObject != a_rSpriteToClean.gameObject)
						{
							// Destroy game object AND component
							GameObject.DestroyImmediate(rMeshColliderComponent.gameObject);
							bRemove = true;
						}
						else
						{
							// If we doesn't need a collider on the game object anymore
							if(a_rNewSpriteSettings.physicsMode == Uni2DSprite.PhysicsMode.NoPhysics
							    || a_rNewSpriteSettings.collisionType == Uni2DSprite.CollisionType.Compound
							   	|| a_rNewSpriteSettings.dimensionMode != Uni2DSprite.DimensionMode._3D
							    )
							{
								// Destroy component
								MonoBehaviour.DestroyImmediate(rMeshColliderComponent);
								bRemove = true;
							}
						}
					}
					else
					{
						bRemove = true;
					}
					
					if(bRemove)
					{
						rSpriteData.meshColliderComponentsList.RemoveAt(i);
						rSpriteData.meshCollidersList.RemoveAt(i);
					}
				}
			}
			if(rSpriteData.meshCollidersList == null || rSpriteData.meshCollidersList.Count <= 0)
			{
				rSpriteData.meshCollidersList = null;
				rSpriteData.meshColliderComponentsList = null;
				rSpriteData.colliderTriangleCount = 0;
			}
			
			// Destroy mesh collider root game object (if any)
			if( rSpriteData.meshCollidersRootGameObject != null )
			{
				// Destroy game object
				GameObject.DestroyImmediate(rSpriteData.meshCollidersRootGameObject);
			}
			
			// Rigidbody
			if(a_rNewSpriteSettings.physicsMode != Uni2DSprite.PhysicsMode.Dynamic
			   || a_rNewSpriteSettings.dimensionMode != Uni2DSprite.DimensionMode._3D)
			{
				Rigidbody rRigidbodyComponent = a_rSpriteToClean.GetComponent<Rigidbody>( );
				if(rRigidbodyComponent != null)
				{
					// Destroy component
					MonoBehaviour.DestroyImmediate( rRigidbodyComponent );
				}
			}
			
			// 2D
			
			#if AFTER_UNITY_4_3
			// Rigidbody
			if(a_rNewSpriteSettings.physicsMode != Uni2DSprite.PhysicsMode.Dynamic
			   || a_rNewSpriteSettings.dimensionMode != Uni2DSprite.DimensionMode._2D)
			{
				Rigidbody2D rRigidbodyComponent2D = a_rSpriteToClean.GetComponent<Rigidbody2D>( );
				if(rRigidbodyComponent2D != null)
				{
					// Destroy component
					MonoBehaviour.DestroyImmediate( rRigidbodyComponent2D );
				}
			}
			
			rSpriteData.polygonCollider2D = null;
			PolygonCollider2D rPolygonCollider2D = a_rSpriteToClean.GetComponent<PolygonCollider2D>();
			if(rPolygonCollider2D != null)
			{
				if(a_rNewSpriteSettings.physicsMode == Uni2DSprite.PhysicsMode.NoPhysics
				   || a_rNewSpriteSettings.dimensionMode != Uni2DSprite.DimensionMode._2D)
				{
					MonoBehaviour.DestroyImmediate(rPolygonCollider2D);
				}
				else
				{
					rSpriteData.polygonCollider2D = rPolygonCollider2D;
				}
				
			}
			#endif
		}
	}
	// NEW
	// Creates/updates the quad mesh of a sprite according to given new settings.
	public static GameObject GenerateSpriteMeshFromSettings( Uni2DEditorSpriteSettings a_rNewSpriteSettings, Uni2DSprite a_rSprite )
	{
		GameObject rSpriteGameObject = a_rSprite.gameObject;

		Uni2DEditorSpriteData rCurrentSpriteData         = a_rSprite.SpriteData;
		Uni2DEditorSpriteSettings rCurrentSpriteSettings = a_rSprite.SpriteSettings;

		Texture2DContainer rTextureContainer = a_rNewSpriteSettings.textureContainer;
		Texture2D rSpriteTexture = rTextureContainer;

		// Init. mesh filter component
		// Add it if not created
		MeshFilter rSpriteMeshFilter = a_rSprite.GetComponent<MeshFilter>( );
		if( rSpriteMeshFilter == null )
		{
			rSpriteMeshFilter = rSpriteGameObject.AddComponent<MeshFilter>( );
		}

		// Retrieve pivot coords
		Vector2 f2ScaledPivotCoords = a_rNewSpriteSettings.ScaledPivotCoords;

		// Quad mesh
		Mesh oSpriteMesh;
		Uni2DTextureAtlas rTextureAtlas = a_rNewSpriteSettings.atlas;
		Vector3[ ] oRenderMeshVertices = null;
		Vector2[ ] oRenderMeshNormalizedUVs = null;
		int iVertexCount;

		SpriteRenderMesh eRenderMesh = a_rNewSpriteSettings.renderMesh;

		// Check if using atlas and texture is well included in this atlas
		if( a_rNewSpriteSettings.ShouldUseAtlas( ) == false )
		{
			// No atlas => clean settings
			a_rNewSpriteSettings.atlas = null;
			rTextureAtlas = null;
		}

		// Render Mesh
		switch( eRenderMesh )
		{
			// Quad
			default:
			case SpriteRenderMesh.Quad:
			{
				// Mesh creation
				oSpriteMesh = new Mesh( );
				
				// Quad vertices
				oRenderMeshVertices = Uni2DSpriteUtils.GenerateQuadVertices( a_rNewSpriteSettings.SpriteWidth,
					a_rNewSpriteSettings.SpriteHeight,
					f2ScaledPivotCoords );
				
				oSpriteMesh.vertices = oRenderMeshVertices;
				iVertexCount = 4;
				
				// Quad triangles
				oSpriteMesh.triangles = new int[ 6 ]
				{
					1, 0, 2,
					2, 0, 3
				};
				
				// Quad UVs
				oRenderMeshNormalizedUVs = new Vector2[ 4 ]
				{
					new Vector2( 0.0f, 0.0f ),
					new Vector2( 1.0f, 0.0f ),
					new Vector2( 1.0f, 1.0f ),
					new Vector2( 0.0f, 1.0f )
				};
			}
			break;

			// Create a sprite via texture polygonization
			case SpriteRenderMesh.Grid:
			case SpriteRenderMesh.TextureToMesh:
			{
				oSpriteMesh = PolygonizeTextureToMeshFromSettings( a_rNewSpriteSettings );
				
				// Copy render mesh vertices/UVs (.vertices & .uv return a copy)
				oRenderMeshNormalizedUVs = oSpriteMesh.uv;
				oRenderMeshVertices      = oSpriteMesh.vertices;
				iVertexCount             = oSpriteMesh.vertexCount;
			}
			break;
		}


		// Build UVs from various settings (atlasing, render mesh, etc)
		oSpriteMesh.uv = Uni2DSpriteUtils.BuildUVs( rTextureContainer, oRenderMeshNormalizedUVs, rTextureAtlas );

		// Re-iterate vertices and unapply pivot in order to have
		// a copy of all mesh vertices in ( 0; 0 ) base
		Vector3 f3ScaledPivotCoords = f2ScaledPivotCoords;
		for( int iVertexIndex = 0; iVertexIndex < iVertexCount; ++iVertexIndex )
		{
			oRenderMeshVertices[ iVertexIndex ] += f3ScaledPivotCoords;
		}

		// Set vertex color array (32bits)
		Uni2DSpriteUtils.UpdateMeshVertexColor( oSpriteMesh, a_rNewSpriteSettings.vertexColor );


		// Optim. mesh
		oSpriteMesh.RecalculateBounds( );
		oSpriteMesh.RecalculateNormals( );
		oSpriteMesh.Optimize( );
		
		oSpriteMesh.name = "mesh_Sprite_";
		
		if(rSpriteTexture != null)
		{
			oSpriteMesh.name += rSpriteTexture.name;	
		}
		else
		{
			oSpriteMesh.name += "MissingTexture";
		}
		
		// Set new sprite settings
		rCurrentSpriteSettings.pivotType         = a_rNewSpriteSettings.pivotType;
		rCurrentSpriteSettings.pivotCustomCoords = a_rNewSpriteSettings.pivotCustomCoords;
		rCurrentSpriteSettings.spriteScale       = a_rNewSpriteSettings.spriteScale;
		rCurrentSpriteSettings.atlas             = rTextureAtlas;
		rCurrentSpriteSettings.textureContainer  = new Texture2DContainer( rSpriteTexture, rTextureAtlas == null );

		rCurrentSpriteSettings.renderMeshAlphaCutOff            = a_rNewSpriteSettings.renderMeshAlphaCutOff;
		rCurrentSpriteSettings.renderMeshPolygonizationAccuracy = a_rNewSpriteSettings.renderMeshPolygonizationAccuracy;
		rCurrentSpriteSettings.renderMeshPolygonizeHoles		= a_rNewSpriteSettings.renderMeshPolygonizeHoles;
		rCurrentSpriteSettings.usePhysicBuildSettings           = a_rNewSpriteSettings.usePhysicBuildSettings;
		rCurrentSpriteSettings.renderMesh                       = a_rNewSpriteSettings.renderMesh;
		rCurrentSpriteSettings.renderMeshGridHorizontalSubDivs  = a_rNewSpriteSettings.renderMeshGridHorizontalSubDivs;
		rCurrentSpriteSettings.renderMeshGridVerticalSubDivs    = a_rNewSpriteSettings.renderMeshGridVerticalSubDivs;

		// Set new sprite generated data
		rCurrentSpriteData.renderMesh         = oSpriteMesh;
		rCurrentSpriteData.renderMeshVertices = oRenderMeshVertices;
		rCurrentSpriteData.renderMeshUVs      = oRenderMeshNormalizedUVs;
		if(rSpriteTexture != null)
		{
			rCurrentSpriteData.spriteWidth        = rSpriteTexture.width;
			rCurrentSpriteData.spriteHeight       = rSpriteTexture.height;
		}
		// Set computed pivot coords
		rCurrentSpriteData.pivotCoords        = a_rNewSpriteSettings.PivotCoords;
		rCurrentSpriteData.scale              = a_rNewSpriteSettings.ScaleFactor;

		a_rSprite.atlasGenerationID = ( rTextureAtlas != null )
			? rTextureAtlas.generationId
			: "";

		// Set mesh to mesh filter component
		rSpriteMeshFilter.sharedMesh = oSpriteMesh;

		// Compute bone weights if needed
		GenerateBoneWeightsFromSettings( a_rNewSpriteSettings, a_rSprite );

		
		return rSpriteGameObject;
	}
Esempio n. 14
0
	// Returns true if the Uni2DSprite data have been generated
	// for a given physic mode
	public bool AreDataGenerated(Uni2DEditorSpriteSettings a_rSpriteSettings)
	{
		bool bArePhysicsDataGenerated = true;
		if(a_rSpriteSettings.physicsMode != Uni2DSprite.PhysicsMode.NoPhysics)
		{
			if(a_rSpriteSettings.dimensionMode == Uni2DSprite.DimensionMode._2D)
			{
				#if AFTER_UNITY_4_3
				bArePhysicsDataGenerated = polygonCollider2D != null && mesh2D != null;
				#endif
			}
			else
			{
				bArePhysicsDataGenerated = ( this.meshCollidersList                            != null
				                            && this.meshCollidersList.Contains( null )          == false
				                            && this.meshColliderComponentsList                  != null
				                            && this.meshColliderComponentsList.Contains( null ) == false);
			}
		}

		
		return this.renderMesh     != null
			&& this.renderMeshMaterial != null
			&& bArePhysicsDataGenerated;
	}
	// Returns true if and only if a_rSpriteParameters is not null and if interactive parameters are equal
	public bool InteractiveParametersEquals( Uni2DEditorSpriteSettings a_rSpriteSettings )
	{
		return a_rSpriteSettings           != null
			&& this.usePhysicBuildSettings == a_rSpriteSettings.usePhysicBuildSettings
			&& this.pivotType              == a_rSpriteSettings.pivotType
			&& this.pivotCustomCoords      == a_rSpriteSettings.pivotCustomCoords
			&& this.spriteScaleMode        == a_rSpriteSettings.spriteScaleMode
			&& this.spriteScale            == a_rSpriteSettings.spriteScale
			&& this.spriteScaleNotUniform  == a_rSpriteSettings.spriteScaleNotUniform
			&& this.extrusionDepth         == a_rSpriteSettings.extrusionDepth
			&& this.atlas                  == a_rSpriteSettings.atlas
			&& this.sharedMaterial		   == a_rSpriteSettings.sharedMaterial
			&& this.vertexColor            == a_rSpriteSettings.vertexColor
			&& this.isKinematic            == a_rSpriteSettings.isKinematic
			&& this.isTrigger			   == a_rSpriteSettings.isTrigger
			&& this.skinQuality            == a_rSpriteSettings.skinQuality
			&& this.boneInfluenceFalloff   == a_rSpriteSettings.boneInfluenceFalloff;
	}
Esempio n. 16
0
 // Same as above but with an Uni2DEditorSpriteSettings argument.
 public bool Equals(Uni2DEditorSpriteSettings a_rSpriteSettings)
 {
     return(this.InteractiveParametersEquals(a_rSpriteSettings) &&
            this.NonInteractiveParametersEquals(a_rSpriteSettings));
 }
    private static void UpdateUni2DAssets( )
    {
        EditorApplication.delayCall -= UpdateUni2DAssets;

        Uni2DEditorAssetTable rAssetTable = Uni2DEditorAssetTable.Instance;

        try
        {
            Uni2DAssetPostprocessor.LockTo(false);

            // Update animation clips first, because they can change the atlases
            foreach (string rAnimationClipGUID in ms_oAnimationClipGUIDsToUpdate)
            {
                Uni2DAnimationClip rAnimationClip = Uni2DEditorUtils.GetAssetFromUnityGUID <Uni2DAnimationClip>(rAnimationClipGUID);
                if (rAnimationClip != null)
                {
                    //Debug.Log ( "Updating clip " + rAnimationClipGUID );
                    rAnimationClip.OnTexturesChange(ms_oImportedTextureGUIDs);

                    rAnimationClip = null;
                    EditorUtility.UnloadUnusedAssets( );
                }
                else
                {
                    // Clean asset table
                    foreach (string rTextureGUID in ms_oImportedTextureGUIDs)
                    {
                        rAssetTable.RemoveClipUsingTexture(rAnimationClipGUID, rTextureGUID);
                    }
                }
            }

            foreach (string rAtlasGUID in ms_oAtlasGUIDsToUpdate)
            {
                Uni2DTextureAtlas rAtlas = Uni2DEditorUtils.GetAssetFromUnityGUID <Uni2DTextureAtlas>(rAtlasGUID);

                if (rAtlas != null)
                {
                    //Debug.Log( "Updating atlas " + rAtlasGUID );
                    rAtlas.OnTextureChange( );

                    rAtlas = null;
                    EditorUtility.UnloadUnusedAssets( );
                }
                else
                {
                    // Clean
                    foreach (string rTextureGUID in ms_oImportedTextureGUIDs)
                    {
                        rAssetTable.RemoveAtlasUsingTexture(rAtlasGUID, rTextureGUID);
                    }
                }
            }

            foreach (string rSpritePrefabGUID in ms_oSpritePrefabGUIDsToUpdate)
            {
                GameObject rSpritePrefab = Uni2DEditorUtils.GetAssetFromUnityGUID <GameObject>(rSpritePrefabGUID);

                if (rSpritePrefab != null)
                {
                    //Debug.Log( "Updating sprite prefab " + rSpritePrefabGUID );
                    foreach (Uni2DSprite rSpritePrefabComponent in rSpritePrefab.GetComponentsInChildren <Uni2DSprite>(true))
                    {
                        Uni2DEditorSpriteSettings rSpriteSettings = rSpritePrefabComponent.SpriteSettings;
                        string rSpriteTextureGUID = rSpriteSettings.textureContainer.GUID;
                        string rSpriteAtlasGUID   = rSpriteSettings.atlas != null?Uni2DEditorUtils.GetUnityAssetGUID(rSpriteSettings.atlas) : null;

                        if (ms_oImportedTextureGUIDs.Contains(rSpriteTextureGUID) || (!string.IsNullOrEmpty(rSpriteAtlasGUID) && ms_oAtlasGUIDsToUpdate.Contains(rSpriteAtlasGUID)))
                        {
                            rSpritePrefabComponent.Regenerate(true);
                        }

                        EditorUtility.UnloadUnusedAssets( );
                    }

                    rSpritePrefab = null;
                    EditorUtility.UnloadUnusedAssets( );
                }
                else
                {
                    // Clean
                    foreach (string rTextureGUID in ms_oImportedTextureGUIDs)
                    {
                        rAssetTable.RemoveSpritePrefabUsingTexture(rSpritePrefabGUID, rTextureGUID);
                    }

                    foreach (string rAtlasGUID in ms_oAtlasGUIDsToUpdate)
                    {
                        rAssetTable.RemoveSpritePrefabUsingAtlas(rSpritePrefabGUID, rAtlasGUID);
                    }
                }
            }
        }
        finally
        {
            ms_oImportedTextureGUIDs.Clear( );

            ms_oAtlasGUIDsToUpdate.Clear( );
            ms_oAnimationClipGUIDsToUpdate.Clear( );
            ms_oSpritePrefabGUIDsToUpdate.Clear( );

            rAssetTable.Save( );

            Uni2DAssetPostprocessor.Unlock( );
            Uni2DAssetPostprocessor.Enabled = true;
        }
    }
	// Same as above but with an Uni2DEditorSpriteSettings argument.
	public bool Equals( Uni2DEditorSpriteSettings a_rSpriteSettings )
	{
		return this.InteractiveParametersEquals( a_rSpriteSettings )
			&& this.NonInteractiveParametersEquals( a_rSpriteSettings );
	}
//	// Returns true if the given settings imply to rebuild the sprite quad
//	public bool DoNewSettingsImplyToRebuildQuad( Uni2DEditorSpriteSettings a_rSpriteSettings )
//	{
//		return this.InteractiveParametersEquals( a_rSpriteSettings ) == false
//			|| this.spriteTexture != a_rSpriteSettings.spriteTexture;
//	}

	// Returns true if the given settings imply to rebuild the sprite physic
	public bool DoNewSettingsImplyToRebuildPhysics( Uni2DEditorSpriteSettings a_rSpriteSettings )
	{
		return this.NonInteractiveParametersEquals( a_rSpriteSettings ) == false
			|| this.pivotType         != a_rSpriteSettings.pivotType
			|| ( this.pivotType       == PivotType.Custom
					&& this.pivotCustomCoords != a_rSpriteSettings.pivotCustomCoords )
			|| this.SpriteScale       != a_rSpriteSettings.SpriteScale;
	}
	// Returns true if and only if a_rSpriteSettings is not null and if non-interactive parameters are equal
	public bool NonInteractiveParametersEquals( Uni2DEditorSpriteSettings a_rSpriteSettings )
	{
		return a_rSpriteSettings                     != null
			&& this.dimensionMode                     == a_rSpriteSettings.dimensionMode
			&& this.physicsMode                      == a_rSpriteSettings.physicsMode
			&& this.collisionType                    == a_rSpriteSettings.collisionType
			&& this.alphaCutOff                      == a_rSpriteSettings.alphaCutOff
			&& this.polygonizationAccuracy           == a_rSpriteSettings.polygonizationAccuracy
			&& this.polygonizeHoles                  == a_rSpriteSettings.polygonizeHoles
			&& this.textureContainer                 == a_rSpriteSettings.textureContainer
			&& this.renderMesh                       == a_rSpriteSettings.renderMesh
			&& this.renderMeshAlphaCutOff            == a_rSpriteSettings.renderMeshAlphaCutOff
			&& this.renderMeshPolygonizationAccuracy == a_rSpriteSettings.renderMeshPolygonizationAccuracy
			&& this.renderMeshPolygonizeHoles == a_rSpriteSettings.renderMeshPolygonizeHoles
			&& this.renderMeshGridHorizontalSubDivs  == a_rSpriteSettings.renderMeshGridHorizontalSubDivs
			&& this.renderMeshGridVerticalSubDivs    == a_rSpriteSettings.renderMeshGridVerticalSubDivs
			&& this.onlyBorder    == a_rSpriteSettings.onlyBorder
			&& this.subdivide    == a_rSpriteSettings.subdivide
			&& this.subdivisionCount    == a_rSpriteSettings.subdivisionCount;
	}
	// NEW
	// Parse a 2D texture and make mesh colliders from edges
	public static Mesh PolygonizeTextureToMeshFromSettings( Uni2DEditorSpriteSettings a_rSpriteSettings )
	{
		// Ensure we have an input texture and an output render mesh requiring to parse that texture to be built
		if( a_rSpriteSettings.textureContainer == null || a_rSpriteSettings.renderMesh == SpriteRenderMesh.Quad )
		{
			return null;
		}

		// The texture to polygonize
		Texture2D rTextureToPolygonize = a_rSpriteSettings.textureContainer;
		float fAlphaCutOff;
		float fPolygonizationAccuracy;

		if( a_rSpriteSettings.usePhysicBuildSettings )
		{
			fAlphaCutOff            = a_rSpriteSettings.alphaCutOff;
			fPolygonizationAccuracy = a_rSpriteSettings.polygonizationAccuracy;
		}
		else
		{
			fAlphaCutOff            = a_rSpriteSettings.renderMeshAlphaCutOff;
			fPolygonizationAccuracy = a_rSpriteSettings.renderMeshPolygonizationAccuracy;
		}

		// Step 1
		// Distinguish completely transparent pixels from significant pixel by "binarizing" the texture.
		Uni2DEditorUtilsBuildingProgressBar.AddProcessedSpriteBuildStep( );
		BinarizedImage rBinarizedImage = Uni2DEditorShapeExtractionUtils.BinarizeTexture( rTextureToPolygonize, fAlphaCutOff );


		// Mesh creation
		Mesh rMesh;
		switch( a_rSpriteSettings.renderMesh )
		{
			case SpriteRenderMesh.TextureToMesh:
			{
				// Step 2
				// Build binarized outer/inner contours and label image regions
				List<Contour> oOuterContours;
				List<Contour> oInnerContours;
				
				Uni2DEditorUtilsBuildingProgressBar.AddProcessedSpriteBuildStep( );
				Uni2DEditorContourExtractionUtils.CombinedContourLabeling( rBinarizedImage, a_rSpriteSettings.renderMeshPolygonizeHoles, out oOuterContours, out oInnerContours );
				
				// Step 3: vectorization (determine dominant points)
				if( a_rSpriteSettings.renderMeshPolygonizeHoles )
				{
					// Step 3a: if hole support asked by user, merge inner contours into outer contours first
					oOuterContours = Uni2DEditorContourPolygonizationUtils.MergeInnerAndOuterContours( oOuterContours, oInnerContours );
				}
			
				// Simplify contours
				Uni2DEditorUtilsBuildingProgressBar.AddProcessedSpriteBuildStep( );
				List<Contour> oDominantContoursList = Uni2DEditorContourPolygonizationUtils.SimplifyContours( oOuterContours, fPolygonizationAccuracy );
				
				// Step 4: triangulation
				Uni2DEditorUtilsBuildingProgressBar.AddProcessedSpriteBuildStep( );
				rMesh = Uni2DEditorPolygonTriangulationUtils.PolygonizeContours( oDominantContoursList,
					a_rSpriteSettings.ScaleFactor,
					a_rSpriteSettings.PivotCoords,
					rTextureToPolygonize.width,
					rTextureToPolygonize.height );
				
			}
			break;

			case SpriteRenderMesh.Grid:
			{
				// Step 2
				// Triangulate the grid straight from binarized image
				Uni2DEditorUtilsBuildingProgressBar.AddProcessedSpriteBuildStep( );
				rMesh = Uni2DEditorPolygonTriangulationUtils.PolygonizeGrid( rBinarizedImage,
					a_rSpriteSettings.ScaleFactor,
					a_rSpriteSettings.PivotCoords,
					a_rSpriteSettings.renderMeshGridHorizontalSubDivs,
					a_rSpriteSettings.renderMeshGridVerticalSubDivs );
			}
			break;

			default:
			{
				return null;
			}
		}

		// Wrap up the mesh before delivering ;^)
		rMesh.name = "mesh_Sprite_" + rTextureToPolygonize.name;
		rMesh.RecalculateBounds( );
		rMesh.RecalculateNormals( );
		rMesh.Optimize( );

		return rMesh;
	}
	public static List<Uni2DMeshShape2D> PolygonizeTextureToBorder2DVerticesFromSettings( Uni2DEditorSpriteSettings a_rSpriteSettings )
	{
		if( a_rSpriteSettings.textureContainer == null || a_rSpriteSettings.physicsMode == Uni2DSprite.PhysicsMode.NoPhysics )
		{
			return new List<Uni2DMeshShape2D>();
		}
		
		// The texture to polygonize
		Texture2D rTextureToPolygonize = a_rSpriteSettings.textureContainer;
		
		// Polygonize holes?
		bool bPolygonizeHoles = a_rSpriteSettings.polygonizeHoles;
		
		// Step 1
		// Distinguish completely transparent pixels from significant pixel by "binarizing" the texture.
		Uni2DEditorUtilsBuildingProgressBar.AddProcessedSpriteBuildStep( );
		BinarizedImage rBinarizedImage = Uni2DEditorShapeExtractionUtils.BinarizeTexture( rTextureToPolygonize, a_rSpriteSettings.alphaCutOff );
		
		// Step 2
		// Build binarized outer/inner contours and label image regions
		List<Contour> oOuterContours;
		List<Contour> oInnerContours;
		
		Uni2DEditorUtilsBuildingProgressBar.AddProcessedSpriteBuildStep( );
		Uni2DEditorContourExtractionUtils.CombinedContourLabeling( rBinarizedImage, bPolygonizeHoles, out oOuterContours, out oInnerContours );
		
		
		// Step 3: vectorization (determine dominant points)
		if( a_rSpriteSettings.polygonizeHoles )
		{
			// Step 3a: if hole support asked by user, merge inner contours into outer contours first
			oOuterContours = Uni2DEditorContourPolygonizationUtils.MergeInnerAndOuterContours( oOuterContours, oInnerContours );
		}
		
		// Simplify contours
		Uni2DEditorUtilsBuildingProgressBar.AddProcessedSpriteBuildStep( );
		List<Contour> oSimplifiedContoursList = Uni2DEditorContourPolygonizationUtils.SimplifyContours( oOuterContours, a_rSpriteSettings.polygonizationAccuracy );
		
		List<Contour> oDominantContoursList;
		if(a_rSpriteSettings.subdivide)
		{
			// subdivide contours
			float fSubdivisionLength = Mathf.Max(rTextureToPolygonize.width, rTextureToPolygonize.height)/(a_rSpriteSettings.subdivisionCount + 1.0f);
			oDominantContoursList = Uni2DEditorContourPolygonizationUtils.SubdivideContours( oSimplifiedContoursList, fSubdivisionLength );
		}
		else
		{
			oDominantContoursList = oSimplifiedContoursList;
		}
		
		List<Uni2DMeshShape2D> oShapes =  Uni2DEditorPolygonTriangulationUtils.Get2DVerticesFromContours(	oDominantContoursList, 
																									a_rSpriteSettings.ScaleFactor,
		                                                                                          	a_rSpriteSettings.PivotCoords);
		
		return oShapes;
	}
	// NEW
	// Parse a 2D texture and make mesh colliders from edges
	public static List<Mesh> PolygonizeTextureToMeshColliderFromSettings( Uni2DEditorSpriteSettings a_rSpriteSettings )
	{
		if( a_rSpriteSettings.textureContainer == null || a_rSpriteSettings.physicsMode == Uni2DSprite.PhysicsMode.NoPhysics )
		{
			return null;
		}
		// The texture to polygonize
		Texture2D rTextureToPolygonize = a_rSpriteSettings.textureContainer;

		// Polygonize holes?
		bool bPolygonizeHoles = ( a_rSpriteSettings.collisionType != Uni2DSprite.CollisionType.Convex && a_rSpriteSettings.polygonizeHoles );

		// Step 1
		// Distinguish completely transparent pixels from significant pixel by "binarizing" the texture.
		Uni2DEditorUtilsBuildingProgressBar.AddProcessedSpriteBuildStep( );
		BinarizedImage rBinarizedImage = Uni2DEditorShapeExtractionUtils.BinarizeTexture( rTextureToPolygonize, a_rSpriteSettings.alphaCutOff );
		
		// Step 2
		// Build binarized outer/inner contours and label image regions
		List<Contour> oOuterContours;
		List<Contour> oInnerContours;

		Uni2DEditorUtilsBuildingProgressBar.AddProcessedSpriteBuildStep( );
		Uni2DEditorContourExtractionUtils.CombinedContourLabeling( rBinarizedImage, bPolygonizeHoles, out oOuterContours, out oInnerContours );


		// Step 3: vectorization (determine dominant points)
		if( a_rSpriteSettings.polygonizeHoles )
		{
			// Step 3a: if hole support asked by user, merge inner contours into outer contours first
			oOuterContours = Uni2DEditorContourPolygonizationUtils.MergeInnerAndOuterContours( oOuterContours, oInnerContours );
		}

		// Simplify contours
		Uni2DEditorUtilsBuildingProgressBar.AddProcessedSpriteBuildStep( );
		List<Contour> oDominantContoursList = Uni2DEditorContourPolygonizationUtils.SimplifyContours( oOuterContours, a_rSpriteSettings.polygonizationAccuracy );

		// Step 4: triangulation
		List<Mesh> oMeshesList;

		Uni2DEditorUtilsBuildingProgressBar.AddProcessedSpriteBuildStep( );
		if( a_rSpriteSettings.collisionType == Uni2DSprite.CollisionType.Compound )
		{
			// Compound mesh
			oMeshesList = Uni2DEditorPolygonTriangulationUtils.CompoundPolygonizeAndExtrudeContours( oDominantContoursList,
				a_rSpriteSettings.extrusionDepth,
				a_rSpriteSettings.ScaleFactor,
				a_rSpriteSettings.PivotCoords );

			int iMeshIndex = 0;
            foreach( Mesh rMesh in oMeshesList )
            {
                rMesh.name = "mesh_Collider_" + rTextureToPolygonize.name + "_" + iMeshIndex;
                ++iMeshIndex;
            }
		}
		else
		{
			// Single mesh
			Mesh rMesh = Uni2DEditorPolygonTriangulationUtils.PolygonizeAndExtrudeContours( oDominantContoursList,
				a_rSpriteSettings.extrusionDepth,
				a_rSpriteSettings.ScaleFactor,
				a_rSpriteSettings.PivotCoords );

			rMesh.name = "mesh_Collider_" + rTextureToPolygonize.name;
			oMeshesList = new List<Mesh>( 1 );
			oMeshesList.Add( rMesh );
		}

		// Optimize meshes
		foreach( Mesh rMesh in oMeshesList )
		{
			rMesh.RecalculateBounds( );
			rMesh.RecalculateNormals( );
			rMesh.Optimize( );
		}

		return oMeshesList;
	}
	// Deep copy constructor
	public Uni2DEditorSpriteSettings( Uni2DEditorSpriteSettings a_rSpriteSettings )
	{
		this.textureContainer       = new Texture2DContainer( a_rSpriteSettings.textureContainer );	// Deep copy
		this.atlas                  = a_rSpriteSettings.atlas;
		this.sharedMaterial			= a_rSpriteSettings.sharedMaterial;
		
		this.renderMesh             = a_rSpriteSettings.renderMesh;
		this.usePhysicBuildSettings = a_rSpriteSettings.usePhysicBuildSettings;
		
		this.spriteScaleMode        = a_rSpriteSettings.spriteScaleMode;
		this.spriteScale            = a_rSpriteSettings.spriteScale;
		this.spriteScaleNotUniform  = a_rSpriteSettings.spriteScaleNotUniform;
		this.pivotType				= a_rSpriteSettings.pivotType;
		this.pivotCustomCoords		= a_rSpriteSettings.pivotCustomCoords;
		this.vertexColor            = a_rSpriteSettings.vertexColor;
		this.dimensionMode			= a_rSpriteSettings.dimensionMode;
		this.physicsMode            = a_rSpriteSettings.physicsMode;
		this.collisionType          = a_rSpriteSettings.collisionType;
		this.isKinematic            = a_rSpriteSettings.isKinematic;
		this.isTrigger				= a_rSpriteSettings.isTrigger;
	
		this.renderMeshAlphaCutOff            = a_rSpriteSettings.renderMeshAlphaCutOff;
		this.renderMeshPolygonizationAccuracy = a_rSpriteSettings.renderMeshPolygonizationAccuracy;
		this.renderMeshPolygonizeHoles = a_rSpriteSettings.renderMeshPolygonizeHoles;
	
		this.alphaCutOff            = a_rSpriteSettings.alphaCutOff;
		this.extrusionDepth         = a_rSpriteSettings.extrusionDepth;
		this.polygonizationAccuracy = a_rSpriteSettings.polygonizationAccuracy;
		this.polygonizeHoles        = a_rSpriteSettings.polygonizeHoles;
		
		this.onlyBorder = a_rSpriteSettings.onlyBorder;
		this.subdivide = a_rSpriteSettings.subdivide;
		this.subdivisionCount = a_rSpriteSettings.subdivisionCount;

		this.renderMeshGridHorizontalSubDivs = a_rSpriteSettings.renderMeshGridHorizontalSubDivs;
		this.renderMeshGridVerticalSubDivs   = a_rSpriteSettings.renderMeshGridVerticalSubDivs;

		this.skinQuality          = a_rSpriteSettings.skinQuality;
		this.boneInfluenceFalloff = a_rSpriteSettings.boneInfluenceFalloff;
	}
Esempio n. 25
0
    public void Rebuild( )
    {
        //Debug.Log( "Rebuilding Uni2D Asset Table..." );

        m_oAtlasGUIDSpritePrefabGUIDsMultiDict.Clear( );
        m_oTextureGUIDAtlasGUIDsMultiDict.Clear( );
        m_oTextureGUIDClipGUIDsMultiDict.Clear( );
        m_oTextureGUIDSpritePrefabGUIDsMultiDict.Clear( );

        m_oAtlasPathGUIDDict.Clear( );
        m_oClipPathGUIDDict.Clear( );

        // Iterate project's assets
        string[] rAssetPaths = AssetDatabase.GetAllAssetPaths( );

        int   iAssetCount      = rAssetPaths.Length;
        float fInvAssetCount   = 1.0f / (float)iAssetCount;
        int   iProcessedAssets = 0;

        try
        {
            foreach (string rPath in rAssetPaths)
            {
                EditorUtility.DisplayProgressBar("Uni2D - Asset Table Rebuilding Progress",
                                                 iProcessedAssets + " out of " + iAssetCount + " asset(s) processed...",
                                                 fInvAssetCount * iProcessedAssets);

                Object rAssetObject = null;

                // Might be an atlas or a clip
                if (rPath.EndsWith(".prefab"))
                {
                    rAssetObject = AssetDatabase.LoadAssetAtPath(rPath, typeof(Uni2DTextureAtlas));
                    if (rAssetObject != null)                           // It's an atlas
                    {
                        Uni2DTextureAtlas rAtlasAsset = (Uni2DTextureAtlas)rAssetObject;
                        string            rAtlasGUID  = AssetDatabase.AssetPathToGUID(rPath);

                        foreach (string rTextureGUID in rAtlasAsset.GetTextureGUIDs( ))
                        {
                            this.AddAtlasUsingTexture(rAtlasGUID, rTextureGUID);
                        }

                        m_oAtlasPathGUIDDict.Add(rPath, rAtlasGUID);

                        rAtlasAsset = null;
                        EditorUtility.UnloadUnusedAssets( );
                    }

                    rAssetObject = AssetDatabase.LoadAssetAtPath(rPath, typeof(Uni2DAnimationClip));
                    if (rAssetObject != null)                           // It's an animation clip
                    {
                        Uni2DAnimationClip rAnimationClipAsset = (Uni2DAnimationClip)rAssetObject;
                        string             rAnimationClipGUID  = AssetDatabase.AssetPathToGUID(rPath);

                        foreach (string rTextureGUID in rAnimationClipAsset.GetAllFramesTextureGUIDs( ))
                        {
                            this.AddClipUsingTexture(rAnimationClipGUID, rTextureGUID);
                        }

                        m_oClipPathGUIDDict.Add(rPath, rAnimationClipGUID);

                        rAnimationClipAsset = null;
                        EditorUtility.UnloadUnusedAssets( );
                    }

                    rAssetObject = AssetDatabase.LoadAssetAtPath(rPath, typeof(GameObject));
                    if (rAssetObject != null)                           // It's a sprite prefab
                    {
                        GameObject    rPrefabAsset            = (GameObject)rAssetObject;
                        string        rPrefabGUID             = AssetDatabase.AssetPathToGUID(rPath);
                        Uni2DSprite[] rSpritePrefabComponents = rPrefabAsset.GetComponentsInChildren <Uni2DSprite>(true);

                        foreach (Uni2DSprite rSpritePrefabComponent in rSpritePrefabComponents)
                        {
                            Uni2DEditorSpriteSettings rSpriteSettings = rSpritePrefabComponent.SpriteSettings;

                            this.AddSpritePrefabUsingTexture(rPrefabGUID, rSpriteSettings.textureContainer.GUID);

                            if (rSpriteSettings.atlas != null)
                            {
                                this.AddSpritePrefabUsingAtlas(rPrefabGUID, Uni2DEditorUtils.GetUnityAssetGUID(rSpriteSettings.atlas));
                            }
                        }

                        rPrefabAsset            = null;
                        rSpritePrefabComponents = null;
                        EditorUtility.UnloadUnusedAssets( );
                    }
                }

                ++iProcessedAssets;
            }
        }
        finally
        {
            this.Save( );

            EditorUtility.UnloadUnusedAssets( );

            EditorUtility.SetDirty(this);
            EditorUtility.ClearProgressBar( );
        }

        //Debug.Log( "Uni2D Asset Table Rebuild: Done." );
    }
	// Setup rigidbody 2d
	private static void SetupRigidbodyFor2D( Uni2DSprite a_rSprite, Uni2DEditorSpriteSettings a_rNewSettings = null )
	{
		Uni2DEditorSpriteSettings rCurrentSettings = a_rNewSettings == null ? a_rSprite.SpriteSettings : a_rNewSettings;
		switch(rCurrentSettings.dimensionMode)
		{
			case DimensionMode._3D:
			{
				#if AFTER_UNITY_4_3
				// Destroy 2d rigidbody
				Rigidbody2D rSpriteRigidbody2D = a_rSprite.GetComponent<Rigidbody2D>();
				if( rSpriteRigidbody2D != null )
				{
					MonoBehaviour.DestroyImmediate(rSpriteRigidbody2D);
				}
				#endif
				
				Rigidbody rSpriteRigidbody = a_rSprite.GetComponent<Rigidbody>( );
		
				// Setup the rigidbody
				if( rCurrentSettings.physicsMode == Uni2DSprite.PhysicsMode.Dynamic )
				{
					// Add the rigidbody component
					if( rSpriteRigidbody == null )
					{
						rSpriteRigidbody = a_rSprite.gameObject.AddComponent<Rigidbody>( );
					}
		
					rSpriteRigidbody.constraints = RigidbodyConstraints.FreezePositionZ | RigidbodyConstraints.FreezeRotationX | RigidbodyConstraints.FreezeRotationY;
					rSpriteRigidbody.isKinematic = rCurrentSettings.isKinematic;
				}
				else if( rSpriteRigidbody != null ) // a rigidbody is not needed in the other modes
				{
					MonoBehaviour.DestroyImmediate( rSpriteRigidbody );
				}
			}
			break;
			
			case DimensionMode._2D:
			{
				// Destroy 3d rigidbody
				Rigidbody rSpriteRigidbody = a_rSprite.GetComponent<Rigidbody>();
				if( rSpriteRigidbody != null ) // a rigidbody is not needed in the other modes
				{
					MonoBehaviour.DestroyImmediate(rSpriteRigidbody);
				}
				
				#if AFTER_UNITY_4_3
				Rigidbody2D rSpriteRigidbody2D = a_rSprite.GetComponent<Rigidbody2D>( );
				
				// Setup the rigidbody
				if( rCurrentSettings.physicsMode == Uni2DSprite.PhysicsMode.Dynamic )
				{
					// Add the rigidbody component
					if( rSpriteRigidbody2D == null )
					{
						rSpriteRigidbody2D = a_rSprite.gameObject.AddComponent<Rigidbody2D>( );
					}
					
					rSpriteRigidbody2D.isKinematic = rCurrentSettings.isKinematic;
				}
				else if( rSpriteRigidbody2D != null ) // a rigidbody is not needed in the other modes
				{
					MonoBehaviour.DestroyImmediate( rSpriteRigidbody2D );
				}
				#endif
			}
			break;
		}
	}