public static CSGBrush CreateBrushFromPlanes(GameObject gameObject, UnityEngine.Plane[] planes, Vector3[] tangents = null, Vector3[] binormals = null, Material[] materials = null, Matrix4x4[] textureMatrices = null, TextureMatrixSpace textureMatrixSpace = TextureMatrixSpace.WorldSpace, uint[] smoothingGroups = null, TexGenFlags[] texGenFlags = null) { ControlMesh controlMesh; Shape shape; if (!BrushFactory.CreateControlMeshFromPlanes(out controlMesh, out shape, planes, tangents, binormals, materials, textureMatrices, textureMatrixSpace, smoothingGroups, texGenFlags)) { return(null); } return(BrushFactory.CreateBrushComponent(gameObject, controlMesh, shape)); }
public static CSGBrush CreateBrushInstanceInScene() { #if DEMO if (CSGBindings.BrushesAvailable() <= 0) { return(null); } #endif var lastUsedModelTransform = !SelectionUtility.LastUsedModel ? null : SelectionUtility.LastUsedModel.transform; if (lastUsedModelTransform == null) { lastUsedModelTransform = CreateModelInstanceInScene().transform; } var name = UnityEditor.GameObjectUtility.GetUniqueNameForSibling(lastUsedModelTransform, "Brush"); var gameObject = new GameObject(name); var brush = gameObject.AddComponent <CSGBrush>(); gameObject.transform.SetParent(lastUsedModelTransform, true); gameObject.transform.position = new Vector3(0.5f, 0.5f, 0.5f); // this aligns it's vertices to the grid BrushFactory.CreateCubeControlMesh(out brush.ControlMesh, out brush.Shape, Vector3.one); UnityEditor.Selection.activeGameObject = gameObject; Undo.RegisterCreatedObjectUndo(gameObject, "Created brush"); InternalCSGModelManager.Refresh(); InternalCSGModelManager.UpdateMeshes(); return(brush); }
public static CSGBrush CreateBrushInstanceInScene(MenuCommand command) { var parent = GetTransformForMenu(command); var lastUsedModelTransform = !SelectionUtility.LastUsedModel ? null : SelectionUtility.LastUsedModel.transform; if (lastUsedModelTransform == null && !parent) { lastUsedModelTransform = CreateModelInstanceInScene(parent).transform; parent = lastUsedModelTransform; } else if (!parent) { parent = lastUsedModelTransform; } var name = UnityEditor.GameObjectUtility.GetUniqueNameForSibling(parent, "Brush"); var gameObject = new GameObject(name); var brush = gameObject.AddComponent <CSGBrush>(); gameObject.transform.SetParent(parent, true); gameObject.transform.position = new Vector3(0.5f, 0.5f, 0.5f); // this aligns it's vertices to the grid BrushFactory.CreateCubeControlMesh(out brush.ControlMesh, out brush.Shape, Vector3.one); UnityEditor.Selection.activeGameObject = gameObject; Undo.RegisterCreatedObjectUndo(gameObject, "Created brush"); InternalCSGModelManager.CheckForChanges(); InternalCSGModelManager.UpdateMeshes(); return(brush); }
public static CSGBrush CreateCubeBrush(Transform parent, string brushName, Vector3 size) { ControlMesh controlMesh; Shape shape; BrushFactory.CreateCubeControlMesh(out controlMesh, out shape, size); return(CreateBrush(parent, brushName, controlMesh, shape)); }
private bool GenerateStairs(CSGBrush[] stepBrushes, int totalSteps, float stepLength, float stepHeight, float stairsDepth, float stairsWidth, float stairsHeight, float extraDepth, float extraHeight) { bool success = true; for (int stepIndex = 0; stepIndex < totalSteps; stepIndex++) { var brush = stepBrushes[stepIndex]; if (!brush) { continue; } var curStepHeight = Mathf.Min(stairsHeight, (stepIndex == 0) ? (extraHeight + stepHeight) : stepHeight); var curStepY = (stepIndex == 0) ? (stepHeight * stepIndex) : (extraHeight + (stepHeight * stepIndex)); var extraLength = lengthDirection * (stepLength * stepIndex); var heightPos = heightDirection * curStepY; var widthSize = (widthDirection * stairsWidth); var lengthSize = (lengthDirection * stairsDepth) - extraLength; var heightSize = (heightDirection * curStepHeight); var size = widthSize + heightSize + lengthSize; var position = (totalSteps == 1) ? (heightPos + brushPosition) : heightPos; ControlMesh newControlMesh; Shape newShape; if (!BrushFactory.CreateCubeControlMesh(out newControlMesh, out newShape, Vector3.zero, size)) { success = false; if (brush.gameObject.activeSelf) { brush.gameObject.SetActive(false); } continue; } if (!brush.gameObject.activeSelf) { brush.gameObject.SetActive(true); } brush.Shape = newShape; brush.ControlMesh = newControlMesh; brush.transform.localPosition = position; SurfaceUtility.TranslateSurfacesInWorldSpace(brush, -position); } return(success); }
public static bool SetBrushCubeMesh(CSGBrush brush, Vector3 size) { if (!brush) { return(false); } ControlMesh controlMesh; Shape shape; BrushFactory.CreateCubeControlMesh(out controlMesh, out shape, size); brush.ControlMesh = controlMesh; brush.Shape = shape; if (brush.ControlMesh != null) { brush.ControlMesh.SetDirty(); } if (brush.Shape != null) { ShapeUtility.EnsureInitialized(brush.Shape); } return(true); }
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; }
private bool GenerateStairs(CSGBrush[] stepBrushes, int totalSteps, float stepLength, float stepHeight, float stepDepth, float stairsDepth, float stairsWidth, float stairsHeight, float extraDepth, float extraHeight, StairsBottom stairsBottom) { //var currentModel = parentModel ? parentModel : SelectionUtility.LastUsedModel; //var modelRotation = Quaternion.Inverse(currentModel.transform.rotation); stairsDepth = Math.Max(0, stairsDepth); bool success = true; for (int stepIndex = 0; stepIndex < totalSteps; stepIndex++) { var brush = stepBrushes[stepIndex]; if (!brush) { continue; } float curStepDepth; float curStepHeight; float curStepY; Vector3 extraLength; Vector3 lengthPos; switch (stairsBottom) { default: case StairsBottom.Filled: { curStepHeight = Mathf.Min(stairsHeight, (stepIndex == 0) ? (extraHeight + stepHeight) : stepHeight); curStepY = (stepIndex == 0) ? (stepHeight * stepIndex) : (extraHeight + (stepHeight * stepIndex)); extraLength = lengthDirection * (stepLength * stepIndex); curStepDepth = stairsDepth; lengthPos = Vector3.zero; break; } case StairsBottom.Steps: { curStepHeight = stepHeight; curStepY = extraHeight + (stepHeight * stepIndex); extraLength = Vector3.zero; curStepDepth = (stepIndex == totalSteps - 1) ? (stepDepth + extraDepth) : stepDepth; lengthPos = (stepIndex == totalSteps - 1) ? Vector3.zero : (lengthDirection * Mathf.Max(0, ((totalSteps - (stepIndex + 1)) * stepDepth) + extraDepth)); break; } } var heightPos = heightDirection * curStepY; var widthSize = (widthDirection * stairsWidth); var lengthSize = (lengthDirection * curStepDepth) - extraLength; var heightSize = (heightDirection * curStepHeight); var size = widthSize + heightSize + lengthSize; var position = (totalSteps == 1) ? (heightPos + lengthPos + brushPosition) : (heightPos + lengthPos); ControlMesh newControlMesh; Shape newShape; if (!BrushFactory.CreateCubeControlMesh(out newControlMesh, out newShape, Vector3.zero, size)) { success = false; if (brush.gameObject.activeSelf) { brush.gameObject.SetActive(false); } continue; } if (!brush.gameObject.activeSelf) { brush.gameObject.SetActive(true); } brush.Shape = newShape; brush.ControlMesh = newControlMesh; if (totalSteps != 1) { brush.transform.localPosition = position; } //brush.transform.localRotation = Quaternion.identity; SurfaceUtility.TranslateSurfacesInWorldSpace(brush, -position); } return(success); }