Submitted with fixes by Julian Valentin

This commit is contained in:
Cedric Pinson
2016-06-25 07:49:56 +01:00
committed by Robert Osfield
parent 295da33cdf
commit 0ecb52ff82
26 changed files with 298 additions and 189 deletions

View File

@@ -14,6 +14,7 @@
#include <osg/Geode>
#include <osgAnimation/MorphGeometry>
#include <osgAnimation/RigGeometry>
#include <sstream>
@@ -63,124 +64,133 @@ void MorphGeometry::transformSoftwareMethod()
osg::Geometry* morphGeometry = this;
osg::Vec3Array* pos = dynamic_cast<osg::Vec3Array*>(morphGeometry->getVertexArray());
if (pos && _positionSource.size() != pos->size())
{
_positionSource = std::vector<osg::Vec3>(pos->begin(),pos->end());
pos->setDataVariance(osg::Object::DYNAMIC);
}
osg::Vec3Array* normal = dynamic_cast<osg::Vec3Array*>(morphGeometry->getNormalArray());
if (normal && _normalSource.size() != normal->size())
if(pos)
{
_normalSource = std::vector<osg::Vec3>(normal->begin(),normal->end());
normal->setDataVariance(osg::Object::DYNAMIC);
}
if (!_positionSource.empty())
{
bool initialized = false;
if (_method == NORMALIZED)
if ( _positionSource.size() != pos->size())
{
// base * 1 - (sum of weights) + sum of (weight * target)
float baseWeight = 0;
for (unsigned int i=0; i < _morphTargets.size(); i++)
{
baseWeight += _morphTargets[i].getWeight();
}
baseWeight = 1 - baseWeight;
_positionSource = std::vector<osg::Vec3>(pos->begin(),pos->end());
pos->setDataVariance(osg::Object::DYNAMIC);
}
if (baseWeight != 0)
osg::Vec3Array* normal = dynamic_cast<osg::Vec3Array*>(morphGeometry->getNormalArray());
bool normalmorphable = _morphNormals && normal;
if (normal && _normalSource.size() != normal->size())
{
_normalSource = std::vector<osg::Vec3>(normal->begin(),normal->end());
normal->setDataVariance(osg::Object::DYNAMIC);
}
if (!_positionSource.empty())
{
bool initialized = false;
if (_method == NORMALIZED)
{
// base * 1 - (sum of weights) + sum of (weight * target)
float baseWeight = 0;
for (unsigned int i=0; i < _morphTargets.size(); i++)
{
baseWeight += _morphTargets[i].getWeight();
}
baseWeight = 1 - baseWeight;
if (baseWeight != 0)
{
initialized = true;
for (unsigned int i=0; i < pos->size(); i++)
{
(*pos)[i] = _positionSource[i] * baseWeight;
}
if (normalmorphable)
{
for (unsigned int i=0; i < normal->size(); i++)
{
(*normal)[i] = _normalSource[i] * baseWeight;
}
}
}
}
else //if (_method == RELATIVE)
{
// base + sum of (weight * target)
initialized = true;
for (unsigned int i=0; i < pos->size(); i++)
{
(*pos)[i] = _positionSource[i] * baseWeight;
(*pos)[i] = _positionSource[i];
}
if (_morphNormals)
if (normalmorphable)
{
for (unsigned int i=0; i < normal->size(); i++)
{
(*normal)[i] = _normalSource[i] * baseWeight;
(*normal)[i] = _normalSource[i];
}
}
}
}
else //if (_method == RELATIVE)
{
// base + sum of (weight * target)
initialized = true;
for (unsigned int i=0; i < pos->size(); i++)
for (unsigned int i=0; i < _morphTargets.size(); i++)
{
(*pos)[i] = _positionSource[i];
}
if (_morphNormals)
{
for (unsigned int i=0; i < normal->size(); i++)
if (_morphTargets[i].getWeight() > 0)
{
(*normal)[i] = _normalSource[i];
}
}
}
// See if any the targets use the internal optimized geometry
osg::Geometry* targetGeometry = _morphTargets[i].getGeometry();
for (unsigned int i=0; i < _morphTargets.size(); i++)
{
if (_morphTargets[i].getWeight() > 0)
{
// See if any the targets use the internal optimized geometry
osg::Geometry* targetGeometry = _morphTargets[i].getGeometry();
osg::Vec3Array* targetPos = dynamic_cast<osg::Vec3Array*>(targetGeometry->getVertexArray());
osg::Vec3Array* targetNormals = dynamic_cast<osg::Vec3Array*>(targetGeometry->getNormalArray());
if (initialized)
{
// If vertices are initialized, add the morphtargets
for (unsigned int j=0; j < pos->size(); j++)
osg::Vec3Array* targetPos = dynamic_cast<osg::Vec3Array*>(targetGeometry->getVertexArray());
osg::Vec3Array* targetNormals = dynamic_cast<osg::Vec3Array*>(targetGeometry->getNormalArray());
normalmorphable = normalmorphable && targetNormals;
if(targetPos)
{
(*pos)[j] += (*targetPos)[j] * _morphTargets[i].getWeight();
}
if (_morphNormals)
{
for (unsigned int j=0; j < normal->size(); j++)
if (initialized)
{
(*normal)[j] += (*targetNormals)[j] * _morphTargets[i].getWeight();
// If vertices are initialized, add the morphtargets
for (unsigned int j=0; j < pos->size(); j++)
{
(*pos)[j] += (*targetPos)[j] * _morphTargets[i].getWeight();
}
if (normalmorphable)
{
for (unsigned int j=0; j < normal->size(); j++)
{
(*normal)[j] += (*targetNormals)[j] * _morphTargets[i].getWeight();
}
}
}
}
}
else
{
// If not initialized, initialize with this morph target
initialized = true;
for (unsigned int j=0; j < pos->size(); j++)
{
(*pos)[j] = (*targetPos)[j] * _morphTargets[i].getWeight();
}
if (_morphNormals)
{
for (unsigned int j=0; j < normal->size(); j++)
else
{
(*normal)[j] = (*targetNormals)[j] * _morphTargets[i].getWeight();
// If not initialized, initialize with this morph target
initialized = true;
for (unsigned int j=0; j < pos->size(); j++)
{
(*pos)[j] = (*targetPos)[j] * _morphTargets[i].getWeight();
}
if (normalmorphable)
{
for (unsigned int j=0; j < normal->size(); j++)
{
(*normal)[j] = (*targetNormals)[j] * _morphTargets[i].getWeight();
}
}
}
}
}
}
pos->dirty();
if (normalmorphable)
{
for (unsigned int j=0; j < normal->size(); j++)
{
(*normal)[j].normalize();
}
normal->dirty();
}
}
pos->dirty();
if (_morphNormals)
{
for (unsigned int j=0; j < normal->size(); j++)
{
(*normal)[j].normalize();
}
normal->dirty();
}
dirtyBound();
}
dirtyBound();
_dirty = false;
}
}
@@ -206,7 +216,12 @@ void UpdateMorph::operator()(osg::Node* node, osg::NodeVisitor* nv)
unsigned int numDrawables = geode->getNumDrawables();
for (unsigned int i = 0; i != numDrawables; ++i)
{
osgAnimation::MorphGeometry* morph = dynamic_cast<osgAnimation::MorphGeometry*>(geode->getDrawable(i));
osg::Drawable *drw = geode->getDrawable(i);
osgAnimation::RigGeometry *rig = dynamic_cast<osgAnimation::RigGeometry*>(drw);
if(rig && rig->getSourceGeometry())
drw = rig->getSourceGeometry();
osgAnimation::MorphGeometry* morph = dynamic_cast<osgAnimation::MorphGeometry*>(drw);
if (morph)
{
// Update morph weights