1
0
mirror of synced 2024-11-27 17:00:50 +01:00

Major KCL update.

KCL support has been greatly improved.
- High poly collisions can now be created (even higher than 65k+).
Collision should still be made with the game limitations and performance in mind!
- Support for all KCL versions (GC, Wii, DS, 3DS, etc). Keep in mind for various games to work, you must create a preset and configure the settings used for individual games. I will be adding many more soon to support a wide range of games.
- KCL files can now have the endianness switched and saved back allowing for direct conversion.
- OBJ importing will auto map materials by name COL_## (## being hex value). This allows to export and reimport collisions with all the data intact.
- File sizes are more optmized and improved.
- Speed signifcantly improved and is much faster for both exporting and replacing.
-Materials are now split in the node view for a KCL.  This is to select and easily see all the material types and so they can be highlighted.
This commit is contained in:
KillzXGaming 2020-08-16 11:42:39 -04:00
parent 553282bb2e
commit 232c44a605
19 changed files with 237 additions and 756 deletions

View File

@ -7,11 +7,14 @@ using GL_EditorFramework.Interfaces;
using OpenTK.Graphics.OpenGL;
using OpenTK;
using Toolbox.Library.Rendering;
using System.Drawing;
using System.Threading;
using Toolbox.Library.IO;
using Toolbox.Library.Forms;
using FirstPlugin.Forms;
using ByamlExt.Byaml;
using KclLibrary;
using KclLibraryGUI;
using Syroot.NintenTools.MarioKart8.Collisions;
namespace FirstPlugin
{
@ -28,10 +31,9 @@ namespace FirstPlugin
public bool Identify(System.IO.Stream stream)
{
using (var reader = new Toolbox.Library.IO.FileReader(stream, true))
{
using (var reader = new Toolbox.Library.IO.FileReader(stream, true)) {
reader.ByteOrder = Syroot.BinaryData.ByteOrder.BigEndian;
return reader.ReadUInt32() == 0x02020000;
return reader.ReadUInt32() == 0x02020000 || Utils.GetExtension(FileName) == ".kcl";
}
}
@ -45,7 +47,7 @@ namespace FirstPlugin
}
}
private byte[] data;
public KCLFile KclFile { get; set; }
public ToolStripItem[] GetContextMenuItems()
{
@ -55,9 +57,8 @@ namespace FirstPlugin
new ToolStripMenuItem("Export", null, Export, Keys.Control | Keys.E),
new ToolStripMenuItem("Replace", null, Replace, Keys.Control | Keys.R),
new ToolStripSeparator(),
new ToolStripMenuItem("Open Material Editor", null, OpenMaterialEditor, Keys.Control | Keys.M),
new ToolStripMenuItem("Big Endian Mode", null, SwapEndianess, Keys.Control | Keys.B)
{ Checked = (Endianness == Syroot.BinaryData.ByteOrder.BigEndian), },
{ Checked = (KclFile.ByteOrder == Syroot.BinaryData.ByteOrder.BigEndian), },
};
}
@ -70,9 +71,7 @@ namespace FirstPlugin
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
MarioKart.MK7.KCL.CollisionPresets.Clear();
MarioKart.MK7.KCL.LoadPresets(Directory.GetFiles(path));
MarioKart.MK7.KCL.LoadDefaultPresets();
CollisionPresetData.LoadPresets(Directory.GetFiles("KclMaterialPresets"));
}
public bool UseOverlay
@ -87,17 +86,6 @@ namespace FirstPlugin
set { Renderer.Visible = value; }
}
private void OpenMaterialEditor(object sender, EventArgs args)
{
CollisionMaterialEditor editor = new CollisionMaterialEditor();
editor.LoadCollisionValues(kcl, Renderer);
if (editor.ShowDialog() == DialogResult.OK)
{
}
}
public DrawableContainer DrawableContainer = new DrawableContainer();
public BymlFileData AttributeByml = null;
@ -114,8 +102,8 @@ namespace FirstPlugin
};
stream.Position = 0;
data = stream.ToArray();
Read(data);
KclFile = new KCLFile(stream);
ReloadData();
}
class MenuExt : IFileMenuExtension
@ -207,38 +195,48 @@ namespace FirstPlugin
public void CreateNew(object sender, EventArgs args)
{
var ByteOrder = Syroot.BinaryData.ByteOrder.LittleEndian;
bool isBigEndian = false;
if (sender.ToString() == "KCL (Wii U)")
ByteOrder = Syroot.BinaryData.ByteOrder.BigEndian;
isBigEndian = true;
OpenFileDialog opn = new OpenFileDialog();
opn.Filter = "Supported Formats|*.obj";
if (opn.ShowDialog() != DialogResult.OK) return;
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "Supported Formats|*.obj";
if (ofd.ShowDialog() != DialogResult.OK) return;
var mod = EditorCore.Common.OBJ.Read(new MemoryStream(File.ReadAllBytes(opn.FileName)), null);
var form = Runtime.MainForm;
var f = MarioKart.MK7.KCL.FromOBJ(mod);
string name = System.IO.Path.GetFileNameWithoutExtension(opn.FileName);
KCL kcl = new KCL();
kcl.Text = name;
kcl.IFileInfo = new IFileInfo();
kcl.FileName = name;
kcl.Renderer = new KCLRendering();
kcl.DrawableContainer = new DrawableContainer()
var thread = new Thread(() =>
{
Name = kcl.FileName,
Drawables = new List<AbstractGlDrawable>() { kcl.Renderer },
};
var result = CollisionLoader.CreateCollisionFromObject(form, ofd.FileName);
CollisionLoader.CloseConsole(form);
kcl.Read(f.Write(ByteOrder));
if (result.KclFie == null) return;
ObjectEditor editor = new ObjectEditor(kcl);
editor.Text = name;
LibraryGUI.CreateMdiWindow(editor);
form.Invoke((MethodInvoker)delegate
{
string name = Path.GetFileNameWithoutExtension(ofd.FileName);
KCL kcl = new KCL();
kcl.KclFile = result.KclFie;
kcl.AttributeByml = result.AttributeByml;
kcl.Text = name;
kcl.IFileInfo = new IFileInfo();
kcl.FileName = name;
kcl.Renderer = new KCLRendering();
kcl.ReloadData();
kcl.DrawableContainer = new DrawableContainer()
{
Name = kcl.FileName,
Drawables = new List<AbstractGlDrawable>() { kcl.Renderer },
};
ObjectEditor editor = new ObjectEditor(kcl);
editor.Text = name;
LibraryGUI.CreateMdiWindow(editor);
});
});
thread.Start();
}
}
@ -249,11 +247,7 @@ namespace FirstPlugin
public void Save(System.IO.Stream stream)
{
using (var writer = new FileWriter(stream))
{
writer.Write(data);
}
KclFile.Save(stream);
SaveAttributeByml();
}
@ -380,22 +374,9 @@ namespace FirstPlugin
}
}
private Syroot.BinaryData.ByteOrder endianness;
public Syroot.BinaryData.ByteOrder Endianness
{
get
{
return endianness;
}
set
{
endianness = value;
}
}
private void Export(object sender, EventArgs args)
{
if (kcl == null)
if (KclFile == null)
return;
SaveFileDialog sfd = new SaveFileDialog();
@ -405,7 +386,8 @@ namespace FirstPlugin
if (sfd.ShowDialog() == DialogResult.OK)
{
kcl.ToOBJ().toWritableObj().WriteObj(sfd.FileName + ".obj");
var obj = KclFile.CreateGenericModel();
obj.Save(sfd.FileName, true);
}
}
@ -416,27 +398,34 @@ namespace FirstPlugin
if (ofd.ShowDialog() == DialogResult.OK)
{
var mod = EditorCore.Common.OBJ.Read(new MemoryStream(File.ReadAllBytes(ofd.FileName)), null);
if (mod.Faces.Count > 65535)
var form = Runtime.MainForm;
var thread = new Thread(() =>
{
MessageBox.Show("this model has too many faces, only models with less than 65535 triangles can be converted");
return;
}
kcl = MarioKart.MK7.KCL.FromOBJ(mod);
AttributeByml = kcl.AttributeByml;
data = kcl.Write(Endianness);
Read(data);
Renderer.UpdateVertexData();
SaveAttributeByml(true);
var result = CollisionLoader.CreateCollisionFromObject(form, ofd.FileName);
CollisionLoader.CloseConsole(form);
if (result.KclFie == null) return;
form.Invoke((MethodInvoker)delegate
{
KclFile = result.KclFie;
AttributeByml = result.AttributeByml;
ReloadData();
Renderer.UpdateVertexData();
SaveAttributeByml(true);
});
});
thread.Start();
}
}
private void SwapEndianess(object sender, EventArgs args)
{
if (Endianness == Syroot.BinaryData.ByteOrder.BigEndian)
Endianness = Syroot.BinaryData.ByteOrder.LittleEndian;
if (KclFile.ByteOrder == Syroot.BinaryData.ByteOrder.BigEndian)
KclFile.ByteOrder = Syroot.BinaryData.ByteOrder.LittleEndian;
else
Endianness = Syroot.BinaryData.ByteOrder.BigEndian;
KclFile.ByteOrder = Syroot.BinaryData.ByteOrder.BigEndian;
}
private Viewport viewport
@ -478,236 +467,61 @@ namespace FirstPlugin
}
}
private MarioKart.MK7.KCL kcl;
private void Read(byte[] file_data)
{
data = file_data;
try
{
Endianness = Syroot.BinaryData.ByteOrder.LittleEndian;
kcl = new MarioKart.MK7.KCL(file_data, Syroot.BinaryData.ByteOrder.LittleEndian);
}
catch
{
Endianness = Syroot.BinaryData.ByteOrder.BigEndian;
kcl = new MarioKart.MK7.KCL(file_data, Syroot.BinaryData.ByteOrder.BigEndian);
}
Read(kcl);
}
public float DropToGround(Vector3 position)
{
List<float> found = new List<float>();
foreach (var model in kcl.Models) {
for (int p = 0; p < model.Planes.Length; p++) {
var triangle = model.GetTriangle(model.Planes[p]);
Vector3 a = Vec3D_To_Vec3(triangle.PointA);
Vector3 b = Vec3D_To_Vec3(triangle.PointB);
Vector3 c = Vec3D_To_Vec3(triangle.PointC);
if (PointInTriangle(position.Xz, a.Xz, b.Xz, c.Xz))
found.Add(barryCentric(a, b, c, position));
}
}
if (found.Count == 0)
return position.Y;
int closest_index = 0;
float closest_abs = 9999999.0f;
for (int i = 0; i < found.Count; i++)
{
float abs = Math.Abs(position.Y - found[i]);
if (abs < closest_abs)
{
closest_abs = abs;
closest_index = i;
}
}
Console.WriteLine($"found closest Y {found[closest_index]}");
return found[closest_index];
}
public static float barryCentric(Vector3 p1, Vector3 p2, Vector3 p3, Vector3 pos)
{
float det = (p2.Z - p3.Z) * (p1.X - p3.X) + (p3.X - p2.X) * (p1.Z - p3.Z);
float l1 = ((p2.Z - p3.Z) * (pos.X - p3.X) + (p3.X - p2.X) * (pos.Z - p3.Z)) / det;
float l2 = ((p3.Z - p1.Z) * (pos.X - p3.X) + (p1.X - p3.X) * (pos.Z - p3.Z)) / det;
float l3 = 1.0f - l1 - l2;
return l1 * p1.Y + l2 * p2.Y + l3 * p3.Y;
}
public static bool PointInTriangle(Vector2 p, Vector2 p0, Vector2 p1, Vector2 p2)
{
var s = p0.Y * p2.X - p0.X * p2.Y + (p2.Y - p0.Y) * p.X + (p0.X - p2.X) * p.Y;
var t = p0.X * p1.Y - p0.Y * p1.X + (p0.Y - p1.Y) * p.X + (p1.X - p0.X) * p.Y;
if ((s < 0) != (t < 0))
return false;
var A = -p1.Y * p2.X + p0.Y * (p2.X - p1.X) + p0.X * (p1.Y - p2.Y) + p1.X * p2.Y;
if (A < 0.0)
{
s = -s;
t = -t;
A = -A;
}
return s > 0 && t > 0 && (s + t) <= A;
}
private void LoadModelTree(TreeNode parent, MarioKart.ModelOctree[] modelOctrees)
{
if (modelOctrees == null)
return;
foreach (var model in modelOctrees)
{
OctreeNode modelNode = new OctreeNode(model, model.Key.ToString("X"));
parent.Nodes.Add(modelNode);
LoadModelTree(modelNode, model.Children);
}
}
public class OctreeNode : TreeNodeCustom
{
public List<OctreeNode> Children
{
get
{
List<OctreeNode> trees = new List<OctreeNode>();
foreach (var node in Nodes)
trees.Add((OctreeNode)node);
return trees;
}
}
MarioKart.ModelOctree Octree;
public OctreeNode(MarioKart.ModelOctree octree, string name)
{
Octree = octree;
Text = name;
}
public override void OnClick(TreeView treeview)
{
}
}
public List<KCLModel> GetKclModels()
{
public List<KCLModel> GetKclModels() {
return Renderer.models;
}
private void Read(MarioKart.MK7.KCL kcl)
private void ReloadData()
{
Vector3 min = new Vector3();
Vector3 max = new Vector3();
//Split collision triangles by materials between all the models
Dictionary<int, List<Triangle>> triangleList = new Dictionary<int, List<Triangle>>();
foreach (var model in KclFile.Models) {
foreach (var prisim in model.Prisims)
{
var triangle = model.GetTriangle(prisim);
if (!triangleList.ContainsKey(prisim.CollisionFlags))
triangleList.Add(prisim.CollisionFlags, new List<Triangle>());
triangleList[prisim.CollisionFlags].Add(triangle);
}
}
Nodes.Clear();
Renderer.OctreeNodes.Clear();
Renderer.models.Clear();
Renderer.KclFile = kcl;
Nodes.Clear();
TreeNode modelTree = new TreeNode("Model Octree");
LoadModelTree(modelTree, kcl.GlobalHeader.ModelOctrees);
foreach (var node in modelTree.Nodes)
Renderer.OctreeNodes.Add((OctreeNode)node);
Nodes.Add(modelTree);
int CurModelIndx = 0;
foreach (MarioKart.MK7.KCL.KCLModel mdl in kcl.Models)
//Load the vertex data for rendering
foreach (var triGroup in triangleList)
{
KCLModel kclmodel = new KCLModel();
kclmodel.Text = $"COL_{triGroup.Key.ToString("X")}";
kclmodel.Text = "Model " + CurModelIndx;
int faceIndex = 0;
int ft = 0;
foreach (var plane in mdl.Planes)
var triangles = triGroup.Value;
for (int i = 0; i < triangles.Count; i++)
{
var triangle = mdl.GetTriangle(plane);
var normal = triangle.Normal;
var pointA = triangle.PointA;
var pointB = triangle.PointB;
var pointC = triangle.PointC;
for (int v = 0; v < triangles[i].Vertices.Length; v++) {
var positon = triangles[i].Vertices[v];
var normal = triangles[i].Normal;
var attribute = triGroup.Key;
Vertex vtx = new Vertex();
Vertex vtx2 = new Vertex();
Vertex vtx3 = new Vertex();
vtx.pos = new Vector3(Vec3D_To_Vec3(pointA));
vtx2.pos = new Vector3(Vec3D_To_Vec3(pointB));
vtx3.pos = new Vector3(Vec3D_To_Vec3(pointC));
vtx.nrm = new Vector3(Vec3D_To_Vec3(normal));
vtx2.nrm = new Vector3(Vec3D_To_Vec3(normal));
vtx3.nrm = new Vector3(Vec3D_To_Vec3(normal));
KCLModel.Face face = new KCLModel.Face();
face.Text = triangle.Collision.ToString();
face.MaterialFlag = triangle.Collision;
var col = MarioKart.MK7.KCLColors.GetMaterialColor(plane.CollisionType);
Vector3 ColorSet = new Vector3(col.R, col.G, col.B);
vtx.col = new Vector4(ColorSet, 1);
vtx2.col = new Vector4(ColorSet, 1);
vtx3.col = new Vector4(ColorSet, 1);
kclmodel.faces.Add(ft);
kclmodel.faces.Add(ft + 1);
kclmodel.faces.Add(ft + 2);
ft += 3;
kclmodel.vertices.Add(vtx);
kclmodel.vertices.Add(vtx2);
kclmodel.vertices.Add(vtx3);
#region FindMaxMin
if (triangle.PointA.X < min.X) min.X = (float)triangle.PointA.X;
if (triangle.PointA.Y < min.Y) min.Y = (float)triangle.PointA.Y;
if (triangle.PointA.Z < min.Z) min.Z = (float)triangle.PointA.Z;
if (triangle.PointA.X > max.X) max.X = (float)triangle.PointA.X;
if (triangle.PointA.Y > max.Y) max.Y = (float)triangle.PointA.Y;
if (triangle.PointA.Z > max.Z) max.Z = (float)triangle.PointA.Z;
if (triangle.PointB.X < min.X) min.X = (float)triangle.PointB.X;
if (triangle.PointB.Y < min.Y) min.Y = (float)triangle.PointB.Y;
if (triangle.PointB.Z < min.Z) min.Z = (float)triangle.PointB.Z;
if (triangle.PointB.X > max.X) max.X = (float)triangle.PointB.X;
if (triangle.PointB.Y > max.Y) max.Y = (float)triangle.PointB.Y;
if (triangle.PointB.Z > max.Z) max.Z = (float)triangle.PointB.Z;
if (triangle.PointC.X < min.X) min.X = (float)triangle.PointC.X;
if (triangle.PointC.Y < min.Y) min.Y = (float)triangle.PointC.Y;
if (triangle.PointC.Z < min.Z) min.Z = (float)triangle.PointC.Z;
if (triangle.PointC.X > max.X) max.X = (float)triangle.PointC.X;
if (triangle.PointC.Y > max.Y) max.Y = (float)triangle.PointC.Y;
if (triangle.PointC.Z > max.Z) max.Z = (float)triangle.PointC.Z;
#endregion
kclmodel.vertices.Add(new Vertex()
{
pos = new Vector3(positon.X, positon.Y, positon.Z),
nrm = new Vector3(normal.X, normal.Y, normal.Z),
col = new Vector4(1,1,1,1),
});
kclmodel.faces.Add(faceIndex + v);
}
faceIndex += 3;
}
Renderer.Max = max;
Renderer.Min = min;
Renderer.models.Add(kclmodel);
Nodes.Add(kclmodel);
CurModelIndx++;
}
}
//Convert KCL lib vec3 to opentk one so i can use the cross and dot methods
public static Vector3 Vec3D_To_Vec3(System.Windows.Media.Media3D.Vector3D v)
{
return new Vector3((float)v.X, (float)v.Y, (float)v.Z);
}
public struct DisplayVertex
{
// Used for rendering.

View File

@ -81,9 +81,13 @@
<HintPath>..\Toolbox\Gl_EditorFramework.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="KCLExt, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\Toolbox\Lib\KCLExt.dll</HintPath>
<Reference Include="KclLibrary">
<HintPath>..\Toolbox\Lib\KclLibrary.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="KclLibraryGUI">
<HintPath>..\Toolbox\Lib\KclLibraryGUI.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="LibHac">
<HintPath>..\Toolbox\Lib\LibHac.dll</HintPath>
@ -1250,12 +1254,6 @@
<Compile Include="GUI\Editors\EffectTableEditor.Designer.cs">
<DependentUpon>EffectTableEditor.cs</DependentUpon>
</Compile>
<Compile Include="GUI\KCL\CollisionMaterialEditor.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="GUI\KCL\CollisionMaterialEditor.Designer.cs">
<DependentUpon>CollisionMaterialEditor.cs</DependentUpon>
</Compile>
<Compile Include="GUI\Message\MSBTEditor.cs">
<SubType>UserControl</SubType>
</Compile>
@ -2138,9 +2136,6 @@
<EmbeddedResource Include="GUI\Editors\VisibiltyAnimEditor.resx">
<DependentUpon>VisibiltyAnimEditor.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="GUI\KCL\CollisionMaterialEditor.resx">
<DependentUpon>CollisionMaterialEditor.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="GUI\KeySelection.resx" />
<EmbeddedResource Include="GUI\Byaml\ByamlEditor.resx">
<DependentUpon>ByamlEditor.cs</DependentUpon>

View File

@ -16,9 +16,6 @@ namespace FirstPlugin
{
public bool DrawGlobalOctrees = false;
public List<KCL.OctreeNode> OctreeNodes = new List<KCL.OctreeNode>();
public MarioKart.MK7.KCL KclFile;
public Vector3 Max = new Vector3(0);
public Vector3 Min = new Vector3(0);
@ -96,52 +93,6 @@ namespace FirstPlugin
LibraryGUI.UpdateViewport();
}
public void DrawGlobalOctree(ref Matrix4 mvp)
{
var octreeMax = KclFile.GlobalHeader.OctreeMax;
var octreeOrigin = KclFile.GlobalHeader.OctreeOrigin;
Vector3 max = new Vector3((float)octreeMax.X, (float)octreeMax.Y, (float)octreeMax.Z);
Vector3 min = new Vector3((float)octreeOrigin.X, (float)octreeOrigin.Y, (float)octreeOrigin.Z);
Console.WriteLine("DrawGlobalOctree " + min + " " + max);
var size = max - min;
var BoxSize = size / 2f;
var QuarterSize = BoxSize / 2f;
// DrawableBoundingBox.DrawBoundingBox(mvp, min, max, new Vector3(0));
DrawSubdivision(ref mvp, min, size, OctreeNodes, 0);
}
private void DrawSubdivision(ref Matrix4 mvp, Vector3 min, Vector3 size, List<KCL.OctreeNode> modelOctrees, int subdiv)
{
var BoxSize = size / 2f;
var QuarterSize = BoxSize / 2f;
int index = 0;
for (int z = 0; z < 2; z++)
{
for (int y = 0; y < 2; y++)
{
for (int x = 0; x < 2; x++)
{
var Boxmin = min + BoxSize * new Vector3(x,y,z);
var pos = BoxSize * new Vector3(x, y, z);
if (modelOctrees[index].IsSelected)
DrawableBoundingBox.DrawBoundingBox(mvp, QuarterSize, Boxmin + QuarterSize, System.Drawing.Color.Red);
else
DrawableBoundingBox.DrawBoundingBox(mvp, QuarterSize, Boxmin + QuarterSize, System.Drawing.Color.Green);
if (modelOctrees[index].Nodes.Count > 0)
DrawSubdivision(ref mvp, Boxmin, BoxSize, modelOctrees[index].Children, subdiv++);
index++;
}
}
}
}
public GLShaderGeneric Shader;
public ShaderProgram defaultShaderProgram;
@ -262,10 +213,6 @@ namespace FirstPlugin
CheckBuffers();
Matrix4 camMat = control.ModelMatrix * control.CameraMatrix * control.ProjectionMatrix;
if (DrawGlobalOctrees)
DrawGlobalOctree(ref camMat);
control.CurrentShader = defaultShaderProgram;
if (UseOverlay)

View File

@ -1,193 +0,0 @@
namespace FirstPlugin.Forms
{
partial class CollisionMaterialEditor
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.stListView1 = new Toolbox.Library.Forms.STListView();
this.olvColumn1 = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn()));
this.olvColumn2 = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn()));
this.numericUpDownUint1 = new Toolbox.Library.Forms.NumericUpDownUint();
this.stMenuStrip1 = new Toolbox.Library.Forms.STMenuStrip();
this.selectToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.byMaterialToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.stButton1 = new Toolbox.Library.Forms.STButton();
this.stButton2 = new Toolbox.Library.Forms.STButton();
this.stPanel1 = new Toolbox.Library.Forms.STPanel();
this.contentContainer.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.stListView1)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.numericUpDownUint1)).BeginInit();
this.stMenuStrip1.SuspendLayout();
this.stPanel1.SuspendLayout();
this.SuspendLayout();
//
// contentContainer
//
this.contentContainer.Controls.Add(this.stPanel1);
this.contentContainer.Size = new System.Drawing.Size(235, 393);
this.contentContainer.Controls.SetChildIndex(this.stPanel1, 0);
//
// stListView1
//
this.stListView1.AllColumns.Add(this.olvColumn1);
this.stListView1.AllColumns.Add(this.olvColumn2);
this.stListView1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.stListView1.CellEditUseWholeCell = false;
this.stListView1.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
this.olvColumn1,
this.olvColumn2});
this.stListView1.Cursor = System.Windows.Forms.Cursors.Default;
this.stListView1.Location = new System.Drawing.Point(-3, 53);
this.stListView1.Name = "stListView1";
this.stListView1.Size = new System.Drawing.Size(235, 277);
this.stListView1.TabIndex = 0;
this.stListView1.UseCompatibleStateImageBehavior = false;
this.stListView1.View = System.Windows.Forms.View.Details;
this.stListView1.SelectedIndexChanged += new System.EventHandler(this.stListView1_SelectedIndexChanged);
//
// olvColumn1
//
this.olvColumn1.AspectName = "ID";
this.olvColumn1.CellEditUseWholeCell = true;
this.olvColumn1.Text = "ID";
this.olvColumn1.Width = 92;
//
// olvColumn2
//
this.olvColumn2.AspectName = "Type";
this.olvColumn2.Text = "Type";
this.olvColumn2.Width = 131;
//
// numericUpDownUint1
//
this.numericUpDownUint1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.numericUpDownUint1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.numericUpDownUint1.Location = new System.Drawing.Point(2, 27);
this.numericUpDownUint1.Maximum = new decimal(new int[] {
2147483647,
0,
0,
0});
this.numericUpDownUint1.Name = "numericUpDownUint1";
this.numericUpDownUint1.Size = new System.Drawing.Size(230, 20);
this.numericUpDownUint1.TabIndex = 1;
//
// stMenuStrip1
//
this.stMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.selectToolStripMenuItem});
this.stMenuStrip1.Location = new System.Drawing.Point(0, 0);
this.stMenuStrip1.Name = "stMenuStrip1";
this.stMenuStrip1.Size = new System.Drawing.Size(235, 24);
this.stMenuStrip1.TabIndex = 2;
this.stMenuStrip1.Text = "stMenuStrip1";
//
// selectToolStripMenuItem
//
this.selectToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.byMaterialToolStripMenuItem});
this.selectToolStripMenuItem.Name = "selectToolStripMenuItem";
this.selectToolStripMenuItem.Size = new System.Drawing.Size(50, 20);
this.selectToolStripMenuItem.Text = "Select";
//
// byMaterialToolStripMenuItem
//
this.byMaterialToolStripMenuItem.Name = "byMaterialToolStripMenuItem";
this.byMaterialToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
this.byMaterialToolStripMenuItem.Text = "By Material";
//
// stButton1
//
this.stButton1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.stButton1.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.stButton1.Location = new System.Drawing.Point(72, 336);
this.stButton1.Name = "stButton1";
this.stButton1.Size = new System.Drawing.Size(77, 26);
this.stButton1.TabIndex = 3;
this.stButton1.Text = "Ok";
this.stButton1.UseVisualStyleBackColor = false;
//
// stButton2
//
this.stButton2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.stButton2.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.stButton2.Location = new System.Drawing.Point(155, 336);
this.stButton2.Name = "stButton2";
this.stButton2.Size = new System.Drawing.Size(77, 26);
this.stButton2.TabIndex = 4;
this.stButton2.Text = "Cancel";
this.stButton2.UseVisualStyleBackColor = false;
//
// stPanel1
//
this.stPanel1.Controls.Add(this.stListView1);
this.stPanel1.Controls.Add(this.stButton1);
this.stPanel1.Controls.Add(this.numericUpDownUint1);
this.stPanel1.Controls.Add(this.stButton2);
this.stPanel1.Controls.Add(this.stMenuStrip1);
this.stPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.stPanel1.Location = new System.Drawing.Point(0, 25);
this.stPanel1.Name = "stPanel1";
this.stPanel1.Size = new System.Drawing.Size(235, 368);
this.stPanel1.TabIndex = 11;
//
// CollisionMaterialEditor
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(238, 398);
this.MainMenuStrip = this.stMenuStrip1;
this.Name = "CollisionMaterialEditor";
this.Text = "Collision Materials";
this.contentContainer.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.stListView1)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.numericUpDownUint1)).EndInit();
this.stMenuStrip1.ResumeLayout(false);
this.stMenuStrip1.PerformLayout();
this.stPanel1.ResumeLayout(false);
this.stPanel1.PerformLayout();
this.ResumeLayout(false);
}
#endregion
private Toolbox.Library.Forms.STListView stListView1;
private BrightIdeasSoftware.OLVColumn olvColumn1;
private BrightIdeasSoftware.OLVColumn olvColumn2;
private Toolbox.Library.Forms.NumericUpDownUint numericUpDownUint1;
private Toolbox.Library.Forms.STMenuStrip stMenuStrip1;
private System.Windows.Forms.ToolStripMenuItem selectToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem byMaterialToolStripMenuItem;
private Toolbox.Library.Forms.STButton stButton1;
private Toolbox.Library.Forms.STButton stButton2;
private Toolbox.Library.Forms.STPanel stPanel1;
}
}

