示例#1
0
        // creates a button in the desired geometry shape
        public void Create()
        {
            entry = GameObjectFactory.CreateParentGO(UniqueNames.GetNext("HUDLabel"));

            bgMesh = new fGameObject(AppendMeshGO("background", make_background_mesh(),
                                                  MaterialUtil.CreateFlatMaterialF(BackgroundColor),
                                                  entry));
            bgMesh.RotateD(Vector3f.AxisX, -90.0f);

            BoxPosition horzAlign = BoxPosition.CenterLeft;

            if (AlignmentHorz == HorizontalAlignment.Center)
            {
                horzAlign = BoxPosition.Center;
            }
            else if (AlignmentHorz == HorizontalAlignment.Right)
            {
                horzAlign = BoxPosition.CenterRight;
            }

            textMesh =
                GameObjectFactory.CreateTextMeshGO(
                    "text", Text, TextColor, TextHeight, horzAlign, SceneGraphConfig.TextLabelZOffset);

            Vector2f toPos = BoxModel.GetBoxPosition(this, horzAlign);

            BoxModel.Translate(textMesh, Vector2f.Zero, toPos);

            AppendNewGO(textMesh, entry, false);
        }
示例#2
0
        public virtual PivotSO Create(SOMaterial shapeMaterial, SOMaterial frameMaterial = null, int nShapeLayer = -1)
        {
            // [TODO] replace frame geometry with line renderer ?
            // [TODO] still cast shadows  (semitransparent objects don't cast shadows, apparently)
            // [TODO] maybe render solid when not obscured by objects? use raycast in PreRender?

            AssignSOMaterial(shapeMaterial);       // need to do this to setup BaseSO material stack

            pivotGO = GameObjectFactory.CreateParentGO(UniqueNames.GetNext("Pivot"));

            shapeGO = create_pivot_shape();
            AppendNewGO(shapeGO, pivotGO, false);

            pivotGO.AddChild(shapeGO);

            if (frameMaterial != null)
            {
                this.frameMaterial = frameMaterial;

                frameGO = UnityUtil.CreateMeshGO("pivotFrame", "icon_meshes/axis_frame", 1.0f,
                                                 UnityUtil.MeshAlignOption.NoAlignment, MaterialUtil.ToUnityMaterial(frameMaterial), false);
                MaterialUtil.SetIgnoreMaterialChanges(frameGO);
                MaterialUtil.DisableShadows(frameGO);
                AppendNewGO(frameGO, pivotGO, false);
            }

            if (nShapeLayer >= 0)
            {
                shapeGO.SetLayer(nShapeLayer);
            }

            increment_timestamp();
            return(this);
        }
示例#3
0
        public PivotSO Create(SOMaterial sphereMaterial, Material frameMaterial, int nSphereLayer = -1)
        {
            // [TODO] replace frame geometry with line renderer ?
            // [TODO] still cast shadows  (semitransparent objects don't cast shadows, apparently)
            // [TODO] maybe render solid when not obscured by objects? use raycast in PreRender?

            AssignSOMaterial(sphereMaterial);       // need to do this to setup BaseSO material stack

            pivot  = new GameObject(UniqueNames.GetNext("Pivot"));
            meshGO = AppendUnityPrimitiveGO("pivotMesh", PrimitiveType.Sphere, CurrentMaterial, pivot);
            meshGO.transform.localScale = 0.9f * Vector3.one;

            if (frameMaterial != null)
            {
                frameMesh = UnityUtil.CreateMeshGO("pivotFrame", "icon_meshes/axis_frame", 1.0f,
                                                   UnityUtil.MeshAlignOption.NoAlignment, frameMaterial, false);
                frameMesh.AddComponent <IgnoreMaterialChanges>();
                MaterialUtil.DisableShadows(frameMesh);
                AppendNewGO(frameMesh, pivot, false);
            }

            if (nSphereLayer >= 0)
            {
                meshGO.SetLayer(nSphereLayer);
            }

            increment_timestamp();
            return(this);
        }
