Пример #1
0
        protected override SolidMeshVertex GetVertex(BinaryReader reader, SolidObjectMaterial material, int stride)
        {
            SolidMeshVertex vertex;

            switch (stride)
            {
            case 60:
                vertex = new SolidMeshVertex
                {
                    Position     = BinaryUtil.ReadVector3(reader),
                    Normal       = BinaryUtil.ReadVector3(reader),
                    Color        = reader.ReadUInt32(),
                    TexCoords    = BinaryUtil.ReadVector2(reader),
                    BlendWeight  = BinaryUtil.ReadVector3(reader),
                    BlendIndices = BinaryUtil.ReadVector3(reader),
                };
                break;

            // position (12 bytes) + normal (12 bytes) + color (4 bytes) + tex coords (8 bytes)
            case 36:
                vertex = new SolidMeshVertex
                {
                    Position  = BinaryUtil.ReadVector3(reader),
                    Normal    = BinaryUtil.ReadVector3(reader),
                    Color     = reader.ReadUInt32(),
                    TexCoords = BinaryUtil.ReadVector2(reader)
                };
                break;

            // position (12 bytes) + color (4 bytes) + tex coords (8 bytes)
            case 24:
                vertex = new SolidMeshVertex
                {
                    Position  = BinaryUtil.ReadVector3(reader),
                    Color     = reader.ReadUInt32(),
                    TexCoords = BinaryUtil.ReadVector2(reader)
                };
                break;

            default:
                throw new Exception($"Cannot handle vertex size: {stride}");
            }

            return(vertex);
        }
Пример #2
0
        protected override SolidMeshVertex GetVertex(BinaryReader reader, SolidObjectMaterial material, int stride)
        {
            MostWantedMaterial mwm    = (MostWantedMaterial)material;
            SolidMeshVertex    vertex = new SolidMeshVertex();

            InternalEffectID id = (InternalEffectID)mwm.EffectId;

            switch (id)
            {
            case InternalEffectID.WorldNormalMap:
            case InternalEffectID.WorldReflectShader:
                vertex.Position             = BinaryUtil.ReadVector3(reader);
                vertex.Normal               = BinaryUtil.ReadVector3(reader);
                vertex.Color                = reader.ReadUInt32();
                vertex.TexCoords            = BinaryUtil.ReadVector2(reader);
                reader.BaseStream.Position += 8;     // TODO: What's this additional D3DDECLUSAGE_TEXCOORD element?
                vertex.Tangent              = BinaryUtil.ReadVector3(reader);
                reader.BaseStream.Position += 4;     // skip W component of tangent vector
                break;

            case InternalEffectID.skyshader:
                vertex.Position             = BinaryUtil.ReadVector3(reader);
                vertex.Normal               = BinaryUtil.ReadVector3(reader);
                vertex.Color                = reader.ReadUInt32();
                vertex.TexCoords            = BinaryUtil.ReadVector2(reader);
                reader.BaseStream.Position += 8;     // TODO: What's this additional D3DDECLUSAGE_TEXCOORD element?
                break;

            case InternalEffectID.WorldShader:
            case InternalEffectID.GlossyWindow:
            case InternalEffectID.billboardshader:
            case InternalEffectID.CarShader:
                vertex.Position  = BinaryUtil.ReadVector3(reader);
                vertex.Normal    = BinaryUtil.ReadVector3(reader);
                vertex.Color     = reader.ReadUInt32();
                vertex.TexCoords = BinaryUtil.ReadVector2(reader);
                break;

            default:
                throw new Exception($"Unsupported effect in object {Name}: {id}");
            }

            return(vertex);
        }
Пример #3
0
 /// <summary>
 /// Read a vertex for a material from a binary stream.
 /// </summary>
 /// <param name="reader"></param>
 /// <param name="material"></param>
 /// <param name="stride"></param>
 /// <returns></returns>
 protected abstract SolidMeshVertex GetVertex(BinaryReader reader, SolidObjectMaterial material, int stride);
