Esempio n. 1
0
        /// <summary>
        /// Rebuilds the volume, creating or deleting the volume component and applying new settings.
        /// </summary>
        internal void RebuildVolume()
        {
            // volumes can only be primitive brushes at the moment.
            if (GetType() != typeof(PrimitiveBrush))
            {
                return;
            }
            PrimitiveBrush self = (PrimitiveBrush)this;

            // remove volumes from brushes that are no longer volumes:
            if (Mode != CSGMode.Volume && Volume != null)
            {
                // set volume handle to null.
                Volume = null;
                // delete any built volume.
                Transform volume1 = transform.Find(Constants.GameObjectVolumeComponentIdentifier);
                if (volume1 != null)
                {
                    GameObject.DestroyImmediate(volume1.gameObject);
                }
            }

            // generate all of the volume brushes:
            if (Mode == CSGMode.Volume && Volume != null)
            {
                // remove any existing built volume:
                Transform volume2 = transform.Find(Constants.GameObjectVolumeComponentIdentifier);
                if (volume2 != null)
                {
                    GameObject.DestroyImmediate(volume2.gameObject);
                }

                // create the game object with convex mesh collider:
                Mesh mesh = new Mesh();
                BrushFactory.GenerateMeshFromPolygonsFast(self.GetPolygons(), ref mesh, 0.0f);
                GameObject gameObject = CreateVolumeMeshCollider(mesh);
                gameObject.transform.position = transform.position;
                gameObject.transform.rotation = transform.rotation;

                // execute custom volume generation code:
                Volume.OnCreateVolume(gameObject);
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Tells the brush it has changed
        /// </summary>
        /// <param name="polygonsChanged">If set to <c>true</c> polygons will be recached.</param>
        public override void Invalidate(bool polygonsChanged)
        {
            base.Invalidate(polygonsChanged);
            if (!gameObject.activeInHierarchy)
            {
                return;
            }

            // previous versions of sabrecsg used to use mesh colliders for ray collision, but that's no longer the case so we clean them up.
            MeshCollider[] meshColliders = GetComponents <MeshCollider>();
            if (meshColliders.Length > 0)
            {
                for (int i = 0; i < meshColliders.Length; i++)
                {
                    DestroyImmediate(meshColliders[i]);
                }
            }

            // Make sure there is a mesh filter on this object
            MeshFilter   meshFilter   = gameObject.AddOrGetComponent <MeshFilter>();
            MeshRenderer meshRenderer = gameObject.AddOrGetComponent <MeshRenderer>();

            bool requireRegen = false;

            // If the cached ID hasn't been set or we mismatch
            if (cachedInstanceID == 0 ||
                gameObject.GetInstanceID() != cachedInstanceID)
            {
                requireRegen     = true;
                cachedInstanceID = gameObject.GetInstanceID();
            }

            Mesh renderMesh = meshFilter.sharedMesh;

            if (requireRegen)
            {
                renderMesh = new Mesh();
            }

            if (polygons != null)
            {
                // generate a mesh preview for the transparent brushes.
                // we also displace the triangles along the normals slightly so we can overlay built geometry
                // with semi-transparent geometry and avoid depth fighting.
                BrushFactory.GenerateMeshFromPolygonsFast(polygons, ref renderMesh, mode == CSGMode.Add ? 0.001f : -0.001f);
            }

            if (mode == CSGMode.Subtract)
            {
                MeshHelper.Invert(ref renderMesh);
            }

            meshFilter.sharedMesh = renderMesh;

            meshRenderer.receiveShadows    = false;
            meshRenderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;

            meshFilter.hideFlags   = HideFlags.NotEditable; // | HideFlags.HideInInspector;
            meshRenderer.hideFlags = HideFlags.NotEditable; // | HideFlags.HideInInspector;

#if UNITY_EDITOR
            Material material;
            if (IsNoCSG)
            {
                material = SabreCSGResources.GetNoCSGMaterial();
            }
            else
            {
                if (this.mode == CSGMode.Add)
                {
                    material = SabreCSGResources.GetAddMaterial();
                }
                else
                {
                    material = SabreCSGResources.GetSubtractMaterial();
                }
            }
            if (meshRenderer.sharedMaterial != material)
            {
                meshRenderer.sharedMaterial = material;
            }
#endif
            //			isBrushConvex = GeometryHelper.IsBrushConvex(polygons);

            if (polygonsChanged)
            {
                RecalculateBrushCache();
            }

            UpdateVisibility();

            objectVersionSerialized++;
            objectVersionUnserialized = objectVersionSerialized;

            if (cachedWorldTransform == null)
            {
                cachedWorldTransform = new WorldTransformData(transform);
            }
            cachedWorldTransform.SetFromTransform(transform);
        }