Example #1
0
	// Update material and texture
	private static void UpdateMaterialForAnim(Uni2DSprite a_rSpriteComponent, Texture2DContainer a_rTextureContainer, Uni2DTextureAtlas a_rTextureAtlas)
	{
		Material oSpriteMaterial = a_rSpriteComponent.SpriteData.renderMeshMaterial;

		if(a_rTextureAtlas == null)
		{
			Material rAnimationMaterial = a_rSpriteComponent.RuntimeData.animationMaterial;

			if( rAnimationMaterial != null )
			{
				oSpriteMaterial = rAnimationMaterial;
			}
			else
			{
				// Instantiate the material to prevent other sprites using this material
				// to be animated too
				oSpriteMaterial = (Material) Material.Instantiate( oSpriteMaterial );
				a_rSpriteComponent.RuntimeData.animationMaterial = oSpriteMaterial;
			}

			oSpriteMaterial.mainTexture = a_rTextureContainer;
		}
		else
		{
			oSpriteMaterial = a_rTextureAtlas.GetMaterial( a_rTextureContainer.GUID );
		}
		
		Renderer rRenderer = a_rSpriteComponent.GetComponent<Renderer>();
		if(rRenderer != null)
		{
			rRenderer.sharedMaterial = oSpriteMaterial;
			rRenderer.material = oSpriteMaterial;
		}
	}
    public bool ApplySettings(Uni2DSprite a_rSpriteMesh)
    {
        if(spriteTexture != null)
        {
            settingsChanged = false;

            GameObject rSpriteMeshGameObject = a_rSpriteMesh.gameObject;

            Uni2DEditorUtilsSpriteBuilder.UpdateSpriteFromTexture(
                rSpriteMeshGameObject,
                spriteTexture,
                textureAtlas,
                vertexColor,
                alphaCutOff,
                polygonizationAccuracy,
                extrusionDepth,
                spriteScale,
                polygonizeHoles,
                pivotPointCoords,
                pivotPointType,
                physicMode,
                collisionType,
                isKinematic);

            EditorUtility.SetDirty(a_rSpriteMesh);

            return true;
        }
        else
        {
            return false;
        }
    }
Example #3
0
	// Set sprite frame
	public static void SetSpriteFrame(Uni2DSprite a_rSpriteComponent, Texture2DContainer a_rTextureContainer, Uni2DTextureAtlas a_rTextureAtlas, float a_fWidth, float a_fHeight, bool a_bUpdateMesh, bool a_bUpdateUV)
	{
		MeshFilter rMeshFilter = a_rSpriteComponent.GetComponent<MeshFilter>( );
		SkinnedMeshRenderer rSkinnedMeshRenderer = a_rSpriteComponent.GetComponent<SkinnedMeshRenderer>( );

		// The mesh to update
		Mesh rSpriteMesh = a_rSpriteComponent.EditableRenderMesh;

		if( rSpriteMesh != null )
		{			
			if( a_bUpdateMesh )
			{
				rSpriteMesh = UpdateSpriteMeshSizeForAnim(a_rSpriteComponent, rSpriteMesh, a_fWidth, a_fHeight);
			}
	
			UpdateMaterialForAnim( a_rSpriteComponent, a_rTextureContainer, a_rTextureAtlas );
	
			if( a_bUpdateUV )
			{
				// Rebuild UVs
				rSpriteMesh.uv = BuildUVs( a_rTextureContainer,
					a_rSpriteComponent.SpriteData.renderMeshUVs,
					a_rTextureAtlas );
			}

			if( rSkinnedMeshRenderer != null && rSkinnedMeshRenderer.sharedMesh != rMeshFilter.sharedMesh )
			{
				rSkinnedMeshRenderer.sharedMesh = rSpriteMesh;
			}
		}
	}
    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;
    }
	// Save Mesh resources
	public static void DuplicateResources( Uni2DSprite a_rSprite, bool a_bPrefab = false)
	{
		// Sprite mesh
		Mesh rSpriteMesh = a_rSprite.SpriteData.renderMesh;

		if( rSpriteMesh != null )
		{
			Mesh rDuplicatedMesh = Uni2DEditorResourceCopyUtils.DuplicateMesh( rSpriteMesh );
			
			MeshFilter rMeshFilterComponent = a_rSprite.GetComponent<MeshFilter>( );
			SkinnedMeshRenderer rSkinnedMeshRendererComponent = a_rSprite.GetComponent<SkinnedMeshRenderer>( );

			// Apply the new generated mesh to the mesh filter component
			// and save it as generated data
			if( rMeshFilterComponent != null )
			{
				rMeshFilterComponent.sharedMesh = rDuplicatedMesh;
				a_rSprite.SpriteData.renderMesh = rDuplicatedMesh;
			}

			if( rSkinnedMeshRendererComponent != null )
			{
				rSkinnedMeshRendererComponent.sharedMesh = rDuplicatedMesh;
			}
		}
		
		// Duplicate the generated material
		if(a_rSprite.SpriteData.generatedMaterial != null)
		{
			// Duplicate generated mesh
			a_rSprite.SpriteData.generatedMaterial = new Material(a_rSprite.SpriteData.generatedMaterial);
			
			// Change the render mesh material ref to the duplicate
			a_rSprite.SpriteData.renderMeshMaterial = a_rSprite.SpriteData.generatedMaterial;
			
			// Update the renderer material
			a_rSprite.GetComponent<Renderer>().sharedMaterial = a_rSprite.SpriteData.generatedMaterial;
		}
		
		// Mesh collider(s)
		List<Mesh> rMeshCollidersList                  = a_rSprite.SpriteData.meshCollidersList;
		List<MeshCollider> rMeshColliderComponentsList = a_rSprite.SpriteData.meshColliderComponentsList;
		for( int iMeshIndex = 0, iMeshCount = rMeshCollidersList.Count; iMeshIndex < iMeshCount; ++iMeshIndex )
		{
			Mesh rDuplicatedMeshCollider = Uni2DEditorResourceCopyUtils.DuplicateMesh( rMeshCollidersList[ iMeshIndex ] );
			MeshCollider rMeshCollider = rMeshColliderComponentsList[ iMeshIndex ];

			if( rMeshCollider != null )
			{
				rMeshCollider.sharedMesh = rDuplicatedMeshCollider;
			}
			rMeshCollidersList[ iMeshIndex ] = rDuplicatedMeshCollider;
		}
		
		#if UNITY_EDITOR
		EditorUtility.SetDirty( a_rSprite );
		#endif
	}
    // Adds a bone to a sprite from a given mouse GUI position
    public static Uni2DSmoothBindingBone AddBoneToSprite( Uni2DSprite a_rSprite, Vector2 a_f2MouseGUIPos, Uni2DSmoothBindingBone a_rBoneRoot )
    {
        Transform rSpriteTransform = a_rSprite.transform;
        Ray oWorldRay = HandleUtility.GUIPointToWorldRay( a_f2MouseGUIPos );
        Plane oSpritePlane = new Plane( rSpriteTransform.forward, rSpriteTransform.position );	// INFO: normal specific to Uni2D's planes

        float fDistance;
        if( oSpritePlane.Raycast( oWorldRay, out fDistance ) )
        {
            Uni2DSmoothBindingBone oBone;

            if( a_rBoneRoot == null )
            {
                oBone = Uni2DEditorSmoothBindingUtils.CreateNewBone( a_rSprite );
            }
            else
            {
                switch( a_rBoneRoot.ChildCount )
                {
                    case 0:
                    {
                        // Add child
                        oBone = Uni2DEditorSmoothBindingUtils.CreateNewBone( a_rBoneRoot );
                    }
                    break;

                    case 1:
                    {
                        // Create branch for existing child + add another one
                        Uni2DSmoothBindingBone oFakeParent1 = Uni2DEditorSmoothBindingUtils.CreateNewBone( a_rBoneRoot, true );
                        Uni2DSmoothBindingBone oFakeParent2 = Uni2DEditorSmoothBindingUtils.CreateNewBone( a_rBoneRoot, true );

                        a_rBoneRoot.Children[ 0 ].Parent = oFakeParent1;
                        oBone = Uni2DEditorSmoothBindingUtils.CreateNewBone( oFakeParent2 );
                    }
                    break;

                    default:
                    {
                        // Add branch
                        Uni2DSmoothBindingBone oFakeParent = Uni2DEditorSmoothBindingUtils.CreateNewBone( a_rBoneRoot, true );
                        oBone = Uni2DEditorSmoothBindingUtils.CreateNewBone( oFakeParent );
                    }
                    break;
                }
            }

            oBone.transform.position = oWorldRay.GetPoint( fDistance );

            return oBone;
        }

        return null;
    }
