History

CR fedback and cleanup

humbletim committed 8 years ago

Commit be8d79f1 parent 5791ca436 files · +890 −645Browse files

Showing the changes to libraries/script-engine/src/ModelScriptingInterface.cpp (1 of 36 files). Show all

Unified · Split

libraries/script-engine/src/ModelScriptingInterface.cpp+251−0
@@ -0,0 +1,251 @@
1+//
2+// ModelScriptingInterface.cpp
3+// libraries/script-engine/src
4+//
5+// Created by Seth Alves on 2017-1-27.
6+// Copyright 2017 High Fidelity, Inc.
7+//
8+// Distributed under the Apache License, Version 2.0.
9+// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
10+//
11+
12+#include "ModelScriptingInterface.h"
13+#include <QScriptEngine>
14+#include <QScriptValueIterator>
15+#include <QtScript/QScriptValue>
16+#include <model-networking/SimpleMeshProxy.h>
17+#include "ScriptEngine.h"
18+#include "ScriptEngineLogging.h"
19+#include "OBJWriter.h"
20+
21+ModelScriptingInterface::ModelScriptingInterface(QObject* parent) : QObject(parent) {
22+ _modelScriptEngine = qobject_cast<QScriptEngine*>(parent);
23+
24+ qScriptRegisterSequenceMetaType<QList<MeshProxy*>>(_modelScriptEngine);
25+ qScriptRegisterMetaType(_modelScriptEngine, meshFaceToScriptValue, meshFaceFromScriptValue);
26+ qScriptRegisterMetaType(_modelScriptEngine, qVectorMeshFaceToScriptValue, qVectorMeshFaceFromScriptValue);
27+}
28+
29+QString ModelScriptingInterface::meshToOBJ(MeshProxyList in) {
30+ QList<MeshPointer> meshes;
31+ foreach (const MeshProxy* meshProxy, in) {
32+ meshes.append(meshProxy->getMeshPointer());
33+ }
34+
35+ return writeOBJToString(meshes);
36+}
37+
38+QScriptValue ModelScriptingInterface::appendMeshes(MeshProxyList in) {
39+ // figure out the size of the resulting mesh
40+ size_t totalVertexCount { 0 };
41+ size_t totalColorCount { 0 };
42+ size_t totalNormalCount { 0 };
43+ size_t totalIndexCount { 0 };
44+ foreach (const MeshProxy* meshProxy, in) {
45+ MeshPointer mesh = meshProxy->getMeshPointer();
46+ totalVertexCount += mesh->getNumVertices();
47+
48+ int attributeTypeColor = gpu::Stream::InputSlot::COLOR; // libraries/gpu/src/gpu/Stream.h
49+ const gpu::BufferView& colorsBufferView = mesh->getAttributeBuffer(attributeTypeColor);
50+ gpu::BufferView::Index numColors = (gpu::BufferView::Index)colorsBufferView.getNumElements();
51+ totalColorCount += numColors;
52+
53+ int attributeTypeNormal = gpu::Stream::InputSlot::NORMAL; // libraries/gpu/src/gpu/Stream.h
54+ const gpu::BufferView& normalsBufferView = mesh->getAttributeBuffer(attributeTypeNormal);
55+ gpu::BufferView::Index numNormals = (gpu::BufferView::Index)normalsBufferView.getNumElements();
56+ totalNormalCount += numNormals;
57+
58+ totalIndexCount += mesh->getNumIndices();
59+ }
60+
61+ // alloc the resulting mesh
62+ gpu::Resource::Size combinedVertexSize = totalVertexCount * sizeof(glm::vec3);
63+ std::unique_ptr<unsigned char> combinedVertexData{ new unsigned char[combinedVertexSize] };
64+ unsigned char* combinedVertexDataCursor = combinedVertexData.get();
65+
66+ gpu::Resource::Size combinedColorSize = totalColorCount * sizeof(glm::vec3);
67+ std::unique_ptr<unsigned char> combinedColorData{ new unsigned char[combinedColorSize] };
68+ unsigned char* combinedColorDataCursor = combinedColorData.get();
69+
70+ gpu::Resource::Size combinedNormalSize = totalNormalCount * sizeof(glm::vec3);
71+ std::unique_ptr<unsigned char> combinedNormalData{ new unsigned char[combinedNormalSize] };
72+ unsigned char* combinedNormalDataCursor = combinedNormalData.get();
73+
74+ gpu::Resource::Size combinedIndexSize = totalIndexCount * sizeof(uint32_t);
75+ std::unique_ptr<unsigned char> combinedIndexData{ new unsigned char[combinedIndexSize] };
76+ unsigned char* combinedIndexDataCursor = combinedIndexData.get();
77+
78+ uint32_t indexStartOffset { 0 };
79+
80+ foreach (const MeshProxy* meshProxy, in) {
81+ MeshPointer mesh = meshProxy->getMeshPointer();
82+ mesh->forEach(
83+ [&](glm::vec3 position){
84+ memcpy(combinedVertexDataCursor, &position, sizeof(position));
85+ combinedVertexDataCursor += sizeof(position);
86+ },
87+ [&](glm::vec3 color){
88+ memcpy(combinedColorDataCursor, &color, sizeof(color));
89+ combinedColorDataCursor += sizeof(color);
90+ },
91+ [&](glm::vec3 normal){
92+ memcpy(combinedNormalDataCursor, &normal, sizeof(normal));
93+ combinedNormalDataCursor += sizeof(normal);
94+ },
95+ [&](uint32_t index){
96+ index += indexStartOffset;
97+ memcpy(combinedIndexDataCursor, &index, sizeof(index));
98+ combinedIndexDataCursor += sizeof(index);
99+ });
100+
101+ gpu::BufferView::Index numVertices = (gpu::BufferView::Index)mesh->getNumVertices();
102+ indexStartOffset += numVertices;
103+ }
104+
105+ graphics::MeshPointer result(new graphics::Mesh());
106+
107+ gpu::Element vertexElement = gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ);
108+ gpu::Buffer* combinedVertexBuffer = new gpu::Buffer(combinedVertexSize, combinedVertexData.get());
109+ gpu::BufferPointer combinedVertexBufferPointer(combinedVertexBuffer);
110+ gpu::BufferView combinedVertexBufferView(combinedVertexBufferPointer, vertexElement);
111+ result->setVertexBuffer(combinedVertexBufferView);
112+
113+ int attributeTypeColor = gpu::Stream::InputSlot::COLOR; // libraries/gpu/src/gpu/Stream.h
114+ gpu::Element colorElement = gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ);
115+ gpu::Buffer* combinedColorsBuffer = new gpu::Buffer(combinedColorSize, combinedColorData.get());
116+ gpu::BufferPointer combinedColorsBufferPointer(combinedColorsBuffer);
117+ gpu::BufferView combinedColorsBufferView(combinedColorsBufferPointer, colorElement);
118+ result->addAttribute(attributeTypeColor, combinedColorsBufferView);
119+
120+ int attributeTypeNormal = gpu::Stream::InputSlot::NORMAL; // libraries/gpu/src/gpu/Stream.h
121+ gpu::Element normalElement = gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ);
122+ gpu::Buffer* combinedNormalsBuffer = new gpu::Buffer(combinedNormalSize, combinedNormalData.get());
123+ gpu::BufferPointer combinedNormalsBufferPointer(combinedNormalsBuffer);
124+ gpu::BufferView combinedNormalsBufferView(combinedNormalsBufferPointer, normalElement);
125+ result->addAttribute(attributeTypeNormal, combinedNormalsBufferView);
126+
127+ gpu::Element indexElement = gpu::Element(gpu::SCALAR, gpu::UINT32, gpu::RAW);
128+ gpu::Buffer* combinedIndexesBuffer = new gpu::Buffer(combinedIndexSize, combinedIndexData.get());
129+ gpu::BufferPointer combinedIndexesBufferPointer(combinedIndexesBuffer);
130+ gpu::BufferView combinedIndexesBufferView(combinedIndexesBufferPointer, indexElement);
131+ result->setIndexBuffer(combinedIndexesBufferView);
132+
133+ std::vector<graphics::Mesh::Part> parts;
134+ parts.emplace_back(graphics::Mesh::Part((graphics::Index)0, // startIndex
135+ (graphics::Index)result->getNumIndices(), // numIndices
136+ (graphics::Index)0, // baseVertex
137+ graphics::Mesh::TRIANGLES)); // topology
138+ result->setPartBuffer(gpu::BufferView(new gpu::Buffer(parts.size() * sizeof(graphics::Mesh::Part),
139+ (gpu::Byte*) parts.data()), gpu::Element::PART_DRAWCALL));
140+
141+
142+ MeshProxy* resultProxy = new SimpleMeshProxy(result);
143+ return meshToScriptValue(_modelScriptEngine, resultProxy);
144+}
145+
146+QScriptValue ModelScriptingInterface::transformMesh(glm::mat4 transform, MeshProxy* meshProxy) {
147+ if (!meshProxy) {
148+ return QScriptValue(false);
149+ }
150+ MeshPointer mesh = meshProxy->getMeshPointer();
151+ if (!mesh) {
152+ return QScriptValue(false);
153+ }
154+
155+ const auto inverseTransposeTransform = glm::inverse(glm::transpose(transform));
156+ graphics::MeshPointer result = mesh->map([&](glm::vec3 position){ return glm::vec3(transform * glm::vec4(position, 1.0f)); },
157+ [&](glm::vec3 color){ return color; },
158+ [&](glm::vec3 normal){ return glm::vec3(inverseTransposeTransform * glm::vec4(normal, 0.0f)); },
159+ [&](uint32_t index){ return index; });
160+ MeshProxy* resultProxy = new SimpleMeshProxy(result);
161+ return meshToScriptValue(_modelScriptEngine, resultProxy);
162+}
163+
164+QScriptValue ModelScriptingInterface::getVertexCount(MeshProxy* meshProxy) {
165+ if (!meshProxy) {
166+ return QScriptValue(false);
167+ }
168+ MeshPointer mesh = meshProxy->getMeshPointer();
169+ if (!mesh) {
170+ return QScriptValue(false);
171+ }
172+
173+ gpu::BufferView::Index numVertices = (gpu::BufferView::Index)mesh->getNumVertices();
174+
175+ return numVertices;
176+}
177+
178+QScriptValue ModelScriptingInterface::getVertex(MeshProxy* meshProxy, int vertexIndex) {
179+ if (!meshProxy) {
180+ return QScriptValue(false);
181+ }
182+ MeshPointer mesh = meshProxy->getMeshPointer();
183+ if (!mesh) {
184+ return QScriptValue(false);
185+ }
186+
187+ const gpu::BufferView& vertexBufferView = mesh->getVertexBuffer();
188+ gpu::BufferView::Index numVertices = (gpu::BufferView::Index)mesh->getNumVertices();
189+
190+ if (vertexIndex < 0 || vertexIndex >= numVertices) {
191+ return QScriptValue(false);
192+ }
193+
194+ glm::vec3 pos = vertexBufferView.get<glm::vec3>(vertexIndex);
195+ return vec3toScriptValue(_modelScriptEngine, pos);
196+}
197+
198+
199+QScriptValue ModelScriptingInterface::newMesh(const QVector<glm::vec3>& vertices,
200+ const QVector<glm::vec3>& normals,
201+ const QVector<MeshFace>& faces) {
202+ graphics::MeshPointer mesh(new graphics::Mesh());
203+
204+ // vertices
205+ auto vertexBuffer = std::make_shared<gpu::Buffer>(vertices.size() * sizeof(glm::vec3), (gpu::Byte*)vertices.data());
206+ auto vertexBufferPtr = gpu::BufferPointer(vertexBuffer);
207+ gpu::BufferView vertexBufferView(vertexBufferPtr, 0, vertexBufferPtr->getSize(),
208+ sizeof(glm::vec3), gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ));
209+ mesh->setVertexBuffer(vertexBufferView);
210+
211+ if (vertices.size() == normals.size()) {
212+ // normals
213+ auto normalBuffer = std::make_shared<gpu::Buffer>(normals.size() * sizeof(glm::vec3), (gpu::Byte*)normals.data());
214+ auto normalBufferPtr = gpu::BufferPointer(normalBuffer);
215+ gpu::BufferView normalBufferView(normalBufferPtr, 0, normalBufferPtr->getSize(),
216+ sizeof(glm::vec3), gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ));
217+ mesh->addAttribute(gpu::Stream::NORMAL, normalBufferView);
218+ } else {
219+ qCDebug(scriptengine) << "ModelScriptingInterface::newMesh normals must be same length as vertices";
220+ }
221+
222+ // indices (faces)
223+ int VERTICES_PER_TRIANGLE = 3;
224+ int indexBufferSize = faces.size() * sizeof(uint32_t) * VERTICES_PER_TRIANGLE;
225+ unsigned char* indexData = new unsigned char[indexBufferSize];
226+ unsigned char* indexDataCursor = indexData;
227+ foreach(const MeshFace& meshFace, faces) {
228+ for (int i = 0; i < VERTICES_PER_TRIANGLE; i++) {
229+ memcpy(indexDataCursor, &meshFace.vertexIndices[i], sizeof(uint32_t));
230+ indexDataCursor += sizeof(uint32_t);
231+ }
232+ }
233+ auto indexBuffer = std::make_shared<gpu::Buffer>(indexBufferSize, (gpu::Byte*)indexData);
234+ auto indexBufferPtr = gpu::BufferPointer(indexBuffer);
235+ gpu::BufferView indexBufferView(indexBufferPtr, gpu::Element(gpu::SCALAR, gpu::UINT32, gpu::RAW));
236+ mesh->setIndexBuffer(indexBufferView);
237+
238+ // parts
239+ std::vector<graphics::Mesh::Part> parts;
240+ parts.emplace_back(graphics::Mesh::Part((graphics::Index)0, // startIndex
241+ (graphics::Index)faces.size() * 3, // numIndices
242+ (graphics::Index)0, // baseVertex
243+ graphics::Mesh::TRIANGLES)); // topology
244+ mesh->setPartBuffer(gpu::BufferView(new gpu::Buffer(parts.size() * sizeof(graphics::Mesh::Part),
245+ (gpu::Byte*) parts.data()), gpu::Element::PART_DRAWCALL));
246+
247+
248+
249+ MeshProxy* meshProxy = new SimpleMeshProxy(mesh);
250+ return meshToScriptValue(_modelScriptEngine, meshProxy);
251+}

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