Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion Crash.UI/Properties/Resources.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Crash.UI/Properties/Resources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -357,4 +357,7 @@
<data name="NSFController_AcShowLevelZones" xml:space="preserve">
<value>Show All Level Zones</value>
</data>
<data name="NSFController_AcExportScenery" xml:space="preserve">
<value>Export all scenery to OBJ</value>
</data>
</root>
41 changes: 0 additions & 41 deletions Crash/Formats/Crash Formats/Animation/OldFrame.cs
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -133,46 +133,5 @@ public byte[] Save()
}
return data;
}

public byte[] ToOBJ(OldModelEntry model)
{
long xorigin = 0;
long yorigin = 0;
long zorigin = 0;
//foreach (OldFrameVertex vertex in vertices)
//{
// xorigin += vertex.X;
// yorigin += vertex.Y;
// zorigin += vertex.Z;
//}
//xorigin /= vertices.Count;
//yorigin /= vertices.Count;
//zorigin /= vertices.Count;
xorigin -= XOffset;
yorigin -= YOffset;
zorigin -= ZOffset;
using (MemoryStream stream = new MemoryStream())
{
using (StreamWriter obj = new StreamWriter(stream))
{
obj.WriteLine("# Vertices");
foreach (OldFrameVertex vertex in vertices)
{
obj.WriteLine("v {0} {1} {2}", vertex.X - xorigin, vertex.Y - yorigin, vertex.Z - zorigin);
}
foreach (OldFrameVertex vertex in vertices)
{
obj.WriteLine("vn {0} {1} {2}", vertex.NormalX / 127.0, vertex.NormalY / 127.0, vertex.NormalZ / 127.0);
}
obj.WriteLine();
obj.WriteLine("# Polygons");
foreach (OldModelPolygon polygon in model.Polygons)
{
obj.WriteLine("f {0}//{0} {1}//{1} {2}//{2}", polygon.VertexA / 6 + 1, polygon.VertexB / 6 + 1, polygon.VertexC / 6 + 1);
}
}
return stream.ToArray();
}
}
}
}
237 changes: 0 additions & 237 deletions Crash/Formats/Crash Formats/Scenery/SceneryEntry.cs
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -104,242 +104,5 @@ public override UnprocessedEntry Unprocess()
}
return new UnprocessedEntry(items, EID, Type);
}

public byte[] ToOBJ()
{
using (MemoryStream stream = new MemoryStream())
{
using (StreamWriter obj = new StreamWriter(stream))
{
obj.WriteLine("# Vertices");
foreach (SceneryVertex vertex in vertices)
{
if (vertex.Color < Colors.Count)
{
SceneryColor color = Colors[vertex.Color];
obj.WriteLine("v {0} {1} {2} {3} {4} {5}", vertex.X + XOffset / 16, vertex.Y + YOffset / 16, vertex.Z + ZOffset / 16, color.Red / 255.0, color.Green / 255.0, color.Blue / 255.0);
}
else
{
obj.WriteLine("v {0} {1} {2}", vertex.X + XOffset / 16, vertex.Y + YOffset / 16, vertex.Z + ZOffset / 16);
}
}
obj.WriteLine();
obj.WriteLine("# Triangles");
foreach (SceneryTriangle triangle in triangles)
{
obj.WriteLine("f {0} {1} {2}", triangle.VertexA + 1, triangle.VertexB + 1, triangle.VertexC + 1);
}
obj.WriteLine();
obj.WriteLine("# Quads");
foreach (SceneryQuad quad in quads)
{
obj.WriteLine("f {0} {1} {2} {3}", quad.VertexA + 1, quad.VertexB + 1, quad.VertexC + 1, quad.VertexD + 1);
}
}
return stream.ToArray();
}
}