Example #7
0
 // Use this for initialization
 void Start()
 {
     free = RigidbodyConstraints.FreezePositionZ | RigidbodyConstraints.FreezeRotationX | RigidbodyConstraints.FreezeRotationY;
     locked = RigidbodyConstraints.FreezePosition | RigidbodyConstraints.FreezeRotation;
     sprite = this.GetComponent<Uni2DSprite> ();
     linkColor = new Color32 (255, 255, 255, 255);
     freeColor = new Color32 (255, 255, 255, 128);
     IsLink = true;
     isLock = false;
     bodyT=this.GetComponent<SpringJoint> ().connectedBody.transform;
 }
    public void MoveBoneAlongSpritePlane(Vector2 a_f2MouseGUIPos, bool a_bMoveChildren = true)
    {
        Uni2DSprite rSprite = this.Sprite;

        if (rSprite != null)
        {
            Transform rSpriteTransform = rSprite.transform;
            Ray       oWorldRay        = HandleUtility.GUIPointToWorldRay(a_f2MouseGUIPos);
            Plane     oSpritePlane     = new Plane(rSpriteTransform.forward, rSpriteTransform.position);

            float fDistance;
            if (oSpritePlane.Raycast(oWorldRay, out fDistance))
            {
                Vector3 f3Delta = oWorldRay.GetPoint(fDistance) - this.transform.position;
                this.transform.position += f3Delta;
                EditorUtility.SetDirty(this);

                if (a_bMoveChildren == false)
                {
                    foreach (Uni2DSmoothBindingBone rBoneChild in this.Children)
                    {
                        if (rBoneChild.IsFakeRootBone == false)
                        {
                            rBoneChild.transform.position -= f3Delta;
                        }
                        else
                        {
                            foreach (Uni2DSmoothBindingBone rFakeBoneChild in rBoneChild.Children)
                            {
                                rFakeBoneChild.transform.position -= f3Delta;
                                EditorUtility.SetDirty(rFakeBoneChild.transform);
                            }
                        }

                        EditorUtility.SetDirty(rBoneChild.transform);
                    }
                }
            }
        }
    }
    ///// Picking /////
    private static Uni2DSmoothBindingBone PickNearestBone( Uni2DSprite a_rSprite,
		Vector2 a_f2MouseGUIPos,
		out BoneHandle a_ePickedHandle,
		Uni2DSmoothBindingBone a_rExclude = null,
		bool a_bAlsoPickBoneLink    = false,
		float a_fBonePickRadius     = Uni2DEditorSmoothBindingUtils.bonePosingPickRadius,
		float a_fBoneLinkPickRadius = Uni2DEditorSmoothBindingUtils.boneLinkAnimPickRadius )
    {
        Uni2DSmoothBindingBone rNearestBone     = null;
        Uni2DSmoothBindingBone rNearestBoneLink = null;

        // Squarred pick radius
        float fMinSqrBoneDistance  = a_fBonePickRadius * a_fBonePickRadius;
        float fMinBoneLinkDistance = a_fBoneLinkPickRadius;

        Uni2DSmoothBindingBone[ ] rBones = a_rSprite.Bones; //rSpriteTransform.GetComponentsInChildren<Transform>( false ).Except( oBonesToExclude ).ToArray( );

        // Look for nearest bone
        for( int iBoneIndex = 0, iBoneCount = rBones.Length; iBoneIndex < iBoneCount; ++iBoneIndex )
        {
            Uni2DSmoothBindingBone rBone = rBones[ iBoneIndex ];

            if( a_rExclude != rBone && rBone.IsFakeRootBone == false )
            {
                Vector2 f2BoneGUIPos = HandleUtility.WorldToGUIPoint( rBone.transform.position );
                Vector2 f2BoneToMouseGUI = a_f2MouseGUIPos - f2BoneGUIPos;

                float fSqrDistance = f2BoneToMouseGUI.sqrMagnitude;

                // New min/nearest
                if( fSqrDistance < fMinSqrBoneDistance )
                {
                    rNearestBone = rBone;
                    fMinSqrBoneDistance = fSqrDistance;
                }

                // Look for nearest bone link
                Uni2DSmoothBindingBone rBoneParent = rBone.Parent;
                if( a_bAlsoPickBoneLink && rBoneParent != null )
                {
                    float fLinkDistance = HandleUtility.DistancePointToLineSegment( a_f2MouseGUIPos,
                        f2BoneGUIPos,
                        HandleUtility.WorldToGUIPoint( rBoneParent.transform.position ) );

                    if( fLinkDistance < fMinBoneLinkDistance )
                    {
                        fMinBoneLinkDistance = fLinkDistance;
                        rNearestBoneLink = rBone;
                    }
                }
            }
        }

        // Picking result
        if( rNearestBone == null && rNearestBoneLink == null )
        {
            a_ePickedHandle = BoneHandle.None;
        }
        else if( rNearestBone != null )
        {
            if( fMinSqrBoneDistance <= a_fBonePickRadius * a_fBonePickRadius * 0.25f )
            {
                a_ePickedHandle = /*invertActionAreas == false ?*/ BoneHandle.InnerDisc; //: BoneHandle.OuterDisc;
            }
            else
            {
                a_ePickedHandle = /*invertActionAreas == false ?*/ BoneHandle.OuterDisc; //: BoneHandle.InnerDisc;
            }
        }
        else
        {
            rNearestBone    = rNearestBoneLink;
            a_ePickedHandle = BoneHandle.Link;
        }

        return rNearestBone;
    }
	// Update a sprite in resource 
	public static void UpdateSpriteInResourceInABatch(Uni2DSprite a_rSprite)
	{
		ms_bUndoEnabled = false;
		
		//Uni2DSprite.prefabUpdateInProgress = true;
		GameObject rPrefab = PrefabUtility.FindPrefabRoot(a_rSprite.gameObject);
			
		// Instantiate the prefab
		GameObject rPrefabInstance = InstantiateSpritePrefabWithoutConnection(rPrefab);
		Uni2DSprite[] oSpritesPrefabInstance = rPrefabInstance.GetComponentsInChildren<Uni2DSprite>();
		
		// Retrieve the instance of the sprite
		Uni2DSprite rSpriteInstance = null;
		foreach(Uni2DSprite rSpritePrefabInstance in oSpritesPrefabInstance)
		{
			if(PrefabUtility.GetPrefabParent(rSpritePrefabInstance) == a_rSprite)
			{
				rSpriteInstance = rSpritePrefabInstance;
			}
		}
		
		if(rSpriteInstance != null)
		{
			// Rebuild the sprite
			rSpriteInstance.RebuildInABatch();
			
			// Replace prefab
			ReplaceSpritePrefab(rPrefabInstance, rPrefab);
		}
			
		// Clear the prefab instance
		Editor.DestroyImmediate(rPrefabInstance);
		//Uni2DSprite.prefabUpdateInProgress = false;
		
		AssetDatabase.SaveAssets( );
		AssetDatabase.Refresh( );
		
		ms_bUndoEnabled = true;
	}
    public static void DeleteBone( Uni2DSprite a_rSprite, Uni2DSmoothBindingBone a_rBoneToDelete )
    {
        if( a_rBoneToDelete != null )
        {
            Uni2DSmoothBindingBone rBoneParent = a_rBoneToDelete.Parent;

            // Need to pack bone hierarchy
            if( rBoneParent != null && rBoneParent.IsFakeRootBone )
            {
                Uni2DSmoothBindingBone rBoneGrandParent = rBoneParent.Parent;

                Object.DestroyImmediate( rBoneParent.gameObject );

                // We broke the branch => flatten bone hierarchy
                if( rBoneGrandParent != null && rBoneGrandParent.IsBranchBone == false )
                {
                    Uni2DSmoothBindingBone rFakeParent = rBoneGrandParent.Children[ 0 ];
                    rFakeParent.Children[ 0 ].Parent = rBoneGrandParent;

                    Object.DestroyImmediate( rFakeParent.gameObject );
                }
            }
            else
            {
                Object.DestroyImmediate( a_rBoneToDelete.gameObject );
            }
        }
    }
    // Specialized picking call used in posing mode
    public static Uni2DSmoothBindingBone PickNearestBoneInPosingMode( Uni2DSprite a_rSprite,
		Vector2 a_f2MouseGUIPos,
		out BoneHandle a_ePickedHandle,
		Uni2DSmoothBindingBone a_rExclude = null )
    {
        return Uni2DEditorSmoothBindingUtils.PickNearestBone( a_rSprite,
            a_f2MouseGUIPos,
            out a_ePickedHandle,
            a_rExclude,
            true,
            Uni2DEditorSmoothBindingUtils.bonePosingPickRadius,
            Uni2DEditorSmoothBindingUtils.boneLinkPosingPickRadius );
    }
	// 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;
	}
	// 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 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;
	}
 // Save inspector
 public void SaveInspectorInitParameter(Uni2DSprite a_rSpriteMesh)
 {
     // Parameters
     m_rSpriteTextureInit = a_rSpriteMesh.spriteTexture;
     m_rTextureAtlasInit = a_rSpriteMesh.textureAtlas;
     m_oVertexColorInit = a_rSpriteMesh.VertexColor;
     m_ePhysicModeInit = a_rSpriteMesh.physicMode;
     m_eCollisionTypeInit = a_rSpriteMesh.collisionType;
     m_bIsKinematicInit = a_rSpriteMesh.isKinematic;
     m_fSpriteScaleInit = a_rSpriteMesh.spriteScale;
     m_ePivotPointTypeInit = a_rSpriteMesh.pivotPointType;
     m_f2PivotPointCoordsInit = a_rSpriteMesh.pivotPointCoords;
     m_fAlphaCutOffInit = a_rSpriteMesh.alphaCutOff;
     m_fPolygonizationAccuracyInit = a_rSpriteMesh.polygonizationAccuracy;
     m_bPolygonizeHolesInit = a_rSpriteMesh.polygonizeHoles;
     m_fExtrusionDepthInit = a_rSpriteMesh.extrusionDepth;
 }
    // Get help message
    private string GetHelpMessage(Uni2DSprite.PhysicMode a_ePhysicMode, Uni2DSprite.CollisionType a_eCollisionType)
    {
        string oHelpMessage = "";
        if(a_ePhysicMode == Uni2DSprite.PhysicMode.NoPhysic)
        {
            oHelpMessage = "In no physic mode, there is no collider attached to the sprite.";
        }
        else if(a_ePhysicMode == Uni2DSprite.PhysicMode.Static)
        {
            if(a_eCollisionType == Uni2DSprite.CollisionType.Convex)
            {
                oHelpMessage = "In static convex mode, the mesh collider does not respond to collisions (e.g. not a rigidbody) as a convex mesh.\n" +
                        "Unity computes a convex hull if the mesh collider is not convex.";
            }
            else if(a_eCollisionType == Uni2DSprite.CollisionType.Concave)
            {
                oHelpMessage = "In static concave mode, mesh collider does not respond to collisions (e.g. not a rigidbody) as a concave mesh.\n" +
                        "A mesh collider marked as concave only interacts with primitive colliders (boxes, spheres...) and convex meshes.";
            }
            else if(a_eCollisionType == Uni2DSprite.CollisionType.Compound)
            {
                oHelpMessage = "In static compound mode, mesh collider does not respond to collisions (e.g. not a rigidbody) as a concave mesh composed of small convex meshes.\n" +
                        "It allows the collider to block any other collider at the expense of performances.";
            }
        }
        else if(a_ePhysicMode == Uni2DSprite.PhysicMode.Dynamic)
        {
            if(a_eCollisionType == Uni2DSprite.CollisionType.Convex)
            {
                oHelpMessage = "In dynamic convex mode, mesh collider does respond to collisions (e.g. rigidbody) as a convex mesh.\n" +
                        "Unity computes a convex hull if the mesh collider is not convex.";
            }
            else if(a_eCollisionType == Uni2DSprite.CollisionType.Concave)
            {
                oHelpMessage = "In dynamic concave mode, mesh collider does respond to collisions (e.g. rigidbody) as a concave mesh.\n" +
                        "A mesh collider marked as concave only interacts with primitive colliders (boxes, spheres...).";
            }
            else if(a_eCollisionType == Uni2DSprite.CollisionType.Compound)
            {
                oHelpMessage = "In dynamic compound mode, mesh collider does respond to collisions (e.g. rigidbody) as a concave mesh composed of small convex meshes.\n" +
                        "It allows the collider to interact with any other collider at the expense of performances.";
            }
        }

        return oHelpMessage;
    }
