Exemplo n.º 1
0
        /*
         * public static bool ContinueTexGenFromSurfaceToSurface(CSGBrush srcBrush, int srcSurfaceIndex, CSGBrush dstBrush, int dstSurfaceIndex)
         * {
         *      if (srcSurfaceIndex < 0 || srcSurfaceIndex >= srcBrush.Shape.Materials.Length ||
         *              srcBrush == null)
         *              return false;
         *
         *      var src_brush_cache = CSGModelManager.GetBrushCache(srcBrush);
         *      if (src_brush_cache == null ||
         *              src_brush_cache.childData == null ||
         *              src_brush_cache.childData.modelTransform == null)
         *              return false;
         *
         *      var dst_brush_cache = CSGModelManager.GetBrushCache(dstBrush);
         *      if (dst_brush_cache == null ||
         *              dst_brush_cache.childData == null ||
         *              dst_brush_cache.childData.modelTransform == null)
         *              return false;
         *
         *      var dstPlane	= dstBrush.Shape.Surfaces[dstSurfaceIndex].Plane;
         *      var srcPlane	= srcBrush.Shape.Surfaces[srcSurfaceIndex].Plane;
         *
         *      // convert planes into worldspace
         *      dstPlane = GeometryUtility.InverseTransformPlane(dstBrush.transform.worldToLocalMatrix, dstPlane);
         *      srcPlane = GeometryUtility.InverseTransformPlane(srcBrush.transform.worldToLocalMatrix, srcPlane);
         *
         *      var dstNormal	= dstPlane.normal;
         *      var srcNormal	= srcPlane.normal;
         *
         *      var srcTexGenIndex = srcBrush.Shape.Surfaces[srcSurfaceIndex].TexGenIndex;
         *      var dstTexGenIndex = dstBrush.Shape.Surfaces[dstSurfaceIndex].TexGenIndex;
         *
         *      var scrShape = srcBrush.Shape;
         *
         *      dstBrush.Shape.Materials[dstSurfaceIndex] = scrShape.Materials[srcSurfaceIndex];
         *      Vector3 srcPoint1, srcPoint2;
         *      Vector3 dstPoint1, dstPoint2;
         *      var edgeDirection = Vector3.Cross(dstNormal, srcNormal);
         *      var det = edgeDirection.sqrMagnitude;
         *      if (det < Constants.AlignmentTestEpsilon)
         *      {
         *              // Find 2 points on intersection of 2 planes
         *              srcPoint1 = srcPlane.pointOnPlane;
         *              srcPoint2 = GeometryUtility.ProjectPointOnPlane(srcPlane, srcPoint1 + MathConstants.oneVector3);
         *
         *              dstPoint1 = GeometryUtility.ProjectPointOnPlane(dstPlane, srcPoint1);
         *              dstPoint2 = GeometryUtility.ProjectPointOnPlane(dstPlane, srcPoint2);
         *      } else
         *      {
         *              // Find 2 points on intersection of 2 planes
         *              srcPoint1 = ((Vector3.Cross(edgeDirection, srcNormal) * -dstPlane.d) +
         *                                              (Vector3.Cross(dstNormal, edgeDirection) * -srcPlane.d)) / det;
         *              srcPoint2 = srcPoint1 + edgeDirection;
         *              dstPoint1 = srcPoint1;
         *              dstPoint2 = srcPoint2;
         *      }
         *
         *      Vector3 srcLocalPoint1 = srcBrush.transform.InverseTransformPoint(srcPoint1);
         *      Vector3 srcLocalPoint2 = srcBrush.transform.InverseTransformPoint(srcPoint2);
         *
         *      Vector3 dstLocalPoint1 = dstBrush.transform.InverseTransformPoint(dstPoint1);
         *      Vector3 dstLocalPoint2 = dstBrush.transform.InverseTransformPoint(dstPoint2);
         *
         *      var srcShape	= srcBrush.Shape;
         *      var srcTexGens	= srcShape.TexGens;
         *      var srcSurfaces	= srcShape.Surfaces;
         *      var dstShape	= dstBrush.Shape;
         *      var dstTexGens	= dstShape.TexGens;
         *      var dstSurfaces	= dstShape.Surfaces;
         *
         *
         *      // Reset destination shape to simplify calculations
         *      dstTexGens[dstTexGenIndex].Scale			= scrShape.TexGens[srcTexGenIndex].Scale;
         *      dstTexGens[dstTexGenIndex].Translation		= MathConstants.zeroVector2;
         *      dstTexGens[dstTexGenIndex].RotationAngle	= 0;
         *
         *      if (!CSGModelManager.AlignTextureSpacesInLocalSpace(ref srcTexGens[srcTexGenIndex], ref srcSurfaces[srcSurfaceIndex],
         *                                                                                                              srcLocalPoint1, srcLocalPoint2,
         *                                                                                                              ref dstTexGens[dstTexGenIndex], ref dstSurfaces[dstSurfaceIndex],
         *                                                                                                              dstLocalPoint1, dstLocalPoint2))
         *              return false;
         *      return true;
         * }
         */

        public static bool ContinueTexGenFromSurfaceToSurface(CSGBrush brush, int srcSurfaceIndex, int dstSurfaceIndex)
        {
            if (srcSurfaceIndex < 0 || srcSurfaceIndex >= brush.Shape.Materials.Length ||
                !brush)
            {
                return(false);
            }

            var shape       = brush.Shape;
            var texGens     = shape.TexGens;
            var texGenFlags = shape.TexGenFlags;
            var surfaces    = shape.Surfaces;

            var dstPlane = surfaces[dstSurfaceIndex].Plane;
            var srcPlane = surfaces[srcSurfaceIndex].Plane;

            // convert planes into worldspace
            dstPlane = InverseTransformPlane(brush.transform.worldToLocalMatrix, dstPlane);
            srcPlane = InverseTransformPlane(brush.transform.worldToLocalMatrix, srcPlane);

            var dstNormal = dstPlane.normal;
            var srcNormal = srcPlane.normal;

            var srcTexGenIndex = surfaces[srcSurfaceIndex].TexGenIndex;
            var dstTexGenIndex = surfaces[dstSurfaceIndex].TexGenIndex;

            shape.Materials[dstSurfaceIndex] = shape.Materials[srcSurfaceIndex];
            Vector3 srcPoint1, srcPoint2;
            Vector3 dstPoint1, dstPoint2;
            var     edgeDirection = Vector3.Cross(dstNormal, srcNormal);
            var     det           = edgeDirection.sqrMagnitude;

            if (det < MathConstants.AlignmentTestEpsilon)
            {
                // Find 2 points on intersection of 2 planes
                srcPoint1 = srcPlane.pointOnPlane;
                srcPoint2 = GeometryUtility.ProjectPointOnPlane(srcPlane, srcPoint1 + MathConstants.oneVector3);

                dstPoint1 = GeometryUtility.ProjectPointOnPlane(dstPlane, srcPoint1);
                dstPoint2 = GeometryUtility.ProjectPointOnPlane(dstPlane, srcPoint2);
            }
            else
            {
                // Find 2 points on intersection of 2 planes
                srcPoint1 = ((Vector3.Cross(edgeDirection, srcNormal) * -dstPlane.d) +
                             (Vector3.Cross(dstNormal, edgeDirection) * -srcPlane.d)) / det;
                srcPoint2 = srcPoint1 + edgeDirection;
                dstPoint1 = srcPoint1;
                dstPoint2 = srcPoint2;
            }

            // Reset destination shape to simplify calculations
            texGens[dstTexGenIndex].Scale         = shape.TexGens[srcTexGenIndex].Scale;
            texGens[dstTexGenIndex].Translation   = MathConstants.zeroVector2;
            texGens[dstTexGenIndex].RotationAngle = 0;

            return(SurfaceUtility.AlignTextureSpaces(brush.transform, ref texGens[srcTexGenIndex], texGenFlags[srcTexGenIndex], ref surfaces[srcSurfaceIndex], srcPoint1, srcPoint2, false,
                                                     brush.transform, ref texGens[dstTexGenIndex], texGenFlags[dstTexGenIndex], ref surfaces[dstSurfaceIndex], dstPoint1, dstPoint2, false));
        }
