CR fedback and cleanup

This commit is contained in:
humbletim 2018-02-22 07:56:09 -05:00
parent caab532d80
commit e4a2a589a5
15 changed files with 159 additions and 221 deletions

View file

@ -607,7 +607,7 @@ void messageHandler(QtMsgType type, const QMessageLogContext& context, const QSt
class ApplicationMeshProvider : public scriptable::ModelProviderFactory {
public:
virtual scriptable::ModelProviderPointer lookupModelProvider(QUuid uuid) {
virtual scriptable::ModelProviderPointer lookupModelProvider(const QUuid& uuid) {
QString error;
scriptable::ModelProviderPointer provider;
@ -631,7 +631,7 @@ public:
if (auto entity = entityTree->findEntityByID(entityID)) {
if (auto renderer = entityTreeRenderer->renderableForEntityId(entityID)) {
provider = std::dynamic_pointer_cast<scriptable::ModelProvider>(renderer);
provider->metadata["providerType"] = "entity";
provider->modelProviderType = NestableType::Entity;
} else {
qCWarning(interfaceapp) << "no renderer for entity ID" << entityID.toString();
}
@ -645,7 +645,7 @@ public:
if (auto overlay = overlays.getOverlay(overlayID)) {
if (auto base3d = std::dynamic_pointer_cast<Base3DOverlay>(overlay)) {
provider = std::dynamic_pointer_cast<scriptable::ModelProvider>(base3d);
provider->metadata["providerType"] = "overlay";
provider->modelProviderType = NestableType::Overlay;
} else {
qCWarning(interfaceapp) << "no renderer for overlay ID" << overlayID.toString();
}
@ -659,7 +659,7 @@ public:
if (auto avatar = avatarManager->getAvatarBySessionID(sessionUUID)) {
if (avatar->getSessionUUID() == sessionUUID) {
provider = std::dynamic_pointer_cast<scriptable::ModelProvider>(avatar);
provider->metadata["providerType"] = "avatar";
provider->modelProviderType = NestableType::Avatar;
}
}
return provider;
@ -811,6 +811,7 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) {
DependencyManager::set<ResourceCacheSharedItems>();
DependencyManager::set<DesktopScriptingInterface>();
DependencyManager::set<EntityScriptingInterface>(true);
DependencyManager::set<GraphicsScriptingInterface>();
DependencyManager::registerInheritance<scriptable::ModelProviderFactory, ApplicationMeshProvider>();
DependencyManager::set<ApplicationMeshProvider>();
DependencyManager::set<RecordingScriptingInterface>();

View file

@ -119,6 +119,7 @@ bool ModelOverlay::addToScene(Overlay::Pointer overlay, const render::ScenePoint
void ModelOverlay::removeFromScene(Overlay::Pointer overlay, const render::ScenePointer& scene, render::Transaction& transaction) {
Volume3DOverlay::removeFromScene(overlay, scene, transaction);
_model->removeFromScene(scene, transaction);
emit DependencyManager::get<scriptable::ModelProviderFactory>()->modelRemovedFromScene(getID(), NestableType::Overlay, _model);
transaction.updateItem<Overlay>(getRenderItemID(), [](Overlay& data) {
auto modelOverlay = static_cast<ModelOverlay*>(&data);
modelOverlay->clearSubRenderItemIDs();

View file

@ -1073,14 +1073,8 @@ void ModelEntityRenderer::removeFromScene(const ScenePointer& scene, Transaction
void ModelEntityRenderer::onRemoveFromSceneTyped(const TypedEntityPointer& entity) {
entity->setModel({});
//emit DependencyManager::get<scriptable::ModelProviderFactory>()->modelRemovedFromScene(entity->getID(), NestableType::Entity, _model);
}
void ModelEntityRenderer::onAddToSceneTyped(const TypedEntityPointer& entity) {
//emit DependencyManager::get<scriptable::ModelProviderFactory>()->modelAddedToScene(entity->getID(), NestableType::Entity, _model);
}
void ModelEntityRenderer::animate(const TypedEntityPointer& entity) {
if (!_animation || !_animation->isLoaded()) {
return;

View file

@ -242,6 +242,9 @@ public:
graphics::MeshPointer _mesh;
bool wasCompressed { false };
void createMeshTangents(bool generateFromTexCoords);
void createBlendShapeTangents(bool generateTangents);
};
class ExtractedMesh {

View file

@ -9,15 +9,14 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "OBJWriter.h"
#include <QFile>
#include <QFileInfo>
#include "graphics/Geometry.h"
#include "OBJWriter.h"
#include <graphics/BufferViewHelpers.h>
#include <graphics/Geometry.h>
#include "ModelFormatLogging.h"
// FIXME: should this live in shared? (it depends on gpu/)
#include <../graphics-scripting/src/graphics-scripting/BufferViewHelpers.h>
static QString formatFloat(double n) {
// limit precision to 6, but don't output trailing zeros.
QString s = QString::number(n, 'f', 6);
@ -71,8 +70,10 @@ bool writeOBJToTextStream(QTextStream& out, QList<MeshPointer> meshes) {
out << formatFloat(v[1]) << " ";
out << formatFloat(v[2]);
if (colorIndex < numColors) {
glm::vec3 color = glmVecFromVariant<glm::vec3>(buffer_helpers::toVariant(colorsBufferView, colorIndex));
//glm::vec3 color = colorsBufferView.get<glm::vec3>(colorIndex);
glm::vec3 color = buffer_helpers::convert<glm::vec3>(colorsBufferView, colorIndex);
// TODO: still verifying that the above decodes properly; previous variations were:
// glm::vec3 color = buffer_helpers::glmVecFromVariant<glm::vec3>(buffer_helpers::toVariant(colorsBufferView, colorIndex));
// glm::vec3 color = colorsBufferView.get<glm::vec3>(colorIndex);
out << " " << formatFloat(color[0]);
out << " " << formatFloat(color[1]);
out << " " << formatFloat(color[2]);
@ -95,8 +96,10 @@ bool writeOBJToTextStream(QTextStream& out, QList<MeshPointer> meshes) {
const gpu::BufferView& normalsBufferView = mesh->getAttributeBuffer(gpu::Stream::InputSlot::NORMAL);
gpu::BufferView::Index numNormals = (gpu::BufferView::Index)normalsBufferView.getNumElements();
for (gpu::BufferView::Index i = 0; i < numNormals; i++) {
glm::vec3 normal = glmVecFromVariant<glm::vec3>(buffer_helpers::toVariant(normalsBufferView, i));
//glm::vec3 normal = normalsBufferView.get<glm::vec3>(i);
glm::vec3 normal = buffer_helpers::convert<glm::vec3>(normalsBufferView, i);
// TODO: still verifying that the above decodes properly; previous variations were:
// glm::vec3 normal = buffer_helpers::glmVecFromVariant<glm::vec3>(buffer_helpers::toVariant(normalsBufferView, i));
// glm::vec3 normal = normalsBufferView.get<glm::vec3>(i);
out << "vn ";
out << formatFloat(normal[0]) << " ";
out << formatFloat(normal[1]) << " ";

View file

@ -2,4 +2,3 @@ set(TARGET_NAME graphics-scripting)
setup_hifi_library()
link_hifi_libraries(shared networking graphics fbx model-networking script-engine)
include_hifi_library_headers(gpu)
include_hifi_library_headers(graphics-scripting)

View file

@ -9,10 +9,10 @@
#include <gpu/Format.h>
#include <gpu/Stream.h>
#include <graphics-scripting/BufferViewHelpers.h>
#include <graphics/BufferViewHelpers.h>
#ifdef DEBUG_BUFFERVIEW_SCRIPTING
#include <graphics/DebugNames.h>
#include "DebugNames.h"
#endif
namespace {

View file

@ -1,8 +1,7 @@
//
// GraphicsScriptingInterface.cpp
// libraries/script-engine/src
// libraries/graphics-scripting/src
//
// Created by Seth Alves on 2017-1-27.
// Copyright 2017 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
@ -10,28 +9,24 @@
//
#include "GraphicsScriptingInterface.h"
#include <QtScript/QScriptEngine>
#include <QtScript/QScriptValueIterator>
#include <QtScript/QScriptValue>
#include <QUuid>
#include "BaseScriptEngine.h"
#include "ScriptEngineLogging.h"
#include "BufferViewScripting.h"
#include "DebugNames.h"
#include "GraphicsScriptingUtil.h"
#include "OBJWriter.h"
#include "RegisteredMetaTypes.h"
#include "ScriptEngineLogging.h"
#include "ScriptableMesh.h"
#include <GeometryUtil.h>
#include <QUuid>
#include <QtScript/QScriptEngine>
#include <QtScript/QScriptValue>
#include <QtScript/QScriptValueIterator>
#include <graphics/BufferViewHelpers.h>
#include <shared/QtHelpers.h>
#include <graphics-scripting/DebugNames.h>
#include <graphics-scripting/BufferViewHelpers.h>
#include "BufferViewScripting.h"
#include "ScriptableMesh.h"
#include "GraphicsScriptingUtil.h"
#include "GraphicsScriptingInterface.moc"
#include "RegisteredMetaTypes.h"
GraphicsScriptingInterface::GraphicsScriptingInterface(QObject* parent) : QObject(parent) {
if (auto scriptEngine = qobject_cast<QScriptEngine*>(parent)) {
this->registerMetaTypes(scriptEngine);

View file

@ -12,12 +12,15 @@ Q_DECLARE_LOGGING_CATEGORY(graphics_scripting)
namespace scriptable {
// derive current context's C++ QObject (based on current JS "this" value)
template <typename T> T this_qobject_cast(QScriptEngine* engine) {
template <typename T>
T this_qobject_cast(QScriptEngine* engine) {
auto context = engine ? engine->currentContext() : nullptr;
return qscriptvalue_cast<T>(context ? context->thisObject() : QScriptValue::NullValue);
}
// JS => QPointer<QObject>
template <typename T> QPointer<T> qpointer_qobject_cast(const QScriptValue& value) {
template <typename T>
QPointer<T> qpointer_qobject_cast(const QScriptValue& value) {
auto obj = value.toQObject();
#ifdef SCRIPTABLE_MESH_DEBUG
qCInfo(graphics_scripting) << "qpointer_qobject_cast" << obj << value.toString();
@ -41,54 +44,21 @@ namespace scriptable {
}
// C++ > QtOwned instance
template <typename T, class... Rest> std::shared_ptr<T> make_qtowned(Rest... rest) {
template <typename T, class... Rest>
std::shared_ptr<T> make_qtowned(Rest... rest) {
T* tmp = new T(rest...);
#ifdef SCRIPTABLE_MESH_DEBUG
qCInfo(graphics_scripting) << "scriptable::make_qtowned" << toDebugString(tmp);
#endif
QString debug = toDebugString(tmp);
if (tmp) {
tmp->metadata["__ownership__"] = QScriptEngine::QtOwnership;
#ifdef SCRIPTABLE_MESH_DEBUG
QObject::connect(tmp, &QObject::destroyed, [=]() { qCInfo(graphics_scripting) << "-------- ~scriptable::make_qtowned" << debug; });
#endif
auto ptr = std::shared_ptr<T>(tmp, [debug](T* tmp) {
//qDebug() << "~std::shared_ptr<T>" << debug;
delete tmp;
});
return ptr;
} else {
return std::shared_ptr<T>(tmp);
}
return std::shared_ptr<T>(tmp);
}
// C++ > ScriptOwned JS instance
template <typename T, class... Rest> QPointer<T> make_scriptowned(Rest... rest) {
template <typename T, class... Rest>
QPointer<T> make_scriptowned(Rest... rest) {
T* tmp = new T(rest...);
#ifdef SCRIPTABLE_MESH_DEBUG
qCInfo(graphics_scripting) << "scriptable::make_scriptowned" << toDebugString(tmp);
#endif
if (tmp) {
tmp->metadata["__ownership__"] = QScriptEngine::ScriptOwnership;
//auto blah = (DeleterFunction)[](void* delme) { };
return add_scriptowned_destructor(tmp);
} else {
return QPointer<T>(tmp);
}
}
// C++ > ScriptOwned JS instance
template <typename T> QPointer<T> add_scriptowned_destructor(T* tmp) {
QString debug = toDebugString(tmp);
if (tmp) {
#ifdef SCRIPTABLE_MESH_DEBUG
QObject::connect(tmp, &QObject::destroyed, [=]() {
qCInfo(graphics_scripting) << "-------- ~scriptable::make_scriptowned" << debug;// << !!customDeleter;
//if (customDeleter) {
// customDeleter(tmp);
//}
});
#endif
} else {
qCInfo(graphics_scripting) << "add_scriptowned_destructor -- not connecting to null value" << debug;
}
return QPointer<T>(tmp);
}

View file

@ -1,41 +1,26 @@
//
// SimpleMeshProxy.cpp
// libraries/model-networking/src/model-networking/
//
// Created by Seth Alves on 2017-3-22.
// Copyright 2017 High Fidelity, Inc.
// Copyright 2018 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 "GraphicsScriptingUtil.h"
#include "ScriptableMesh.h"
#include <glm/glm.hpp>
#include <glm/gtx/transform.hpp>
#include <glm/gtx/norm.hpp>
#include <graphics/Geometry.h>
#include <graphics-scripting/DebugNames.h>
#include <graphics-scripting/BufferViewHelpers.h>
#include <graphics-scripting/BufferViewScripting.h>
#include "ScriptableMesh.moc"
#include <RegisteredMetaTypes.h>
#include "BufferViewScripting.h"
#include "DebugNames.h"
#include "GraphicsScriptingUtil.h"
#include "OBJWriter.h"
#include <BaseScriptEngine.h>
#include <QtScript/QScriptValue>
#include <RegisteredMetaTypes.h>
#include <glm/glm.hpp>
#include <glm/gtx/norm.hpp>
#include <glm/gtx/transform.hpp>
#include <graphics/BufferViewHelpers.h>
#include <graphics/Geometry.h>
#include "OBJWriter.h"
// #define SCRIPTABLE_MESH_DEBUG
namespace scriptable {
// QScriptValue jsBindCallback(QScriptValue callback);
// template <typename T> QPointer<T> qpointer_qobject_cast(const QScriptValue& value);
// template <typename T> T this_qobject_cast(QScriptEngine* engine);
// template <typename T, class... Rest> QPointer<T> make_scriptowned(Rest... rest);
}
#include "ScriptableMesh.moc"
scriptable::ScriptableMeshPart::ScriptableMeshPart(scriptable::ScriptableMeshPointer parentMesh, int partIndex)
: parentMesh(parentMesh), partIndex(partIndex) {

View file

@ -1,26 +1,22 @@
#pragma once
#include <glm/glm.hpp>
#include <QtCore/QObject>
#include <QtCore/QVector>
#include <QtCore/QList>
#include <QtCore/QVariant>
#include <QtCore/QUuid>
#include <QPointer>
#include <memory>
#include "ScriptableModel.h"
#include <glm/glm.hpp>
#include <graphics/BufferViewHelpers.h>
#include <DependencyManager.h>
//#include <graphics-scriping/Forward.h>
#include <graphics-scripting/ScriptableModel.h>
#include <graphics-scripting/BufferViewHelpers.h>
#include <QtScript/QScriptable>
#include <memory>
#include <QPointer>
#include <QtCore/QList>
#include <QtCore/QObject>
#include <QtCore/QUuid>
#include <QtCore/QVariant>
#include <QtCore/QVector>
#include <QtScript/QScriptValue>
#include <QtScript/QScriptable>
namespace scriptable {
QScriptValue jsBindCallback(QScriptValue callback);
class ScriptableMesh : public ScriptableMeshBase, QScriptable {
Q_OBJECT
public:

View file

@ -1,4 +1,11 @@
#include "./graphics-scripting/BufferViewHelpers.h"
//
// Copyright 2018 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 "BufferViewHelpers.h"
#include <QDebug>
#include <QVariant>
@ -7,7 +14,7 @@
#include <gpu/Format.h>
#include <gpu/Stream.h>
#include <graphics/Geometry.h>
#include "Geometry.h"
#include <Extents.h>
#include <AABox.h>
@ -15,25 +22,26 @@
#include <glm/gtx/string_cast.hpp>
#include <glm/gtc/packing.hpp>
#include <glm/detail/type_vec.hpp>
namespace glm {
using hvec2 = glm::tvec2<glm::detail::hdata>;
using hvec4 = glm::tvec4<glm::detail::hdata>;
}
//#define DEBUG_BUFFERVIEW_SCRIPTING
//#ifdef DEBUG_BUFFERVIEW_SCRIPTING
#include "DebugNames.h"
//#endif
#ifdef DEBUG_BUFFERVIEW_SCRIPTING
#include "../../graphics-scripting/src/graphics-scripting/DebugNames.h"
#endif
namespace {
QLoggingCategory bufferhelper_logging{"hifi.bufferview"};
const std::array<const char*, 4> XYZW = {{ "x", "y", "z", "w" }};
const std::array<const char*, 4> ZERO123 = {{ "0", "1", "2", "3" }};
QLoggingCategory bufferhelper_logging{ "hifi.bufferview" };
const std::array<const char*, 4> XYZW = { { "x", "y", "z", "w" } };
const std::array<const char*, 4> ZERO123 = { { "0", "1", "2", "3" } };
}
gpu::BufferView buffer_helpers::getBufferView(graphics::MeshPointer mesh, gpu::Stream::Slot slot) {
return slot == gpu::Stream::POSITION ? mesh->getVertexBuffer() : mesh->getAttributeBuffer(slot);
}
QMap<QString,int> buffer_helpers::ATTRIBUTES{
{"position", gpu::Stream::POSITION },
{"normal", gpu::Stream::NORMAL },
@ -49,16 +57,23 @@ QMap<QString,int> buffer_helpers::ATTRIBUTES{
};
template <typename T>
QVariant getBufferViewElement(const gpu::BufferView& view, quint32 index, bool asArray = false) {
return glmVecToVariant(view.get<T>(index), asArray);
}
namespace {
bool boundsCheck(const gpu::BufferView& view, quint32 index) {
const auto byteLength = view._element.getSize();
return (
index < view.getNumElements() &&
index * byteLength < (view._size - 1) * byteLength
);
}
template <typename T>
void setBufferViewElement(const gpu::BufferView& view, quint32 index, const QVariant& v) {
view.edit<T>(index) = glmVecFromVariant<T>(v);
}
template <typename T> QVariant getBufferViewElement(const gpu::BufferView& view, quint32 index, bool asArray = false) {
return buffer_helpers::glmVecToVariant(view.get<T>(index), asArray);
}
template <typename T> void setBufferViewElement(const gpu::BufferView& view, quint32 index, const QVariant& v) {
view.edit<T>(index) = buffer_helpers::glmVecFromVariant<T>(v);
}
}
void buffer_helpers::packNormalAndTangent(glm::vec3 normal, glm::vec3 tangent, glm::uint32& packedNormal, glm::uint32& packedTangent) {
auto absNormal = glm::abs(normal);
@ -147,14 +162,6 @@ bool buffer_helpers::fromVariant(const gpu::BufferView& view, quint32 index, con
return false;
}
bool boundsCheck(const gpu::BufferView& view, quint32 index) {
const auto byteLength = view._element.getSize();
return (
index < view.getNumElements() &&
index * byteLength < (view._size - 1) * byteLength
);
}
QVariant buffer_helpers::toVariant(const gpu::BufferView& view, quint32 index, bool asArray, const char* hint) {
const auto& element = view._element;
const auto vecN = element.getScalarCount();
@ -167,14 +174,17 @@ QVariant buffer_helpers::toVariant(const gpu::BufferView& view, quint32 index, b
auto byteOffset = index * vecN * BYTES_PER_ELEMENT;
auto maxByteOffset = (view._size - 1) * vecN * BYTES_PER_ELEMENT;
if (byteOffset > maxByteOffset) {
qDebug() << "bufferViewElementToVariant -- byteOffset out of range " << byteOffset << " < " << maxByteOffset << DebugNames::stringFrom(dataType);
qDebug() << "bufferViewElementToVariant -- index: " << index << "numElements" << view.getNumElements();
qDebug() << "bufferViewElementToVariant -- vecN: " << vecN << "byteLength" << byteLength << "BYTES_PER_ELEMENT" << BYTES_PER_ELEMENT;
#ifdef DEBUG_BUFFERVIEW_SCRIPTING
qDebug() << "toVariant -- " << DebugNames::stringFrom(dataType)
#endif
qDebug() << "toVariant -- byteOffset out of range " << byteOffset << " < " << maxByteOffset;
qDebug() << "toVariant -- index: " << index << "numElements" << view.getNumElements();
qDebug() << "toVariant -- vecN: " << vecN << "byteLength" << byteLength << "BYTES_PER_ELEMENT" << BYTES_PER_ELEMENT;
}
Q_ASSERT(byteOffset <= maxByteOffset);
}
#ifdef DEBUG_BUFFERVIEW_SCRIPTING
qCDebug(bufferhelper_logging) << "bufferViewElementToVariant" << index << DebugNames::stringFrom(dataType) << BYTES_PER_ELEMENT << vecN;
qCDebug(bufferhelper_logging) << "toVariant -- " << index << DebugNames::stringFrom(dataType) << BYTES_PER_ELEMENT << vecN;
#endif
if (BYTES_PER_ELEMENT == 1) {
switch(vecN) {
@ -223,7 +233,7 @@ QVariant buffer_helpers::toVariant(const gpu::BufferView& view, quint32 index, b
}
template <typename T>
QVariant glmVecToVariant(const T& v, bool asArray /*= false*/) {
QVariant buffer_helpers::glmVecToVariant(const T& v, bool asArray /*= false*/) {
static const auto len = T().length();
if (asArray) {
QVariantList list;
@ -239,8 +249,9 @@ QVariant glmVecToVariant(const T& v, bool asArray /*= false*/) {
return obj;
}
}
template <typename T>
const T glmVecFromVariant(const QVariant& v) {
const T buffer_helpers::glmVecFromVariant(const QVariant& v) {
auto isMap = v.type() == (QVariant::Type)QMetaType::QVariantMap;
static const auto len = T().length();
const auto& components = isMap ? XYZW : ZERO123;
@ -255,9 +266,11 @@ const T glmVecFromVariant(const QVariant& v) {
} else {
value = list.value(i).toFloat();
}
#ifdef DEBUG_BUFFERVIEW_SCRIPTING
if (value != value) { // NAN
qWarning().nospace()<< "vec" << len << "." << components[i] << " NAN received from script.... " << v.toString();
}
#endif
result[i] = value;
}
return result;
@ -268,17 +281,26 @@ gpu::BufferView buffer_helpers::fromVector(const QVector<T>& elements, const gpu
auto vertexBuffer = std::make_shared<gpu::Buffer>(elements.size() * sizeof(T), (gpu::Byte*)elements.data());
return { vertexBuffer, 0, vertexBuffer->getSize(),sizeof(T), elementType };
}
template<> gpu::BufferView buffer_helpers::fromVector<unsigned int>(const QVector<unsigned int>& elements, const gpu::Element& elementType) { return fromVector(elements, elementType); }
template<> gpu::BufferView buffer_helpers::fromVector<glm::vec3>(const QVector<glm::vec3>& elements, const gpu::Element& elementType) { return fromVector(elements, elementType); }
template<> gpu::BufferView buffer_helpers::fromVector<unsigned int>(
const QVector<unsigned int>& elements, const gpu::Element& elementType
) { return fromVector(elements, elementType); }
template <typename T> struct GpuVec4ToGlm;// { static T get(const gpu::BufferView& view, quint32 index, const char *hint); };
template <typename T> struct getScalar;// { static T get(const gpu::BufferView& view, quint32 index, const char *hint); };
template<> gpu::BufferView buffer_helpers::fromVector<glm::vec3>(
const QVector<glm::vec3>& elements, const gpu::Element& elementType
) { return fromVector(elements, elementType); }
template <typename T> struct GpuVec4ToGlm;
template <typename T> struct GpuScalarToGlm;
struct GpuToGlmAdapter {
static float error(const QString& name, const gpu::BufferView& view, quint32 index, const char *hint) {
QString debugName;
#ifdef DEBUG_BUFFERVIEW_SCRIPTING
debugName = DebugNames::stringFrom(view._element.getType())
#endif
qDebug() << QString("GpuToGlmAdapter:: unhandled type=%1(element=%2(%3)) size=%4(per=%5) vec%6 hint=%7 #%8")
.arg(name)
.arg(DebugNames::stringFrom(view._element.getType()))
.arg(debugName)
.arg(view._element.getType())
.arg(view._element.getSize())
.arg(view._element.getSize() / view._element.getScalarCount())
@ -290,7 +312,8 @@ struct GpuToGlmAdapter {
return NAN;
}
};
template <typename T> struct getScalar : GpuToGlmAdapter {
template <typename T> struct GpuScalarToGlm : GpuToGlmAdapter {
static T get(const gpu::BufferView& view, quint32 index, const char *hint) { switch(view._element.getType()) {
case gpu::UINT32: return view.get<glm::uint32>(index);
case gpu::UINT16: return view.get<glm::uint16>(index);
@ -301,7 +324,7 @@ template <typename T> struct getScalar : GpuToGlmAdapter {
case gpu::FLOAT: return view.get<glm::float32>(index);
case gpu::HALF: return T(glm::unpackSnorm1x8(view.get<glm::int8>(index)));
default: break;
} return T(error("getScalar", view, index, hint));
} return T(error("GpuScalarToGlm", view, index, hint));
}
};
@ -376,8 +399,9 @@ struct getVec {
}
};
// BufferView => QVector<T>
template <> QVector<int> buffer_helpers::toVector<int>(const gpu::BufferView& view, const char *hint) {
return getVec<getScalar<int>,int>::__to_vector__(view, hint);
return getVec<GpuScalarToGlm<int>,int>::__to_vector__(view, hint);
}
template <> QVector<glm::vec2> buffer_helpers::toVector<glm::vec2>(const gpu::BufferView& view, const char *hint) {
return getVec<GpuVec2ToGlm<glm::vec2>,glm::vec2>::__to_vector__(view, hint);
@ -390,8 +414,9 @@ template <> QVector<glm::vec4> buffer_helpers::toVector<glm::vec4>(const gpu::Bu
}
// indexed conversion accessors (similar to "view.convert<T>(i)" existed)
template <> int buffer_helpers::convert<int>(const gpu::BufferView& view, quint32 index, const char *hint) {
return getVec<getScalar<int>,int>::__to_scalar__(view, index, hint);
return getVec<GpuScalarToGlm<int>,int>::__to_scalar__(view, index, hint);
}
template <> glm::vec2 buffer_helpers::convert<glm::vec2>(const gpu::BufferView& view, quint32 index, const char *hint) {
return getVec<GpuVec2ToGlm<glm::vec2>,glm::vec2>::__to_scalar__(view, index, hint);
@ -407,30 +432,25 @@ gpu::BufferView buffer_helpers::clone(const gpu::BufferView& input) {
return gpu::BufferView(
std::make_shared<gpu::Buffer>(input._buffer->getSize(), input._buffer->getData()),
input._offset, input._size, input._stride, input._element
);
);
}
// TODO: preserve existing data
gpu::BufferView buffer_helpers::resize(const gpu::BufferView& input, quint32 numElements) {
auto effectiveSize = input._buffer->getSize() / input.getNumElements();
qDebug() << "resize input" << input.getNumElements() << input._buffer->getSize() << "effectiveSize" << effectiveSize;
qCDebug(bufferhelper_logging) << "resize input" << input.getNumElements() << input._buffer->getSize() << "effectiveSize" << effectiveSize;
auto vsize = input._element.getSize() * numElements;
gpu::Byte *data = new gpu::Byte[vsize];
memset(data, 0, vsize);
auto buffer = new gpu::Buffer(vsize, (gpu::Byte*)data);
delete[] data;
std::unique_ptr<gpu::Byte[]> data{ new gpu::Byte[vsize] };
memset(data.get(), 0, vsize);
auto buffer = new gpu::Buffer(vsize, data.get());
auto output = gpu::BufferView(buffer, input._element);
qDebug() << "resized output" << output.getNumElements() << output._buffer->getSize();
qCDebug(bufferhelper_logging) << "resized output" << output.getNumElements() << output._buffer->getSize();
return output;
}
graphics::MeshPointer buffer_helpers::cloneMesh(graphics::MeshPointer mesh) {
auto clone = std::make_shared<graphics::Mesh>();
//[](graphics::Mesh* blah) {
//qCDebug(bufferhelper_logging) << "--- DELETING MESH POINTER" << blah;
// delete blah;
//});
clone->displayName = (QString::fromStdString(mesh->displayName) + "-clone").toStdString();
//qCInfo(bufferhelper_logging) << "+++ ALLOCATED MESH POINTER ScriptableMesh::cloneMesh" << clone->displayName << clone.get() << !!mesh;
clone->setIndexBuffer(buffer_helpers::clone(mesh->getIndexBuffer()));
clone->setPartBuffer(buffer_helpers::clone(mesh->getPartBuffer()));
auto attributeViews = buffer_helpers::gatherBufferViews(mesh);
@ -447,18 +467,11 @@ graphics::MeshPointer buffer_helpers::cloneMesh(graphics::MeshPointer mesh) {
return clone;
}
/// --- buffer view <-> variant helpers
namespace {
// expand the corresponding attribute buffer (creating it if needed) so that it matches POSITIONS size and specified element type
gpu::BufferView _expandedAttributeBuffer(const graphics::MeshPointer mesh, gpu::Stream::Slot slot) {
gpu::BufferView bufferView = buffer_helpers::getBufferView(mesh, slot);
const auto& elementType = bufferView._element;
//auto vecN = element.getScalarCount();
//auto type = element.getType();
//gpu::Element elementType = getVecNElement(type, vecN);
gpu::Size elementSize = elementType.getSize();
auto nPositions = mesh->getNumVertices();
auto vsize = nPositions * elementSize;
@ -478,10 +491,9 @@ namespace {
if (bufferView.getNumElements() < nPositions || diffTypes) {
if (!bufferView._buffer || bufferView.getNumElements() == 0) {
qCInfo(bufferhelper_logging).nospace() << "ScriptableMesh -- adding missing mesh attribute '" << hint << "' for BufferView";
gpu::Byte *data = new gpu::Byte[vsize];
memset(data, 0, vsize);
auto buffer = new gpu::Buffer(vsize, (gpu::Byte*)data);
delete[] data;
std::unique_ptr<gpu::Byte[]> data{ new gpu::Byte[vsize] };
memset(data.get(), 0, vsize);
auto buffer = new gpu::Buffer(vsize, data.get());
bufferView = gpu::BufferView(buffer, elementType);
mesh->addAttribute(slot, bufferView);
} else {
@ -553,7 +565,6 @@ std::map<QString, gpu::BufferView> buffer_helpers::gatherBufferViews(graphics::M
return attributeViews;
}
bool buffer_helpers::recalculateNormals(graphics::MeshPointer mesh) {
qCInfo(bufferhelper_logging) << "Recalculating normals" << !!mesh;
if (!mesh) {
@ -567,10 +578,8 @@ bool buffer_helpers::recalculateNormals(graphics::MeshPointer mesh) {
auto numPoints = indices.getNumElements();
const auto TRIANGLE = 3;
quint32 numFaces = (quint32)numPoints / TRIANGLE;
//QVector<Triangle> faces;
QVector<glm::vec3> faceNormals;
QMap<QString,QVector<quint32>> vertexToFaces;
//faces.resize(numFaces);
faceNormals.resize(numFaces);
auto numNormals = normals.getNumElements();
qCInfo(bufferhelper_logging) << QString("numFaces: %1, numNormals: %2, numPoints: %3").arg(numFaces).arg(numNormals).arg(numPoints);
@ -590,7 +599,9 @@ bool buffer_helpers::recalculateNormals(graphics::MeshPointer mesh) {
};
faceNormals[i] = face.getNormal();
if (glm::isnan(faceNormals[i].x)) {
#ifdef DEBUG_BUFFERVIEW_SCRIPTING
qCInfo(bufferhelper_logging) << i << i0 << i1 << i2 << glmVecToVariant(face.v0) << glmVecToVariant(face.v1) << glmVecToVariant(face.v2);
#endif
break;
}
vertexToFaces[glm::to_string(face.v0).c_str()] << i;
@ -615,10 +626,12 @@ bool buffer_helpers::recalculateNormals(graphics::MeshPointer mesh) {
normal = verts.get<glm::vec3>(j);
}
if (glm::isnan(normal.x)) {
#ifdef DEBUG_BUFFERVIEW_SCRIPTING
static int logged = 0;
if (logged++ < 10) {
qCInfo(bufferhelper_logging) << "isnan(normal.x)" << j << glmVecToVariant(normal);
}
#endif
break;
}
buffer_helpers::fromVariant(normals, j, glmVecToVariant(glm::normalize(normal)));

View file

@ -15,9 +15,6 @@ namespace gpu {
class Element;
}
template <typename T> QVariant glmVecToVariant(const T& v, bool asArray = false);
template <typename T> const T glmVecFromVariant(const QVariant& v);
namespace graphics {
class Mesh;
using MeshPointer = std::shared_ptr<Mesh>;
@ -27,6 +24,9 @@ class Extents;
class AABox;
struct buffer_helpers {
template <typename T> static QVariant glmVecToVariant(const T& v, bool asArray = false);
template <typename T> static const T glmVecFromVariant(const QVariant& v);
static graphics::MeshPointer cloneMesh(graphics::MeshPointer mesh);
static QMap<QString,int> ATTRIBUTES;
static std::map<QString, gpu::BufferView> gatherBufferViews(graphics::MeshPointer mesh, const QStringList& expandToMatchPositions = QStringList());

View file

@ -9,10 +9,6 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include <QtCore/QLoggingCategory>
namespace { QLoggingCategory wtf{ "tim.Model.cpp" }; }
#include "Model.h"
#include <QMetaType>
@ -31,7 +27,7 @@ namespace { QLoggingCategory wtf{ "tim.Model.cpp" }; }
#include <TBBHelpers.h>
#include <graphics-scripting/Forward.h>
#include <graphics-scripting/BufferViewHelpers.h>
#include <graphics/BufferViewHelpers.h>
#include <DualQuaternion.h>
#include <glm/gtc/packing.hpp>
@ -372,7 +368,7 @@ bool Model::updateGeometry() {
#if FBX_PACK_NORMALS
glm::uint32 finalNormal;
glm::uint32 finalTangent;
packNormalAndTangent(*normalIt, *tangentIt, finalNormal, finalTangent);
buffer_helpers::packNormalAndTangent(*normalIt, *tangentIt, finalNormal, finalTangent);
#else
const auto finalNormal = *normalIt;
const auto finalTangent = *tangentIt;
@ -569,25 +565,15 @@ bool Model::replaceScriptableModelMeshPart(scriptable::ScriptableModelBasePointe
auto newRenderGeometry = new MyGeometryMappingResource(
_url, _renderGeometry, _newModel ? scriptable::make_qtowned<scriptable::ScriptableModelBase>(*_newModel) : nullptr
);
//_needsUpdateTextures = true;
_visualGeometryRequestFailed = false;
//invalidCalculatedMeshBoxes();
deleteGeometry();
_renderGeometry.reset(newRenderGeometry);
//onInvalidate();
//reset();
_rig.destroyAnimGraph();
//assert(_rig.jointStatesEmpty());
updateGeometry();
calculateTriangleSets();
//computeMeshPartLocalBounds();
//_needsReload = false;
_needsReload = false;
_needsFixupInScene = true;
//invalidCalculatedMeshBoxes();
setRenderItemsNeedUpdate();
//_hasCalculatedTextureInfo = false;
//calculateTextureInfo();
//updateRenderItems();
}
return true;
}
@ -597,7 +583,7 @@ scriptable::ScriptableModelBase Model::getScriptableModel(bool* ok) {
scriptable::ScriptableModelBase result;
if (!isLoaded()) {
qCDebug(wtf) << "Model::getScriptableModel -- !isLoaded";
qCDebug(renderutils) << "Model::getScriptableModel -- !isLoaded";
return scriptable::ModelProvider::modelUnavailableError(ok);
}

View file

@ -1,15 +1,7 @@
#include <graphics-scripting/BufferViewHelpers.h>
#include <graphics/BufferViewHelpers.h>
#include <graphics-scripting/GraphicsScriptingUtil.h>
class MyGeometryMappingResource : public GeometryResource {
// Q_OBJECT
public:
virtual void init(bool resetLoaded = true) override {
qCDebug(wtf) << "############################# Snarfing init()...";
}
virtual void deleter() override {
qCDebug(wtf) << "############################# Snarfing deleter()...";
}
shared_ptr<FBXGeometry> fbxGeometry;
MyGeometryMappingResource(const QUrl& url, Geometry::Pointer originalGeometry, std::shared_ptr<scriptable::ScriptableModelBase> newModel) : GeometryResource(url) {
fbxGeometry = std::make_shared<FBXGeometry>();
@ -77,6 +69,8 @@ public:
mesh.colors = buffer_helpers::toVector<glm::vec3>(buffer_helpers::getBufferView(mesh._mesh, gpu::Stream::COLOR), "mesh.colors");
mesh.texCoords = buffer_helpers::toVector<glm::vec2>(buffer_helpers::getBufferView(mesh._mesh, gpu::Stream::TEXCOORD0), "mesh.texCoords");
mesh.texCoords1 = buffer_helpers::toVector<glm::vec2>(buffer_helpers::getBufferView(mesh._mesh, gpu::Stream::TEXCOORD1), "mesh.texCoords1");
mesh.createMeshTangents(true);
mesh.createBlendShapeTangents(false);
geometry.meshes << mesh;
// Copy mesh pointers
meshes->emplace_back(newMesh.getMeshPointer());//buffer_helpers::cloneMesh(ptr));
@ -84,10 +78,9 @@ public:
const auto oldParts = mesh.parts;
mesh.parts.clear();
for (const FBXMeshPart& fbxPart : oldParts) {
FBXMeshPart part; // copy;
FBXMeshPart part; // new copy
part.materialID = fbxPart.materialID;
// Construct local parts
///qCDebug(wtf) << "GeometryMappingResource -- meshes part" << meshID << partID << part.materialID;
part.triangleIndices = buffer_helpers::toVector<int>(mesh._mesh->getIndexBuffer(), "part.triangleIndices");
mesh.parts << part;
auto p = std::make_shared<MeshPart>(meshID, partID, (int)materialIDAtlas[part.materialID]);
@ -115,7 +108,6 @@ public:
_animGraphOverrideUrl = originalGeometry ? originalGeometry->getAnimGraphOverrideUrl() : QUrl();
_loaded = true;
_fbxGeometry = fbxGeometry;
finishedLoading(true);
};
};