Exemplo n.º 1
0
		public void EndCommit()
        {
            if (generatedBrushes == null)
				return;
			var bounds = BoundsUtilities.GetBounds(generatedBrushes);
			if (!bounds.IsEmpty())
            {/*
                var center = bounds.Center - operationGameObject.transform.position;
				GeometryUtility.MoveControlMeshVertices(generatedBrushes, -center);
				SurfaceUtility.TranslateSurfacesInWorldSpace(generatedBrushes, -center);
                operationGameObject.transform.position += center;*/
				ControlMeshUtility.RebuildShapes(generatedBrushes);
                var models = operationGameObject.GetComponentsInParent<CSGModel>(includeInactive: true);
                var model = models.Length == 0 ? null : models[0];
                model.forceUpdate = true;

                InternalCSGModelManager.CheckForChanges(forceHierarchyUpdate: true);
				Undo.CollapseUndoOperations(undoGroupIndex);
				Cleanup();

				if (generatedGameObjects != null &&
					generatedGameObjects.Length > 0) 
					Selection.objects = generatedGameObjects;

				Reset();
			}

			if (shapeCommitted != null)
				shapeCommitted();
		}
Exemplo n.º 2
0
        public void UpdateTargets()
        {
            for (var i = 0; i < Brushes.Length; i++)
            {
                if (!Brushes[i] ||
                    Brushes[i].ControlMesh == null)
                {
                    continue;
                }

                if (!Brushes[i].ControlMesh.Valid)
                {
                    Brushes[i].ControlMesh.Valid = ControlMeshUtility.Validate(Brushes[i].ControlMesh, Brushes[i].Shape);
                }

                LocalToWorld[i] = Brushes[i].transform.localToWorldMatrix;

                if (States[i] != null)
                {
                    continue;
                }

                States[i] = new ControlMeshState(Brushes[i]);
                BackupControlMeshes[i] = (Brushes[i].ControlMesh != null) ? Brushes[i].ControlMesh.Clone() : null;
                BackupShapes[i]        = (Brushes[i].Shape != null) ? Brushes[i].Shape.Clone() : null;

                ControlMeshes[i] = BackupControlMeshes[i];
                Shapes[i]        = BackupShapes[i];
            }
            UpdateParentModelTransforms();
        }
Exemplo n.º 3
0
        public void EndCommit()
        {
            if (generatedBrushes == null)
            {
                return;
            }
            var bounds = BoundsUtilities.GetBounds(generatedBrushes);

            if (!bounds.IsEmpty())
            {
                var center = bounds.Center - operationGameObject.transform.position;
                GeometryUtility.MoveControlMeshVertices(generatedBrushes, -center);
                SurfaceUtility.TranslateSurfacesInWorldSpace(generatedBrushes, -center);
                ControlMeshUtility.RebuildShapes(generatedBrushes);
                InternalCSGModelManager.Refresh(forceHierarchyUpdate: true);

                operationGameObject.transform.position += center;

                Undo.CollapseUndoOperations(undoGroupIndex);
                Cleanup();

                if (generatedGameObjects != null &&
                    generatedGameObjects.Length > 0)
                {
                    Selection.objects = generatedGameObjects;
                }

                Reset();
            }

            if (shapeCommitted != null)
            {
                shapeCommitted();
            }
        }
Exemplo n.º 4
0
        internal override bool CreateControlMeshForBrushIndex(CSGModel parentModel, CSGBrush brush, ShapePolygon polygon, Matrix4x4 localToWorld, float height, out ControlMesh newControlMesh, out Shape newShape)
        {
            var direction = haveForcedDirection ? forcedDirection : buildPlane.normal;

            if (!ShapePolygonUtility.GenerateControlMeshFromVertices(polygon,
                                                                     localToWorld,
                                                                     GeometryUtility.RotatePointIntoPlaneSpace(buildPlane, direction),
                                                                     height,

                                                                     new TexGen(),

                                                                     false,
                                                                     true,
                                                                     out newControlMesh,
                                                                     out newShape))
            {
                return(false);
            }

            brush.Shape       = newShape;
            brush.ControlMesh = newControlMesh;
            InternalCSGModelManager.ValidateBrush(brush, true);
            ControlMeshUtility.RebuildShape(brush);
            return(true);
        }
Exemplo n.º 5
0
        public static void TransformControlPoints(this BrushSelection selection, Matrix4x4 transform)
        {
            for (var t = 0; t < selection.Brushes.Length; t++)
            {
                var targetControlMesh = selection.BackupControlMeshes[t].Clone();
                if (!targetControlMesh.Valid)
                {
                    targetControlMesh.Valid = ControlMeshUtility.Validate(targetControlMesh, selection.Shapes[t]);
                }

                if (!targetControlMesh.Valid)
                {
                    continue;
                }

                var targetBrush     = selection.Brushes[t];
                var targetMeshState = selection.States[t];

                if (targetMeshState.BackupPoints == null)
                {
                    continue;
                }

                var targetShape        = selection.Shapes[t].Clone();
                var localToWorldMatrix = targetMeshState.BrushTransform.localToWorldMatrix;
                var worldToLocalMatrix = targetMeshState.BrushTransform.worldToLocalMatrix;

                var localCombinedMatrix = worldToLocalMatrix *
                                          transform *
                                          localToWorldMatrix;

                var selectedIndices = targetMeshState.GetSelectedPointIndices();

                for (var p = 0; p < targetMeshState.BackupPoints.Length; p++)
                {
                    if (!selectedIndices.Contains((short)p))
                    {
                        continue;
                    }

                    var point = targetMeshState.BackupPoints[p];

                    point = localCombinedMatrix.MultiplyPoint(point);

                    targetControlMesh.Vertices[p] = GridUtility.CleanPosition(point);
                }

                selection.ControlMeshes[t] = targetControlMesh;

                // This might create new controlmesh / shape
                ControlMeshUtility.MergeDuplicatePoints(targetBrush, ref targetControlMesh, ref targetShape);
                if (targetControlMesh.Valid)
                {
                    targetControlMesh.SetDirty();
                    ControlMeshUtility.RebuildShapeFrom(targetBrush, targetControlMesh, targetShape);
                }
            }
        }
Exemplo n.º 6
0
        public static void TranslatePivot(CSGBrush[] brushes, Vector3 offset)
        {
            if (brushes == null ||
                brushes.Length == 0 ||
                offset.sqrMagnitude < MathConstants.ConsideredZero)
            {
                return;
            }

            for (int i = 0; i < brushes.Length; i++)
            {
                brushes[i].transform.position += offset;
            }

            GeometryUtility.MoveControlMeshVertices(brushes, -offset);
            SurfaceUtility.TranslateSurfacesInWorldSpace(brushes, -offset);
            ControlMeshUtility.RebuildShapes(brushes);
        }
Exemplo n.º 7
0
        public static void TranslateControlPoints(this BrushSelection selection, Vector3 translation)
        {
            for (var t = 0; t < selection.Brushes.Length; t++)
            {
                var targetControlMesh = selection.BackupControlMeshes[t].Clone();

                if (!targetControlMesh.Valid)
                {
                    targetControlMesh.Valid = ControlMeshUtility.Validate(targetControlMesh, selection.Shapes[t]);
                }

                if (!targetControlMesh.Valid)
                {
                    continue;
                }

                var targetBrush     = selection.Brushes[t];
                var targetMeshState = selection.States[t];

                if (targetMeshState.BackupPoints == null)
                {
                    continue;
                }

                var targetShape        = selection.Shapes[t].Clone();
                var worldToLocalMatrix = targetMeshState.BrushTransform.worldToLocalMatrix;
                var localDeltaMovement = GridUtility.CleanPosition(worldToLocalMatrix.MultiplyVector(translation));

                var selectedIndices = targetMeshState.GetSelectedPointIndices();

                for (var p = 0; p < targetMeshState.WorldPoints.Length; p++)
                {
                    if (!selectedIndices.Contains((short)p))
                    {
                        continue;
                    }

                    targetControlMesh.Vertices[p] = GridUtility.CleanPosition(targetMeshState.BackupPoints[p] + localDeltaMovement);
                }

                ControlMeshUtility.RebuildShapeFrom(targetBrush, targetControlMesh, targetShape);
                selection.ControlMeshes[t] = targetControlMesh;
            }
        }
