mirror of
https://github.com/overte-org/overte.git
synced 2025-04-19 15:43:50 +02:00
Merge branch 'master' of github.com:highfidelity/hifi into black-bis
This commit is contained in:
commit
9c06967ac1
9 changed files with 95 additions and 81 deletions
|
@ -22,7 +22,7 @@
|
|||
|
||||
class Animation;
|
||||
|
||||
typedef QSharedPointer<Animation> AnimationPointer;
|
||||
using AnimationPointer = QSharedPointer<Animation>;
|
||||
|
||||
class AnimationCache : public ResourceCache, public Dependency {
|
||||
Q_OBJECT
|
||||
|
|
|
@ -24,12 +24,18 @@ bool MaterialEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityP
|
|||
if (entity->getMaterialMappingPos() != _materialMappingPos || entity->getMaterialMappingScale() != _materialMappingScale || entity->getMaterialMappingRot() != _materialMappingRot) {
|
||||
return true;
|
||||
}
|
||||
if (!_texturesLoaded) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void MaterialEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) {
|
||||
withWriteLock([&] {
|
||||
_drawMaterial = entity->getMaterial();
|
||||
if (_drawMaterial != entity->getMaterial()) {
|
||||
_texturesLoaded = false;
|
||||
_drawMaterial = entity->getMaterial();
|
||||
}
|
||||
_parentID = entity->getParentID();
|
||||
_materialMappingPos = entity->getMaterialMappingPos();
|
||||
_materialMappingScale = entity->getMaterialMappingScale();
|
||||
|
@ -38,6 +44,12 @@ void MaterialEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer&
|
|||
const float MATERIAL_ENTITY_SCALE = 0.5f;
|
||||
_renderTransform.postScale(MATERIAL_ENTITY_SCALE);
|
||||
_renderTransform.postScale(ENTITY_ITEM_DEFAULT_DIMENSIONS);
|
||||
|
||||
bool newTexturesLoaded = _drawMaterial ? !_drawMaterial->isMissingTexture() : false;
|
||||
if (!_texturesLoaded && newTexturesLoaded) {
|
||||
_drawMaterial->checkResetOpacityMap();
|
||||
}
|
||||
_texturesLoaded = newTexturesLoaded;
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@ private:
|
|||
glm::vec2 _materialMappingPos;
|
||||
glm::vec2 _materialMappingScale;
|
||||
float _materialMappingRot;
|
||||
bool _texturesLoaded { false };
|
||||
|
||||
std::shared_ptr<NetworkMaterial> _drawMaterial;
|
||||
};
|
||||
|
|
|
@ -975,14 +975,21 @@ QStringList RenderableModelEntityItem::getJointNames() const {
|
|||
return result;
|
||||
}
|
||||
|
||||
// FIXME: deprecated; remove >= RC67
|
||||
bool RenderableModelEntityItem::getMeshes(MeshProxyList& result) {
|
||||
auto model = getModel();
|
||||
if (!model || !model->isLoaded()) {
|
||||
return false;
|
||||
void RenderableModelEntityItem::setAnimationURL(const QString& url) {
|
||||
QString oldURL = getAnimationURL();
|
||||
ModelEntityItem::setAnimationURL(url);
|
||||
if (oldURL != getAnimationURL()) {
|
||||
_needsAnimationReset = true;
|
||||
}
|
||||
BLOCKING_INVOKE_METHOD(model.get(), "getMeshes", Q_RETURN_ARG(MeshProxyList, result));
|
||||
return !result.isEmpty();
|
||||
}
|
||||
|
||||
bool RenderableModelEntityItem::needsAnimationReset() const {
|
||||
return _needsAnimationReset;
|
||||
}
|
||||
|
||||
QString RenderableModelEntityItem::getAnimationURLAndReset() {
|
||||
_needsAnimationReset = false;
|
||||
return getAnimationURL();
|
||||
}
|
||||
|
||||
scriptable::ScriptableModelBase render::entities::ModelEntityRenderer::getScriptableModel() {
|
||||
|
@ -1068,6 +1075,13 @@ void RenderableModelEntityItem::copyAnimationJointDataToModel() {
|
|||
}
|
||||
}
|
||||
|
||||
bool RenderableModelEntityItem::readyToAnimate() const {
|
||||
return resultWithReadLock<bool>([&] {
|
||||
float firstFrame = _animationProperties.getFirstFrame();
|
||||
return (firstFrame >= 0.0f) && (firstFrame <= _animationProperties.getLastFrame());
|
||||
});
|
||||
}
|
||||
|
||||
using namespace render;
|
||||
using namespace render::entities;
|
||||
|
||||
|
@ -1155,7 +1169,7 @@ void ModelEntityRenderer::animate(const TypedEntityPointer& entity) {
|
|||
|
||||
const QVector<glm::quat>& rotations = frames[_lastKnownCurrentFrame].rotations;
|
||||
const QVector<glm::vec3>& translations = frames[_lastKnownCurrentFrame].translations;
|
||||
|
||||
|
||||
jointsData.resize(_jointMapping.size());
|
||||
for (int j = 0; j < _jointMapping.size(); j++) {
|
||||
int index = _jointMapping[j];
|
||||
|
@ -1169,13 +1183,12 @@ void ModelEntityRenderer::animate(const TypedEntityPointer& entity) {
|
|||
}
|
||||
} else if (index < animationJointNames.size()) {
|
||||
QString jointName = fbxJoints[index].name; // Pushing this here so its not done on every entity, with the exceptions of those allowing for translation
|
||||
|
||||
if (originalFbxIndices.contains(jointName)) {
|
||||
// Making sure the joint names exist in the original model the animation is trying to apply onto. If they do, then remap and get it's translation.
|
||||
int remappedIndex = originalFbxIndices[jointName] - 1; // JointIndeces seem to always start from 1 and the found index is always 1 higher than actual.
|
||||
translationMat = glm::translate(originalFbxJoints[remappedIndex].translation);
|
||||
}
|
||||
}
|
||||
}
|
||||
glm::mat4 rotationMat;
|
||||
if (index < rotations.size()) {
|
||||
rotationMat = glm::mat4_cast(fbxJoints[index].preRotation * rotations[index] * fbxJoints[index].postRotation);
|
||||
|
@ -1477,14 +1490,17 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce
|
|||
if (_animating) {
|
||||
DETAILED_PROFILE_RANGE(simulation_physics, "Animate");
|
||||
|
||||
if (!jointsMapped()) {
|
||||
mapJoints(entity, model->getJointNames());
|
||||
//else the joint have been mapped before but we have a new animation to load
|
||||
} else if (_animation && (_animation->getURL().toString() != entity->getAnimationURL())) {
|
||||
if (_animation && entity->needsAnimationReset()) {
|
||||
//(_animation->getURL().toString() != entity->getAnimationURL())) { // bad check
|
||||
// the joints have been mapped before but we have a new animation to load
|
||||
_animation.reset();
|
||||
_jointMappingCompleted = false;
|
||||
mapJoints(entity, model->getJointNames());
|
||||
}
|
||||
if (!(entity->getAnimationFirstFrame() < 0) && !(entity->getAnimationFirstFrame() > entity->getAnimationLastFrame())) {
|
||||
|
||||
if (!_jointMappingCompleted) {
|
||||
mapJoints(entity, model);
|
||||
}
|
||||
if (entity->readyToAnimate()) {
|
||||
animate(entity);
|
||||
}
|
||||
emit requestRenderUpdate();
|
||||
|
@ -1518,19 +1534,20 @@ void ModelEntityRenderer::doRender(RenderArgs* args) {
|
|||
#endif
|
||||
}
|
||||
|
||||
void ModelEntityRenderer::mapJoints(const TypedEntityPointer& entity, const QStringList& modelJointNames) {
|
||||
void ModelEntityRenderer::mapJoints(const TypedEntityPointer& entity, const ModelPointer& model) {
|
||||
// if we don't have animation, or we're already joint mapped then bail early
|
||||
if (!entity->hasAnimation() || jointsMapped()) {
|
||||
if (!entity->hasAnimation()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_animation || _animation->getURL().toString() != entity->getAnimationURL()) {
|
||||
_animation = DependencyManager::get<AnimationCache>()->getAnimation(entity->getAnimationURL());
|
||||
if (!_animation) {
|
||||
_animation = DependencyManager::get<AnimationCache>()->getAnimation(entity->getAnimationURLAndReset());
|
||||
}
|
||||
|
||||
if (_animation && _animation->isLoaded()) {
|
||||
QStringList animationJointNames = _animation->getJointNames();
|
||||
|
||||
auto modelJointNames = model->getJointNames();
|
||||
if (modelJointNames.size() > 0 && animationJointNames.size() > 0) {
|
||||
_jointMapping.resize(modelJointNames.size());
|
||||
for (int i = 0; i < modelJointNames.size(); i++) {
|
||||
|
|
|
@ -112,21 +112,25 @@ public:
|
|||
virtual int getJointIndex(const QString& name) const override;
|
||||
virtual QStringList getJointNames() const override;
|
||||
|
||||
bool getMeshes(MeshProxyList& result) override; // deprecated
|
||||
void setAnimationURL(const QString& url) override;
|
||||
bool needsAnimationReset() const;
|
||||
QString getAnimationURLAndReset();
|
||||
|
||||
private:
|
||||
bool needsUpdateModelBounds() const;
|
||||
void autoResizeJointArrays();
|
||||
void copyAnimationJointDataToModel();
|
||||
|
||||
bool readyToAnimate() const;
|
||||
void getCollisionGeometryResource();
|
||||
|
||||
GeometryResource::Pointer _compoundShapeResource;
|
||||
bool _jointMapCompleted { false };
|
||||
bool _originalTexturesRead { false };
|
||||
std::vector<int> _jointMap;
|
||||
QVariantMap _originalTextures;
|
||||
bool _jointMapCompleted { false };
|
||||
bool _originalTexturesRead { false };
|
||||
bool _dimensionsInitialized { true };
|
||||
bool _needsJointSimulation { false };
|
||||
bool _needsAnimationReset { false };
|
||||
};
|
||||
|
||||
namespace render { namespace entities {
|
||||
|
@ -167,8 +171,7 @@ protected:
|
|||
|
||||
private:
|
||||
void animate(const TypedEntityPointer& entity);
|
||||
void mapJoints(const TypedEntityPointer& entity, const QStringList& modelJointNames);
|
||||
bool jointsMapped() const { return _jointMappingCompleted; }
|
||||
void mapJoints(const TypedEntityPointer& entity, const ModelPointer& model);
|
||||
|
||||
// Transparency is handled in ModelMeshPartPayload
|
||||
virtual bool isTransparent() const override { return false; }
|
||||
|
|
|
@ -629,30 +629,6 @@ bool ModelEntityItem::getAnimationHold() const {
|
|||
});
|
||||
}
|
||||
|
||||
void ModelEntityItem::setAnimationFirstFrame(float firstFrame) {
|
||||
withWriteLock([&] {
|
||||
_animationProperties.setFirstFrame(firstFrame);
|
||||
});
|
||||
}
|
||||
|
||||
float ModelEntityItem::getAnimationFirstFrame() const {
|
||||
return resultWithReadLock<float>([&] {
|
||||
return _animationProperties.getFirstFrame();
|
||||
});
|
||||
}
|
||||
|
||||
void ModelEntityItem::setAnimationLastFrame(float lastFrame) {
|
||||
withWriteLock([&] {
|
||||
_animationProperties.setLastFrame(lastFrame);
|
||||
});
|
||||
}
|
||||
|
||||
float ModelEntityItem::getAnimationLastFrame() const {
|
||||
return resultWithReadLock<float>([&] {
|
||||
return _animationProperties.getLastFrame();
|
||||
});
|
||||
}
|
||||
|
||||
bool ModelEntityItem::getAnimationIsPlaying() const {
|
||||
return resultWithReadLock<bool>([&] {
|
||||
return _animationProperties.getRunning();
|
||||
|
|
|
@ -79,9 +79,10 @@ public:
|
|||
// Animation related items...
|
||||
AnimationPropertyGroup getAnimationProperties() const;
|
||||
|
||||
// TODO: audit and remove unused Animation accessors
|
||||
bool hasAnimation() const;
|
||||
QString getAnimationURL() const;
|
||||
void setAnimationURL(const QString& url);
|
||||
virtual void setAnimationURL(const QString& url);
|
||||
|
||||
void setAnimationCurrentFrame(float value);
|
||||
void setAnimationIsPlaying(bool value);
|
||||
|
@ -99,12 +100,6 @@ public:
|
|||
void setRelayParentJoints(bool relayJoints);
|
||||
bool getRelayParentJoints() const;
|
||||
|
||||
void setAnimationFirstFrame(float firstFrame);
|
||||
float getAnimationFirstFrame() const;
|
||||
|
||||
void setAnimationLastFrame(float lastFrame);
|
||||
float getAnimationLastFrame() const;
|
||||
|
||||
bool getAnimationIsPlaying() const;
|
||||
float getAnimationCurrentFrame() const;
|
||||
float getAnimationFPS() const;
|
||||
|
|
|
@ -414,33 +414,13 @@ bool Geometry::areTexturesLoaded() const {
|
|||
if (!_areTexturesLoaded) {
|
||||
for (auto& material : _materials) {
|
||||
// Check if material textures are loaded
|
||||
bool materialMissingTexture = std::any_of(material->_textures.cbegin(), material->_textures.cend(),
|
||||
[](const NetworkMaterial::Textures::value_type& it) {
|
||||
auto texture = it.texture;
|
||||
if (!texture) {
|
||||
return false;
|
||||
}
|
||||
// Failed texture downloads need to be considered as 'loaded'
|
||||
// or the object will never fade in
|
||||
bool finished = texture->isFailed() || (texture->isLoaded() && texture->getGPUTexture() && texture->getGPUTexture()->isDefined());
|
||||
if (!finished) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
bool materialMissingTexture = material->isMissingTexture();
|
||||
|
||||
if (materialMissingTexture) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If material textures are loaded, check the material translucency
|
||||
// FIXME: This should not be done here. The opacity map should already be reset in Material::setTextureMap.
|
||||
// However, currently that code can be called before the albedo map is defined, so resetOpacityMap will fail.
|
||||
// Geometry::areTexturesLoaded() is called repeatedly until it returns true, so we do the check here for now
|
||||
const auto albedoTexture = material->_textures[NetworkMaterial::MapChannel::ALBEDO_MAP];
|
||||
if (albedoTexture.texture) {
|
||||
material->resetOpacityMap();
|
||||
}
|
||||
material->checkResetOpacityMap();
|
||||
}
|
||||
|
||||
_areTexturesLoaded = true;
|
||||
|
@ -783,4 +763,31 @@ void NetworkMaterial::setTextures(const QVariantMap& textureMap) {
|
|||
}
|
||||
}
|
||||
|
||||
bool NetworkMaterial::isMissingTexture() {
|
||||
for (auto& networkTexture : _textures) {
|
||||
auto& texture = networkTexture.texture;
|
||||
if (!texture) {
|
||||
continue;
|
||||
}
|
||||
// Failed texture downloads need to be considered as 'loaded'
|
||||
// or the object will never fade in
|
||||
bool finished = texture->isFailed() || (texture->isLoaded() && texture->getGPUTexture() && texture->getGPUTexture()->isDefined());
|
||||
if (!finished) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void NetworkMaterial::checkResetOpacityMap() {
|
||||
// If material textures are loaded, check the material translucency
|
||||
// FIXME: This should not be done here. The opacity map should already be reset in Material::setTextureMap.
|
||||
// However, currently that code can be called before the albedo map is defined, so resetOpacityMap will fail.
|
||||
// Geometry::areTexturesLoaded() is called repeatedly until it returns true, so we do the check here for now
|
||||
const auto& albedoTexture = _textures[NetworkMaterial::MapChannel::ALBEDO_MAP];
|
||||
if (albedoTexture.texture) {
|
||||
resetOpacityMap();
|
||||
}
|
||||
}
|
||||
|
||||
#include "ModelCache.moc"
|
||||
|
|
|
@ -177,6 +177,9 @@ public:
|
|||
void setScatteringMap(const QUrl& url);
|
||||
void setLightmapMap(const QUrl& url);
|
||||
|
||||
bool isMissingTexture();
|
||||
void checkResetOpacityMap();
|
||||
|
||||
protected:
|
||||
friend class Geometry;
|
||||
|
||||
|
|
Loading…
Reference in a new issue