コード例 #1
0
ファイル: AlphaMeshCollider.cs プロジェクト: C453/Valdemar
	//-------------------------------------------------------------------------
	bool ExportMeshToFile(GeneratedColliderData generatedColliderData) {
		
		ColladaExporter colladaWriter = new ColladaExporter();
		ColladaExporter.GeometryNode rootGeometryNode = new ColladaExporter.GeometryNode();
		
		Vector3[] jointVertices = null;
		int[] jointIndices = null;
		JoinVertexGroups(generatedColliderData.mColliderRegions, out jointVertices, out jointIndices);

		if (jointVertices == null || jointVertices.Length == 0) {
			CreateDummyTriangleToCreateAValidColladaFile(out jointVertices, out jointIndices);
		}
			
		rootGeometryNode.mName = "Collider";
		rootGeometryNode.mAreVerticesLeftHanded = true;
		rootGeometryNode.mVertices = jointVertices;
		rootGeometryNode.mTriangleIndices = jointIndices;
		rootGeometryNode.mGenerateNormals = true;

		float scaleX = GetOutputScaleX(true);
		float scaleY = GetOutputScaleY();
		
		colladaWriter.mVertexScaleAfterInitialRotation.x = scaleX; // the mesh is imported in a way that we end up correct this way.
		colladaWriter.mVertexScaleAfterInitialRotation.y = scaleY;
		colladaWriter.mVertexScaleAfterSecondRotation = Vector3.one;
		
		float atlasFrameRotation = mAtlasFrameRotation;
		if (mRegionIndependentParameters.CustomTex != null) {
			colladaWriter.mVertexScaleAfterInitialRotation.Scale(GetCustomImageScale());
			atlasFrameRotation = 0.0f;
		}
		
		// In order to rotate well, we need to compensate for the gameobject's
		// transform.scale that is applied automatically after all of our transforms.
		Vector3 automaticallyAppliedScale = this.transform.localScale;
		Vector3 rotationCompensationScaleBefore = new Vector3(automaticallyAppliedScale.x, automaticallyAppliedScale.y, 1.0f);
		Vector3 rotationCompensationScaleAfter = new Vector3(1.0f / automaticallyAppliedScale.x, 1.0f / automaticallyAppliedScale.y, 1.0f);
		colladaWriter.mVertexScaleAfterInitialRotation.Scale(rotationCompensationScaleBefore);
		colladaWriter.mVertexScaleAfterSecondRotation.Scale(rotationCompensationScaleAfter);
		
		colladaWriter.mVertexOffset.x = -mOutlineOffset.x -mRegionIndependentParameters.CustomOffset.x;
		colladaWriter.mVertexOffset.y = mOutlineOffset.y + mRegionIndependentParameters.CustomOffset.y;
		colladaWriter.mVertexOffset.z = -mOutlineOffset.z -mRegionIndependentParameters.CustomOffset.z;
		colladaWriter.mVertexTransformationCenter = new Vector3(0, 0, 0);
		colladaWriter.mVertexInitialRotationQuaternion = Quaternion.Euler(0, 0, -atlasFrameRotation);
		colladaWriter.mVertexSecondRotationQuaternion = Quaternion.Euler(0, 0,  -mRegionIndependentParameters.CustomRotation);
		
		System.IO.Directory.CreateDirectory(mColliderMeshDirectory);
		colladaWriter.ExportTriangleMeshToFile(ActiveFrameFullColliderMeshPath(), rootGeometryNode);
		return true;
	}
