187 lines · 6.7 KB · C++
RawDownload
////  Created by Bradley Austin Davis on 2016/05/16//  Copyright 2014 High Fidelity, Inc.////  Distributed under the Apache License, Version 2.0.//  See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html// #include "TestFbx.h" #include <glm/gtc/matrix_transform.hpp> #include <QtCore/QFile> #include <FBXSerializer.h> struct MyVertex {    vec3 position;    vec2 texCoords;    vec3 normal;    uint32_t color;     static gpu::Stream::FormatPointer getVertexFormat() {        static const gpu::Element POSITION_ELEMENT { gpu::VEC3, gpu::FLOAT, gpu::XYZ };        static const gpu::Element TEXTURE_ELEMENT { gpu::VEC2, gpu::FLOAT, gpu::UV };        static const gpu::Element NORMAL_ELEMENT { gpu::VEC3, gpu::FLOAT, gpu::XYZ };        static const gpu::Element COLOR_ELEMENT { gpu::VEC4, gpu::NUINT8, gpu::RGBA };        gpu::Stream::FormatPointer vertexFormat { std::make_shared<gpu::Stream::Format>() };        vertexFormat->setAttribute(gpu::Stream::POSITION, 0, POSITION_ELEMENT, offsetof(MyVertex, position));        vertexFormat->setAttribute(gpu::Stream::TEXCOORD, 0, TEXTURE_ELEMENT, offsetof(MyVertex, texCoords));        vertexFormat->setAttribute(gpu::Stream::COLOR, 0, COLOR_ELEMENT, offsetof(MyVertex, color));        vertexFormat->setAttribute(gpu::Stream::NORMAL, 0, NORMAL_ELEMENT, offsetof(MyVertex, normal));        return vertexFormat;    } }; struct Part {    size_t baseVertex;    size_t baseIndex;    size_t materialId;}; struct DrawElementsIndirectCommand {    uint  count { 0 };    uint  instanceCount { 1 };    uint  firstIndex { 0 };    uint  baseVertex { 0 };    uint  baseInstance { 0 };};  class FileDownloader : public QObject {    Q_OBJECTpublic:    explicit FileDownloader(QUrl imageUrl, QObject *parent = 0) : QObject(parent) {        connect(&m_WebCtrl, SIGNAL(finished(QNetworkReply*)), this, SLOT(fileDownloaded(QNetworkReply*)));        QNetworkRequest request(imageUrl);        request.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);        m_WebCtrl.get(request);    }     virtual ~FileDownloader() {}     const QByteArray& downloadedData() const {        return m_DownloadedData;    } signals:    void downloaded(); private slots:    void fileDownloaded(QNetworkReply* pReply) {        m_DownloadedData = pReply->readAll();        pReply->deleteLater();        emit downloaded();    } private:    QNetworkAccessManager m_WebCtrl;    QByteArray m_DownloadedData;};  static const QUrl TEST_ASSET = QString("https://s3.amazonaws.com/DreamingContent/assets/models/tardis/console.fbx");static const mat4 TEST_ASSET_TRANSFORM = glm::translate(mat4(), vec3(0, -1.5f, 0)) * glm::scale(mat4(), vec3(0.01f));//static const QUrl TEST_ASSET = QString("https://s3.amazonaws.com/DreamingContent/assets/simple/SimpleMilitary/Models/Vehicles/tank_02_c.fbx");//static const mat4 TEST_ASSET_TRANSFORM = glm::translate(mat4(), vec3(0, -0.5f, 0)) * glm::scale(mat4(), vec3(0.1f)); TestFbx::TestFbx(const render::ShapePlumberPointer& shapePlumber) : _shapePlumber(shapePlumber) {    FileDownloader* downloader = new FileDownloader(TEST_ASSET, qApp);    QObject::connect(downloader, &FileDownloader::downloaded, [this, downloader] {        parseFbx(downloader->downloadedData());    });} bool TestFbx::isReady() const {    return _partCount != 0;} void TestFbx::parseFbx(const QByteArray& fbxData) {    QVariantHash mapping;    HFMModel::Pointer hfmModel = FBXSerializer().read(fbxData, mapping);    size_t totalVertexCount = 0;    size_t totalIndexCount = 0;    size_t totalPartCount = 0;    size_t highestIndex = 0;    for (const auto& mesh : hfmModel->meshes) {        size_t vertexCount = mesh.vertices.size();        totalVertexCount += mesh.vertices.size();        highestIndex = std::max(highestIndex, vertexCount);        totalPartCount += mesh.parts.size();        for (const auto& part : mesh.parts) {            totalIndexCount += part.quadTrianglesIndices.size();            totalIndexCount += part.triangleIndices.size();        }    }    size_t baseVertex = 0;    std::vector<MyVertex> vertices;    vertices.reserve(totalVertexCount);    std::vector<uint16_t> indices;    indices.reserve(totalIndexCount);    std::vector<DrawElementsIndirectCommand> parts;    parts.reserve(totalPartCount);    _partCount = totalPartCount;    for (const auto& mesh : hfmModel->meshes) {        baseVertex = vertices.size();         vec3 color;        for (const auto& part : mesh.parts) {            DrawElementsIndirectCommand partIndirect;            partIndirect.baseVertex = (uint)baseVertex;            partIndirect.firstIndex = (uint)indices.size();            partIndirect.baseInstance = (uint)parts.size();            _partTransforms.push_back(mesh.modelTransform);            auto material = hfmModel->materials[part.materialID];            color = material.diffuseColor;            for (auto index : part.quadTrianglesIndices) {                indices.push_back(index);            }            for (auto index : part.triangleIndices) {                indices.push_back(index);            }            size_t triangles = (indices.size() - partIndirect.firstIndex);            Q_ASSERT(0 == (triangles % 3));            //triangles /= 3;            partIndirect.count = (uint)triangles;            parts.push_back(partIndirect);        }         size_t vertexCount = mesh.vertices.size();        for (size_t i = 0; i < vertexCount; ++i) {            MyVertex vertex;            vertex.position = mesh.vertices[(int)i];            vec3 n = mesh.normals[(int)i];            vertex.normal = n;             vertex.texCoords = mesh.texCoords[(int)i];            vertex.color = toCompactColor(vec4(color, 1));            vertices.push_back(vertex);        }    }     _vertexBuffer->append(vertices);    _indexBuffer->append(indices);    _indirectBuffer->append(parts);} void TestFbx::renderTest(size_t testId, RenderArgs* args) {    gpu::Batch& batch = *(args->_batch);    //pipeline->pipeline    if (_partCount) {        for (size_t i = 0; i < _partCount; ++i) {            batch.setModelTransform(TEST_ASSET_TRANSFORM * _partTransforms[i]);            batch.setupNamedCalls(__FUNCTION__, [this](gpu::Batch& batch, gpu::Batch::NamedBatchData&) {                RenderArgs args; args._batch = &batch;                _shapePlumber->pickPipeline(&args, render::ShapeKey());                batch.setInputBuffer(0, _vertexBuffer, 0, sizeof(MyVertex));                batch.setIndexBuffer(gpu::UINT16, _indexBuffer, 0);                batch.setInputFormat(MyVertex::getVertexFormat());                batch.setIndirectBuffer(_indirectBuffer, 0);                batch.multiDrawIndexedIndirect((uint)_partCount, gpu::TRIANGLES);            });        }    }} #include "TestFbx.moc"

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t