示例#4
0
        public CylinderSO Create(SOMaterial defaultMaterial)
        {
            cylinder = new GameObject(UniqueNames.GetNext("Cylinder"));
            AssignSOMaterial(defaultMaterial);       // need to do this to setup BaseSO material stack

            Material useMaterial = CurrentMaterial;

            topCap = AppendMeshGO("topCap",
                                  MeshGenerators.CreateDisc(radius, 1, 16),
                                  useMaterial, cylinder);
            topCap.transform.localPosition += 0.5f * height * Vector3.up;

            bottomCap = AppendMeshGO("bottomCap",
                                     MeshGenerators.CreateDisc(radius, 1, 16),
                                     useMaterial, cylinder);
            bottomCap.transform.RotateAround(Vector3.zero, Vector3.right, 180.0f);
            bottomCap.transform.localPosition -= 0.5f * height * Vector3.up;

            body = AppendMeshGO("body",
                                MeshGenerators.CreateCylider(radius, height, 16),
                                useMaterial, cylinder);
            body.transform.localPosition -= 0.5f * height * Vector3.up;

            update_shift();
            cylinder.transform.position += centerShift;

            increment_timestamp();
            return(this);
        }
示例#5
0
        public virtual void Create()
        {
            rootGO = new GameObject(UniqueNames.GetNext("HUDSlider"));

            fMaterial useMaterial = MaterialUtil.CreateFlatMaterialF(bgColor);

            backgroundGO = GameObjectFactory.CreateRectangleGO("background",
                                                               SliderWidth, SliderHeight, useMaterial, true, true);
            MaterialUtil.DisableShadows(backgroundGO);
            backgroundGO.RotateD(Vector3f.AxisX, -90.0f); // ??
            AppendNewGO(backgroundGO, rootGO, false);

            handleMaterial = MaterialUtil.CreateFlatMaterialF(handleColor);
            handleGO       = create_handle_go(handleMaterial);
            if (handleGO != null)
            {
                handleGO.Translate(0.001f * Vector3f.AxisY, true);
                AppendNewGO(handleGO, rootGO, false);
                handleStart = handleGO.GetLocalFrame();
            }

            create_visuals_geometry();

            TickMaterial = MaterialUtil.CreateFlatMaterialF(tickColor);

            update_geometry();
        }
示例#6
0
        public PolyCurveSO Create(SOMaterial defaultMaterial)
        {
            if (curve == null)
            {
                LineGenerator gen = new LineGenerator()
                {
                    Start = Vector3.zero, End = 10.0f * Vector3.up, StepSize = 0.1f
                };
                gen.Generate();
                curve = new DCurve3();
                gen.Make(curve);
            }

            // assumes type identifier is something like BlahBlahSO
            root = new GameObject(UniqueNames.GetNext(Type.identifier.Remove(Type.identifier.Length - 2)));

            if (EnableLineRenderer)
            {
                LineRenderer ren = root.AddComponent <LineRenderer>();
                ren.startWidth    = ren.endWidth = 0.05f;
                ren.useWorldSpace = false;
            }

            AssignSOMaterial(defaultMaterial);       // need to do this to setup BaseSO material stack
            Material useMaterial = CurrentMaterial;

            Create_internal(useMaterial);

            UpdateGeometry();

            increment_timestamp();

            return(this);
        }
        // creates a popup in the desired geometry shape
        public void Create(Material defaultMaterial)
        {
            popup     = new GameObject(UniqueNames.GetNext("HUDPopup"));
            popupMesh = AppendMeshGO("popup", make_mesh(),
                                     defaultMaterial, popup);

            popupMesh.transform.Rotate(Vector3.right, -90.0f); // ??
        }
示例#8
0
 public SOMaterial()
 {
     Name        = UniqueNames.GetNext("SOMaterial");
     Type        = MaterialType.StandardRGBColor;
     RGBColor    = Colorf.VideoWhite;
     CullingMode = CullingModes.None;
     Hints       = HintFlags.None;
 }
示例#9
0
        // creates a button that is just the mesh
        public void Create(fMesh mesh, fMaterial meshMaterial, float fScale, Quaternionf transform)
        {
            button = GameObjectFactory.CreateParentGO(UniqueNames.GetNext("HUDButton"));

            iconMesh = AppendMeshGO("shape", mesh, meshMaterial, button);
            iconMesh.SetLocalScale(new Vector3f(fScale, fScale, fScale));
            iconMesh.SetLocalRotation(iconMesh.GetLocalRotation() * transform);
            MaterialUtil.DisableShadows(iconMesh);

            standard_mat = new fMaterial(meshMaterial);
        }