コード例 #2
0
ファイル: AlphaMeshCollider.cs プロジェクト: C453/Valdemar
	//-------------------------------------------------------------------------
	bool GenerateUnreducedColliderMesh(ref GeneratedColliderData generatedColliderData) {
		
		UpdateFromOldVersionForBackwardsCompatibility();

		// just in case the texture has changed.
		InitTextureParams();

#if UNITY_4_3_AND_LATER
		if (mHasUnity43SpriteAnimatorComponent) {
			EnsureHasUnity43AnimatedColliderComponents();
			EnsureDataIsPreparedForMultipleColliders();
		}
#endif
		
		if (mHasSmoothMovesAnimBoneColliderComponent || mHasSmoothMovesBoneAnimationParent == InitState.Yes) {
			EnsureSmoothMovesBoneAnimHasRestoreComponent(mSmoothMovesBoneAnimation);
		}
		
		if (UsedTexture == null) {
			return false;
		}
		
		UpdateColliderMeshFilename();

		if (generatedColliderData.mOutlineAlgorithm == null) {
			generatedColliderData.mOutlineAlgorithm = new PolygonOutlineFromImageFrontend();
		}
		PolygonOutlineFromImageFrontend outlineAlgorithm = generatedColliderData.mOutlineAlgorithm;
		
		bool useImageRegion = false;
		int regionX = 0;
		int regionY = 0;
		int regionWidth = UsedTexture.width;
		int regionHeight = UsedTexture.height;
		
		float unroundedRegionX = 0.0f;
		float unroundedRegionY = 0.0f;
		float unroundedWidth = 1.0f;
		float unroundedHeight = 1.0f;
		
		float pixelCutawayLeft = 0.0f;
		float pixelCutawayRight = 0.0f;
		float pixelCutawayBottom = 0.0f;
		float pixelCutawayTop = 0.0f;
		
		if (mRegionIndependentParameters.IsCustomAtlasRegionUsed || mIsAtlasUsed) {
			
			useImageRegion = true;
			if (mRegionIndependentParameters.IsCustomAtlasRegionUsed) {
				
				unroundedRegionX = mRegionIndependentParameters.CustomAtlasFramePositionInPixels.x;
				unroundedRegionY = mRegionIndependentParameters.CustomAtlasFramePositionInPixels.y;
				unroundedWidth = mRegionIndependentParameters.CustomAtlasFrameSizeInPixels.x;
				unroundedHeight = mRegionIndependentParameters.CustomAtlasFrameSizeInPixels.y;
			}
			else if (mIsAtlasUsed) { // mRegionIndependentParameters.IsCustomAtlasRegionUsed has priority over mIsAtlasUsed.
				
				unroundedRegionX = mAtlasFramePositionInPixels.x;
				unroundedRegionY = mAtlasFramePositionInPixels.y;
				unroundedWidth = mAtlasFrameSizeInPixels.x;
				unroundedHeight = mAtlasFrameSizeInPixels.y;
			}
		
			regionX = Mathf.FloorToInt(unroundedRegionX);
			regionY = Mathf.FloorToInt(unroundedRegionY);
			float unroundedEndX = unroundedRegionX + unroundedWidth;
			float unroundedEndY = unroundedRegionY + unroundedHeight;
			int endX = Mathf.CeilToInt(unroundedEndX);
			int endY = Mathf.CeilToInt(unroundedEndY);
			regionWidth =  endX - regionX;
			regionHeight = endY - regionY;
			
			pixelCutawayLeft = unroundedRegionX - regionX;
			pixelCutawayRight = endX - unroundedEndX;
			pixelCutawayBottom = endY - unroundedEndY;
			pixelCutawayTop = unroundedRegionY - regionY;
		}

		if (regionWidth == 0 || regionHeight == 0) {
			Debug.LogError("Error: Encountered image width or height of 0. Stopping collider generation.");
			return false;
		}
		
		bool wasSuccessful = outlineAlgorithm.BinaryAlphaThresholdImageFromTexture(out generatedColliderData.mBinaryImage, UsedTexture, mRegionIndependentParameters.AlphaOpaqueThreshold,
															   											  useImageRegion, regionX, regionY, regionWidth, regionHeight);
		if (!wasSuccessful) {
			Debug.LogError(outlineAlgorithm.LastError);
			return false;
		}

		IslandDetector.Region[] islands;
		IslandDetector.Region[] seaRegions;
		/*bool anyIslandsFound =*/ CalculateIslandStartingPoints(generatedColliderData.mBinaryImage, out islands, out seaRegions);
        /*if (!anyIslandsFound) { // we now tolerate if there is no island pixel, one could still enable the single sea-region.
            return false;
        }*/
		
		SetupColliderRegions(out generatedColliderData.mColliderRegions, islands, seaRegions);

		CopyOldColliderRegionParametersForBackwardsCompatibility();
		SetupColliderRegionParameters(ref mIslandRegionParameters, ref mSeaRegionParameters, mRegionIndependentParameters.DefaultMaxPointCount, islands, seaRegions);
		CopyOldPointCountParameterToFirstIslandForBackwardsCompatibility(ref mIslandRegionParameters, ref mMaxPointCount);
		
		bool ccwVertexOrder = IsOutlineInCCWOrderNecessary();
		outlineAlgorithm.RegionPixelCutawayLeft = pixelCutawayLeft;
		outlineAlgorithm.RegionPixelCutawayRight = pixelCutawayRight;
		outlineAlgorithm.RegionPixelCutawayBottom = pixelCutawayBottom;
		outlineAlgorithm.RegionPixelCutawayTop = pixelCutawayTop;
		outlineAlgorithm.NormalizeResultToCutRegion = true;
			
		CalculateUnreducedOutlineForAllColliderRegions(ref generatedColliderData.mColliderRegions, ref outlineAlgorithm, mRegionIndependentParameters, mIslandRegionParameters, mSeaRegionParameters, generatedColliderData.mBinaryImage, ccwVertexOrder);
        return true;
	}
