コード例 #1
0
ファイル: ShaderBinary.cs プロジェクト: yorki00/SPICA
 private Vector4 ReadVec4(BinaryReader Reader)
 {
     return(new Vector4(
                PICAVectorFloat24.GetFloat24(Reader.ReadUInt32()),
                PICAVectorFloat24.GetFloat24(Reader.ReadUInt32()),
                PICAVectorFloat24.GetFloat24(Reader.ReadUInt32()),
                PICAVectorFloat24.GetFloat24(Reader.ReadUInt32())));
 }
コード例 #2
0
ファイル: GFMesh.cs プロジェクト: HelloOO7/SPICA
        public GFMesh(BinaryReader Reader) : this()
        {
            GFSection MeshSection = new GFSection(Reader);

            long Position = Reader.BaseStream.Position;

            uint   NameHash = Reader.ReadUInt32();
            string NameStr  = Reader.ReadPaddedString(0x40);

            Name = NameStr;

            Reader.ReadUInt32();

            BBoxMinVector = Reader.ReadVector4(); //Is it right? seems to be 0, 0, 0, 1
            BBoxMaxVector = Reader.ReadVector4(); //Is it right? seems to be 0, 0, 0, 1

            uint SubMeshesCount = Reader.ReadUInt32();

            BoneIndicesPerVertex = Reader.ReadInt32();

            Reader.BaseStream.Seek(0x10, SeekOrigin.Current); //Padding

            List <uint[]> CmdList = new List <uint[]>();

            uint CommandsLength;
            uint CommandIndex;
            uint CommandsCount;
            uint Padding;

            do
            {
                CommandsLength = Reader.ReadUInt32();
                CommandIndex   = Reader.ReadUInt32();
                CommandsCount  = Reader.ReadUInt32();
                Padding        = Reader.ReadUInt32();

                uint[] Commands = new uint[CommandsLength >> 2];

                for (int Index = 0; Index < Commands.Length; Index++)
                {
                    Commands[Index] = Reader.ReadUInt32();
                }

                CmdList.Add(Commands);
            }while (CommandIndex < CommandsCount - 1);

            SubMeshSize[] SMSizes = new SubMeshSize[SubMeshesCount];

            //Add SubMesh with Hash, Name and Bone Indices.
            //The rest is added latter (because the data is split inside the file).
            for (int MeshIndex = 0; MeshIndex < SubMeshesCount; MeshIndex++)
            {
                GFSubMesh SM = new GFSubMesh();

                uint SMNameHash = Reader.ReadUInt32();

                SM.Name             = Reader.ReadIntLengthString();
                SM.BoneIndicesCount = Reader.ReadByte();

                for (int Bone = 0; Bone < 0x1f; Bone++)
                {
                    SM.BoneIndices[Bone] = Reader.ReadByte();
                }

                SMSizes[MeshIndex] = new SubMeshSize()
                {
                    VerticesCount  = Reader.ReadInt32(),
                    IndicesCount   = Reader.ReadInt32(),
                    VerticesLength = Reader.ReadInt32(),
                    IndicesLength  = Reader.ReadInt32()
                };

                SubMeshes.Add(SM);
            }

            for (int MeshIndex = 0; MeshIndex < SubMeshesCount; MeshIndex++)
            {
                GFSubMesh SM = SubMeshes[MeshIndex];

                uint[] EnableCommands  = CmdList[MeshIndex * 3 + 0];
                uint[] DisableCommands = CmdList[MeshIndex * 3 + 1];
                uint[] IndexCommands   = CmdList[MeshIndex * 3 + 2];

                PICACommandReader CmdReader;

                CmdReader = new PICACommandReader(EnableCommands);

                PICAVectorFloat24[] Fixed = new PICAVectorFloat24[12];

                ulong BufferFormats     = 0;
                ulong BufferAttributes  = 0;
                ulong BufferPermutation = 0;
                int   AttributesCount   = 0;
                int   AttributesTotal   = 0;

                int FixedIndex = 0;

                while (CmdReader.HasCommand)
                {
                    PICACommand Cmd = CmdReader.GetCommand();

                    uint Param = Cmd.Parameters[0];

                    switch (Cmd.Register)
                    {
                    case PICARegister.GPUREG_ATTRIBBUFFERS_FORMAT_LOW:  BufferFormats |= (ulong)Param << 0; break;

                    case PICARegister.GPUREG_ATTRIBBUFFERS_FORMAT_HIGH: BufferFormats |= (ulong)Param << 32; break;

                    case PICARegister.GPUREG_ATTRIBBUFFER0_CONFIG1:
                        BufferAttributes |= Param;
                        break;

                    case PICARegister.GPUREG_ATTRIBBUFFER0_CONFIG2:
                        BufferAttributes |= (ulong)(Param & 0xffff) << 32;
                        SM.VertexStride   = (byte)(Param >> 16);
                        AttributesCount   = (int)(Param >> 28);
                        break;

                    case PICARegister.GPUREG_FIXEDATTRIB_INDEX: FixedIndex = (int)Param; break;

                    case PICARegister.GPUREG_FIXEDATTRIB_DATA0: Fixed[FixedIndex].Word0 = Param; break;

                    case PICARegister.GPUREG_FIXEDATTRIB_DATA1: Fixed[FixedIndex].Word1 = Param; break;

                    case PICARegister.GPUREG_FIXEDATTRIB_DATA2: Fixed[FixedIndex].Word2 = Param; break;

                    case PICARegister.GPUREG_VSH_NUM_ATTR: AttributesTotal = (int)(Param + 1); break;

                    case PICARegister.GPUREG_VSH_ATTRIBUTES_PERMUTATION_LOW:  BufferPermutation |= (ulong)Param << 0; break;

                    case PICARegister.GPUREG_VSH_ATTRIBUTES_PERMUTATION_HIGH: BufferPermutation |= (ulong)Param << 32; break;
                    }
                }

                for (int Index = 0; Index < AttributesTotal; Index++)
                {
                    if (((BufferFormats >> (48 + Index)) & 1) != 0)
                    {
                        PICAAttributeName Name = (PICAAttributeName)((BufferPermutation >> Index * 4) & 0xf);

                        float Scale =
                            Name == PICAAttributeName.Color ||
                            Name == PICAAttributeName.BoneWeight ? Scales[1] : 1;

                        SM.FixedAttributes.Add(new PICAFixedAttribute()
                        {
                            Name  = Name,
                            Value = Fixed[Index] * Scale
                        });
                    }
                    else
                    {
                        int PermutationIdx = (int)((BufferAttributes >> Index * 4) & 0xf);
                        int AttributeName  = (int)((BufferPermutation >> PermutationIdx * 4) & 0xf);
                        int AttributeFmt   = (int)((BufferFormats >> PermutationIdx * 4) & 0xf);

                        PICAAttribute Attrib = new PICAAttribute()
                        {
                            Name     = (PICAAttributeName)AttributeName,
                            Format   = (PICAAttributeFormat)(AttributeFmt & 3),
                            Elements = (AttributeFmt >> 2) + 1,
                            Scale    = Scales[AttributeFmt & 3]
                        };

                        if (Attrib.Name == PICAAttributeName.BoneIndex)
                        {
                            Attrib.Scale = 1;
                        }

                        SM.Attributes.Add(Attrib);
                    }
                }

                CmdReader = new PICACommandReader(IndexCommands);

                uint BufferAddress = 0;
                uint BufferCount   = 0;

                while (CmdReader.HasCommand)
                {
                    PICACommand Cmd = CmdReader.GetCommand();

                    uint Param = Cmd.Parameters[0];

                    switch (Cmd.Register)
                    {
                    case PICARegister.GPUREG_INDEXBUFFER_CONFIG: BufferAddress = Param; break;

                    case PICARegister.GPUREG_NUMVERTICES:        BufferCount = Param; break;

                    case PICARegister.GPUREG_PRIMITIVE_CONFIG:
                        SM.PrimitiveMode = (PICAPrimitiveMode)(Param >> 8);
                        break;
                    }
                }

                SM.RawBuffer = Reader.ReadBytes(SMSizes[MeshIndex].VerticesLength);

                SM.Indices = new ushort[BufferCount];

                long IndexAddress = Reader.BaseStream.Position;

                for (int Index = 0; Index < BufferCount; Index++)
                {
                    if ((BufferAddress >> 31) != 0)
                    {
                        SM.Indices[Index] = Reader.ReadUInt16();
                    }
                    else
                    {
                        SM.Indices[Index] = Reader.ReadByte();
                    }
                }

                Reader.BaseStream.Seek(IndexAddress + SMSizes[MeshIndex].IndicesLength, SeekOrigin.Begin);
            }

            Reader.BaseStream.Seek(Position + MeshSection.Length, SeekOrigin.Begin);
        }
コード例 #3
0
ファイル: Vector.cs プロジェクト: yorki00/SPICA
 public static Vector4 ToVector4(this PICAVectorFloat24 v)
 {
     return(new Vector4(v.X, v.Y, v.Z, v.W));
 }