mirror of
https://github.com/overte-org/overte.git
synced 2025-08-10 00:36:30 +02:00
CR fedback and cleanup
This commit is contained in:
parent
caab532d80
commit
e4a2a589a5
15 changed files with 159 additions and 221 deletions
|
@ -607,7 +607,7 @@ void messageHandler(QtMsgType type, const QMessageLogContext& context, const QSt
|
||||||
|
|
||||||
class ApplicationMeshProvider : public scriptable::ModelProviderFactory {
|
class ApplicationMeshProvider : public scriptable::ModelProviderFactory {
|
||||||
public:
|
public:
|
||||||
virtual scriptable::ModelProviderPointer lookupModelProvider(QUuid uuid) {
|
virtual scriptable::ModelProviderPointer lookupModelProvider(const QUuid& uuid) {
|
||||||
QString error;
|
QString error;
|
||||||
|
|
||||||
scriptable::ModelProviderPointer provider;
|
scriptable::ModelProviderPointer provider;
|
||||||
|
@ -631,7 +631,7 @@ public:
|
||||||
if (auto entity = entityTree->findEntityByID(entityID)) {
|
if (auto entity = entityTree->findEntityByID(entityID)) {
|
||||||
if (auto renderer = entityTreeRenderer->renderableForEntityId(entityID)) {
|
if (auto renderer = entityTreeRenderer->renderableForEntityId(entityID)) {
|
||||||
provider = std::dynamic_pointer_cast<scriptable::ModelProvider>(renderer);
|
provider = std::dynamic_pointer_cast<scriptable::ModelProvider>(renderer);
|
||||||
provider->metadata["providerType"] = "entity";
|
provider->modelProviderType = NestableType::Entity;
|
||||||
} else {
|
} else {
|
||||||
qCWarning(interfaceapp) << "no renderer for entity ID" << entityID.toString();
|
qCWarning(interfaceapp) << "no renderer for entity ID" << entityID.toString();
|
||||||
}
|
}
|
||||||
|
@ -645,7 +645,7 @@ public:
|
||||||
if (auto overlay = overlays.getOverlay(overlayID)) {
|
if (auto overlay = overlays.getOverlay(overlayID)) {
|
||||||
if (auto base3d = std::dynamic_pointer_cast<Base3DOverlay>(overlay)) {
|
if (auto base3d = std::dynamic_pointer_cast<Base3DOverlay>(overlay)) {
|
||||||
provider = std::dynamic_pointer_cast<scriptable::ModelProvider>(base3d);
|
provider = std::dynamic_pointer_cast<scriptable::ModelProvider>(base3d);
|
||||||
provider->metadata["providerType"] = "overlay";
|
provider->modelProviderType = NestableType::Overlay;
|
||||||
} else {
|
} else {
|
||||||
qCWarning(interfaceapp) << "no renderer for overlay ID" << overlayID.toString();
|
qCWarning(interfaceapp) << "no renderer for overlay ID" << overlayID.toString();
|
||||||
}
|
}
|
||||||
|
@ -659,7 +659,7 @@ public:
|
||||||
if (auto avatar = avatarManager->getAvatarBySessionID(sessionUUID)) {
|
if (auto avatar = avatarManager->getAvatarBySessionID(sessionUUID)) {
|
||||||
if (avatar->getSessionUUID() == sessionUUID) {
|
if (avatar->getSessionUUID() == sessionUUID) {
|
||||||
provider = std::dynamic_pointer_cast<scriptable::ModelProvider>(avatar);
|
provider = std::dynamic_pointer_cast<scriptable::ModelProvider>(avatar);
|
||||||
provider->metadata["providerType"] = "avatar";
|
provider->modelProviderType = NestableType::Avatar;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return provider;
|
return provider;
|
||||||
|
@ -811,6 +811,7 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) {
|
||||||
DependencyManager::set<ResourceCacheSharedItems>();
|
DependencyManager::set<ResourceCacheSharedItems>();
|
||||||
DependencyManager::set<DesktopScriptingInterface>();
|
DependencyManager::set<DesktopScriptingInterface>();
|
||||||
DependencyManager::set<EntityScriptingInterface>(true);
|
DependencyManager::set<EntityScriptingInterface>(true);
|
||||||
|
DependencyManager::set<GraphicsScriptingInterface>();
|
||||||
DependencyManager::registerInheritance<scriptable::ModelProviderFactory, ApplicationMeshProvider>();
|
DependencyManager::registerInheritance<scriptable::ModelProviderFactory, ApplicationMeshProvider>();
|
||||||
DependencyManager::set<ApplicationMeshProvider>();
|
DependencyManager::set<ApplicationMeshProvider>();
|
||||||
DependencyManager::set<RecordingScriptingInterface>();
|
DependencyManager::set<RecordingScriptingInterface>();
|
||||||
|
|
|
@ -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) {
|
void ModelOverlay::removeFromScene(Overlay::Pointer overlay, const render::ScenePointer& scene, render::Transaction& transaction) {
|
||||||
Volume3DOverlay::removeFromScene(overlay, scene, transaction);
|
Volume3DOverlay::removeFromScene(overlay, scene, transaction);
|
||||||
_model->removeFromScene(scene, transaction);
|
_model->removeFromScene(scene, transaction);
|
||||||
|
emit DependencyManager::get<scriptable::ModelProviderFactory>()->modelRemovedFromScene(getID(), NestableType::Overlay, _model);
|
||||||
transaction.updateItem<Overlay>(getRenderItemID(), [](Overlay& data) {
|
transaction.updateItem<Overlay>(getRenderItemID(), [](Overlay& data) {
|
||||||
auto modelOverlay = static_cast<ModelOverlay*>(&data);
|
auto modelOverlay = static_cast<ModelOverlay*>(&data);
|
||||||
modelOverlay->clearSubRenderItemIDs();
|
modelOverlay->clearSubRenderItemIDs();
|
||||||
|
|
|
@ -1073,14 +1073,8 @@ void ModelEntityRenderer::removeFromScene(const ScenePointer& scene, Transaction
|
||||||
|
|
||||||
void ModelEntityRenderer::onRemoveFromSceneTyped(const TypedEntityPointer& entity) {
|
void ModelEntityRenderer::onRemoveFromSceneTyped(const TypedEntityPointer& entity) {
|
||||||
entity->setModel({});
|
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) {
|
void ModelEntityRenderer::animate(const TypedEntityPointer& entity) {
|
||||||
if (!_animation || !_animation->isLoaded()) {
|
if (!_animation || !_animation->isLoaded()) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -242,6 +242,9 @@ public:
|
||||||
|
|
||||||
graphics::MeshPointer _mesh;
|
graphics::MeshPointer _mesh;
|
||||||
bool wasCompressed { false };
|
bool wasCompressed { false };
|
||||||
|
|
||||||
|
void createMeshTangents(bool generateFromTexCoords);
|
||||||
|
void createBlendShapeTangents(bool generateTangents);
|
||||||
};
|
};
|
||||||
|
|
||||||
class ExtractedMesh {
|
class ExtractedMesh {
|
||||||
|
|
|
@ -9,15 +9,14 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include "OBJWriter.h"
|
||||||
|
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include "graphics/Geometry.h"
|
#include <graphics/BufferViewHelpers.h>
|
||||||
#include "OBJWriter.h"
|
#include <graphics/Geometry.h>
|
||||||
#include "ModelFormatLogging.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) {
|
static QString formatFloat(double n) {
|
||||||
// limit precision to 6, but don't output trailing zeros.
|
// limit precision to 6, but don't output trailing zeros.
|
||||||
QString s = QString::number(n, 'f', 6);
|
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[1]) << " ";
|
||||||
out << formatFloat(v[2]);
|
out << formatFloat(v[2]);
|
||||||
if (colorIndex < numColors) {
|
if (colorIndex < numColors) {
|
||||||
glm::vec3 color = glmVecFromVariant<glm::vec3>(buffer_helpers::toVariant(colorsBufferView, colorIndex));
|
glm::vec3 color = buffer_helpers::convert<glm::vec3>(colorsBufferView, colorIndex);
|
||||||
//glm::vec3 color = colorsBufferView.get<glm::vec3>(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[0]);
|
||||||
out << " " << formatFloat(color[1]);
|
out << " " << formatFloat(color[1]);
|
||||||
out << " " << formatFloat(color[2]);
|
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);
|
const gpu::BufferView& normalsBufferView = mesh->getAttributeBuffer(gpu::Stream::InputSlot::NORMAL);
|
||||||
gpu::BufferView::Index numNormals = (gpu::BufferView::Index)normalsBufferView.getNumElements();
|
gpu::BufferView::Index numNormals = (gpu::BufferView::Index)normalsBufferView.getNumElements();
|
||||||
for (gpu::BufferView::Index i = 0; i < numNormals; i++) {
|
for (gpu::BufferView::Index i = 0; i < numNormals; i++) {
|
||||||
glm::vec3 normal = glmVecFromVariant<glm::vec3>(buffer_helpers::toVariant(normalsBufferView, i));
|
glm::vec3 normal = buffer_helpers::convert<glm::vec3>(normalsBufferView, i);
|
||||||
//glm::vec3 normal = normalsBufferView.get<glm::vec3>(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 << "vn ";
|
||||||
out << formatFloat(normal[0]) << " ";
|
out << formatFloat(normal[0]) << " ";
|
||||||
out << formatFloat(normal[1]) << " ";
|
out << formatFloat(normal[1]) << " ";
|
||||||
|
|
|
@ -2,4 +2,3 @@ set(TARGET_NAME graphics-scripting)
|
||||||
setup_hifi_library()
|
setup_hifi_library()
|
||||||
link_hifi_libraries(shared networking graphics fbx model-networking script-engine)
|
link_hifi_libraries(shared networking graphics fbx model-networking script-engine)
|
||||||
include_hifi_library_headers(gpu)
|
include_hifi_library_headers(gpu)
|
||||||
include_hifi_library_headers(graphics-scripting)
|
|
||||||
|
|
|
@ -9,10 +9,10 @@
|
||||||
#include <gpu/Format.h>
|
#include <gpu/Format.h>
|
||||||
#include <gpu/Stream.h>
|
#include <gpu/Stream.h>
|
||||||
|
|
||||||
#include <graphics-scripting/BufferViewHelpers.h>
|
#include <graphics/BufferViewHelpers.h>
|
||||||
|
|
||||||
#ifdef DEBUG_BUFFERVIEW_SCRIPTING
|
#ifdef DEBUG_BUFFERVIEW_SCRIPTING
|
||||||
#include <graphics/DebugNames.h>
|
#include "DebugNames.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
//
|
//
|
||||||
// GraphicsScriptingInterface.cpp
|
// GraphicsScriptingInterface.cpp
|
||||||
// libraries/script-engine/src
|
// libraries/graphics-scripting/src
|
||||||
//
|
//
|
||||||
// Created by Seth Alves on 2017-1-27.
|
|
||||||
// Copyright 2017 High Fidelity, Inc.
|
// Copyright 2017 High Fidelity, Inc.
|
||||||
//
|
//
|
||||||
// Distributed under the Apache License, Version 2.0.
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
@ -10,28 +9,24 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "GraphicsScriptingInterface.h"
|
#include "GraphicsScriptingInterface.h"
|
||||||
#include <QtScript/QScriptEngine>
|
|
||||||
#include <QtScript/QScriptValueIterator>
|
|
||||||
#include <QtScript/QScriptValue>
|
|
||||||
#include <QUuid>
|
|
||||||
#include "BaseScriptEngine.h"
|
#include "BaseScriptEngine.h"
|
||||||
#include "ScriptEngineLogging.h"
|
#include "BufferViewScripting.h"
|
||||||
|
#include "DebugNames.h"
|
||||||
|
#include "GraphicsScriptingUtil.h"
|
||||||
#include "OBJWriter.h"
|
#include "OBJWriter.h"
|
||||||
|
#include "RegisteredMetaTypes.h"
|
||||||
|
#include "ScriptEngineLogging.h"
|
||||||
|
#include "ScriptableMesh.h"
|
||||||
#include <GeometryUtil.h>
|
#include <GeometryUtil.h>
|
||||||
|
#include <QUuid>
|
||||||
|
#include <QtScript/QScriptEngine>
|
||||||
|
#include <QtScript/QScriptValue>
|
||||||
|
#include <QtScript/QScriptValueIterator>
|
||||||
|
#include <graphics/BufferViewHelpers.h>
|
||||||
#include <shared/QtHelpers.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 "GraphicsScriptingInterface.moc"
|
||||||
|
|
||||||
#include "RegisteredMetaTypes.h"
|
|
||||||
|
|
||||||
GraphicsScriptingInterface::GraphicsScriptingInterface(QObject* parent) : QObject(parent) {
|
GraphicsScriptingInterface::GraphicsScriptingInterface(QObject* parent) : QObject(parent) {
|
||||||
if (auto scriptEngine = qobject_cast<QScriptEngine*>(parent)) {
|
if (auto scriptEngine = qobject_cast<QScriptEngine*>(parent)) {
|
||||||
this->registerMetaTypes(scriptEngine);
|
this->registerMetaTypes(scriptEngine);
|
||||||
|
|
|
@ -12,12 +12,15 @@ Q_DECLARE_LOGGING_CATEGORY(graphics_scripting)
|
||||||
|
|
||||||
namespace scriptable {
|
namespace scriptable {
|
||||||
// derive current context's C++ QObject (based on current JS "this" value)
|
// 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;
|
auto context = engine ? engine->currentContext() : nullptr;
|
||||||
return qscriptvalue_cast<T>(context ? context->thisObject() : QScriptValue::NullValue);
|
return qscriptvalue_cast<T>(context ? context->thisObject() : QScriptValue::NullValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
// JS => QPointer<QObject>
|
// 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();
|
auto obj = value.toQObject();
|
||||||
#ifdef SCRIPTABLE_MESH_DEBUG
|
#ifdef SCRIPTABLE_MESH_DEBUG
|
||||||
qCInfo(graphics_scripting) << "qpointer_qobject_cast" << obj << value.toString();
|
qCInfo(graphics_scripting) << "qpointer_qobject_cast" << obj << value.toString();
|
||||||
|
@ -41,54 +44,21 @@ namespace scriptable {
|
||||||
}
|
}
|
||||||
|
|
||||||
// C++ > QtOwned instance
|
// 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...);
|
T* tmp = new T(rest...);
|
||||||
#ifdef SCRIPTABLE_MESH_DEBUG
|
|
||||||
qCInfo(graphics_scripting) << "scriptable::make_qtowned" << toDebugString(tmp);
|
|
||||||
#endif
|
|
||||||
QString debug = toDebugString(tmp);
|
|
||||||
if (tmp) {
|
if (tmp) {
|
||||||
tmp->metadata["__ownership__"] = QScriptEngine::QtOwnership;
|
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
|
// 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...);
|
T* tmp = new T(rest...);
|
||||||
#ifdef SCRIPTABLE_MESH_DEBUG
|
|
||||||
qCInfo(graphics_scripting) << "scriptable::make_scriptowned" << toDebugString(tmp);
|
|
||||||
#endif
|
|
||||||
if (tmp) {
|
if (tmp) {
|
||||||
tmp->metadata["__ownership__"] = QScriptEngine::ScriptOwnership;
|
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);
|
return QPointer<T>(tmp);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,41 +1,26 @@
|
||||||
//
|
//
|
||||||
// SimpleMeshProxy.cpp
|
// Copyright 2018 High Fidelity, Inc.
|
||||||
// libraries/model-networking/src/model-networking/
|
|
||||||
//
|
|
||||||
// Created by Seth Alves on 2017-3-22.
|
|
||||||
// Copyright 2017 High Fidelity, Inc.
|
|
||||||
//
|
//
|
||||||
// Distributed under the Apache License, Version 2.0.
|
// Distributed under the Apache License, Version 2.0.
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "GraphicsScriptingUtil.h"
|
|
||||||
#include "ScriptableMesh.h"
|
#include "ScriptableMesh.h"
|
||||||
|
|
||||||
#include <glm/glm.hpp>
|
#include "BufferViewScripting.h"
|
||||||
#include <glm/gtx/transform.hpp>
|
#include "DebugNames.h"
|
||||||
#include <glm/gtx/norm.hpp>
|
#include "GraphicsScriptingUtil.h"
|
||||||
#include <graphics/Geometry.h>
|
#include "OBJWriter.h"
|
||||||
#include <graphics-scripting/DebugNames.h>
|
|
||||||
#include <graphics-scripting/BufferViewHelpers.h>
|
|
||||||
#include <graphics-scripting/BufferViewScripting.h>
|
|
||||||
|
|
||||||
#include "ScriptableMesh.moc"
|
|
||||||
|
|
||||||
#include <RegisteredMetaTypes.h>
|
|
||||||
#include <BaseScriptEngine.h>
|
#include <BaseScriptEngine.h>
|
||||||
#include <QtScript/QScriptValue>
|
#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"
|
#include "ScriptableMesh.moc"
|
||||||
|
|
||||||
// #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);
|
|
||||||
}
|
|
||||||
|
|
||||||
scriptable::ScriptableMeshPart::ScriptableMeshPart(scriptable::ScriptableMeshPointer parentMesh, int partIndex)
|
scriptable::ScriptableMeshPart::ScriptableMeshPart(scriptable::ScriptableMeshPointer parentMesh, int partIndex)
|
||||||
: parentMesh(parentMesh), partIndex(partIndex) {
|
: parentMesh(parentMesh), partIndex(partIndex) {
|
||||||
|
|
|
@ -1,26 +1,22 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <glm/glm.hpp>
|
#include "ScriptableModel.h"
|
||||||
#include <QtCore/QObject>
|
|
||||||
#include <QtCore/QVector>
|
|
||||||
#include <QtCore/QList>
|
|
||||||
#include <QtCore/QVariant>
|
|
||||||
#include <QtCore/QUuid>
|
|
||||||
#include <QPointer>
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <graphics/BufferViewHelpers.h>
|
||||||
#include <DependencyManager.h>
|
#include <DependencyManager.h>
|
||||||
|
|
||||||
//#include <graphics-scriping/Forward.h>
|
#include <memory>
|
||||||
#include <graphics-scripting/ScriptableModel.h>
|
#include <QPointer>
|
||||||
#include <graphics-scripting/BufferViewHelpers.h>
|
#include <QtCore/QList>
|
||||||
|
#include <QtCore/QObject>
|
||||||
#include <QtScript/QScriptable>
|
#include <QtCore/QUuid>
|
||||||
|
#include <QtCore/QVariant>
|
||||||
|
#include <QtCore/QVector>
|
||||||
#include <QtScript/QScriptValue>
|
#include <QtScript/QScriptValue>
|
||||||
|
#include <QtScript/QScriptable>
|
||||||
|
|
||||||
namespace scriptable {
|
namespace scriptable {
|
||||||
|
|
||||||
QScriptValue jsBindCallback(QScriptValue callback);
|
|
||||||
class ScriptableMesh : public ScriptableMeshBase, QScriptable {
|
class ScriptableMesh : public ScriptableMeshBase, QScriptable {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -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 <QDebug>
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
|
@ -7,7 +14,7 @@
|
||||||
#include <gpu/Format.h>
|
#include <gpu/Format.h>
|
||||||
#include <gpu/Stream.h>
|
#include <gpu/Stream.h>
|
||||||
|
|
||||||
#include <graphics/Geometry.h>
|
#include "Geometry.h"
|
||||||
|
|
||||||
#include <Extents.h>
|
#include <Extents.h>
|
||||||
#include <AABox.h>
|
#include <AABox.h>
|
||||||
|
@ -15,25 +22,26 @@
|
||||||
#include <glm/gtx/string_cast.hpp>
|
#include <glm/gtx/string_cast.hpp>
|
||||||
#include <glm/gtc/packing.hpp>
|
#include <glm/gtc/packing.hpp>
|
||||||
#include <glm/detail/type_vec.hpp>
|
#include <glm/detail/type_vec.hpp>
|
||||||
|
|
||||||
namespace glm {
|
namespace glm {
|
||||||
using hvec2 = glm::tvec2<glm::detail::hdata>;
|
using hvec2 = glm::tvec2<glm::detail::hdata>;
|
||||||
using hvec4 = glm::tvec4<glm::detail::hdata>;
|
using hvec4 = glm::tvec4<glm::detail::hdata>;
|
||||||
}
|
}
|
||||||
|
|
||||||
//#define DEBUG_BUFFERVIEW_SCRIPTING
|
#ifdef DEBUG_BUFFERVIEW_SCRIPTING
|
||||||
//#ifdef DEBUG_BUFFERVIEW_SCRIPTING
|
#include "../../graphics-scripting/src/graphics-scripting/DebugNames.h"
|
||||||
#include "DebugNames.h"
|
#endif
|
||||||
//#endif
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
QLoggingCategory bufferhelper_logging{"hifi.bufferview"};
|
QLoggingCategory bufferhelper_logging{ "hifi.bufferview" };
|
||||||
const std::array<const char*, 4> XYZW = {{ "x", "y", "z", "w" }};
|
const std::array<const char*, 4> XYZW = { { "x", "y", "z", "w" } };
|
||||||
const std::array<const char*, 4> ZERO123 = {{ "0", "1", "2", "3" }};
|
const std::array<const char*, 4> ZERO123 = { { "0", "1", "2", "3" } };
|
||||||
}
|
}
|
||||||
|
|
||||||
gpu::BufferView buffer_helpers::getBufferView(graphics::MeshPointer mesh, gpu::Stream::Slot slot) {
|
gpu::BufferView buffer_helpers::getBufferView(graphics::MeshPointer mesh, gpu::Stream::Slot slot) {
|
||||||
return slot == gpu::Stream::POSITION ? mesh->getVertexBuffer() : mesh->getAttributeBuffer(slot);
|
return slot == gpu::Stream::POSITION ? mesh->getVertexBuffer() : mesh->getAttributeBuffer(slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
QMap<QString,int> buffer_helpers::ATTRIBUTES{
|
QMap<QString,int> buffer_helpers::ATTRIBUTES{
|
||||||
{"position", gpu::Stream::POSITION },
|
{"position", gpu::Stream::POSITION },
|
||||||
{"normal", gpu::Stream::NORMAL },
|
{"normal", gpu::Stream::NORMAL },
|
||||||
|
@ -49,16 +57,23 @@ QMap<QString,int> buffer_helpers::ATTRIBUTES{
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
namespace {
|
||||||
QVariant getBufferViewElement(const gpu::BufferView& view, quint32 index, bool asArray = false) {
|
bool boundsCheck(const gpu::BufferView& view, quint32 index) {
|
||||||
return glmVecToVariant(view.get<T>(index), asArray);
|
const auto byteLength = view._element.getSize();
|
||||||
}
|
return (
|
||||||
|
index < view.getNumElements() &&
|
||||||
|
index * byteLength < (view._size - 1) * byteLength
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T> QVariant getBufferViewElement(const gpu::BufferView& view, quint32 index, bool asArray = false) {
|
||||||
void setBufferViewElement(const gpu::BufferView& view, quint32 index, const QVariant& v) {
|
return buffer_helpers::glmVecToVariant(view.get<T>(index), asArray);
|
||||||
view.edit<T>(index) = glmVecFromVariant<T>(v);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
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) {
|
void buffer_helpers::packNormalAndTangent(glm::vec3 normal, glm::vec3 tangent, glm::uint32& packedNormal, glm::uint32& packedTangent) {
|
||||||
auto absNormal = glm::abs(normal);
|
auto absNormal = glm::abs(normal);
|
||||||
|
@ -147,14 +162,6 @@ bool buffer_helpers::fromVariant(const gpu::BufferView& view, quint32 index, con
|
||||||
return false;
|
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) {
|
QVariant buffer_helpers::toVariant(const gpu::BufferView& view, quint32 index, bool asArray, const char* hint) {
|
||||||
const auto& element = view._element;
|
const auto& element = view._element;
|
||||||
const auto vecN = element.getScalarCount();
|
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 byteOffset = index * vecN * BYTES_PER_ELEMENT;
|
||||||
auto maxByteOffset = (view._size - 1) * vecN * BYTES_PER_ELEMENT;
|
auto maxByteOffset = (view._size - 1) * vecN * BYTES_PER_ELEMENT;
|
||||||
if (byteOffset > maxByteOffset) {
|
if (byteOffset > maxByteOffset) {
|
||||||
qDebug() << "bufferViewElementToVariant -- byteOffset out of range " << byteOffset << " < " << maxByteOffset << DebugNames::stringFrom(dataType);
|
#ifdef DEBUG_BUFFERVIEW_SCRIPTING
|
||||||
qDebug() << "bufferViewElementToVariant -- index: " << index << "numElements" << view.getNumElements();
|
qDebug() << "toVariant -- " << DebugNames::stringFrom(dataType)
|
||||||
qDebug() << "bufferViewElementToVariant -- vecN: " << vecN << "byteLength" << byteLength << "BYTES_PER_ELEMENT" << BYTES_PER_ELEMENT;
|
#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);
|
Q_ASSERT(byteOffset <= maxByteOffset);
|
||||||
}
|
}
|
||||||
#ifdef DEBUG_BUFFERVIEW_SCRIPTING
|
#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
|
#endif
|
||||||
if (BYTES_PER_ELEMENT == 1) {
|
if (BYTES_PER_ELEMENT == 1) {
|
||||||
switch(vecN) {
|
switch(vecN) {
|
||||||
|
@ -223,7 +233,7 @@ QVariant buffer_helpers::toVariant(const gpu::BufferView& view, quint32 index, b
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
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();
|
static const auto len = T().length();
|
||||||
if (asArray) {
|
if (asArray) {
|
||||||
QVariantList list;
|
QVariantList list;
|
||||||
|
@ -239,8 +249,9 @@ QVariant glmVecToVariant(const T& v, bool asArray /*= false*/) {
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
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;
|
auto isMap = v.type() == (QVariant::Type)QMetaType::QVariantMap;
|
||||||
static const auto len = T().length();
|
static const auto len = T().length();
|
||||||
const auto& components = isMap ? XYZW : ZERO123;
|
const auto& components = isMap ? XYZW : ZERO123;
|
||||||
|
@ -255,9 +266,11 @@ const T glmVecFromVariant(const QVariant& v) {
|
||||||
} else {
|
} else {
|
||||||
value = list.value(i).toFloat();
|
value = list.value(i).toFloat();
|
||||||
}
|
}
|
||||||
|
#ifdef DEBUG_BUFFERVIEW_SCRIPTING
|
||||||
if (value != value) { // NAN
|
if (value != value) { // NAN
|
||||||
qWarning().nospace()<< "vec" << len << "." << components[i] << " NAN received from script.... " << v.toString();
|
qWarning().nospace()<< "vec" << len << "." << components[i] << " NAN received from script.... " << v.toString();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
result[i] = value;
|
result[i] = value;
|
||||||
}
|
}
|
||||||
return result;
|
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());
|
auto vertexBuffer = std::make_shared<gpu::Buffer>(elements.size() * sizeof(T), (gpu::Byte*)elements.data());
|
||||||
return { vertexBuffer, 0, vertexBuffer->getSize(),sizeof(T), elementType };
|
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<unsigned int>(
|
||||||
template<> gpu::BufferView buffer_helpers::fromVector<glm::vec3>(const QVector<glm::vec3>& elements, const gpu::Element& elementType) { return fromVector(elements, elementType); }
|
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<> gpu::BufferView buffer_helpers::fromVector<glm::vec3>(
|
||||||
template <typename T> struct getScalar;// { static T get(const gpu::BufferView& view, quint32 index, const char *hint); };
|
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 {
|
struct GpuToGlmAdapter {
|
||||||
static float error(const QString& name, const gpu::BufferView& view, quint32 index, const char *hint) {
|
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")
|
qDebug() << QString("GpuToGlmAdapter:: unhandled type=%1(element=%2(%3)) size=%4(per=%5) vec%6 hint=%7 #%8")
|
||||||
.arg(name)
|
.arg(name)
|
||||||
.arg(DebugNames::stringFrom(view._element.getType()))
|
.arg(debugName)
|
||||||
.arg(view._element.getType())
|
.arg(view._element.getType())
|
||||||
.arg(view._element.getSize())
|
.arg(view._element.getSize())
|
||||||
.arg(view._element.getSize() / view._element.getScalarCount())
|
.arg(view._element.getSize() / view._element.getScalarCount())
|
||||||
|
@ -290,7 +312,8 @@ struct GpuToGlmAdapter {
|
||||||
return NAN;
|
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()) {
|
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::UINT32: return view.get<glm::uint32>(index);
|
||||||
case gpu::UINT16: return view.get<glm::uint16>(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::FLOAT: return view.get<glm::float32>(index);
|
||||||
case gpu::HALF: return T(glm::unpackSnorm1x8(view.get<glm::int8>(index)));
|
case gpu::HALF: return T(glm::unpackSnorm1x8(view.get<glm::int8>(index)));
|
||||||
default: break;
|
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) {
|
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) {
|
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);
|
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) {
|
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) {
|
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);
|
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(
|
return gpu::BufferView(
|
||||||
std::make_shared<gpu::Buffer>(input._buffer->getSize(), input._buffer->getData()),
|
std::make_shared<gpu::Buffer>(input._buffer->getSize(), input._buffer->getData()),
|
||||||
input._offset, input._size, input._stride, input._element
|
input._offset, input._size, input._stride, input._element
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: preserve existing data
|
||||||
gpu::BufferView buffer_helpers::resize(const gpu::BufferView& input, quint32 numElements) {
|
gpu::BufferView buffer_helpers::resize(const gpu::BufferView& input, quint32 numElements) {
|
||||||
auto effectiveSize = input._buffer->getSize() / input.getNumElements();
|
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;
|
auto vsize = input._element.getSize() * numElements;
|
||||||
gpu::Byte *data = new gpu::Byte[vsize];
|
std::unique_ptr<gpu::Byte[]> data{ new gpu::Byte[vsize] };
|
||||||
memset(data, 0, vsize);
|
memset(data.get(), 0, vsize);
|
||||||
auto buffer = new gpu::Buffer(vsize, (gpu::Byte*)data);
|
auto buffer = new gpu::Buffer(vsize, data.get());
|
||||||
delete[] data;
|
|
||||||
auto output = gpu::BufferView(buffer, input._element);
|
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;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
graphics::MeshPointer buffer_helpers::cloneMesh(graphics::MeshPointer mesh) {
|
graphics::MeshPointer buffer_helpers::cloneMesh(graphics::MeshPointer mesh) {
|
||||||
auto clone = std::make_shared<graphics::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();
|
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->setIndexBuffer(buffer_helpers::clone(mesh->getIndexBuffer()));
|
||||||
clone->setPartBuffer(buffer_helpers::clone(mesh->getPartBuffer()));
|
clone->setPartBuffer(buffer_helpers::clone(mesh->getPartBuffer()));
|
||||||
auto attributeViews = buffer_helpers::gatherBufferViews(mesh);
|
auto attributeViews = buffer_helpers::gatherBufferViews(mesh);
|
||||||
|
@ -447,18 +467,11 @@ graphics::MeshPointer buffer_helpers::cloneMesh(graphics::MeshPointer mesh) {
|
||||||
return clone;
|
return clone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// --- buffer view <-> variant helpers
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
// expand the corresponding attribute buffer (creating it if needed) so that it matches POSITIONS size and specified element type
|
// 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 _expandedAttributeBuffer(const graphics::MeshPointer mesh, gpu::Stream::Slot slot) {
|
||||||
gpu::BufferView bufferView = buffer_helpers::getBufferView(mesh, slot);
|
gpu::BufferView bufferView = buffer_helpers::getBufferView(mesh, slot);
|
||||||
const auto& elementType = bufferView._element;
|
const auto& elementType = bufferView._element;
|
||||||
//auto vecN = element.getScalarCount();
|
|
||||||
//auto type = element.getType();
|
|
||||||
//gpu::Element elementType = getVecNElement(type, vecN);
|
|
||||||
|
|
||||||
gpu::Size elementSize = elementType.getSize();
|
gpu::Size elementSize = elementType.getSize();
|
||||||
auto nPositions = mesh->getNumVertices();
|
auto nPositions = mesh->getNumVertices();
|
||||||
auto vsize = nPositions * elementSize;
|
auto vsize = nPositions * elementSize;
|
||||||
|
@ -478,10 +491,9 @@ namespace {
|
||||||
if (bufferView.getNumElements() < nPositions || diffTypes) {
|
if (bufferView.getNumElements() < nPositions || diffTypes) {
|
||||||
if (!bufferView._buffer || bufferView.getNumElements() == 0) {
|
if (!bufferView._buffer || bufferView.getNumElements() == 0) {
|
||||||
qCInfo(bufferhelper_logging).nospace() << "ScriptableMesh -- adding missing mesh attribute '" << hint << "' for BufferView";
|
qCInfo(bufferhelper_logging).nospace() << "ScriptableMesh -- adding missing mesh attribute '" << hint << "' for BufferView";
|
||||||
gpu::Byte *data = new gpu::Byte[vsize];
|
std::unique_ptr<gpu::Byte[]> data{ new gpu::Byte[vsize] };
|
||||||
memset(data, 0, vsize);
|
memset(data.get(), 0, vsize);
|
||||||
auto buffer = new gpu::Buffer(vsize, (gpu::Byte*)data);
|
auto buffer = new gpu::Buffer(vsize, data.get());
|
||||||
delete[] data;
|
|
||||||
bufferView = gpu::BufferView(buffer, elementType);
|
bufferView = gpu::BufferView(buffer, elementType);
|
||||||
mesh->addAttribute(slot, bufferView);
|
mesh->addAttribute(slot, bufferView);
|
||||||
} else {
|
} else {
|
||||||
|
@ -553,7 +565,6 @@ std::map<QString, gpu::BufferView> buffer_helpers::gatherBufferViews(graphics::M
|
||||||
return attributeViews;
|
return attributeViews;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool buffer_helpers::recalculateNormals(graphics::MeshPointer mesh) {
|
bool buffer_helpers::recalculateNormals(graphics::MeshPointer mesh) {
|
||||||
qCInfo(bufferhelper_logging) << "Recalculating normals" << !!mesh;
|
qCInfo(bufferhelper_logging) << "Recalculating normals" << !!mesh;
|
||||||
if (!mesh) {
|
if (!mesh) {
|
||||||
|
@ -567,10 +578,8 @@ bool buffer_helpers::recalculateNormals(graphics::MeshPointer mesh) {
|
||||||
auto numPoints = indices.getNumElements();
|
auto numPoints = indices.getNumElements();
|
||||||
const auto TRIANGLE = 3;
|
const auto TRIANGLE = 3;
|
||||||
quint32 numFaces = (quint32)numPoints / TRIANGLE;
|
quint32 numFaces = (quint32)numPoints / TRIANGLE;
|
||||||
//QVector<Triangle> faces;
|
|
||||||
QVector<glm::vec3> faceNormals;
|
QVector<glm::vec3> faceNormals;
|
||||||
QMap<QString,QVector<quint32>> vertexToFaces;
|
QMap<QString,QVector<quint32>> vertexToFaces;
|
||||||
//faces.resize(numFaces);
|
|
||||||
faceNormals.resize(numFaces);
|
faceNormals.resize(numFaces);
|
||||||
auto numNormals = normals.getNumElements();
|
auto numNormals = normals.getNumElements();
|
||||||
qCInfo(bufferhelper_logging) << QString("numFaces: %1, numNormals: %2, numPoints: %3").arg(numFaces).arg(numNormals).arg(numPoints);
|
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();
|
faceNormals[i] = face.getNormal();
|
||||||
if (glm::isnan(faceNormals[i].x)) {
|
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);
|
qCInfo(bufferhelper_logging) << i << i0 << i1 << i2 << glmVecToVariant(face.v0) << glmVecToVariant(face.v1) << glmVecToVariant(face.v2);
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
vertexToFaces[glm::to_string(face.v0).c_str()] << i;
|
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);
|
normal = verts.get<glm::vec3>(j);
|
||||||
}
|
}
|
||||||
if (glm::isnan(normal.x)) {
|
if (glm::isnan(normal.x)) {
|
||||||
|
#ifdef DEBUG_BUFFERVIEW_SCRIPTING
|
||||||
static int logged = 0;
|
static int logged = 0;
|
||||||
if (logged++ < 10) {
|
if (logged++ < 10) {
|
||||||
qCInfo(bufferhelper_logging) << "isnan(normal.x)" << j << glmVecToVariant(normal);
|
qCInfo(bufferhelper_logging) << "isnan(normal.x)" << j << glmVecToVariant(normal);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
buffer_helpers::fromVariant(normals, j, glmVecToVariant(glm::normalize(normal)));
|
buffer_helpers::fromVariant(normals, j, glmVecToVariant(glm::normalize(normal)));
|
|
@ -15,9 +15,6 @@ namespace gpu {
|
||||||
class Element;
|
class Element;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> QVariant glmVecToVariant(const T& v, bool asArray = false);
|
|
||||||
template <typename T> const T glmVecFromVariant(const QVariant& v);
|
|
||||||
|
|
||||||
namespace graphics {
|
namespace graphics {
|
||||||
class Mesh;
|
class Mesh;
|
||||||
using MeshPointer = std::shared_ptr<Mesh>;
|
using MeshPointer = std::shared_ptr<Mesh>;
|
||||||
|
@ -27,6 +24,9 @@ class Extents;
|
||||||
class AABox;
|
class AABox;
|
||||||
|
|
||||||
struct buffer_helpers {
|
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 graphics::MeshPointer cloneMesh(graphics::MeshPointer mesh);
|
||||||
static QMap<QString,int> ATTRIBUTES;
|
static QMap<QString,int> ATTRIBUTES;
|
||||||
static std::map<QString, gpu::BufferView> gatherBufferViews(graphics::MeshPointer mesh, const QStringList& expandToMatchPositions = QStringList());
|
static std::map<QString, gpu::BufferView> gatherBufferViews(graphics::MeshPointer mesh, const QStringList& expandToMatchPositions = QStringList());
|
|
@ -9,10 +9,6 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// 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 "Model.h"
|
||||||
|
|
||||||
#include <QMetaType>
|
#include <QMetaType>
|
||||||
|
@ -31,7 +27,7 @@ namespace { QLoggingCategory wtf{ "tim.Model.cpp" }; }
|
||||||
#include <TBBHelpers.h>
|
#include <TBBHelpers.h>
|
||||||
|
|
||||||
#include <graphics-scripting/Forward.h>
|
#include <graphics-scripting/Forward.h>
|
||||||
#include <graphics-scripting/BufferViewHelpers.h>
|
#include <graphics/BufferViewHelpers.h>
|
||||||
#include <DualQuaternion.h>
|
#include <DualQuaternion.h>
|
||||||
|
|
||||||
#include <glm/gtc/packing.hpp>
|
#include <glm/gtc/packing.hpp>
|
||||||
|
@ -372,7 +368,7 @@ bool Model::updateGeometry() {
|
||||||
#if FBX_PACK_NORMALS
|
#if FBX_PACK_NORMALS
|
||||||
glm::uint32 finalNormal;
|
glm::uint32 finalNormal;
|
||||||
glm::uint32 finalTangent;
|
glm::uint32 finalTangent;
|
||||||
packNormalAndTangent(*normalIt, *tangentIt, finalNormal, finalTangent);
|
buffer_helpers::packNormalAndTangent(*normalIt, *tangentIt, finalNormal, finalTangent);
|
||||||
#else
|
#else
|
||||||
const auto finalNormal = *normalIt;
|
const auto finalNormal = *normalIt;
|
||||||
const auto finalTangent = *tangentIt;
|
const auto finalTangent = *tangentIt;
|
||||||
|
@ -569,25 +565,15 @@ bool Model::replaceScriptableModelMeshPart(scriptable::ScriptableModelBasePointe
|
||||||
auto newRenderGeometry = new MyGeometryMappingResource(
|
auto newRenderGeometry = new MyGeometryMappingResource(
|
||||||
_url, _renderGeometry, _newModel ? scriptable::make_qtowned<scriptable::ScriptableModelBase>(*_newModel) : nullptr
|
_url, _renderGeometry, _newModel ? scriptable::make_qtowned<scriptable::ScriptableModelBase>(*_newModel) : nullptr
|
||||||
);
|
);
|
||||||
//_needsUpdateTextures = true;
|
|
||||||
_visualGeometryRequestFailed = false;
|
_visualGeometryRequestFailed = false;
|
||||||
//invalidCalculatedMeshBoxes();
|
|
||||||
deleteGeometry();
|
deleteGeometry();
|
||||||
_renderGeometry.reset(newRenderGeometry);
|
_renderGeometry.reset(newRenderGeometry);
|
||||||
//onInvalidate();
|
|
||||||
//reset();
|
|
||||||
_rig.destroyAnimGraph();
|
_rig.destroyAnimGraph();
|
||||||
//assert(_rig.jointStatesEmpty());
|
|
||||||
updateGeometry();
|
updateGeometry();
|
||||||
calculateTriangleSets();
|
calculateTriangleSets();
|
||||||
//computeMeshPartLocalBounds();
|
_needsReload = false;
|
||||||
//_needsReload = false;
|
|
||||||
_needsFixupInScene = true;
|
_needsFixupInScene = true;
|
||||||
//invalidCalculatedMeshBoxes();
|
|
||||||
setRenderItemsNeedUpdate();
|
setRenderItemsNeedUpdate();
|
||||||
//_hasCalculatedTextureInfo = false;
|
|
||||||
//calculateTextureInfo();
|
|
||||||
//updateRenderItems();
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -597,7 +583,7 @@ scriptable::ScriptableModelBase Model::getScriptableModel(bool* ok) {
|
||||||
scriptable::ScriptableModelBase result;
|
scriptable::ScriptableModelBase result;
|
||||||
|
|
||||||
if (!isLoaded()) {
|
if (!isLoaded()) {
|
||||||
qCDebug(wtf) << "Model::getScriptableModel -- !isLoaded";
|
qCDebug(renderutils) << "Model::getScriptableModel -- !isLoaded";
|
||||||
return scriptable::ModelProvider::modelUnavailableError(ok);
|
return scriptable::ModelProvider::modelUnavailableError(ok);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,7 @@
|
||||||
#include <graphics-scripting/BufferViewHelpers.h>
|
#include <graphics/BufferViewHelpers.h>
|
||||||
#include <graphics-scripting/GraphicsScriptingUtil.h>
|
#include <graphics-scripting/GraphicsScriptingUtil.h>
|
||||||
class MyGeometryMappingResource : public GeometryResource {
|
class MyGeometryMappingResource : public GeometryResource {
|
||||||
// Q_OBJECT
|
|
||||||
public:
|
public:
|
||||||
virtual void init(bool resetLoaded = true) override {
|
|
||||||
qCDebug(wtf) << "############################# Snarfing init()...";
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void deleter() override {
|
|
||||||
qCDebug(wtf) << "############################# Snarfing deleter()...";
|
|
||||||
}
|
|
||||||
shared_ptr<FBXGeometry> fbxGeometry;
|
shared_ptr<FBXGeometry> fbxGeometry;
|
||||||
MyGeometryMappingResource(const QUrl& url, Geometry::Pointer originalGeometry, std::shared_ptr<scriptable::ScriptableModelBase> newModel) : GeometryResource(url) {
|
MyGeometryMappingResource(const QUrl& url, Geometry::Pointer originalGeometry, std::shared_ptr<scriptable::ScriptableModelBase> newModel) : GeometryResource(url) {
|
||||||
fbxGeometry = std::make_shared<FBXGeometry>();
|
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.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.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.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;
|
geometry.meshes << mesh;
|
||||||
// Copy mesh pointers
|
// Copy mesh pointers
|
||||||
meshes->emplace_back(newMesh.getMeshPointer());//buffer_helpers::cloneMesh(ptr));
|
meshes->emplace_back(newMesh.getMeshPointer());//buffer_helpers::cloneMesh(ptr));
|
||||||
|
@ -84,10 +78,9 @@ public:
|
||||||
const auto oldParts = mesh.parts;
|
const auto oldParts = mesh.parts;
|
||||||
mesh.parts.clear();
|
mesh.parts.clear();
|
||||||
for (const FBXMeshPart& fbxPart : oldParts) {
|
for (const FBXMeshPart& fbxPart : oldParts) {
|
||||||
FBXMeshPart part; // copy;
|
FBXMeshPart part; // new copy
|
||||||
part.materialID = fbxPart.materialID;
|
part.materialID = fbxPart.materialID;
|
||||||
// Construct local parts
|
// Construct local parts
|
||||||
///qCDebug(wtf) << "GeometryMappingResource -- meshes part" << meshID << partID << part.materialID;
|
|
||||||
part.triangleIndices = buffer_helpers::toVector<int>(mesh._mesh->getIndexBuffer(), "part.triangleIndices");
|
part.triangleIndices = buffer_helpers::toVector<int>(mesh._mesh->getIndexBuffer(), "part.triangleIndices");
|
||||||
mesh.parts << part;
|
mesh.parts << part;
|
||||||
auto p = std::make_shared<MeshPart>(meshID, partID, (int)materialIDAtlas[part.materialID]);
|
auto p = std::make_shared<MeshPart>(meshID, partID, (int)materialIDAtlas[part.materialID]);
|
||||||
|
@ -115,7 +108,6 @@ public:
|
||||||
_animGraphOverrideUrl = originalGeometry ? originalGeometry->getAnimGraphOverrideUrl() : QUrl();
|
_animGraphOverrideUrl = originalGeometry ? originalGeometry->getAnimGraphOverrideUrl() : QUrl();
|
||||||
_loaded = true;
|
_loaded = true;
|
||||||
_fbxGeometry = fbxGeometry;
|
_fbxGeometry = fbxGeometry;
|
||||||
finishedLoading(true);
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue