ModelScriptingInterface::appendMeshes

This commit is contained in:
Seth Alves 2017-03-16 15:22:34 -07:00
parent a3fadbc367
commit 200550aba9
4 changed files with 94 additions and 3 deletions

View file

@ -1574,7 +1574,6 @@ void RenderablePolyVoxEntityItem::locationChanged(bool tellPhysics) {
bool RenderablePolyVoxEntityItem::getMeshAsScriptValue(QScriptEngine *engine, QScriptValue& result) const {
bool success = false;
MeshProxy* meshProxy = nullptr;
model::MeshPointer mesh = nullptr;
withReadLock([&] {
if (_meshInitialized) {
success = true;

View file

@ -198,7 +198,7 @@ public:
BufferView(const BufferPointer& buffer, Size offset, Size size, const Element& element = DEFAULT_ELEMENT);
BufferView(const BufferPointer& buffer, Size offset, Size size, uint16 stride, const Element& element = DEFAULT_ELEMENT);
Size getNumElements() const { return _size / _element.getSize(); }
Size getNumElements() const { return (_size - _offset) / _stride; }
//Template iterator with random access on the buffer sysmem
template<typename T>

View file

@ -12,11 +12,12 @@
#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) {
@ -51,3 +52,89 @@ QString ModelScriptingInterface::meshToOBJ(MeshProxyList in) {
return writeOBJToString(meshes);
}
QScriptValue ModelScriptingInterface::appendMeshes(MeshProxyList in) {
model::MeshPointer result(new model::Mesh());
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 = totalVertexCount * sizeof(glm::vec3);
unsigned char* combinedNormalData = new unsigned char[combinedNormalSize];
unsigned char* combinedNormalDataCursor = combinedNormalData;
gpu::Resource::Size combinedIndexSize = totalVertexCount * 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->getNumAttributes();
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;
}
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);
MeshProxy* resultProxy = new MeshProxy(result);
return meshToScriptValue(_modelScriptEngine, resultProxy);
}

View file

@ -20,6 +20,7 @@
#include "MeshProxy.h"
using MeshPointer = std::shared_ptr<model::Mesh>;
class ScriptEngine;
class ModelScriptingInterface : public QObject {
Q_OBJECT
@ -28,6 +29,10 @@ public:
ModelScriptingInterface(QObject* parent);
Q_INVOKABLE QString meshToOBJ(MeshProxyList in);
Q_INVOKABLE QScriptValue appendMeshes(MeshProxyList in);
private:
ScriptEngine* _modelScriptEngine { nullptr };
};
QScriptValue meshToScriptValue(QScriptEngine* engine, MeshProxy* const &in);