255 lines · 11.4 KB · C++
RawDownload
////  ModelScriptingInterface.cpp//  libraries/script-engine/src////  Created by Seth Alves on 2017-1-27.//  Copyright 2017 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 <QScriptEngine>#include <QScriptValueIterator>#include <QtScript/QScriptValue>#include "ScriptEngine.h"#include "ModelScriptingInterface.h"#include "OBJWriter.h" ModelScriptingInterface::ModelScriptingInterface(QObject* parent) : QObject(parent) {    _modelScriptEngine = qobject_cast<ScriptEngine*>(parent);} QScriptValue meshToScriptValue(QScriptEngine* engine, MeshProxy* const &in) {    return engine->newQObject(in, QScriptEngine::QtOwnership,                              QScriptEngine::ExcludeDeleteLater | QScriptEngine::ExcludeChildObjects);} void meshFromScriptValue(const QScriptValue& value, MeshProxy* &out) {    out = qobject_cast<MeshProxy*>(value.toQObject());} QScriptValue meshesToScriptValue(QScriptEngine* engine, const MeshProxyList &in) {    return engine->toScriptValue(in);} void meshesFromScriptValue(const QScriptValue& value, MeshProxyList &out) {    QScriptValueIterator itr(value);    while(itr.hasNext()) {        itr.next();        MeshProxy* meshProxy = qscriptvalue_cast<MeshProxyList::value_type>(itr.value());        if (meshProxy) {            out.append(meshProxy);        }    }} QString ModelScriptingInterface::meshToOBJ(MeshProxyList in) {    QList<MeshPointer> meshes;    foreach (const MeshProxy* meshProxy, in) {        meshes.append(meshProxy->getMeshPointer());    }     return writeOBJToString(meshes);}  QScriptValue ModelScriptingInterface::appendMeshes(MeshProxyList in) {    int attributeTypeNormal = gpu::Stream::InputSlot::NORMAL; // libraries/gpu/src/gpu/Stream.h     size_t totalVertexCount { 0 };    size_t totalAttributeCount { 0 };    size_t totalIndexCount { 0 };    foreach (const MeshProxy* meshProxy, in) {        MeshPointer mesh = meshProxy->getMeshPointer();        totalVertexCount += mesh->getNumVertices();        totalAttributeCount += mesh->getNumAttributes();        totalIndexCount += mesh->getNumIndices();    }     gpu::Resource::Size combinedVertexSize = totalVertexCount * sizeof(glm::vec3);    unsigned char* combinedVertexData  = new unsigned char[combinedVertexSize];    unsigned char* combinedVertexDataCursor = combinedVertexData;     gpu::Resource::Size combinedNormalSize = totalAttributeCount * sizeof(glm::vec3);    unsigned char* combinedNormalData  = new unsigned char[combinedNormalSize];    unsigned char* combinedNormalDataCursor = combinedNormalData;     gpu::Resource::Size combinedIndexSize = totalIndexCount * sizeof(uint32_t);    unsigned char* combinedIndexData  = new unsigned char[combinedIndexSize];    unsigned char* combinedIndexDataCursor = combinedIndexData;     uint32_t indexStartOffset { 0 };     foreach (const MeshProxy* meshProxy, in) {        MeshPointer mesh = meshProxy->getMeshPointer();         // vertex data        const gpu::BufferView& vertexBufferView = mesh->getVertexBuffer();        gpu::BufferView::Index numVertices = (gpu::BufferView::Index)mesh->getNumVertices();        for (gpu::BufferView::Index i = 0; i < numVertices; i ++) {            glm::vec3 pos = vertexBufferView.get<glm::vec3>(i);            memcpy(combinedVertexDataCursor, &pos, sizeof(pos));            combinedVertexDataCursor += sizeof(pos);        }         // normal data        const gpu::BufferView& normalsBufferView = mesh->getAttributeBuffer(attributeTypeNormal);        gpu::BufferView::Index numNormals = (gpu::BufferView::Index)mesh->getNumAttributes();        for (gpu::BufferView::Index i = 0; i < numNormals; i ++) {            glm::vec3 normal = normalsBufferView.get<glm::vec3>(i);            memcpy(combinedNormalDataCursor, &normal, sizeof(normal));            combinedNormalDataCursor += sizeof(normal);        }        // TODO -- other attributes         // face data        const gpu::BufferView& indexBufferView = mesh->getIndexBuffer();        gpu::BufferView::Index numIndexes = (gpu::BufferView::Index)mesh->getNumIndices();        for (gpu::BufferView::Index i = 0; i < numIndexes; i ++) {            uint32_t index = indexBufferView.get<uint32_t>(i);            index += indexStartOffset;            memcpy(combinedIndexDataCursor, &index, sizeof(index));            combinedIndexDataCursor += sizeof(index);        }         indexStartOffset += numVertices;    }     model::MeshPointer result(new model::Mesh());     gpu::Element vertexElement = gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ);    gpu::Buffer* combinedVertexBuffer = new gpu::Buffer(combinedVertexSize, combinedVertexData);    gpu::BufferPointer combinedVertexBufferPointer(combinedVertexBuffer);    gpu::BufferView combinedVertexBufferView(combinedVertexBufferPointer, vertexElement);    result->setVertexBuffer(combinedVertexBufferView);     gpu::Element normalElement = gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ);    gpu::Buffer* combinedNormalsBuffer = new gpu::Buffer(combinedNormalSize, combinedNormalData);    gpu::BufferPointer combinedNormalsBufferPointer(combinedNormalsBuffer);    gpu::BufferView combinedNormalsBufferView(combinedNormalsBufferPointer, normalElement);    result->addAttribute(attributeTypeNormal, combinedNormalsBufferView);     gpu::Element indexElement = gpu::Element(gpu::SCALAR, gpu::UINT32, gpu::RAW);    gpu::Buffer* combinedIndexesBuffer = new gpu::Buffer(combinedIndexSize, combinedIndexData);    gpu::BufferPointer combinedIndexesBufferPointer(combinedIndexesBuffer);    gpu::BufferView combinedIndexesBufferView(combinedIndexesBufferPointer, indexElement);    result->setIndexBuffer(combinedIndexesBufferView);      std::vector<model::Mesh::Part> parts;    parts.emplace_back(model::Mesh::Part((model::Index)0, // startIndex                                         (model::Index)result->getNumIndices(), // numIndices                                         (model::Index)0, // baseVertex                                         model::Mesh::TRIANGLES)); // topology    result->setPartBuffer(gpu::BufferView(new gpu::Buffer(parts.size() * sizeof(model::Mesh::Part),                                                          (gpu::Byte*) parts.data()), gpu::Element::PART_DRAWCALL));      MeshProxy* resultProxy = new MeshProxy(result);    return meshToScriptValue(_modelScriptEngine, resultProxy);}  // QScriptValue ModelScriptingInterface::transformMesh(glm::mat4 transform, MeshProxy* meshProxy) {//     int attributeTypeNormal = gpu::Stream::InputSlot::NORMAL; // libraries/gpu/src/gpu/Stream.h //     if (!meshProxy) {//         return QScriptValue(false);//     } //     MeshPointer mesh = meshProxy->getMeshPointer(); //     gpu::Resource::Size vertexSize = mesh->getNumVertices() * sizeof(glm::vec3);//     unsigned char* resultVertexData  = new unsigned char[vertexSize];//     unsigned char* vertexDataCursor = resultVertexData; //     gpu::Resource::Size normalSize = mesh->getNumAttributes() * sizeof(glm::vec3);//     unsigned char* resultNormalData  = new unsigned char[normalSize];//     unsigned char* normalDataCursor = resultNormalData; //     gpu::Resource::Size indexSize = mesh->getNumIndices() * sizeof(uint32_t);//     unsigned char* resultIndexData  = new unsigned char[indexSize];//     unsigned char* indexDataCursor = resultIndexData; //     // vertex data//     const gpu::BufferView& vertexBufferView = mesh->getVertexBuffer();//     gpu::BufferView::Index numVertices = (gpu::BufferView::Index)mesh->getNumVertices();//     for (gpu::BufferView::Index i = 0; i < numVertices; i ++) {//         glm::vec3 pos = vertexBufferView.get<glm::vec3>(i);//         pos = glm::vec3(transform * glm::vec4(pos, 1.0f));//         memcpy(vertexDataCursor, &pos, sizeof(pos));//         vertexDataCursor += sizeof(pos);//     } //     // normal data//     const gpu::BufferView& normalsBufferView = mesh->getAttributeBuffer(attributeTypeNormal);//     gpu::BufferView::Index numNormals =  (gpu::BufferView::Index)mesh->getNumAttributes();//     for (gpu::BufferView::Index i = 0; i < numNormals; i ++) {//         glm::vec3 normal = normalsBufferView.get<glm::vec3>(i);//         normal = glm::vec3(transform * glm::vec4(normal, 0.0f));//         memcpy(normalDataCursor, &normal, sizeof(normal));//         normalDataCursor += sizeof(normal);//     }//     // TODO -- other attributes //     // face data//     const gpu::BufferView& indexBufferView = mesh->getIndexBuffer();//     gpu::BufferView::Index numIndexes =  (gpu::BufferView::Index)mesh->getNumIndices();//     for (gpu::BufferView::Index i = 0; i < numIndexes; i ++) {//         uint32_t index = indexBufferView.get<uint32_t>(i);//         memcpy(indexDataCursor, &index, sizeof(index));//         indexDataCursor += sizeof(index);//     } //     model::MeshPointer result(new model::Mesh()); //     gpu::Element vertexElement = gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ);//     gpu::Buffer* resultVertexBuffer = new gpu::Buffer(vertexSize, resultVertexData);//     gpu::BufferPointer resultVertexBufferPointer(resultVertexBuffer);//     gpu::BufferView resultVertexBufferView(resultVertexBufferPointer, vertexElement);//     result->setVertexBuffer(resultVertexBufferView); //     gpu::Element normalElement = gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ);//     gpu::Buffer* resultNormalsBuffer = new gpu::Buffer(normalSize, resultNormalData);//     gpu::BufferPointer resultNormalsBufferPointer(resultNormalsBuffer);//     gpu::BufferView resultNormalsBufferView(resultNormalsBufferPointer, normalElement);//     result->addAttribute(attributeTypeNormal, resultNormalsBufferView); //     gpu::Element indexElement = gpu::Element(gpu::SCALAR, gpu::UINT32, gpu::RAW);//     gpu::Buffer* resultIndexesBuffer = new gpu::Buffer(indexSize, resultIndexData);//     gpu::BufferPointer resultIndexesBufferPointer(resultIndexesBuffer);//     gpu::BufferView resultIndexesBufferView(resultIndexesBufferPointer, indexElement);//     result->setIndexBuffer(resultIndexesBufferView);  //     std::vector<model::Mesh::Part> parts;//     parts.emplace_back(model::Mesh::Part((model::Index)0, // startIndex//                                          (model::Index)result->getNumIndices(), // numIndices//                                          (model::Index)0, // baseVertex//                                          model::Mesh::TRIANGLES)); // topology//     result->setPartBuffer(gpu::BufferView(new gpu::Buffer(parts.size() * sizeof(model::Mesh::Part),//                                                           (gpu::Byte*) parts.data()), gpu::Element::PART_DRAWCALL));   //     MeshProxy* resultProxy = new MeshProxy(result);//     return meshToScriptValue(_modelScriptEngine, resultProxy);// }  QScriptValue ModelScriptingInterface::transformMesh(glm::mat4 transform, MeshProxy* meshProxy) {    if (!meshProxy) {        return QScriptValue(false);    }    MeshPointer mesh = meshProxy->getMeshPointer();    if (!mesh) {        return QScriptValue(false);    }     model::MeshPointer result = mesh->map([&](glm::vec3 position){ return glm::vec3(transform * glm::vec4(position, 1.0f)); },                                          [&](glm::vec3 normal){ return glm::vec3(transform * glm::vec4(normal, 0.0f)); },                                          [&](uint32_t index){ return index; });    MeshProxy* resultProxy = new MeshProxy(result);    return meshToScriptValue(_modelScriptEngine, resultProxy);}