using UnityEngine; using System.Collections.Generic; namespace BrainFailProductions.PolyFew.AsImpL { /// /// Data set for storing data in a neutral format for a generic model /// /// This should be completed and extended to support more formats. /// TODO: Classes to hold data for internal hierarchy should be defined. public class DataSet { /// /// List of objects /// public List objectList = new List(); /// /// List of vertices /// public List vertList = new List(); /// /// List of texture coordinates (UV) /// public List uvList = new List(); /// /// List of normals /// public List normalList = new List(); /// /// List of colors /// public List colorList = new List(); // naming index for unnamed group (e.g. "Unnamed-1") private int unnamedGroupIndex = 1; private ObjectData currObjData; private FaceGroupData currGroup; private bool noFaceDefined = true; /// /// Name of the current group. /// public string CurrGroupName { get { return currGroup != null ? currGroup.name : ""; } } /// /// Check if there is no vertex defined. /// public bool IsEmpty { get { return vertList.Count == 0; } } /// /// Get a string key based on the given face indices /// /// face indices structure /// public static string GetFaceIndicesKey(FaceIndices fi) { return fi.vertIdx.ToString() + "/" + fi.uvIdx.ToString() + "/" + fi.normIdx.ToString(); } /// /// Change the material name to be compliant with Unity material asset naming. /// /// original material name /// Returns the name modified to be compliant with Unity material asset naming. public static string FixMaterialName(string mtlName) { return mtlName .Replace(':', '_') .Replace('\\', '_') .Replace('/', '_') .Replace('*', '_') .Replace('?', '_') .Replace('<', '_') .Replace('>', '_') .Replace('|', '_'); } /// /// Constructor: create data lists and initialzize the default object. /// public DataSet() { ObjectData d = new ObjectData(); d.name = "default"; objectList.Add(d); currObjData = d; FaceGroupData g = new FaceGroupData(); g.name = "default"; d.faceGroups.Add(g); currGroup = g; } /// /// Add and initialize a new object. /// /// name of the new object public void AddObject(string objectName) { //Debug.Log("Adding new object " + name + ". Current is empty: " + isEmpty); string currentMaterial = currObjData.faceGroups[currObjData.faceGroups.Count - 1].materialName; if (noFaceDefined) objectList.Remove(currObjData); ObjectData objData = new ObjectData(); objData.name = objectName; objectList.Add(objData); FaceGroupData grp = new FaceGroupData(); grp.materialName = currentMaterial; grp.name = "default"; objData.faceGroups.Add(grp); currGroup = grp; currObjData = objData; } /// /// Add and initialize a new group and add it to the current object. /// /// name of the new group public void AddGroup(string groupName) { string currentMaterial = currObjData.faceGroups[currObjData.faceGroups.Count - 1].materialName; if (currGroup.IsEmpty) currObjData.faceGroups.Remove(currGroup); FaceGroupData grp = new FaceGroupData(); grp.materialName = currentMaterial; if (groupName == null) { groupName = "Unnamed-" + unnamedGroupIndex; unnamedGroupIndex++; } grp.name = groupName; currObjData.faceGroups.Add(grp); currGroup = grp; } /// /// Set a new material name to the current group (add a group if not yet added). /// /// name of the new material /// TODO: do not split by materials if there is only one meterial public void AddMaterialName(string matName) { if (!currGroup.IsEmpty) AddGroup(matName); if (currGroup.name == "default") currGroup.name = matName; currGroup.materialName = matName; } /// /// Add a vertex to the global vertex list /// /// new vertex public void AddVertex(Vector3 vertex) { vertList.Add(vertex); } /// /// Add a texture coordinate (U,V) to the global list /// /// texture coordinate (U,V) public void AddUV(Vector2 uv) { uvList.Add(uv); } /// /// Add a new normal to the global list /// /// normal public void AddNormal(Vector3 normal) { normalList.Add(normal); } /// /// Add a new color to the global list /// /// color public void AddColor(Color color) { colorList.Add(color); currObjData.hasColors = true; } /// /// Add a new face indices entry to the current faces group /// /// new vertex indices public void AddFaceIndices(FaceIndices faceIdx) { noFaceDefined = false; currGroup.faces.Add(faceIdx); currObjData.allFaces.Add(faceIdx); if (faceIdx.normIdx >= 0) { currObjData.hasNormals = true; } } /// /// Print a summary of the stored data /// public void PrintSummary() { string stats = "This data set has " + objectList.Count + " object(s)" + "\n " + vertList.Count + " vertices" + "\n " + uvList.Count + " uvs" + "\n " + normalList.Count + " normals"; foreach (ObjectData od in objectList) { stats += "\n " + od.name + " has " + od.faceGroups.Count + " group(s)"; foreach (FaceGroupData gd in od.faceGroups) { stats += "\n " + gd.name + " has " + gd.faces.Count + " faces(s)"; } } Debug.Log(stats); } /// /// Indices for each vertex /// public struct FaceIndices { public int vertIdx; public int uvIdx; public int normIdx; } /// /// Container class for object data. /// public class ObjectData { public string name; public List faceGroups = new List(); public List allFaces = new List(); public bool hasNormals = false; public bool hasColors = false; public ObjectData() { } } /// /// Container class for faces group data. /// public class FaceGroupData { public string name; public string materialName; public List faces; public FaceGroupData() { faces = new List(); } public bool IsEmpty { get { return faces.Count == 0; } } } } }