public static uint FromVector3(Vector3 vec, int intPart = 0, int fracPart = 9) { var buffer = new byte[] { 0x00, 0x00 }; var coords = new ushort[3]; var m = new MemoryStream(buffer); var ew = new EndianBinaryWriterEx(m, Endianness.LittleEndian); var er = new EndianBinaryReaderEx(m, Endianness.LittleEndian); ew.WriteFixedPoint(vec.X, true, intPart, fracPart); m.Position = 0; coords[0] = er.ReadUInt16(); m.Position = 0; ew.WriteFixedPoint(vec.Y, true, intPart, fracPart); m.Position = 0; coords[1] = er.ReadUInt16(); m.Position = 0; ew.WriteFixedPoint(vec.Z, true, intPart, fracPart); m.Position = 0; coords[2] = er.ReadUInt16(); m.Close(); var res = (uint)(coords[0] | (coords[1] << 10) | (coords[2] << 20)); return(res); }
public static byte[] Encode(IEnumerable <DisplayListCommand> commands) { var m = new MemoryStream(); var ew = new EndianBinaryWriterEx(m, Endianness.LittleEndian); int offset = 0; int packed = 0; var cmdList = commands.ToList(); var nops = (cmdList.Count % 4) == 0 ? 0 : 4 - (cmdList.Count % 4); //Add NOPs at the end for (int i = 0; i < nops; i++) { cmdList.Add(new DisplayListCommand(G3dCommand.Nop)); } var commandQueue = new Queue <DisplayListCommand>(); bool param0Flag = false; void Flush() { packed = 0; var count = commandQueue.Count; for (int i = 0; i < count; i++) { var cmd = commandQueue.Dequeue(); //m.Position = offset; switch (cmd.G3dCommand) { default: case G3dCommand.Identity: case G3dCommand.PushMatrix: case G3dCommand.End: case G3dCommand.Nop: break; case G3dCommand.TexCoord: ew.WriteFixedPoint(cmd.RealArgs[0], true, 11, 4); ew.WriteFixedPoint(cmd.RealArgs[1], true, 11, 4); offset += 4; break; case G3dCommand.VertexXY: case G3dCommand.VertexXZ: case G3dCommand.VertexYZ: ew.WriteFx16s(cmd.RealArgs); offset += 4; break; case G3dCommand.Begin: case G3dCommand.RestoreMatrix: ew.Write(cmd.IntArgs[0]); offset += 4; break; case G3dCommand.VertexDiff: var vec2 = VecFx10.FromVector3((cmd.RealArgs[0] * 8, cmd.RealArgs[1] * 8, cmd.RealArgs[2] * 8)); ew.Write(vec2); offset += 4; break; case G3dCommand.VertexShort: var vec3 = VecFx10.FromVector3((cmd.RealArgs[0], cmd.RealArgs[1], cmd.RealArgs[2]), 3, 6); ew.Write(vec3); offset += 4; break; case G3dCommand.Normal: var vec = VecFx10.FromVector3((cmd.RealArgs[0], cmd.RealArgs[1], cmd.RealArgs[2])); ew.Write(vec); offset += 4; break; case G3dCommand.Color: var color = GFXUtil.ConvertColorFormat( (uint)Color.FromArgb(0, (int)cmd.IntArgs[0], (int)cmd.IntArgs[1], (int)cmd.IntArgs[2]).ToArgb(), ColorFormat.ARGB8888, ColorFormat.ABGR1555); ew.Write(color); offset += 4; break; case G3dCommand.Vertex: ew.WriteFx16s(cmd.RealArgs); ew.Write((ushort)0); offset += 8; break; } } if (param0Flag) { ew.Write(0); offset += 4; param0Flag = false; } } foreach (var command in cmdList) { if (command.G3dCommand != G3dCommand.Nop) { param0Flag = packed > 0 && (command.G3dCommand == G3dCommand.Identity || command.G3dCommand == G3dCommand.PushMatrix || command.G3dCommand == G3dCommand.End); } //m.Position = offset; commandQueue.Enqueue(command); ew.Write((byte)command.G3dCommand); packed++; offset++; if (packed == 4) { Flush(); } } var dl = m.ToArray(); m.Close(); return(dl); }