Fixed seg fault, don't attempt to transfer joints between different models

(as opposed to different LODs).
This commit is contained in:
Andrzej Kapolka 2014-02-28 14:29:18 -08:00
parent 21a149348b
commit 0bb3752121
2 changed files with 62 additions and 49 deletions

View file

@ -102,43 +102,7 @@ void Model::reset() {
void Model::simulate(float deltaTime, bool delayLoad) {
// update our LOD
QVector<JointState> newJointStates;
if (_geometry) {
QSharedPointer<NetworkGeometry> geometry = _geometry;
if (_nextGeometry) {
if (!delayLoad) {
_nextGeometry->setLoadPriority(this, -_lodDistance);
_nextGeometry->ensureLoading();
}
if (_nextGeometry->isLoaded()) {
geometry = _nextGeometry;
_nextGeometry.clear();
}
}
geometry = geometry->getLODOrFallback(_lodDistance, _lodHysteresis, delayLoad);
if (_geometry != geometry) {
if (!_jointStates.isEmpty()) {
// copy the existing joint states
const FBXGeometry& oldGeometry = _geometry->getFBXGeometry();
const FBXGeometry& newGeometry = geometry->getFBXGeometry();
newJointStates = createJointStates(newGeometry);
for (QHash<QString, int>::const_iterator it = oldGeometry.jointIndices.constBegin();
it != oldGeometry.jointIndices.constEnd(); it++) {
int newIndex = newGeometry.jointIndices.value(it.key());
if (newIndex != 0) {
newJointStates[newIndex - 1] = _jointStates.at(it.value() - 1);
}
}
}
deleteGeometry();
_dilatedTextures.clear();
_geometry = geometry;
}
if (!delayLoad) {
_geometry->setLoadPriority(this, -_lodDistance);
_geometry->ensureLoading();
}
}
QVector<JointState> newJointStates = updateGeometry(delayLoad);
if (!isActive()) {
return;
}
@ -451,19 +415,10 @@ void Model::setURL(const QUrl& url, const QUrl& fallback, bool retainCurrent, bo
_url = url;
// if so instructed, keep the current geometry until the new one is loaded
_nextGeometry = Application::getInstance()->getGeometryCache()->getGeometry(url, fallback, delayLoad);
if (retainCurrent && isActive() && !_nextGeometry->isLoaded()) {
return;
_nextBaseGeometry = _nextGeometry = Application::getInstance()->getGeometryCache()->getGeometry(url, fallback, delayLoad);
if (!retainCurrent || !isActive() || _nextGeometry->isLoaded()) {
applyNextGeometry();
}
// delete our local geometry and custom textures
deleteGeometry();
_dilatedTextures.clear();
_lodHysteresis = NetworkGeometry::NO_HYSTERESIS;
// we retain a reference to the base geometry so that its reference count doesn't fall to zero
_baseGeometry = _geometry = _nextGeometry;
_nextGeometry.reset();
}
glm::vec4 Model::computeAverageColor() const {
@ -826,6 +781,61 @@ void Model::applyCollision(CollisionInfo& collision) {
}
}
QVector<Model::JointState> Model::updateGeometry(bool delayLoad) {
QVector<JointState> newJointStates;
if (_nextGeometry) {
_nextGeometry = _nextGeometry->getLODOrFallback(_lodDistance, _lodHysteresis, delayLoad);
if (!delayLoad) {
_nextGeometry->setLoadPriority(this, -_lodDistance);
_nextGeometry->ensureLoading();
}
if (_nextGeometry->isLoaded()) {
applyNextGeometry();
return newJointStates;
}
}
if (!_geometry) {
return newJointStates;
}
QSharedPointer<NetworkGeometry> geometry = _geometry->getLODOrFallback(_lodDistance, _lodHysteresis, delayLoad);
if (_geometry != geometry) {
if (!_jointStates.isEmpty()) {
// copy the existing joint states
const FBXGeometry& oldGeometry = _geometry->getFBXGeometry();
const FBXGeometry& newGeometry = geometry->getFBXGeometry();
newJointStates = createJointStates(newGeometry);
for (QHash<QString, int>::const_iterator it = oldGeometry.jointIndices.constBegin();
it != oldGeometry.jointIndices.constEnd(); it++) {
int newIndex = newGeometry.jointIndices.value(it.key());
if (newIndex != 0) {
newJointStates[newIndex - 1] = _jointStates.at(it.value() - 1);
}
}
}
deleteGeometry();
_dilatedTextures.clear();
_geometry = geometry;
}
if (!delayLoad) {
_geometry->setLoadPriority(this, -_lodDistance);
_geometry->ensureLoading();
}
return newJointStates;
}
void Model::applyNextGeometry() {
// delete our local geometry and custom textures
deleteGeometry();
_dilatedTextures.clear();
_lodHysteresis = NetworkGeometry::NO_HYSTERESIS;
// we retain a reference to the base geometry so that its reference count doesn't fall to zero
_baseGeometry = _nextBaseGeometry;
_geometry = _nextGeometry;
_nextBaseGeometry.reset();
_nextGeometry.reset();
}
void Model::deleteGeometry() {
foreach (Model* attachment, _attachments) {
delete attachment;

View file

@ -237,10 +237,13 @@ protected:
private:
QVector<JointState> updateGeometry(bool delayLoad);
void applyNextGeometry();
void deleteGeometry();
void renderMeshes(float alpha, bool translucent);
QSharedPointer<NetworkGeometry> _baseGeometry; ///< reference required to prevent collection of base
QSharedPointer<NetworkGeometry> _nextBaseGeometry;
QSharedPointer<NetworkGeometry> _nextGeometry;
float _lodDistance;
float _lodHysteresis;