Exemplo n.º 8
0
        public static void SetPivot(CSGBrush brush, Vector3 newCenter)
        {
            if (!brush)
            {
                return;
            }

            var transform  = brush.transform;
            var realCenter = transform.position;
            var difference = newCenter - realCenter;

            if (difference.sqrMagnitude < MathConstants.ConsideredZero)
            {
                return;
            }

            transform.position += difference;

            GeometryUtility.MoveControlMeshVertices(brush, -difference);
            SurfaceUtility.TranslateSurfacesInWorldSpace(brush, -difference);
            ControlMeshUtility.RebuildShape(brush);
        }
        public static void CheckTransformChanged(bool checkAllBrushes = false)
        {
            if (External == null)
            {
                return;
            }

            for (int i = 0; i < Operations.Count; i++)
            {
                var operation = Operations[i];
                if (!Operations[i])
                {
                    continue;
                }

                if ((int)operation.PrevOperation == (int)operation.OperationType)
                {
                    continue;
                }

                operation.PrevOperation = operation.OperationType;
                External.SetOperationOperationType(operation.operationNodeID,
                                                   operation.OperationType);
            }

            for (int i = 0; i < Models.Length; i++)
            {
                var model = Models[i];
                if (!model || !model.gameObject.activeInHierarchy)
                {
                    continue;
                }

                if (!model.cachedTransform)
                {
                    model.cachedTransform = model.transform;
                }
            }

            for (int brushIndex = 0; brushIndex < Brushes.Count; brushIndex++)
            {
                var brush = Brushes[brushIndex];
                if (System.Object.ReferenceEquals(brush, null) || !brush)
                {
                    continue;
                }

                var brushNodeID = brush.brushNodeID;
                // make sure it's registered, otherwise ignore it
                if (brushNodeID == CSGNode.InvalidNodeID)
                {
                    continue;
                }

                var brushTransform            = brush.hierarchyItem.Transform;
                var currentLocalToWorldMatrix = brushTransform.localToWorldMatrix;
                var prevTransformMatrix       = brush.compareTransformation.localToWorldMatrix;
                if (prevTransformMatrix.m00 != currentLocalToWorldMatrix.m00 ||
                    prevTransformMatrix.m01 != currentLocalToWorldMatrix.m01 ||
                    prevTransformMatrix.m02 != currentLocalToWorldMatrix.m02 ||
                    prevTransformMatrix.m03 != currentLocalToWorldMatrix.m03 ||

                    prevTransformMatrix.m10 != currentLocalToWorldMatrix.m10 ||
                    prevTransformMatrix.m11 != currentLocalToWorldMatrix.m11 ||
                    prevTransformMatrix.m12 != currentLocalToWorldMatrix.m12 ||
                    prevTransformMatrix.m13 != currentLocalToWorldMatrix.m13 ||

                    prevTransformMatrix.m20 != currentLocalToWorldMatrix.m20 ||
                    prevTransformMatrix.m21 != currentLocalToWorldMatrix.m21 ||
                    prevTransformMatrix.m22 != currentLocalToWorldMatrix.m22 ||
                    prevTransformMatrix.m23 != currentLocalToWorldMatrix.m23)
                {
                    var modelTransform = brush.ChildData.Model.transform;
                    brush.compareTransformation.localToWorldMatrix      = currentLocalToWorldMatrix;
                    brush.compareTransformation.brushToModelSpaceMatrix = modelTransform.worldToLocalMatrix *
                                                                          brush.compareTransformation.localToWorldMatrix;

                    var localToModelMatrix = brush.compareTransformation.brushToModelSpaceMatrix;
                    External.SetBrushToModelSpace(brushNodeID, localToModelMatrix);

                    if (brush.ControlMesh != null)
                    {
                        brush.ControlMesh.Generation = brush.controlMeshGeneration + 1;
                    }
                }

                if (brush.OperationType != brush.prevOperation)
                {
                    brush.prevOperation = brush.OperationType;

                    External.SetBrushOperationType(brushNodeID,
                                                   brush.OperationType);
                }

                if (brush.ControlMesh == null)
                {
                    brush.ControlMesh = ControlMeshUtility.EnsureValidControlMesh(brush);
                    if (brush.ControlMesh == null)
                    {
                        continue;
                    }

                    brush.controlMeshGeneration = brush.ControlMesh.Generation;
                    ControlMeshUtility.RebuildShape(brush);
                }
                else
                if (brush.controlMeshGeneration != brush.ControlMesh.Generation)
                {
                    brush.controlMeshGeneration = brush.ControlMesh.Generation;
                    ControlMeshUtility.RebuildShape(brush);
                }
            }
        }
Exemplo n.º 10
0
        public static void Flip(CSGBrush[] brushes, Matrix4x4 flipMatrix, string undoDescription = "Flip brushes")
        {
            var fail = false;

            Undo.IncrementCurrentGroup();
            Undo.RegisterCompleteObjectUndo(brushes.ToArray <UnityEngine.Object>(), undoDescription);

            var isGlobal = Tools.pivotRotation == PivotRotation.Global;

            var centerAll = BoundsUtilities.GetCenter(brushes);

            for (var t = 0; t < brushes.Length; t++)
            {
                var brush    = brushes[t];
                var position = brush.transform.position;

                Matrix4x4 brushFlip;
                Vector3   brushCenter;
                if (isGlobal)
                {
                    brushFlip = brush.transform.localToWorldMatrix *
                                flipMatrix *
                                brush.transform.worldToLocalMatrix;
                    brushCenter = brush.transform.InverseTransformPoint(centerAll) - position;
                }
                else
                {
                    brushFlip   = flipMatrix;
                    brushCenter = brush.transform.InverseTransformPoint(centerAll);
                }

                brushFlip = Matrix4x4.TRS(brushCenter, Quaternion.identity, Vector3.one) *
                            brushFlip *
                            Matrix4x4.TRS(-brushCenter, Quaternion.identity, Vector3.one);

                brush.EnsureInitialized();
                var shape = brush.Shape;
                for (var s = 0; s < shape.Surfaces.Length; s++)
                {
                    var plane = shape.Surfaces[s].Plane;

                    var normal   = brushFlip.MultiplyVector(plane.normal);
                    var biNormal = brushFlip.MultiplyVector(shape.Surfaces[s].BiNormal);
                    var tangent  = brushFlip.MultiplyVector(shape.Surfaces[s].Tangent);

                    var pointOnPlane = plane.pointOnPlane;
                    pointOnPlane = brushFlip.MultiplyPoint(pointOnPlane);

                    shape.Surfaces[s].Plane    = new CSGPlane(normal, pointOnPlane);
                    shape.Surfaces[s].BiNormal = biNormal;
                    shape.Surfaces[s].Tangent  = tangent;
                }

                var controlMesh = brush.ControlMesh;
                var vertices    = controlMesh.Vertices;
                for (var v = 0; v < vertices.Length; v++)
                {
                    vertices[v] = brushFlip.MultiplyPoint(vertices[v]);
                }

                var polygons = controlMesh.Polygons;
                for (var p = 0; p < polygons.Length; p++)
                {
                    Array.Reverse(polygons[p].EdgeIndices);
                }

                var edges        = controlMesh.Edges;
                var twinVertices = new short[edges.Length];
                for (var e = 0; e < edges.Length; e++)
                {
                    twinVertices[e] = edges[edges[e].TwinIndex].VertexIndex;
                }

                for (var e = 0; e < edges.Length; e++)
                {
                    edges[e].VertexIndex = twinVertices[e];
                }

                brush.ControlMesh.SetDirty();
                EditorUtility.SetDirty(brush);

                InternalCSGModelManager.CheckSurfaceModifications(brush, true);

                ControlMeshUtility.RebuildShape(brush);
            }
            if (fail)
            {
                Debug.LogWarning("Failed to perform operation");
                Undo.RevertAllInCurrentGroup();
            }
            InternalCSGModelManager.Refresh();
        }
