mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 08:49:05 +02:00
possible fix for collisions again
This commit is contained in:
parent
f413ad3312
commit
a3c85bd438
4 changed files with 96 additions and 144 deletions
|
@ -76,34 +76,6 @@ void RenderableModelEntityItem::setUnscaledDimensions(const glm::vec3& value) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderableModelEntityItem::doInitialModelSimulation() {
|
|
||||||
DETAILED_PROFILE_RANGE(simulation_physics, __FUNCTION__);
|
|
||||||
ModelPointer model = getModel();
|
|
||||||
if (!model) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// The machinery for updateModelBounds will give existing models the opportunity to fix their
|
|
||||||
// translation/rotation/scale/registration. The first two are straightforward, but the latter two have guards to
|
|
||||||
// make sure they don't happen after they've already been set. Here we reset those guards. This doesn't cause the
|
|
||||||
// entity values to change -- it just allows the model to match once it comes in.
|
|
||||||
model->setScaleToFit(false, getScaledDimensions());
|
|
||||||
model->setSnapModelToRegistrationPoint(false, getRegistrationPoint());
|
|
||||||
|
|
||||||
// now recalculate the bounds and registration
|
|
||||||
model->setScaleToFit(true, getScaledDimensions());
|
|
||||||
model->setSnapModelToRegistrationPoint(true, getRegistrationPoint());
|
|
||||||
model->setRotation(getWorldOrientation());
|
|
||||||
model->setTranslation(getWorldPosition());
|
|
||||||
|
|
||||||
glm::vec3 scale = model->getScale();
|
|
||||||
model->setUseDualQuaternionSkinning(!isNonUniformScale(scale));
|
|
||||||
|
|
||||||
if (_needsInitialSimulation) {
|
|
||||||
model->simulate(0.0f);
|
|
||||||
_needsInitialSimulation = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RenderableModelEntityItem::autoResizeJointArrays() {
|
void RenderableModelEntityItem::autoResizeJointArrays() {
|
||||||
ModelPointer model = getModel();
|
ModelPointer model = getModel();
|
||||||
if (model && model->isLoaded() && !_needsInitialSimulation) {
|
if (model && model->isLoaded() && !_needsInitialSimulation) {
|
||||||
|
@ -217,6 +189,9 @@ void RenderableModelEntityItem::updateModelBounds() {
|
||||||
glm::vec3 scale = model->getScale();
|
glm::vec3 scale = model->getScale();
|
||||||
model->setUseDualQuaternionSkinning(!isNonUniformScale(scale));
|
model->setUseDualQuaternionSkinning(!isNonUniformScale(scale));
|
||||||
model->updateRenderItems();
|
model->updateRenderItems();
|
||||||
|
|
||||||
|
markDirtyFlags(Simulation::DIRTY_SHAPE | Simulation::DIRTY_MASS);
|
||||||
|
locationChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -276,7 +251,18 @@ bool RenderableModelEntityItem::findDetailedParabolaIntersection(const glm::vec3
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderableModelEntityItem::fetchCollisionGeometryResource() {
|
void RenderableModelEntityItem::fetchCollisionGeometryResource() {
|
||||||
_collisionGeometryResource = DependencyManager::get<ModelCache>()->getCollisionGeometryResource(getCollisionShapeURL());
|
_collisionGeometryResource = DependencyManager::get<ModelCache>()->getCollisionGeometryResource(getCompoundShapeURL());
|
||||||
|
if (_collisionGeometryResource) {
|
||||||
|
if (_collisionGeometryResource->isLoaded()) {
|
||||||
|
markDirtyFlags(Simulation::DIRTY_SHAPE | Simulation::DIRTY_MASS);
|
||||||
|
locationChanged();
|
||||||
|
} else {
|
||||||
|
connect(_collisionGeometryResource.get(), &GeometryResource::finished, this, [&] {
|
||||||
|
markDirtyFlags(Simulation::DIRTY_SHAPE | Simulation::DIRTY_MASS);
|
||||||
|
locationChanged();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RenderableModelEntityItem::unableToLoadCollisionShape() {
|
bool RenderableModelEntityItem::unableToLoadCollisionShape() {
|
||||||
|
@ -290,7 +276,7 @@ void RenderableModelEntityItem::setShapeType(ShapeType type) {
|
||||||
ModelEntityItem::setShapeType(type);
|
ModelEntityItem::setShapeType(type);
|
||||||
auto shapeType = getShapeType();
|
auto shapeType = getShapeType();
|
||||||
if (shapeType == SHAPE_TYPE_COMPOUND || shapeType == SHAPE_TYPE_SIMPLE_COMPOUND) {
|
if (shapeType == SHAPE_TYPE_COMPOUND || shapeType == SHAPE_TYPE_SIMPLE_COMPOUND) {
|
||||||
if (!_collisionGeometryResource && !getCollisionShapeURL().isEmpty()) {
|
if (!_collisionGeometryResource && !getCompoundShapeURL().isEmpty()) {
|
||||||
fetchCollisionGeometryResource();
|
fetchCollisionGeometryResource();
|
||||||
}
|
}
|
||||||
} else if (_collisionGeometryResource && !getCompoundShapeURL().isEmpty()) {
|
} else if (_collisionGeometryResource && !getCompoundShapeURL().isEmpty()) {
|
||||||
|
@ -302,63 +288,32 @@ void RenderableModelEntityItem::setShapeType(ShapeType type) {
|
||||||
void RenderableModelEntityItem::setCompoundShapeURL(const QString& url) {
|
void RenderableModelEntityItem::setCompoundShapeURL(const QString& url) {
|
||||||
auto currentCompoundShapeURL = getCompoundShapeURL();
|
auto currentCompoundShapeURL = getCompoundShapeURL();
|
||||||
ModelEntityItem::setCompoundShapeURL(url);
|
ModelEntityItem::setCompoundShapeURL(url);
|
||||||
if (getCompoundShapeURL() != currentCompoundShapeURL) {
|
if (url != currentCompoundShapeURL && !url.isEmpty()) {
|
||||||
auto shapeType = getShapeType();
|
auto shapeType = getShapeType();
|
||||||
if (shapeType == SHAPE_TYPE_COMPOUND || shapeType == SHAPE_TYPE_SIMPLE_COMPOUND) {
|
if (shapeType == SHAPE_TYPE_COMPOUND || shapeType == SHAPE_TYPE_SIMPLE_COMPOUND) {
|
||||||
fetchCollisionGeometryResource();
|
fetchCollisionGeometryResource();
|
||||||
markDirtyFlags(Simulation::DIRTY_SHAPE | Simulation::DIRTY_MASS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RenderableModelEntityItem::setModelURL(const QString& url) {
|
|
||||||
auto currentModelURL = getModelURL();
|
|
||||||
ModelEntityItem::setModelURL(url);
|
|
||||||
if (getModelURL() != currentModelURL) {
|
|
||||||
auto shapeType = getShapeType();
|
|
||||||
if (shapeType == SHAPE_TYPE_COMPOUND || shapeType == SHAPE_TYPE_SIMPLE_COMPOUND) {
|
|
||||||
fetchCollisionGeometryResource();
|
|
||||||
markDirtyFlags(Simulation::DIRTY_SHAPE | Simulation::DIRTY_MASS);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RenderableModelEntityItem::isReadyToComputeShape() const {
|
bool RenderableModelEntityItem::isReadyToComputeShape() const {
|
||||||
ShapeType type = getShapeType();
|
|
||||||
auto model = getModel();
|
auto model = getModel();
|
||||||
auto shapeType = getShapeType();
|
auto shapeType = getShapeType();
|
||||||
if (shapeType == SHAPE_TYPE_COMPOUND || shapeType == SHAPE_TYPE_SIMPLE_COMPOUND) {
|
if (shapeType == SHAPE_TYPE_COMPOUND || shapeType == SHAPE_TYPE_SIMPLE_COMPOUND) {
|
||||||
auto shapeURL = getCollisionShapeURL();
|
auto shapeURL = getCompoundShapeURL();
|
||||||
|
// we need a render geometry with a scale to proceed
|
||||||
if (!model || shapeURL.isEmpty()) {
|
if (model && !model->getURL().isEmpty() && !shapeURL.isEmpty() && _dimensionsInitialized && model->isLoaded()) {
|
||||||
return false;
|
if (!_collisionGeometryResource) {
|
||||||
}
|
|
||||||
|
|
||||||
if (model->getURL().isEmpty() || !_dimensionsInitialized) {
|
|
||||||
// we need a render geometry with a scale to proceed, so give up.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (model->isLoaded()) {
|
|
||||||
if (!shapeURL.isEmpty() && !_collisionGeometryResource) {
|
|
||||||
const_cast<RenderableModelEntityItem*>(this)->fetchCollisionGeometryResource();
|
const_cast<RenderableModelEntityItem*>(this)->fetchCollisionGeometryResource();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_collisionGeometryResource && _collisionGeometryResource->isLoaded() && _collisionGeometryResource->isHFMModelLoaded()) {
|
// do we have both URLs AND both geometries AND they are both fully loaded?
|
||||||
// we have both URLs AND both geometries AND they are both fully loaded.
|
return _collisionGeometryResource && _collisionGeometryResource->isLoaded() && _collisionGeometryResource->isHFMModelLoaded();
|
||||||
if (_needsInitialSimulation) {
|
|
||||||
// the _model's offset will be wrong until _needsInitialSimulation is false
|
|
||||||
DETAILED_PERFORMANCE_TIMER("_model->simulate");
|
|
||||||
const_cast<RenderableModelEntityItem*>(this)->doInitialModelSimulation();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// the model is still being downloaded.
|
|
||||||
return false;
|
return false;
|
||||||
} else if (type >= SHAPE_TYPE_SIMPLE_HULL && type <= SHAPE_TYPE_STATIC_MESH) {
|
} else if (shapeType >= SHAPE_TYPE_SIMPLE_HULL && shapeType <= SHAPE_TYPE_STATIC_MESH) {
|
||||||
return model && model->isLoaded();
|
return model && model->isLoaded() && _dimensionsInitialized;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -370,20 +325,31 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) {
|
||||||
ShapeType type = getShapeType();
|
ShapeType type = getShapeType();
|
||||||
|
|
||||||
auto model = getModel();
|
auto model = getModel();
|
||||||
if (!model || !model->isLoaded()) {
|
if (type >= SHAPE_TYPE_COMPOUND && type <= SHAPE_TYPE_STATIC_MESH) {
|
||||||
type = SHAPE_TYPE_NONE;
|
if (!model) {
|
||||||
|
type = SHAPE_TYPE_NONE;
|
||||||
|
} else if (!model->isLoaded()) {
|
||||||
|
type = SHAPE_TYPE_NONE;
|
||||||
|
if (!model->didVisualGeometryRequestFail()) {
|
||||||
|
markDirtyFlags(Simulation::DIRTY_SHAPE | Simulation::DIRTY_MASS);
|
||||||
|
locationChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type == SHAPE_TYPE_COMPOUND || type == SHAPE_TYPE_SIMPLE_COMPOUND) {
|
||||||
|
if (!_collisionGeometryResource || !_collisionGeometryResource->isLoaded() || !_collisionGeometryResource->isHFMModelLoaded()) {
|
||||||
|
type = SHAPE_TYPE_NONE;
|
||||||
|
if (!_collisionGeometryResource->isFailed()) {
|
||||||
|
markDirtyFlags(Simulation::DIRTY_SHAPE | Simulation::DIRTY_MASS);
|
||||||
|
locationChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == SHAPE_TYPE_COMPOUND) {
|
if (type == SHAPE_TYPE_COMPOUND) {
|
||||||
if (!_collisionGeometryResource || !_collisionGeometryResource->isLoaded() || !_collisionGeometryResource->isHFMModelLoaded()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
updateModelBounds();
|
updateModelBounds();
|
||||||
|
|
||||||
// should never fall in here when collision model not fully loaded
|
|
||||||
// TODO: assert that all geometries exist and are loaded
|
|
||||||
//assert(_model && _model->isLoaded() && _collisionGeometryResource && _collisionGeometryResource->isLoaded());
|
|
||||||
const HFMModel& collisionGeometry = _collisionGeometryResource->getHFMModel();
|
const HFMModel& collisionGeometry = _collisionGeometryResource->getHFMModel();
|
||||||
|
|
||||||
ShapeInfo::PointCollection& pointCollection = shapeInfo.getPointCollection();
|
ShapeInfo::PointCollection& pointCollection = shapeInfo.getPointCollection();
|
||||||
|
@ -460,7 +426,8 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) {
|
||||||
// collision model's extents).
|
// collision model's extents).
|
||||||
|
|
||||||
glm::vec3 dimensions = getScaledDimensions();
|
glm::vec3 dimensions = getScaledDimensions();
|
||||||
glm::vec3 scaleToFit = dimensions / model->getHFMModel().getUnscaledMeshExtents().size();
|
glm::vec3 extents = model->getHFMModel().getUnscaledMeshExtents().size();
|
||||||
|
glm::vec3 scaleToFit = dimensions / extents;
|
||||||
// multiply each point by scale before handing the point-set off to the physics engine.
|
// multiply each point by scale before handing the point-set off to the physics engine.
|
||||||
// also determine the extents of the collision model.
|
// also determine the extents of the collision model.
|
||||||
glm::vec3 registrationOffset = dimensions * (ENTITY_ITEM_DEFAULT_REGISTRATION_POINT - getRegistrationPoint());
|
glm::vec3 registrationOffset = dimensions * (ENTITY_ITEM_DEFAULT_REGISTRATION_POINT - getRegistrationPoint());
|
||||||
|
@ -470,12 +437,10 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) {
|
||||||
pointCollection[i][j] = scaleToFit * (pointCollection[i][j] + model->getOffset()) - registrationOffset;
|
pointCollection[i][j] = scaleToFit * (pointCollection[i][j] + model->getOffset()) - registrationOffset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
shapeInfo.setParams(type, dimensions, getCompoundShapeURL());
|
shapeInfo.setParams(type, 0.5f * extents, getCompoundShapeURL());
|
||||||
adjustShapeInfoByRegistration(shapeInfo);
|
adjustShapeInfoByRegistration(shapeInfo);
|
||||||
} else if (type >= SHAPE_TYPE_SIMPLE_HULL && type <= SHAPE_TYPE_STATIC_MESH) {
|
} else if (type >= SHAPE_TYPE_SIMPLE_HULL && type <= SHAPE_TYPE_STATIC_MESH) {
|
||||||
updateModelBounds();
|
updateModelBounds();
|
||||||
// assert we never fall in here when model not fully loaded
|
|
||||||
assert(model && model->isLoaded());
|
|
||||||
model->updateGeometry();
|
model->updateGeometry();
|
||||||
|
|
||||||
// compute meshPart local transforms
|
// compute meshPart local transforms
|
||||||
|
@ -484,16 +449,16 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) {
|
||||||
int numHFMMeshes = hfmModel.meshes.size();
|
int numHFMMeshes = hfmModel.meshes.size();
|
||||||
int totalNumVertices = 0;
|
int totalNumVertices = 0;
|
||||||
glm::vec3 dimensions = getScaledDimensions();
|
glm::vec3 dimensions = getScaledDimensions();
|
||||||
glm::mat4 invRegistraionOffset = glm::translate(dimensions * (getRegistrationPoint() - ENTITY_ITEM_DEFAULT_REGISTRATION_POINT));
|
glm::mat4 invRegistrationOffset = glm::translate(dimensions * (getRegistrationPoint() - ENTITY_ITEM_DEFAULT_REGISTRATION_POINT));
|
||||||
for (int i = 0; i < numHFMMeshes; i++) {
|
for (int i = 0; i < numHFMMeshes; i++) {
|
||||||
const HFMMesh& mesh = hfmModel.meshes.at(i);
|
const HFMMesh& mesh = hfmModel.meshes.at(i);
|
||||||
if (mesh.clusters.size() > 0) {
|
if (mesh.clusters.size() > 0) {
|
||||||
const HFMCluster& cluster = mesh.clusters.at(0);
|
const HFMCluster& cluster = mesh.clusters.at(0);
|
||||||
auto jointMatrix = model->getRig().getJointTransform(cluster.jointIndex);
|
auto jointMatrix = model->getRig().getJointTransform(cluster.jointIndex);
|
||||||
// we backtranslate by the registration offset so we can apply that offset to the shapeInfo later
|
// we backtranslate by the registration offset so we can apply that offset to the shapeInfo later
|
||||||
localTransforms.push_back(invRegistraionOffset * jointMatrix * cluster.inverseBindMatrix);
|
localTransforms.push_back(invRegistrationOffset * jointMatrix * cluster.inverseBindMatrix);
|
||||||
} else {
|
} else {
|
||||||
localTransforms.push_back(invRegistraionOffset);
|
localTransforms.push_back(invRegistrationOffset);
|
||||||
}
|
}
|
||||||
totalNumVertices += mesh.vertices.size();
|
totalNumVertices += mesh.vertices.size();
|
||||||
}
|
}
|
||||||
|
@ -506,9 +471,6 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) {
|
||||||
|
|
||||||
std::vector<std::shared_ptr<const graphics::Mesh>> meshes;
|
std::vector<std::shared_ptr<const graphics::Mesh>> meshes;
|
||||||
if (type == SHAPE_TYPE_SIMPLE_COMPOUND) {
|
if (type == SHAPE_TYPE_SIMPLE_COMPOUND) {
|
||||||
if (!_collisionGeometryResource || !_collisionGeometryResource->isLoaded() || !_collisionGeometryResource->isHFMModelLoaded()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
auto& hfmMeshes = _collisionGeometryResource->getHFMModel().meshes;
|
auto& hfmMeshes = _collisionGeometryResource->getHFMModel().meshes;
|
||||||
meshes.reserve(hfmMeshes.size());
|
meshes.reserve(hfmMeshes.size());
|
||||||
for (auto& hfmMesh : hfmMeshes) {
|
for (auto& hfmMesh : hfmMeshes) {
|
||||||
|
@ -708,7 +670,7 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
shapeInfo.setParams(type, 0.5f * dimensions, getModelURL());
|
shapeInfo.setParams(type, 0.5f * extents.size(), getModelURL());
|
||||||
adjustShapeInfoByRegistration(shapeInfo);
|
adjustShapeInfoByRegistration(shapeInfo);
|
||||||
} else {
|
} else {
|
||||||
EntityItem::computeShapeInfo(shapeInfo);
|
EntityItem::computeShapeInfo(shapeInfo);
|
||||||
|
@ -749,21 +711,19 @@ bool RenderableModelEntityItem::contains(const glm::vec3& point) const {
|
||||||
bool RenderableModelEntityItem::shouldBePhysical() const {
|
bool RenderableModelEntityItem::shouldBePhysical() const {
|
||||||
bool physicalModelLoaded = false;
|
bool physicalModelLoaded = false;
|
||||||
ShapeType shapeType = getShapeType();
|
ShapeType shapeType = getShapeType();
|
||||||
if (shapeType >= SHAPE_TYPE_SIMPLE_HULL && shapeType <= SHAPE_TYPE_STATIC_MESH) {
|
if (shapeType >= SHAPE_TYPE_COMPOUND && shapeType <= SHAPE_TYPE_STATIC_MESH) {
|
||||||
auto model = getModel();
|
auto model = getModel();
|
||||||
// If we have a model, make sure it hasn't failed to download.
|
// If we have a model, make sure it hasn't failed to download.
|
||||||
// If it has, we'll report back that we shouldn't be physical so that physics aren't held waiting for us to be ready.
|
// If it has, we'll report back that we shouldn't be physical so that physics aren't held waiting for us to be ready.
|
||||||
physicalModelLoaded = model && !model->didVisualGeometryRequestFail();
|
physicalModelLoaded = model && !model->didVisualGeometryRequestFail();
|
||||||
if (shapeType == SHAPE_TYPE_SIMPLE_COMPOUND) {
|
if (shapeType == SHAPE_TYPE_COMPOUND || shapeType == SHAPE_TYPE_SIMPLE_COMPOUND) {
|
||||||
physicalModelLoaded &= _collisionGeometryResource && !_collisionGeometryResource->isFailed();
|
physicalModelLoaded &= _collisionGeometryResource && !_collisionGeometryResource->isFailed();
|
||||||
}
|
}
|
||||||
} else if (shapeType == SHAPE_TYPE_COMPOUND) {
|
|
||||||
physicalModelLoaded = _collisionGeometryResource && !_collisionGeometryResource->isFailed();
|
|
||||||
} else if (shapeType != SHAPE_TYPE_NONE) {
|
} else if (shapeType != SHAPE_TYPE_NONE) {
|
||||||
physicalModelLoaded = true;
|
physicalModelLoaded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return physicalModelLoaded && !isDead() && !isLocalEntity() && QUrl(_modelURL).isValid();
|
return physicalModelLoaded && !isDead() && !isLocalEntity() && QUrl(getModelURL()).isValid();
|
||||||
}
|
}
|
||||||
|
|
||||||
int RenderableModelEntityItem::getJointParent(int index) const {
|
int RenderableModelEntityItem::getJointParent(int index) const {
|
||||||
|
@ -1243,7 +1203,7 @@ void ModelEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPoint
|
||||||
entity->bumpAncestorChainRenderableVersion();
|
entity->bumpAncestorChainRenderableVersion();
|
||||||
emit DependencyManager::get<scriptable::ModelProviderFactory>()->
|
emit DependencyManager::get<scriptable::ModelProviderFactory>()->
|
||||||
modelRemovedFromScene(entity->getEntityItemID(), NestableType::Entity, model);
|
modelRemovedFromScene(entity->getEntityItemID(), NestableType::Entity, model);
|
||||||
withWriteLock([&] { model.reset(); });
|
withWriteLock([&] { _model.reset(); });
|
||||||
}
|
}
|
||||||
_didLastVisualGeometryRequestSucceed = false;
|
_didLastVisualGeometryRequestSucceed = false;
|
||||||
setKey(_didLastVisualGeometryRequestSucceed, model);
|
setKey(_didLastVisualGeometryRequestSucceed, model);
|
||||||
|
@ -1256,33 +1216,34 @@ void ModelEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPoint
|
||||||
connect(model.get(), &Model::requestRenderUpdate, this, &ModelEntityRenderer::requestRenderUpdate);
|
connect(model.get(), &Model::requestRenderUpdate, this, &ModelEntityRenderer::requestRenderUpdate);
|
||||||
connect(model.get(), &Model::setURLFinished, this, [&](bool didVisualGeometryRequestSucceed) {
|
connect(model.get(), &Model::setURLFinished, this, [&](bool didVisualGeometryRequestSucceed) {
|
||||||
const render::ScenePointer& scene = AbstractViewStateInterface::instance()->getMain3DScene();
|
const render::ScenePointer& scene = AbstractViewStateInterface::instance()->getMain3DScene();
|
||||||
withWriteLock([&] {
|
render::Transaction transaction;
|
||||||
setKey(didVisualGeometryRequestSucceed, _model);
|
transaction.updateItem<PayloadProxyInterface>(_renderItemID, [&](PayloadProxyInterface& self) {
|
||||||
_model->setVisibleInScene(_visible, scene);
|
const render::ScenePointer& scene = AbstractViewStateInterface::instance()->getMain3DScene();
|
||||||
_model->setCauterized(_cauterized, scene);
|
withWriteLock([&] {
|
||||||
_model->setCanCastShadow(_canCastShadow, scene);
|
setKey(didVisualGeometryRequestSucceed, _model);
|
||||||
_model->setGroupCulled(entity->getGroupCulled(), scene);
|
_model->setVisibleInScene(_visible, scene);
|
||||||
_model->setTagMask(getTagMask(), scene);
|
_model->setCauterized(_cauterized, scene);
|
||||||
_model->setHifiRenderLayer(getHifiRenderLayer(), scene);
|
_model->setCanCastShadow(_canCastShadow, scene);
|
||||||
_model->setPrimitiveMode(_primitiveMode, scene);
|
_model->setGroupCulled(entity->getGroupCulled(), scene);
|
||||||
_model->setCullWithParent(_cullWithParent, scene);
|
_model->setTagMask(getTagMask(), scene);
|
||||||
_model->setRenderWithZones(_renderWithZones, scene);
|
_model->setHifiRenderLayer(getHifiRenderLayer(), scene);
|
||||||
entity->markDirtyFlags(Simulation::DIRTY_SHAPE | Simulation::DIRTY_MASS);
|
_model->setPrimitiveMode(_primitiveMode, scene);
|
||||||
entity->locationChanged();
|
_model->setCullWithParent(_cullWithParent, scene);
|
||||||
entity->dimensionsChanged();
|
_model->setRenderWithZones(_renderWithZones, scene);
|
||||||
|
});
|
||||||
|
if (didVisualGeometryRequestSucceed) {
|
||||||
|
emit DependencyManager::get<scriptable::ModelProviderFactory>()->
|
||||||
|
modelAddedToScene(entity->getEntityItemID(), NestableType::Entity, model);
|
||||||
|
}
|
||||||
|
_didLastVisualGeometryRequestSucceed = didVisualGeometryRequestSucceed;
|
||||||
|
entity->_originalTexturesRead = false;
|
||||||
|
entity->_needsJointSimulation = true;
|
||||||
|
entity->_needsToRescaleModel = true;
|
||||||
|
entity->updateModelBounds();
|
||||||
|
emit requestRenderUpdate();
|
||||||
});
|
});
|
||||||
if (didVisualGeometryRequestSucceed) {
|
scene->enqueueTransaction(transaction);
|
||||||
emit DependencyManager::get<scriptable::ModelProviderFactory>()->
|
|
||||||
modelAddedToScene(entity->getEntityItemID(), NestableType::Entity, model);
|
|
||||||
}
|
|
||||||
_didLastVisualGeometryRequestSucceed = didVisualGeometryRequestSucceed;
|
|
||||||
entity->_originalTexturesRead = false;
|
|
||||||
entity->_needsJointSimulation = true;
|
|
||||||
entity->_needsToRescaleModel = true;
|
|
||||||
entity->updateModelBounds();
|
|
||||||
emit requestRenderUpdate();
|
|
||||||
});
|
});
|
||||||
model->setLoadingPriority(EntityTreeRenderer::getEntityLoadingPriority(*entity));
|
|
||||||
entity->setModel(model);
|
entity->setModel(model);
|
||||||
withWriteLock([&] { _model = model; });
|
withWriteLock([&] { _model = model; });
|
||||||
}
|
}
|
||||||
|
@ -1291,6 +1252,7 @@ void ModelEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPoint
|
||||||
if (_parsedModelURL != model->getURL()) {
|
if (_parsedModelURL != model->getURL()) {
|
||||||
_texturesLoaded = false;
|
_texturesLoaded = false;
|
||||||
_jointMappingCompleted = false;
|
_jointMappingCompleted = false;
|
||||||
|
model->setLoadingPriority(EntityTreeRenderer::getEntityLoadingPriority(*entity));
|
||||||
model->setURL(_parsedModelURL);
|
model->setURL(_parsedModelURL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1301,7 +1263,6 @@ void ModelEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPoint
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for initializing the model
|
// Check for initializing the model
|
||||||
// FIXME: There are several places below here where we are modifying the entity, which we should not be doing from the renderable
|
|
||||||
if (!entity->_dimensionsInitialized) {
|
if (!entity->_dimensionsInitialized) {
|
||||||
EntityItemProperties properties;
|
EntityItemProperties properties;
|
||||||
properties.setLastEdited(usecTimestampNow()); // we must set the edit time since we're editing it
|
properties.setLastEdited(usecTimestampNow()); // we must set the edit time since we're editing it
|
||||||
|
@ -1335,16 +1296,18 @@ void ModelEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPoint
|
||||||
entity->updateModelBounds();
|
entity->updateModelBounds();
|
||||||
entity->stopModelOverrideIfNoParent();
|
entity->stopModelOverrideIfNoParent();
|
||||||
|
|
||||||
setKey(_didLastVisualGeometryRequestSucceed, model);
|
withWriteLock([&] {
|
||||||
model->setVisibleInScene(_visible, scene);
|
setKey(_didLastVisualGeometryRequestSucceed, model);
|
||||||
model->setCauterized(_cauterized, scene);
|
model->setVisibleInScene(_visible, scene);
|
||||||
model->setCanCastShadow(_canCastShadow, scene);
|
model->setCauterized(_cauterized, scene);
|
||||||
model->setGroupCulled(entity->getGroupCulled(), scene);
|
model->setCanCastShadow(_canCastShadow, scene);
|
||||||
model->setTagMask(getTagMask(), scene);
|
model->setGroupCulled(entity->getGroupCulled(), scene);
|
||||||
model->setHifiRenderLayer(getHifiRenderLayer(), scene);
|
model->setTagMask(getTagMask(), scene);
|
||||||
model->setPrimitiveMode(_primitiveMode, scene);
|
model->setHifiRenderLayer(getHifiRenderLayer(), scene);
|
||||||
model->setCullWithParent(_cullWithParent, scene);
|
model->setPrimitiveMode(_primitiveMode, scene);
|
||||||
model->setRenderWithZones(_renderWithZones, scene);
|
model->setCullWithParent(_cullWithParent, scene);
|
||||||
|
model->setRenderWithZones(_renderWithZones, scene);
|
||||||
|
});
|
||||||
|
|
||||||
if (entity->blendshapesChanged()) {
|
if (entity->blendshapesChanged()) {
|
||||||
model->setBlendshapeCoefficients(entity->getBlendshapeCoefficientVector());
|
model->setBlendshapeCoefficients(entity->getBlendshapeCoefficientVector());
|
||||||
|
|
|
@ -61,7 +61,6 @@ public:
|
||||||
virtual void setUnscaledDimensions(const glm::vec3& value) override;
|
virtual void setUnscaledDimensions(const glm::vec3& value) override;
|
||||||
|
|
||||||
virtual EntityItemProperties getProperties(const EntityPropertyFlags& desiredProperties, bool allowEmptyDesiredProperties) const override;
|
virtual EntityItemProperties getProperties(const EntityPropertyFlags& desiredProperties, bool allowEmptyDesiredProperties) const override;
|
||||||
void doInitialModelSimulation();
|
|
||||||
void updateModelBounds();
|
void updateModelBounds();
|
||||||
|
|
||||||
virtual bool supportsDetailedIntersection() const override;
|
virtual bool supportsDetailedIntersection() const override;
|
||||||
|
@ -76,7 +75,6 @@ public:
|
||||||
|
|
||||||
virtual void setShapeType(ShapeType type) override;
|
virtual void setShapeType(ShapeType type) override;
|
||||||
virtual void setCompoundShapeURL(const QString& url) override;
|
virtual void setCompoundShapeURL(const QString& url) override;
|
||||||
virtual void setModelURL(const QString& url) override;
|
|
||||||
|
|
||||||
virtual bool isReadyToComputeShape() const override;
|
virtual bool isReadyToComputeShape() const override;
|
||||||
virtual void computeShapeInfo(ShapeInfo& shapeInfo) override;
|
virtual void computeShapeInfo(ShapeInfo& shapeInfo) override;
|
||||||
|
@ -185,8 +183,6 @@ private:
|
||||||
bool _hasTransitioned{ false };
|
bool _hasTransitioned{ false };
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const void* _collisionMeshKey { nullptr };
|
|
||||||
|
|
||||||
QUrl _parsedModelURL;
|
QUrl _parsedModelURL;
|
||||||
bool _jointMappingCompleted { false };
|
bool _jointMappingCompleted { false };
|
||||||
QVector<int> _jointMapping; // domain is index into model-joints, range is index into animation-joints
|
QVector<int> _jointMapping; // domain is index into model-joints, range is index into animation-joints
|
||||||
|
|
|
@ -273,7 +273,7 @@ ShapeType ModelEntityItem::getShapeType() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
ShapeType ModelEntityItem::computeTrueShapeType() const {
|
ShapeType ModelEntityItem::computeTrueShapeType() const {
|
||||||
ShapeType type = _shapeType;
|
ShapeType type = resultWithReadLock<ShapeType>([&] { return _shapeType; });
|
||||||
if (type == SHAPE_TYPE_STATIC_MESH && _dynamic) {
|
if (type == SHAPE_TYPE_STATIC_MESH && _dynamic) {
|
||||||
// dynamic is incompatible with STATIC_MESH
|
// dynamic is incompatible with STATIC_MESH
|
||||||
// shouldn't fall in here but just in case --> fall back to COMPOUND
|
// shouldn't fall in here but just in case --> fall back to COMPOUND
|
||||||
|
@ -565,10 +565,6 @@ QString ModelEntityItem::getCompoundShapeURL() const {
|
||||||
return _compoundShapeURL.get();
|
return _compoundShapeURL.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ModelEntityItem::getCollisionShapeURL() const {
|
|
||||||
return getShapeType() == SHAPE_TYPE_COMPOUND ? getCompoundShapeURL() : getModelURL();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ModelEntityItem::setColor(const glm::u8vec3& value) {
|
void ModelEntityItem::setColor(const glm::u8vec3& value) {
|
||||||
withWriteLock([&] {
|
withWriteLock([&] {
|
||||||
_color = value;
|
_color = value;
|
||||||
|
|
|
@ -76,9 +76,6 @@ public:
|
||||||
static const QString DEFAULT_COMPOUND_SHAPE_URL;
|
static const QString DEFAULT_COMPOUND_SHAPE_URL;
|
||||||
QString getCompoundShapeURL() const;
|
QString getCompoundShapeURL() const;
|
||||||
|
|
||||||
// Returns the URL used for the collision shape
|
|
||||||
QString getCollisionShapeURL() const;
|
|
||||||
|
|
||||||
// model related properties
|
// model related properties
|
||||||
virtual void setModelURL(const QString& url);
|
virtual void setModelURL(const QString& url);
|
||||||
virtual void setCompoundShapeURL(const QString& url);
|
virtual void setCompoundShapeURL(const QString& url);
|
||||||
|
|
Loading…
Reference in a new issue