Example #1
0
        public override void AbcGetConfig(ref AbcAPI.aiConfig config)
        {
            if (m_normalsMode != AbcAPI.aiNormalsModeOverride.InheritStreamSetting)
            {
                config.normalsMode = (AbcAPI.aiNormalsMode)m_normalsMode;
            }

            if (m_tangentsMode != AbcAPI.aiTangentsModeOverride.InheritStreamSetting)
            {
                config.tangentsMode = (AbcAPI.aiTangentsMode)m_tangentsMode;
            }

            if (m_faceWinding != AbcAPI.aiFaceWindingOverride.InheritStreamSetting)
            {
                config.swapFaceWinding = (m_faceWinding == AbcAPI.aiFaceWindingOverride.Swap);
            }

            config.cacheTangentsSplits = m_cacheTangentsSplits;

            // if 'forceUpdate' is set true, even if alembic sample data do not change at all
            // AbcSampleUpdated will still be called (topologyChanged will be false)

            AlembicMaterial abcMaterials = m_trans.GetComponent <AlembicMaterial>();

            config.forceUpdate = m_freshSetup || (abcMaterials != null ? abcMaterials.HasFacesetsChanged() : hasFacesets);
        }
Example #2
0
        public override void AbcSampleUpdated(AbcAPI.aiSample sample, bool topologyChanged)
        {
            AlembicMaterial abcMaterials = m_trans.GetComponent <AlembicMaterial>();

            if (abcMaterials != null)
            {
                if (abcMaterials.HasFacesetsChanged())
                {
                    AbcVerboseLog("AlembicMesh.AbcSampleUpdated: Facesets updated, force topology update");
                    topologyChanged = true;
                }

                hasFacesets = (abcMaterials.GetFacesetsCount() > 0);
            }
            else if (hasFacesets)
            {
                AbcVerboseLog("AlembicMesh.AbcSampleUpdated: Facesets cleared, force topology update");
                topologyChanged = true;
                hasFacesets     = false;
            }

            if (m_freshSetup)
            {
                topologyChanged = true;

                m_freshSetup = false;
            }

            AbcAPI.aiPolyMeshGetSampleSummary(sample, ref m_sampleSummary, topologyChanged);

            AbcAPI.aiPolyMeshData vertexData = default(AbcAPI.aiPolyMeshData);

            UpdateSplits(m_sampleSummary.splitCount);

            for (int s = 0; s < m_sampleSummary.splitCount; ++s)
            {
                Split split = m_splits[s];

                split.clear  = topologyChanged;
                split.active = true;

                int vertexCount = AbcAPI.aiPolyMeshGetVertexBufferLength(sample, s);

                Array.Resize(ref split.positionCache, vertexCount);
                vertexData.positions = GetArrayPtr(split.positionCache);

                if (m_sampleSummary.hasNormals)
                {
                    Array.Resize(ref split.normalCache, vertexCount);
                    vertexData.normals = GetArrayPtr(split.normalCache);
                }
                else
                {
                    Array.Resize(ref split.normalCache, 0);
                    vertexData.normals = IntPtr.Zero;
                }

                if (m_sampleSummary.hasUVs)
                {
                    Array.Resize(ref split.uvCache, vertexCount);
                    vertexData.uvs = GetArrayPtr(split.uvCache);
                }
                else
                {
                    Array.Resize(ref split.uvCache, 0);
                    vertexData.uvs = IntPtr.Zero;
                }

                if (m_sampleSummary.hasTangents)
                {
                    Array.Resize(ref split.tangentCache, vertexCount);
                    vertexData.tangents = GetArrayPtr(split.tangentCache);
                }
                else
                {
                    Array.Resize(ref split.tangentCache, 0);
                    vertexData.tangents = IntPtr.Zero;
                }

                AbcAPI.aiPolyMeshFillVertexBuffer(sample, s, ref vertexData);

                split.center = vertexData.center;
                split.size   = vertexData.size;
            }

            if (topologyChanged)
            {
                AbcAPI.aiFacesets       facesets       = default(AbcAPI.aiFacesets);
                AbcAPI.aiSubmeshSummary submeshSummary = default(AbcAPI.aiSubmeshSummary);
                AbcAPI.aiSubmeshData    submeshData    = default(AbcAPI.aiSubmeshData);

                if (abcMaterials != null)
                {
                    abcMaterials.GetFacesets(ref facesets);
                }

                int numSubmeshes = AbcAPI.aiPolyMeshPrepareSubmeshes(sample, ref facesets);

                if (m_submeshes.Count > numSubmeshes)
                {
                    m_submeshes.RemoveRange(numSubmeshes, m_submeshes.Count - numSubmeshes);
                }

                for (int s = 0; s < m_sampleSummary.splitCount; ++s)
                {
                    m_splits[s].submeshCount = AbcAPI.aiPolyMeshGetSplitSubmeshCount(sample, s);
                }

                while (AbcAPI.aiPolyMeshGetNextSubmesh(sample, ref submeshSummary))
                {
                    if (submeshSummary.splitIndex >= m_splits.Count)
                    {
                        Debug.Log("Invalid split index");
                        continue;
                    }

                    Submesh submesh = null;

                    if (submeshSummary.index < m_submeshes.Count)
                    {
                        submesh = m_submeshes[submeshSummary.index];
                    }
                    else
                    {
                        submesh = new Submesh
                        {
                            indexCache   = new int[0],
                            facesetIndex = -1,
                            splitIndex   = -1,
                            index        = -1,
                            update       = true
                        };

                        m_submeshes.Add(submesh);
                    }

                    submesh.facesetIndex = submeshSummary.facesetIndex;
                    submesh.splitIndex   = submeshSummary.splitIndex;
                    submesh.index        = submeshSummary.splitSubmeshIndex;
                    submesh.update       = true;

                    Array.Resize(ref submesh.indexCache, 3 * submeshSummary.triangleCount);

                    submeshData.indices = GetArrayPtr(submesh.indexCache);

                    AbcAPI.aiPolyMeshFillSubmeshIndices(sample, ref submeshSummary, ref submeshData);
                }

                if (abcMaterials != null)
                {
                    abcMaterials.AknowledgeFacesetsChanges();
                }
            }
            else
            {
                for (int i = 0; i < m_submeshes.Count; ++i)
                {
                    m_submeshes[i].update = false;
                }
            }

            AbcDirty();
        }
        public void OnGUI()
        {
            float hp = 5;
            float vp = 5;
            float hs = 5;
            float rh = 16;
            float lw;
            float fw;
            float bw;
            Rect  r;

            // Material assignment file controls
            r  = NewControlRect(true, rh, hp, vp);
            lw = r.width * 0.33f;

            EditorGUI.PrefixLabel(new Rect(r.x, r.y, lw, r.height), new GUIContent("Assignments File"));

            bw      = 26;
            fw      = r.width - lw - bw - 2 * hs;
            xmlPath = EditorGUI.TextField(new Rect(r.x + lw + hs, r.y, fw, r.height), xmlPath);
            if (GUI.Button(new Rect(r.x + lw + hs + fw + hs, r.y, bw, r.height), "..."))
            {
                string startFolder = (xmlPath.Length > 0 ? Path.GetDirectoryName(xmlPath) : Application.dataPath);
                xmlPath = MakeDataRelativePath(EditorUtility.OpenFilePanel("Select Material Assignment File", startFolder, "xml"));

                if (xmlPath.Length > 0)
                {
                    materialFolder = Path.GetDirectoryName(xmlPath);
                }
            }

            // Material folder controls
            r  = NewControlRect(true, rh, hp, vp);
            lw = r.width * 0.33f;

            EditorGUI.PrefixLabel(new Rect(r.x, r.y, lw, r.height), new GUIContent("Materials Folder"));

            bw             = 26;
            fw             = r.width - lw - bw - 2 * hs;
            materialFolder = EditorGUI.TextField(new Rect(r.x + lw + hs, r.y, fw, r.height), materialFolder);
            if (GUI.Button(new Rect(r.x + lw + hs + fw + hs, r.y, bw, r.height), "..."))
            {
                string startFolder = (materialFolder.Length > 0 ? materialFolder : Application.dataPath);
                materialFolder = MakeDataRelativePath(EditorUtility.OpenFolderPanel("Select Materials Folder", startFolder, ""));
            }

            // Target asset node controls
            r  = NewControlRect(true, rh, hp, vp);
            lw = r.width * 0.33f;

            EditorGUI.PrefixLabel(new Rect(r.x, r.y, lw, r.height), new GUIContent("Asset Root"));

            fw        = r.width - lw - hs;
            assetRoot = (GameObject)EditorGUI.ObjectField(new Rect(r.x + lw + hs, r.y, fw, r.height), assetRoot, typeof(GameObject), true);

            // Action buttons
            r  = NewControlRect(false, rh, hp, vp);
            bw = 0.5f * (r.width - hs);

            if (GUI.Button(new Rect(r.x, r.y, bw, r.height), "Import"))
            {
                AlembicMaterial.Import(Application.dataPath + "/" + xmlPath, assetRoot, "Assets/" + materialFolder); //relMatFolder);
            }

            if (GUI.Button(new Rect(r.x + bw + hs, r.y, bw, r.height), "Export"))
            {
                AlembicMaterial.Export(Application.dataPath + "/" + xmlPath, assetRoot);
            }
        }
        public static void Import(string xmlPath, GameObject root, string materialFolder)
        {
            XmlDocument doc = new XmlDocument();

            doc.Load(xmlPath);

            XmlNode xmlRoot = doc.DocumentElement;

            XmlNodeList nodes = xmlRoot.SelectNodes("/assignments/node");

            Dictionary <GameObject, List <AlembicMaterial.Assignment> > allAssignments = new Dictionary <GameObject, List <AlembicMaterial.Assignment> >();

            foreach (XmlNode node in nodes)
            {
                string path = node.Attributes["path"].Value;

                XmlNodeList shaders = node.SelectNodes("shader");

                foreach (XmlNode shader in shaders)
                {
                    XmlAttribute name = shader.Attributes["name"];
                    XmlAttribute inst = shader.Attributes["instance"];

                    if (name == null)
                    {
                        continue;
                    }

                    int instNum = (inst == null ? 0 : Convert.ToInt32(inst.Value));

                    GameObject target = FindNode(root, path, instNum);

                    if (target == null)
                    {
                        // Debug.Log("Could not find node: " + path);
                        continue;
                    }

                    List <AlembicMaterial.Assignment> assignments;

                    if (!allAssignments.ContainsKey(target))
                    {
                        assignments = new List <AlembicMaterial.Assignment>();
                        allAssignments.Add(target, assignments);
                    }
                    else
                    {
                        assignments = allAssignments[target];
                    }

                    Material material = GetMaterial(name.Value, materialFolder);

                    if (material == null)
                    {
                        material = new Material(Shader.Find("Standard"));

                        material.color = new Color(UnityEngine.Random.value,
                                                   UnityEngine.Random.value,
                                                   UnityEngine.Random.value);

                        AssetDatabase.CreateAsset(material, materialFolder + "/" + name.Value + ".mat");
                    }

                    // Get or create material assignment
                    bool newlyAssigned           = false;
                    AlembicMaterial.Assignment a = null;

                    if (a == null)
                    {
                        a          = new AlembicMaterial.Assignment();
                        a.material = material;
                        a.faces    = new List <int>();

                        assignments.Add(a);

                        newlyAssigned = true;
                    }

                    string faceset = shader.InnerText;
                    faceset.Trim();

                    if (faceset.Length > 0 && (newlyAssigned || a.faces.Count > 0))
                    {
                        string[] items = faceset.Split(FaceSep, StringSplitOptions.RemoveEmptyEntries);

                        for (int i = 0; i < items.Length; ++i)
                        {
                            string[] rng = items[i].Split(RangeSep, StringSplitOptions.RemoveEmptyEntries);

                            if (rng.Length == 1)
                            {
                                a.faces.Add(Convert.ToInt32(rng[0]));
                            }
                            else if (rng.Length == 2)
                            {
                                int j0 = Convert.ToInt32(rng[0]);
                                int j1 = Convert.ToInt32(rng[1]);

                                for (int j = j0; j <= j1; ++j)
                                {
                                    a.faces.Add(j);
                                }
                            }
                        }

                        if (!newlyAssigned)
                        {
                            a.faces = new List <int>(new HashSet <int>(a.faces));
                        }
                    }
                    else if (faceset.Length == 0 && a.faces.Count > 0)
                    {
                        // Shader assgined to whole object, remove any face level assignments
                        a.faces.Clear();
                    }
                }
            }

            // Update AlembicMaterial components
            foreach (KeyValuePair <GameObject, List <AlembicMaterial.Assignment> > pair in allAssignments)
            {
                AlembicMaterial abcmaterial = pair.Key.GetComponent <AlembicMaterial>();

                if (abcmaterial == null)
                {
                    abcmaterial = pair.Key.AddComponent <AlembicMaterial>();
                }

                abcmaterial.UpdateAssignments(pair.Value);
            }

            // Force refresh
            AlembicStream abcstream = root.GetComponent <AlembicStream>();

            if (abcstream != null)
            {
                abcstream.m_forceRefresh = true;
                abcstream.SendMessage("AbcUpdate", abcstream.m_time, SendMessageOptions.DontRequireReceiver);
            }
        }