View File

@ -1,77 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using FirstPlugin;
using Toolbox.Library.Forms;
namespace FirstPlugin.Forms
{
public partial class CollisionMaterialEditor : STForm
{
public CollisionMaterialEditor()
{
InitializeComponent();
}
public KCL.GameSet GameMaterialSet = KCL.GameSet.MarioKart8D;
public class CollisionMaterial
{
public ushort ID { get; set; }
public string Type { get; set; }
}
KCLRendering Render;
public void LoadCollisionValues(MarioKart.MK7.KCL kcl, KCLRendering renderer)
{
Render = renderer;
List<CollisionMaterial> Materials = new List<CollisionMaterial>();
foreach (var model in kcl.Models)
{
foreach (var plane in model.Planes)
{
string type = "Unknown";
switch (GameMaterialSet)
{
case KCL.GameSet.MarioKart8D:
type = ((KCL.CollisionType_MK8D)plane.CollisionType).ToString();
break;
case KCL.GameSet.MarioOdyssey:
type = ((KCL.CollisionType_MarioOdssey)plane.CollisionType).ToString();
break;
}
Materials.Add(new CollisionMaterial()
{
ID = plane.CollisionType,
Type = type,
});
}
stListView1.SetObjects(Materials);
}
stListView1.SetTheme();
}
private void stListView1_SelectedIndexChanged(object sender, EventArgs e)
{
Render.SelectedTypes.Clear();
foreach (var collision in stListView1.SelectedObjects)
{
var coll = (CollisionMaterial)collision;
Render.SelectedTypes.Add(coll.ID);
}
}
}
}