Exemplo n.º 2
0
		private bool GenerateSphere(float radius, int splits, CSGModel parentModel, CSGBrush brush, out ControlMesh controlMesh, out Shape shape)
        {
			if (prevSplits != splits || prevIsHemisphere != IsHemiSphere || splitControlMesh == null || splitShape == null)
			{
				splitControlMesh = null;
				splitShape = null;
				BrushFactory.CreateCubeControlMesh(out splitControlMesh, out splitShape, Vector3.one);

				var axi = new Vector3[] { MathConstants.upVector3, MathConstants.leftVector3, MathConstants.forwardVector3 };
				List<int> intersectedEdges = new List<int>();
				float step = 1.0f / (float)(splits + 1);
				float offset;
				for (int i = 0; i < axi.Length; i++)
				{
					var normal = axi[i];
					offset = 0.5f - step;
					while (offset > 0.0f)
					{
						ControlMeshUtility.CutMesh(splitControlMesh, splitShape, new CSGPlane(-normal, -offset), ref intersectedEdges);
						if (i != 0 || !IsHemiSphere)
						{
							ControlMeshUtility.CutMesh(splitControlMesh, splitShape, new CSGPlane(normal, -offset), ref intersectedEdges);
						}
						offset -= step;
					}
					if (i != 0 || !IsHemiSphere)
					{
						if ((splits & 1) == 1)
							ControlMeshUtility.CutMesh(splitControlMesh, splitShape, new CSGPlane(normal, 0), ref intersectedEdges);
					}
				}

				if (IsHemiSphere)
				{
					var cuttingPlane = new CSGPlane(MathConstants.upVector3, 0);
					intersectedEdges.Clear();
					if (ControlMeshUtility.CutMesh(splitControlMesh, splitShape, cuttingPlane, ref intersectedEdges))
					{
						var edge_loop = ControlMeshUtility.FindEdgeLoop(splitControlMesh, ref intersectedEdges);
						if (edge_loop != null)
						{
							if (ControlMeshUtility.SplitEdgeLoop(splitControlMesh, splitShape, edge_loop))
							{
								Shape foundShape;
								ControlMesh foundControlMesh;
								ControlMeshUtility.FindAndDetachSeparatePiece(splitControlMesh, splitShape, cuttingPlane, out foundControlMesh, out foundShape);
							}
						}
					}
				}


				// Spherize the cube
				for (int i = 0; i < splitControlMesh.Vertices.Length; i++)
				{
					Vector3 v = splitControlMesh.Vertices[i] * 2.0f;
					float x2 = v.x * v.x;
					float y2 = v.y * v.y;
					float z2 = v.z * v.z;
					Vector3 s;
					s.x = v.x * Mathf.Sqrt(1f - (y2 * 0.5f) - (z2 * 0.5f) + ((y2 * z2) / 3.0f));
					s.y = v.y * Mathf.Sqrt(1f - (z2 * 0.5f) - (x2 * 0.5f) + ((z2 * x2) / 3.0f));
					s.z = v.z * Mathf.Sqrt(1f - (x2 * 0.5f) - (y2 * 0.5f) + ((x2 * y2) / 3.0f));
					splitControlMesh.Vertices[i] = s;//(splitControlMesh.Vertices[i] * 0.75f) + (splitControlMesh.Vertices[i].normalized * 0.25f);
				}


				if (!ControlMeshUtility.Triangulate(null, splitControlMesh, splitShape))
				{
					Debug.LogWarning("!ControlMeshUtility.IsConvex");
					controlMesh = null;
					shape = null;
					return false;
				}
				ControlMeshUtility.FixTexGens(splitControlMesh, splitShape);

				if (!ControlMeshUtility.IsConvex(splitControlMesh, splitShape))
				{
					Debug.LogWarning("!ControlMeshUtility.IsConvex");
					controlMesh = null;
					shape = null;
					return false;
				}
				ControlMeshUtility.UpdateTangents(splitControlMesh, splitShape);

				prevSplits = splits;
				prevIsHemisphere = IsHemiSphere;
			}

			if (splitControlMesh == null || splitShape == null || !splitControlMesh.Valid)
			{
				Debug.LogWarning("splitControlMesh == null || splitShape == null || !splitControlMesh.IsValid");
				controlMesh = null;
				shape = null;
				return false;
			}

			controlMesh = splitControlMesh.Clone();
			shape = splitShape.Clone();

			/*
			float angle_offset = GeometryUtility.SignedAngle(gridTangent, delta / sphereRadius, buildPlane.normal);
			angle_offset -= 90;

			angle_offset += sphereOffset;
			angle_offset *= Mathf.Deg2Rad;

			Vector3 p1 = MathConstants.zeroVector3;
			for (int i = 0; i < realSplits; i++)
			{
				var angle = ((i * Mathf.PI * 2.0f) / (float)realSplits) + angle_offset;

				p1.x = (Mathf.Sin(angle) * sphereRadius);
				p1.z = (Mathf.Cos(angle) * sphereRadius);
			}
			*/

			for (int i = 0; i < controlMesh.Vertices.Length; i++)
			{
				var vertex = controlMesh.Vertices[i];
				vertex *= radius;
				controlMesh.Vertices[i] = vertex;
			}

			for (int i = 0; i < shape.Surfaces.Length; i++)
			{
				var plane = shape.Surfaces[i].Plane;
				plane.d *= radius;
				shape.Surfaces[i].Plane = plane;
			}

			bool smoothShading = SphereSmoothShading;
			if (!sphereSmoothingGroup.HasValue && smoothShading)
			{
				sphereSmoothingGroup = SurfaceUtility.FindUnusedSmoothingGroupIndex();
			}

			for (int i = 0; i < shape.TexGenFlags.Length; i++)
			{
				shape.TexGens[i].SmoothingGroup = smoothShading ? sphereSmoothingGroup.Value : 0;
			}

			var defaultTexGen = new TexGen();
			defaultTexGen.Scale = MathConstants.oneVector3;
			//defaultTexGen.Color = Color.white;
			
			var fakeSurface = new Surface();
			fakeSurface.TexGenIndex = 0;
			
			var defaultMaterial = CSGSettings.DefaultMaterial;
			for (var s = 0; s < shape.Surfaces.Length; s++)
			{
				var texGenIndex = shape.Surfaces[s].TexGenIndex;

				var axis		= GeometryUtility.SnapToClosestAxis(shape.Surfaces[s].Plane.normal);
				var rotation	= Quaternion.FromToRotation(axis, MathConstants.backVector3);
				var matrix		= Matrix4x4.TRS(MathConstants.zeroVector3, rotation, MathConstants.oneVector3);

				SurfaceUtility.AlignTextureSpaces(matrix, false, ref shape.TexGens[texGenIndex], ref shape.TexGenFlags[texGenIndex], ref shape.Surfaces[s]);
				shape.TexGens[texGenIndex].RenderMaterial = defaultMaterial;
			}

			return true;
        }
        /// <summary>Generate a <see cref="RealtimeCSG.Legacy.ControlMesh"/>/<see cref="RealtimeCSG.Legacy.Shape"/> pair from the given planes (and optional other values)</summary>
        /// <remarks><note>Keep in mind that the planes encapsulate the geometry we're generating, so it can only be <i>convex</i>.</note></remarks>
        /// <param name="controlMesh">The generated <see cref="RealtimeCSG.Legacy.ControlMesh"/></param>
        /// <param name="shape">The generated <see cref="RealtimeCSG.Legacy.Shape"/></param>
        /// <param name="planes">The geometric planes of all the surfaces that define this convex shape</param>
        /// <param name="tangents">The tangents for each plane (optional)</param>
        /// <param name="binormals">The binormals for each plane (optional)</param>
        /// <param name="materials">The materials for each plane (optional)</param>
        /// <param name="textureMatrices">The texture matrices for each plane (optional)</param>
        /// <param name="textureMatrixSpace">The texture matrix space for each plane (optional)</param>
        /// <param name="smoothingGroups">The smoothing groups for each plane (optional)</param>
        /// <param name="texGenFlags">The <see cref="RealtimeCSG.Legacy.TexGenFlags"/> for each plane (optional)</param>
        /// <returns>*true* on success, *false* on failure</returns>
        public static bool CreateControlMeshFromPlanes(out ControlMesh controlMesh,
                                                       out Shape shape,
                                                       UnityEngine.Plane[]              planes,
                                                       UnityEngine.Vector3[]    tangents        = null,
                                                       UnityEngine.Vector3[]    binormals       = null,
                                                       UnityEngine.Material[]   materials       = null,
                                                       UnityEngine.Matrix4x4[]  textureMatrices = null,
                                                       TextureMatrixSpace textureMatrixSpace    = TextureMatrixSpace.WorldSpace,
                                                       uint[]                                   smoothingGroups = null,
                                                       TexGenFlags[]                    texGenFlags             = null)
        {
            controlMesh = null;
            shape       = null;
            if (planes == null)
            {
                Debug.LogError("The planes array is not allowed to be null");
                return(false);
            }
            if (planes.Length < 4)
            {
                Debug.LogError("The planes array must have at least 4 planes");
                return(false);
            }
            if (materials == null)
            {
                materials = new Material[planes.Length];
                for (int i = 0; i < materials.Length; i++)
                {
                    materials[i] = CSGSettings.DefaultMaterial;
                }
            }
            if (planes.Length != materials.Length ||
                (textureMatrices != null && planes.Length != textureMatrices.Length) ||
                (tangents != null && tangents.Length != textureMatrices.Length) ||
                (binormals != null && binormals.Length != textureMatrices.Length) ||
                (smoothingGroups != null && smoothingGroups.Length != materials.Length))
            {
                Debug.LogError("All non null arrays need to be of equal length");
                return(false);
            }

            shape             = new Shape();
            shape.TexGenFlags = new TexGenFlags[planes.Length];
            shape.Surfaces    = new Surface[planes.Length];
            shape.TexGens     = new TexGen[planes.Length];
            for (int i = 0; i < planes.Length; i++)
            {
                shape.Surfaces[i].Plane = new CSGPlane(planes[i].normal, -planes[i].distance);

                Vector3 tangent, binormal;
                if (tangents != null && binormals != null)
                {
                    tangent  = tangents[i];
                    binormal = binormals[i];
                }
                else
                {
                    GeometryUtility.CalculateTangents(planes[i].normal, out tangent, out binormal);
                }

                shape.Surfaces[i].Tangent     = -tangent;
                shape.Surfaces[i].BiNormal    = -binormal;
                shape.Surfaces[i].TexGenIndex = i;
                shape.TexGens[i] = new TexGen(materials[i]);
                if (smoothingGroups != null)
                {
                    shape.TexGens[i].SmoothingGroup = smoothingGroups[i];
                }
                if (texGenFlags != null)
                {
                    shape.TexGenFlags[i] = texGenFlags[i];
                }
                else
                {
                    shape.TexGenFlags[i] = RealtimeCSG.CSGSettings.DefaultTexGenFlags;
                }
            }

            controlMesh = ControlMeshUtility.CreateFromShape(shape, MathConstants.DistanceEpsilon);
            if (controlMesh == null)
            {
                return(false);
            }

            if (!ControlMeshUtility.Validate(controlMesh, shape))
            {
                //Debug.LogError("Generated mesh is not valid");
                return(false);
            }

            if (textureMatrices != null)
            {
                int n = 0;
                for (var i = 0; i < planes.Length; i++)
                {
                    if (shape.Surfaces[n].TexGenIndex != i)
                    {
                        continue;
                    }
                    shape.Surfaces[n].TexGenIndex = n;
                    SurfaceUtility.AlignTextureSpaces(textureMatrices[i], textureMatrixSpace == TextureMatrixSpace.PlaneSpace, ref shape.TexGens[n], ref shape.TexGenFlags[n], ref shape.Surfaces[n]);
                    n++;
                }
            }
            return(true);
        }
