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
21ModelScriptingInterface::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
29QString 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
38QScriptValue 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
146QScriptValue 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
164QScriptValue 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
178QScriptValue 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
199QScriptValue 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