示例#10
0
 public SOMeshMaterial()
 {
     Name            = UniqueNames.GetNext("SOMeshMaterial");
     Type            = MaterialType.StandardMesh;
     RGBColor        = Colorf.VideoWhite;
     CullingMode     = CullingModes.None;
     Hints           = HintFlags.None;
     EnableWireframe = false;
     ClipPlaneMode   = ClipPlaneModes.NoClip;
     ClipPlanePos    = Frame3f.Identity;
 }
示例#11
0
        // creates a button that is just the mesh
        public void Create(Mesh mesh, Material meshMaterial, float fScale, Quaternion transform)
        {
            button = new GameObject(UniqueNames.GetNext("HUDButton"));

            GameObject meshGO = AppendMeshGO("shape", mesh, meshMaterial, button);

            meshGO.transform.localScale     = new Vector3(fScale, fScale, fScale);
            meshGO.transform.localRotation *= transform;
            MaterialUtil.DisableShadows(meshGO);

            standard_mat = new fMaterial(meshMaterial);
        }
示例#12
0
        public void Create(fMaterial defaultMaterial)
        {
            button     = GameObjectFactory.CreateParentGO(UniqueNames.GetNext("HUDToggleButton"));
            buttonMesh = AppendMeshGO("shape", HUDUtil.MakeBackgroundMesh(this.Shape),
                                      defaultMaterial, button);

            buttonMesh.RotateD(Vector3f.AxisX, -90.0f); // ??

            if (text.Length > 0)
            {
                UpdateText();
            }
        }
示例#13
0
        public virtual DMeshSO Create(DMesh3 mesh, SOMaterial setMaterial)
        {
            AssignSOMaterial(setMaterial);       // need to do this to setup BaseSO material stack
            parentGO = GameObjectFactory.CreateParentGO(UniqueNames.GetNext("DMesh"));

            this.mesh = mesh;
            on_mesh_changed();

            displayComponents = new List <DisplayMeshComponent>();
            validate_decomp();

            return(this);
        }
示例#14
0
        public void Create(fMaterial defaultMaterial)
        {
            button     = GameObjectFactory.CreateParentGO(UniqueNames.GetNext("HUDToggleButton"));
            buttonMesh = AppendMeshGO("disc", make_button_body_mesh(),
                                      defaultMaterial, button);

            buttonMesh.RotateD(Vector3f.AxisX, -90.0f); // ??

            if (text.Length > 0)
            {
                UpdateText();
            }
        }
示例#15
0
        public virtual DMeshSO Create(DMesh3 mesh, SOMaterial setMaterial)
        {
            AssignSOMaterial(setMaterial);       // need to do this to setup BaseSO material stack
            parentGO = GameObjectFactory.CreateParentGO(UniqueNames.GetNext("DMesh"));

            this.mesh = mesh;



            on_mesh_changed();
            validate_view_meshes();

            return(this);
        }
示例#16
0
        // creates a button that is just the mesh, basically same as above but without the background disc
        public void Create(PrimitiveType eType, Material primMaterial, float fPrimScale = 1.0f)
        {
            button = new GameObject(UniqueNames.GetNext("HUDButton"));

            buttonMesh = AppendUnityPrimitiveGO(UniqueNames.GetNext("HUDButton"), eType, primMaterial, button);
            float primSize = Shape.EffectiveRadius() * fPrimScale;

            buttonMesh.transform.localScale = new Vector3(primSize, primSize, primSize);
            buttonMesh.transform.Translate(0.0f, 0.0f, -primSize);
            buttonMesh.transform.Rotate(-15.0f, 45.0f, 0.0f, Space.Self);
            MaterialUtil.DisableShadows(buttonMesh);

            standard_mat = new fMaterial(primMaterial);
        }
示例#17
0
        public SphereSO Create(SOMaterial defaultMaterial)
        {
            AssignSOMaterial(defaultMaterial);       // need to do this to setup BaseSO material stack

            sphere     = new GameObject(UniqueNames.GetNext("Sphere"));
            sphereMesh = AppendUnityPrimitiveGO("sphereMesh", PrimitiveType.Sphere, CurrentMaterial, sphere);
            sphereMesh.transform.localScale = new Vector3(2 * radius, 2 * radius, 2 * radius);

            update_shift();
            sphere.transform.position += centerShift;

            increment_timestamp();
            return(this);
        }
