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; } }
}
}
}