Exemplo n.º 11
0
        internal static void CreateCubeControlMesh(out ControlMesh controlMesh, out Shape shape, Vector3 size)
        {
            size                *= 0.5f;
            controlMesh          = new ControlMesh();
            controlMesh.Vertices = new Vector3[]
            {
                new Vector3(-size.x, -size.y, -size.z),
                new Vector3(-size.x, size.y, -size.z),
                new Vector3(size.x, size.y, -size.z),
                new Vector3(size.x, -size.y, -size.z),

                new Vector3(-size.x, -size.y, size.z),
                new Vector3(-size.x, size.y, size.z),
                new Vector3(size.x, size.y, size.z),
                new Vector3(size.x, -size.y, size.z)
            };

            controlMesh.Edges = new HalfEdge[]
            {
                new HalfEdge(0, 21, 0, true),                   //  0
                new HalfEdge(0, 9, 1, true),                    //  1
                new HalfEdge(0, 13, 2, true),                   //  2
                new HalfEdge(0, 17, 3, true),                   //  3

                new HalfEdge(1, 23, 7, true),                   //  4
                new HalfEdge(1, 19, 6, true),                   //  5
                new HalfEdge(1, 15, 5, true),                   //  6
                new HalfEdge(1, 11, 4, true),                   //  7

                new HalfEdge(2, 14, 1, true),                   //  8
                new HalfEdge(2, 1, 0, true),                    //  9
                new HalfEdge(2, 20, 4, true),                   // 10
                new HalfEdge(2, 7, 5, true),                    // 11

                new HalfEdge(3, 18, 2, true),                   // 12
                new HalfEdge(3, 2, 1, true),                    // 13
                new HalfEdge(3, 8, 5, true),                    // 14
                new HalfEdge(3, 6, 6, true),                    // 15

                new HalfEdge(4, 22, 3, true),                   // 16
                new HalfEdge(4, 3, 2, true),                    // 17
                new HalfEdge(4, 12, 6, true),                   // 18
                new HalfEdge(4, 5, 7, true),                    // 19

                new HalfEdge(5, 10, 0, true),                   // 20
                new HalfEdge(5, 0, 3, true),                    // 21
                new HalfEdge(5, 16, 7, true),                   // 22
                new HalfEdge(5, 4, 4, true)                     // 23
            };

            controlMesh.Polygons = new Polygon[]
            {
                // left/right
                new Polygon(new int[] { 0, 1, 2, 3 }, 0),                       // 0
                new Polygon(new int[] { 7, 4, 5, 6 }, 1),                       // 1

                // front/back
                new Polygon(new int[] { 9, 10, 11, 8 }, 2),                     // 2
                new Polygon(new int[] { 13, 14, 15, 12 }, 3),                   // 3

                // top/down
                new Polygon(new int[] { 16, 17, 18, 19 }, 4),                   // 4
                new Polygon(new int[] { 20, 21, 22, 23 }, 5)                    // 5
            };

            shape = new Shape();

            shape.Surfaces = new Surface[6];
            shape.Surfaces[0].TexGenIndex = 0;
            shape.Surfaces[1].TexGenIndex = 1;
            shape.Surfaces[2].TexGenIndex = 2;
            shape.Surfaces[3].TexGenIndex = 3;
            shape.Surfaces[4].TexGenIndex = 4;
            shape.Surfaces[5].TexGenIndex = 5;

            shape.Surfaces[0].Plane = GeometryUtility.CalcPolygonPlane(controlMesh, 0);
            shape.Surfaces[1].Plane = GeometryUtility.CalcPolygonPlane(controlMesh, 1);
            shape.Surfaces[2].Plane = GeometryUtility.CalcPolygonPlane(controlMesh, 2);
            shape.Surfaces[3].Plane = GeometryUtility.CalcPolygonPlane(controlMesh, 3);
            shape.Surfaces[4].Plane = GeometryUtility.CalcPolygonPlane(controlMesh, 4);
            shape.Surfaces[5].Plane = GeometryUtility.CalcPolygonPlane(controlMesh, 5);

            GeometryUtility.CalculateTangents(shape.Surfaces[0].Plane.normal, out shape.Surfaces[0].Tangent, out shape.Surfaces[0].BiNormal);
            GeometryUtility.CalculateTangents(shape.Surfaces[1].Plane.normal, out shape.Surfaces[1].Tangent, out shape.Surfaces[1].BiNormal);
            GeometryUtility.CalculateTangents(shape.Surfaces[2].Plane.normal, out shape.Surfaces[2].Tangent, out shape.Surfaces[2].BiNormal);
            GeometryUtility.CalculateTangents(shape.Surfaces[3].Plane.normal, out shape.Surfaces[3].Tangent, out shape.Surfaces[3].BiNormal);
            GeometryUtility.CalculateTangents(shape.Surfaces[4].Plane.normal, out shape.Surfaces[4].Tangent, out shape.Surfaces[4].BiNormal);
            GeometryUtility.CalculateTangents(shape.Surfaces[5].Plane.normal, out shape.Surfaces[5].Tangent, out shape.Surfaces[5].BiNormal);

            shape.TexGens          = new TexGen[6];
            shape.TexGens[0].Scale = MathConstants.oneVector3;
            shape.TexGens[1].Scale = MathConstants.oneVector3;
            shape.TexGens[2].Scale = MathConstants.oneVector3;
            shape.TexGens[3].Scale = MathConstants.oneVector3;
            shape.TexGens[4].Scale = MathConstants.oneVector3;
            shape.TexGens[5].Scale = MathConstants.oneVector3;


            shape.TexGens[0].Color = Color.white;
            shape.TexGens[1].Color = Color.white;
            shape.TexGens[2].Color = Color.white;
            shape.TexGens[3].Color = Color.white;
            shape.TexGens[4].Color = Color.white;
            shape.TexGens[5].Color = Color.white;


            shape.TexGenFlags    = new TexGenFlags[6];
            shape.TexGenFlags[0] = TexGenFlags.None;
            shape.TexGenFlags[1] = TexGenFlags.None;
            shape.TexGenFlags[2] = TexGenFlags.None;
            shape.TexGenFlags[3] = TexGenFlags.None;
            shape.TexGenFlags[4] = TexGenFlags.None;
            shape.TexGenFlags[5] = TexGenFlags.None;

            shape.Materials    = new Material[6];
            shape.Materials[0] = CSGSettings.DefaultMaterial;
            shape.Materials[1] = CSGSettings.DefaultMaterial;
            shape.Materials[2] = CSGSettings.DefaultMaterial;
            shape.Materials[3] = CSGSettings.DefaultMaterial;
            shape.Materials[4] = CSGSettings.DefaultMaterial;
            shape.Materials[5] = CSGSettings.DefaultMaterial;

            //controlMesh.Validate();
            ShapeUtility.CreateCutter(shape, controlMesh);
            ShapeUtility.EnsureInitialized(shape);
            controlMesh.IsValid = ControlMeshUtility.Validate(controlMesh, shape);
        }
