mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/PCK-Studio.git
synced 2026-09-23 07:22:25 +00:00
Created PSM Version 2
This commit is contained in:
@@ -4,33 +4,58 @@ using PckStudio.Core.Skin;
|
||||
|
||||
namespace PckStudio.ModelSupport.Internal.Format
|
||||
{
|
||||
/*
|
||||
Magic - 3 bytes("psm")
|
||||
Version - 1 byte [u8]
|
||||
Anim - 4 bytes[int32]
|
||||
NumberOfParts - 4 bytes[int32]
|
||||
{
|
||||
part parent - 1 byte (HEAD=0, BODY=1, LEG0=2, LEG1=3, ARM0=4, ARM1=5)
|
||||
Position-X - 4 bytes (float32)
|
||||
Position-Y - 4 bytes (float32)
|
||||
Position-Z - 4 bytes (float32)
|
||||
Size-X - 4 bytes (float32)
|
||||
Size-Y - 4 bytes (float32)
|
||||
Size-Z - 4 bytes (float32)
|
||||
MirrorAndUvX - 1 bit flag 7 bits uv.x value(0-64) (s8)
|
||||
HideWithArmorAndUvY - 1 bit flag 7 bits uv.y value(0-64) (s8)
|
||||
inflation/scale value - 4 bytes (float32)
|
||||
}
|
||||
NumberOfOffsets - 4 bytes[int32]
|
||||
{
|
||||
offset part - 1 byte
|
||||
vertical offset - 4 bytes[float]
|
||||
}
|
||||
*/
|
||||
/*
|
||||
* VERSION 1
|
||||
Magic - 3 bytes("psm")
|
||||
Version - 1 byte [u8]
|
||||
Anim - 4 bytes[int32]
|
||||
NumberOfParts - 4 bytes[int32]
|
||||
{
|
||||
part parent - 1 byte (HEAD=0, BODY=1, LEG0=2, LEG1=3, ARM0=4, ARM1=5)
|
||||
Position-X - 4 bytes (float32)
|
||||
Position-Y - 4 bytes (float32)
|
||||
Position-Z - 4 bytes (float32)
|
||||
Size-X - 4 bytes (float32)
|
||||
Size-Y - 4 bytes (float32)
|
||||
Size-Z - 4 bytes (float32)
|
||||
MirrorAndUvX - 1 bit flag 7 bits uv.x value(0-64) (s8)
|
||||
HideWithArmorAndUvY - 1 bit flag 7 bits uv.y value(0-64) (s8)
|
||||
Inflation - 4 bytes (float32)
|
||||
}
|
||||
NumberOfOffsets - 4 bytes[int32]
|
||||
{
|
||||
offset part - 1 byte
|
||||
vertical offset - 4 bytes[float]
|
||||
}
|
||||
|
||||
* VERSION 2
|
||||
Magic - 3 bytes("psm")
|
||||
Version - 1 byte [u8]
|
||||
Anim - 4 bytes [int32]
|
||||
Game Flags - 1 byte [u8]
|
||||
NumberOfParts - 4 bytes[int32]
|
||||
{
|
||||
ArmorMaskAndParParent - 3 bits Armor Mask 5 bits (Box Parent Type)
|
||||
Position-X - 4 bytes (float32)
|
||||
Position-Y - 4 bytes (float32)
|
||||
Position-Z - 4 bytes (float32)
|
||||
Size-X - 4 bytes (float32)
|
||||
Size-Y - 4 bytes (float32)
|
||||
Size-Z - 4 bytes (float32)
|
||||
MirrorAndUvX - 1 bit flag 7 bits uv.x value(0-64) (s8)
|
||||
ArmorMaskingAndUvY - 1 bit Helmet Mask 7 bits uv.y value(0-64) (s8)
|
||||
Inflation - 4 bytes (float32)
|
||||
}
|
||||
NumberOfOffsets - 4 bytes[int32]
|
||||
{
|
||||
offset part - 1 byte
|
||||
vertical offset - 4 bytes[float]
|
||||
}
|
||||
*/
|
||||
public sealed class PSMFile
|
||||
{
|
||||
internal static readonly string HEADER_MAGIC = "psm";
|
||||
internal const byte CurrentVersion = 1;
|
||||
internal const byte CurrentVersion = 2;
|
||||
|
||||
public readonly byte Version;
|
||||
|
||||
@@ -39,13 +64,15 @@ namespace PckStudio.ModelSupport.Internal.Format
|
||||
Version = version;
|
||||
}
|
||||
|
||||
internal PSMFile(byte version, SkinANIM skinANIM)
|
||||
: this(version)
|
||||
internal PSMFile(byte version, SkinANIM skinANIM, SkinGameFlags skinFlags)
|
||||
: this(version)
|
||||
{
|
||||
SkinANIM = skinANIM;
|
||||
SkinANIM = skinANIM;
|
||||
SkinFlags = skinFlags;
|
||||
}
|
||||
|
||||
public SkinANIM SkinANIM { get; private set; }
|
||||
public SkinANIM SkinANIM { get; private set; }
|
||||
public SkinGameFlags SkinFlags { get; private set; }
|
||||
|
||||
public readonly List<SkinBOX> Parts = new List<SkinBOX>();
|
||||
public readonly List<SkinPartOffset> Offsets = new List<SkinPartOffset>();
|
||||
@@ -82,5 +109,22 @@ namespace PckStudio.ModelSupport.Internal.Format
|
||||
ARM1 = 3,
|
||||
LEG0 = 4,
|
||||
LEG1 = 5,
|
||||
HEADWEAR = 6,
|
||||
JACKET = 7,
|
||||
SLEEVE0 = 8,
|
||||
SLEEVE1 = 9,
|
||||
PANTS0 = 10,
|
||||
PANTS1 = 11,
|
||||
WAIST = 12,
|
||||
LEGGING0 = 13,
|
||||
LEGGING1 = 14,
|
||||
SOCK0 = 15,
|
||||
SOCK1 = 16,
|
||||
BOOT0 = 17,
|
||||
BOOT1 = 18,
|
||||
ARMAMOR0 = 19,
|
||||
ARMAMOR1 = 20,
|
||||
BODYARMOR = 21,
|
||||
BELT = 22,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@ using OMI.Workers;
|
||||
using PckStudio.Core.FileFormats;
|
||||
using PckStudio.Core;
|
||||
using PckStudio.Core.Skin;
|
||||
using System;
|
||||
using System.Runtime.InteropServices.WindowsRuntime;
|
||||
|
||||
namespace PckStudio.ModelSupport.Internal.Format
|
||||
{
|
||||
@@ -35,33 +37,49 @@ namespace PckStudio.ModelSupport.Internal.Format
|
||||
}
|
||||
|
||||
byte version = reader.ReadByte();
|
||||
if (version < 1 || version > 1)
|
||||
if (version < 1 || version > PSMFile.CurrentVersion)
|
||||
{
|
||||
Trace.TraceError("PSMFileReader.FromStream - Failed to load csmb.\n\tReason: Unsupported version.");
|
||||
return new PSMFile(byte.MaxValue);
|
||||
}
|
||||
|
||||
var skinANIM = SkinANIM.FromValue(reader.ReadInt32());
|
||||
PSMFile csmbFile = new PSMFile(version, skinANIM);
|
||||
var skinFlags = SkinGameFlags.Empty;
|
||||
|
||||
if(version > 1)
|
||||
skinFlags = SkinGameFlags.FromValue(reader.ReadByte());
|
||||
|
||||
PSMFile psmFile = new PSMFile(version, skinANIM, skinFlags);
|
||||
int numOfParts = reader.ReadInt32();
|
||||
for (int i = 0; i < numOfParts; i++)
|
||||
{
|
||||
SkinBOX part = ReadPart(reader);
|
||||
csmbFile.Parts.Add(part);
|
||||
SkinBOX part = ReadPart(reader, version);
|
||||
psmFile.Parts.Add(part);
|
||||
}
|
||||
int numOfOffsets = reader.ReadInt32();
|
||||
for (int i = 0; i < numOfOffsets; i++)
|
||||
{
|
||||
SkinPartOffset offset = ReadOffset(reader);
|
||||
csmbFile.Offsets.Add(offset);
|
||||
psmFile.Offsets.Add(offset);
|
||||
}
|
||||
|
||||
return csmbFile;
|
||||
return psmFile;
|
||||
}
|
||||
|
||||
private SkinBOX ReadPart(EndiannessAwareBinaryReader reader)
|
||||
private SkinBOX ReadPart(EndiannessAwareBinaryReader reader, int version)
|
||||
{
|
||||
string type = GetParentType((PSMParentType)reader.ReadByte());
|
||||
int armorMask = 0;
|
||||
string type = "";
|
||||
if(version == 1)
|
||||
type = GetParentType((PSMParentType)reader.ReadByte());
|
||||
else
|
||||
{
|
||||
byte armorMaskAndParentType = reader.ReadByte();
|
||||
|
||||
type = GetParentType((PSMParentType)(armorMaskAndParentType & 0x1F)); // get first 5 bits
|
||||
armorMask = (armorMaskAndParentType & 0xE0) >> 5; // get last 3 bits
|
||||
}
|
||||
|
||||
float posX = reader.ReadSingle();
|
||||
float posY = reader.ReadSingle();
|
||||
float posZ = reader.ReadSingle();
|
||||
@@ -73,9 +91,9 @@ namespace PckStudio.ModelSupport.Internal.Format
|
||||
int uvX = mirrorAndUvX & 0x7f;
|
||||
int uvY = hideWithArmorAndUvY & 0x7f;
|
||||
bool mirror = (mirrorAndUvX & 0x80) != 0;
|
||||
int hideWithArmor = (hideWithArmorAndUvY & 0x80);
|
||||
armorMask = (armorMask << 1) | ((hideWithArmorAndUvY >> 7) & 1);
|
||||
float scale = reader.ReadSingle();
|
||||
return new SkinBOX(type, new System.Numerics.Vector3(posX, posY, posZ), new System.Numerics.Vector3(sizeX, sizeY, sizeZ), new System.Numerics.Vector2(uvX, uvY), hideWithArmor, mirror, scale);
|
||||
return new SkinBOX(type, new System.Numerics.Vector3(posX, posY, posZ), new System.Numerics.Vector3(sizeX, sizeY, sizeZ), new System.Numerics.Vector2(uvX, uvY), armorMask, mirror, scale);
|
||||
}
|
||||
|
||||
private SkinPartOffset ReadOffset(EndiannessAwareBinaryReader reader)
|
||||
@@ -101,6 +119,40 @@ namespace PckStudio.ModelSupport.Internal.Format
|
||||
return "LEG0";
|
||||
case PSMParentType.LEG1:
|
||||
return "LEG1";
|
||||
case PSMParentType.HEADWEAR:
|
||||
return "HEADWEAR";
|
||||
case PSMParentType.JACKET:
|
||||
return "JACKET";
|
||||
case PSMParentType.SLEEVE0:
|
||||
return "SLEEVE0";
|
||||
case PSMParentType.SLEEVE1:
|
||||
return "SLEEVE1";
|
||||
case PSMParentType.PANTS0:
|
||||
return "PANTS0";
|
||||
case PSMParentType.PANTS1:
|
||||
return "PANTS1";
|
||||
case PSMParentType.WAIST:
|
||||
return "WAIST";
|
||||
case PSMParentType.LEGGING0:
|
||||
return "LEGGING0";
|
||||
case PSMParentType.LEGGING1:
|
||||
return "LEGGING1";
|
||||
case PSMParentType.SOCK0:
|
||||
return "SOCK0";
|
||||
case PSMParentType.SOCK1:
|
||||
return "SOCK1";
|
||||
case PSMParentType.BOOT0:
|
||||
return "BOOT0";
|
||||
case PSMParentType.BOOT1:
|
||||
return "BOOT1";
|
||||
case PSMParentType.ARMAMOR0:
|
||||
return "ARMARMOR0";
|
||||
case PSMParentType.ARMAMOR1:
|
||||
return "ARMARMOR1";
|
||||
case PSMParentType.BODYARMOR:
|
||||
return "BODYARMOR";
|
||||
case PSMParentType.BELT:
|
||||
return "BELT";
|
||||
default:
|
||||
throw new InvalidDataException(type.ToString());
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ using OMI;
|
||||
using System;
|
||||
using OpenTK;
|
||||
using PckStudio.Core.Skin;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace PckStudio.ModelSupport.Internal.Format
|
||||
{
|
||||
@@ -33,6 +34,7 @@ namespace PckStudio.ModelSupport.Internal.Format
|
||||
writer.WriteString(PSMFile.HEADER_MAGIC);
|
||||
writer.Write(_PSM.Version);
|
||||
writer.Write(_PSM.SkinANIM.ToValue());
|
||||
writer.Write((byte)_PSM.SkinFlags.ToValue());
|
||||
writer.Write(_PSM.Parts.Count);
|
||||
foreach (SkinBOX part in _PSM.Parts)
|
||||
{
|
||||
@@ -49,7 +51,11 @@ namespace PckStudio.ModelSupport.Internal.Format
|
||||
|
||||
private void WritePart(EndiannessAwareBinaryWriter writer, SkinBOX part)
|
||||
{
|
||||
writer.Write((byte)GetParentPart(part.Type));
|
||||
byte armorMask = (byte)((part.ArmorMaskFlags.ToValue() >> 1) & 0x07);
|
||||
byte parentType = (byte)((int)GetParentPart(part.Type) & 0x1F);
|
||||
|
||||
byte armorMaskAndParentType = (byte)((armorMask << 5) | parentType);
|
||||
writer.Write(armorMaskAndParentType);
|
||||
writer.Write(part.Pos.X);
|
||||
writer.Write(part.Pos.Y);
|
||||
writer.Write(part.Pos.Z);
|
||||
@@ -60,9 +66,9 @@ namespace PckStudio.ModelSupport.Internal.Format
|
||||
byte uvX = (byte)MathHelper.Clamp((int)part.UV.X, 0, 64);
|
||||
byte uvY = (byte)MathHelper.Clamp((int)part.UV.Y, 0, 64);
|
||||
byte mirrorAndUvX = (byte)(Convert.ToByte(part.Mirror) << 7 | uvX);
|
||||
byte hideWithArmorAndUvY = (byte)(Convert.ToByte(part.ArmorMaskFlags.ToValue()) << 7 | uvY);
|
||||
byte helmetMaskAndUvY = (byte)(Convert.ToByte(part.ArmorMaskFlags.ToValue()) << 7 | uvY);
|
||||
writer.Write(mirrorAndUvX);
|
||||
writer.Write(hideWithArmorAndUvY);
|
||||
writer.Write(helmetMaskAndUvY);
|
||||
writer.Write(part.Scale);
|
||||
}
|
||||
|
||||
@@ -82,6 +88,40 @@ namespace PckStudio.ModelSupport.Internal.Format
|
||||
return PSMParentType.LEG0;
|
||||
case "LEG1":
|
||||
return PSMParentType.LEG1;
|
||||
case "HEADWEAR":
|
||||
return PSMParentType.HEADWEAR;
|
||||
case "JACKET":
|
||||
return PSMParentType.JACKET;
|
||||
case "SLEEVE0":
|
||||
return PSMParentType.SLEEVE0;
|
||||
case "SLEEVE1":
|
||||
return PSMParentType.SLEEVE1;
|
||||
case "PANTS0":
|
||||
return PSMParentType.PANTS0;
|
||||
case "PANTS1":
|
||||
return PSMParentType.PANTS1;
|
||||
case "WAIST":
|
||||
return PSMParentType.WAIST;
|
||||
case "LEGGING0":
|
||||
return PSMParentType.LEGGING0;
|
||||
case "LEGGING1":
|
||||
return PSMParentType.LEGGING1;
|
||||
case "SOCK0":
|
||||
return PSMParentType.SOCK0;
|
||||
case "SOCK1":
|
||||
return PSMParentType.SOCK1;
|
||||
case "BOOT0":
|
||||
return PSMParentType.BOOT0;
|
||||
case "BOOT1":
|
||||
return PSMParentType.BOOT1;
|
||||
case "ARMARMOR0":
|
||||
return PSMParentType.ARMAMOR0;
|
||||
case "ARMARMOR1":
|
||||
return PSMParentType.ARMAMOR1;
|
||||
case "BODYARMOR":
|
||||
return PSMParentType.BODYARMOR;
|
||||
case "BELT":
|
||||
return PSMParentType.BELT;
|
||||
default:
|
||||
throw new InvalidDataException(type);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user