View File

@ -1,123 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="stMenuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
</root>

View File

@ -1041,6 +1041,20 @@ namespace Toolbox.Library
dds.header.ddspf.ABitMask = components[(int)AlphaChannel];*/
}
/* if (Runtime.ImageEditor.PreviewGammaFix)
{
foreach (var surface in surfaces)
{
Bitmap bitMap = GetBitmap(surfaces.IndexOf(surface), 0);
bitMap = BitmapExtension.AdjustGamma(bitMap, 1.0f / 2.2f);
if (Runtime.ImageEditor.UseComponetSelector)
bitMap = BitmapExtension.SetChannel(bitMap, RedChannel, GreenChannel, BlueChannel, AlphaChannel);
var reEncoded = GenerateMipsAndCompress(bitMap, MipCount, Format);
//surface.mipmaps = reEncoded;
}
}*/
bool isCubeMap = ArrayCount == 6;
if (surfaces.Count > 1) //Use DX10 format for array surfaces as it can do custom amounts

View File

@ -0,0 +1,8 @@
{
"GameTitle": "Mario 3D World",
"PrismThickness": 40.0,
"SphereRadius": 0.0,
"Comments": "This game uses byml to customize presets.",
"MaterialPresets": {
}
}

View File

@ -0,0 +1,16 @@
{
"GameTitle": "Default",
"Platform": "SWITCH",
"PrismThickness": 30.0,
"SphereRadius": 25.0,
"PaddingMin": -50.0,
"PaddingMax": 50.0,
"MaxRootSize": 2048,
"MinRootSize": 128,
"MinCubeSize": 32,
"MaxTrianglesInCube": 10,
"Comments": "",
"MaterialPresets": {
"0": "Unknown"
}
}

