mirror of
https://github.com/KillzXGaming/Switch-Toolbox
synced 2024-11-26 06:20:24 +00:00
Better gfbmdl materials
This commit is contained in:
parent
067244555a
commit
09e9bf0e95
10 changed files with 305 additions and 15 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -98,11 +98,41 @@ namespace FirstPlugin
|
|||
header = new Header();
|
||||
header.Read(new FileReader(stream), this);
|
||||
|
||||
ContextMenuStrip = new STContextMenuStrip();
|
||||
ContextMenuStrip.Items.Add(new ToolStripMenuItem("Export Model", null, ExportModelAction, Keys.Control | Keys.E));
|
||||
}
|
||||
|
||||
private void ExportModelAction(object sender, EventArgs args) {
|
||||
ExportModel();
|
||||
}
|
||||
|
||||
private void ExportModel()
|
||||
{
|
||||
SaveFileDialog sfd = new SaveFileDialog();
|
||||
sfd.Filter = "Supported Formats|*.dae;";
|
||||
if (sfd.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
ExportModel(sfd.FileName);
|
||||
}
|
||||
}
|
||||
|
||||
private void ExportModel(string FileName)
|
||||
{
|
||||
AssimpSaver assimp = new AssimpSaver();
|
||||
ExportModelSettings settings = new ExportModelSettings();
|
||||
|
||||
var model = new STGenericModel();
|
||||
model.Materials = header.GenericMaterials;
|
||||
model.Objects = Renderer.Meshes;
|
||||
|
||||
assimp.SaveFromModel(model, FileName, new List<STGenericTexture>(), ((STSkeleton)DrawableContainer.Drawables[0]));
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public byte[] Save()
|
||||
{
|
||||
var mem = new System.IO.MemoryStream();
|
||||
|
@ -221,7 +251,7 @@ namespace FirstPlugin
|
|||
|
||||
for (int i = 0; i < Materials.Count; i++)
|
||||
{
|
||||
GFBMaterial mat = new GFBMaterial(Root);
|
||||
GFBMaterial mat = new GFBMaterial(Root, Materials[i]);
|
||||
mat.Text = Materials[i].Name;
|
||||
|
||||
int textureUnit = 1;
|
||||
|
@ -232,7 +262,7 @@ namespace FirstPlugin
|
|||
STGenericMatTexture matTexture = new STGenericMatTexture();
|
||||
matTexture.Name = textureMap.Name;
|
||||
matTexture.textureUnit = textureUnit++;
|
||||
matTexture.wrapModeS = 0;
|
||||
matTexture.wrapModeS = 1;
|
||||
matTexture.wrapModeT = 0;
|
||||
|
||||
if (textureMap.Effect == "Col0Tex")
|
||||
|
@ -390,6 +420,10 @@ namespace FirstPlugin
|
|||
|
||||
public List<TextureMap> TextureMaps = new List<TextureMap>();
|
||||
|
||||
public Dictionary<string, SwitchParam> SwitchParams = new Dictionary<string, SwitchParam>();
|
||||
public Dictionary<string, ValueParam> ValueParams = new Dictionary<string, ValueParam>();
|
||||
public Dictionary<string, ColorParam> ColorParams = new Dictionary<string, ColorParam>();
|
||||
|
||||
public void Read(FileReader reader)
|
||||
{
|
||||
long DataPosition = reader.Position;
|
||||
|
@ -438,6 +472,53 @@ namespace FirstPlugin
|
|||
ShaderName = reader.ReadNameOffset(true, typeof(uint), true);
|
||||
}
|
||||
|
||||
if (ShaderParamAPosition != 0)
|
||||
{
|
||||
reader.SeekBegin(InfoPosition + ShaderParamAPosition);
|
||||
var ParamOffset = reader.ReadOffset(true, typeof(uint));
|
||||
reader.SeekBegin(ParamOffset);
|
||||
|
||||
uint Count = reader.ReadUInt32();
|
||||
for (int i = 0; i < Count; i++)
|
||||
{
|
||||
SwitchParam param = new SwitchParam();
|
||||
param.ReadParam(reader);
|
||||
SwitchParams.Add(param.Name, param);
|
||||
}
|
||||
}
|
||||
|
||||
if (ShaderParamBPosition != 0)
|
||||
{
|
||||
reader.SeekBegin(InfoPosition + ShaderParamBPosition);
|
||||
var ParamOffset = reader.ReadOffset(true, typeof(uint));
|
||||
reader.SeekBegin(ParamOffset);
|
||||
|
||||
uint Count = reader.ReadUInt32();
|
||||
for (int i = 0; i < Count; i++)
|
||||
{
|
||||
ValueParam param = new ValueParam();
|
||||
param.ReadParam(reader);
|
||||
ValueParams.Add(param.Name, param);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (ShaderParamCPosition != 0)
|
||||
{
|
||||
reader.SeekBegin(InfoPosition + ShaderParamCPosition);
|
||||
var ParamOffset = reader.ReadOffset(true, typeof(uint));
|
||||
reader.SeekBegin(ParamOffset);
|
||||
|
||||
uint Count = reader.ReadUInt32();
|
||||
for (int i = 0; i < Count; i++)
|
||||
{
|
||||
ColorParam param = new ColorParam();
|
||||
param.ReadParam(reader);
|
||||
ColorParams.Add(param.Name, param);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (TextureMapsPosition != 0)
|
||||
{
|
||||
reader.SeekBegin(InfoPosition + TextureMapsPosition);
|
||||
|
@ -458,6 +539,143 @@ namespace FirstPlugin
|
|||
}
|
||||
}
|
||||
|
||||
public class ColorParam : BaseParam
|
||||
{
|
||||
public void ReadParam(FileReader reader)
|
||||
{
|
||||
base.Read(reader);
|
||||
|
||||
if (ValuePosition != 0)
|
||||
{
|
||||
reader.SeekBegin(InfoPosition + ValuePosition);
|
||||
if (Format == 4)
|
||||
Value = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
|
||||
else if (Format == 8)
|
||||
Value = new Vector3(reader.ReadUInt32(), reader.ReadUInt32(), reader.ReadUInt32());
|
||||
else
|
||||
throw new Exception("Unknown format for switch param! " + Format);
|
||||
}
|
||||
else
|
||||
Value = 0;
|
||||
|
||||
Console.WriteLine($"Param {Name} {Value}");
|
||||
|
||||
//Seek back to next in array
|
||||
reader.SeekBegin(DataPosition + sizeof(uint));
|
||||
}
|
||||
}
|
||||
|
||||
public class ValueParam : BaseParam
|
||||
{
|
||||
public void ReadParam(FileReader reader)
|
||||
{
|
||||
base.Read(reader);
|
||||
|
||||
if (ValuePosition != 0)
|
||||
{
|
||||
reader.SeekBegin(InfoPosition + ValuePosition);
|
||||
if (Format == 4)
|
||||
Value = reader.ReadUInt32();
|
||||
else if (Format == 8)
|
||||
Value = reader.ReadSingle();
|
||||
else
|
||||
throw new Exception("Unknown format for switch param! " + Format);
|
||||
}
|
||||
else
|
||||
Value = 0;
|
||||
|
||||
//Seek back to next in array
|
||||
reader.SeekBegin(DataPosition + sizeof(uint));
|
||||
}
|
||||
}
|
||||
|
||||
public class SwitchParam : BaseParam
|
||||
{
|
||||
public void ReadParam(FileReader reader)
|
||||
{
|
||||
base.Read(reader);
|
||||
|
||||
if (ValuePosition != 0)
|
||||
{
|
||||
reader.SeekBegin(InfoPosition + ValuePosition);
|
||||
if (Format == 4)
|
||||
Value = (reader.ReadByte() == 1);
|
||||
else
|
||||
throw new Exception("Unknown format for switch param! " + Format);
|
||||
}
|
||||
else
|
||||
Value = false;
|
||||
|
||||
Console.WriteLine($"Param {Name} {Value}");
|
||||
|
||||
//Seek back to next in array
|
||||
reader.SeekBegin(DataPosition + sizeof(uint));
|
||||
}
|
||||
}
|
||||
|
||||
public class BaseParam
|
||||
{
|
||||
public string Effect { get; set; }
|
||||
public string Name { get; set; }
|
||||
|
||||
public uint Index { get; set; } = 0;
|
||||
|
||||
public uint Format { get; set; }
|
||||
|
||||
public object Value { get; set; }
|
||||
|
||||
internal long DataPosition;
|
||||
internal long InfoPosition;
|
||||
|
||||
internal ushort NamePosition;
|
||||
internal ushort FormatPosition;
|
||||
internal ushort ValuePosition;
|
||||
|
||||
public void Read(FileReader reader)
|
||||
{
|
||||
DataPosition = reader.Position;
|
||||
var DataOffset = reader.ReadOffset(true, typeof(uint));
|
||||
|
||||
reader.SeekBegin(DataOffset);
|
||||
InfoPosition = reader.Position;
|
||||
int InfoOffset = reader.ReadInt32();
|
||||
|
||||
//Read the info section for position data
|
||||
reader.SeekBegin(InfoPosition - InfoOffset);
|
||||
ushort HeaderSize = reader.ReadUInt16();
|
||||
NamePosition = 0;
|
||||
FormatPosition = 0;
|
||||
ValuePosition = 0;
|
||||
|
||||
if (HeaderSize == 0x06)
|
||||
{
|
||||
NamePosition = reader.ReadUInt16();
|
||||
FormatPosition = reader.ReadUInt16();
|
||||
}
|
||||
else if (HeaderSize == 0x08)
|
||||
{
|
||||
NamePosition = reader.ReadUInt16();
|
||||
FormatPosition = reader.ReadUInt16();
|
||||
ValuePosition = reader.ReadUInt16();
|
||||
}
|
||||
else
|
||||
throw new Exception("Unexpected header size! " + HeaderSize);
|
||||
|
||||
if (NamePosition != 0)
|
||||
{
|
||||
reader.SeekBegin(InfoPosition + NamePosition);
|
||||
uint NameLength = reader.ReadUInt32();
|
||||
Name = reader.ReadString((int)NameLength);
|
||||
}
|
||||
|
||||
if (FormatPosition != 0)
|
||||
{
|
||||
reader.SeekBegin(InfoPosition + FormatPosition);
|
||||
Format = reader.ReadUInt32();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class TextureMap
|
||||
{
|
||||
public string Effect { get; set; }
|
||||
|
|
|
@ -11,10 +11,13 @@ namespace FirstPlugin
|
|||
{
|
||||
public class GFBMaterial : STGenericMaterial
|
||||
{
|
||||
public GFBMDL.MaterialShaderData MaterialData { get; set; }
|
||||
|
||||
public GFBMDL ParentModel { get; set; }
|
||||
|
||||
public GFBMaterial(GFBMDL model) {
|
||||
public GFBMaterial(GFBMDL model, GFBMDL.MaterialShaderData data) {
|
||||
ParentModel = model;
|
||||
MaterialData = data;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -211,7 +211,59 @@ namespace FirstPlugin
|
|||
|
||||
private static void SetUniforms(GFBMaterial mat, ShaderProgram shader, GFBMesh m, int id)
|
||||
{
|
||||
// Texture Maps
|
||||
/* shader.SetBoolToInt("useColorTex", false);
|
||||
shader.SetBoolToInt("EmissionMaskUse", false);
|
||||
shader.SetBoolToInt("SwitchPriority", false);
|
||||
shader.SetBoolToInt("Layer1Enable", false);
|
||||
shader.SetBoolToInt("AmbientMapEnable", false);
|
||||
shader.SetBoolToInt("NormalMapEnable", false);
|
||||
shader.SetBoolToInt("LightTableEnable", false);
|
||||
shader.SetBoolToInt("BaseColorAddEnable", false);
|
||||
shader.SetBoolToInt("SphereMapEnable", false);
|
||||
shader.SetBoolToInt("EffectVal", false);*/
|
||||
|
||||
//Switch UVs
|
||||
shader.SetBoolToInt("SwitchEmissionMaskTexUV", false);
|
||||
shader.SetBoolToInt("SwitchAmbientTexUV", false);
|
||||
shader.SetBoolToInt("SwitchNormalMapUV", false);
|
||||
|
||||
//UV Scale
|
||||
shader.SetFloat("ColorUVScaleU", 1);
|
||||
shader.SetFloat("ColorUVScaleV", 1);
|
||||
|
||||
//UV Translate
|
||||
shader.SetFloat("ColorUVTranslateU", 0);
|
||||
shader.SetFloat("ColorUVTranslateV", 0);
|
||||
|
||||
SetUniformData(mat, shader, "ColorUVScaleU");
|
||||
SetUniformData(mat, shader, "ColorUVScaleV");
|
||||
SetUniformData(mat, shader, "ColorUVTranslateU");
|
||||
SetUniformData(mat, shader, "ColorUVTranslateV");
|
||||
}
|
||||
|
||||
private static void SetUniformData(GFBMaterial mat, ShaderProgram shader, string propertyName)
|
||||
{
|
||||
if (mat.MaterialData.SwitchParams.ContainsKey(propertyName))
|
||||
{
|
||||
bool Value = (bool)mat.MaterialData.SwitchParams[propertyName].Value;
|
||||
shader.SetBoolToInt(propertyName, Value);
|
||||
}
|
||||
if (mat.MaterialData.ValueParams.ContainsKey(propertyName))
|
||||
{
|
||||
var Value = mat.MaterialData.ValueParams[propertyName].Value;
|
||||
if (Value is float)
|
||||
shader.SetFloat(propertyName, (float)Value);
|
||||
if (Value is uint)
|
||||
shader.SetFloat(propertyName, (uint)Value);
|
||||
if (Value is int)
|
||||
shader.SetFloat(propertyName, (int)Value);
|
||||
}
|
||||
if (mat.MaterialData.ColorParams.ContainsKey(propertyName))
|
||||
{
|
||||
Vector3 Value = (Vector3)mat.MaterialData.ColorParams[propertyName].Value;
|
||||
shader.SetVector3(propertyName, Value);
|
||||
}
|
||||
}
|
||||
|
||||
private static void SetTextureUniforms(GFBMaterial mat, GFBMesh m, ShaderProgram shader)
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -87,9 +87,8 @@ namespace Switch_Toolbox.Library
|
|||
int MeshIndex = 0;
|
||||
foreach (var obj in Meshes)
|
||||
{
|
||||
var mesh = SaveMesh((STGenericObject)obj, MeshIndex, skeleton, NodeArray);
|
||||
var mesh = SaveMesh((STGenericObject)obj, MeshIndex++, skeleton, NodeArray);
|
||||
scene.Meshes.Add(mesh);
|
||||
MeshIndex++;
|
||||
}
|
||||
Node geomNode = new Node(Path.GetFileNameWithoutExtension(FileName), scene.RootNode);
|
||||
|
||||
|
@ -120,10 +119,6 @@ namespace Switch_Toolbox.Library
|
|||
textureCoords1.Add(new Vector3D(v.uv1.X, v.uv1.Y, 0));
|
||||
textureCoords2.Add(new Vector3D(v.uv2.X, v.uv2.Y, 0));
|
||||
vertexColors.Add(new Color4D(v.col.X, v.col.Y, v.col.Z, v.col.W));
|
||||
mesh.TextureCoordinateChannels[0] = textureCoords0;
|
||||
mesh.TextureCoordinateChannels[1] = textureCoords1;
|
||||
mesh.TextureCoordinateChannels[2] = textureCoords2;
|
||||
mesh.VertexColorChannels[0] = vertexColors;
|
||||
|
||||
if (skeleton != null)
|
||||
{
|
||||
|
@ -179,11 +174,27 @@ namespace Switch_Toolbox.Library
|
|||
|
||||
vertexID++;
|
||||
}
|
||||
List<int> faces = genericObj.lodMeshes[genericObj.DisplayLODIndex].faces;
|
||||
for (int f = 0; f < faces.Count; f++)
|
||||
mesh.Faces.Add(new Face(new int[] { faces[f++], faces[f++], faces[f] }));
|
||||
|
||||
if (genericObj.lodMeshes.Count != 0)
|
||||
{
|
||||
List<int> faces = genericObj.lodMeshes[genericObj.DisplayLODIndex].faces;
|
||||
for (int f = 0; f < faces.Count; f++)
|
||||
mesh.Faces.Add(new Face(new int[] { faces[f++], faces[f++], faces[f] }));
|
||||
}
|
||||
if (genericObj.PolygonGroups.Count != 0)
|
||||
{
|
||||
for (int p = 0; p < genericObj.PolygonGroups.Count; p++)
|
||||
{
|
||||
var polygonGroup = genericObj.PolygonGroups[p];
|
||||
for (int f = 0; f < polygonGroup.faces.Count; f++)
|
||||
mesh.Faces.Add(new Face(new int[] { polygonGroup.faces[f++], polygonGroup.faces[f++], polygonGroup.faces[f] }));
|
||||
}
|
||||
}
|
||||
|
||||
mesh.TextureCoordinateChannels.SetValue(textureCoords0, 0);
|
||||
mesh.TextureCoordinateChannels.SetValue(textureCoords1, 1);
|
||||
mesh.TextureCoordinateChannels.SetValue(textureCoords2, 2);
|
||||
mesh.VertexColorChannels.SetValue(vertexColors, 0);
|
||||
|
||||
return mesh;
|
||||
}
|
||||
|
|
|
@ -45,9 +45,12 @@ uniform int NoSkinning;
|
|||
uniform int RigidSkinning;
|
||||
uniform int SingleBoneIndex;
|
||||
|
||||
vec2 ST0_Translate;
|
||||
float ST0_Rotate;
|
||||
vec2 ST0_Scale;
|
||||
//Parameters
|
||||
uniform float ColorUVScaleU;
|
||||
uniform float ColorUVScaleV;
|
||||
uniform float ColorUVTranslateU;
|
||||
uniform float ColorUVTranslateV;
|
||||
|
||||
|
||||
vec4 skin(vec3 pos, ivec4 index)
|
||||
{
|
||||
|
@ -128,6 +131,9 @@ void main()
|
|||
|
||||
position = mtxCam * mtxMdl * vec4(vPosition.xyz, 1.0);
|
||||
|
||||
f_texcoord0.x *= ColorUVScaleU + ColorUVTranslateU;
|
||||
f_texcoord0.y *= ColorUVScaleV + ColorUVTranslateV;
|
||||
|
||||
gl_Position = position;
|
||||
|
||||
objectPosition = position.xyz;
|
||||
|
|
Loading…
Reference in a new issue