mirror of
https://mirror.ghproxy.com/https://github.com/dexyfex/CodeWalker
synced 2024-11-16 20:17:30 +08:00
Updated Dec3N XML conversion. Ported BoundGeometry.VerticesShrunk code from rageAm. Added Track2AnimUV shader param name
This commit is contained in:
parent
b62162cf21
commit
d0cdb1bd76
@ -4144,7 +4144,9 @@ namespace CodeWalker.GameFiles
|
|||||||
}
|
}
|
||||||
public void TestYfts()
|
public void TestYfts()
|
||||||
{
|
{
|
||||||
|
bool xmltest = true;
|
||||||
bool savetest = false;
|
bool savetest = false;
|
||||||
|
bool glasstest = false;
|
||||||
var errorfiles = new List<RpfEntry>();
|
var errorfiles = new List<RpfEntry>();
|
||||||
var sb = new StringBuilder();
|
var sb = new StringBuilder();
|
||||||
var flagdict = new Dictionary<uint, int>();
|
var flagdict = new Dictionary<uint, int>();
|
||||||
@ -4167,6 +4169,14 @@ namespace CodeWalker.GameFiles
|
|||||||
UpdateStatus("Error! " + ex.ToString());
|
UpdateStatus("Error! " + ex.ToString());
|
||||||
errorfiles.Add(entry);
|
errorfiles.Add(entry);
|
||||||
}
|
}
|
||||||
|
if (xmltest && (yft != null) && (yft.Fragment != null))
|
||||||
|
{
|
||||||
|
var xml = YftXml.GetXml(yft);
|
||||||
|
var yft2 = XmlYft.GetYft(xml);//can't do full roundtrip here due to embedded textures
|
||||||
|
var xml2 = YftXml.GetXml(yft2);
|
||||||
|
if (xml != xml2)
|
||||||
|
{ }
|
||||||
|
}
|
||||||
if (savetest && (yft != null) && (yft.Fragment != null))
|
if (savetest && (yft != null) && (yft.Fragment != null))
|
||||||
{
|
{
|
||||||
var fentry = entry as RpfFileEntry;
|
var fentry = entry as RpfFileEntry;
|
||||||
@ -4189,7 +4199,7 @@ namespace CodeWalker.GameFiles
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (yft?.Fragment?.GlassWindows?.data_items != null)
|
if (glasstest && (yft?.Fragment?.GlassWindows?.data_items != null))
|
||||||
{
|
{
|
||||||
var lastf = -1;
|
var lastf = -1;
|
||||||
for (int i = 0; i < yft.Fragment.GlassWindows.data_items.Length; i++)
|
for (int i = 0; i < yft.Fragment.GlassWindows.data_items.Length; i++)
|
||||||
|
@ -3182,6 +3182,7 @@ namespace CodeWalker.GameFiles
|
|||||||
topcloudthreshold = 1907493970,
|
topcloudthreshold = 1907493970,
|
||||||
toplum = 2532426199,
|
toplum = 2532426199,
|
||||||
totalelapsedtime = 3838297418,
|
totalelapsedtime = 3838297418,
|
||||||
|
track2animuv = 3640659359,
|
||||||
trackanimuv = 3759799674,
|
trackanimuv = 3759799674,
|
||||||
transcolor = 2460231751,
|
transcolor = 2460231751,
|
||||||
transparentdstmapsampler = 2450925918,
|
transparentdstmapsampler = 2450925918,
|
||||||
|
@ -1248,13 +1248,13 @@ namespace CodeWalker.GameFiles
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CalculateVertsShrunkByMargin();
|
|
||||||
CalculateOctants();
|
|
||||||
|
|
||||||
BuildMaterials();
|
BuildMaterials();
|
||||||
CalculateQuantum();
|
CalculateQuantum();
|
||||||
UpdateEdgeIndices();
|
UpdateEdgeIndices();
|
||||||
UpdateTriangleAreas();
|
UpdateTriangleAreas();
|
||||||
|
CalculateVertsShrunk();
|
||||||
|
//CalculateVertsShrunkByNormals();
|
||||||
|
CalculateOctants();
|
||||||
|
|
||||||
FileVFT = 1080226408;
|
FileVFT = 1080226408;
|
||||||
}
|
}
|
||||||
@ -1327,7 +1327,17 @@ namespace CodeWalker.GameFiles
|
|||||||
}
|
}
|
||||||
if (Materials != null)
|
if (Materials != null)
|
||||||
{
|
{
|
||||||
MaterialsBlock = new ResourceSystemStructBlock<BoundMaterial_s>(Materials);
|
var mats = Materials;
|
||||||
|
if (mats.Length < 4) //add padding to the array for writing if necessary
|
||||||
|
{
|
||||||
|
mats = new BoundMaterial_s[4];
|
||||||
|
for (int i = 0; i < Materials.Length; i++)
|
||||||
|
{
|
||||||
|
mats[i] = Materials[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MaterialsBlock = new ResourceSystemStructBlock<BoundMaterial_s>(mats);
|
||||||
list.Add(MaterialsBlock);
|
list.Add(MaterialsBlock);
|
||||||
}
|
}
|
||||||
if (MaterialColours != null)
|
if (MaterialColours != null)
|
||||||
@ -1781,7 +1791,230 @@ namespace CodeWalker.GameFiles
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CalculateVertsShrunkByMargin()
|
public void CalculateVertsShrunk()
|
||||||
|
{
|
||||||
|
//this will also adjust the Margin if it can't successfully shrink!
|
||||||
|
//thanks to ranstar74
|
||||||
|
//https://github.com/ranstar74/rageAm/blob/master/projects/app/src/rage/physics/bounds/boundgeometry.cpp
|
||||||
|
|
||||||
|
if (Vertices == null) return;//must have existing vertices for this!
|
||||||
|
VerticesShrunk = null;
|
||||||
|
var size = Vector3.Abs(BoxMax - BoxMin) * 0.5f;
|
||||||
|
var margin = Math.Min(Math.Min(Math.Min(Margin, size.X), size.Y), size.Z);
|
||||||
|
while (margin > 1e-6f)
|
||||||
|
{
|
||||||
|
var verts = ShrinkPolysByMargin(margin); //try shrink by this margin, if successful, break out
|
||||||
|
var check = CheckShrunkPolys(verts);
|
||||||
|
if (check)
|
||||||
|
{
|
||||||
|
VerticesShrunk = verts;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
margin *= 0.5f;
|
||||||
|
}
|
||||||
|
if (VerticesShrunk == null)
|
||||||
|
{
|
||||||
|
CalculateVertsShrunkByNormals();//fallback case, just shrink by normals
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
margin = Math.Max(margin, 0.025f);
|
||||||
|
//Margin = margin;//should we actually update this here?
|
||||||
|
|
||||||
|
var shrunkMin = BoxMin + margin - CenterGeom;
|
||||||
|
var shrunkMax = BoxMax - margin - CenterGeom;
|
||||||
|
for (int i = 0; i < VerticesShrunk.Length; i++)//make sure the shrunk vertices fit in the box. (usually shouldn't do anything)
|
||||||
|
{
|
||||||
|
var vertex = VerticesShrunk[i];
|
||||||
|
vertex = Vector3.Min(vertex, shrunkMax);
|
||||||
|
vertex = Vector3.Max(vertex, shrunkMin);
|
||||||
|
if (VerticesShrunk[i] != vertex)
|
||||||
|
{
|
||||||
|
VerticesShrunk[i] = vertex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
private Vector3[] ShrinkPolysByMargin(float margin)
|
||||||
|
{
|
||||||
|
var verts = new Vector3[Vertices.Length];
|
||||||
|
Array.Copy(Vertices, verts, Vertices.Length);
|
||||||
|
|
||||||
|
var vc = verts.Length;
|
||||||
|
var polyNormals = new Vector3[Polygons.Length];//precompute all the poly normals.
|
||||||
|
for (int polyIndex = 0; polyIndex < Polygons.Length; polyIndex++)
|
||||||
|
{
|
||||||
|
var tri = Polygons[polyIndex] as BoundPolygonTriangle;
|
||||||
|
if (tri == null) { continue; }//can only compute poly normals for triangles!
|
||||||
|
var vi1 = tri.vertIndex1;
|
||||||
|
var vi2 = tri.vertIndex2;
|
||||||
|
var vi3 = tri.vertIndex3;
|
||||||
|
if ((vi1 >= vc) || (vi2 >= vc) || (vi3 >= vc)) continue;//vertex index out of range!?
|
||||||
|
var v1 = Vertices[vi1];//test against non-shrunk triangle
|
||||||
|
var v2 = Vertices[vi2];
|
||||||
|
var v3 = Vertices[vi3];
|
||||||
|
polyNormals[polyIndex] = Vector3.Normalize(Vector3.Cross(v3 - v2, v1 - v2));
|
||||||
|
}
|
||||||
|
|
||||||
|
var normals = new Vector3[64];//first is current poly normal, and remaining are neighbours (assumes 63 neighbours is enough!)
|
||||||
|
var processedVertices = new uint[2048];//2048*32 = 65536 vertices max
|
||||||
|
var negMargin = -margin;
|
||||||
|
for (int polyIndex = 0; polyIndex < Polygons.Length; polyIndex++)
|
||||||
|
{
|
||||||
|
var tri = Polygons[polyIndex] as BoundPolygonTriangle;
|
||||||
|
if (tri == null) { continue; }
|
||||||
|
for (int polyVertexIndex = 0; polyVertexIndex < 3; polyVertexIndex++)
|
||||||
|
{
|
||||||
|
var vertexIndex = tri.GetVertexIndex(polyVertexIndex);
|
||||||
|
var bucket = vertexIndex >> 5;
|
||||||
|
var mask = 1u << (vertexIndex & 0x1F);
|
||||||
|
if ((processedVertices[bucket] & mask) != 0) continue;//already processed this vertex
|
||||||
|
processedVertices[bucket] |= mask;
|
||||||
|
|
||||||
|
var vertex = verts[vertexIndex];
|
||||||
|
var normal = polyNormals[polyIndex];
|
||||||
|
normals[0] = normal;//used for weighted normal computation
|
||||||
|
var averageNormal = normal;//compute average normal from surrounding polygons
|
||||||
|
var prevNeighbour = polyIndex;
|
||||||
|
var normalCount = 1;
|
||||||
|
var neighbourCount = 0;
|
||||||
|
var polyNeighbourIndex = (polyVertexIndex + 2) % 3;//find starting neighbour index
|
||||||
|
var neighbour = tri.GetEdgeIndex(polyNeighbourIndex);
|
||||||
|
if (neighbour < 0)
|
||||||
|
{
|
||||||
|
neighbour = tri.GetEdgeIndex(polyVertexIndex);
|
||||||
|
polyNeighbourIndex = polyVertexIndex;//is this needed?
|
||||||
|
}
|
||||||
|
while (neighbour >= 0)
|
||||||
|
{
|
||||||
|
var neighbourPoly = Polygons[neighbour] as BoundPolygonTriangle;
|
||||||
|
var neighbourNormal = polyNormals[neighbour];
|
||||||
|
averageNormal += neighbourNormal;
|
||||||
|
normals[neighbourCount + 1] = neighbourNormal;
|
||||||
|
normalCount++;
|
||||||
|
neighbourCount++;
|
||||||
|
var newNeighbour = -1;
|
||||||
|
if (neighbourPoly != null)
|
||||||
|
{
|
||||||
|
for (var j = 0; j < 3; j++)
|
||||||
|
{
|
||||||
|
var nextIndex = (j + 1) % 3;
|
||||||
|
var n = neighbourPoly.GetVertexIndex(nextIndex);
|
||||||
|
if (n == vertexIndex)
|
||||||
|
{
|
||||||
|
newNeighbour = neighbourPoly.GetEdgeIndex(j);
|
||||||
|
if (newNeighbour == prevNeighbour)
|
||||||
|
{
|
||||||
|
newNeighbour = neighbourPoly.GetEdgeIndex(nextIndex);
|
||||||
|
}
|
||||||
|
prevNeighbour = neighbour;
|
||||||
|
neighbour = newNeighbour;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (newNeighbour == polyIndex) break; //check the circle is closed and iterated all neighbours
|
||||||
|
if (neighbourCount >= 63) break;//too many neighbours! possibly a mesh error
|
||||||
|
}
|
||||||
|
averageNormal = Vector3.Normalize(averageNormal);
|
||||||
|
|
||||||
|
if (normalCount == 1)
|
||||||
|
{
|
||||||
|
verts[vertexIndex] = vertex + (normal * negMargin);
|
||||||
|
}
|
||||||
|
else if (normalCount == 2)
|
||||||
|
{
|
||||||
|
var cross = Vector3.Cross(normal, normals[1]);
|
||||||
|
var crossMagSq = cross.LengthSquared();
|
||||||
|
if (crossMagSq < 0.1f)//small angle between normals, just shrink by base normal
|
||||||
|
{
|
||||||
|
verts[vertexIndex] = vertex + (normal * negMargin);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
var lengthInv = 1.0f / (float)Math.Sqrt(crossMagSq);//insert new normal to weighted set
|
||||||
|
normals[2] = cross * lengthInv;
|
||||||
|
normalCount = 3;
|
||||||
|
}
|
||||||
|
if (normalCount < 3) continue;
|
||||||
|
|
||||||
|
var neighbourNormalCount = normalCount - 1;
|
||||||
|
var shrunk = vertex + (averageNormal * negMargin);
|
||||||
|
for (var i = 0; i < neighbourNormalCount - 1; i++)//traverse and compute weighted normals
|
||||||
|
{
|
||||||
|
for (var j = 0; j < neighbourNormalCount - i - 1; j++)
|
||||||
|
{
|
||||||
|
for (var k = 0; k < neighbourNormalCount - j - i - 1; k++)
|
||||||
|
{
|
||||||
|
var normal1 = normals[i];
|
||||||
|
var normal2 = normals[i + j + 1];
|
||||||
|
var normal3 = normals[i + j + k + 2];
|
||||||
|
var cross23 = Vector3.Cross(normal2, normal3);
|
||||||
|
var dot = Vector3.Dot(normal1, cross23);
|
||||||
|
if (Math.Abs(dot) > 0.25f)//check only neighbours with large angle between neighbour normals and poly normal
|
||||||
|
{
|
||||||
|
var dotinv = 1.0f / dot;//normals with angle closer to 0.25 will contribute more to weighted normal
|
||||||
|
var cross31 = Vector3.Cross(normal3, normal1);
|
||||||
|
var cross12 = Vector3.Cross(normal1, normal2);
|
||||||
|
var newNormal = (cross23 + cross31 + cross12) * dotinv;//compute weighted normal
|
||||||
|
var newShrink = vertex + (newNormal * negMargin);
|
||||||
|
var toOld = shrunk - vertex;//choose shrunk vertex that is furthest from original vertex
|
||||||
|
var toNew = newShrink - vertex;
|
||||||
|
if (toNew.LengthSquared() > toOld.LengthSquared())
|
||||||
|
{
|
||||||
|
shrunk = newShrink;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
verts[vertexIndex] = shrunk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return verts;
|
||||||
|
}
|
||||||
|
private bool CheckShrunkPolys(Vector3[] verts)
|
||||||
|
{
|
||||||
|
bool rayIntersects(in Ray ray, ref Vector3 v1, ref Vector3 v2, ref Vector3 v3, float maxDist)
|
||||||
|
{
|
||||||
|
var hit = ray.Intersects(ref v1, ref v2, ref v3, out float dist);
|
||||||
|
return hit && (dist <= maxDist);
|
||||||
|
}
|
||||||
|
var vc = verts.Length;
|
||||||
|
if (vc != Vertices.Length) return false;//vertex count mismatch!?
|
||||||
|
for (var i = 0; i < vc; i++)
|
||||||
|
{
|
||||||
|
var vertex = Vertices[i];
|
||||||
|
var shrunkVertex = verts[i];
|
||||||
|
var segmentPos = shrunkVertex;
|
||||||
|
var segmentDir = vertex - shrunkVertex;
|
||||||
|
var segmentLength = segmentDir.Length();
|
||||||
|
if (segmentLength == 0) continue;//vertex wasn't shrunk!?
|
||||||
|
segmentDir *= (1.0f / segmentLength);
|
||||||
|
var segmentRay = new Ray(segmentPos, segmentDir);
|
||||||
|
for (int p = 0; p < Polygons.Length; p++)
|
||||||
|
{
|
||||||
|
var tri = Polygons[p] as BoundPolygonTriangle;
|
||||||
|
if (tri == null) { continue; }
|
||||||
|
var vi1 = tri.vertIndex1;
|
||||||
|
var vi2 = tri.vertIndex2;
|
||||||
|
var vi3 = tri.vertIndex3;
|
||||||
|
if ((vi1 >= vc) || (vi2 >= vc) || (vi3 >= vc)) return false;//vertex index out of range!?
|
||||||
|
if ((vi1 == i) || (vi2 == i) || (vi3 == i)) continue;//only test polys not using this vertex
|
||||||
|
var v1 = Vertices[vi1];//test against non-shrunk triangle
|
||||||
|
var v2 = Vertices[vi2];
|
||||||
|
var v3 = Vertices[vi3];
|
||||||
|
if (rayIntersects(segmentRay, ref v1, ref v2, ref v3, segmentLength)) return false;
|
||||||
|
var vs1 = verts[vi1];//test against shrunk triangle
|
||||||
|
var vs2 = verts[vi2];
|
||||||
|
var vs3 = verts[vi3];
|
||||||
|
if (rayIntersects(segmentRay, ref vs1, ref vs2, ref vs3, segmentLength)) return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void CalculateVertsShrunkByNormals()
|
||||||
{
|
{
|
||||||
Vector3[] vertNormals = CalculateVertNormals();
|
Vector3[] vertNormals = CalculateVertNormals();
|
||||||
VerticesShrunk = new Vector3[Vertices.Length];
|
VerticesShrunk = new Vector3[Vertices.Length];
|
||||||
@ -1792,7 +2025,6 @@ namespace CodeWalker.GameFiles
|
|||||||
VerticesShrunk[i] = Vertices[i] + normalShrunk;
|
VerticesShrunk[i] = Vertices[i] + normalShrunk;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector3[] CalculateVertNormals()
|
public Vector3[] CalculateVertNormals()
|
||||||
{
|
{
|
||||||
Vector3[] vertNormals = new Vector3[Vertices.Length];
|
Vector3[] vertNormals = new Vector3[Vertices.Length];
|
||||||
@ -1825,7 +2057,8 @@ namespace CodeWalker.GameFiles
|
|||||||
return vertNormals;
|
return vertNormals;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CalculateQuantum()
|
|
||||||
|
public void CalculateMinMax()
|
||||||
{
|
{
|
||||||
var min = new Vector3(float.MaxValue);
|
var min = new Vector3(float.MaxValue);
|
||||||
var max = new Vector3(float.MinValue);
|
var max = new Vector3(float.MinValue);
|
||||||
@ -1837,7 +2070,7 @@ namespace CodeWalker.GameFiles
|
|||||||
max = Vector3.Max(max, v);
|
max = Vector3.Max(max, v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (VerticesShrunk != null)
|
if (VerticesShrunk != null)//this shouldn't be needed
|
||||||
{
|
{
|
||||||
foreach (var v in VerticesShrunk)
|
foreach (var v in VerticesShrunk)
|
||||||
{
|
{
|
||||||
@ -1845,9 +2078,38 @@ namespace CodeWalker.GameFiles
|
|||||||
max = Vector3.Max(max, v);
|
max = Vector3.Max(max, v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var maxsiz = Vector3.Max(min.Abs(), max.Abs());
|
if (min.X == float.MaxValue) min = Vector3.Zero;
|
||||||
var q = (maxsiz+Margin) / 32767.0f;
|
if (max.X == float.MinValue) max = Vector3.Zero;
|
||||||
Quantum = q;
|
BoxMin = min - Margin;
|
||||||
|
BoxMax = max + Margin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CalculateQuantum()
|
||||||
|
{
|
||||||
|
Quantum = (BoxMax - BoxMin) * 0.5f / 32767.0f;
|
||||||
|
|
||||||
|
|
||||||
|
//var min = new Vector3(float.MaxValue);
|
||||||
|
//var max = new Vector3(float.MinValue);
|
||||||
|
//if (Vertices != null)
|
||||||
|
//{
|
||||||
|
// foreach (var v in Vertices)
|
||||||
|
// {
|
||||||
|
// min = Vector3.Min(min, v);
|
||||||
|
// max = Vector3.Max(max, v);
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
//if (VerticesShrunk != null)
|
||||||
|
//{
|
||||||
|
// foreach (var v in VerticesShrunk)
|
||||||
|
// {
|
||||||
|
// min = Vector3.Min(min, v);
|
||||||
|
// max = Vector3.Max(max, v);
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
//var maxsiz = Vector3.Max(min.Abs(), max.Abs());
|
||||||
|
//var q = (maxsiz+Margin) / 32767.0f;
|
||||||
|
//Quantum = q;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void BuildMaterials()
|
public void BuildMaterials()
|
||||||
@ -1878,13 +2140,6 @@ namespace CodeWalker.GameFiles
|
|||||||
}
|
}
|
||||||
|
|
||||||
MaterialsCount = (byte)matlist.Count;
|
MaterialsCount = (byte)matlist.Count;
|
||||||
|
|
||||||
//add padding to the array for writing
|
|
||||||
for (int i = matlist.Count; i < 4; i++)
|
|
||||||
{
|
|
||||||
matlist.Add(new BoundMaterial_s());
|
|
||||||
}
|
|
||||||
|
|
||||||
Materials = matlist.ToArray();
|
Materials = matlist.ToArray();
|
||||||
PolygonMaterialIndices = polymats.ToArray();
|
PolygonMaterialIndices = polymats.ToArray();
|
||||||
}
|
}
|
||||||
@ -1918,49 +2173,49 @@ namespace CodeWalker.GameFiles
|
|||||||
{
|
{
|
||||||
if (edge1.Triangle2 != null)
|
if (edge1.Triangle2 != null)
|
||||||
{
|
{
|
||||||
btri.SetEdgeIndex(1, (short)edge1.Triangle1.Index);
|
btri.SetEdgeIndex(0, edge1.Triangle1.Index);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
edge1.Triangle2 = btri;
|
edge1.Triangle2 = btri;
|
||||||
edge1.EdgeID2 = 1;
|
edge1.EdgeID2 = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
edgedict[e1] = new BoundEdge(btri, 1);
|
edgedict[e1] = new BoundEdge(btri, 0);
|
||||||
}
|
}
|
||||||
if (edgedict.TryGetValue(e2, out BoundEdge edge2))
|
if (edgedict.TryGetValue(e2, out BoundEdge edge2))
|
||||||
{
|
{
|
||||||
if (edge2.Triangle2 != null)
|
if (edge2.Triangle2 != null)
|
||||||
{
|
{
|
||||||
btri.SetEdgeIndex(2, (short)edge2.Triangle1.Index);
|
btri.SetEdgeIndex(1, edge2.Triangle1.Index);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
edge2.Triangle2 = btri;
|
edge2.Triangle2 = btri;
|
||||||
edge2.EdgeID2 = 2;
|
edge2.EdgeID2 = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
edgedict[e2] = new BoundEdge(btri, 2);
|
edgedict[e2] = new BoundEdge(btri, 1);
|
||||||
}
|
}
|
||||||
if (edgedict.TryGetValue(e3, out BoundEdge edge3))
|
if (edgedict.TryGetValue(e3, out BoundEdge edge3))
|
||||||
{
|
{
|
||||||
if (edge3.Triangle2 != null)
|
if (edge3.Triangle2 != null)
|
||||||
{
|
{
|
||||||
btri.SetEdgeIndex(3, (short)edge3.Triangle1.Index);
|
btri.SetEdgeIndex(2, edge3.Triangle1.Index);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
edge3.Triangle2 = btri;
|
edge3.Triangle2 = btri;
|
||||||
edge3.EdgeID2 = 3;
|
edge3.EdgeID2 = 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
edgedict[e3] = new BoundEdge(btri, 3);
|
edgedict[e3] = new BoundEdge(btri, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1981,8 +2236,8 @@ namespace CodeWalker.GameFiles
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
edge.Triangle1.SetEdgeIndex(edge.EdgeID1, (short)edge.Triangle2.Index);
|
edge.Triangle1.SetEdgeIndex(edge.EdgeID1, edge.Triangle2.Index);
|
||||||
edge.Triangle2.SetEdgeIndex(edge.EdgeID2, (short)edge.Triangle1.Index);
|
edge.Triangle2.SetEdgeIndex(edge.EdgeID2, edge.Triangle1.Index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2045,12 +2300,12 @@ namespace CodeWalker.GameFiles
|
|||||||
var poly = Polygons[i];
|
var poly = Polygons[i];
|
||||||
if (poly is BoundPolygonTriangle btri)
|
if (poly is BoundPolygonTriangle btri)
|
||||||
{
|
{
|
||||||
if (btri.edgeIndex1 == idx) btri.edgeIndex1 = -1;
|
if (btri.edgeIndex1 == idx) btri.edgeIndex1 = 0xFFFF;
|
||||||
if (btri.edgeIndex1 > idx) btri.edgeIndex1--;
|
if ((btri.edgeIndex1 > idx) && (btri.edgeIndex1 != 0xFFFF)) btri.edgeIndex1--;
|
||||||
if (btri.edgeIndex2 == idx) btri.edgeIndex2 = -1;
|
if (btri.edgeIndex2 == idx) btri.edgeIndex2 = 0xFFFF;
|
||||||
if (btri.edgeIndex2 > idx) btri.edgeIndex2--;
|
if ((btri.edgeIndex2 > idx) && (btri.edgeIndex2 != 0xFFFF)) btri.edgeIndex2--;
|
||||||
if (btri.edgeIndex3 == idx) btri.edgeIndex3 = -1;
|
if (btri.edgeIndex3 == idx) btri.edgeIndex3 = 0xFFFF;
|
||||||
if (btri.edgeIndex3 > idx) btri.edgeIndex3--;
|
if ((btri.edgeIndex3 > idx) && (btri.edgeIndex3 != 0xFFFF)) btri.edgeIndex3--;
|
||||||
}
|
}
|
||||||
poly.Index = i;
|
poly.Index = i;
|
||||||
}
|
}
|
||||||
@ -2363,7 +2618,7 @@ namespace CodeWalker.GameFiles
|
|||||||
|
|
||||||
var newpolys = new BoundPolygon[items.Count];
|
var newpolys = new BoundPolygon[items.Count];
|
||||||
var newpolymats = new byte[items.Count];
|
var newpolymats = new byte[items.Count];
|
||||||
var itemlookup = new short[items.Count];
|
var itemlookup = new int[items.Count];
|
||||||
for (int i = 0; i < items.Count; i++)
|
for (int i = 0; i < items.Count; i++)
|
||||||
{
|
{
|
||||||
var poly = items[i]?.Polygon;
|
var poly = items[i]?.Polygon;
|
||||||
@ -2371,7 +2626,7 @@ namespace CodeWalker.GameFiles
|
|||||||
{
|
{
|
||||||
if (poly.Index < itemlookup.Length)
|
if (poly.Index < itemlookup.Length)
|
||||||
{
|
{
|
||||||
itemlookup[poly.Index] = (short)i;
|
itemlookup[poly.Index] = i;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ }//shouldn't happen
|
{ }//shouldn't happen
|
||||||
@ -2389,9 +2644,12 @@ namespace CodeWalker.GameFiles
|
|||||||
poly.Index = i;
|
poly.Index = i;
|
||||||
if (poly is BoundPolygonTriangle ptri)
|
if (poly is BoundPolygonTriangle ptri)
|
||||||
{
|
{
|
||||||
ptri.edgeIndex1 = ((ptri.edgeIndex1 >= 0) && (ptri.edgeIndex1 < itemlookup.Length)) ? itemlookup[ptri.edgeIndex1] : (short)-1;
|
var edgeIndex1 = ((ptri.edgeIndex1 >= 0) && (ptri.edgeIndex1 < itemlookup.Length)) ? itemlookup[ptri.edgeIndex1] : -1;
|
||||||
ptri.edgeIndex2 = ((ptri.edgeIndex2 >= 0) && (ptri.edgeIndex2 < itemlookup.Length)) ? itemlookup[ptri.edgeIndex2] : (short)-1;
|
var edgeIndex2 = ((ptri.edgeIndex2 >= 0) && (ptri.edgeIndex2 < itemlookup.Length)) ? itemlookup[ptri.edgeIndex2] : -1;
|
||||||
ptri.edgeIndex3 = ((ptri.edgeIndex3 >= 0) && (ptri.edgeIndex3 < itemlookup.Length)) ? itemlookup[ptri.edgeIndex3] : (short)-1;
|
var edgeIndex3 = ((ptri.edgeIndex3 >= 0) && (ptri.edgeIndex3 < itemlookup.Length)) ? itemlookup[ptri.edgeIndex3] : -1;
|
||||||
|
ptri.SetEdgeIndex(1, edgeIndex1);
|
||||||
|
ptri.SetEdgeIndex(2, edgeIndex2);
|
||||||
|
ptri.SetEdgeIndex(3, edgeIndex3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3214,9 +3472,9 @@ namespace CodeWalker.GameFiles
|
|||||||
public ushort triIndex1 { get; set; }
|
public ushort triIndex1 { get; set; }
|
||||||
public ushort triIndex2 { get; set; }
|
public ushort triIndex2 { get; set; }
|
||||||
public ushort triIndex3 { get; set; }
|
public ushort triIndex3 { get; set; }
|
||||||
public short edgeIndex1 { get; set; }
|
public ushort edgeIndex1 { get; set; }
|
||||||
public short edgeIndex2 { get; set; }
|
public ushort edgeIndex2 { get; set; }
|
||||||
public short edgeIndex3 { get; set; }
|
public ushort edgeIndex3 { get; set; }
|
||||||
|
|
||||||
public int vertIndex1 { get { return (triIndex1 & 0x7FFF); } set { triIndex1 = (ushort)((value & 0x7FFF) + (vertFlag1 ? 0x8000 : 0)); } }
|
public int vertIndex1 { get { return (triIndex1 & 0x7FFF); } set { triIndex1 = (ushort)((value & 0x7FFF) + (vertFlag1 ? 0x8000 : 0)); } }
|
||||||
public int vertIndex2 { get { return (triIndex2 & 0x7FFF); } set { triIndex2 = (ushort)((value & 0x7FFF) + (vertFlag2 ? 0x8000 : 0)); } }
|
public int vertIndex2 { get { return (triIndex2 & 0x7FFF); } set { triIndex2 = (ushort)((value & 0x7FFF) + (vertFlag2 ? 0x8000 : 0)); } }
|
||||||
@ -3358,29 +3616,61 @@ namespace CodeWalker.GameFiles
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetEdgeIndex(int edgeid, short polyindex)
|
public int GetVertexIndex(int i)
|
||||||
{
|
{
|
||||||
switch (edgeid)
|
switch (i)
|
||||||
{
|
{
|
||||||
case 1:
|
default:
|
||||||
if (edgeIndex1 != polyindex)
|
case 0: return vertIndex1;
|
||||||
|
case 1: return vertIndex2;
|
||||||
|
case 2: return vertIndex3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public int GetEdgeIndex(int i)
|
||||||
|
{
|
||||||
|
switch (i)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case 0: return UnpackEdgeIndex(edgeIndex1);
|
||||||
|
case 1: return UnpackEdgeIndex(edgeIndex2);
|
||||||
|
case 2: return UnpackEdgeIndex(edgeIndex3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void SetEdgeIndex(int i, int polyindex)
|
||||||
|
{
|
||||||
|
var e = PackEdgeIndex(polyindex);
|
||||||
|
switch (i)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
if (edgeIndex1 != e)
|
||||||
{ }
|
{ }
|
||||||
edgeIndex1 = polyindex;
|
edgeIndex1 = e;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
if (edgeIndex2 != e)
|
||||||
|
{ }
|
||||||
|
edgeIndex2 = e;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
if (edgeIndex2 != polyindex)
|
if (edgeIndex3 != e)
|
||||||
{ }
|
{ }
|
||||||
edgeIndex2 = polyindex;
|
edgeIndex3 = e;
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
if (edgeIndex3 != polyindex)
|
|
||||||
{ }
|
|
||||||
edgeIndex3 = polyindex;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public static ushort PackEdgeIndex(int polyIndex)
|
||||||
|
{
|
||||||
|
if (polyIndex < 0) return 0xFFFF;
|
||||||
|
if (polyIndex > 0xFFFF) return 0xFFFF;
|
||||||
|
return (ushort)polyIndex;
|
||||||
|
}
|
||||||
|
public static int UnpackEdgeIndex(ushort edgeIndex)
|
||||||
|
{
|
||||||
|
if (edgeIndex == 0xFFFF) return -1;
|
||||||
|
return (int)edgeIndex;
|
||||||
|
}
|
||||||
|
|
||||||
public BoundPolygonTriangle()
|
public BoundPolygonTriangle()
|
||||||
{
|
{
|
||||||
@ -3392,9 +3682,9 @@ namespace CodeWalker.GameFiles
|
|||||||
triIndex1 = BitConverter.ToUInt16(bytes, offset + 4);
|
triIndex1 = BitConverter.ToUInt16(bytes, offset + 4);
|
||||||
triIndex2 = BitConverter.ToUInt16(bytes, offset + 6);
|
triIndex2 = BitConverter.ToUInt16(bytes, offset + 6);
|
||||||
triIndex3 = BitConverter.ToUInt16(bytes, offset + 8);
|
triIndex3 = BitConverter.ToUInt16(bytes, offset + 8);
|
||||||
edgeIndex1 = BitConverter.ToInt16(bytes, offset + 10);
|
edgeIndex1 = BitConverter.ToUInt16(bytes, offset + 10);
|
||||||
edgeIndex2 = BitConverter.ToInt16(bytes, offset + 12);
|
edgeIndex2 = BitConverter.ToUInt16(bytes, offset + 12);
|
||||||
edgeIndex3 = BitConverter.ToInt16(bytes, offset + 14);
|
edgeIndex3 = BitConverter.ToUInt16(bytes, offset + 14);
|
||||||
}
|
}
|
||||||
public override void Write(BinaryWriter bw)
|
public override void Write(BinaryWriter bw)
|
||||||
{
|
{
|
||||||
|
@ -3779,7 +3779,7 @@ namespace CodeWalker.GameFiles
|
|||||||
case VertexComponentType.Float2: SetVector2(v, c, new Vector2(f(0), f(1))); break;
|
case VertexComponentType.Float2: SetVector2(v, c, new Vector2(f(0), f(1))); break;
|
||||||
case VertexComponentType.Float3: SetVector3(v, c, new Vector3(f(0), f(1), f(2))); break;
|
case VertexComponentType.Float3: SetVector3(v, c, new Vector3(f(0), f(1), f(2))); break;
|
||||||
case VertexComponentType.Float4: SetVector4(v, c, new Vector4(f(0), f(1), f(2), f(3))); break;
|
case VertexComponentType.Float4: SetVector4(v, c, new Vector4(f(0), f(1), f(2), f(3))); break;
|
||||||
case VertexComponentType.Dec3N: SetDec3N(v, c, new Vector3(f(0), f(1), f(2))); break;
|
case VertexComponentType.Dec3N: SetDec3N(v, c, new Vector4(f(0), f(1), f(2), f(3))); break;
|
||||||
case VertexComponentType.Half2: SetHalf2(v, c, new Half2(f(0), f(1))); break;
|
case VertexComponentType.Half2: SetHalf2(v, c, new Half2(f(0), f(1))); break;
|
||||||
case VertexComponentType.Half4: SetHalf4(v, c, new Half4(f(0), f(1), f(2), f(3))); break;
|
case VertexComponentType.Half4: SetHalf4(v, c, new Half4(f(0), f(1), f(2), f(3))); break;
|
||||||
case VertexComponentType.Colour: SetColour(v, c, new Color(b(0), b(1), b(2), b(3))); break;
|
case VertexComponentType.Colour: SetColour(v, c, new Color(b(0), b(1), b(2), b(3))); break;
|
||||||
@ -3862,7 +3862,7 @@ namespace CodeWalker.GameFiles
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public void SetDec3N(int v, int c, Vector3 val)
|
public void SetDec3N(int v, int c, Vector4 val)
|
||||||
{
|
{
|
||||||
//see https://docs.microsoft.com/en-us/previous-versions/windows/desktop/bb322868(v%3Dvs.85)
|
//see https://docs.microsoft.com/en-us/previous-versions/windows/desktop/bb322868(v%3Dvs.85)
|
||||||
if ((Info != null) && (VertexBytes != null))
|
if ((Info != null) && (VertexBytes != null))
|
||||||
@ -3873,16 +3873,18 @@ namespace CodeWalker.GameFiles
|
|||||||
var e = o + 4;//sizeof(Dec3N)
|
var e = o + 4;//sizeof(Dec3N)
|
||||||
if (e <= VertexBytes.Length)
|
if (e <= VertexBytes.Length)
|
||||||
{
|
{
|
||||||
var sx = (val.X < 0.0f);
|
var sx = (val.X >= 0.0f);
|
||||||
var sy = (val.X < 0.0f);
|
var sy = (val.Y >= 0.0f);
|
||||||
var sz = (val.X < 0.0f);
|
var sz = (val.Z >= 0.0f);
|
||||||
|
var sw = (val.W >= 0.0f);
|
||||||
var x = Math.Min((uint)(Math.Abs(val.X) * 511.0f), 511);
|
var x = Math.Min((uint)(Math.Abs(val.X) * 511.0f), 511);
|
||||||
var y = Math.Min((uint)(Math.Abs(val.Y) * 511.0f), 511);
|
var y = Math.Min((uint)(Math.Abs(val.Y) * 511.0f), 511);
|
||||||
var z = Math.Min((uint)(Math.Abs(val.Z) * 511.0f), 511);
|
var z = Math.Min((uint)(Math.Abs(val.Z) * 511.0f), 511);
|
||||||
var ux = ((sx ? ~x : x) & 0x1FF) + (sx ? 0x200 : 0);
|
var w = Math.Min((uint)(val.W), 2);
|
||||||
var uy = ((sy ? ~y : y) & 0x1FF) + (sy ? 0x200 : 0);
|
var ux = ((sx ? x : ~x) & 0x1FF) + (sx ? 0x200 : 0);
|
||||||
var uz = ((sz ? ~z : z) & 0x1FF) + (sz ? 0x200 : 0);
|
var uy = ((sy ? y : ~y) & 0x1FF) + (sy ? 0x200 : 0);
|
||||||
var uw = 0u;
|
var uz = ((sz ? z : ~z) & 0x1FF) + (sz ? 0x200 : 0);
|
||||||
|
var uw = sw ? w : 3;//(0,1,2)=>(0,1,2); (-1)=>(3)
|
||||||
var u = ux + (uy << 10) + (uz << 20) + (uw << 30);
|
var u = ux + (uy << 10) + (uz << 20) + (uw << 30);
|
||||||
var b = BitConverter.GetBytes(u);
|
var b = BitConverter.GetBytes(u);
|
||||||
Buffer.BlockCopy(b, 0, VertexBytes, o, 4);
|
Buffer.BlockCopy(b, 0, VertexBytes, o, 4);
|
||||||
@ -3971,7 +3973,7 @@ namespace CodeWalker.GameFiles
|
|||||||
case VertexComponentType.Float2: return FloatUtil.GetVector2String(GetVector2(v, c), d);
|
case VertexComponentType.Float2: return FloatUtil.GetVector2String(GetVector2(v, c), d);
|
||||||
case VertexComponentType.Float3: return FloatUtil.GetVector3String(GetVector3(v, c), d);
|
case VertexComponentType.Float3: return FloatUtil.GetVector3String(GetVector3(v, c), d);
|
||||||
case VertexComponentType.Float4: return FloatUtil.GetVector4String(GetVector4(v, c), d);
|
case VertexComponentType.Float4: return FloatUtil.GetVector4String(GetVector4(v, c), d);
|
||||||
case VertexComponentType.Dec3N: return FloatUtil.GetVector3String(GetDec3N(v, c), d);
|
case VertexComponentType.Dec3N: return FloatUtil.GetVector4String(GetDec3N(v, c), d);
|
||||||
case VertexComponentType.Half2: return FloatUtil.GetHalf2String(GetHalf2(v, c), d);
|
case VertexComponentType.Half2: return FloatUtil.GetHalf2String(GetHalf2(v, c), d);
|
||||||
case VertexComponentType.Half4: return FloatUtil.GetHalf4String(GetHalf4(v, c), d);
|
case VertexComponentType.Half4: return FloatUtil.GetHalf4String(GetHalf4(v, c), d);
|
||||||
case VertexComponentType.Colour: return FloatUtil.GetColourString(GetColour(v, c), d);
|
case VertexComponentType.Colour: return FloatUtil.GetColourString(GetColour(v, c), d);
|
||||||
@ -4052,7 +4054,7 @@ namespace CodeWalker.GameFiles
|
|||||||
}
|
}
|
||||||
return Vector4.Zero;
|
return Vector4.Zero;
|
||||||
}
|
}
|
||||||
public Vector3 GetDec3N(int v, int c)
|
public Vector4 GetDec3N(int v, int c)
|
||||||
{
|
{
|
||||||
//see https://docs.microsoft.com/en-us/previous-versions/windows/desktop/bb322868(v%3Dvs.85)
|
//see https://docs.microsoft.com/en-us/previous-versions/windows/desktop/bb322868(v%3Dvs.85)
|
||||||
if ((Info != null) && (VertexBytes != null))
|
if ((Info != null) && (VertexBytes != null))
|
||||||
@ -4067,17 +4069,18 @@ namespace CodeWalker.GameFiles
|
|||||||
var ux = (u >> 0) & 0x3FF;
|
var ux = (u >> 0) & 0x3FF;
|
||||||
var uy = (u >> 10) & 0x3FF;
|
var uy = (u >> 10) & 0x3FF;
|
||||||
var uz = (u >> 20) & 0x3FF;
|
var uz = (u >> 20) & 0x3FF;
|
||||||
var uw = (u >> 30);
|
var uw = (u >> 30) & 0x3;
|
||||||
var sx = (ux & 0x200) > 0;
|
var sx = (ux & 0x200) > 0;
|
||||||
var sy = (uy & 0x200) > 0;
|
var sy = (uy & 0x200) > 0;
|
||||||
var sz = (uz & 0x200) > 0;
|
var sz = (uz & 0x200) > 0;
|
||||||
var x = ((sx ? ~ux : ux) & 0x1FF) / (sx ? -511.0f : 511.0f);
|
var x = ((sx ? ux : ~ux) & 0x1FF) / (sx ? 511.0f : -511.0f);
|
||||||
var y = ((sy ? ~uy : uy) & 0x1FF) / (sy ? -511.0f : 511.0f);
|
var y = ((sy ? uy : ~uy) & 0x1FF) / (sy ? 511.0f : -511.0f);
|
||||||
var z = ((sz ? ~uz : uz) & 0x1FF) / (sz ? -511.0f : 511.0f);
|
var z = ((sz ? uz : ~uz) & 0x1FF) / (sz ? 511.0f : -511.0f);
|
||||||
return new Vector3(x, y, z);
|
var w = (uw == 3) ? -1.0f : uw;//(0,1,2)=>(0,1,2); (3)=>(-1)
|
||||||
|
return new Vector4(x, y, z, w);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Vector3.Zero;
|
return Vector4.Zero;
|
||||||
}
|
}
|
||||||
public Half2 GetHalf2(int v, int c)
|
public Half2 GetHalf2(int v, int c)
|
||||||
{
|
{
|
||||||
|
@ -512,6 +512,10 @@ namespace CodeWalker.GameFiles
|
|||||||
}
|
}
|
||||||
LightAttributes = new ResourceSimpleList64<LightAttributes>();
|
LightAttributes = new ResourceSimpleList64<LightAttributes>();
|
||||||
LightAttributes.data_items = XmlMeta.ReadItemArray<LightAttributes>(node, "Lights");
|
LightAttributes.data_items = XmlMeta.ReadItemArray<LightAttributes>(node, "Lights");
|
||||||
|
if (LightAttributes.data_items == null)
|
||||||
|
{
|
||||||
|
LightAttributes.data_items = new LightAttributes[0];
|
||||||
|
}
|
||||||
Cloths = new ResourcePointerList64<EnvironmentCloth>();
|
Cloths = new ResourcePointerList64<EnvironmentCloth>();
|
||||||
var cnode = node.SelectSingleNode("Cloths");
|
var cnode = node.SelectSingleNode("Cloths");
|
||||||
if (cnode != null)
|
if (cnode != null)
|
||||||
@ -526,6 +530,10 @@ namespace CodeWalker.GameFiles
|
|||||||
v.ReadXml(inode, ddsfolder);
|
v.ReadXml(inode, ddsfolder);
|
||||||
vlist.Add(v);
|
vlist.Add(v);
|
||||||
|
|
||||||
|
if (v.Drawable != null)
|
||||||
|
{
|
||||||
|
v.Drawable.OwnerCloth = v;
|
||||||
|
}
|
||||||
if (Drawable == null)
|
if (Drawable == null)
|
||||||
{
|
{
|
||||||
Drawable = v.Drawable;
|
Drawable = v.Drawable;
|
||||||
@ -2898,6 +2906,7 @@ namespace CodeWalker.GameFiles
|
|||||||
{
|
{
|
||||||
var type = Xml.GetEnumValue<FragJointType>(Xml.GetStringAttribute(jnode, "type"));
|
var type = Xml.GetEnumValue<FragJointType>(Xml.GetStringAttribute(jnode, "type"));
|
||||||
var j = FragPhysJointType.Create(type);
|
var j = FragPhysJointType.Create(type);
|
||||||
|
j.Type = type;
|
||||||
j?.ReadXml(jnode);
|
j?.ReadXml(jnode);
|
||||||
jlist.Add(j);
|
jlist.Add(j);
|
||||||
}
|
}
|
||||||
|
@ -1315,6 +1315,7 @@ namespace CodeWalker.GameFiles
|
|||||||
topLum = 2532426199,
|
topLum = 2532426199,
|
||||||
TotalElapsedTime = 3838297418,
|
TotalElapsedTime = 3838297418,
|
||||||
TrackAnimUV = 3759799674,
|
TrackAnimUV = 3759799674,
|
||||||
|
Track2AnimUV = 3640659359,
|
||||||
TransColor = 2460231751,
|
TransColor = 2460231751,
|
||||||
TransparentDstMapSampler = 2450925918,
|
TransparentDstMapSampler = 2450925918,
|
||||||
TransparentSrcMap = 2768420156,
|
TransparentSrcMap = 2768420156,
|
||||||
|
@ -62,7 +62,7 @@ namespace CodeWalker.GameFiles
|
|||||||
case VertexComponentType.Float4: return 4;
|
case VertexComponentType.Float4: return 4;
|
||||||
case VertexComponentType.UByte4: return 4;
|
case VertexComponentType.UByte4: return 4;
|
||||||
case VertexComponentType.Colour: return 4;
|
case VertexComponentType.Colour: return 4;
|
||||||
case VertexComponentType.Dec3N: return 3;
|
case VertexComponentType.Dec3N: return 4;
|
||||||
default: return 0;
|
default: return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4346,9 +4346,9 @@ namespace CodeWalker.Project
|
|||||||
|
|
||||||
if (ptri != null)
|
if (ptri != null)
|
||||||
{
|
{
|
||||||
ptri.edgeIndex1 = -1;
|
ptri.edgeIndex1 = 0xFFFF;
|
||||||
ptri.edgeIndex2 = -1;
|
ptri.edgeIndex2 = 0xFFFF;
|
||||||
ptri.edgeIndex3 = -1;
|
ptri.edgeIndex3 = 0xFFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (copy != null)
|
if (copy != null)
|
||||||
|
Loading…
Reference in New Issue
Block a user