Example #18
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;
	}
	////////////////////////////////////////////////////////////////////////////////

	public static void RegenerateInteractiveDataFromSettings( Uni2DSprite a_rSprite )
	{
		// New sprite settings
		Uni2DEditorSpriteSettings rSpriteSettings = a_rSprite.SpriteSettings;

		// Current sprite data
		Uni2DEditorSpriteData rSpriteData = a_rSprite.SpriteData;
		
		
		if(rSpriteSettings.ShouldUseAtlas())
		{
			// If using the atlas remove the shared material
			rSpriteSettings.sharedMaterial = null;
		}
		else if(rSpriteSettings.sharedMaterial != null)
		{
			// If the shared material is in use
			// Ensure the sprite texture is the shared material texture
			
			Texture rSharedMaterialTexture = rSpriteSettings.sharedMaterial.mainTexture; 
			if(rSharedMaterialTexture != null)
			{
				rSpriteSettings.textureContainer = new Texture2DContainer( (Texture2D)rSharedMaterialTexture, false );
			}
			else
			{
				rSpriteSettings.sharedMaterial.mainTexture = rSpriteSettings.textureContainer;
			}
		}
		
		Texture2DContainer rSpriteTextureContainer = rSpriteSettings.textureContainer;
		Texture2D rSpriteTexture = rSpriteTextureContainer;
		
		a_rSprite.RestorePosePosition( );
		// If texture changed...
		if( a_rSprite.m_oTextureImportGUID != Uni2DEditorUtils.GetTextureImportGUID( rSpriteTexture ) )
		{
			string oTexturePath = AssetDatabase.GetAssetPath( rSpriteTexture );
			TextureImporter rTextureImporter = TextureImporter.GetAtPath(oTexturePath) as TextureImporter;

			if(rTextureImporter != null)
			{
				// Regenerate sprite mat & mesh
				TextureImporterSettings oTextureImporterSettings = Uni2DEditorSpriteBuilderUtils.TextureProcessingBegin(rTextureImporter);
				Uni2DEditorSpriteBuilderUtils.GenerateSpriteMatFromSettings( rSpriteSettings, a_rSprite );
				Uni2DEditorSpriteBuilderUtils.GenerateSpriteMeshFromSettings( rSpriteSettings, a_rSprite );

				// Don't forget to update texture import ID
				a_rSprite.AfterBuild();
				Uni2DEditorSpriteBuilderUtils.TextureProcessingEnd( rTextureImporter, oTextureImporterSettings );
			}
		}
		else
		{
			Uni2DEditorSpriteBuilderUtils.GenerateSpriteMatFromSettings( rSpriteSettings, a_rSprite );
			
			float fRealScale           = rSpriteSettings.ScaleFactor;

			// Current pivot point
			Vector2 f2CurrentPivotPoint = rSpriteData.pivotCoords;
			Vector2 f2NewPivotCoords    = Uni2DSpriteUtils.ComputePivotCoords( rSpriteData.spriteWidth, rSpriteData.spriteHeight, rSpriteSettings.pivotType, rSpriteSettings.pivotCustomCoords );
		
			// The delta to apply
			float fScalingDelta        = fRealScale / rSpriteData.scale;
			Vector3 f3ScaledDeltaPivot = ( f2NewPivotCoords - f2CurrentPivotPoint ) * fRealScale;
	
			// Rigidbody settings (kinematic, constraints...)
			Uni2DEditorSpriteBuilderUtils.SetupRigidbodyFor2D( a_rSprite );
	
			// Apply delta to mesh colliders
			for( int iMeshIndex = 0, iMeshCount = rSpriteData.meshCollidersList.Count; iMeshIndex < iMeshCount; ++iMeshIndex )
			{
				Mesh rMesh = rSpriteData.meshCollidersList[ iMeshIndex ];
	
				Vector3[ ] oMeshVerticesArray = rMesh.vertices;
	
				for( int iVertexIndex = 0, iVertexCount = rMesh.vertexCount; iVertexIndex < iVertexCount; ++iVertexIndex )
				{
					Vector3 f3Vertex = oMeshVerticesArray[ iVertexIndex ];
	
					f3Vertex   -= f3ScaledDeltaPivot;
					f3Vertex.x *= fScalingDelta;
					f3Vertex.y *= fScalingDelta;
					f3Vertex.z  = Mathf.Sign( f3Vertex.z ) * rSpriteSettings.extrusionDepth * 0.5f;
	
					oMeshVerticesArray[ iVertexIndex ] = f3Vertex;
				}
	
				// Must set array again ("vertices" getter gives a copy)
				rMesh.vertices = oMeshVerticesArray;

				// Force mesh collider update by setting it null then reassigning it
				MeshCollider rMeshCollider = rSpriteData.meshColliderComponentsList[ iMeshIndex ];
				rMeshCollider.sharedMesh   = null;
				rMeshCollider.sharedMesh   = rMesh;
			}
	
			// Apply delta to sprite mesh
			Mesh rSpriteMesh = rSpriteData.renderMesh;
			Vector3[ ] oSpriteQuadMeshVerticesArray = rSpriteMesh.vertices;
	
			for( int iVertexIndex = 0, iVertexCount = rSpriteMesh.vertexCount; iVertexIndex < iVertexCount; ++iVertexIndex )
			{
				Vector3 f3Vertex = oSpriteQuadMeshVerticesArray[ iVertexIndex ];
	
				f3Vertex   -= f3ScaledDeltaPivot;
				f3Vertex.x *= fScalingDelta;
				f3Vertex.y *= fScalingDelta;
	
				oSpriteQuadMeshVerticesArray[ iVertexIndex ] = f3Vertex;
			}

			// Must set array again ("vertices" getter gives a copy)
			rSpriteMesh.vertices = oSpriteQuadMeshVerticesArray;

			// Recalc mesh bounds
			rSpriteMesh.RecalculateBounds( );
	
			// Update vertex color
			Uni2DSpriteUtils.UpdateMeshVertexColor( rSpriteMesh, rSpriteSettings.vertexColor );
	
			// Update UV
			// Check first the atlas is still valid
			Uni2DTextureAtlas rTextureAtlas = rSpriteSettings.atlas;
			Material rSpriteMaterial;
			if( rSpriteSettings.ShouldUseAtlas( ) )
			{
				// Update atlas generation ID
				a_rSprite.atlasGenerationID = rTextureAtlas.generationId;
				rSpriteMaterial = rTextureAtlas.GetMaterial( rSpriteTextureContainer.GUID );
			}
			else
			{
				a_rSprite.atlasGenerationID = "";
				rSpriteSettings.atlas = null;
				rTextureAtlas = null;
				rSpriteMaterial = rSpriteData.renderMeshMaterial;
			}

			// .. and rebuild UVs
			rSpriteMesh.uv = Uni2DSpriteUtils.BuildUVs( rSpriteTextureContainer, rSpriteData.renderMeshUVs, rTextureAtlas );

			// Update material
			Renderer rRenderer = a_rSprite.renderer;
			if( rRenderer != null )
			{
				rRenderer.sharedMaterial = rSpriteMaterial;
			}
			
			// If the pivot point has changed
			if( f2CurrentPivotPoint != f2NewPivotCoords )
			{
				// Compute the local position change
                Vector3 f3LocalPivotMovement = f3ScaledDeltaPivot;
				Vector3 f3PivotMovement      = f3ScaledDeltaPivot;
                
                Vector3 f3SpriteTransformLocalScale = a_rSprite.transform.localScale;
    
                f3PivotMovement.Scale( f3SpriteTransformLocalScale );
                f3PivotMovement = a_rSprite.transform.TransformDirection( f3PivotMovement );
                
                Transform rParentTransform = a_rSprite.transform.parent;
                if(rParentTransform != null)
                {
                    f3PivotMovement = rParentTransform.InverseTransformDirection(f3PivotMovement);
                }
                
                a_rSprite.transform.localPosition += f3PivotMovement;

                // Update bone roots local pos (if any)
                /*a_rSprite.RestorePosePosition( );
                foreach( Uni2DSmoothBindingBone rBone in a_rSprite.Bones )
                {
                    if( rBone.Parent == null )
                    {
                        Vector3 f3BonePivotMovement = rBone.transform.InverseTransformDirection( f3PivotMovement );
                        rBone.transform.localPosition -= f3BonePivotMovement;
                    }
                }*/
                
				Transform rMeshCollidersRootTransform = rSpriteData.meshCollidersRootGameObject != null
					? rSpriteData.meshCollidersRootGameObject.transform 
					: null;

                foreach(Transform rChild in a_rSprite.transform)
                {
					if( rChild != rMeshCollidersRootTransform )
					{
	                    rChild.localPosition -= f3LocalPivotMovement;
					}
				}
			}
			
			a_rSprite.UpdatePosing( );

			// Save new pivot coords
			rSpriteData.pivotCoords = f2NewPivotCoords;
			rSpriteData.scale       = rSpriteSettings.ScaleFactor;
		}
	}
	// NEW
	// Removes the generated physic colliders attached to a sprite
	private static void RemoveGeneratedColliders( Uni2DSprite a_rSpriteToClean )
	{
		if( a_rSpriteToClean != null )
		{
			// Retrieve the generated data of the sprite to clean
			Uni2DEditorSpriteData rSpriteData = a_rSpriteToClean.SpriteData;

			// Delete resources
			// Delete game objects in excess
			foreach( MeshCollider rMeshColliderComponent in rSpriteData.meshColliderComponentsList )
			{
				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 );
					}
					else
					{
						// Destroy component
						MonoBehaviour.DestroyImmediate( rMeshColliderComponent );
					}
				}
			}

			// Destroy mesh collider root game object (if any)
			if( rSpriteData.meshCollidersRootGameObject != null )
			{
				// Destroy game object
				GameObject.DestroyImmediate( rSpriteData.meshCollidersRootGameObject );
			}

			// Delete components in excess
			Rigidbody rRigidbodyComponent = a_rSpriteToClean.GetComponent<Rigidbody>( );
			if( rRigidbodyComponent != null )
			{
				// Destroy component
				MonoBehaviour.DestroyImmediate( rRigidbodyComponent );
			}

			// Reset mesh list
			rSpriteData.meshCollidersList          = null;
			rSpriteData.meshColliderComponentsList = null;
			rSpriteData.colliderTriangleCount      = 0;
		}
	}
	// 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;
	}
    // On sprite reset
    public void OnSpriteReset(Uni2DSprite a_rSpriteMesh)
    {
        if(ms_bInspectorHasBeenInit)
        {
            // Cancel Reset

            // Parameters
            RestoreInspectorInitParameter(a_rSpriteMesh);

            // Data
            a_rSpriteMesh.spriteTextureWidth = spriteTextureWidth;
            a_rSpriteMesh.spriteTextureHeight = spriteTextureHeight;
            a_rSpriteMesh.spriteQuadMesh = spriteQuadMesh;
            a_rSpriteMesh.spriteQuadMaterial = spriteQuadMaterial;
            a_rSpriteMesh.meshCollidersList.Clear();
            a_rSpriteMesh.meshCollidersList.AddRange(meshCollidersList);
            a_rSpriteMesh.meshCollidersRootGameObject = meshCollidersRootGameObject;
            a_rSpriteMesh.meshColliderComponentsList.Clear();
            a_rSpriteMesh.meshColliderComponentsList.AddRange(meshColliderComponentsList);

            // Reset the temporary values
            Uni2DEditorSpriteBuilderWindow.ResetSpriteParameters(	ref vertexColor,
                                                                    ref alphaCutOff,
                                                                    ref polygonizationAccuracy,
                                                                    ref extrusionDepth,
                                                                    ref spriteScale,
                                                                    ref polygonizeHoles,
                                                                    ref pivotPointCoords,
                                                                    ref pivotPointType,
                                                                    ref physicMode,
                                                                    ref collisionType,
                                                                    ref isKinematic);

            settingsChanged = false;

            ApplySettings(a_rSpriteMesh);
        }
    }
    // On init inspector
    public void OnInitInspector(Uni2DSprite a_rSpriteMesh)
    {
        SaveInspectorInitParameter(a_rSpriteMesh);

        // Parameters
        spriteTexture = a_rSpriteMesh.spriteTexture;
        textureAtlas = a_rSpriteMesh.textureAtlas;
        vertexColor = a_rSpriteMesh.VertexColor;
        physicMode = a_rSpriteMesh.physicMode;
        collisionType = a_rSpriteMesh.collisionType;
        isKinematic = a_rSpriteMesh.isKinematic;
        spriteScale = a_rSpriteMesh.spriteScale;
        pivotPointType = a_rSpriteMesh.pivotPointType;
        pivotPointCoords = a_rSpriteMesh.pivotPointCoords;
        alphaCutOff = a_rSpriteMesh.alphaCutOff;
        polygonizationAccuracy = a_rSpriteMesh.polygonizationAccuracy;
        polygonizeHoles = a_rSpriteMesh.polygonizeHoles;
        extrusionDepth = a_rSpriteMesh.extrusionDepth;

        // Info
        colliderTriangleCount  = a_rSpriteMesh.GetColliderTriangleCount();

        // Data
        spriteTextureWidth = a_rSpriteMesh.spriteTextureWidth;
        spriteTextureHeight = a_rSpriteMesh.spriteTextureHeight;
        spriteQuadMesh = a_rSpriteMesh.spriteQuadMesh;
        spriteQuadMaterial = a_rSpriteMesh.spriteQuadMaterial;
        meshCollidersList.Clear();
        if(a_rSpriteMesh.meshCollidersList != null)
        {
            meshCollidersList.AddRange(a_rSpriteMesh.meshCollidersList);
        }
        meshCollidersRootGameObject = a_rSpriteMesh.meshCollidersRootGameObject;
        meshColliderComponentsList.Clear();
        if(a_rSpriteMesh.meshColliderComponentsList != null)
        {
            meshColliderComponentsList.AddRange(a_rSpriteMesh.meshColliderComponentsList);
        }

        ms_bInspectorHasBeenInit = true;
    }
 // Restore inspector
 public void RestoreInspectorInitParameter(Uni2DSprite a_rSpriteMesh)
 {
     // Parameters
     a_rSpriteMesh.spriteTexture = m_rSpriteTextureInit;
     a_rSpriteMesh.textureAtlas = m_rTextureAtlasInit;
     a_rSpriteMesh.VertexColor = m_oVertexColorInit;
     a_rSpriteMesh.physicMode = m_ePhysicModeInit;
     a_rSpriteMesh.collisionType = m_eCollisionTypeInit;
     a_rSpriteMesh.isKinematic = m_bIsKinematicInit;
     a_rSpriteMesh.spriteScale = m_fSpriteScaleInit;
     a_rSpriteMesh.pivotPointType = m_ePivotPointTypeInit;
     a_rSpriteMesh.pivotPointCoords = m_f2PivotPointCoordsInit;
     a_rSpriteMesh.alphaCutOff = m_fAlphaCutOffInit;
     a_rSpriteMesh.polygonizationAccuracy = m_fPolygonizationAccuracyInit;
     a_rSpriteMesh.polygonizeHoles = m_bPolygonizeHolesInit;
     a_rSpriteMesh.extrusionDepth = m_fExtrusionDepthInit;
 }
 public Uni2DEditorSmoothBindingGUI( Uni2DSprite a_rSprite )
 {
     this.Reset( a_rSprite );
 }
    // Reset a sprite
    public static void ResetSpriteParameters(	ref Color a_rVertexColor,
												ref float a_fAlphaCutOff,
												ref float a_fPoligonizationAccuracy,
												ref float a_fExtrusionDepth,
												ref float a_fScale,
												ref bool a_bPolygonizeHoles,
												ref Vector2 a_f2CustomPivotPoint,
												ref Uni2DSprite.PivotPointType a_ePivotPoint,
												ref Uni2DSprite.PhysicMode a_ePhysicMode,
												ref Uni2DSprite.CollisionType a_eCollisionType,
												ref bool a_bIsKinematic)
    {
        // Default sprite parameters
        a_rVertexColor = m_oVertexColorSprite;
        a_ePhysicMode = m_ePhysicModeSprite;
        a_eCollisionType = m_eCollisionTypeSprite;
        a_bIsKinematic = m_bIsKinematicSprite;
        a_fScale = m_fScaleSprite;
        a_ePivotPoint = m_ePivotPointSprite;
        a_f2CustomPivotPoint = m_f2CustomPivotPointSprite;

        // Default physic sprite parameters
        a_fAlphaCutOff = m_fAlphaCutOffPhysicSprite;
        a_fPoligonizationAccuracy = m_fPolygonizationAccuracyPhysicSprite;
        a_bPolygonizeHoles = m_bPolygonizeHolesPhysicSprite;
        a_fExtrusionDepth = m_fExtrusionDepthPhysicSprite;
    }
	// 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;
	}
    public void Reset( Uni2DSprite a_rSprite, bool a_bKeepCurrentModeIfPossible = false )
    {
        m_rLastAddedBone   = null;
        m_rBoneChainOrigin = null;
        Uni2DEditorSmoothBindingGUI.activeBone = null;

        m_f2MouseGUIOffset = Vector2.zero;
        ms_eEditorTool = BoneEditorTool.Select;

        BoneEditMode eSavedEditMode = Uni2DEditorSmoothBindingGUI.CurrentBoneEditMode;

        Uni2DEditorSmoothBindingGUI.CurrentBoneEditMode = BoneEditMode.None;

        ms_rSprite = a_rSprite;

        if( a_bKeepCurrentModeIfPossible )
        {
            Uni2DEditorSmoothBindingGUI.CurrentBoneEditMode = eSavedEditMode;
        }
    }
 public static Uni2DSmoothBindingBone CreateNewBone( Uni2DSprite a_rSprite )
 {
     return Uni2DEditorSmoothBindingUtils.CreateNewBone( a_rSprite.transform, false );
 }
	// Returns true if the Uni2DSprite data have been generated
	// for a given physic mode
	public bool AreDataGenerated( Uni2DSprite.PhysicsMode a_ePhysicMode )
	{
		return this.renderMesh     != null
			&& this.renderMeshMaterial != null
			&& ( a_ePhysicMode           == Uni2DSprite.PhysicsMode.NoPhysics	// No physic == no mesh collider to generate
				 || ( this.meshCollidersList                            != null
					&& this.meshCollidersList.Contains( null )          == false
					&& this.meshColliderComponentsList                  != null
					&& this.meshColliderComponentsList.Contains( null ) == false
					)
				);
	}
	public static void UpdateSpriteSize( Uni2DSprite a_rSprite, float a_fWidth, float a_fHeight )
	{
		Uni2DEditorSpriteSettings rSpriteSettings = a_rSprite.SpriteSettings;
		Uni2DEditorSpriteData rSpriteData         = a_rSprite.SpriteData;

		float fExtrusionDepth    = rSpriteSettings.extrusionDepth;
		Vector2 f2OldPivotCoords = rSpriteData.pivotCoords;
		
		// The delta to apply
		Vector2 f2ScalingDelta = new Vector2( a_fWidth / rSpriteData.spriteWidth, a_fHeight / rSpriteData.spriteHeight );
		
		// Apply to the pivot point
		Vector2 f2NewPivotCoords = Vector2.Scale( f2OldPivotCoords, f2ScalingDelta );
		
		// Apply delta to mesh colliders
		List<Mesh> rMeshCollidersList = rSpriteData.meshCollidersList;
		if( rMeshCollidersList != null)
		{
			for( int iMeshIndex = 0, iMeshCount = rMeshCollidersList.Count; iMeshIndex < iMeshCount; ++iMeshIndex )
			{
				Mesh rMesh = rMeshCollidersList[ iMeshIndex ];
				
				Vector3[ ] oMeshVerticesArray = rMesh.vertices;
				for( int iVertexIndex = 0, iVertexCount = rMesh.vertexCount; iVertexIndex < iVertexCount; ++iVertexIndex )
				{
					Vector3 f3Vertex = oMeshVerticesArray[ iVertexIndex ];
					f3Vertex.x *= f2ScalingDelta.x;
					f3Vertex.y *= f2ScalingDelta.y;
					//f3Vertex -= f3ScaledDeltaPivot;
					f3Vertex.z = Mathf.Sign( f3Vertex.z ) * fExtrusionDepth * 0.5f;
					oMeshVerticesArray[ iVertexIndex ] = f3Vertex;
				}
	
				// Must set array again ("vertices" getter gives a copy)
				rMesh.vertices = oMeshVerticesArray;
				
				MeshCollider rMeshCollider = rSpriteData.meshColliderComponentsList[ iMeshIndex ];
				if(rMeshCollider != null)
				{
					rMeshCollider.sharedMesh = null;
					rMeshCollider.sharedMesh = rMesh;
				}
			}
		}
		
		// Apply delta to sprite quad mesh
		Mesh rSpriteMesh = rSpriteData.renderMesh;
		Vector3[ ] oSpriteQuadMeshVerticesArray = rSpriteMesh.vertices;
		for( int iVertexIndex = 0, iVertexCount = rSpriteMesh.vertexCount; iVertexIndex < iVertexCount; ++iVertexIndex )
		{
			Vector3 f3Vertex = oSpriteQuadMeshVerticesArray[ iVertexIndex ];
			f3Vertex.x *= f2ScalingDelta.x;
			f3Vertex.y *= f2ScalingDelta.y;
			//f3Vertex -= f3ScaledDeltaPivot;
			oSpriteQuadMeshVerticesArray[ iVertexIndex ] = f3Vertex;
		}

		rSpriteSettings.pivotCustomCoords = f2NewPivotCoords;
		
		// Must set array again ("vertices" getter gives a copy)
		rSpriteMesh.vertices = oSpriteQuadMeshVerticesArray;
	}