Exemplo n.º 4
0
        /*
         * public static bool ContinueTexGenFromSurfaceToSurface(CSGBrush srcBrush, int srcSurfaceIndex, CSGBrush dstBrush, int dstSurfaceIndex)
         * {
         *  if (srcSurfaceIndex < 0 || srcSurfaceIndex >= srcBrush.Shape.Materials.Length ||
         *      srcBrush == null)
         *      return false;
         *
         *  var src_brush_cache = CSGModelManager.GetBrushCache(srcBrush);
         *  if (src_brush_cache == null ||
         *      src_brush_cache.childData == null ||
         *      src_brush_cache.childData.modelTransform == null)
         *      return false;
         *
         *  var dst_brush_cache = CSGModelManager.GetBrushCache(dstBrush);
         *  if (dst_brush_cache == null ||
         *      dst_brush_cache.childData == null ||
         *      dst_brush_cache.childData.modelTransform == null)
         *      return false;
         *
         *  var dstPlane	= dstBrush.Shape.Surfaces[dstSurfaceIndex].Plane;
         *  var srcPlane	= srcBrush.Shape.Surfaces[srcSurfaceIndex].Plane;
         *
         *  // convert planes into worldspace
         *  dstPlane = GeometryUtility.InverseTransformPlane(dstBrush.transform.worldToLocalMatrix, dstPlane);
         *  srcPlane = GeometryUtility.InverseTransformPlane(srcBrush.transform.worldToLocalMatrix, srcPlane);
         *
         *  var dstNormal	= dstPlane.normal;
         *  var srcNormal	= srcPlane.normal;
         *
         *  var srcTexGenIndex = srcBrush.Shape.Surfaces[srcSurfaceIndex].TexGenIndex;
         *  var dstTexGenIndex = dstBrush.Shape.Surfaces[dstSurfaceIndex].TexGenIndex;
         *
         *  var scrShape = srcBrush.Shape;
         *
         *  dstBrush.Shape.Materials[dstSurfaceIndex] = scrShape.Materials[srcSurfaceIndex];
         *  Vector3 srcPoint1, srcPoint2;
         *  Vector3 dstPoint1, dstPoint2;
         *  var edgeDirection = Vector3.Cross(dstNormal, srcNormal);
         *  var det = edgeDirection.sqrMagnitude;
         *  if (det < Constants.AlignmentTestEpsilon)
         *  {
         *      // Find 2 points on intersection of 2 planes
         *      srcPoint1 = srcPlane.pointOnPlane;
         *      srcPoint2 = GeometryUtility.ProjectPointOnPlane(srcPlane, srcPoint1 + MathConstants.oneVector3);
         *
         *      dstPoint1 = GeometryUtility.ProjectPointOnPlane(dstPlane, srcPoint1);
         *      dstPoint2 = GeometryUtility.ProjectPointOnPlane(dstPlane, srcPoint2);
         *  } else
         *  {
         *      // Find 2 points on intersection of 2 planes
         *      srcPoint1 = ((Vector3.Cross(edgeDirection, srcNormal) * -dstPlane.d) +
         *                      (Vector3.Cross(dstNormal, edgeDirection) * -srcPlane.d)) / det;
         *      srcPoint2 = srcPoint1 + edgeDirection;
         *      dstPoint1 = srcPoint1;
         *      dstPoint2 = srcPoint2;
         *  }
         *
         *  Vector3 srcLocalPoint1 = srcBrush.transform.InverseTransformPoint(srcPoint1);
         *  Vector3 srcLocalPoint2 = srcBrush.transform.InverseTransformPoint(srcPoint2);
         *
         *  Vector3 dstLocalPoint1 = dstBrush.transform.InverseTransformPoint(dstPoint1);
         *  Vector3 dstLocalPoint2 = dstBrush.transform.InverseTransformPoint(dstPoint2);
         *
         *  var srcShape	= srcBrush.Shape;
         *  var srcTexGens	= srcShape.TexGens;
         *  var srcSurfaces	= srcShape.Surfaces;
         *  var dstShape	= dstBrush.Shape;
         *  var dstTexGens	= dstShape.TexGens;
         *  var dstSurfaces	= dstShape.Surfaces;
         *
         *
         *  // Reset destination shape to simplify calculations
         *  dstTexGens[dstTexGenIndex].Scale			= scrShape.TexGens[srcTexGenIndex].Scale;
         *  dstTexGens[dstTexGenIndex].Translation		= MathConstants.zeroVector2;
         *  dstTexGens[dstTexGenIndex].RotationAngle	= 0;
         *
         *  if (!CSGModelManager.AlignTextureSpacesInLocalSpace(ref srcTexGens[srcTexGenIndex], ref srcSurfaces[srcSurfaceIndex],
         *                                                      srcLocalPoint1, srcLocalPoint2,
         *                                                      ref dstTexGens[dstTexGenIndex], ref dstSurfaces[dstSurfaceIndex],
         *                                                      dstLocalPoint1, dstLocalPoint2))
         *      return false;
         *  return true;
         * }
         */

        public static bool ContinueTexGenFromSurfaceToSurface(CSGBrush brush, int srcSurfaceIndex, int dstSurfaceIndex)
        {
            if (srcSurfaceIndex < 0 || srcSurfaceIndex >= brush.Shape.TexGens.Length ||
                !brush)
            {
                return(false);
            }

            var shape       = brush.Shape;
            var texGens     = shape.TexGens;
            var texGenFlags = shape.TexGenFlags;
            var surfaces    = shape.Surfaces;

            var srcTexGenIndex = surfaces[srcSurfaceIndex].TexGenIndex;
            var dstTexGenIndex = surfaces[dstSurfaceIndex].TexGenIndex;

//          var src_is_world_space = (texGenFlags[srcTexGenIndex] & TexGenFlags.WorldSpaceTexture) != TexGenFlags.None;
//          var dst_is_world_space = (texGenFlags[dstTexGenIndex] & TexGenFlags.WorldSpaceTexture) != TexGenFlags.None;

//          if (src_is_world_space) SurfaceUtility.SetTextureLock(brush, srcSurfaceIndex, true);
//          if (dst_is_world_space) SurfaceUtility.SetTextureLock(brush, dstSurfaceIndex, true);

            var dstLocalPlane = surfaces[dstSurfaceIndex].Plane;
            var srcLocalPlane = surfaces[srcSurfaceIndex].Plane;

            CSGModel     parentModel;
            CSGOperation parentOp;

            InternalCSGModelManager.FindParentOperationAndModel(brush.transform, out parentOp, out parentModel);

            var localFromWorld = brush.transform.worldToLocalMatrix;
            var worldFromModel = parentModel.transform.localToWorldMatrix;
            var modelFromWorld = parentModel.transform.worldToLocalMatrix;
            var localFromModel = localFromWorld * worldFromModel;
            //var localToWorldMatrix = brush.transform.localToWorldMatrix;

            // convert planes into worldspace
            var dstWorldPlane = InverseTransformPlane(localFromWorld, dstLocalPlane);
            var srcWorldPlane = InverseTransformPlane(localFromWorld, srcLocalPlane);

            var dstWorldNormal = dstWorldPlane.normal;
            var srcWorldNormal = srcWorldPlane.normal;


            shape.TexGens[dstSurfaceIndex].RenderMaterial = shape.TexGens[srcSurfaceIndex].RenderMaterial;
            Vector3 srcWorldPoint1, srcWorldPoint2;
            Vector3 dstWorldPoint1, dstWorldPoint2;
            var     edgeDirection = Vector3.Cross(dstWorldNormal, srcWorldNormal);
            var     det           = edgeDirection.sqrMagnitude;

            if (det < MathConstants.AlignmentTestEpsilon)
            {
                // Find 2 points on intersection of 2 planes
                srcWorldPoint1 = srcWorldPlane.pointOnPlane;
                srcWorldPoint2 = GeometryUtility.ProjectPointOnPlane(srcWorldPlane, srcWorldPoint1 + MathConstants.oneVector3);

                dstWorldPoint1 = GeometryUtility.ProjectPointOnPlane(dstWorldPlane, srcWorldPoint1);
                dstWorldPoint2 = GeometryUtility.ProjectPointOnPlane(dstWorldPlane, srcWorldPoint2);
            }
            else
            {
                // Find 2 points on intersection of 2 planes
                srcWorldPoint1 = ((Vector3.Cross(edgeDirection, srcWorldNormal) * -dstWorldPlane.d) +
                                  (Vector3.Cross(dstWorldNormal, edgeDirection) * -srcWorldPlane.d)) / det;
                srcWorldPoint2 = srcWorldPoint1 + edgeDirection;
                dstWorldPoint1 = srcWorldPoint1;
                dstWorldPoint2 = srcWorldPoint2;
            }

            var srcModelPoint1 = modelFromWorld.MultiplyPoint(srcWorldPoint1);
            var srcModelPoint2 = modelFromWorld.MultiplyPoint(srcWorldPoint2);

            var dstModelPoint1 = modelFromWorld.MultiplyPoint(dstWorldPoint1);
            var dstModelPoint2 = modelFromWorld.MultiplyPoint(dstWorldPoint2);

            var result = SurfaceUtility.AlignTextureSpaces(localFromModel, texGens[srcTexGenIndex], texGenFlags[srcTexGenIndex], ref surfaces[srcSurfaceIndex], srcModelPoint1, srcModelPoint2,
                                                           localFromModel, ref texGens[dstTexGenIndex], texGenFlags[dstTexGenIndex], ref surfaces[dstSurfaceIndex], dstModelPoint1, dstModelPoint2, false, Vector3.one);

//          if (src_is_world_space) SurfaceUtility.SetTextureLock(brush, srcSurfaceIndex, false);
//          if (dst_is_world_space) SurfaceUtility.SetTextureLock(brush, dstSurfaceIndex, false);
            return(result);
        }