Exemplo n.º 12
0
        internal override bool UpdateBaseShape(bool registerUndo = true)
		{
			if (settings.vertices == null ||
				settings.vertices.Length == 0)
				editMode = EditMode.CreatePlane;

			if (editMode == EditMode.CreatePlane)
				return false;

			float radius = SphereRadius;
			if (editMode == EditMode.CreateShape)
			{
				brushPosition = settings.vertices[0];
				//extrusionPoints[0].Vertex = settings.vertices[0];
				radius = (settings.vertices[0] - worldPosition).magnitude;
			}

            GenerateBrushObjects(1);
			
            if (radius == 0 || generatedBrushes == null || generatedBrushes.Length < 1)
			{
				InternalCSGModelManager.skipCheckForChanges = false;
                HideGenerateBrushes();
                return false;
            }
			
            //UpdateBrushOperation(height);

            bool failures = false;
            bool modifiedHierarchy = false;
            if (generatedGameObjects != null && generatedGameObjects.Length > 0)
            {
                for (int i = generatedGameObjects.Length - 1; i >= 0; i--)
                {
                    if (generatedGameObjects[i])
                        continue;
                    ArrayUtility.RemoveAt(ref generatedGameObjects, i);
                }
            }
            if (generatedGameObjects == null || generatedGameObjects.Length == 0)
            {
                Cancel();
                return false;
            }
            if (generatedGameObjects != null && generatedGameObjects.Length > 0)
            {
                if (registerUndo)
                    Undo.RecordObjects(generatedGameObjects, "Created Sphere");
                
                var brush = generatedBrushes[0];
                if (brush && brush.gameObject)
                {
                    ControlMesh newControlMesh;
                    Shape newShape;
                    if (GenerateSphere(radius, settings.sphereSplits, parentModel, brush, out newControlMesh, out newShape))
                    {
                        if (!brush.gameObject.activeSelf)
                        {
                            modifiedHierarchy = true;
                            brush.gameObject.SetActive(true);
                        }
						
						brush.Shape = newShape;
						brush.ControlMesh = newControlMesh;
						if (registerUndo)
							EditorUtility.SetDirty(brush);
						ControlMeshUtility.UpdateBrushMesh(brush, brush.ControlMesh, brush.Shape);
                    } else
                    {
                        failures = true;
                        if (brush.gameObject.activeSelf)
                        {
                            modifiedHierarchy = true;
                            brush.gameObject.SetActive(false);
                        }
                    }
                }
            }

            try
            {
                InternalCSGModelManager.skipCheckForChanges = true;
                if (registerUndo)
                    EditorUtility.SetDirty(this);
                //CSGModelManager.External.SetDirty(parentModel.modelNodeID); 
                InternalCSGModelManager.CheckForChanges(forceHierarchyUpdate: modifiedHierarchy);
            }
            finally
            {
                InternalCSGModelManager.skipCheckForChanges = false;
            }
            return !failures;
		}
        internal static bool CreateCubeControlMesh(out ControlMesh controlMesh, out Shape shape, UnityEngine.Vector3 min, UnityEngine.Vector3 max, UnityEngine.Material material = null)
        {
            if (min.x > max.x)
            {
                float x = min.x; min.x = max.x; max.x = x;
            }
            if (min.y > max.y)
            {
                float y = min.y; min.y = max.y; max.y = y;
            }
            if (min.z > max.z)
            {
                float z = min.z; min.z = max.z; max.z = z;
            }

            if (min.x == max.x || min.y == max.y || min.z == max.z)
            {
                shape       = null;
                controlMesh = null;
                return(false);
            }

            controlMesh          = new ControlMesh();
            controlMesh.Vertices = new []
            {
                new Vector3(min.x, min.y, min.z),       // 0
                new Vector3(min.x, max.y, min.z),       // 1
                new Vector3(max.x, max.y, min.z),       // 2
                new Vector3(max.x, min.y, min.z),       // 3

                new Vector3(min.x, min.y, max.z),       // 4
                new Vector3(max.x, min.y, max.z),       // 5
                new Vector3(max.x, max.y, max.z),       // 6
                new Vector3(min.x, max.y, max.z)        // 7
            };

            controlMesh.Edges = new []
            {
                new HalfEdge {
                    PolygonIndex = 0, TwinIndex = 21, VertexIndex = 0
                },                                                                      //  0
                new HalfEdge {
                    PolygonIndex = 0, TwinIndex = 8, VertexIndex = 1
                },                                                                      //  1
                new HalfEdge {
                    PolygonIndex = 0, TwinIndex = 12, VertexIndex = 2
                },                                                                      //  2
                new HalfEdge {
                    PolygonIndex = 0, TwinIndex = 17, VertexIndex = 3
                },                                                                      //  3

                new HalfEdge {
                    PolygonIndex = 1, TwinIndex = 10, VertexIndex = 4
                },                                                                      //  4
                new HalfEdge {
                    PolygonIndex = 1, TwinIndex = 23, VertexIndex = 5
                },                                                                      //  5
                new HalfEdge {
                    PolygonIndex = 1, TwinIndex = 19, VertexIndex = 6
                },                                                                      //  6
                new HalfEdge {
                    PolygonIndex = 1, TwinIndex = 14, VertexIndex = 7
                },                                                                      //  7

                new HalfEdge {
                    PolygonIndex = 2, TwinIndex = 1, VertexIndex = 0
                },                                                                      //  8
                new HalfEdge {
                    PolygonIndex = 2, TwinIndex = 20, VertexIndex = 4
                },                                                                      //  9
                new HalfEdge {
                    PolygonIndex = 2, TwinIndex = 4, VertexIndex = 7
                },                                                                      // 10
                new HalfEdge {
                    PolygonIndex = 2, TwinIndex = 13, VertexIndex = 1
                },                                                                      // 11

                new HalfEdge {
                    PolygonIndex = 3, TwinIndex = 2, VertexIndex = 1
                },                                                                      // 12
                new HalfEdge {
                    PolygonIndex = 3, TwinIndex = 11, VertexIndex = 7
                },                                                                      // 13
                new HalfEdge {
                    PolygonIndex = 3, TwinIndex = 7, VertexIndex = 6
                },                                                                      // 14
                new HalfEdge {
                    PolygonIndex = 3, TwinIndex = 18, VertexIndex = 2
                },                                                                      // 15

                new HalfEdge {
                    PolygonIndex = 4, TwinIndex = 22, VertexIndex = 3
                },                                                                      // 16
                new HalfEdge {
                    PolygonIndex = 4, TwinIndex = 3, VertexIndex = 2
                },                                                                      // 17
                new HalfEdge {
                    PolygonIndex = 4, TwinIndex = 15, VertexIndex = 6
                },                                                                      // 18
                new HalfEdge {
                    PolygonIndex = 4, TwinIndex = 6, VertexIndex = 5
                },                                                                      // 19

                new HalfEdge {
                    PolygonIndex = 5, TwinIndex = 9, VertexIndex = 0
                },                                                                      // 20
                new HalfEdge {
                    PolygonIndex = 5, TwinIndex = 0, VertexIndex = 3
                },                                                                      // 21
                new HalfEdge {
                    PolygonIndex = 5, TwinIndex = 16, VertexIndex = 5
                },                                                                      // 22
                new HalfEdge {
                    PolygonIndex = 5, TwinIndex = 5, VertexIndex = 4
                }                                                                       // 23
            };

            controlMesh.Polygons = new []
            {
                // left/right
                new Polygon(new int[] { 0, 1, 2, 3 }, 0),       // 0
                new Polygon(new int[] { 4, 5, 6, 7 }, 1),       // 1

                // front/back
                new Polygon(new int[] { 8, 9, 10, 11 }, 2),     // 2
                new Polygon(new int[] { 12, 13, 14, 15 }, 3),   // 3

                // top/down
                new Polygon(new int[] { 16, 17, 18, 19 }, 4),   // 4
                new Polygon(new int[] { 20, 21, 22, 23 }, 5)    // 5
            };

            shape = new Shape();

            shape.Surfaces = new Surface[6];
            shape.Surfaces[0].TexGenIndex = 0;
            shape.Surfaces[1].TexGenIndex = 1;
            shape.Surfaces[2].TexGenIndex = 2;
            shape.Surfaces[3].TexGenIndex = 3;
            shape.Surfaces[4].TexGenIndex = 4;
            shape.Surfaces[5].TexGenIndex = 5;

            shape.Surfaces[0].Plane = GeometryUtility.CalcPolygonPlane(controlMesh, 0);
            shape.Surfaces[1].Plane = GeometryUtility.CalcPolygonPlane(controlMesh, 1);
            shape.Surfaces[2].Plane = GeometryUtility.CalcPolygonPlane(controlMesh, 2);
            shape.Surfaces[3].Plane = GeometryUtility.CalcPolygonPlane(controlMesh, 3);
            shape.Surfaces[4].Plane = GeometryUtility.CalcPolygonPlane(controlMesh, 4);
            shape.Surfaces[5].Plane = GeometryUtility.CalcPolygonPlane(controlMesh, 5);

            GeometryUtility.CalculateTangents(shape.Surfaces[0].Plane.normal, out shape.Surfaces[0].Tangent, out shape.Surfaces[0].BiNormal);
            GeometryUtility.CalculateTangents(shape.Surfaces[1].Plane.normal, out shape.Surfaces[1].Tangent, out shape.Surfaces[1].BiNormal);
            GeometryUtility.CalculateTangents(shape.Surfaces[2].Plane.normal, out shape.Surfaces[2].Tangent, out shape.Surfaces[2].BiNormal);
            GeometryUtility.CalculateTangents(shape.Surfaces[3].Plane.normal, out shape.Surfaces[3].Tangent, out shape.Surfaces[3].BiNormal);
            GeometryUtility.CalculateTangents(shape.Surfaces[4].Plane.normal, out shape.Surfaces[4].Tangent, out shape.Surfaces[4].BiNormal);
            GeometryUtility.CalculateTangents(shape.Surfaces[5].Plane.normal, out shape.Surfaces[5].Tangent, out shape.Surfaces[5].BiNormal);

            if (material == null)
            {
                material = CSGSettings.DefaultMaterial;
            }

            shape.TexGens = new TexGen[6];

            shape.TexGens[0].RenderMaterial = material;
            shape.TexGens[1].RenderMaterial = material;
            shape.TexGens[2].RenderMaterial = material;
            shape.TexGens[3].RenderMaterial = material;
            shape.TexGens[4].RenderMaterial = material;
            shape.TexGens[5].RenderMaterial = material;

            shape.TexGens[0].Scale = MathConstants.oneVector3;
            shape.TexGens[1].Scale = MathConstants.oneVector3;
            shape.TexGens[2].Scale = MathConstants.oneVector3;
            shape.TexGens[3].Scale = MathConstants.oneVector3;
            shape.TexGens[4].Scale = MathConstants.oneVector3;
            shape.TexGens[5].Scale = MathConstants.oneVector3;


            //			shape.TexGens[0].Color = Color.white;
            //			shape.TexGens[1].Color = Color.white;
            //			shape.TexGens[2].Color = Color.white;
            //			shape.TexGens[3].Color = Color.white;
            //			shape.TexGens[4].Color = Color.white;
            //			shape.TexGens[5].Color = Color.white;

            shape.TexGenFlags = new []
            {
                RealtimeCSG.CSGSettings.DefaultTexGenFlags,
                RealtimeCSG.CSGSettings.DefaultTexGenFlags,
                RealtimeCSG.CSGSettings.DefaultTexGenFlags,
                RealtimeCSG.CSGSettings.DefaultTexGenFlags,
                RealtimeCSG.CSGSettings.DefaultTexGenFlags,
                RealtimeCSG.CSGSettings.DefaultTexGenFlags
            };

            //controlMesh.Validate();
            ShapeUtility.EnsureInitialized(shape);
            controlMesh.Valid = ControlMeshUtility.Validate(controlMesh, shape);

            return(controlMesh.Valid);
        }