Пример #4
0
        protected override SolidMeshVertex GetVertex(BinaryReader reader, SolidObjectMaterial material, int stride)
        {
            World15Material wm     = (World15Material)material;
            SolidMeshVertex vertex = new SolidMeshVertex();

            InternalEffectID id = (InternalEffectID)wm.EffectId;

            switch (id)
            {
            case InternalEffectID.WorldShader:
            case InternalEffectID.GLASS_REFLECT:
            case InternalEffectID.WorldZBiasShader:
            case InternalEffectID.Tree:
            case InternalEffectID.WATER:
                vertex.Position  = BinaryUtil.ReadVector3(reader);
                vertex.Normal    = BinaryUtil.ReadNormal(reader, true);
                vertex.TexCoords = BinaryUtil.ReadVector2(reader);
                vertex.Color     = reader.ReadUInt32(); // daytime color
                reader.ReadUInt32();                    // nighttime color
                break;

            case InternalEffectID.WorldPrelitShader:
                vertex.Position = BinaryUtil.ReadVector3(reader);
                vertex.Color    = reader.ReadUInt32(); // daytime color
                reader.ReadUInt32();                   // nighttime color
                vertex.TexCoords = BinaryUtil.ReadVector2(reader);
                break;

            case InternalEffectID.WorldZBiasPrelitShader:
                vertex.Position = BinaryUtil.ReadVector3(reader);
                vertex.Normal   = BinaryUtil.ReadNormal(reader, true);
                vertex.Color    = reader.ReadUInt32(); // daytime color
                reader.ReadUInt32();                   // nighttime color
                vertex.TexCoords = BinaryUtil.ReadVector2(reader);
                break;

            case InternalEffectID.WorldNormalMap:
            case InternalEffectID.GLASS_REFLECTNM:
            case InternalEffectID.WorldRoadShader:
            case InternalEffectID.WorldFEShader:
                vertex.Position  = BinaryUtil.ReadVector3(reader);
                vertex.Normal    = BinaryUtil.ReadNormal(reader, true);
                vertex.TexCoords = BinaryUtil.ReadVector2(reader);
                vertex.Color     = reader.ReadUInt32(); // daytime color
                reader.ReadUInt32();                    // nighttime color
                vertex.Tangent = BinaryUtil.ReadNormal(reader, true);
                break;

            case InternalEffectID.CarShader:
            case InternalEffectID.CARNORMALMAP:
                vertex.Position  = BinaryUtil.ReadNormal(reader, true) * 8;
                vertex.TexCoords = new Vector2(reader.ReadInt16() / 4096f, reader.ReadInt16() / 4096f - 1);
                vertex.Color     = reader.ReadUInt32();
                vertex.Normal    = BinaryUtil.ReadNormal(reader, true);
                vertex.Tangent   = BinaryUtil.ReadNormal(reader, true);
                break;

            default:
                throw new Exception($"Unsupported effect in object {Name}: {id}");
            }

            return(vertex);
        }
