public static Component_TransformOffset Attach(Component_ObjectInSpace attachTo, Component_ObjectInSpace objectToAttach, DocumentInstance documentforUndoRedo = null, UndoMultiAction undoMultiAction = null)
        {
            var objectToTransform = CalculateObjectToTransform(objectToAttach);

            if (objectToTransform != null)
            {
                objectToAttach = objectToTransform;
            }

            //create _TransformOffset
            Component_TransformOffset transformOffset;

            {
                const string transformOffsetName = "Attach Transform Offset";

                transformOffset        = objectToAttach.CreateComponent <Component_TransformOffset>(enabled: false);
                transformOffset.Name   = transformOffsetName;
                transformOffset.Source = ReferenceUtility.MakeReference <Transform>(null, ReferenceUtility.CalculateThisReference(transformOffset, attachTo, "Transform"));

                try
                {
                    var f      = attachTo.Transform.Value;
                    var s      = objectToAttach.Transform.Value;
                    var offset = f.ToMatrix4().GetInverse() * s.ToMatrix4();
                    offset.Decompose(out Vector3 pos, out Quaternion rot, out Vector3 scl);

                    transformOffset.PositionOffset = pos;
                    transformOffset.RotationOffset = rot;
                    transformOffset.ScaleOffset    = scl;
                    //transformOffset.Matrix = offset;

                    //var offset = new Mat4( s.Rotation.ToMat3(), s.Position ) * new Mat4( f.Rotation.ToMat3(), f.Position ).GetInverse();
                    //var f = first.Transform.Value;
                    //var s = second.Transform.Value;
                    //var offset = new Mat4( s.Rotation.ToMat3(), s.Position ) * new Mat4( f.Rotation.ToMat3(), f.Position ).GetInverse();
                    ////var offset = second.Transform.Value.ToMat4() * first.Transform.Value.ToMat4().GetInverse();
                    //offset.Decompose( out Vec3 pos, out Quat rot, out Vec3 scl );

                    //transformOffset.PositionOffset = pos / f.Scale;// / s.Scale;
                    //transformOffset.RotationOffset = rot;

                    //transformOffset.ScaleOffset = s.Scale / f.Scale;
                    ////transformOffset.ScaleOffset = scl;
                }
                catch { }

                transformOffset.Enabled = true;

                if (undoMultiAction != null)
                {
                    undoMultiAction.AddAction(new UndoActionComponentCreateDelete(documentforUndoRedo, new Component[] { transformOffset }, true));
                }
            }

            //change Transform
            {
                //undo action
                if (undoMultiAction != null)
                {
                    var property = (Metadata.Property)objectToAttach.MetadataGetMemberBySignature("property:Transform");
                    var undoItem = new UndoActionPropertiesChange.Item(objectToAttach, property, objectToAttach.Transform, new object[0]);
                    undoMultiAction.AddAction(new UndoActionPropertiesChange(new UndoActionPropertiesChange.Item[] { undoItem }));
                }

                //configure reference
                objectToAttach.Transform = ReferenceUtility.MakeReference <Transform>(null, ReferenceUtility.CalculateThisReference(objectToAttach, transformOffset, "Result"));
            }

            return(transformOffset);
        }
Exemplo n.º 2
0
        public Component_Import3D CreateForPreviewDisplay(Component_Scene scene, out bool onlyOneMaterial, out Dictionary <Component_Mesh, Transform> transformBySourceMesh)
        {
            onlyOneMaterial       = false;
            transformBySourceMesh = new Dictionary <Component_Mesh, Transform>();

            var createdObject = (Component_Import3D)Clone();

            createdObject.Name = "Import3D";
            FixRootReferences(createdObject);
            scene.AddComponent(createdObject);

            //create MeshInSpace for one mesh
            {
                var mesh = createdObject.GetComponent("Mesh") as Component_Mesh;
                if (mesh != null)
                {
                    var objectInSpace = createdObject.CreateComponent <Component_MeshInSpace>();
                    objectInSpace.Mesh = ReferenceUtility.MakeReference <Component_Mesh>(null, ReferenceUtility.CalculateThisReference(objectInSpace, mesh));
                }
            }

            //create meshes in space for Meshes
            {
                var sourceMeshesGroup         = GetComponent("Meshes");
                Component_Mesh[] sourceMeshes = null;
                if (sourceMeshesGroup != null)
                {
                    sourceMeshes = sourceMeshesGroup.GetComponents <Component_Mesh>();
                }

                var createdMeshesGroup = createdObject.GetComponent("Meshes");
                if (createdMeshesGroup != null)
                {
                    var createdMeshes = createdMeshesGroup.GetComponents <Component_Mesh>();

                    var positions = new Vector3[createdMeshes.Length];
                    {
                        if (sourceMeshesGroup != null)
                        {
                            double maxSizeY = 0;
                            foreach (var sourceMesh in sourceMeshesGroup.GetComponents <Component_Mesh>())
                            {
                                if (sourceMesh.Result != null)
                                {
                                    var bounds = sourceMesh.Result.SpaceBounds.CalculatedBoundingBox;
                                    var sizeY  = bounds.GetSize().Y;
                                    if (sizeY > maxSizeY)
                                    {
                                        maxSizeY = sizeY;
                                    }
                                }
                            }
                            var step      = maxSizeY * 1.2;
                            var totalSize = (double)(createdMeshes.Length - 1) * step;

                            for (int n = 0; n < createdMeshes.Length; n++)
                            {
                                var positionY = (double)n * step - totalSize / 2;
                                positions[n] = new Vector3(0, positionY, 0);
                            }
                        }
                    }

                    for (int n = 0; n < createdMeshes.Length; n++)
                    {
                        var createdMesh = createdMeshes[n];

                        var transform = new Transform(positions[n], Quaternion.Identity);

                        var objectInSpace = createdObject.CreateComponent <Component_MeshInSpace>();
                        objectInSpace.Transform = transform;
                        objectInSpace.Mesh      = ReferenceUtility.MakeReference <Component_Mesh>(null, ReferenceUtility.CalculateThisReference(objectInSpace, createdMesh));

                        if (sourceMeshes != null && sourceMeshes.Length == createdMeshes.Length)
                        {
                            transformBySourceMesh[sourceMeshes[n]] = transform;
                        }
                    }
                }
            }

            //create MeshInSpace for only one material
            {
                var material = createdObject.GetComponent("Material") as Component_Material;
                if (material != null)
                {
                    var mesh = ProjectSettings.Get.MaterialPreviewMesh.Value;
                    if (mesh != null)
                    {
                        var objectInSpace = createdObject.CreateComponent <Component_MeshInSpace>();
                        objectInSpace.Mesh = mesh;

                        objectInSpace.ReplaceMaterial = ReferenceUtility.MakeReference <Component_Material>(null, ReferenceUtility.CalculateThisReference(objectInSpace, material));

                        onlyOneMaterial = true;
                    }
                }
            }

            return(createdObject);
        }