Exemplo n.º 14
0
        internal static bool CreateCubeControlMesh(out ControlMesh controlMesh, out Shape shape, Vector3 min, Vector3 max)
        {
            if (min.x > max.x)
            {
                float x = min.x; min.x = max.x; max.x = x;
            }
            if (min.y > max.y)
            {
                float y = min.y; min.y = max.y; max.y = y;
            }
            if (min.z > max.z)
            {
                float z = min.z; min.z = max.z; max.z = z;
            }

            if (min.x == max.x || min.y == max.y || min.z == max.z)
            {
                shape       = null;
                controlMesh = null;
                return(false);
            }

            controlMesh          = new ControlMesh();
            controlMesh.Vertices = new Vector3[]
            {
                new Vector3(min.x, min.y, min.z),
                new Vector3(min.x, max.y, min.z),
                new Vector3(max.x, max.y, min.z),
                new Vector3(max.x, min.y, min.z),

                new Vector3(min.x, min.y, max.z),
                new Vector3(min.x, max.y, max.z),
                new Vector3(max.x, max.y, max.z),
                new Vector3(max.x, min.y, max.z)
            };

            controlMesh.Edges = new HalfEdge[]
            {
                new HalfEdge(0, 21, 0, true),                   //  0
                new HalfEdge(0, 9, 1, true),                    //  1
                new HalfEdge(0, 13, 2, true),                   //  2
                new HalfEdge(0, 17, 3, true),                   //  3

                new HalfEdge(1, 23, 7, true),                   //  4
                new HalfEdge(1, 19, 6, true),                   //  5
                new HalfEdge(1, 15, 5, true),                   //  6
                new HalfEdge(1, 11, 4, true),                   //  7

                new HalfEdge(2, 14, 1, true),                   //  8
                new HalfEdge(2, 1, 0, true),                    //  9
                new HalfEdge(2, 20, 4, true),                   // 10
                new HalfEdge(2, 7, 5, true),                    // 11

                new HalfEdge(3, 18, 2, true),                   // 12
                new HalfEdge(3, 2, 1, true),                    // 13
                new HalfEdge(3, 8, 5, true),                    // 14
                new HalfEdge(3, 6, 6, true),                    // 15

                new HalfEdge(4, 22, 3, true),                   // 16
                new HalfEdge(4, 3, 2, true),                    // 17
                new HalfEdge(4, 12, 6, true),                   // 18
                new HalfEdge(4, 5, 7, true),                    // 19

                new HalfEdge(5, 10, 0, true),                   // 20
                new HalfEdge(5, 0, 3, true),                    // 21
                new HalfEdge(5, 16, 7, true),                   // 22
                new HalfEdge(5, 4, 4, true)                     // 23
            };

            controlMesh.Polygons = new Polygon[]
            {
                // left/right
                new Polygon(new int[] { 0, 1, 2, 3 }, 0),                       // 0
                new Polygon(new int[] { 7, 4, 5, 6 }, 1),                       // 1

                // front/back
                new Polygon(new int[] { 9, 10, 11, 8 }, 2),                     // 2
                new Polygon(new int[] { 13, 14, 15, 12 }, 3),                   // 3

                // top/down
                new Polygon(new int[] { 16, 17, 18, 19 }, 4),                   // 4
                new Polygon(new int[] { 20, 21, 22, 23 }, 5)                    // 5
            };

            shape = new Shape();

            shape.Surfaces = new Surface[6];
            shape.Surfaces[0].TexGenIndex = 0;
            shape.Surfaces[1].TexGenIndex = 1;
            shape.Surfaces[2].TexGenIndex = 2;
            shape.Surfaces[3].TexGenIndex = 3;
            shape.Surfaces[4].TexGenIndex = 4;
            shape.Surfaces[5].TexGenIndex = 5;

            shape.Surfaces[0].Plane = GeometryUtility.CalcPolygonPlane(controlMesh, 0);
            shape.Surfaces[1].Plane = GeometryUtility.CalcPolygonPlane(controlMesh, 1);
            shape.Surfaces[2].Plane = GeometryUtility.CalcPolygonPlane(controlMesh, 2);
            shape.Surfaces[3].Plane = GeometryUtility.CalcPolygonPlane(controlMesh, 3);
            shape.Surfaces[4].Plane = GeometryUtility.CalcPolygonPlane(controlMesh, 4);
            shape.Surfaces[5].Plane = GeometryUtility.CalcPolygonPlane(controlMesh, 5);

            GeometryUtility.CalculateTangents(shape.Surfaces[0].Plane.normal, out shape.Surfaces[0].Tangent, out shape.Surfaces[0].BiNormal);
            GeometryUtility.CalculateTangents(shape.Surfaces[1].Plane.normal, out shape.Surfaces[1].Tangent, out shape.Surfaces[1].BiNormal);
            GeometryUtility.CalculateTangents(shape.Surfaces[2].Plane.normal, out shape.Surfaces[2].Tangent, out shape.Surfaces[2].BiNormal);
            GeometryUtility.CalculateTangents(shape.Surfaces[3].Plane.normal, out shape.Surfaces[3].Tangent, out shape.Surfaces[3].BiNormal);
            GeometryUtility.CalculateTangents(shape.Surfaces[4].Plane.normal, out shape.Surfaces[4].Tangent, out shape.Surfaces[4].BiNormal);
            GeometryUtility.CalculateTangents(shape.Surfaces[5].Plane.normal, out shape.Surfaces[5].Tangent, out shape.Surfaces[5].BiNormal);

            var defaultMaterial = CSGSettings.DefaultMaterial;

            shape.TexGens = new TexGen[6];

            shape.TexGens[0].RenderMaterial = defaultMaterial;
            shape.TexGens[1].RenderMaterial = defaultMaterial;
            shape.TexGens[2].RenderMaterial = defaultMaterial;
            shape.TexGens[3].RenderMaterial = defaultMaterial;
            shape.TexGens[4].RenderMaterial = defaultMaterial;
            shape.TexGens[5].RenderMaterial = defaultMaterial;

            shape.TexGens[0].Scale = MathConstants.oneVector3;
            shape.TexGens[1].Scale = MathConstants.oneVector3;
            shape.TexGens[2].Scale = MathConstants.oneVector3;
            shape.TexGens[3].Scale = MathConstants.oneVector3;
            shape.TexGens[4].Scale = MathConstants.oneVector3;
            shape.TexGens[5].Scale = MathConstants.oneVector3;


            shape.TexGens[0].Color = Color.white;
            shape.TexGens[1].Color = Color.white;
            shape.TexGens[2].Color = Color.white;
            shape.TexGens[3].Color = Color.white;
            shape.TexGens[4].Color = Color.white;
            shape.TexGens[5].Color = Color.white;


            shape.TexGenFlags    = new TexGenFlags[6];
            shape.TexGenFlags[0] = TexGenFlags.None;
            shape.TexGenFlags[1] = TexGenFlags.None;
            shape.TexGenFlags[2] = TexGenFlags.None;
            shape.TexGenFlags[3] = TexGenFlags.None;
            shape.TexGenFlags[4] = TexGenFlags.None;
            shape.TexGenFlags[5] = TexGenFlags.None;

            //controlMesh.Validate();
            ShapeUtility.EnsureInitialized(shape);
            controlMesh.IsValid = ControlMeshUtility.Validate(controlMesh, shape);

            return(controlMesh.IsValid);
        }
        internal override bool CreateControlMeshForBrushIndex(CSGModel parentModel, CSGBrush brush, ShapePolygon polygon, Matrix4x4 localToWorld, float height, out ControlMesh newControlMesh, out Shape newShape)
        {
            bool smooth            = settings.circleSmoothShading;
            bool singleSurfaceEnds = settings.circleSingleSurfaceEnds;
            var  direction         = haveForcedDirection ? forcedDirection : buildPlane.normal;

            if (!ShapePolygonUtility.GenerateControlMeshFromVertices(polygon,
                                                                     localToWorld,
                                                                     GeometryUtility.RotatePointIntoPlaneSpace(buildPlane, direction),
                                                                     height,

                                                                     new TexGen(),

                                                                     smooth,
                                                                     singleSurfaceEnds,
                                                                     out newControlMesh,
                                                                     out newShape))
            {
                return(false);
            }

            brush.Shape       = newShape;
            brush.ControlMesh = newControlMesh;
            InternalCSGModelManager.ValidateBrush(brush, true);
            ControlMeshUtility.RebuildShape(brush);

            var   vertices      = polygon.Vertices;
            float circumference = 0.0f;

            for (int j = vertices.Length - 1, i = 0; i < vertices.Length; j = i, i++)
            {
                circumference += (vertices[j] - vertices[i]).magnitude;
            }

            var shape = brush.Shape;

            float desiredTextureLength = Mathf.Max(1.0f, Mathf.Round(circumference));
            float scalar = desiredTextureLength / circumference;

            shape.TexGens[0].Scale.x       = scalar;
            shape.TexGens[0].Scale.y       = shape.TexGens[0].Scale.y;
            shape.TexGens[0].Translation.x = 0;

            var count = vertices.Length;

            if (!singleSurfaceEnds)
            {
                GeometryUtility.ContinueTexGenFromSurfaceToSurface(brush, 0, count);
                GeometryUtility.ContinueTexGenFromSurfaceToSurface(brush, 0, count + count);
                for (int j = 0, i = 1; i < count; j = i, i++)
                {
                    GeometryUtility.ContinueTexGenFromSurfaceToSurface(brush, j, i);
                    GeometryUtility.ContinueTexGenFromSurfaceToSurface(brush, i, i + count);
                    GeometryUtility.ContinueTexGenFromSurfaceToSurface(brush, i, i + count + count);
                }
            }
            else
            {
                for (int j = 0, i = 1; i < count; j = i, i++)
                {
                    GeometryUtility.ContinueTexGenFromSurfaceToSurface(brush, j, i);
                }
            }

            return(true);
        }