public byte[] ToPLY()
{
using (MemoryStream stream = new MemoryStream())
{
using (StreamWriter ply = new StreamWriter(stream))
{
int polycount = 0;
foreach (SceneryTriangle triangle in triangles)
{
if (triangle.VertexA < vertices.Count - 1 && triangle.VertexB < vertices.Count - 1 && triangle.VertexC < vertices.Count - 1)
{
++polycount;
}
}
foreach (SceneryQuad quad in quads)
{
if (quad.VertexA < vertices.Count - 1 && quad.VertexB < vertices.Count - 1 && quad.VertexC < vertices.Count - 1 && quad.VertexD < vertices.Count - 1)
{
++polycount;
}
}
ply.WriteLine("ply");
ply.WriteLine("format ascii 1.0");
ply.WriteLine("element vertex {0}", Vertices.Count);
ply.WriteLine("property int x");
ply.WriteLine("property int y");
ply.WriteLine("property int z");
ply.WriteLine("property uchar red");
ply.WriteLine("property uchar green");
ply.WriteLine("property uchar blue");
ply.WriteLine("element face {0}", polycount);
ply.WriteLine("property list uchar int vertex_index");
ply.WriteLine("end_header");
foreach (SceneryVertex vertex in vertices)
{
if (vertex.Color < Colors.Count)
{
SceneryColor color = Colors[vertex.Color];
ply.WriteLine("{0} {1} {2} {3} {4} {5}", vertex.X + XOffset / 16, vertex.Y + YOffset / 16, vertex.Z + ZOffset / 16, color.Red, color.Green, color.Blue);
}
else
{
ply.WriteLine("{0} {1} {2} 255 0 255", vertex.X + XOffset / 16, vertex.Y + YOffset / 16, vertex.Z + ZOffset / 16);
}
}
foreach (SceneryTriangle triangle in triangles)
{
if (triangle.VertexA < vertices.Count - 1 && triangle.VertexB < vertices.Count - 1 && triangle.VertexC < vertices.Count - 1)
{
ply.WriteLine("3 {0} {1} {2}", triangle.VertexA, triangle.VertexB, triangle.VertexC);
}
}
foreach (SceneryQuad quad in quads)
{
if (quad.VertexA < vertices.Count - 1 && quad.VertexB < vertices.Count - 1 && quad.VertexC < vertices.Count - 1 && quad.VertexD < vertices.Count - 1)
{
ply.WriteLine("4 {0} {1} {2} {3}", quad.VertexA, quad.VertexB, quad.VertexC, quad.VertexD);
}
}
}
return stream.ToArray();
}
}