示例#18
0
        // remove all scene stuff and reset view to default
        public void NewScene()
        {
            if (InCameraManipulation)
            {
                return;     // not supported yet
            }
            Scene.RemoveAllSceneObjects();
            Scene.RemoveAllUIElements();
            Scene.SetCurrentTime(0);

            UniqueNames.Reset();

            ResetView();
        }
示例#19
0
        public BoxSO Create(SOMaterial defaultMaterial)
        {
            AssignSOMaterial(defaultMaterial);       // need to do this to setup BaseSO material stack

            box     = new GameObject(UniqueNames.GetNext("Box"));
            boxMesh = AppendUnityPrimitiveGO("boxMesh", PrimitiveType.Cube, CurrentMaterial, box);
            boxMesh.transform.localScale = new Vector3(width, height, depth);

            update_shift();
            box.transform.position += centerShift;

            increment_timestamp();
            return(this);
        }
示例#20
0
        // actually create GO elements, etc
        public void Create()
        {
            entry = GameObjectFactory.CreateParentGO(UniqueNames.GetNext("HUDPopupMessage"));

            bgMesh = AppendMeshGO("background", make_background_mesh(),
                                  MaterialUtil.CreateFlatMaterialF(BackgroundColor),
                                  entry);
            bgMesh.RotateD(Vector3f.AxisX, -90.0f);


            IBoxModelElement contentArea = BoxModel.PaddedBounds(this, Padding);

            BoxPosition titleBoxPos = BoxModel.ToPosition(TitleAlignment, VerticalAlignment.Top);

            titleTextMesh = (titleText == "") ? null : GameObjectFactory.CreateTextMeshGO(
                "title", TitleText, TextColor, TitleTextHeight, titleBoxPos, SceneGraphConfig.TextLabelZOffset);
            float fTitleHeight = 0;

            if (titleTextMesh != null)
            {
                Vector2f titleToPos = BoxModel.GetBoxPosition(contentArea, titleBoxPos);
                BoxModel.Translate(titleTextMesh, Vector2f.Zero, titleToPos);
                AppendNewGO(titleTextMesh, entry, false);
                fTitleHeight = TitleTextHeight;
            }

            IBoxModelElement messageArea = BoxModel.PaddedBounds(contentArea, 0, 0, 0, Padding + fTitleHeight);
            Vector2f         textDims    = messageArea.Size2D;

            BoxPosition textBoxPos = BoxModel.ToPosition(Alignment, VerticalAlignment.Top);

            textMesh = GameObjectFactory.CreateTextAreaGO(
                "message", Text, TextColor, TextHeight, textDims, Alignment, textBoxPos, SceneGraphConfig.TextLabelZOffset);
            Vector2f textToPos = BoxModel.GetBoxPosition(messageArea, textBoxPos);

            BoxModel.Translate(textMesh, Vector2f.Zero, textToPos);
            AppendNewGO(textMesh, entry, false);



            if (EnableClickToDismiss)
            {
                footerTextMesh = GameObjectFactory.CreateTextMeshGO(
                    "footer", DismissText, DismissTextColor, TextHeight * 0.5f,
                    BoxPosition.CenterBottom, SceneGraphConfig.TextLabelZOffset);
                BoxModel.Translate(footerTextMesh, Vector2f.Zero, BoxModel.GetBoxPosition(contentArea, BoxPosition.CenterBottom));
                AppendNewGO(footerTextMesh, entry, false);
            }
        }
示例#21
0
        // creates a button in the desired geometry shape
        public void Create(Material defaultMaterial, Material disabledMaterial = null)
        {
            button     = new GameObject(UniqueNames.GetNext("HUDButton"));
            buttonMesh = AppendMeshGO("disc", make_button_body_mesh(),
                                      defaultMaterial, button);

            buttonMesh.transform.Rotate(Vector3.right, -90.0f);              // ??
            MaterialUtil.DisableShadows(buttonMesh);

            standard_mat = new fMaterial(defaultMaterial);
            if (disabledMaterial != null)
            {
                disabled_mat = new fMaterial(disabledMaterial);
            }
        }