Exemplo n.º 16
0
        public static bool GenerateControlMeshFromVertices(ShapePolygon shape2DPolygon,
                                                           Matrix4x4 localToWorld,
                                                           Vector3 direction,
                                                           float height,
                                                           Material capMaterial,
                                                           TexGen capTexgen,
                                                           bool?smooth,
                                                           bool singleSurfaceEnds,                                                                                 //Plane buildPlane,
                                                           out ControlMesh controlMesh,
                                                           out Shape shape)
        {
            if (shape2DPolygon == null)
            {
                controlMesh = null;
                shape       = null;
                return(false);
            }

            var vertices = shape2DPolygon.Vertices;

            if (vertices.Length < 3)
            {
                controlMesh = null;
                shape       = null;
                return(false);
            }
            if (height == 0.0f)
            {
                controlMesh = null;
                shape       = null;
                return(false);
            }

            Vector3 from;
            Vector3 to;

            if (height > 0)
            {
                @from = direction * height;                // buildPlane.normal * height;
                to    = MathConstants.zeroVector3;
            }
            else
            {
                @from = MathConstants.zeroVector3;
                to    = direction * height;               //buildPlane.normal * height;
            }

            var count           = vertices.Length;
            var doubleCount     = (count * 2);
            var extraPoints     = 0;
            var extraEdges      = 0;
            var endsPolygons    = 2;
            var startEdgeOffset = doubleCount;

            if (!singleSurfaceEnds)
            {
                extraPoints      = 2;
                extraEdges       = (4 * count);
                endsPolygons     = doubleCount;
                startEdgeOffset += extraEdges;
            }


            var dstPoints   = new Vector3 [doubleCount + extraPoints];
            var dstEdges    = new HalfEdge[(count * 6) + extraEdges];
            var dstPolygons = new Polygon [count + endsPolygons];

            var center1 = MathConstants.zeroVector3;
            var center2 = MathConstants.zeroVector3;


            for (int i = 0; i < count; i++)
            {
                var point1 = vertices[i];
                var point2 = vertices[(count + i - 1) % count];

                point1 += @from;
                point2 += to;

                // swap y/z to solve texgen issues
                dstPoints[i].x = point1.x;
                dstPoints[i].y = point1.y;
                dstPoints[i].z = point1.z;

                center1 += dstPoints[i];

                dstEdges [i].VertexIndex = (short)i;
                dstEdges [i].HardEdge    = true;

                // swap y/z to solve texgen issues
                dstPoints[i + count].x = point2.x;
                dstPoints[i + count].y = point2.y;
                dstPoints[i + count].z = point2.z;
                center2 += dstPoints[i + count];

                dstEdges [i + count].VertexIndex = (short)(i + count);
                dstEdges [i + count].HardEdge    = true;
            }

            if (!singleSurfaceEnds)
            {
                dstPoints[doubleCount]     = center1 / count;
                dstPoints[doubleCount + 1] = center2 / count;

                int   edge_offset   = doubleCount;
                short polygon_index = (short)count;

                // 'top'
                for (int i = 0, j = count - 1; i < count; j = i, i++)
                {
                    var jm = (j) % count;
                    var im = (i) % count;

                    var edgeOut0 = edge_offset + (jm * 2) + 1;
                    var edgeIn0  = edge_offset + (im * 2) + 0;
                    var edgeOut1 = edge_offset + (im * 2) + 1;

                    dstEdges[edgeIn0].VertexIndex = (short)(doubleCount);
                    dstEdges[edgeIn0].HardEdge    = true;
                    dstEdges[edgeIn0].TwinIndex   = edgeOut1;

                    dstEdges[edgeOut1].VertexIndex = (short)im;
                    dstEdges[edgeOut1].HardEdge    = true;
                    dstEdges[edgeOut1].TwinIndex   = edgeIn0;

                    dstEdges[im].PolygonIndex       = polygon_index;
                    dstEdges[edgeIn0].PolygonIndex  = polygon_index;
                    dstEdges[edgeOut0].PolygonIndex = polygon_index;

                    dstPolygons[polygon_index] = new Polygon(new int[] { im, edgeIn0, edgeOut0 }, polygon_index);
                    polygon_index++;
                }

                edge_offset = doubleCount * 2;
                // 'bottom'
                for (int i = 0, j = count - 1; j >= 0; i = j, j--)
                {
                    var jm = (count + count - j) % count;
                    var im = (count + count - i) % count;

                    var edgeOut0 = edge_offset + (jm * 2) + 1;
                    var edgeIn0  = edge_offset + (im * 2) + 0;
                    var edgeOut1 = edge_offset + (im * 2) + 1;

                    dstEdges[edgeIn0].VertexIndex = (short)(doubleCount + 1);
                    dstEdges[edgeIn0].HardEdge    = true;
                    dstEdges[edgeIn0].TwinIndex   = edgeOut1;

                    dstEdges[edgeOut1].VertexIndex = (short)(im + count);
                    dstEdges[edgeOut1].HardEdge    = true;
                    dstEdges[edgeOut1].TwinIndex   = edgeIn0;

                    dstEdges[im + count].PolygonIndex = polygon_index;
                    dstEdges[edgeIn0].PolygonIndex    = polygon_index;
                    dstEdges[edgeOut0].PolygonIndex   = polygon_index;

                    dstPolygons[polygon_index] = new Polygon(new int[] { im + count, edgeIn0, edgeOut0 }, polygon_index);
                    polygon_index++;
                }
            }
            else
            {
                var polygon0Edges = new int[count];
                var polygon1Edges = new int[count];
                for (var i = 0; i < count; i++)
                {
                    dstEdges [i].PolygonIndex         = (short)(count + 0);
                    dstEdges [i + count].PolygonIndex = (short)(count + 1);
                    polygon0Edges[i] = i;
                    polygon1Edges[count - (i + 1)] = i + count;
                }
                dstPolygons[count + 0] = new Polygon(polygon0Edges, count + 0);
                dstPolygons[count + 1] = new Polygon(polygon1Edges, count + 1);
            }


            for (int v0 = count - 1, v1 = 0; v1 < count; v0 = v1, v1++)
            {
                var polygonIndex = (short)(v1);

                var nextOffset = startEdgeOffset + (((v1 + 1) % count) * 4);
                var currOffset = startEdgeOffset + (((v1)) * 4);
                var prevOffset = startEdgeOffset + (((v1 + count - 1) % count) * 4);

                var nextTwin = nextOffset + 1;
                var prevTwin = prevOffset + 3;

                dstEdges[v1].TwinIndex         = currOffset + 0;
                dstEdges[v1 + count].TwinIndex = currOffset + 2;

                dstEdges[currOffset + 0].PolygonIndex = polygonIndex;
                dstEdges[currOffset + 1].PolygonIndex = polygonIndex;
                dstEdges[currOffset + 2].PolygonIndex = polygonIndex;
                dstEdges[currOffset + 3].PolygonIndex = polygonIndex;

                dstEdges[currOffset + 0].TwinIndex = (v1);
                dstEdges[currOffset + 1].TwinIndex = prevTwin;
                dstEdges[currOffset + 2].TwinIndex = (v1 + count);
                dstEdges[currOffset + 3].TwinIndex = nextTwin;

                dstEdges[currOffset + 0].VertexIndex = (short)(v0);
                dstEdges[currOffset + 1].VertexIndex = (short)(v1 + count);
                dstEdges[currOffset + 2].VertexIndex = (short)(((v1 + 1) % count) + count);
                dstEdges[currOffset + 3].VertexIndex = (short)(v1);

                dstEdges[currOffset + 0].HardEdge = true;
                dstEdges[currOffset + 1].HardEdge = true;
                dstEdges[currOffset + 2].HardEdge = true;
                dstEdges[currOffset + 3].HardEdge = true;

                dstPolygons[polygonIndex] = new Polygon(new [] { currOffset + 0,
                                                                 currOffset + 1,
                                                                 currOffset + 2,
                                                                 currOffset + 3 }, polygonIndex);
            }

            for (int i = 0; i < dstPoints.Length; i++)
            {
                dstPoints[i] = localToWorld.MultiplyPoint(dstPoints[i]);
            }

            controlMesh = new ControlMesh
            {
                Vertices = dstPoints,
                Edges    = dstEdges,
                Polygons = dstPolygons
            };
            controlMesh.SetDirty();

            shape = new Shape
            {
                Materials   = new Material[dstPolygons.Length],
                Surfaces    = new Surface[dstPolygons.Length],
                TexGenFlags = new TexGenFlags[dstPolygons.Length],
                TexGens     = new TexGen[dstPolygons.Length]
            };


            var smoothinggroup = (smooth.HasValue && smooth.Value) ? SurfaceUtility.FindUnusedSmoothingGroupIndex() : 0;


            var containedMaterialCount = 0;

            if (shape2DPolygon.EdgeMaterials != null &&
                shape2DPolygon.EdgeTexgens != null /* &&
                                                    * shape2DPolygon.edgeTexgenFlags != null*/)
            {
                containedMaterialCount = Mathf.Min(shape2DPolygon.EdgeMaterials.Length,
                                                   shape2DPolygon.EdgeTexgens.Length /*,
                                                                                      *                        shape2DPolygon.edgeTexgenFlags.Length*/);
            }

            if (!capMaterial)
            {
                capMaterial = CSGSettings.DefaultMaterial;
                capTexgen   = new TexGen(-1);
            }

            for (var i = 0; i < dstPolygons.Length; i++)
            {
                if (i < containedMaterialCount)
                {
                    //shape.TexGenFlags[i] = shape2DPolygon.edgeTexgenFlags[i];
                    shape.Materials  [i]             = shape2DPolygon.EdgeMaterials[i];
                    shape.TexGens    [i]             = shape2DPolygon.EdgeTexgens[i];
                    shape.Surfaces   [i].TexGenIndex = i;
                    shape.TexGens[i].MaterialIndex   = -1;
                }
                else
                {
                    shape.Materials[i] = capMaterial;
                    shape.TexGens[i]   = capTexgen;
                    //shape.TexGenFlags[i]			= TexGenFlags.None;
                    shape.Surfaces[i].TexGenIndex  = i;
                    shape.TexGens[i].MaterialIndex = -1;
                }
                if (smooth.HasValue)
                {
                    if (i < count)
                    {
                        shape.TexGens[i].SmoothingGroup = smoothinggroup;
                    }
                    else
                    {
                        shape.TexGens[i].SmoothingGroup = 0;
                    }
                }
            }

            for (var s = 0; s < dstPolygons.Length; s++)
            {
                var normal = shape.Surfaces[s].Plane.normal;
                shape.Surfaces[s].Plane = GeometryUtility.CalcPolygonPlane(controlMesh, (short)s);
                Vector3 tangent, binormal;
                GeometryUtility.CalculateTangents(normal, out tangent, out binormal);
                //var tangent		= Vector3.Cross(GeometryUtility.CalculateTangent(normal), normal).normalized;
                //var binormal	= Vector3.Cross(normal, tangent);
                shape.Surfaces[s].Tangent     = tangent;
                shape.Surfaces[s].BiNormal    = binormal;
                shape.Surfaces[s].TexGenIndex = s;
            }

            controlMesh.IsValid = ControlMeshUtility.Validate(controlMesh, shape);
            if (controlMesh.IsValid)
            {
                return(true);
            }

            controlMesh = null;
            shape       = null;
            return(false);
        }
        /// <summary>Converts a <see cref="RealtimeCSG.Legacy.ControlMesh"/>/<see cref="RealtimeCSG.Legacy.Shape"/> pair into a <see cref="RealtimeCSG.Foundation.BrushMesh"/>.</summary>
        /// <param name="controlMesh">A legacy <see cref="RealtimeCSG.Legacy.ControlMesh"/> that describes the shape of the <see cref="RealtimeCSG.Foundation.BrushMesh"/>.</param>
        /// <param name="shape">A legacy <see cref="RealtimeCSG.Legacy.Shape"/> that describes the surfaces in the <see cref="RealtimeCSG.Foundation.BrushMesh"/>.</param>
        /// <returns>A new <see cref="RealtimeCSG.Foundation.BrushMesh"/></returns>
        public static BrushMesh GenerateFromControlMesh(ControlMesh controlMesh, Shape shape)
        {
            if (controlMesh == null ||
                shape == null)
            {
                return(null);
            }

            if (!ControlMeshUtility.Validate(controlMesh, shape))
            {
                return(null);
            }

            var vertices    = controlMesh.Vertices;
            var srcEdges    = controlMesh.Edges;
            var srcPolygons = controlMesh.Polygons;

            if (vertices == null ||
                srcEdges == null ||
                srcPolygons == null)
            {
                return(null);
            }

            var surfaces    = shape.Surfaces;
            var texgens     = shape.TexGens;
            var texgenFlags = shape.TexGenFlags;

            if (surfaces == null ||
                texgens == null ||
                texgenFlags == null)
            {
                return(null);
            }

            var polygonCount = surfaces.Length;

            if (polygonCount != srcPolygons.Length ||
                polygonCount != texgens.Length ||
                polygonCount != texgenFlags.Length ||
                polygonCount != surfaces.Length)
            {
                return(null);
            }

            var brushMesh = new BrushMesh
            {
                polygons = new BrushMesh.Polygon[polygonCount],
                vertices = vertices.ToArray()
            };

            for (int i = 0; i < polygonCount; i++)
            {
                var polygonIndex = i;
                var surface      = surfaces[polygonIndex];
                var texGenIndex  = surface.TexGenIndex;
                var texGen       = texgens[texGenIndex];
                var flags        = texgenFlags[texGenIndex];

                brushMesh.polygons[i].polygonID = polygonIndex;
                brushMesh.polygons[i].surface   = CreateSurfaceDescription(surface, texGen, flags);
                brushMesh.polygons[i].layers    = CreateSurfaceLayer(texGen, flags);
            }

            int counter = 0;

            for (var i = 0; i < polygonCount; i++)
            {
                var polygonIndex = i;
                var edgeIndices  = srcPolygons[polygonIndex].EdgeIndices;
                brushMesh.polygons[i].firstEdge = counter;
                brushMesh.polygons[i].edgeCount = edgeIndices.Length;
                counter += edgeIndices.Length;
            }

            brushMesh.halfEdges = new BrushMesh.HalfEdge[counter];

            counter = 0;
            for (var i = 0; i < polygonCount; i++)
            {
                var polygonIndex = i;
                var edgeIndices  = srcPolygons[polygonIndex].EdgeIndices;
                for (var v = 0; v < edgeIndices.Length; v++)
                {
                    var edge = srcEdges[edgeIndices[v]];
                    brushMesh.halfEdges[counter + v].vertexIndex = edge.VertexIndex;

                    var twinIndex        = edge.TwinIndex;
                    var twinPolygonIndex = srcEdges[twinIndex].PolygonIndex;
                    var twinEdges        = srcPolygons[twinPolygonIndex].EdgeIndices;
                    var found            = false;
                    for (var t = 0; t < twinEdges.Length; t++)
                    {
                        if (twinEdges[t] == twinIndex)
                        {
                            twinIndex = t + brushMesh.polygons[twinPolygonIndex].firstEdge;
                            found     = true;
                            break;
                        }
                    }

                    if (!found)
                    {
                        return(null);
                    }

                    brushMesh.halfEdges[counter + v].twinIndex = twinIndex;
                }
                counter += edgeIndices.Length;
            }
            return(brushMesh);
        }
        /// <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.º 19
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;
        }