View File

@ -0,0 +1,46 @@
{
"GameTitle": "Mario Kart 8 Deluxe",
"Platform": "SWITCH",
"PrismThickness": 30.0,
"SphereRadius": 25.0,
"Comments": "KCL Flag list by Divengerss from https://docs.google.com/spreadsheets/d/1muupGKuNDDe4ckRN_Wv6xd0L0FqA8tsvZUJNJs-4Sgs/edit#gid=0",
"MaterialPresets": {
"0": "Road",
"1": "Road_2",
"2": "Road (Bumpy)",
"3": "Road_3",
"4": "Road (Slippery)",
"5": "Road (Offroad Sand / No Particles",
"6": "Road (Offroad Sand)",
"7": "Road (Sticky Sound / No Particles)",
"8": "Road (Offroad)",
"9": "Road (Ice Particles Only)",
"10": "Road (Booster)",
"11": "Road (Anti-G-Panel)",
"12": "Road_4",
"13": "Road (Wet Road / Sound & particles)",
"14": "Road_5",
"15": "Road (Semi-solid)",
"16": "Lakitu Boundry",
"17": "Wall (Invisible / No sound & particles",
"18": "Wall (Water Wave on collide / No sound)",
"19": "Wall (Default particles / No sound)",
"31": "Glider",
"32": "Road (Foamy Sound)",
"40": "Road (Offroad, clicking Sound)",
"56": "Unsolid",
"60": "Water (Drown reset)",
"64": "Road (Rocky Sound)",
"81": "Wall (Metal sounds on impact)",
"129": "Road (3DS MP Piano)",
"134": "Road (RoyalR Offroad Grass)",
"161": "Road (3DS MP Xylophone)",
"193": "Road (3DS MP Vibraphone)",
"227": "Road (SNES RR road)",
"297": "Road (MKS Offroad Grass)",
"500": "Road (Water Wall)",
"4096": "Road (Stunt)",
"4106": "Road (Booster + Stunt)",
"4108": "Road (Stunt + Glider)"
}
}

