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