using System.IO; using System.Runtime.InteropServices; using UnityEngine; namespace MindPowerSdk { public enum ModelObjType : uint { Geometry = 1, Helper = 2 } public class lwModelObjInfo { [StructLayout(LayoutKind.Sequential, Pack = 4)] struct lwModelObjInfoHeader { public ModelObjType Type; public uint Addr; public uint Size; } public int GeomObjNum; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public lwGeomObjInfo[] GeomObjSeq; // 最多32个 public int Load(string file) { string filePath = Path.Combine(GlobalDefine.ClientDir, file); using FileStream fs = File.OpenRead(filePath); using BinaryReader fp = new BinaryReader(fs); uint version = fp.ReadUInt32(); int objNum = fp.ReadInt32(); lwModelObjInfoHeader[] header = new lwModelObjInfoHeader[objNum]; for (int i = 0; i < objNum; i++) { var h = StructReader.ReadStruct(fp); header[i] = h; } GeomObjNum = 0; GeomObjSeq = new lwGeomObjInfo[32]; for (int i = 0; i < objNum; i++) { var headerInfo = header[i]; fs.Seek(headerInfo.Addr, SeekOrigin.Begin); switch (headerInfo.Type) { case ModelObjType.Geometry: { this.GeomObjSeq[GeomObjNum] = new lwGeomObjInfo(); if (version == 0) // EXP_OBJ_VERSION_0_0_0_0 { int old_version = fp.ReadInt32(); } this.GeomObjSeq[GeomObjNum].Load(fp, version); GeomObjNum += 1; break; } case ModelObjType.Helper: { break; } } } return 0; } } public enum lwModelObjectLoadType { MODELOBJECT_LOAD_RESET = 0, MODELOBJECT_LOAD_MERGE = 1, MODELOBJECT_LOAD_MERGE2 = 2 }; public struct lwRenderCtrlCreateInfo { public uint ctrl_id; public uint decl_id; public uint vs_id; public uint ps_id; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public class lwStateCtrl { [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] /* this+0x0 */ public byte[] _state_seq; // MindPower::lwObjectStateEnum ??? public void SetState(uint state, byte value) { this._state_seq[state] = value; } } public class lwGeomObjInfo { [StructLayout(LayoutKind.Sequential, Pack = 1)] /* this+0x4 */ public struct lwGeomObjInfoHeader { /* this+0x0 */ public uint id; /* this+0x4 */ public uint parent_id; /* this+0x8 */ public lwModelObjectLoadType type; /* this+0xc */ public Matrix4x4 mat_local; /* this+0x4c */ public lwRenderCtrlCreateInfo rcci; /* this+0x5c */ public lwStateCtrl state_ctrl; /* this+0x64 */ public uint mtl_size; /* this+0x68 */ public uint mesh_size; /* this+0x6c */ public uint helper_size; /* this+0x70 */ public uint anim_size; }; /* this+0x4 */ public lwGeomObjInfoHeader header; /* this+0x78 */ public uint mtl_num; [MarshalAs(UnmanagedType.LPArray)] /* this+0x7c */ public lwMtlTexInfo[] mtl_seq; /* this+0x80 */ public lwMeshInfo mesh; /* this+0x130 */ public lwHelperInfo helper_data; /* this+0x160 */ public lwAnimDataInfo anim_data; public int Load(BinaryReader fp, uint version) { this.header = StructReader.ReadStruct(fp); this.header.state_ctrl.SetState(5, 0); this.header.state_ctrl.SetState(3, 1); if (this.header.mtl_size > 100000) { // System.Windows.Forms.MessageBox.Show("iii", "error"); return -1; } if (this.header.mtl_size > 0) { // lwLoadMtlTexInfo(ref this.mtl_seq, ref this.mtl_num, fp, version); } if (this.header.mesh_size > 0) { // lwMeshInfo_Load(ref this.mesh, fp, version); } if (this.header.helper_size > 0) { // this.helper_data.Load(fp, version); } if (this.header.anim_size > 0) { this.anim_data = new lwAnimDataInfo(); // this.anim_data.Load(fp, version); } return 0; } public int Load(string file) { if (!File.Exists(file)) return -1; FileStream fs = File.Open(file, FileMode.Open, FileAccess.Read); BinaryReader fp = new BinaryReader(fs); uint version = fp.ReadUInt32(); int ret = this.Load(fp, version); fp.Close(); fs.Close(); return ret; } } [StructLayout(LayoutKind.Sequential, Pack = 1)] public class lwMtlTexInfo { /* this+0x0 */ public float opacity; /* this+0x4 */ [MarshalAs(UnmanagedType.U4)] public lwMtlTexInfoTransparencyTypeEnum transp_type; // MindPower::lwMtlTexInfoTransparencyTypeEnum /* this+0x8 */ public lwMaterial mtl; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] /* this+0x4c */ public lwRenderStateAtom[] rs_set; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] /* this+0xac */ public lwTexInfo[] tex_seq; } public enum lwMtlTexInfoTransparencyTypeEnum { MTLTEX_TRANSP_FILTER = 0, MTLTEX_TRANSP_ADDITIVE = 1, MTLTEX_TRANSP_ADDITIVE1 = 2, MTLTEX_TRANSP_ADDITIVE2 = 3, MTLTEX_TRANSP_ADDITIVE3 = 4, MTLTEX_TRANSP_SUBTRACTIVE = 5, MTLTEX_TRANSP_SUBTRACTIVE1 = 6, MTLTEX_TRANSP_SUBTRACTIVE2 = 7, MTLTEX_TRANSP_SUBTRACTIVE3 = 8 } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct lwMaterial { /* this+0x0 */ public Color dif; /* this+0x10 */ public Color amb; /* this+0x20 */ public Color spe; /* this+0x30 */ public Color emi; /* this+0x40 */ public float power; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct lwRenderStateAtom { /* this+0x0 */ public uint state; // MindPower::lwRenderStateAtomType /* this+0x4 */ public uint value0; /* this+0x8 */ public uint value1; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public class lwTexInfo { /* this+0x0 */ public uint stage; /* this+0x4 */ public uint level; /* this+0x8 */ public uint usage; /* this+0xc */ [MarshalAs(UnmanagedType.U4)] public _D3DFORMAT format; /* this+0x10 */ [MarshalAs(UnmanagedType.U4)] public _D3DPOOL pool; /* this+0x14 */ public uint byte_alignment_flag; /* this+0x18 */ [MarshalAs(UnmanagedType.U4)] public lwTexInfoTypeEnum type; /* this+0x1c */ public uint width; /* this+0x20 */ public uint height; /* this+0x24 */ [MarshalAs(UnmanagedType.U4)] public lwColorKeyTypeEnum colorkey_type; /* this+0x28 */ public Color32 colorkey; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)] /* this+0x2c */ public char[] file_name; /* this+0x6c */ public uint data_pointer; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] /* this+0x70 */ public lwRenderStateAtom[] tss_set; }; public enum _D3DFORMAT { D3DFMT_UNKNOWN = 0x0, D3DFMT_R8G8B8 = 0x14, D3DFMT_A8R8G8B8 = 0x15, D3DFMT_X8R8G8B8 = 0x16, D3DFMT_R5G6B5 = 0x17, D3DFMT_X1R5G5B5 = 0x18, D3DFMT_A1R5G5B5 = 0x19, D3DFMT_A4R4G4B4 = 0x1a, D3DFMT_R3G3B2 = 0x1b, D3DFMT_A8 = 0x1c, D3DFMT_A8R3G3B2 = 0x1d, D3DFMT_X4R4G4B4 = 0x1e, D3DFMT_A2B10G10R10 = 0x1f, D3DFMT_G16R16 = 0x22, D3DFMT_A8P8 = 0x28, D3DFMT_P8 = 0x29, D3DFMT_L8 = 0x32, D3DFMT_A8L8 = 0x33, D3DFMT_A4L4 = 0x34, D3DFMT_V8U8 = 0x3c, D3DFMT_L6V5U5 = 0x3d, D3DFMT_X8L8V8U8 = 0x3e, D3DFMT_Q8W8V8U8 = 0x3f, D3DFMT_V16U16 = 0x40, D3DFMT_W11V11U10 = 0x41, D3DFMT_A2W10V10U10 = 0x43, D3DFMT_UYVY = 0x59565955, D3DFMT_YUY2 = 0x32595559, D3DFMT_DXT1 = 0x31545844, D3DFMT_DXT2 = 0x32545844, D3DFMT_DXT3 = 0x33545844, D3DFMT_DXT4 = 0x34545844, D3DFMT_DXT5 = 0x35545844, D3DFMT_D16_LOCKABLE = 0x46, D3DFMT_D32 = 0x47, D3DFMT_D15S1 = 0x49, D3DFMT_D24S8 = 0x4b, D3DFMT_D16 = 0x50, D3DFMT_D24X8 = 0x4d, D3DFMT_D24X4S4 = 0x4f, D3DFMT_VERTEXDATA = 0x64, D3DFMT_INDEX16 = 0x65, D3DFMT_INDEX32 = 0x66, D3DFMT_FORCE_DWORD = 0x7fffffff, } public enum _D3DPOOL { D3DPOOL_DEFAULT = 0x0, D3DPOOL_MANAGED = 0x1, D3DPOOL_SYSTEMMEM = 0x2, D3DPOOL_SCRATCH = 0x3, D3DPOOL_FORCE_DWORD = 0x7fffffff, } public enum lwTexInfoTypeEnum { TEX_TYPE_FILE = 0, TEX_TYPE_SIZE = 1, TEX_TYPE_DATA = 2, TEX_TYPE_INVALID = -1 } public enum lwColorKeyTypeEnum { COLORKEY_TYPE_NONE = 0, COLORKEY_TYPE_COLOR = 1, COLORKEY_TYPE_PIXEL = 2 } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct lwMeshInfo { [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct lwMeshInfoHeader { /* this+0x0 */ public uint fvf; /* this+0x4 */ [MarshalAs(UnmanagedType.U4)] public _D3DPRIMITIVETYPE pt_type; /* this+0x8 */ public uint vertex_num; /* this+0xc */ public uint index_num; /* this+0x10 */ public uint subset_num; /* this+0x14 */ public uint bone_index_num; /* this+0x18 */ public uint bone_infl_factor; /* this+0x1c */ public uint vertex_element_num; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] /* this+0x20 */ public lwRenderStateAtom[] rs_set; }; /* this+0x0 */ public lwMeshInfoHeader header; [MarshalAs(UnmanagedType.LPArray)] /* this+0x80 */ public Vector3[] vertex_seq; [MarshalAs(UnmanagedType.LPArray)] /* this+0x84 */ public Vector3[] normal_seq; [MarshalAs(UnmanagedType.LPArray)] /* this+0x88 */ public Vector2[] texcoord0_seq; [MarshalAs(UnmanagedType.LPArray)] /* this+0x8c */ public Vector2[] texcoord1_seq; [MarshalAs(UnmanagedType.LPArray)] /* this+0x90 */ public Vector2[] texcoord2_seq; [MarshalAs(UnmanagedType.LPArray)] /* this+0x94 */ public Vector2[] texcoord3_seq; [MarshalAs(UnmanagedType.LPArray)] /* this+0x98 */ public uint[] vercol_seq; [MarshalAs(UnmanagedType.LPArray)] /* this+0x9c */ public uint[] index_seq; [MarshalAs(UnmanagedType.LPArray)] /* this+0xa0 */ public uint[] bone_index_seq; [MarshalAs(UnmanagedType.LPArray)] /* this+0xa4 */ public lwBlendInfo[] blend_seq; [MarshalAs(UnmanagedType.LPArray)] /* this+0xa8 */ public lwSubsetInfo[] subset_seq; [MarshalAs(UnmanagedType.LPArray)] /* this+0xac */ public _D3DVERTEXELEMENT9[] vertex_element_seq; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct _D3DVERTEXELEMENT9 { /* this+0x0 */ public ushort Stream; /* this+0x2 */ public ushort Offset; /* this+0x4 */ public byte Type; /* this+0x5 */ public byte Method; /* this+0x6 */ public byte Usage; /* this+0x7 */ public byte UsageIndex; }; [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct lwSubsetInfo { /* this+0x0 */ public uint primitive_num; /* this+0x4 */ public uint start_index; /* this+0x8 */ public uint vertex_num; /* this+0xc */ public uint min_index; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct lwBlendInfo { [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] /* this+0x0 */ public byte[] index; /* this+0x0 */ //uint indexd; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] /* this+0x4 */ public float[] weight; } public enum _D3DPRIMITIVETYPE { D3DPT_POINTLIST = 0x1, D3DPT_LINELIST = 0x2, D3DPT_LINESTRIP = 0x3, D3DPT_TRIANGLELIST = 0x4, D3DPT_TRIANGLESTRIP = 0x5, D3DPT_TRIANGLEFAN = 0x6, D3DPT_FORCE_DWORD = 0x7fffffff, } }