void IBinarySerializable.Read(EndianBinaryReader reader, object context)
        {
            NodeIndex = ( short )context;

            var positionsPacket = reader.ReadObject <VifPacket>();

            VifValidationHelper.Ensure(positionsPacket, null, true, false, null, VifUnpackElementFormat.Float, 4);
            Positions = positionsPacket.Vector4Array;

            // @NOTE(TGE): Not a single mesh type 7 mesh has the normals flag not set so I'm not sure if the flag is checked for.
            var normalsPacket = reader.ReadObject <VifPacket>();

            VifValidationHelper.Ensure(normalsPacket, null, true, false, VertexCount, VifUnpackElementFormat.Float, 3);
            Normals = normalsPacket.Vector3Array;

            var cmdTag = reader.ReadObject <VifCode>();

            if (cmdTag.Command == VifCommand.ActMicro)
            {
                VifValidationHelper.Ensure(cmdTag, 0x14, 0, VifCommand.ActMicro);
            }
            else if (cmdTag.Command != VifCommand.CntMicro)
            {
                throw new InvalidDataException("Expected activate or execute microprogram vif command");
            }
        }
Exemple #2
0
        void IBinarySerializable.Read(EndianBinaryReader reader, object context)
        {
            var flags = ( MeshFlags )context;

            var headerPacket = reader.ReadObject <VifPacket>();

            VifValidationHelper.Ensure(headerPacket, 0xFF, true, false, 1, VifUnpackElementFormat.Short, 2);

            var vertexCount = headerPacket.Int16Arrays[0][0];

            if (headerPacket.Int16Arrays[0][1] != 0)
            {
                throw new InvalidDataException("Header packet second short is not 0");
            }

            var positionsPacket = reader.ReadObject <VifPacket>();

            VifValidationHelper.Ensure(positionsPacket, 0, true, false, vertexCount, VifUnpackElementFormat.Float, 3);
            Positions = positionsPacket.Vector3Array;

            var normalsPacket = reader.ReadObject <VifPacket>();

            VifValidationHelper.Ensure(normalsPacket, 0x18, true, false, vertexCount, VifUnpackElementFormat.Float, 3);
            Normals = normalsPacket.Vector3Array;

            var texCoordPacket = reader.ReadObject <VifPacket>();

            VifValidationHelper.Ensure(texCoordPacket, 0x30, true, false, vertexCount, VifUnpackElementFormat.Float, 2);
            TexCoords = texCoordPacket.Vector2Array;

            var activateTag = reader.ReadObject <VifCode>();

            VifValidationHelper.Ensure(activateTag, 0x16, 0, VifCommand.ActMicro);

            var flushTag = reader.ReadObject <VifCode>();

            VifValidationHelper.Ensure(flushTag, 0, 0, VifCommand.FlushEnd);
            reader.Align(16);
        }
        void IBinarySerializable.Read(EndianBinaryReader reader, object context)
        {
            (short[] usedNodeIds, MeshFlags flags) = ((short[], MeshFlags))context;

            var headerPacket = reader.ReadObject <VifPacket>();

            VifValidationHelper.Ensure(headerPacket, 0xFF, true, false, 1, VifUnpackElementFormat.Short, 2);

            var usedNodeCount = headerPacket.Int16Arrays[0][0];
            var vertexCount   = headerPacket.Int16Arrays[0][1];

            if (usedNodeCount + 1 != usedNodeIds.Length)
            {
                throw new InvalidDataException("Used node count + 1 is not equal to the number of used node ids.");
            }

            foreach (short nodeId in usedNodeIds)
            {
                NodeBatches.Add(reader.ReadObject <MeshType7NodeBatch>(nodeId));
            }

            // @NOTE(TGE): Not a single mesh type 7 mesh does not have this flag set so I don't know if it should be checked for.
            var texCoordsPacket = reader.ReadObject <VifPacket>();

            VifValidationHelper.Ensure(texCoordsPacket, null, true, false, vertexCount, VifUnpackElementFormat.Float, 2);
            TexCoords = texCoordsPacket.Vector2Array;

            var texCoordsKickTag = reader.ReadObject <VifCode>();

            VifValidationHelper.Ensure(texCoordsKickTag, 0, 0, VifCommand.CntMicro);

            var flushTag = reader.ReadObject <VifCode>();

            VifValidationHelper.Ensure(flushTag, 0, 0, VifCommand.FlushEnd);
            reader.Align(16);
        }
