//-------------------------------------------------------------------------
    /// Copy Constructor - creates a deep copy of the src object.
    public ColliderGenTK2DParametersForSprite(ColliderGenTK2DParametersForSprite src)
    {
        mSpriteIndex = src.mSpriteIndex;

        mOutlineVertexCount = src.mOutlineVertexCount;
        // other old unused parameters skipped.

        // deep copy of the following two member variables
        if (src.mRegionIndependentParameters != null) {
            mRegionIndependentParameters = new RegionIndependentParametersTK2D(src.mRegionIndependentParameters);
        }
        else {
            mRegionIndependentParameters = null;
        }

        if (src.mColliderRegionParameters != null) {
            mColliderRegionParameters = new ColliderRegionParametersTK2D[src.mColliderRegionParameters.Length];
            for (int index = 0; index < src.mColliderRegionParameters.Length; ++index) {
                mColliderRegionParameters[index] = new ColliderRegionParametersTK2D(src.mColliderRegionParameters[index]);
            }
        }
        else {
            src.mColliderRegionParameters = null;
        }

        mVersionID = src.mVersionID;
    }
    //-------------------------------------------------------------------------
    /// Copy Constructor - creates a deep copy of the src object.
    public ColliderGenTK2DParametersForSprite(ColliderGenTK2DParametersForSprite src)
    {
        mSpriteIndex = src.mSpriteIndex;

        mOutlineVertexCount = src.mOutlineVertexCount;
        // other old unused parameters skipped.

        // deep copy of the following two member variables
        if (src.mRegionIndependentParameters != null)
        {
            mRegionIndependentParameters = new RegionIndependentParametersTK2D(src.mRegionIndependentParameters);
        }
        else
        {
            mRegionIndependentParameters = null;
        }

        if (src.mColliderRegionParameters != null)
        {
            mColliderRegionParameters = new ColliderRegionParametersTK2D[src.mColliderRegionParameters.Length];
            for (int index = 0; index < src.mColliderRegionParameters.Length; ++index)
            {
                mColliderRegionParameters[index] = new ColliderRegionParametersTK2D(src.mColliderRegionParameters[index]);
            }
        }
        else
        {
            src.mColliderRegionParameters = null;
        }

        mVersionID = src.mVersionID;
    }
    //-------------------------------------------------------------------------
    public static void SetupColliderRegionParameters(ref ColliderRegionParametersTK2D[] colliderRegionParameters, int defaultMaxPointCount,
                                                     IslandDetector.Region[] islands, IslandDetector.Region[] seaRegions)
    {
        int numColliderRegions = islands.Length + seaRegions.Length;

        bool shallResetRegionParameters = (colliderRegionParameters == null || numColliderRegions != colliderRegionParameters.Length);         // TODO!! check when to throw parameters away!

        if (shallResetRegionParameters)
        {
            colliderRegionParameters = new ColliderRegionParametersTK2D[numColliderRegions];
            int colliderRegionIndex = 0;

            // Note: We enable the first island region only. All other island- and all sea-regions are initially disabled.
            for (int islandIndex = 0; islandIndex < islands.Length; ++islandIndex)
            {
                ColliderRegionParametersTK2D newParameters = new ColliderRegionParametersTK2D();
                if (islandIndex == 0)
                {
                    newParameters.EnableRegion = true;
                }
                else
                {
                    newParameters.EnableRegion = false;
                }
                newParameters.MaxPointCount = defaultMaxPointCount;
                colliderRegionParameters[colliderRegionIndex++] = newParameters;
            }
            for (int seaRegionIndex = 0; seaRegionIndex < seaRegions.Length; ++seaRegionIndex)
            {
                ColliderRegionParametersTK2D newParameters = new ColliderRegionParametersTK2D();
                newParameters.EnableRegion  = false;
                newParameters.MaxPointCount = defaultMaxPointCount;
                colliderRegionParameters[colliderRegionIndex++] = newParameters;
            }
        }
        else
        {
            for (int count = 0; count < colliderRegionParameters.Length; ++count)
            {
                colliderRegionParameters[count].RegionUpdateCalculationNeeded = true;
            }
        }
    }
	//-------------------------------------------------------------------------
	public static int ReduceOutlineForAllColliderRegions(ref ColliderRegionData[] colliderRegions, ref PolygonOutlineFromImageFrontend outlineAlgorithm,
														  RegionIndependentParametersTK2D regionIndependentParameters,
														  ColliderRegionParametersTK2D[] colliderRegionParameters) {
		
		int numRegionsWithData = 0;
		if (colliderRegions == null || colliderRegions.Length == 0 || outlineAlgorithm == null) {
			Debug.LogError("Error: Unexpected state in ReduceOutlineForAllColliderRegions(): colliderRegions is empty or null or outlineAlgorithm is null!");
			return 0;
		}
		
		for (int count = 0; count < colliderRegions.Length; ++count) {
			
			if (colliderRegions[count].mIntermediateOutlineVertices == null) {
				colliderRegions[count].mResultVertices = null;
				colliderRegions[count].mResultTriangleIndices = null;
				continue;
			}
			if (colliderRegions[count].mReducedOutlineVertices != null && !colliderRegionParameters[count].RegionUpdateCalculationNeeded) {
				continue;
			}
			
			outlineAlgorithm.VertexReductionDistanceTolerance = regionIndependentParameters.VertexReductionDistanceTolerance;
			outlineAlgorithm.MaxPointCount = colliderRegionParameters[count].MaxPointCount;
			// TODO: replace this with a joint-convex hull implementation, just a workaround for now.
			bool allRegionsConvex = regionIndependentParameters.Convex;
			outlineAlgorithm.Convex = allRegionsConvex ? true : colliderRegionParameters[count].Convex;
			
			colliderRegions[count].mReducedOutlineVertices = outlineAlgorithm.ReduceOutline(colliderRegions[count].mIntermediateOutlineVertices, colliderRegions[count].mOutlineVertexOrderIsCCW);
			colliderRegionParameters[count].RegionUpdateCalculationNeeded = false;
			++numRegionsWithData;
		}
		return numRegionsWithData;
	}
	//-------------------------------------------------------------------------
	public static void CalculateUnreducedOutlineForAllColliderRegions(ref ColliderRegionData[] colliderRegions, ref PolygonOutlineFromImageFrontend outlineAlgorithm,
																	  RegionIndependentParametersTK2D regionIndependentParameters,
																	  ColliderRegionParametersTK2D[] colliderRegionParameters, bool [,] binaryImage,
																	  bool ccwVertexOrder) {
		
		Vector3 customOffset = regionIndependentParameters.CustomOffset;
		Vector3 customScale = regionIndependentParameters.CustomScale;
		
		for (int count = 0; count < colliderRegions.Length; ++count) {
        
			if (colliderRegionParameters[count].EnableRegion) {
				// Calculate polygon bounds
	            outlineAlgorithm.VertexReductionDistanceTolerance = regionIndependentParameters.VertexReductionDistanceTolerance;
			    outlineAlgorithm.MaxPointCount = colliderRegionParameters[count].MaxPointCount;
				
				// TODO: replace this with a joint-convex hull implementation, just a workaround for now.
				bool allRegionsConvex = regionIndependentParameters.Convex;
				outlineAlgorithm.Convex = allRegionsConvex ? true : colliderRegionParameters[count].Convex;
			    //outlineAlgorithm.Convex = colliderRegionParameters[count].Convex;
			    
				outlineAlgorithm.XOffsetNormalized = 0.0f + customOffset.x + (0.5f - (0.5f * customScale.x));
	            outlineAlgorithm.YOffsetNormalized = 1.0f - customOffset.y - (0.5f - (0.5f * customScale.y));
				outlineAlgorithm.XScale = 1.0f * customScale.x;
	            outlineAlgorithm.YScale = -1.0f * customScale.y;
			    bool outputVerticesInNormalizedSpace = false;
				
				bool regionVertexOrder = ccwVertexOrder;
				if (!colliderRegions[count].mRegionIsIsland) {
					regionVertexOrder = !regionVertexOrder;
				}
	
				colliderRegions[count].mOutlineVertexOrderIsCCW = regionVertexOrder;
	            outlineAlgorithm.UnreducedOutlineFromBinaryImage(out colliderRegions[count].mIntermediateOutlineVertices, binaryImage, colliderRegions[count].mDetectedRegion.mPointAtBorder, colliderRegions[count].mRegionIsIsland, outputVerticesInNormalizedSpace, regionVertexOrder);
			}
			else {
				colliderRegions[count].mIntermediateOutlineVertices = null;
				colliderRegions[count].mResultVertices = null;
				colliderRegions[count].mResultTriangleIndices = null;
			}
        }
	}
	//-------------------------------------------------------------------------
	public static void SetupColliderRegionParameters(ref ColliderRegionParametersTK2D[] colliderRegionParameters, int defaultMaxPointCount,
													 IslandDetector.Region[] islands, IslandDetector.Region[] seaRegions) {
		
		int numColliderRegions = islands.Length + seaRegions.Length;
		
		bool shallResetRegionParameters = (colliderRegionParameters == null || numColliderRegions != colliderRegionParameters.Length); // TODO!! check when to throw parameters away!
		if (shallResetRegionParameters) {
			
			colliderRegionParameters = new ColliderRegionParametersTK2D[numColliderRegions];
			int colliderRegionIndex = 0;
			
			// Note: We enable the first island region only. All other island- and all sea-regions are initially disabled.
			for (int islandIndex = 0; islandIndex < islands.Length; ++islandIndex) {
				
				ColliderRegionParametersTK2D newParameters = new ColliderRegionParametersTK2D();
				if (islandIndex == 0) {
					newParameters.EnableRegion = true;
				}
				else {
					newParameters.EnableRegion = false;
				}
				newParameters.MaxPointCount = defaultMaxPointCount;
				colliderRegionParameters[colliderRegionIndex++] = newParameters;
			}
			for (int seaRegionIndex = 0; seaRegionIndex < seaRegions.Length; ++seaRegionIndex) {

				ColliderRegionParametersTK2D newParameters = new ColliderRegionParametersTK2D();
				newParameters.EnableRegion = false;
				newParameters.MaxPointCount = defaultMaxPointCount;
				colliderRegionParameters[colliderRegionIndex++] = newParameters;
			}
		}
		else {
			for (int count = 0; count < colliderRegionParameters.Length; ++count) {
				colliderRegionParameters[count].RegionUpdateCalculationNeeded = true;
			}
		}
	}
