mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 23:14:34 +02:00
Merge pull request #12026 from SamGondelman/burp3
Remove _model from ModelMeshPartPayload
This commit is contained in:
commit
a2c16ddf6a
10 changed files with 112 additions and 137 deletions
|
@ -24,7 +24,6 @@ ModelOverlay::ModelOverlay()
|
||||||
: _model(std::make_shared<Model>(nullptr, this)),
|
: _model(std::make_shared<Model>(nullptr, this)),
|
||||||
_modelTextures(QVariantMap())
|
_modelTextures(QVariantMap())
|
||||||
{
|
{
|
||||||
_model->init();
|
|
||||||
_model->setLoadingPriority(_loadPriority);
|
_model->setLoadingPriority(_loadPriority);
|
||||||
_isLoaded = false;
|
_isLoaded = false;
|
||||||
}
|
}
|
||||||
|
@ -38,7 +37,6 @@ ModelOverlay::ModelOverlay(const ModelOverlay* modelOverlay) :
|
||||||
_scaleToFit(modelOverlay->_scaleToFit),
|
_scaleToFit(modelOverlay->_scaleToFit),
|
||||||
_loadPriority(modelOverlay->_loadPriority)
|
_loadPriority(modelOverlay->_loadPriority)
|
||||||
{
|
{
|
||||||
_model->init();
|
|
||||||
_model->setLoadingPriority(_loadPriority);
|
_model->setLoadingPriority(_loadPriority);
|
||||||
if (_url.isValid()) {
|
if (_url.isValid()) {
|
||||||
_updateModel = true;
|
_updateModel = true;
|
||||||
|
|
|
@ -138,7 +138,6 @@ Avatar::~Avatar() {
|
||||||
|
|
||||||
void Avatar::init() {
|
void Avatar::init() {
|
||||||
getHead()->init();
|
getHead()->init();
|
||||||
_skeletonModel->init();
|
|
||||||
_initialized = true;
|
_initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1209,7 +1209,6 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce
|
||||||
connect(model.get(), &Model::requestRenderUpdate, this, &ModelEntityRenderer::requestRenderUpdate);
|
connect(model.get(), &Model::requestRenderUpdate, this, &ModelEntityRenderer::requestRenderUpdate);
|
||||||
connect(entity.get(), &RenderableModelEntityItem::requestCollisionGeometryUpdate, this, &ModelEntityRenderer::flagForCollisionGeometryUpdate);
|
connect(entity.get(), &RenderableModelEntityItem::requestCollisionGeometryUpdate, this, &ModelEntityRenderer::flagForCollisionGeometryUpdate);
|
||||||
model->setLoadingPriority(EntityTreeRenderer::getEntityLoadingPriority(*entity));
|
model->setLoadingPriority(EntityTreeRenderer::getEntityLoadingPriority(*entity));
|
||||||
model->init();
|
|
||||||
entity->setModel(model);
|
entity->setModel(model);
|
||||||
withWriteLock([&] { _model = model; });
|
withWriteLock([&] { _model = model; });
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,17 +40,7 @@ void CauterizedMeshPartPayload::updateTransformForCauterizedMesh(const Transform
|
||||||
|
|
||||||
void CauterizedMeshPartPayload::bindTransform(gpu::Batch& batch, const render::ShapePipeline::LocationsPointer locations, RenderArgs::RenderMode renderMode) const {
|
void CauterizedMeshPartPayload::bindTransform(gpu::Batch& batch, const render::ShapePipeline::LocationsPointer locations, RenderArgs::RenderMode renderMode) const {
|
||||||
// Still relying on the raw data from the model
|
// Still relying on the raw data from the model
|
||||||
bool useCauterizedMesh = (renderMode != RenderArgs::RenderMode::SHADOW_RENDER_MODE && renderMode != RenderArgs::RenderMode::SECONDARY_CAMERA_RENDER_MODE);
|
bool useCauterizedMesh = (renderMode != RenderArgs::RenderMode::SHADOW_RENDER_MODE && renderMode != RenderArgs::RenderMode::SECONDARY_CAMERA_RENDER_MODE) && _enableCauterization;
|
||||||
if (useCauterizedMesh) {
|
|
||||||
ModelPointer model = _model.lock();
|
|
||||||
if (model) {
|
|
||||||
CauterizedModel* skeleton = static_cast<CauterizedModel*>(model.get());
|
|
||||||
useCauterizedMesh = useCauterizedMesh && skeleton->getEnableCauterization();
|
|
||||||
} else {
|
|
||||||
useCauterizedMesh = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (useCauterizedMesh) {
|
if (useCauterizedMesh) {
|
||||||
if (_cauterizedClusterBuffer) {
|
if (_cauterizedClusterBuffer) {
|
||||||
batch.setUniformBuffer(ShapePipeline::Slot::BUFFER::SKINNING, _cauterizedClusterBuffer);
|
batch.setUniformBuffer(ShapePipeline::Slot::BUFFER::SKINNING, _cauterizedClusterBuffer);
|
||||||
|
|
|
@ -21,9 +21,12 @@ public:
|
||||||
|
|
||||||
void bindTransform(gpu::Batch& batch, const render::ShapePipeline::LocationsPointer locations, RenderArgs::RenderMode renderMode) const override;
|
void bindTransform(gpu::Batch& batch, const render::ShapePipeline::LocationsPointer locations, RenderArgs::RenderMode renderMode) const override;
|
||||||
|
|
||||||
|
void setEnableCauterization(bool enableCauterization) { _enableCauterization = enableCauterization; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
gpu::BufferPointer _cauterizedClusterBuffer;
|
gpu::BufferPointer _cauterizedClusterBuffer;
|
||||||
Transform _cauterizedTransform;
|
Transform _cauterizedTransform;
|
||||||
|
bool _enableCauterization { false };
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_CauterizedMeshPartPayload_h
|
#endif // hifi_CauterizedMeshPartPayload_h
|
||||||
|
|
|
@ -178,6 +178,12 @@ void CauterizedModel::updateRenderItems() {
|
||||||
modelTransform.setTranslation(self->getTranslation());
|
modelTransform.setTranslation(self->getTranslation());
|
||||||
modelTransform.setRotation(self->getRotation());
|
modelTransform.setRotation(self->getRotation());
|
||||||
|
|
||||||
|
bool isWireframe = self->isWireframe();
|
||||||
|
bool isVisible = self->isVisible();
|
||||||
|
bool isLayeredInFront = self->isLayeredInFront();
|
||||||
|
bool isLayeredInHUD = self->isLayeredInHUD();
|
||||||
|
bool enableCauterization = self->getEnableCauterization();
|
||||||
|
|
||||||
render::Transaction transaction;
|
render::Transaction transaction;
|
||||||
for (int i = 0; i < (int)self->_modelMeshRenderItemIDs.size(); i++) {
|
for (int i = 0; i < (int)self->_modelMeshRenderItemIDs.size(); i++) {
|
||||||
|
|
||||||
|
@ -186,7 +192,10 @@ void CauterizedModel::updateRenderItems() {
|
||||||
auto clusterMatrices(self->getMeshState(meshIndex).clusterMatrices);
|
auto clusterMatrices(self->getMeshState(meshIndex).clusterMatrices);
|
||||||
auto clusterMatricesCauterized(self->getCauterizeMeshState(meshIndex).clusterMatrices);
|
auto clusterMatricesCauterized(self->getCauterizeMeshState(meshIndex).clusterMatrices);
|
||||||
|
|
||||||
transaction.updateItem<CauterizedMeshPartPayload>(itemID, [modelTransform, clusterMatrices, clusterMatricesCauterized](CauterizedMeshPartPayload& data) {
|
bool invalidatePayloadShapeKey = self->shouldInvalidatePayloadShapeKey(meshIndex);
|
||||||
|
|
||||||
|
transaction.updateItem<CauterizedMeshPartPayload>(itemID, [modelTransform, clusterMatrices, clusterMatricesCauterized, invalidatePayloadShapeKey,
|
||||||
|
isWireframe, isVisible, isLayeredInFront, isLayeredInHUD, enableCauterization](CauterizedMeshPartPayload& data) {
|
||||||
data.updateClusterBuffer(clusterMatrices, clusterMatricesCauterized);
|
data.updateClusterBuffer(clusterMatrices, clusterMatricesCauterized);
|
||||||
|
|
||||||
Transform renderTransform = modelTransform;
|
Transform renderTransform = modelTransform;
|
||||||
|
@ -200,6 +209,11 @@ void CauterizedModel::updateRenderItems() {
|
||||||
renderTransform = modelTransform.worldTransform(Transform(clusterMatricesCauterized[0]));
|
renderTransform = modelTransform.worldTransform(Transform(clusterMatricesCauterized[0]));
|
||||||
}
|
}
|
||||||
data.updateTransformForCauterizedMesh(renderTransform);
|
data.updateTransformForCauterizedMesh(renderTransform);
|
||||||
|
|
||||||
|
data.setEnableCauterization(enableCauterization);
|
||||||
|
data.setKey(isVisible, isLayeredInFront || isLayeredInHUD);
|
||||||
|
data.setLayer(isLayeredInFront, isLayeredInHUD);
|
||||||
|
data.setShapeKey(invalidatePayloadShapeKey, isWireframe);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -325,7 +325,7 @@ ModelMeshPartPayload::ModelMeshPartPayload(ModelPointer model, int meshIndex, in
|
||||||
_shapeID(shapeIndex) {
|
_shapeID(shapeIndex) {
|
||||||
|
|
||||||
assert(model && model->isLoaded());
|
assert(model && model->isLoaded());
|
||||||
_model = model;
|
_blendedVertexBuffer = model->_blendedVertexBuffers[_meshIndex];
|
||||||
auto& modelMesh = model->getGeometry()->getMeshes().at(_meshIndex);
|
auto& modelMesh = model->getGeometry()->getMeshes().at(_meshIndex);
|
||||||
const Model::MeshState& state = model->getMeshState(_meshIndex);
|
const Model::MeshState& state = model->getMeshState(_meshIndex);
|
||||||
|
|
||||||
|
@ -339,13 +339,10 @@ ModelMeshPartPayload::ModelMeshPartPayload(ModelPointer model, int meshIndex, in
|
||||||
}
|
}
|
||||||
updateTransformForSkinnedMesh(renderTransform, transform);
|
updateTransformForSkinnedMesh(renderTransform, transform);
|
||||||
|
|
||||||
initCache();
|
initCache(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModelMeshPartPayload::initCache() {
|
void ModelMeshPartPayload::initCache(const ModelPointer& model) {
|
||||||
ModelPointer model = _model.lock();
|
|
||||||
assert(model && model->isLoaded());
|
|
||||||
|
|
||||||
if (_drawMesh) {
|
if (_drawMesh) {
|
||||||
auto vertexFormat = _drawMesh->getVertexFormat();
|
auto vertexFormat = _drawMesh->getVertexFormat();
|
||||||
_hasColorAttrib = vertexFormat->hasAttribute(gpu::Stream::COLOR);
|
_hasColorAttrib = vertexFormat->hasAttribute(gpu::Stream::COLOR);
|
||||||
|
@ -355,6 +352,7 @@ void ModelMeshPartPayload::initCache() {
|
||||||
const FBXMesh& mesh = geometry.meshes.at(_meshIndex);
|
const FBXMesh& mesh = geometry.meshes.at(_meshIndex);
|
||||||
|
|
||||||
_isBlendShaped = !mesh.blendshapes.isEmpty();
|
_isBlendShaped = !mesh.blendshapes.isEmpty();
|
||||||
|
_hasTangents = !mesh.tangents.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto networkMaterial = model->getGeometry()->getShapeMaterial(_shapeID);
|
auto networkMaterial = model->getGeometry()->getShapeMaterial(_shapeID);
|
||||||
|
@ -388,94 +386,70 @@ void ModelMeshPartPayload::updateTransformForSkinnedMesh(const Transform& render
|
||||||
_worldBound.transform(boundTransform);
|
_worldBound.transform(boundTransform);
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemKey ModelMeshPartPayload::getKey() const {
|
void ModelMeshPartPayload::setKey(bool isVisible, bool isLayered) {
|
||||||
ItemKey::Builder builder;
|
ItemKey::Builder builder;
|
||||||
builder.withTypeShape();
|
builder.withTypeShape();
|
||||||
|
|
||||||
ModelPointer model = _model.lock();
|
if (!isVisible) {
|
||||||
if (model) {
|
builder.withInvisible();
|
||||||
if (!model->isVisible()) {
|
}
|
||||||
builder.withInvisible();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (model->isLayeredInFront() || model->isLayeredInHUD()) {
|
if (isLayered) {
|
||||||
builder.withLayered();
|
builder.withLayered();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_isBlendShaped || _isSkinned) {
|
if (_isBlendShaped || _isSkinned) {
|
||||||
builder.withDeformed();
|
builder.withDeformed();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_drawMaterial) {
|
if (_drawMaterial) {
|
||||||
auto matKey = _drawMaterial->getKey();
|
auto matKey = _drawMaterial->getKey();
|
||||||
if (matKey.isTranslucent()) {
|
if (matKey.isTranslucent()) {
|
||||||
builder.withTransparent();
|
builder.withTransparent();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return builder.build();
|
|
||||||
|
_itemKey = builder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemKey ModelMeshPartPayload::getKey() const {
|
||||||
|
return _itemKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelMeshPartPayload::setLayer(bool isLayeredInFront, bool isLayeredInHUD) {
|
||||||
|
if (isLayeredInFront) {
|
||||||
|
_layer = Item::LAYER_3D_FRONT;
|
||||||
|
} else if (isLayeredInHUD) {
|
||||||
|
_layer = Item::LAYER_3D_HUD;
|
||||||
|
} else {
|
||||||
|
_layer = Item::LAYER_3D;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int ModelMeshPartPayload::getLayer() const {
|
int ModelMeshPartPayload::getLayer() const {
|
||||||
ModelPointer model = _model.lock();
|
return _layer;
|
||||||
if (model) {
|
|
||||||
if (model->isLayeredInFront()) {
|
|
||||||
return Item::LAYER_3D_FRONT;
|
|
||||||
} else if (model->isLayeredInHUD()) {
|
|
||||||
return Item::LAYER_3D_HUD;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Item::LAYER_3D;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ShapeKey ModelMeshPartPayload::getShapeKey() const {
|
void ModelMeshPartPayload::setShapeKey(bool invalidateShapeKey, bool isWireframe) {
|
||||||
// guard against partially loaded meshes
|
if (invalidateShapeKey) {
|
||||||
ModelPointer model = _model.lock();
|
_shapeKey = ShapeKey::Builder::invalid();
|
||||||
if (!model || !model->isLoaded() || !model->getGeometry()) {
|
return;
|
||||||
return ShapeKey::Builder::invalid();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const FBXGeometry& geometry = model->getFBXGeometry();
|
|
||||||
const auto& networkMeshes = model->getGeometry()->getMeshes();
|
|
||||||
|
|
||||||
// guard against partially loaded meshes
|
|
||||||
if (_meshIndex >= (int)networkMeshes.size() || _meshIndex >= (int)geometry.meshes.size() || _meshIndex >= (int)model->_meshStates.size()) {
|
|
||||||
return ShapeKey::Builder::invalid();
|
|
||||||
}
|
|
||||||
|
|
||||||
const FBXMesh& mesh = geometry.meshes.at(_meshIndex);
|
|
||||||
|
|
||||||
// if our index is ever out of range for either meshes or networkMeshes, then skip it, and set our _meshGroupsKnown
|
|
||||||
// to false to rebuild out mesh groups.
|
|
||||||
if (_meshIndex < 0 || _meshIndex >= (int)networkMeshes.size() || _meshIndex > geometry.meshes.size()) {
|
|
||||||
model->_needsFixupInScene = true; // trigger remove/add cycle
|
|
||||||
model->invalidCalculatedMeshBoxes(); // if we have to reload, we need to assume our mesh boxes are all invalid
|
|
||||||
return ShapeKey::Builder::invalid();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int vertexCount = mesh.vertices.size();
|
|
||||||
if (vertexCount == 0) {
|
|
||||||
// sanity check
|
|
||||||
return ShapeKey::Builder::invalid(); // FIXME
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
model::MaterialKey drawMaterialKey;
|
model::MaterialKey drawMaterialKey;
|
||||||
if (_drawMaterial) {
|
if (_drawMaterial) {
|
||||||
drawMaterialKey = _drawMaterial->getKey();
|
drawMaterialKey = _drawMaterial->getKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isTranslucent = drawMaterialKey.isTranslucent();
|
bool isTranslucent = drawMaterialKey.isTranslucent();
|
||||||
bool hasTangents = drawMaterialKey.isNormalMap() && !mesh.tangents.isEmpty();
|
bool hasTangents = drawMaterialKey.isNormalMap() && _hasTangents;
|
||||||
bool hasSpecular = drawMaterialKey.isMetallicMap();
|
bool hasSpecular = drawMaterialKey.isMetallicMap();
|
||||||
bool hasLightmap = drawMaterialKey.isLightmapMap();
|
bool hasLightmap = drawMaterialKey.isLightmapMap();
|
||||||
bool isUnlit = drawMaterialKey.isUnlit();
|
bool isUnlit = drawMaterialKey.isUnlit();
|
||||||
|
|
||||||
bool isSkinned = _isSkinned;
|
bool isSkinned = _isSkinned;
|
||||||
bool wireframe = model->isWireframe();
|
|
||||||
|
|
||||||
if (wireframe) {
|
if (isWireframe) {
|
||||||
isTranslucent = hasTangents = hasSpecular = hasLightmap = isSkinned = false;
|
isTranslucent = hasTangents = hasSpecular = hasLightmap = isSkinned = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -500,10 +474,14 @@ ShapeKey ModelMeshPartPayload::getShapeKey() const {
|
||||||
if (isSkinned) {
|
if (isSkinned) {
|
||||||
builder.withSkinned();
|
builder.withSkinned();
|
||||||
}
|
}
|
||||||
if (wireframe) {
|
if (isWireframe) {
|
||||||
builder.withWireframe();
|
builder.withWireframe();
|
||||||
}
|
}
|
||||||
return builder.build();
|
_shapeKey = builder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
ShapeKey ModelMeshPartPayload::getShapeKey() const {
|
||||||
|
return _shapeKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModelMeshPartPayload::bindMesh(gpu::Batch& batch) {
|
void ModelMeshPartPayload::bindMesh(gpu::Batch& batch) {
|
||||||
|
@ -515,10 +493,9 @@ void ModelMeshPartPayload::bindMesh(gpu::Batch& batch) {
|
||||||
batch.setIndexBuffer(gpu::UINT32, (_drawMesh->getIndexBuffer()._buffer), 0);
|
batch.setIndexBuffer(gpu::UINT32, (_drawMesh->getIndexBuffer()._buffer), 0);
|
||||||
batch.setInputFormat((_drawMesh->getVertexFormat()));
|
batch.setInputFormat((_drawMesh->getVertexFormat()));
|
||||||
|
|
||||||
ModelPointer model = _model.lock();
|
if (_blendedVertexBuffer) {
|
||||||
if (model) {
|
batch.setInputBuffer(0, _blendedVertexBuffer, 0, sizeof(glm::vec3));
|
||||||
batch.setInputBuffer(0, model->_blendedVertexBuffers[_meshIndex], 0, sizeof(glm::vec3));
|
batch.setInputBuffer(1, _blendedVertexBuffer, _drawMesh->getNumVertices() * sizeof(glm::vec3), sizeof(glm::vec3));
|
||||||
batch.setInputBuffer(1, model->_blendedVertexBuffers[_meshIndex], _drawMesh->getNumVertices() * sizeof(glm::vec3), sizeof(glm::vec3));
|
|
||||||
batch.setInputStream(2, _drawMesh->getVertexStream().makeRangedStream(2));
|
batch.setInputStream(2, _drawMesh->getVertexStream().makeRangedStream(2));
|
||||||
} else {
|
} else {
|
||||||
batch.setIndexBuffer(gpu::UINT32, (_drawMesh->getIndexBuffer()._buffer), 0);
|
batch.setIndexBuffer(gpu::UINT32, (_drawMesh->getIndexBuffer()._buffer), 0);
|
||||||
|
@ -544,31 +521,9 @@ void ModelMeshPartPayload::bindTransform(gpu::Batch& batch, const ShapePipeline:
|
||||||
void ModelMeshPartPayload::render(RenderArgs* args) {
|
void ModelMeshPartPayload::render(RenderArgs* args) {
|
||||||
PerformanceTimer perfTimer("ModelMeshPartPayload::render");
|
PerformanceTimer perfTimer("ModelMeshPartPayload::render");
|
||||||
|
|
||||||
ModelPointer model = _model.lock();
|
|
||||||
if (!model || !model->isAddedToScene() || !model->isVisible()) {
|
|
||||||
return; // bail asap
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_state == WAITING_TO_START) {
|
|
||||||
if (model->isLoaded()) {
|
|
||||||
_state = STARTED;
|
|
||||||
model->setRenderItemsNeedUpdate();
|
|
||||||
} else {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_materialNeedsUpdate && model->getGeometry()->areTexturesLoaded()) {
|
|
||||||
model->setRenderItemsNeedUpdate();
|
|
||||||
_materialNeedsUpdate = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!args) {
|
if (!args) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!getShapeKey().isValid()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
gpu::Batch& batch = *(args->_batch);
|
gpu::Batch& batch = *(args->_batch);
|
||||||
auto locations = args->_shapePipeline->locations;
|
auto locations = args->_shapePipeline->locations;
|
||||||
|
|
|
@ -96,32 +96,32 @@ public:
|
||||||
render::ShapeKey getShapeKey() const override; // shape interface
|
render::ShapeKey getShapeKey() const override; // shape interface
|
||||||
void render(RenderArgs* args) override;
|
void render(RenderArgs* args) override;
|
||||||
|
|
||||||
|
void setKey(bool isVisible, bool isLayered);
|
||||||
|
void setLayer(bool isLayeredInFront, bool isLayeredInHUD);
|
||||||
|
void setShapeKey(bool invalidateShapeKey, bool isWireframe);
|
||||||
|
|
||||||
// ModelMeshPartPayload functions to perform render
|
// ModelMeshPartPayload functions to perform render
|
||||||
void bindMesh(gpu::Batch& batch) override;
|
void bindMesh(gpu::Batch& batch) override;
|
||||||
void bindTransform(gpu::Batch& batch, const render::ShapePipeline::LocationsPointer locations, RenderArgs::RenderMode renderMode) const override;
|
void bindTransform(gpu::Batch& batch, const render::ShapePipeline::LocationsPointer locations, RenderArgs::RenderMode renderMode) const override;
|
||||||
|
|
||||||
void initCache();
|
|
||||||
|
|
||||||
void computeAdjustedLocalBound(const std::vector<glm::mat4>& clusterMatrices);
|
void computeAdjustedLocalBound(const std::vector<glm::mat4>& clusterMatrices);
|
||||||
|
|
||||||
gpu::BufferPointer _clusterBuffer;
|
gpu::BufferPointer _clusterBuffer;
|
||||||
ModelWeakPointer _model;
|
|
||||||
|
|
||||||
int _meshIndex;
|
int _meshIndex;
|
||||||
int _shapeID;
|
int _shapeID;
|
||||||
|
|
||||||
bool _isSkinned{ false };
|
bool _isSkinned{ false };
|
||||||
bool _isBlendShaped { false };
|
bool _isBlendShaped { false };
|
||||||
bool _materialNeedsUpdate { true };
|
bool _hasTangents { false };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void initCache(const ModelPointer& model);
|
||||||
|
|
||||||
enum State : uint8_t {
|
gpu::BufferPointer _blendedVertexBuffer;
|
||||||
WAITING_TO_START = 0,
|
render::ItemKey _itemKey { render::ItemKey::Builder::opaqueShape().build() };
|
||||||
STARTED = 1,
|
render::ShapeKey _shapeKey { render::ShapeKey::Builder::invalid() };
|
||||||
};
|
int _layer { render::Item::LAYER_3D };
|
||||||
|
|
||||||
mutable State _state { WAITING_TO_START } ;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace render {
|
namespace render {
|
||||||
|
|
|
@ -210,6 +210,24 @@ int Model::getRenderInfoTextureCount() {
|
||||||
return _renderInfoTextureCount;
|
return _renderInfoTextureCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Model::shouldInvalidatePayloadShapeKey(int meshIndex) {
|
||||||
|
if (!getGeometry()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const FBXGeometry& geometry = getFBXGeometry();
|
||||||
|
const auto& networkMeshes = getGeometry()->getMeshes();
|
||||||
|
// if our index is ever out of range for either meshes or networkMeshes, then skip it, and set our _meshGroupsKnown
|
||||||
|
// to false to rebuild out mesh groups.
|
||||||
|
if (meshIndex < 0 || meshIndex >= (int)networkMeshes.size() || meshIndex >= (int)geometry.meshes.size() || meshIndex >= (int)_meshStates.size()) {
|
||||||
|
_needsFixupInScene = true; // trigger remove/add cycle
|
||||||
|
invalidCalculatedMeshBoxes(); // if we have to reload, we need to assume our mesh boxes are all invalid
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void Model::updateRenderItems() {
|
void Model::updateRenderItems() {
|
||||||
if (!_addedToScene) {
|
if (!_addedToScene) {
|
||||||
return;
|
return;
|
||||||
|
@ -237,6 +255,11 @@ void Model::updateRenderItems() {
|
||||||
Transform modelTransform = self->getTransform();
|
Transform modelTransform = self->getTransform();
|
||||||
modelTransform.setScale(glm::vec3(1.0f));
|
modelTransform.setScale(glm::vec3(1.0f));
|
||||||
|
|
||||||
|
bool isWireframe = self->isWireframe();
|
||||||
|
bool isVisible = self->isVisible();
|
||||||
|
bool isLayeredInFront = self->isLayeredInFront();
|
||||||
|
bool isLayeredInHUD = self->isLayeredInHUD();
|
||||||
|
|
||||||
render::Transaction transaction;
|
render::Transaction transaction;
|
||||||
for (int i = 0; i < (int) self->_modelMeshRenderItemIDs.size(); i++) {
|
for (int i = 0; i < (int) self->_modelMeshRenderItemIDs.size(); i++) {
|
||||||
|
|
||||||
|
@ -244,13 +267,20 @@ void Model::updateRenderItems() {
|
||||||
auto meshIndex = self->_modelMeshRenderItemShapes[i].meshIndex;
|
auto meshIndex = self->_modelMeshRenderItemShapes[i].meshIndex;
|
||||||
auto clusterMatrices(self->getMeshState(meshIndex).clusterMatrices);
|
auto clusterMatrices(self->getMeshState(meshIndex).clusterMatrices);
|
||||||
|
|
||||||
transaction.updateItem<ModelMeshPartPayload>(itemID, [modelTransform, clusterMatrices](ModelMeshPartPayload& data) {
|
bool invalidatePayloadShapeKey = self->shouldInvalidatePayloadShapeKey(meshIndex);
|
||||||
|
|
||||||
|
transaction.updateItem<ModelMeshPartPayload>(itemID, [modelTransform, clusterMatrices, invalidatePayloadShapeKey,
|
||||||
|
isWireframe, isVisible, isLayeredInFront, isLayeredInHUD](ModelMeshPartPayload& data) {
|
||||||
data.updateClusterBuffer(clusterMatrices);
|
data.updateClusterBuffer(clusterMatrices);
|
||||||
Transform renderTransform = modelTransform;
|
Transform renderTransform = modelTransform;
|
||||||
if (clusterMatrices.size() == 1) {
|
if (clusterMatrices.size() == 1) {
|
||||||
renderTransform = modelTransform.worldTransform(Transform(clusterMatrices[0]));
|
renderTransform = modelTransform.worldTransform(Transform(clusterMatrices[0]));
|
||||||
}
|
}
|
||||||
data.updateTransformForSkinnedMesh(renderTransform, modelTransform);
|
data.updateTransformForSkinnedMesh(renderTransform, modelTransform);
|
||||||
|
|
||||||
|
data.setKey(isVisible, isLayeredInFront || isLayeredInHUD);
|
||||||
|
data.setLayer(isLayeredInFront, isLayeredInHUD);
|
||||||
|
data.setShapeKey(invalidatePayloadShapeKey, isWireframe);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,16 +302,6 @@ void Model::setRenderItemsNeedUpdate() {
|
||||||
emit requestRenderUpdate();
|
emit requestRenderUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Model::initJointTransforms() {
|
|
||||||
if (isLoaded()) {
|
|
||||||
glm::mat4 modelOffset = glm::scale(_scale) * glm::translate(_offset);
|
|
||||||
_rig.setModelOffset(modelOffset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Model::init() {
|
|
||||||
}
|
|
||||||
|
|
||||||
void Model::reset() {
|
void Model::reset() {
|
||||||
if (isLoaded()) {
|
if (isLoaded()) {
|
||||||
const FBXGeometry& geometry = getFBXGeometry();
|
const FBXGeometry& geometry = getFBXGeometry();
|
||||||
|
|
|
@ -122,7 +122,6 @@ public:
|
||||||
void setIsWireframe(bool isWireframe) { _isWireframe = isWireframe; }
|
void setIsWireframe(bool isWireframe) { _isWireframe = isWireframe; }
|
||||||
bool isWireframe() const { return _isWireframe; }
|
bool isWireframe() const { return _isWireframe; }
|
||||||
|
|
||||||
void init();
|
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
void setSnapModelToRegistrationPoint(bool snapModelToRegistrationPoint, const glm::vec3& registrationPoint);
|
void setSnapModelToRegistrationPoint(bool snapModelToRegistrationPoint, const glm::vec3& registrationPoint);
|
||||||
|
@ -346,11 +345,7 @@ protected:
|
||||||
// hook for derived classes to be notified when setUrl invalidates the current model.
|
// hook for derived classes to be notified when setUrl invalidates the current model.
|
||||||
virtual void onInvalidate() {};
|
virtual void onInvalidate() {};
|
||||||
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
virtual void deleteGeometry();
|
virtual void deleteGeometry();
|
||||||
void initJointTransforms();
|
|
||||||
|
|
||||||
QVector<float> _blendshapeCoefficients;
|
QVector<float> _blendshapeCoefficients;
|
||||||
|
|
||||||
|
@ -419,6 +414,8 @@ protected:
|
||||||
bool _isLayeredInFront { false };
|
bool _isLayeredInFront { false };
|
||||||
bool _isLayeredInHUD { false };
|
bool _isLayeredInHUD { false };
|
||||||
|
|
||||||
|
bool shouldInvalidatePayloadShapeKey(int meshIndex);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
float _loadingPriority { 0.0f };
|
float _loadingPriority { 0.0f };
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue