//------------------------------------------------------------------------- /// 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; } } }
//------------------------------------------------------------------------- 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) { }