Exemple #4
0
        void IBinarySerializable.Read(EndianBinaryReader reader, object context)
        {
            var ctx = ( IOContext )context;

            NodeIndex = ctx.NodeIndex;

            // Read header
            var headerPacket = reader.ReadObject <VifPacket>();

            VifValidationHelper.Ensure(headerPacket, 0, true, true, 1, VifUnpackElementFormat.Short, 4);
            var triangleCount = headerPacket.Int16Arrays[0][0];
            var vertexCount   = headerPacket.Int16Arrays[0][1];
            var flags         = Flags = ( MeshFlags )(( ushort )headerPacket.Int16Arrays[0][2] | ( ushort )headerPacket.Int16Arrays[0][3] << 16);

            if (ctx.IsLastBatch)
            {
                // Read triangles
                var indicesPacket = reader.ReadObject <VifPacket>();
                VifValidationHelper.Ensure(indicesPacket, 1, true, true, triangleCount, VifUnpackElementFormat.Byte, 4);
                ctx.Triangles = indicesPacket.SByteArrays.Select(x =>
                {
                    if (x[3] != 0)
                    {
                        throw new InvalidDataException();
                    }

                    return(new Triangle(( byte )x[0], ( byte )x[1], ( byte )x[2]));
                }).ToArray();
            }

            var positionsPacket = reader.ReadObject <VifPacket>();

            VifValidationHelper.Ensure(positionsPacket, !ctx.IsLastBatch ? 1 : ( int? )null, true, true, vertexCount, VifUnpackElementFormat.Float, 4);
            Positions = positionsPacket.Vector4Array;

            // Read normals
            if (flags.HasFlag(MeshFlags.Normal))
            {
                var normalsPacket = reader.ReadObject <VifPacket>();
                VifValidationHelper.Ensure(normalsPacket, null, true, true, vertexCount, VifUnpackElementFormat.Float, 3);
                Normals = normalsPacket.Vector3Array;
            }

            if (ctx.IsLastBatch)
            {
                if (flags.HasFlag(MeshFlags.TexCoord))
                {
                    var texCoordsPacket = reader.ReadObject <VifPacket>();

                    // Read texture coords
                    if (!flags.HasFlag(MeshFlags.TexCoord2))
                    {
                        VifValidationHelper.Ensure(texCoordsPacket, null, true, true, vertexCount, VifUnpackElementFormat.Float, 2);
                        ctx.TexCoords = texCoordsPacket.Vector2Array;
                    }
                    else
                    {
                        VifValidationHelper.Ensure(texCoordsPacket, null, true, true, vertexCount, VifUnpackElementFormat.Float, 4);
                        ctx.TexCoords  = texCoordsPacket.Vector4Array.Select(x => new Vector2(x.X, x.Y)).ToArray();
                        ctx.TexCoords2 = texCoordsPacket.Vector4Array.Select(x => new Vector2(x.Z, x.W)).ToArray();
                    }
                }

                if (flags.HasFlag(MeshFlags.Color))
                {
                    // Read colors
                    var colorsPacket = reader.ReadObject <VifPacket>();
                    VifValidationHelper.Ensure(colorsPacket, null, true, true, vertexCount, VifUnpackElementFormat.Byte, 4);
                    ctx.Colors = colorsPacket.SByteArrays.Select(x => new Color(( byte )x[0], ( byte )x[1], ( byte )x[2], ( byte )x[3]))
                                 .ToArray();
                }
            }

            // Read activate command
            var activateCode = reader.ReadObject <VifCode>();

            VifValidationHelper.ValidateActivateMicro(activateCode);

            // Not sure if this makes any difference yet
            RenderMode = activateCode.Immediate == 0x0C ? MeshBatchRenderMode.Mode1 : MeshBatchRenderMode.Mode2;

            Debug.Assert(Flags == flags);
        }