Example #7
0
    //-------------------------------------------------------------------------
    void OnInspectorGuiHolesAndIslandsSection(out bool haveColliderRegionEnabledChanged,
                                              out bool haveColliderRegionMaxPointCountChanged,
                                              out bool haveColliderRegionConvexChanged)
    {
        haveColliderRegionEnabledChanged       = false;
        haveColliderRegionMaxPointCountChanged = false;
        haveColliderRegionConvexChanged        = false;

        if (mAlgorithmHelper.ColliderRegions == null || mAlgorithmHelper.ColliderRegions.Length == 0 ||
            mAlgorithmHelper.ColliderRegionParams == null || mAlgorithmHelper.ColliderRegionParams.Length == 0)
        {
            return;
        }

        if (!mAllSelectedSpritesHaveSameNumColliderRegions)
        {
            EditorGUILayout.LabelField("Holes and Islands", "<different number of Holes/Islands>");
            return;
        }

        int numColliderRegions = 0;

        if (mAlgorithmHelper.ColliderRegions != null)
        {
            numColliderRegions = mAlgorithmHelper.ColliderRegions.Length;
        }

        bool[] newIsRegionEnabled   = new bool [numColliderRegions];
        int[]  newRegionPointCount  = new int [numColliderRegions];
        bool[] newForceRegionConvex = new bool [numColliderRegions];

        string foldoutString = "Holes and Islands [" + mAlgorithmHelper.NumEnabledColliderRegions + "][" + mAlgorithmHelper.ActualPointCountOfAllRegions + " vertices]";

        mShowHolesAndIslandsSection = EditorGUILayout.Foldout(mShowHolesAndIslandsSection, foldoutString);
        if (mShowHolesAndIslandsSection)
        {
            EditorGUI.indentLevel++;
            for (int regionIndex = 0; regionIndex < numColliderRegions; ++regionIndex)
            {
                ColliderRegionData           colliderRegion = mAlgorithmHelper.ColliderRegions[regionIndex];
                ColliderRegionParametersTK2D parameters     = mAlgorithmHelper.ColliderRegionParams[regionIndex];
                bool isEnabled     = parameters.EnableRegion;
                int  maxPointCount = parameters.MaxPointCount;
                bool convex        = parameters.Convex;

                if (regionIndex != 0)
                {
                    EditorGUILayout.Space();
                }



                string regionOrIslandString = colliderRegion.mRegionIsIsland ? "Island " : "Hole ";
                regionOrIslandString += regionIndex + " [" + colliderRegion.mDetectedRegion.mPointCount + " px]";

                //EditorGUILayout.BeginToggleGroup(regionOrIslandString, true);
                bool newIsEnabled = EditorGUILayout.BeginToggleGroup(regionOrIslandString, isEnabled);
                //bool newIsEnabled = EditorGUILayout.Toggle(regionOrIslandString, isEnabled);

                EditorGUI.indentLevel++;


                // int [3..100] max point count
                int  newPointCount = EditorGUILayout.IntSlider("Outline Vertex Count", maxPointCount, 3, mPointCountSliderMax);
                bool newConvex     = EditorGUILayout.Toggle("Force Convex", convex);

                EditorGUI.indentLevel--;
                EditorGUILayout.EndToggleGroup();

                bool hasEnabledChanged    = newIsEnabled != isEnabled;
                bool hasPountCountChanged = newPointCount != maxPointCount;
                bool hasConvexChanged     = newConvex != convex;
                if (hasEnabledChanged)
                {
                    haveColliderRegionEnabledChanged = true;
                }
                if (hasPountCountChanged)
                {
                    haveColliderRegionMaxPointCountChanged = true;
                }
                if (hasConvexChanged)
                {
                    haveColliderRegionConvexChanged = true;
                }

                newIsRegionEnabled[regionIndex]   = newIsEnabled;
                newRegionPointCount[regionIndex]  = newPointCount;
                newForceRegionConvex[regionIndex] = newConvex;
            }

            for (int regionIndex = 0; regionIndex < numColliderRegions; ++regionIndex)
            {
                ColliderRegionParametersTK2D colliderRegionParams = mAlgorithmHelper.ColliderRegionParams[regionIndex];
                colliderRegionParams.EnableRegion  = newIsRegionEnabled[regionIndex];
                colliderRegionParams.MaxPointCount = newRegionPointCount[regionIndex];
                colliderRegionParams.Convex        = newForceRegionConvex[regionIndex];
            }

            EditorGUI.indentLevel--;
        }
    }
 // Deep-copy constructor.
 public ColliderRegionParametersTK2D(ColliderRegionParametersTK2D src) : base(src)
 {
 }