View File

@ -1,5 +1,6 @@
{
"GameTitle": "Mario Kart 8 Wii U / Deluxe",
"GameTitle": "Mario Kart 8 Wii U",
"Platform": "WII U",
"PrismThickness": 30.0,
"SphereRadius": 25.0,
"Comments": "KCL Flag list by Divengerss from https://docs.google.com/spreadsheets/d/1muupGKuNDDe4ckRN_Wv6xd0L0FqA8tsvZUJNJs-4Sgs/edit#gid=0",
@ -40,6 +41,6 @@
"500": "Road (Water Wall)",
"4096": "Road (Stunt)",
"4106": "Road (Booster + Stunt)",
"4108": "Road (Stunt + Glider)",
"4108": "Road (Stunt + Glider)"
}
}

View File

@ -0,0 +1,15 @@
{
"GameTitle": "Mario Kart Wii",
"Platform": "WII",
"PrismThickness": 300.0,
"SphereRadius": 250.0,
"PaddingMin": -250.0,
"PaddingMax": 250.0,
"MaxRootSize": 2048,
"MinRootSize": 128,
"MinCubeSize": 512,
"MaxTrianglesInCube": 60,
"Comments": "",
"MaterialPresets": {
}
}

View File

@ -1,5 +1,6 @@
{
"GameTitle": "Mario Odyssey",
"Platform": "SWITCH",
"PrismThickness": 40.0,
"SphereRadius": 0.0,
"Comments": "This game uses byml to customize presets.",

View File

@ -1,9 +1,10 @@
{
"GameTitle": "Splatoon 1",
"Platform": "WII U",
"PrismThickness": 30.0,
"SphereRadius": 25.0,
"Comments": "",
"MaterialPresets": {
"0": "Unknown",
"0": "Unknown"
}
}

View File

@ -1,9 +1,10 @@
{
"GameTitle": "Splatoon 2",
"Platform": "SWITCH",
"PrismThickness": 30.0,
"SphereRadius": 25.0,
"Comments": "",
"MaterialPresets": {
"0": "Unknown",
"0": "Unknown"
}
}

Binary file not shown.

BIN
Toolbox/Lib/KclLibrary.dll Normal file

Binary file not shown.

Binary file not shown.

View File

@ -10,7 +10,7 @@
<AssemblyName>Toolbox</AssemblyName>
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<AutoGenerateBindingRedirects>false</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
<TargetFrameworkProfile />
<NuGetPackageImportStamp>
@ -184,9 +184,21 @@
<DependentUpon>Resources.resx</DependentUpon>
<DesignTime>True</DesignTime>
</Compile>
<None Include="KclMaterialPresets\3D World.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="KclMaterialPresets\Default.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="KclMaterialPresets\Mario Kart 8 Deluxe.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="KclMaterialPresets\Mario Kart 8.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="KclMaterialPresets\Mario Kart Wii.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="KclMaterialPresets\Mario Odyssey.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
@ -446,7 +458,10 @@
<Content Include="Lib\K4os.Hash.xxHash.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Lib\KCLExt.dll">
<Content Include="Lib\KclLibrary.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Lib\KclLibraryGUI.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Lib\LibHac.dll">