コード例 #3
0
ファイル: AlphaMeshCollider.cs プロジェクト: C453/Valdemar
	//-------------------------------------------------------------------------
	bool ReduceAndStoreColliderMesh(ref GeneratedColliderData generatedColliderData) {
		
		UpdateFromOldVersionForBackwardsCompatibility();
		
		if (generatedColliderData.mColliderRegions == null || generatedColliderData.mColliderRegions.Length == 0) {
			return false; // needs to be calculated before calling this method!
		}

		if (generatedColliderData.mOutlineAlgorithm == null) {
			generatedColliderData.mOutlineAlgorithm = new PolygonOutlineFromImageFrontend();
		}
		PolygonOutlineFromImageFrontend outlineAlgorithm = generatedColliderData.mOutlineAlgorithm;

		bool needsTriangleFenceUpdate = this.mRegionIndependentParameters.HasThicknessChanged;
		this.mRegionIndependentParameters.HasThicknessChanged = false;

		ColliderRegionData[] colliderRegions = generatedColliderData.mColliderRegions;
		int islandIndex = 0;
		int seaRegionIndex = 0;
		bool anyRegionWithVerticesFound = false;
		for (int count = 0; count < colliderRegions.Length; ++count) {

			ColliderRegionData region = colliderRegions[count];

			bool isIslandRegion = region.mRegionIsIsland;
			ColliderRegionParameters regionParameters = isIslandRegion ? mIslandRegionParameters[islandIndex] : mSeaRegionParameters[seaRegionIndex];
			if (isIslandRegion) {
				++islandIndex;
			}
			else {
				++seaRegionIndex;
			}

			if (region.mIntermediateOutlineVertices == null) {
				region.mResultVertices = null;
				region.mResultTriangleIndices = null;
				continue;
			}
			anyRegionWithVerticesFound = true;
			
			bool needsRegionReduction = true;
			if (region.mReducedOutlineVertices != null && region.mReducedOutlineVertices.Count != 0 &&
			    !regionParameters.RegionUpdateCalculationNeeded) {
				needsRegionReduction = false;
			}
			
			outlineAlgorithm.VertexReductionDistanceTolerance = this.mRegionIndependentParameters.VertexReductionDistanceTolerance;
			outlineAlgorithm.MaxPointCount = regionParameters.MaxPointCount;
			// TODO: replace this with a joint-convex hull implementation, just a workaround for now.
			bool allRegionsConvex = mRegionIndependentParameters.Convex;
			outlineAlgorithm.Convex = allRegionsConvex ? true : regionParameters.Convex;
			outlineAlgorithm.XOffsetNormalized = -0.5f;//-this.transform.localScale.x / 2.0f;
			outlineAlgorithm.YOffsetNormalized = -0.5f;//-this.transform.localScale.y / 2.0f;
			outlineAlgorithm.Thickness = this.mRegionIndependentParameters.Thickness;
			
			if (needsRegionReduction) {
				region.mReducedOutlineVertices = outlineAlgorithm.ReduceOutline(region.mIntermediateOutlineVertices, region.mOutlineVertexOrderIsCCW);
			}
			regionParameters.RegionUpdateCalculationNeeded = false;
        
			if (needsRegionReduction || needsTriangleFenceUpdate) {
				Vector3[] vertices;
				int[] triangleIndices;
			
				outlineAlgorithm.TriangleFenceFromOutline(out vertices, out triangleIndices, region.mReducedOutlineVertices, false);
			
				region.mResultVertices = vertices;
				region.mResultTriangleIndices = triangleIndices;
			}
		}

		if (!anyRegionWithVerticesFound) {
			return false; // we cannot/don't want to store a collada file with no vertices and import it back in, unfortunately.
		}

		bool needsToWriteMeshColliderFile = true;
#if UNITY_4_3_AND_LATER
		needsToWriteMeshColliderFile = (mRegionIndependentParameters.TargetColliderType == TargetColliderType.MeshCollider);
#endif
		if (needsToWriteMeshColliderFile) {
			return ExportMeshToFile(generatedColliderData);
		}
		else {
			return true; // done already
		}
	}
コード例 #4
0
ファイル: AlphaMeshCollider.cs プロジェクト: C453/Valdemar
	//-------------------------------------------------------------------------
	void EnsureDataIsPreparedForMultipleColliders() {
		int oldSize = mGeneratedColliderData.Length;
		int desiredSize = mRegionIndependentParameters.NumCollidersNeeded;
		if (oldSize != desiredSize) {
			Array.Resize(ref mGeneratedColliderData, desiredSize);
			for (int newIndexToInit = oldSize; newIndexToInit < desiredSize; ++newIndexToInit) {
				mGeneratedColliderData[newIndexToInit] = new GeneratedColliderData();
			}
		}
	}