示例#22
0
        public virtual DMeshSO Create(DMesh3 mesh, SOMaterial setMaterial)
        {
            AssignSOMaterial(setMaterial);       // need to do this to setup BaseSO material stack
            parentGO = GameObjectFactory.CreateParentGO(UniqueNames.GetNext("DMesh"));

            this.mesh = mesh;

            //viewMeshes = new LinearDecompViewMeshManager(this);
            viewMeshes = new TrivialViewMeshManager(this);

            on_mesh_changed();
            viewMeshes.ValidateViewMeshes();

            return(this);
        }
示例#23
0
        public virtual MeshSO Create(Mesh mesh, SOMaterial setMaterial)
        {
            AssignSOMaterial(setMaterial);       // need to do this to setup BaseSO material stack

            parentGO = GameObjectFactory.CreateParentGO(UniqueNames.GetNext("Mesh"));

            meshGO = new GameObject("mesh");
            meshGO.AddComponent <MeshFilter>();
            meshGO.SetMesh(mesh);
            meshGO.AddComponent <MeshCollider>().enabled  = false;
            meshGO.AddComponent <MeshRenderer>().material = CurrentMaterial;

            AppendNewGO(meshGO, (GameObject)parentGO, true);
            return(this);
        }
示例#24
0
        // creates a button in the desired geometry shape
        public void Create()
        {
            entry = GameObjectFactory.CreateParentGO(UniqueNames.GetNext("HUDLabel"));

            bgMesh = AppendMeshGO("background", HUDUtil.MakeBackgroundMesh(Shape),
                                  MaterialUtil.CreateFlatMaterialF(BackgroundColor),
                                  entry);
            bgMesh.RotateD(Vector3f.AxisX, -90.0f);


            if (EnableBorder)
            {
                HUDShape borderShape = Shape;
                borderShape.Radius += BorderWidth;
                borderShape.Height += 2 * BorderWidth;
                borderShape.Width  += 2 * BorderWidth;
                border              = AppendMeshGO("border", HUDUtil.MakeBackgroundMesh(borderShape),
                                                   MaterialUtil.CreateFlatMaterialF(BorderColor), entry);
                border.RotateD(Vector3f.AxisX, -90.0f);
                border.Translate(-0.001f * Vector3f.AxisY, true);
            }

            BoxPosition horzAlign = BoxPosition.CenterLeft;

            if (AlignmentHorz == HorizontalAlignment.Center)
            {
                horzAlign = BoxPosition.Center;
            }
            else if (AlignmentHorz == HorizontalAlignment.Right)
            {
                horzAlign = BoxPosition.CenterRight;
            }

            textMesh =
                GameObjectFactory.CreateTextMeshGO(
                    "text", Text, TextColor, TextHeight, horzAlign, SceneGraphConfig.TextLabelZOffset);

            textMesh.TextObject.SetFixedWidth(Shape.Width);
            textMesh.TextObject.SetOverflowMode(TextOverflowMode.Ellipses);

            Vector2f toPos = BoxModel.GetBoxPosition(this, horzAlign);

            BoxModel.Translate(textMesh, Vector2f.Zero, toPos);

            AppendNewGO(textMesh, entry, false);

            MaterialUtil.DisableShadows(RootGameObject);
        }
示例#25
0
        // creates a button with a background shape and a foreground mesh
        public void Create(fMaterial bgMaterial, fMesh mesh, fMaterial meshMaterial, float fScale, Frame3f deltaF)
        {
            button = GameObjectFactory.CreateParentGO(UniqueNames.GetNext("HUDButton"));

            buttonMesh = AppendMeshGO("shape", HUDUtil.MakeBackgroundMesh(this.Shape), bgMaterial, button);
            buttonMesh.RotateD(Vector3f.AxisX, -90.0f); // ??
            MaterialUtil.DisableShadows(buttonMesh);

            iconMesh = AppendMeshGO("shape", mesh, meshMaterial, button);
            iconMesh.SetLocalScale(new Vector3f(fScale, fScale, fScale));
            iconMesh.SetLocalPosition(deltaF.Origin);
            iconMesh.SetLocalRotation(deltaF.Rotation);
            MaterialUtil.DisableShadows(iconMesh);

            standard_mat = new fMaterial(bgMaterial);
        }