Пример #5
0
        /// <inheritdoc />
        /// <summary>
        /// This thing is responsible for somehow deriving proper vertex data from
        /// a NFS:Undercover vertex buffer. Getting the coordinates is easy, but
        /// the hard part is getting the texture coordinates. Can it be done? Who knnows?
        /// </summary>
        /// <remarks>And I didn't even mention the fact that there are wayyyy too many edge cases...</remarks>
        /// <remarks>I hate this game. Worse than E.T.</remarks>
        /// <param name="reader"></param>
        /// <param name="material"></param>
        /// <param name="stride"></param>
        /// <returns></returns>
        protected override SolidMeshVertex GetVertex(BinaryReader reader, SolidObjectMaterial material, int stride)
        {
            var             effectId = ((UndercoverMaterial)material).EffectId;
            SolidMeshVertex vertex   = new SolidMeshVertex();

            switch (effectId)
            {
            case EffectID.mw2_constant:
            case EffectID.mw2_constant_alpha_bias:
            case EffectID.mw2_illuminated:
            case EffectID.mw2_pano:
                vertex.Position = BinaryUtil.ReadVector3(reader);
                reader.ReadSingle();
                vertex.TexCoords = BinaryUtil.ReadShort2N(reader) * 32;
                break;

            case EffectID.mw2_matte:
            case EffectID.mw2_diffuse_spec:
            case EffectID.mw2_branches:
            case EffectID.mw2_glass_no_n:
            case EffectID.mw2_diffuse_spec_illum:
            case EffectID.diffuse_spec_2sided:
            case EffectID.mw2_combo_refl:
            case EffectID.mw2_dirt:
            case EffectID.mw2_grass:
            case EffectID.mw2_tunnel_illum:
            case EffectID.mw2_diffuse_spec_alpha:
            case EffectID.mw2_trunk:
                vertex.Position = BinaryUtil.ReadVector3(reader);
                reader.ReadSingle();
                vertex.Color     = reader.ReadUInt32();
                vertex.TexCoords = BinaryUtil.ReadShort2N(reader) * 32;
                vertex.Normal    = BinaryUtil.ReadNormal(reader, true);
                break;

            case EffectID.mw2_normalmap:
            case EffectID.mw2_normalmap_bias:
            case EffectID.mw2_glass_refl:
            case EffectID.normalmap2sided:
            case EffectID.mw2_road_overlay:
            case EffectID.mw2_road_refl_overlay:
            case EffectID.mw2_rock:
                vertex.Position = BinaryUtil.ReadVector3(reader);
                reader.ReadSingle();
                vertex.Color     = reader.ReadUInt32();
                vertex.TexCoords = BinaryUtil.ReadShort2N(reader) * 32;
                vertex.Normal    = BinaryUtil.ReadNormal(reader, true);
                // todo: read packed tangent vector
                reader.BaseStream.Position += 0x8;
                break;

            case EffectID.mw2_grass_rock:
            case EffectID.mw2_road_refl:
            case EffectID.mw2_road_refl_tile:
            case EffectID.mw2_road_tile:
            case EffectID.mw2_dirt_rock:
                vertex.Position = BinaryUtil.ReadVector3(reader);
                reader.ReadSingle();
                vertex.Color     = reader.ReadUInt32();
                vertex.TexCoords = BinaryUtil.ReadShort2N(reader) * 32;
                // TODO: TEXCOORD1??? what do we do with this?
                reader.ReadInt16();
                reader.ReadInt16();
                vertex.Normal = BinaryUtil.ReadNormal(reader, true);
                // todo: read packed tangent vector
                reader.BaseStream.Position += 0x8;
                break;

            case EffectID.mw2_tunnel_road:
                vertex.Position = BinaryUtil.ReadVector3(reader);
                reader.ReadSingle();
                vertex.Color     = reader.ReadUInt32();
                vertex.TexCoords = BinaryUtil.ReadShort2N(reader) * 32;
                // TODO: TEXCOORD1??? what do we do with this?
                reader.ReadInt16();
                reader.ReadInt16();
                // TODO: TEXCOORD2??? what do we do with this?
                reader.ReadInt16();
                reader.ReadInt16();
                vertex.Normal = BinaryUtil.ReadNormal(reader, true);
                // todo: read packed tangent vector
                reader.BaseStream.Position += 0x8;
                break;

            case EffectID.mw2_road_refl_lite:
            case EffectID.mw2_road_lite:
            case EffectID.mw2_grass_dirt:
                vertex.Position = BinaryUtil.ReadVector3(reader);
                reader.ReadSingle();
                vertex.Color     = reader.ReadUInt32();
                vertex.TexCoords = BinaryUtil.ReadShort2N(reader) * 32;
                // TODO: TEXCOORD1??? what do we do with this?
                reader.ReadInt16();
                reader.ReadInt16();
                vertex.Normal = BinaryUtil.ReadNormal(reader, true);
                break;

            case EffectID.mw2_tunnel_wall:
                vertex.Position = BinaryUtil.ReadVector3(reader);
                reader.ReadSingle();
                vertex.Color     = reader.ReadUInt32();
                vertex.TexCoords = BinaryUtil.ReadShort2N(reader) * 32;
                // TODO: TEXCOORD1??? what do we do with this?
                reader.ReadInt16();
                reader.ReadInt16();
                break;

            case EffectID.mw2_matte_alpha:
            case EffectID.mw2_dif_spec_a_bias:
            case EffectID.mw2_dirt_overlay:
                vertex.Position = BinaryUtil.ReadVector3(reader);
                reader.ReadSingle();
                vertex.Color     = reader.ReadUInt32();
                vertex.TexCoords = BinaryUtil.ReadShort2N(reader) * 32;
                vertex.Normal    = BinaryUtil.ReadNormal(reader, true);
                break;

            case EffectID.mw2_foliage:
            case EffectID.mw2_foliage_lod:
            case EffectID.mw2_scrub:
            case EffectID.mw2_scrub_lod:
            case EffectID.mw2_ocean:
                vertex.Position = BinaryUtil.ReadVector3(reader);
                reader.ReadSingle();
                vertex.Color     = reader.ReadUInt32();
                vertex.TexCoords = BinaryUtil.ReadShort2N(reader) * 32;
                break;

            case EffectID.mw2_sky:
                vertex.Position = BinaryUtil.ReadVector3(reader);
                reader.ReadSingle();
                vertex.TexCoords = BinaryUtil.ReadVector2(reader);
                break;

            case EffectID.mw2_texture_scroll:
            case EffectID.mw2_car_heaven_default:
                vertex.Position = BinaryUtil.ReadVector3(reader);
                reader.ReadSingle();
                // TODO: COLOR0 is a float4. how do we deal with that?
                reader.BaseStream.Position += 0x10;
                vertex.TexCoords            = BinaryUtil.ReadVector2(reader);
                break;

            case EffectID.mw2_car_heaven:
                vertex.Position = BinaryUtil.ReadVector3(reader);
                reader.ReadSingle();
                // TODO: COLOR0 is a float4. how do we deal with that?
                reader.BaseStream.Position += 0x10;
                vertex.TexCoords            = BinaryUtil.ReadVector2(reader);
                vertex.Normal = BinaryUtil.ReadNormal(reader, true);
                break;

            case EffectID.mw2_carhvn_floor:
            case EffectID.mw2_road:
                vertex.Position = BinaryUtil.ReadVector3(reader);
                reader.ReadSingle();
                vertex.Color     = reader.ReadUInt32();
                vertex.TexCoords = BinaryUtil.ReadShort2N(reader) * 32;
                // TODO: TEXCOORD1??? what do we do with this?
                reader.ReadInt16();
                reader.ReadInt16();
                vertex.Normal = BinaryUtil.ReadNormal(reader, true);
                // todo: read packed tangent vector
                reader.BaseStream.Position += 0x8;
                break;

            case EffectID.car:
            case EffectID.car_a:
            case EffectID.car_a_nzw:
            case EffectID.car_nm:
            case EffectID.car_nm_a:
            case EffectID.car_nm_v_s:
            case EffectID.car_nm_v_s_a:
            case EffectID.car_si:
            case EffectID.car_si_a:
            case EffectID.car_t:
            case EffectID.car_t_a:
            case EffectID.car_t_nm:
            case EffectID.car_v:
                vertex.Position  = BinaryUtil.ReadNormal(reader, true) * 10;
                vertex.TexCoords = BinaryUtil.ReadShort2N(reader) * 32;
                vertex.Color     = reader.ReadUInt32();
                vertex.Normal    = BinaryUtil.ReadNormal(reader, true);
                vertex.Tangent   = BinaryUtil.ReadNormal(reader, true);
                break;

            default:
                throw new Exception($"Unsupported effect: {effectId}");
            }

            return(vertex);
        }