Exemplo n.º 20
0
        public static void Flip(CSGBrush[] brushes, Matrix4x4 flipMatrix, string undoDescription = "Flip brushes")
        {
            var fail = false;

            Undo.IncrementCurrentGroup();
            Undo.RegisterCompleteObjectUndo(brushes.ToArray <UnityEngine.Object>(), undoDescription);

            var isGlobal = Tools.pivotRotation == PivotRotation.Global;

            var centerAll = BoundsUtilities.GetCenter(brushes);

            for (var t = 0; t < brushes.Length; t++)
            {
                var brush    = brushes[t];
                var shape    = brush.Shape;
                var position = brush.transform.position;

                Matrix4x4 brushFlip;
                Vector3   brushCenter;
                if (isGlobal)
                {
                    brushFlip = brush.transform.localToWorldMatrix *
                                flipMatrix *
                                brush.transform.worldToLocalMatrix;
                    brushCenter = brush.transform.InverseTransformPoint(centerAll) - position;
                }
                else
                {
                    brushFlip   = flipMatrix;
                    brushCenter = brush.transform.InverseTransformPoint(centerAll);
                }

                for (var s = 0; s < shape.Surfaces.Length; s++)
                {
                    var plane = shape.Surfaces[s].Plane;

                    var normal   = brushFlip.MultiplyVector(plane.normal);
                    var biNormal = brushFlip.MultiplyVector(shape.Surfaces[s].BiNormal);
                    var tangent  = brushFlip.MultiplyVector(shape.Surfaces[s].Tangent);

                    var pointOnPlane = plane.pointOnPlane;
                    pointOnPlane -= brushCenter;
                    pointOnPlane  = brushFlip.MultiplyPoint(pointOnPlane);
                    pointOnPlane += brushCenter;

                    shape.Surfaces[s].Plane    = new CSGPlane(normal, pointOnPlane);
                    shape.Surfaces[s].BiNormal = biNormal;
                    shape.Surfaces[s].Tangent  = tangent;
                }

                var controlMesh = brush.ControlMesh;
                brush.Shape = shape;

                brush.ControlMesh = ControlMeshUtility.CreateFromShape(shape);
                if (brush.ControlMesh == null)
                {
                    brush.ControlMesh = controlMesh;
                    fail = true;
                    break;
                }

                ShapeUtility.CreateCutter(shape, brush.ControlMesh);
                brush.EnsureInitialized();

                brush.ControlMesh.SetDirty();
                EditorUtility.SetDirty(brush);

                InternalCSGModelManager.CheckSurfaceModifications(brush, true);

                ControlMeshUtility.RebuildShape(brush);
            }
            if (fail)
            {
                Debug.Log("Failed to perform operation");
                Undo.RevertAllInCurrentGroup();
            }
            InternalCSGModelManager.Refresh();
        }