/*public byte[] ToCOLLADA()
{
using (MemoryStream stream = new MemoryStream())
{
using (StreamWriter textwriter = new StreamWriter(stream))
using (XmlTextWriter xmlwriter = new XmlTextWriter(textwriter))
{
xmlwriter.WriteStartDocument();
xmlwriter.WriteStartElement("COLLADA");
xmlwriter.WriteAttributeString("xmlns", "http://www.collada.org/2005/11/COLLADASchema");
xmlwriter.WriteAttributeString("version", "1.4.1");
xmlwriter.WriteStartElement("library_geometries");
xmlwriter.WriteStartElement("geometry");
xmlwriter.WriteStartElement("mesh");
xmlwriter.WriteStartElement("source");
xmlwriter.WriteAttributeString("id", "positions");
xmlwriter.WriteStartElement("float_array");
xmlwriter.WriteAttributeString("id", "positions-array");
xmlwriter.WriteAttributeString("count", (vertices.Count * 3).ToString());
foreach (SceneryVertex vertex in vertices)
{
xmlwriter.WriteValue(vertex.X + XOffset / 4);
xmlwriter.WriteWhitespace(" ");
xmlwriter.WriteValue(vertex.Y + YOffset / 4);
xmlwriter.WriteWhitespace(" ");
xmlwriter.WriteValue(vertex.Z + ZOffset / 4);
xmlwriter.WriteWhitespace(" ");
}
xmlwriter.WriteEndElement();
xmlwriter.WriteStartElement("technique_common");
xmlwriter.WriteStartElement("accessor");
xmlwriter.WriteAttributeString("source", "#positions-array");
xmlwriter.WriteAttributeString("count", vertices.Count.ToString());
xmlwriter.WriteAttributeString("stride", "3");
xmlwriter.WriteStartElement("param");
xmlwriter.WriteAttributeString("name", "X");
xmlwriter.WriteAttributeString("type", "float");
xmlwriter.WriteEndElement();
xmlwriter.WriteStartElement("param");
xmlwriter.WriteAttributeString("name", "Y");
xmlwriter.WriteAttributeString("type", "float");
xmlwriter.WriteEndElement();
xmlwriter.WriteStartElement("param");
xmlwriter.WriteAttributeString("name", "Y");
xmlwriter.WriteAttributeString("type", "float");
xmlwriter.WriteEndElement();
xmlwriter.WriteEndElement();
xmlwriter.WriteEndElement();
xmlwriter.WriteEndElement();
xmlwriter.WriteStartElement("source");
xmlwriter.WriteAttributeString("id", "colors");
xmlwriter.WriteStartElement("float_array");
xmlwriter.WriteAttributeString("id", "colors-array");
xmlwriter.WriteAttributeString("count", (vertices.Count * 3).ToString());
foreach (SceneryVertex vertex in vertices)
{
if (vertex.Color < Colors.Count)
{
SceneryColor color = Colors[vertex.Color];
xmlwriter.WriteValue(color.Red / 256.0);
xmlwriter.WriteWhitespace(" ");
xmlwriter.WriteValue(color.Green / 256.0);
xmlwriter.WriteWhitespace(" ");
xmlwriter.WriteValue(color.Blue / 256.0);
xmlwriter.WriteWhitespace(" ");
}
else
{
xmlwriter.WriteValue(256.0 / 256.0);
xmlwriter.WriteWhitespace(" ");
xmlwriter.WriteValue(0 / 256.0);
xmlwriter.WriteWhitespace(" ");
xmlwriter.WriteValue(256.0 / 256.0);
xmlwriter.WriteWhitespace(" ");
}
}
xmlwriter.WriteEndElement();
xmlwriter.WriteStartElement("technique_common");
xmlwriter.WriteStartElement("accessor");
xmlwriter.WriteAttributeString("source", "#colors-array");
xmlwriter.WriteAttributeString("count", vertices.Count.ToString());
xmlwriter.WriteAttributeString("stride", "3");
xmlwriter.WriteStartElement("param");
xmlwriter.WriteAttributeString("name", "R");
xmlwriter.WriteAttributeString("type", "float");
xmlwriter.WriteEndElement();
xmlwriter.WriteStartElement("param");
xmlwriter.WriteAttributeString("name", "G");
xmlwriter.WriteAttributeString("type", "float");
xmlwriter.WriteEndElement();
xmlwriter.WriteStartElement("param");
xmlwriter.WriteAttributeString("name", "B");
xmlwriter.WriteAttributeString("type", "float");
xmlwriter.WriteEndElement();
xmlwriter.WriteEndElement();
xmlwriter.WriteEndElement();
xmlwriter.WriteEndElement();
xmlwriter.WriteStartElement("vertices");
xmlwriter.WriteAttributeString("id", "vertices");
xmlwriter.WriteStartElement("input");
xmlwriter.WriteAttributeString("semantic", "POSITION");
xmlwriter.WriteAttributeString("source", "positions");
xmlwriter.WriteEndElement();
xmlwriter.WriteStartElement("input");
xmlwriter.WriteAttributeString("semantic", "COLOR");
xmlwriter.WriteAttributeString("source", "colors");
xmlwriter.WriteEndElement();
xmlwriter.WriteEndElement();
xmlwriter.WriteStartElement("triangles");
xmlwriter.WriteAttributeString("count", triangles.Count.ToString());
xmlwriter.WriteStartElement("input");
xmlwriter.WriteAttributeString("semantic", "VERTEX");
xmlwriter.WriteAttributeString("source", "vertices");
xmlwriter.WriteAttributeString("offset", "0");
xmlwriter.WriteEndElement();
xmlwriter.WriteStartElement("p");
foreach (SceneryTriangle triangle in triangles)
{
xmlwriter.WriteValue(triangle.VertexA);
xmlwriter.WriteWhitespace(" ");
xmlwriter.WriteValue(triangle.VertexB);
xmlwriter.WriteWhitespace(" ");
xmlwriter.WriteValue(triangle.VertexC);
xmlwriter.WriteWhitespace(" ");
}
xmlwriter.WriteEndElement();
xmlwriter.WriteEndElement();
xmlwriter.WriteEndElement();
xmlwriter.WriteEndElement();
xmlwriter.WriteEndElement();
xmlwriter.WriteEndElement();
xmlwriter.WriteEndDocument();
}
return stream.ToArray();
}
}*/
}
}
25 changes: 25 additions & 0 deletions CrashEdit/Controllers/Animation/AnimationEntryController.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.IO;
using Crash;
using System.Windows.Forms;

Expand All @@ -14,8 +15,32 @@ public AnimationEntryController(EntryChunkController entrychunkcontroller, Anima
}
InvalidateNode();
InvalidateNodeImage();
AddMenu ("Export as OBJ", Menu_Export_OBJ_Game);
}

private void Menu_Export_OBJ_Game ()
{
if (!FileUtil.SelectSaveFile (out string output, FileFilters.OBJ, FileFilters.Any))
return;

// modify the path to add a number before the extension
string ext = Path.GetExtension (output);
string filename = Path.GetFileNameWithoutExtension (output);
string path = Path.GetDirectoryName (output);

int id = 0;
int count = Node.Nodes.Count.ToString().Length;

foreach (TreeNode node in Node.Nodes)
{
if (node.Tag is not FrameController frame)
continue;

frame.ToOBJ (path, filename + id.ToString().PadLeft (count, '0'));
id++;
}
}

public override void InvalidateNode()
{
Node.Text = string.Format(Crash.UI.Properties.Resources.AnimationEntryController_Text, AnimationEntry.EName);
Expand Down
Loading