Пример #6
0
        protected override SolidMeshVertex GetVertex(BinaryReader reader, SolidObjectMaterial material, int stride)
        {
            ProStreetMaterial psm    = (ProStreetMaterial)material;
            SolidMeshVertex   vertex = new SolidMeshVertex();

            switch ((EffectID)psm.EffectId)
            {
            case EffectID.WORLDBAKEDLIGHTING:
                vertex.Position             = BinaryUtil.ReadVector3(reader);
                vertex.Color                = reader.ReadUInt32();
                vertex.TexCoords            = BinaryUtil.ReadVector2(reader);
                reader.BaseStream.Position += 16;
                vertex.Normal               = BinaryUtil.ReadNormal(reader, true);
                break;

            case EffectID.WORLD:
            case EffectID.SKY:
                vertex.Position             = BinaryUtil.ReadVector3(reader);
                vertex.Normal               = BinaryUtil.ReadNormal(reader);
                vertex.Color                = reader.ReadUInt32();
                vertex.TexCoords            = BinaryUtil.ReadVector2(reader);
                reader.BaseStream.Position += 8;     // TODO: what is this second D3DDECLUSAGE_TEXCOORD element?
                break;

            case EffectID.WORLDNORMALMAP:
                vertex.Position             = BinaryUtil.ReadVector3(reader);
                vertex.Normal               = BinaryUtil.ReadNormal(reader);
                vertex.Color                = reader.ReadUInt32();
                vertex.TexCoords            = BinaryUtil.ReadVector2(reader);
                reader.BaseStream.Position += 8;     // TODO: what is this second D3DDECLUSAGE_TEXCOORD element?
                // TODO: read tangent
                reader.BaseStream.Position += 16;
                reader.BaseStream.Position +=
                    8;     // TODO: what are these other D3DDECLUSAGE_TEXCOORD elements? (2x D3DDECLTYPE_UBYTE4)
                break;

            case EffectID.WorldDepthShader:
                vertex.Position  = BinaryUtil.ReadVector3(reader);
                vertex.Normal    = BinaryUtil.ReadNormal(reader);
                vertex.Color     = reader.ReadUInt32();
                vertex.TexCoords = BinaryUtil.ReadVector2(reader);
                break;

            case EffectID.TREELEAVES:
                vertex.Position = BinaryUtil.ReadVector3(reader);
                vertex.Color    = reader.ReadUInt32();
                vertex.Normal   = BinaryUtil.ReadNormal(reader);
                // TODO: COLLADA supports tangent vectors, so we should eventually read them
                //> elements[3]: type=D3DDECLTYPE_FLOAT4 usage=D3DDECLUSAGE_TANGENT size=16 offset=0x1c
                reader.BaseStream.Position += 0x10;
                vertex.TexCoords            = BinaryUtil.ReadVector2(reader);
                break;

            case EffectID.WORLDCONSTANT:
                vertex.Position  = BinaryUtil.ReadVector3(reader);
                vertex.TexCoords = BinaryUtil.ReadVector2(reader);
                vertex.Color     = reader.ReadUInt32();
                break;

            case EffectID.ROAD:
                vertex.Position             = BinaryUtil.ReadVector3(reader);
                vertex.TexCoords            = BinaryUtil.ReadVector2(reader);
                reader.BaseStream.Position += 28;
                vertex.Color = reader.ReadUInt32();
                break;

            case EffectID.TERRAIN:
                vertex.Position             = BinaryUtil.ReadVector3(reader);
                vertex.TexCoords            = BinaryUtil.ReadVector2(reader);
                reader.BaseStream.Position += 16;
                vertex.Normal = BinaryUtil.ReadNormal(reader, true);
                // TODO: read packed tangent vector (4 short-components)
                reader.BaseStream.Position += 8;
                vertex.Color = reader.ReadUInt32();
                reader.BaseStream.Position +=
                    8;     // TODO: what are these other D3DDECLUSAGE_TEXCOORD elements? (2x D3DDECLTYPE_UBYTE4)
                break;

            case EffectID.GRASSTERRAIN:
                vertex.Position             = BinaryUtil.ReadVector3(reader);
                vertex.TexCoords            = BinaryUtil.ReadVector2(reader);
                reader.BaseStream.Position += 20;
                vertex.Normal = BinaryUtil.ReadNormal(reader, true);
                // TODO: read packed tangent vector (4 short-components)
                reader.BaseStream.Position += 8;
                vertex.Color = reader.ReadUInt32();
                break;

            case EffectID.FLAG:
                vertex.Position             = BinaryUtil.ReadVector3(reader);
                vertex.Color                = reader.ReadUInt32();
                vertex.Normal               = BinaryUtil.ReadNormal(reader, true);
                vertex.TexCoords            = BinaryUtil.ReadVector2(reader);
                reader.BaseStream.Position += 8;     // TODO: what is this second D3DDECLUSAGE_TEXCOORD element?
                break;

            case EffectID.GRASSCARD:
                vertex.Position = BinaryUtil.ReadVector3(reader);
                vertex.Color    = reader.ReadUInt32();
                vertex.Normal   = BinaryUtil.ReadNormal(reader, true);
                // TODO: read packed tangent vector (4 short-components)
                reader.BaseStream.Position += 8;
                vertex.TexCoords            = BinaryUtil.ReadVector2(reader);
                reader.BaseStream.Position += 8;     // TODO: what is this second D3DDECLUSAGE_TEXCOORD element?
                break;

            case EffectID.CAR:
            case EffectID.CARNORMALMAP:
            case EffectID.CARVINYL:
                vertex.Position  = BinaryUtil.ReadNormal(reader, true);
                vertex.TexCoords = BinaryUtil.ReadShort2N(reader);
                vertex.Color     = reader.ReadUInt32();
                vertex.Normal    = BinaryUtil.ReadNormal(reader, true);
                vertex.Tangent   = BinaryUtil.ReadNormal(reader, true);
                break;

            case EffectID.ALWAYSFACING:
                vertex.Position = BinaryUtil.ReadVector3(reader);
                vertex.Color    = reader.ReadUInt32();
                vertex.Normal   = BinaryUtil.ReadNormal(reader, true);
                // TODO: read packed tangent vector (4 short-components)
                reader.BaseStream.Position += 8;
                vertex.TexCoords            = BinaryUtil.ReadVector2(reader);
                break;

            case EffectID.STANDARD:
                vertex.Position             = BinaryUtil.ReadVector3(reader);
                vertex.Color                = reader.ReadUInt32();
                vertex.TexCoords            = BinaryUtil.ReadVector2(reader);
                reader.BaseStream.Position += 8;     // todo: what's this?
                break;

            case EffectID.TUNNEL:
                vertex.Position             = BinaryUtil.ReadVector3(reader);
                vertex.TexCoords            = BinaryUtil.ReadVector2(reader);
                reader.BaseStream.Position += 8;     // todo: what's this?
                reader.BaseStream.Position += 4;     // todo: what's this?
                reader.BaseStream.Position += 4;     // todo: what's this?
                vertex.Color  = reader.ReadUInt32();
                vertex.Normal = BinaryUtil.ReadNormal(reader, true);
                break;

            case EffectID.ROADLIGHTMAP:
                vertex.Position             = BinaryUtil.ReadVector3(reader);
                vertex.TexCoords            = BinaryUtil.ReadVector2(reader);
                reader.BaseStream.Position += 8;     // todo: what's this?
                reader.BaseStream.Position += 8;     // todo: what's this?
                reader.BaseStream.Position += 4;     // todo: what's this?
                vertex.Normal = BinaryUtil.ReadNormal(reader, true);
                vertex.Color  = reader.ReadUInt32();
                break;

            case EffectID.WATER:
                vertex.Position  = BinaryUtil.ReadVector3(reader);
                vertex.Color     = reader.ReadUInt32();
                vertex.TexCoords = BinaryUtil.ReadVector2(reader);
                break;

            case EffectID.WORLDBONE:
                vertex.Position     = BinaryUtil.ReadVector3(reader);
                vertex.Normal       = BinaryUtil.ReadNormal(reader);
                vertex.Color        = reader.ReadUInt32();
                vertex.TexCoords    = BinaryUtil.ReadVector2(reader);
                vertex.BlendWeight  = BinaryUtil.ReadVector3(reader);
                vertex.BlendIndices = BinaryUtil.ReadVector3(reader);
                vertex.Tangent      = BinaryUtil.ReadVector3(reader);
                break;

            default:
                throw new Exception($"Unsupported effect in object {Name}: {psm.EffectId}");
            }

            return(vertex);
        }