diff --git a/CHANGELOG.md b/CHANGELOG.md index aa1cab9eab..d36f5e6ad3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -74,6 +74,7 @@ Bug #6363: Some scripts in Morrowland fail to work Bug #6376: Creatures should be able to use torches Bug #6386: Artifacts in water reflection due to imprecise screen-space coordinate computation + Bug #6416: Morphs are applied to the wrong target Feature #890: OpenMW-CS: Column filtering Feature #2554: Modifying an object triggers the instances table to scroll to the corresponding record Feature #2780: A way to see current OpenMW version in the console diff --git a/components/nifosg/controller.cpp b/components/nifosg/controller.cpp index 956fe2e489..54300d34e8 100644 --- a/components/nifosg/controller.cpp +++ b/components/nifosg/controller.cpp @@ -224,7 +224,7 @@ void GeomMorpherController::operator()(SceneUtil::MorphGeometry* node, osg::Node if (mKeyFrames.size() <= 1) return; float input = getInputValue(nv); - int i = 0; + int i = 1; for (std::vector::iterator it = mKeyFrames.begin()+1; it != mKeyFrames.end(); ++it,++i) { float val = 0; diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index dad5feb041..2fa533518c 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -1264,8 +1264,9 @@ namespace NifOsg const std::vector& morphs = morpher->data.getPtr()->mMorphs; if (morphs.empty()) return morphGeom; - // Note we are not interested in morph 0, which just contains the original vertices - for (unsigned int i = 1; i < morphs.size(); ++i) + if (morphs[0].mVertices.size() != static_cast(sourceGeometry->getVertexArray())->size()) + return morphGeom; + for (unsigned int i = 0; i < morphs.size(); ++i) morphGeom->addMorphTarget(new osg::Vec3Array(morphs[i].mVertices.size(), morphs[i].mVertices.data()), 0.f); return morphGeom; diff --git a/components/sceneutil/morphgeometry.cpp b/components/sceneutil/morphgeometry.cpp index 59adbffffe..3e34e3dedc 100644 --- a/components/sceneutil/morphgeometry.cpp +++ b/components/sceneutil/morphgeometry.cpp @@ -104,8 +104,8 @@ void MorphGeometry::accept(osg::PrimitiveFunctor& func) const osg::BoundingBox MorphGeometry::computeBoundingBox() const { bool anyMorphTarget = false; - for (unsigned int i=0; i 0) + for (unsigned int i=1; i(mSourceGeometry->getVertexArray()); - std::vector vertBounds(sourceVerts.size()); + const osg::Vec3Array* sourceVerts = static_cast(mSourceGeometry->getVertexArray()); + if (mMorphTargets.size() != 0) + sourceVerts = mMorphTargets[0].getOffsets(); + std::vector vertBounds(sourceVerts->size()); // Since we don't know what combinations of morphs are being applied we need to keep track of a bounding box for each vertex. // The minimum/maximum of the box is the minimum/maximum offset the vertex can have from its starting position. @@ -132,7 +134,7 @@ osg::BoundingBox MorphGeometry::computeBoundingBox() const for (unsigned int i=0; igetTraversalNumber() || !mDirty) + if (mLastFrameNumber == nv->getTraversalNumber() || !mDirty || mMorphTargets.size() == 0) { osg::Geometry& geom = *getGeometry(mLastFrameNumber); nv->pushOntoNodePath(&geom); @@ -169,13 +171,13 @@ void MorphGeometry::cull(osg::NodeVisitor *nv) mLastFrameNumber = nv->getTraversalNumber(); osg::Geometry& geom = *getGeometry(mLastFrameNumber); - const osg::Vec3Array* positionSrc = static_cast(mSourceGeometry->getVertexArray()); + const osg::Vec3Array* positionSrc = mMorphTargets[0].getOffsets(); osg::Vec3Array* positionDst = static_cast(geom.getVertexArray()); assert(positionSrc->size() == positionDst->size()); for (unsigned int vertex=0; vertexsize(); ++vertex) (*positionDst)[vertex] = (*positionSrc)[vertex]; - for (unsigned int i=0; i