示例#26
0
        // creates a button with a background shape and a foreground mesh
        public void Create(Material bgMaterial, Mesh mesh, Material meshMaterial, float fScale, Frame3f deltaF)
        {
            button = new GameObject(UniqueNames.GetNext("HUDButton"));

            buttonMesh = AppendMeshGO("disc", make_button_body_mesh(), bgMaterial, button);
            buttonMesh.transform.Rotate(Vector3.right, -90.0f); // ??
            MaterialUtil.DisableShadows(buttonMesh);

            GameObject meshGO = AppendMeshGO("shape", mesh, meshMaterial, button);

            meshGO.transform.localScale    = new Vector3(fScale, fScale, fScale);
            meshGO.transform.localPosition = deltaF.Origin;
            meshGO.transform.localRotation = deltaF.Rotation;
            MaterialUtil.DisableShadows(meshGO);

            standard_mat = new fMaterial(bgMaterial);
        }
示例#27
0
        // creates a button with a floating primitive in front of the button shape
        public void Create(PrimitiveType eType, Material bgMaterial, Material primMaterial, float fPrimScale = 0.7f)
        {
            button     = new GameObject(UniqueNames.GetNext("HUDButton"));
            buttonMesh = AppendMeshGO("disc", make_button_body_mesh(), bgMaterial, button);
            buttonMesh.transform.Rotate(Vector3.right, -90.0f);              // ??
            MaterialUtil.DisableShadows(buttonMesh);

            GameObject prim     = AppendUnityPrimitiveGO("primitive", eType, primMaterial, button);
            float      primSize = Shape.EffectiveRadius() * fPrimScale;

            prim.transform.localScale = new Vector3(primSize, primSize, primSize);
            prim.transform.Translate(0.0f, 0.0f, -primSize);
            prim.transform.Rotate(-15.0f, 45.0f, 0.0f, Space.Self);
            MaterialUtil.DisableShadows(prim);

            standard_mat = new fMaterial(bgMaterial);
        }
示例#28
0
        // creates a button in the desired geometry shape
        public void Create(fMaterial defaultMaterial, fMaterial disabledMaterial = null, fMaterial hoverMaterial = null)
        {
            button     = GameObjectFactory.CreateParentGO(UniqueNames.GetNext("HUDButton"));
            buttonMesh = AppendMeshGO("shape", HUDUtil.MakeBackgroundMesh(this.Shape),
                                      defaultMaterial, button);
            buttonMesh.RotateD(Vector3f.AxisX, -90.0f); // ??
            MaterialUtil.DisableShadows(buttonMesh);

            standard_mat = defaultMaterial;
            if (disabledMaterial != null)
            {
                disabled_mat = disabledMaterial;
            }
            if (hoverMaterial != null)
            {
                hover_mat = hoverMaterial;
            }
        }
示例#29
0
        public MeshReferenceSO GetMeshReference(SOMaterial defaultMaterial)
        {
            MeshReferenceSO ref_group = new MeshReferenceSO();

            ref_group.MeshReferencePath = sSourcePath;
            ref_group.Create();
            ref_group.Name = UniqueNames.GetNext("MeshReference");

            foreach (ImportedObject obj in SceneObjects)
            {
                DMeshSO meshSO = new DMeshSO();
                meshSO.Create(obj.mesh,
                              (obj.material == null) ? defaultMaterial : obj.material);
                meshSO.Name = UniqueNames.GetNext("ImportMesh");
                ref_group.AddChild(meshSO);
            }

            return(ref_group);
        }
        // add the meshes we have read into SceneObjects list to the given Scene
        public void AppendReadMeshesToScene(FScene scene, bool bSaveHistory)
        {
            if (ImportBehavior == ImportMode.AsMeshReference)
            {
                MeshReferenceSO ref_group = GetMeshReference(scene.DefaultMeshSOMaterial);

                var change = new AddSOChange()
                {
                    scene = scene, so = ref_group
                };
                if (bSaveHistory)
                {
                    scene.History.PushChange(change);
                }
                else
                {
                    change.Apply();
                }
            }
            else
            {
                foreach (ImportedObject obj in SceneObjects)
                {
                    MeshSO meshSO = new MeshSO();
                    meshSO.Create(obj.mesh,
                                  (obj.material == null) ? scene.DefaultMeshSOMaterial : obj.material);
                    meshSO.Name = UniqueNames.GetNext("ImportMesh");

                    var change = new AddSOChange()
                    {
                        scene = scene, so = meshSO
                    };
                    if (bSaveHistory)
                    {
                        scene.History.PushChange(change);
                    }
                    else
                    {
                        change.Apply();
                    }
                }
            }
        }