Ticket #1497: multicoord-final2.diff

File multicoord-final2.diff, 18.1 KB (added by myconid, 12 years ago)
  • source/collada/GeomReindex.cpp

    commit 37cc0ff3d7ad496f7e56c02762ad197026ae0fd5
    Author: myconid <christofi.cos@gmail.com>
    Date:   Thu Jun 21 09:43:50 2012 +0300
    
        Multi-texcoord support, so multiple UV sets can be loaded
    
    diff --git a/source/collada/GeomReindex.cpp b/source/collada/GeomReindex.cpp
    index ceca97e..d924a2a 100644
    a b  
    2121
    2222#include "FCollada.h"
    2323#include "FCDocument/FCDEntity.h"
     24#include "FCDocument/FCDGeometryMesh.h"
    2425#include "FCDocument/FCDGeometryPolygons.h"
    2526#include "FCDocument/FCDGeometryPolygonsInput.h"
    2627#include "FCDocument/FCDGeometrySource.h"
     
    3334
    3435struct VertexData
    3536{
    36     VertexData(const float* pos, const float* norm, const float* tex, const std::vector<FCDJointWeightPair>& weights)
     37    VertexData(const float* pos, const float* norm, const std::vector<float> &uvs, const std::vector<FCDJointWeightPair>& weights)
    3738        : x(pos[0]), y(pos[1]), z(pos[2]),
    3839        nx(norm[0]), ny(norm[1]), nz(norm[2]),
    39         u(tex[0]), v(tex[1]),
     40        uvs(uvs),
    4041        weights(weights)
    4142    {
    4243    }
    4344
    4445    float x, y, z;
    4546    float nx, ny, nz;
    46     float u, v;
     47    std::vector<float> uvs;
    4748    std::vector<FCDJointWeightPair> weights;
    4849};
    4950
    bool operator==(const VertexData& a, const VertexData& b)  
    7576{
    7677    return (similar(a.x,  b.x)  && similar(a.y,  b.y)  && similar(a.z,  b.z)
    7778         && similar(a.nx, b.nx) && similar(a.ny, b.ny) && similar(a.nz, b.nz)
    78          && similar(a.u,  b.u)  && similar(a.v,  b.v)
     79         && (a.uvs == b.uvs)
    7980         && (a.weights == b.weights));
    8081}
    8182
    bool operator<(const VertexData& a, const VertexData& b)  
    8485#define CMP(f) if (a.f < b.f) return true; if (a.f > b.f) return false
    8586    CMP(x);  CMP(y);  CMP(z);
    8687    CMP(nx); CMP(ny); CMP(nz);
    87     CMP(u);  CMP(v);
     88    CMP(uvs);
    8889    CMP(weights);
    8990#undef CMP
    9091    return false;
    void ReindexGeometry(FCDGeometryPolygons* polys, FCDSkinController* skin)  
    148149    assert(indicesNormal);
    149150    assert(indicesTexcoord); // TODO - should be optional, because textureless meshes aren't unreasonable
    150151
     152    FCDGeometrySourceList texcoordSources;
     153    polys->GetParent()->FindSourcesByType(FUDaeGeometryInput::TEXCOORD, texcoordSources);
     154
    151155    FCDGeometrySource* sourcePosition = inputPosition->GetSource();
    152156    FCDGeometrySource* sourceNormal   = inputNormal  ->GetSource();
    153     FCDGeometrySource* sourceTexcoord = inputTexcoord->GetSource();
    154157
    155158    const float* dataPosition = sourcePosition->GetData();
    156159    const float* dataNormal   = sourceNormal  ->GetData();
    157     const float* dataTexcoord = sourceTexcoord->GetData();
    158160
    159161    if (skin)
    160162    {
    void ReindexGeometry(FCDGeometryPolygons* polys, FCDSkinController* skin)  
    166168
    167169    uint32 stridePosition = sourcePosition->GetStride();
    168170    uint32 strideNormal   = sourceNormal  ->GetStride();
    169     uint32 strideTexcoord = sourceTexcoord->GetStride();
    170171
    171172    std::vector<uint32> indicesCombined;
    172173    std::vector<VertexData> vertexes;
    void ReindexGeometry(FCDGeometryPolygons* polys, FCDSkinController* skin)  
    188189            CanonicaliseWeights(weights);
    189190        }
    190191
     192        std::vector<float> uvs;
     193        for (size_t set = 0; set < texcoordSources.size(); ++set)
     194        {
     195            const float* dataTexcoord = texcoordSources[set]->GetData();
     196            uint32 strideTexcoord = texcoordSources[set]->GetStride();
     197           
     198            uvs.push_back(dataTexcoord[indicesTexcoord[i]*strideTexcoord]);
     199            uvs.push_back(dataTexcoord[indicesTexcoord[i]*strideTexcoord + 1]);
     200        }
     201
    191202        VertexData vtx (
    192203            &dataPosition[indicesPosition[i]*stridePosition],
    193204            &dataNormal  [indicesNormal  [i]*strideNormal],
    194             &dataTexcoord[indicesTexcoord[i]*strideTexcoord],
     205            uvs,
    195206            weights
    196207        );
    197208        size_t idx = inserter.add(vtx);
    void ReindexGeometry(FCDGeometryPolygons* polys, FCDSkinController* skin)  
    215226        newDataNormal  .push_back(vertexes[i].nx);
    216227        newDataNormal  .push_back(vertexes[i].ny);
    217228        newDataNormal  .push_back(vertexes[i].nz);
    218         newDataTexcoord.push_back(vertexes[i].u);
    219         newDataTexcoord.push_back(vertexes[i].v);
    220229        newWeightedMatches.push_back(vertexes[i].weights);
    221230    }
    222231
    void ReindexGeometry(FCDGeometryPolygons* polys, FCDSkinController* skin)  
    226235    inputNormal  ->SetIndices(&indicesCombined.front(), indicesCombined.size());
    227236    inputTexcoord->SetIndices(&indicesCombined.front(), indicesCombined.size());
    228237
     238    for (size_t set = 0; set < texcoordSources.size(); ++set)
     239    {
     240        newDataTexcoord.clear();
     241        for (size_t i = 0; i < vertexes.size(); ++i)
     242        {
     243            newDataTexcoord.push_back(vertexes[i].uvs[set * 2]);
     244            newDataTexcoord.push_back(vertexes[i].uvs[set * 2 + 1]);
     245        }
     246        texcoordSources[set]->SetData(newDataTexcoord, 2);
     247    }
     248
    229249    sourcePosition->SetData(newDataPosition, 3);
    230250    sourceNormal  ->SetData(newDataNormal,   3);
    231     sourceTexcoord->SetData(newDataTexcoord, 2);
    232251
    233252    if (skin)
    234253    {
  • source/collada/PMDConvert.cpp

    diff --git a/source/collada/PMDConvert.cpp b/source/collada/PMDConvert.cpp
    index 5cbcd88..a3b31b7 100644
    a b public:  
    149149
    150150            FCDGeometryPolygonsInput* inputPosition = polys->FindInput(FUDaeGeometryInput::POSITION);
    151151            FCDGeometryPolygonsInput* inputNormal   = polys->FindInput(FUDaeGeometryInput::NORMAL);
    152             FCDGeometryPolygonsInput* inputTexcoord = polys->FindInput(FUDaeGeometryInput::TEXCOORD);
    153152
    154153            const uint32* indicesCombined = inputPosition->GetIndices();
    155154            size_t indicesCombinedCount = inputPosition->GetIndexCount();
    public:  
    157156
    158157            FCDGeometrySource* sourcePosition = inputPosition->GetSource();
    159158            FCDGeometrySource* sourceNormal   = inputNormal  ->GetSource();
    160             FCDGeometrySource* sourceTexcoord = inputTexcoord->GetSource();
     159           
     160            FCDGeometrySourceList texcoordSources;
     161            polys->GetParent()->FindSourcesByType(FUDaeGeometryInput::TEXCOORD, texcoordSources);
     162           
     163            std::vector<float*> dataTexcoords;
     164            for (size_t i = 0; i < texcoordSources.size(); ++i)
     165            {
     166                dataTexcoords.push_back(texcoordSources[i]->GetData());
     167                assert(texcoordSources[i]->GetDataCount() == vertexCount*2);
     168            }
    161169
    162170            float* dataPosition = sourcePosition->GetData();
    163171            float* dataNormal   = sourceNormal  ->GetData();
    164             float* dataTexcoord = sourceTexcoord->GetData();
    165172            size_t vertexCount = sourcePosition->GetDataCount() / 3;
    166173            assert(sourcePosition->GetDataCount() == vertexCount*3);
    167174            assert(sourceNormal  ->GetDataCount() == vertexCount*3);
    168             assert(sourceTexcoord->GetDataCount() == vertexCount*2);
    169175
    170176            // Transform mesh coordinate system to game coordinates
    171177            // (doesn't modify prop points)
    public:  
    190196
    191197            AddStaticPropPoints(propPoints, upAxisTransform, converter.GetInstance().GetParent());
    192198
    193             WritePMD(output, indicesCombined, indicesCombinedCount, dataPosition, dataNormal, dataTexcoord, vertexCount, boneWeights, boneTransforms, propPoints);
     199            WritePMD(output, indicesCombined, indicesCombinedCount, dataPosition, dataNormal, dataTexcoords, vertexCount, boneWeights, boneTransforms, propPoints);
    194200        }
    195201        else if (converter.GetInstance().GetType() == FCDEntityInstance::CONTROLLER)
    196202        {
    public:  
    417423
    418424            FCDGeometryPolygonsInput* inputPosition = polys->FindInput(FUDaeGeometryInput::POSITION);
    419425            FCDGeometryPolygonsInput* inputNormal   = polys->FindInput(FUDaeGeometryInput::NORMAL);
    420             FCDGeometryPolygonsInput* inputTexcoord = polys->FindInput(FUDaeGeometryInput::TEXCOORD);
    421 
    422426
    423427            const uint32* indicesCombined = inputPosition->GetIndices();
    424428            size_t indicesCombinedCount = inputPosition->GetIndexCount();
    public:  
    426430
    427431            FCDGeometrySource* sourcePosition = inputPosition->GetSource();
    428432            FCDGeometrySource* sourceNormal   = inputNormal  ->GetSource();
    429             FCDGeometrySource* sourceTexcoord = inputTexcoord->GetSource();
     433
     434            FCDGeometrySourceList texcoordSources;
     435            polys->GetParent()->FindSourcesByType(FUDaeGeometryInput::TEXCOORD, texcoordSources);
     436           
     437            std::vector<float*> dataTexcoords;
     438            for (size_t i = 0; i < texcoordSources.size(); ++i)
     439            {
     440                dataTexcoords.push_back(texcoordSources[i]->GetData());
     441                assert(texcoordSources[i]->GetDataCount() == vertexCount*2);
     442            }
    430443
    431444            float* dataPosition = sourcePosition->GetData();
    432445            float* dataNormal   = sourceNormal  ->GetData();
    433             float* dataTexcoord = sourceTexcoord->GetData();
    434446            size_t vertexCount = sourcePosition->GetDataCount() / 3;
    435447            assert(sourcePosition->GetDataCount() == vertexCount*3);
    436448            assert(sourceNormal  ->GetDataCount() == vertexCount*3);
    437             assert(sourceTexcoord->GetDataCount() == vertexCount*2);
    438449
    439450            // Transform model coordinate system to game coordinates
    440451
    public:  
    442453                converter.GetEntityTransform(), skin->GetBindShapeTransform(),
    443454                converter.IsYUp(), converter.IsXSI());
    444455
    445             WritePMD(output, indicesCombined, indicesCombinedCount, dataPosition, dataNormal, dataTexcoord, vertexCount, boneWeights, boneTransforms, propPoints);
     456            WritePMD(output, indicesCombined, indicesCombinedCount, dataPosition, dataNormal, dataTexcoords, vertexCount, boneWeights, boneTransforms, propPoints);
    446457        }
    447458        else
    448459        {
    public:  
    470481     */
    471482    static void WritePMD(OutputCB& output,
    472483        const uint32* indices, size_t indexCount,
    473         const float* position, const float* normal, const float* texcoord, size_t vertexCount,
     484        const float* position, const float* normal,
     485        const std::vector<float*>& texcoords,
     486        size_t vertexCount,
    474487        const std::vector<VertexBlend>& boneWeights, const std::vector<BoneTransform>& boneTransforms,
    475488        const std::vector<PropPoint>& propPoints)
    476489    {
    public:  
    489502        }
    490503
    491504        output("PSMD", 4);  // magic number
    492         write(output, (uint32)3); // version number
     505        write(output, (uint32)4); // version number
    493506        write(output, (uint32)(
    494             4 + 13*4*vertexCount + // vertices
     507            4 + 11*4*vertexCount + 4 + 8*texcoords.size()*vertexCount + // vertices
    495508            4 + 6*faceCount + // faces
    496509            4 + 7*4*boneCount + // bones
    497510            4 + propPointsSize // props
    public:  
    499512
    500513        // Vertex data
    501514        write<uint32>(output, (uint32)vertexCount);
     515        write<uint32>(output, (uint32)texcoords.size()); // UV pairs per vertex
    502516        for (size_t i = 0; i < vertexCount; ++i)
    503517        {
    504518            output((char*)&position[i*3], 12);
    505519            output((char*)&normal  [i*3], 12);
    506             output((char*)&texcoord[i*2],  8);
     520
     521            for (size_t s = 0; s < texcoords.size(); ++s)
     522            {
     523                output((char*)&texcoords[s][i*2], 8);
     524            }
     525
    507526            if (boneCount)
    508527                write(output, boneWeights[i]);
    509528            else
  • source/graphics/ModelDef.cpp

    diff --git a/source/graphics/ModelDef.cpp b/source/graphics/ModelDef.cpp
    index d328d49..e6c0923 100644
    a b void CModelDef::BlendBoneMatrices(  
    226226
    227227// CModelDef Constructor
    228228CModelDef::CModelDef() :
    229     m_NumVertices(0), m_pVertices(0), m_NumFaces(0), m_pFaces(0),
     229    m_NumVertices(0), m_NumUVsPerVertex(0), m_pVertices(0), m_NumFaces(0), m_pFaces(0),
    230230    m_NumBones(0), m_Bones(0), m_InverseBindBoneMatrices(NULL),
    231231    m_NumBlends(0), m_pBlends(0), m_pBlendIndices(0),
    232232    m_Name(L"[not loaded]")
    CModelDef* CModelDef::Load(const VfsPath& filename, const VfsPath& name)  
    275275
    276276    // now unpack everything
    277277    mdef->m_NumVertices = unpacker.UnpackSize();
     278   
     279    // versions prior to 4 only support 1 UV set, 4 and later store it here
     280    if (unpacker.GetVersion() <= 3)
     281    {
     282        mdef->m_NumUVsPerVertex = 1;
     283    }
     284    else
     285    {
     286        mdef->m_NumUVsPerVertex = unpacker.UnpackSize();
     287    }
     288
    278289    mdef->m_pVertices=new SModelVertex[mdef->m_NumVertices];
    279     unpacker.UnpackRaw(mdef->m_pVertices,sizeof(SModelVertex)*mdef->m_NumVertices);
     290   
     291    for (size_t i = 0; i < mdef->m_NumVertices; ++i)
     292    {
     293        unpacker.UnpackRaw(&mdef->m_pVertices[i].m_Coords, 12);
     294        unpacker.UnpackRaw(&mdef->m_pVertices[i].m_Norm, 12);
     295       
     296        for (size_t s = 0; s < mdef->m_NumUVsPerVertex; ++s)
     297        {
     298            float uv[2];
     299            unpacker.UnpackRaw(&uv[0], 8);
     300            mdef->m_pVertices[i].m_UVs.push_back(uv[0]);
     301            mdef->m_pVertices[i].m_UVs.push_back(uv[1]);
     302        }
     303       
     304        unpacker.UnpackRaw(&mdef->m_pVertices[i].m_Blend, sizeof(SVertexBlend));
     305    }
    280306   
    281307    mdef->m_NumFaces = unpacker.UnpackSize();
    282308    mdef->m_pFaces=new SModelFace[mdef->m_NumFaces];
  • source/graphics/ModelDef.h

    diff --git a/source/graphics/ModelDef.h b/source/graphics/ModelDef.h
    index 7f67301..ea5f344 100644
    a b  
    2323#define INCLUDED_MODELDEF
    2424
    2525#include "ps/CStr.h"
     26#include "maths/Vector2D.h"
    2627#include "maths/Vector3D.h"
    2728#include "maths/Quaternion.h"
    2829#include "lib/file/vfs/vfs_path.h"
    struct SModelVertex  
    104105    // vertex normal
    105106    CVector3D m_Norm;
    106107    // vertex UVs
    107     float m_U, m_V;
     108    std::vector<float> m_UVs;
    108109    // vertex blend data
    109110    SVertexBlend m_Blend;
    110111};
    public:  
    164165    // accessor: get vertex data
    165166    size_t GetNumVertices() const { return m_NumVertices; }
    166167    SModelVertex* GetVertices() const { return m_pVertices; }
     168   
     169    // accessor: get number of UV sets
     170    size_t GetNumUVsPerVertex() const { return m_NumUVsPerVertex; }
    167171
    168172    // accessor: get face data
    169173    size_t GetNumFaces() const { return m_NumFaces; }
    public:  
    256260    // vertex data
    257261    size_t m_NumVertices;
    258262    SModelVertex* m_pVertices;
     263    size_t m_NumUVsPerVertex; // number of UV pairs per vertex
    259264    // face data
    260265    size_t m_NumFaces;
    261266    SModelFace* m_pFaces;
  • source/renderer/HWLightingModelRenderer.cpp

    diff --git a/source/renderer/HWLightingModelRenderer.cpp b/source/renderer/HWLightingModelRenderer.cpp
    index c1fc61d..083a71a 100644
    a b ShaderModelDef::ShaderModelDef(const CModelDefPtr& mdef)  
    6262
    6363    VertexArrayIterator<float[2]> UVit = m_UV.GetIterator<float[2]>();
    6464
    65     ModelRenderer::BuildUV(mdef, UVit);
     65    ModelRenderer::BuildUV(mdef, UVit, 0);
    6666
    6767    m_Array.Upload();
    6868    m_Array.FreeBackingStore();
    void ShaderModelVertexRenderer::UpdateModelData(CModel* model, CModelRData* data  
    232232void ShaderModelVertexRenderer::BeginPass(int streamflags)
    233233{
    234234    if (m->cpuLighting)
    235         ENSURE(streamflags == (streamflags & (STREAM_POS | STREAM_UV0 | STREAM_COLOR)));
     235        ENSURE(streamflags == (streamflags & (STREAM_POS | STREAM_UV0 | STREAM_UV1 | STREAM_COLOR)));
    236236    else
    237         ENSURE(streamflags == (streamflags & (STREAM_POS | STREAM_UV0 | STREAM_NORMAL)));
     237        ENSURE(streamflags == (streamflags & (STREAM_POS | STREAM_UV0 | STREAM_UV1 | STREAM_NORMAL)));
    238238}
    239239
    240240// Cleanup one rendering pass
  • source/renderer/InstancingModelRenderer.cpp

    diff --git a/source/renderer/InstancingModelRenderer.cpp b/source/renderer/InstancingModelRenderer.cpp
    index 9932731..4d8b500 100644
    a b struct IModelDef : public CModelDefRPrivate  
    4646    /// Static per-CModel vertex array
    4747    VertexArray m_Array;
    4848
    49     /// Position, normals and UV are all static
     49    /// Position and normals are static
    5050    VertexArray::Attribute m_Position;
    5151    VertexArray::Attribute m_Normal;
    52     VertexArray::Attribute m_UV;
    5352    VertexArray::Attribute m_BlendJoints; // valid iff gpuSkinning == true
    5453    VertexArray::Attribute m_BlendWeights; // valid iff gpuSkinning == true
    5554
     55    /// The number of UVs is determined by the model
     56    VertexArray::Attribute m_UVs[5];
     57
    5658    /// Indices are the same for all models, so share them
    5759    VertexIndexArray m_IndexArray;
    5860
    IModelDef::IModelDef(const CModelDefPtr& mdef, bool gpuSkinning)  
    7375    m_Normal.elems = 3;
    7476    m_Array.AddAttribute(&m_Normal);
    7577
    76     m_UV.type = GL_FLOAT;
    77     m_UV.elems = 2;
    78     m_Array.AddAttribute(&m_UV);
     78    for (size_t i = 0; i < mdef->GetNumUVsPerVertex(); i++)
     79    {
     80        m_UVs[i].type = GL_FLOAT;
     81        m_UVs[i].elems = 2;
     82        m_Array.AddAttribute(&m_UVs[i]);
     83    }
    7984
    8085    if (gpuSkinning)
    8186    {
    IModelDef::IModelDef(const CModelDefPtr& mdef, bool gpuSkinning)  
    9398
    9499    VertexArrayIterator<CVector3D> Position = m_Position.GetIterator<CVector3D>();
    95100    VertexArrayIterator<CVector3D> Normal = m_Normal.GetIterator<CVector3D>();
    96     VertexArrayIterator<float[2]> UVit = m_UV.GetIterator<float[2]>();
    97101
    98102    ModelRenderer::CopyPositionAndNormals(mdef, Position, Normal);
    99     ModelRenderer::BuildUV(mdef, UVit);
     103
     104    for (size_t i = 0; i < mdef->GetNumUVsPerVertex(); i++)
     105    {
     106        VertexArrayIterator<float[2]> UVit = m_UVs[i].GetIterator<float[2]>();
     107        ModelRenderer::BuildUV(mdef, UVit, i);
     108    }
    100109
    101110    if (gpuSkinning)
    102111    {
    void InstancingModelRenderer::UpdateModelData(CModel* UNUSED(model), CModelRData  
    180189// Setup one rendering pass.
    181190void InstancingModelRenderer::BeginPass(int streamflags)
    182191{
    183     ENSURE(streamflags == (streamflags & (STREAM_POS|STREAM_NORMAL|STREAM_UV0)));
     192    ENSURE(streamflags == (streamflags & (STREAM_POS|STREAM_NORMAL|STREAM_UV0|STREAM_UV1)));
    184193}
    185194
    186195// Cleanup rendering pass.
    void InstancingModelRenderer::PrepareModelDef(const CShaderProgramPtr& shader, i  
    209218        shader->NormalPointer(GL_FLOAT, stride, base + m->imodeldef->m_Normal.offset);
    210219
    211220    if (streamflags & STREAM_UV0)
    212         shader->TexCoordPointer(GL_TEXTURE0, 2, GL_FLOAT, stride, base + m->imodeldef->m_UV.offset);
     221        shader->TexCoordPointer(GL_TEXTURE0, 2, GL_FLOAT, stride, base + m->imodeldef->m_UVs[0].offset);
     222   
     223    if ((streamflags & STREAM_UV1) && def.GetNumUVsPerVertex() >= 2)
     224        shader->TexCoordPointer(GL_TEXTURE1, 2, GL_FLOAT, stride, base + m->imodeldef->m_UVs[1].offset);
    213225
    214226    // GPU skinning requires extra attributes to compute positions/normals
    215227    if (m->gpuSkinning)
  • source/renderer/ModelRenderer.cpp

    diff --git a/source/renderer/ModelRenderer.cpp b/source/renderer/ModelRenderer.cpp
    index b020071..65a2baa 100644
    a b void ModelRenderer::BuildColor4ub(  
    148148// Copy UV coordinates
    149149void ModelRenderer::BuildUV(
    150150        const CModelDefPtr& mdef,
    151         const VertexArrayIterator<float[2]>& UV)
     151        const VertexArrayIterator<float[2]>& UV,
     152        int UVset)
    152153{
    153154    size_t numVertices = mdef->GetNumVertices();
    154155    SModelVertex* vertices = mdef->GetVertices();
    155156
    156157    for (size_t j=0; j < numVertices; ++j)
    157158    {
    158         UV[j][0] = vertices[j].m_U;
    159         UV[j][1] = 1.0-vertices[j].m_V;
     159        UV[j][0] = vertices[j].m_UVs[UVset * 2];
     160        UV[j][1] = 1.0-vertices[j].m_UVs[UVset * 2 + 1];
    160161    }
    161162}
    162163
  • source/renderer/ModelRenderer.h

    diff --git a/source/renderer/ModelRenderer.h b/source/renderer/ModelRenderer.h
    index e27a0c6..7019524 100644
    a b public:  
    241241     */
    242242    static void BuildUV(
    243243            const CModelDefPtr& mdef,
    244             const VertexArrayIterator<float[2]>& UV);
     244            const VertexArrayIterator<float[2]>& UV,
     245            int UVset);
    245246
    246247    /**
    247248     * BuildIndices: Create the indices array for the given CModelDef.