Skip to content

Commit

Permalink
NUD bounding sphere updates (#388)
Browse files Browse the repository at this point in the history
* NUD bounding sphere updates

* Tweaks
  • Loading branch information
Dr-HyperCake authored Sep 3, 2024
1 parent f94417f commit 46c13a3
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 205 deletions.
23 changes: 11 additions & 12 deletions Smash Forge/Filetypes/Application/MaterialXML.cs
Original file line number Diff line number Diff line change
Expand Up @@ -115,12 +115,11 @@ private static void WriteMatParams(XmlDocument doc, Nud.Material mat, XmlNode ma
{
float[] values = mat.GetPropertyValues(materialProperty);
// Only print 4 values, to avoid lots of trailing zeroes.
for (int count = 0, max = Math.Min(4, values.Length);;)
for (int i = 0; i < 4 && i < values.Length; i++)
{
paramnode.InnerText += values[count++].ToString("G9");
if (count >= max)
break;
paramnode.InnerText += " ";
if (i > 0)
paramnode.InnerText += " ";
paramnode.InnerText += values[i].ToString("G9");
}

}
Expand Down Expand Up @@ -152,7 +151,7 @@ private static void AddUintAttribute(XmlDocument doc, string name, uint value, X

public static void ImportMaterialAsXml(Nud n, string filename)
{
// Creates a list of materials and then trys to apply the materials to the polygons.
// Creates a list of materials and then tries to apply the materials to the polygons.
int polyCount = CalculatePolygonCount(n);

XmlDocument doc = new XmlDocument();
Expand All @@ -172,7 +171,7 @@ public static void ImportMaterialAsXml(Nud n, string filename)
{
if (!(polynode.Name.Equals("polygon")))
continue;

matCountForPolyId.Add(polynode.ChildNodes.Count);

if (matCountForPolyId.Count > polyCount)
Expand Down Expand Up @@ -222,7 +221,7 @@ private static void ApplyMaterials(Nud n, List<Nud.Material> materialList, List<
}
matIndex += 1;
}

polyIndex += 1;
}
}
Expand Down Expand Up @@ -308,7 +307,7 @@ private static void ReadTextures(Nud.Material material, XmlNode textureNode)
{
if (!(textureNode.Name.Equals("texture")))
return;

Nud.MatTexture matTexture = new Nud.MatTexture();
material.textures.Add(matTexture);

Expand Down Expand Up @@ -346,7 +345,7 @@ private static void ReadMatParams(XmlNode polyNode, Nud.Material material, XmlNo
string name = GetNodeName(materialNode);
List<float> valueList = ParamValuesFromMaterialPropertyText(materialNode, name);

// Parameters should always have 4 values.
// Parameters should always have 4 values.
if (valueList.Count != 4)
throw new ParamArrayLengthException(polyNode.ChildNodes.Count, name);

Expand All @@ -359,7 +358,7 @@ private static void ReadMatParams(XmlNode polyNode, Nud.Material material, XmlNo
{
MessageBox.Show(String.Format("Polygon{0} contains more than 1 instance of {1}. \n"
+ "Only the first instance of {1} will be added.", polyNode.ChildNodes.Count.ToString(), name));
}
}
}

private static List<float> ParamValuesFromMaterialPropertyText(XmlNode materialPropertyNode, string propertyName)
Expand Down Expand Up @@ -387,7 +386,7 @@ private static List<float> ParamValuesFromMaterialPropertyText(XmlNode materialP
else if (float.TryParse(stringValue, out newValue))
valueList.Add(newValue);
else
valueList.Add(0.0f);
valueList.Add(0.0f);
}

return valueList;
Expand Down
126 changes: 25 additions & 101 deletions Smash Forge/Filetypes/Models/Nuds/Mesh.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@ public enum BoneFlags

public int boneflag = (int)BoneFlags.Rigged;
public short singlebind = -1;
public int sortBias = 0;
public bool billboardY = false;
public bool billboard = false;
public bool useNsc = false;

public bool sortByObjHierarchy = true;
public float[] boundingSphere = new float[8];
public float[] boundingSphere = new float[4];
public float sortBias = 0;
public float sortingDistance = 0;

public Mesh()
Expand Down Expand Up @@ -71,88 +71,45 @@ public void addVertex(Vertex v)

public void GenerateBoundingSphere()
{
Vector3 cen1 = new Vector3(0,0,0), cen2 = new Vector3(0,0,0);
double rad1 = 0, rad2 = 0;

//Get first vert
int vertCount = 0;
Vector3 vert0 = new Vector3();
bool initial = false;
Vector3 min = new Vector3();
Vector3 max = new Vector3();
foreach (Polygon p in Nodes)
{
foreach (Vertex v in p.vertices)
{
vert0 = v.pos;
vertCount++;
break;
}
break;
}

if (vertCount == 0)
return;

//Calculate average and min/max
Vector3 min = new Vector3(vert0);
Vector3 max = new Vector3(vert0);

vertCount = 0;
foreach (Polygon p in Nodes)
{
foreach(Vertex v in p.vertices)
{
for (int i = 0; i < 3; i++)
if (!initial)
{
min[i] = Math.Min(min[i], v.pos[i]);
max[i] = Math.Max(max[i], v.pos[i]);
min = new Vector3(v.pos);
max = new Vector3(v.pos);
initial = true;
}
else
{
for (int i = 0; i < 3; i++)
{
min[i] = Math.Min(min[i], v.pos[i]);
max[i] = Math.Max(max[i], v.pos[i]);
}
}

cen1 += v.pos;
vertCount++;
}
}

cen1 /= vertCount;
for (int i = 0; i < 3; i++)
cen2[i] = (min[i]+max[i])/2;

//Calculate the radius of each
double dist1, dist2;
Vector3 center = (min + max) / 2;
float radius = 0.0f;
foreach (Polygon p in Nodes)
{
foreach (Vertex v in p.vertices)
{
dist1 = ((Vector3)(v.pos - cen1)).Length;
if (dist1 > rad1)
rad1 = dist1;

dist2 = ((Vector3)(v.pos - cen2)).Length;
if (dist2 > rad2)
rad2 = dist2;
radius = Math.Max(radius, (v.pos - center).LengthSquared);
}
}
// Use LengthSquared since it's faster than Length, then Sqrt afterwards.
radius = (float)Math.Sqrt(radius);

// Use the one with the lowest radius.
Vector3 temp;
double radius;
if (rad1 < rad2)
{
temp = cen1;
radius = rad1;
}
else
{
temp = cen2;
radius = rad2;
}

// Set
for (int i = 0; i < 3; i++)
{
boundingSphere[i] = temp[i];
boundingSphere[i+4] = temp[i];
}
boundingSphere[3] = (float)radius;
boundingSphere[7] = 0;
boundingSphere[i] = center[i];
boundingSphere[3] = radius;
}

public float CalculateSortingDistance(Vector3 cameraPosition)
Expand All @@ -168,44 +125,11 @@ public float CalculateSortingDistance(Vector3 cameraPosition)
}

Vector3 distanceVector = new Vector3(cameraPosition - meshCenter);
return distanceVector.Length + boundingSphere[3] + sortBias;
}

private int CalculateSortBias()
{
if (!(Text.Contains("SORTBIAS")))
return 0;

// Isolate the integer value from the mesh name.
string sortBiasKeyWord = "SORTBIAS";
string sortBiasText = GetSortBiasNumbers(sortBiasKeyWord);

int sortBiasValue = 0;
int.TryParse(sortBiasText, out sortBiasValue);

return sortBiasValue;
}

private string GetSortBiasNumbers(string sortBiasKeyWord)
{
// HACK: Just ignore the 'm' prefix.
string modifiedText = Text.Replace("m", "");

string numbers = "";
for (int i = modifiedText.IndexOf(sortBiasKeyWord) + sortBiasKeyWord.Length; i < Text.Length; i++)
{
if (modifiedText[i] != '_')
numbers += modifiedText[i];
else
break;
}

return numbers;
return distanceVector.Length + boundingSphere[3] - sortBias;
}

public void SetMeshAttributesFromName()
{
sortBias = CalculateSortBias();
billboard = Text.Contains("BILLBOARD");
billboardY = Text.Contains("BILLBOARDYAXIS");
useNsc = Text.Contains("NSC");
Expand Down
Loading

0 comments on commit 46c13a3

Please sign in to comment.