Exemplo n.º 1
0
        private string ComputeHash(Scene scene, Transform trans)
        {
            Binary.Buffer buffer = Module.Import.Binary.serializer.GetBuffer(5 * 1024);             // Start with 5 Ko buffer

            uint written = 0;

            foreach (Component component in trans.GetComponents <Component>())
            {
                if (SerializedComponent(component))
                {
                    written += Module.Import.Binary.serializer.ToBytes(ref buffer, written, UnityComponent.FromUnity(scene, component));
                }
            }

            uint size = (uint)System.Text.Encoding.UTF8.GetByteCount(name);

            size += 2 * Binary.Size(Binary.SupportedTypes.UNITY_VECTOR3);
            size += Binary.Size(Binary.SupportedTypes.UNITY_QUATERNION);

            Module.Import.Binary.serializer.ResizeBuffer(ref buffer, written + size);

            written += Module.Import.Binary.serializer.ToBytes(ref buffer, written, trans.name);
            written += Module.Import.Binary.serializer.ToBytes(ref buffer, written, trans.localPosition);
            written += Module.Import.Binary.serializer.ToBytes(ref buffer, written, trans.localRotation);
            written += Module.Import.Binary.serializer.ToBytes(ref buffer, written, trans.localScale);

            return(Hash.ComputeHash(buffer.Data, 0, (int)written));
        }
Exemplo n.º 2
0
        public static IEnumerator FromUnity(Scene scene, Transform node, Action <Node> callback, Progress progress = null, LinkedList <Transform> meshes_nodes = null)
        {
            if (scene != null && node != null && callback != null)
            {
                // Create a new node
                Node current = new Node();

                // Handle easy stuff
                current.id        = scene.IdMapping.GetNewId();
                current.name      = node.name;
                current.tag       = node.tag;
                current.layer     = node.gameObject.layer;
                current.active    = node.gameObject.activeSelf;
                current.hideFlags = node.gameObject.hideFlags;
                current.position  = node.localPosition;
                current.rotation  = node.localRotation;
                current.scale     = node.localScale;

                // Update mapping
                scene.IdMapping.Add(node.gameObject, current.id);

                // Handle components
                current.components = node.gameObject.GetComponents <Component>()
                                     .Where(SerializedComponent)
                                     .Select(c => UnityComponent.FromUnity(scene, c))
                                     .ToArray();

                // Handle meshes and materials
                List <GraphicMesh> graphic_meshes = new List <GraphicMesh>();

                FromUnityMeshAndMaterials(scene, node, ref graphic_meshes);

                if (meshes_nodes != null)
                {
                    foreach (Transform t in meshes_nodes)
                    {
                        FromUnityMeshAndMaterials(scene, t, ref graphic_meshes);
                    }
                }

                if (graphic_meshes.Count > 0)
                {
                    current.meshes = graphic_meshes.ToArray();
                }

                // Handle children
                if (node.childCount > 0)
                {
                    Dictionary <string, LinkedList <Transform> > children_sorted = new Dictionary <string, LinkedList <Transform> >();

                    // Group all children by hash, i.e. same name, transform, components and metadata
                    foreach (Transform child in node)
                    {
                        LinkedList <Transform> group;

                        string hash = current.ComputeHash(scene, child);

                        if (!children_sorted.TryGetValue(hash, out group))
                        {
                            group = new LinkedList <Transform>();

                            children_sorted.Add(hash, group);
                        }

                        group.AddLast(child);
                    }

                    List <Node> children_nodes = new List <Node>(children_sorted.Count);

                    foreach (KeyValuePair <string, LinkedList <Transform> > pair in children_sorted)
                    {
                        // For each hash, check how many children have a descendancy
                        int child_count = pair.Value.Count(t => t.childCount > 0);

                        // Only one with descendancy ? The nodes must be grouped as they are only different meshes of the original unique node
                        if (child_count <= 1)
                        {
                            Transform main_child = null;

                            // No families at all ? Select the first one of the meshes to serve as the main one
                            if (child_count <= 0 || pair.Value.First.Value.childCount > 0)
                            {
                                main_child = pair.Value.First.Value;

                                pair.Value.RemoveFirst();
                            }
                            else // Main child is not he first one. We need to manually search for it.
                            {
                                LinkedListNode <Transform> list_node = pair.Value.First;
                                LinkedListNode <Transform> list_end  = pair.Value.Last;

                                while (list_node.Value.childCount <= 0 && list_node != list_end)
                                {
                                    list_node = list_node.Next;
                                }

                                if (list_node.Value.childCount > 0)
                                {
                                    main_child = list_node.Value;

                                    pair.Value.Remove(list_node);
                                }
                            }

                            if (main_child != null)
                            {
                                pair.Value.Remove(main_child);

                                IEnumerator it_progress = FromUnity(scene, main_child, children_nodes.Add, progress, pair.Value);

                                while (it_progress.MoveNext())
                                {
                                    yield return(it_progress.Current);
                                }
                            }
                        }
                        else                         // Many families ? We don't have sufficient information to group the nodes together
                        {
                            foreach (Transform child in pair.Value)
                            {
                                IEnumerator it = FromUnity(scene, child, children_nodes.Add, progress);

                                while (it.MoveNext())
                                {
                                    yield return(it.Current);
                                }
                            }
                        }

                        // Yield between each children nodes
                        yield return(null);
                    }

                    if (children_nodes.Count > 0)
                    {
                        current.children = children_nodes.ToArray();
                    }
                }

                callback(current);

                if (progress != null)
                {
                    progress.Update(1);
                }
            }
        }