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

@ -47,6 +47,9 @@ namespace osgAnimation
// addChannel insert the channel and call the computeDuration function
void addChannel (Channel* pChannel);
// removeChannel remove the channel from channels list and call the computeDuration function
void removeChannel (Channel* pChannel);
/** Those accessors let you add and remove channels
* if you modify something that can change the duration
* you are supposed to call computeDuration or setDuration
@ -61,16 +64,13 @@ namespace osgAnimation
*/
void setDuration(double duration);
/** Compute duration from channel and keyframes
* if the duration is not specified you should
* call this method before using it
*/
void computeDuration();
double getDuration() const;
void setWeight (float weight);
float getWeight() const;
@ -85,10 +85,10 @@ namespace osgAnimation
protected:
double computeDurationFromChannels() const;
~Animation() {}
double computeDurationFromChannels() const;
double _duration;
double _originalDuration;
float _weight;

View File

@ -40,6 +40,7 @@ namespace osgAnimation
virtual void update(double t) = 0;
virtual bool needToLink() const;
const AnimationList& getAnimationList() const { return _animations;}
AnimationList& getAnimationList() { return _animations;}
/** Callback method called by the NodeVisitor when visiting a node.*/
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);

View File

@ -25,10 +25,11 @@
#include <osg/Referenced>
#include <string>
namespace osgAnimation
{
class OSGANIMATION_EXPORT Channel : public osg::Referenced
class OSGANIMATION_EXPORT Channel : public osg::Object
{
public:
@ -37,6 +38,10 @@ namespace osgAnimation
virtual ~Channel();
virtual Channel* clone() const = 0;
virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast<const Channel*>(obj)!=NULL; }
virtual const char* libraryName() const { return "osgAnimation"; }
virtual const char* className() const { return "Channel"; }
virtual void update(double time, float weight, int priority) = 0;
virtual void reset() = 0;
virtual Target* getTarget() = 0;
@ -74,6 +79,9 @@ namespace osgAnimation
typedef typename SamplerType::UsingType UsingType;
typedef TemplateTarget<UsingType> TargetType;
typedef TemplateKeyframeContainer<typename SamplerType::KeyframeType> KeyframeContainerType;
Object* cloneType() const { return new TemplateChannel(); }
Object* clone(const osg::CopyOp& copyop) const { return new TemplateChannel<SamplerType>(*this); }
Channel* clone() const { return new TemplateChannel<SamplerType>(*this); }
TemplateChannel (const TemplateChannel& channel) :
@ -170,8 +178,10 @@ namespace osgAnimation
typedef TemplateChannel<FloatLinearSampler> FloatLinearChannel;
typedef TemplateChannel<Vec2LinearSampler> Vec2LinearChannel;
typedef TemplateChannel<Vec3LinearSampler> Vec3LinearChannel;
typedef TemplateChannel<Vec3usLinearSampler> Vec3usLinearChannel; // quantized Vec3LinearChannel
typedef TemplateChannel<Vec4LinearSampler> Vec4LinearChannel;
typedef TemplateChannel<QuatSphericalLinearSampler> QuatSphericalLinearChannel;
typedef TemplateChannel<Vec3usSphericalLinearSampler> Vec3usSphericalLinearChannel; // quantized QuatSphericalLinearChannel
typedef TemplateChannel<MatrixLinearSampler> MatrixLinearChannel;
typedef TemplateChannel<FloatCubicBezierSampler> FloatCubicBezierChannel;

View File

@ -21,11 +21,11 @@
namespace osgAnimation
{
template <class T>
class TemplateCubicBezier
{
public:
TemplateCubicBezier() : _position(osg::default_value<T>()), _controlPointIn(osg::default_value<T>()), _controlPointOut(osg::default_value<T>()) {}
TemplateCubicBezier(const T& p, const T& i, const T& o) : _position(p), _controlPointIn(i), _controlPointOut(o)
@ -49,6 +49,9 @@ namespace osgAnimation
void setControlPointIn(const T& v) {_controlPointIn = v;}
void setControlPointOut(const T& v) {_controlPointOut = v;}
bool operator==(const TemplateCubicBezier<T>& other) const
{ return _position == other._position && _controlPointIn == other._controlPointIn && _controlPointOut == other._controlPointOut; }
// steaming operators.
friend std::ostream& operator << (std::ostream& output, const TemplateCubicBezier<T>& tcb)
{

View File

@ -221,9 +221,11 @@ namespace osgAnimation
typedef TemplateLinearInterpolator<float, float> FloatLinearInterpolator;
typedef TemplateLinearInterpolator<osg::Vec2, osg::Vec2> Vec2LinearInterpolator;
typedef TemplateLinearInterpolator<osg::Vec3, osg::Vec3> Vec3LinearInterpolator;
typedef TemplateLinearInterpolator<osg::Vec3us, osg::Vec3us> Vec3usLinearInterpolator;
typedef TemplateLinearInterpolator<osg::Vec3, Vec3Packed> Vec3PackedLinearInterpolator;
typedef TemplateLinearInterpolator<osg::Vec4, osg::Vec4> Vec4LinearInterpolator;
typedef TemplateSphericalLinearInterpolator<osg::Quat, osg::Quat> QuatSphericalLinearInterpolator;
typedef TemplateSphericalLinearInterpolator<osg::Vec3us, osg::Vec3us> Vec3usSphericalLinearInterpolator;
typedef TemplateLinearInterpolator<osg::Matrixf, osg::Matrixf> MatrixLinearInterpolator;
typedef TemplateCubicBezierInterpolator<float, FloatCubicBezier > FloatCubicBezierInterpolator;

View File

@ -17,12 +17,14 @@
#include <string>
#include <osg/Referenced>
#include <osg/MixinVector>
#include <osgAnimation/Vec3Packed>
#include <osgAnimation/CubicBezier>
#include <osg/Quat>
#include <osg/Vec4>
#include <osg/Vec3>
#include <osg/Vec2>
#include <osg/Vec3us>
#include <osg/Matrixf>
namespace osgAnimation
@ -45,6 +47,8 @@ namespace osgAnimation
protected:
T _value;
public:
typedef T value_type;
TemplateKeyframe () {}
~TemplateKeyframe () {}
@ -71,19 +75,19 @@ namespace osgAnimation
template <class T>
class TemplateKeyframeContainer : public std::vector<TemplateKeyframe<T> >, public KeyframeContainer
class TemplateKeyframeContainer : public osg::MixinVector<TemplateKeyframe<T> >, public KeyframeContainer
{
public:
// const char* getKeyframeType() { return #T ;}
TemplateKeyframeContainer() {}
typedef TemplateKeyframe<T> KeyType;
virtual unsigned int size() const { return (unsigned int)std::vector<TemplateKeyframe<T> >::size(); }
typedef typename osg::MixinVector< TemplateKeyframe<T> > VectorType;
virtual unsigned int size() const { return (unsigned int)osg::MixinVector<TemplateKeyframe<T> >::size(); }
};
template <>
class TemplateKeyframeContainer<Vec3Packed> : public std::vector<TemplateKeyframe<Vec3Packed> >, public KeyframeContainer
class TemplateKeyframeContainer<Vec3Packed> : public osg::MixinVector<TemplateKeyframe<Vec3Packed> >, public KeyframeContainer
{
public:
typedef TemplateKeyframe<Vec3Packed> KeyType;
@ -109,12 +113,18 @@ namespace osgAnimation
typedef TemplateKeyframe<osg::Vec3> Vec3Keyframe;
typedef TemplateKeyframeContainer<osg::Vec3> Vec3KeyframeContainer;
typedef TemplateKeyframe<osg::Vec3us> Vec3usKeyframe;
typedef TemplateKeyframeContainer<osg::Vec3us> Vec3usKeyframeContainer;
typedef TemplateKeyframe<osg::Vec4> Vec4Keyframe;
typedef TemplateKeyframeContainer<osg::Vec4> Vec4KeyframeContainer;
typedef TemplateKeyframe<osg::Quat> QuatKeyframe;
typedef TemplateKeyframeContainer<osg::Quat> QuatKeyframeContainer;
typedef TemplateKeyframe<osg::Vec3us> Vec3usKeyframe;
typedef TemplateKeyframeContainer<osg::Vec3us> Vec3usKeyframeContainer;
typedef TemplateKeyframe<osg::Matrixf> MatrixKeyframe;
typedef TemplateKeyframeContainer<osg::Matrixf> MatrixKeyframeContainer;

View File

@ -52,7 +52,7 @@ namespace osgAnimation
public:
RigGeometry();
// RigGeometry(const osg::Geometry& b);
RigGeometry(const RigGeometry& b, const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY);
META_Object(osgAnimation, RigGeometry);
@ -123,7 +123,7 @@ namespace osgAnimation
};
struct UpdateRigGeometry : public osg::DrawableUpdateCallback
struct UpdateRigGeometry : public osg::Drawable::UpdateCallback
{
UpdateRigGeometry() {}
@ -131,7 +131,7 @@ namespace osgAnimation
META_Object(osgAnimation, UpdateRigGeometry);
virtual void update(osg::NodeVisitor*, osg::Drawable* drw) {
virtual void update(osg::NodeVisitor* nv, osg::Drawable* drw) {
RigGeometry* geom = dynamic_cast<RigGeometry*>(drw);
if(!geom)
return;
@ -157,6 +157,12 @@ namespace osgAnimation
if(geom->getNeedToComputeMatrix())
geom->computeMatrixFromRootSkeleton();
if(geom->getSourceGeometry()) {
osg::Drawable::UpdateCallback * up = dynamic_cast<osg::Drawable::UpdateCallback*>(geom->getSourceGeometry()->getUpdateCallback());
if(up)
up->update(nv, geom->getSourceGeometry());
}
geom->update();
}
};

View File

@ -34,6 +34,7 @@ namespace osgAnimation
typedef osgAnimation::Bone BoneType;
typedef std::vector<osg::ref_ptr<osg::Vec4Array> > BoneWeightAttribList;
typedef std::vector<osg::ref_ptr<BoneType> > BonePalette;
typedef std::map<std::string, int> BoneNamePaletteIndex;
typedef std::vector<osg::Matrix> MatrixPalette;
struct IndexWeightEntry
@ -63,6 +64,10 @@ namespace osgAnimation
virtual void operator()(RigGeometry&);
void setShader(osg::Shader*);
const BoneNamePaletteIndex& getBoneNameToPalette() {
return _boneNameToPalette;
}
protected:
bool init(RigGeometry&);
@ -74,6 +79,7 @@ namespace osgAnimation
int _nbVertexes;
VertexIndexWeightList _vertexIndexMatrixWeightList;
BonePalette _bonePalette;
BoneNamePaletteIndex _boneNameToPalette;
BoneWeightAttribList _boneWeightAttribArrays;
osg::ref_ptr<osg::Uniform> _uniformMatrixPalette;
osg::ref_ptr<osg::Shader> _shader;

View File

@ -166,6 +166,7 @@ namespace osgAnimation
bool _needInit;
std::map<std::string,bool> _invalidInfluence;
};
}

View File

@ -123,8 +123,10 @@ namespace osgAnimation
typedef TemplateSampler<FloatLinearInterpolator> FloatLinearSampler;
typedef TemplateSampler<Vec2LinearInterpolator> Vec2LinearSampler;
typedef TemplateSampler<Vec3LinearInterpolator> Vec3LinearSampler;
typedef TemplateSampler<Vec3usLinearInterpolator> Vec3usLinearSampler;
typedef TemplateSampler<Vec4LinearInterpolator> Vec4LinearSampler;
typedef TemplateSampler<QuatSphericalLinearInterpolator> QuatSphericalLinearSampler;
typedef TemplateSampler<Vec3usSphericalLinearInterpolator> Vec3usSphericalLinearSampler;
typedef TemplateSampler<MatrixLinearInterpolator> MatrixLinearSampler;
typedef TemplateSampler<FloatCubicBezierInterpolator> FloatCubicBezierSampler;

View File

@ -32,9 +32,6 @@ namespace osgAnimation
const osg::Matrix& getMatrix() const;
protected:
typedef osg::MixinVector<osg::ref_ptr<StackedTransformElement> > inherited;
osg::Matrix _matrix;
};

View File

@ -90,7 +90,7 @@ public:
void setSupportBinaryBrackets( bool b ) { _supportBinaryBrackets = b; }
bool getSupportBinaryBrackets() const { return _supportBinaryBrackets; }
void checkStream() const { if (_in->rdstate()&_in->failbit) _failed = true; }
void checkStream() const;
bool isFailed() const { return _failed; }
virtual bool isBinary() const = 0;

View File

@ -22,8 +22,16 @@ Action::Action()
_fps = 25;
_speed = 1.0;
_loop = 1;
_state = Stop;
}
Action::Action(const Action&rhs,const osg::CopyOp&)
{
_numberFrame = rhs._numberFrame;
_fps = rhs._fps;
_speed = rhs._speed;
_loop = rhs._loop;
_state = Stop;
}
Action::Action(const Action&,const osg::CopyOp&) {}
Action::Callback* Action::getFrameCallback(unsigned int frame)
{
if (_framesCallback.find(frame) != _framesCallback.end())

View File

@ -140,8 +140,8 @@ void UpdateActionVisitor::apply(ActionAnimation& action)
{
unsigned int frame = getLocalFrame();
apply(static_cast<Action&>(action));
int pri = static_cast<int>(_currentAnimationPriority);
_currentAnimationPriority++;
int pri = static_cast<int>(_currentAnimationPriority);
_currentAnimationPriority++;
action.updateAnimation(frame, -pri);
}
}
@ -159,6 +159,7 @@ void UpdateActionVisitor::apply(ActionStripAnimation& action)
ClearActionVisitor::ClearActionVisitor(ClearType type) : _clearType(type)
{
_frame = 0;
}
void ClearActionVisitor::apply(Timeline& tm)

View File

@ -40,8 +40,27 @@ void Animation::addChannel(Channel* pChannel)
_originalDuration = computeDurationFromChannels();
}
void Animation::removeChannel(Channel* pChannel)
{
ChannelList::iterator it = _channels.begin();
while(it != _channels.end() && it->get() != pChannel)
{
++ it;
}
if (it != _channels.end())
{
_channels.erase(it);
}
computeDuration();
}
double Animation::computeDurationFromChannels() const
{
if(_channels.empty())
return 0;
double tmin = 1e5;
double tmax = -1e5;
ChannelList::const_iterator chan;

View File

@ -17,7 +17,7 @@ using namespace osgAnimation;
Channel::Channel() {}
Channel::~Channel() {}
Channel::Channel(const Channel& channel) : osg::Referenced(channel),
Channel::Channel(const Channel& channel) : osg::Object(channel),
_targetName(channel._targetName),
_name(channel._name)
{

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

View File

@ -24,7 +24,7 @@ osg::BoundingBox RigComputeBoundingBoxCallback::computeBound(const osg::Drawable
{
const osgAnimation::RigGeometry& rig = dynamic_cast<const osgAnimation::RigGeometry&>(drawable);
// if a valid initial bounding box is set we use it without asking more
// if a valid inital bounding box is set we use it without asking more
if (rig.getInitialBound().valid())
return rig.getInitialBound();
@ -32,7 +32,7 @@ osg::BoundingBox RigComputeBoundingBoxCallback::computeBound(const osg::Drawable
return _boundingBox;
// if the computing of bb is invalid (like no geometry inside)
// then don't tag the bounding box as computed
// then dont tag the bounding box as computed
osg::BoundingBox bb = rig.computeBoundingBox();
if (!bb.valid())
return bb;
@ -58,8 +58,7 @@ RigGeometry::RigGeometry()
_needToComputeMatrix = true;
_matrixFromSkeletonToGeometry = _invMatrixFromSkeletonToGeometry = osg::Matrix::identity();
// disable the computation of boundingbox for the rig mesh
setComputeBoundingBoxCallback(new RigComputeBoundingBoxCallback);
}
@ -70,8 +69,8 @@ RigGeometry::RigGeometry(const RigGeometry& b, const osg::CopyOp& copyop) :
_vertexInfluenceMap(b._vertexInfluenceMap),
_needToComputeMatrix(b._needToComputeMatrix)
{
// we don't copy the RigImplementation yet. because the RigImplementation need to be initialized in a valid graph, with a skeleton ...
// don't know yet what to do with a clone of a RigGeometry
// we dont copy the RigImplementation yet. because the RigImplementation need to be initialized in a valid graph, with a skeleton ...
// dont know yet what to do with a clone of a RigGeometry
}
@ -113,7 +112,9 @@ void RigGeometry::computeMatrixFromRootSkeleton()
osg::Matrix notRoot = _root->getMatrix();
_matrixFromSkeletonToGeometry = mtxList[0] * osg::Matrix::inverse(notRoot);
_invMatrixFromSkeletonToGeometry = osg::Matrix::inverse(_matrixFromSkeletonToGeometry);
_needToComputeMatrix = false;
_needToComputeMatrix = false;
// disable the computation of boundingbox for the rig mesh
setComputeBoundingBoxCallback(new RigComputeBoundingBoxCallback);
}
void RigGeometry::update()

View File

@ -66,8 +66,6 @@ int RigTransformHardware::getNumVertexes() const { return _nbVertexes;}
bool RigTransformHardware::createPalette(int nbVertexes, BoneMap boneMap, const VertexInfluenceSet::VertexIndexToBoneWeightMap& vertexIndexToBoneWeightMap)
{
typedef std::map<std::string, int> BoneNameCountMap;
typedef std::map<std::string, int> BoneNamePaletteIndex;
BoneNamePaletteIndex bname2palette;
BonePalette palette;
BoneNameCountMap boneNameCountMap;
@ -76,32 +74,35 @@ bool RigTransformHardware::createPalette(int nbVertexes, BoneMap boneMap, const
vertexIndexWeight.resize(nbVertexes);
int maxBonePerVertex = 0;
for (VertexInfluenceSet::VertexIndexToBoneWeightMap::const_iterator vis_itr = vertexIndexToBoneWeightMap.begin(); vis_itr != vertexIndexToBoneWeightMap.end(); ++vis_itr)
for (VertexInfluenceSet::VertexIndexToBoneWeightMap::const_iterator it = vertexIndexToBoneWeightMap.begin(); it != vertexIndexToBoneWeightMap.end(); ++it)
{
int vertexIndex = vis_itr->first;
const VertexInfluenceSet::BoneWeightList& boneWeightList = vis_itr->second;
int vertexIndex = it->first;
const VertexInfluenceSet::BoneWeightList& boneWeightList = it->second;
int bonesForThisVertex = 0;
for (VertexInfluenceSet::BoneWeightList::const_iterator it = boneWeightList.begin(); it != boneWeightList.end(); ++it)
{
const VertexInfluenceSet::BoneWeight& bw = *it;
if (boneNameCountMap.find(bw.getBoneName()) != boneNameCountMap.end())
if(fabs(bw.getWeight()) > 1e-2) // dont use bone with weight too small
{
boneNameCountMap[bw.getBoneName()]++;
bonesForThisVertex++; // count max number of bones per vertexes
vertexIndexWeight[vertexIndex].push_back(IndexWeightEntry(bname2palette[bw.getBoneName()],bw.getWeight()));
}
else if (fabs(bw.getWeight()) > 1e-2) // don't use bone with weight too small
{
if (boneMap.find(bw.getBoneName()) == boneMap.end())
if (boneNameCountMap.find(bw.getBoneName()) != boneNameCountMap.end())
{
OSG_INFO << "RigTransformHardware::createPalette can't find bone " << bw.getBoneName() << " skip this influence" << std::endl;
continue;
boneNameCountMap[bw.getBoneName()]++;
bonesForThisVertex++; // count max number of bones per vertexes
vertexIndexWeight[vertexIndex].push_back(IndexWeightEntry(_boneNameToPalette[bw.getBoneName()],bw.getWeight()));
}
else
{
if (boneMap.find(bw.getBoneName()) == boneMap.end())
{
OSG_INFO << "RigTransformHardware::createPalette can't find bone " << bw.getBoneName() << " skip this influence" << std::endl;
continue;
}
boneNameCountMap[bw.getBoneName()] = 1; // for stats
bonesForThisVertex++;
palette.push_back(boneMap[bw.getBoneName()]);
_boneNameToPalette[bw.getBoneName()] = palette.size()-1;
vertexIndexWeight[vertexIndex].push_back(IndexWeightEntry(_boneNameToPalette[bw.getBoneName()],bw.getWeight()));
}
boneNameCountMap[bw.getBoneName()] = 1; // for stats
bonesForThisVertex++;
palette.push_back(boneMap[bw.getBoneName()]);
bname2palette[bw.getBoneName()] = palette.size()-1;
vertexIndexWeight[vertexIndex].push_back(IndexWeightEntry(bname2palette[bw.getBoneName()],bw.getWeight()));
}
else
{

View File

@ -59,47 +59,53 @@ void RigTransformSoftware::operator()(RigGeometry& geom)
osg::Vec3Array* positionSrc = dynamic_cast<osg::Vec3Array*>(source.getVertexArray());
osg::Vec3Array* positionDst = dynamic_cast<osg::Vec3Array*>(destination.getVertexArray());
if (positionSrc && (!positionDst || (positionDst->size() != positionSrc->size()) ) )
if (positionSrc )
{
if (!positionDst)
if (!positionDst || (positionDst->size() != positionSrc->size()) )
{
positionDst = new osg::Vec3Array;
positionDst->setDataVariance(osg::Object::DYNAMIC);
destination.setVertexArray(positionDst);
if (!positionDst)
{
positionDst = new osg::Vec3Array;
positionDst->setDataVariance(osg::Object::DYNAMIC);
destination.setVertexArray(positionDst);
}
*positionDst = *positionSrc;
}
*positionDst = *positionSrc;
if (positionDst && !positionDst->empty())
{
compute<osg::Vec3>(geom.getMatrixFromSkeletonToGeometry(),
geom.getInvMatrixFromSkeletonToGeometry(),
&positionSrc->front(),
&positionDst->front());
positionDst->dirty();
}
}
osg::Vec3Array* normalSrc = dynamic_cast<osg::Vec3Array*>(source.getNormalArray());
osg::Vec3Array* normalDst = dynamic_cast<osg::Vec3Array*>(destination.getNormalArray());
if (normalSrc && (!normalDst || (normalDst->size() != normalSrc->size()) ) )
if (normalSrc )
{
if (!normalDst)
if (!normalDst || (normalDst->size() != normalSrc->size()) )
{
normalDst = new osg::Vec3Array;
normalDst->setDataVariance(osg::Object::DYNAMIC);
destination.setNormalArray(normalDst, osg::Array::BIND_PER_VERTEX);
if (!normalDst)
{
normalDst = new osg::Vec3Array;
normalDst->setDataVariance(osg::Object::DYNAMIC);
destination.setNormalArray(normalDst, osg::Array::BIND_PER_VERTEX);
}
*normalDst = *normalSrc;
}
if (normalDst && !normalDst->empty())
{
computeNormal<osg::Vec3>(geom.getMatrixFromSkeletonToGeometry(),
geom.getInvMatrixFromSkeletonToGeometry(),
&normalSrc->front(),
&normalDst->front());
normalDst->dirty();
}
*normalDst = *normalSrc;
}
if (positionDst && !positionDst->empty())
{
compute<osg::Vec3>(geom.getMatrixFromSkeletonToGeometry(),
geom.getInvMatrixFromSkeletonToGeometry(),
&positionSrc->front(),
&positionDst->front());
positionDst->dirty();
}
if (normalDst && !normalDst->empty())
{
computeNormal<osg::Vec3>(geom.getMatrixFromSkeletonToGeometry(),
geom.getInvMatrixFromSkeletonToGeometry(),
&normalSrc->front(),
&normalDst->front());
normalDst->dirty();
}
}
void RigTransformSoftware::initVertexSetFromBones(const BoneMap& map, const VertexInfluenceSet::UniqVertexSetToBoneSetList& influence)
@ -120,9 +126,12 @@ void RigTransformSoftware::initVertexSetFromBones(const BoneMap& map, const Vert
const std::string& bname = inf.getBones()[b].getBoneName();
float weight = inf.getBones()[b].getWeight();
BoneMap::const_iterator it = map.find(bname);
if (it == map.end())
if (it == map.end() )
{
OSG_WARN << "RigTransformSoftware Bone " << bname << " not found, skip the influence group " <<bname << std::endl;
if (_invalidInfluence.find(bname) != _invalidInfluence.end()) {
_invalidInfluence[bname] = true;
OSG_WARN << "RigTransformSoftware Bone " << bname << " not found, skip the influence group " <<bname << std::endl;
}
continue;
}
Bone* bone = it->second.get();

View File

@ -18,7 +18,7 @@ using namespace osgAnimation;
StackedRotateAxisElement::StackedRotateAxisElement(const std::string& name, const osg::Vec3& axis, double angle) : StackedTransformElement(), _axis(axis), _angle(angle) { setName(name); }
StackedRotateAxisElement::StackedRotateAxisElement(const osg::Vec3& axis, double angle) : _axis(axis), _angle(angle) { setName("rotateaxis"); }
StackedRotateAxisElement::StackedRotateAxisElement() {}
StackedRotateAxisElement::StackedRotateAxisElement() : _axis(osg::Vec3(1,0,0)), _angle(0) {}
StackedRotateAxisElement::StackedRotateAxisElement(const StackedRotateAxisElement& rhs, const osg::CopyOp&) : StackedTransformElement(rhs), _axis(rhs._axis), _angle(rhs._angle)
{
if (rhs._target.valid())

View File

@ -18,8 +18,7 @@ using namespace osgAnimation;
StackedTransform::StackedTransform() {}
StackedTransform::StackedTransform(const StackedTransform& rhs, const osg::CopyOp& co):
inherited(rhs)
StackedTransform::StackedTransform(const StackedTransform& rhs, const osg::CopyOp& co)
{
reserve(rhs.size());
for (StackedTransform::const_iterator it = rhs.begin(); it != rhs.end(); ++it)

View File

@ -90,6 +90,7 @@ struct StatsGraph : public osg::MatrixTransform
void changeYposition(float y)
{
osg::Vec3 _pos = getMatrix().getTrans();
_pos[1] = y - _height;
setMatrix(osg::Matrix::translate(_pos));
}
@ -201,7 +202,7 @@ struct StatsGraph : public osg::MatrixTransform
// Create primitive set if none exists.
if (geometry->getNumPrimitiveSets() == 0)
geometry->addPrimitiveSet(new osg::DrawArrays(GL_LINE_STRIP, 0, 0));
osg::DrawArrays* drawArrays = dynamic_cast<osg::DrawArrays*>(geometry->getPrimitiveSet(0));
osg::DrawArrays* drawArrays = static_cast<osg::DrawArrays*>(geometry->getPrimitiveSet(0));
drawArrays->setFirst(0);
drawArrays->setCount(vertices->size());
}
@ -286,7 +287,7 @@ struct ValueTextDrawCallback : public virtual osg::Drawable::DrawCallback
std::string _name;
osg::ref_ptr<osg::Group> _group;
osg::ref_ptr<osg::Geode> _label;
osg::ref_ptr<osg::MatrixTransform> _graph;
osg::ref_ptr<StatsGraph> _graph;
osg::ref_ptr<osgText::Text> _textLabel;
osgAnimation::OutCubicMotion _fade;
@ -444,7 +445,7 @@ struct ValueTextDrawCallback : public virtual osg::Drawable::DrawCallback
}
pos.y() -= backgroundMargin;
osg::Vec3Array* array = dynamic_cast<osg::Vec3Array*>(_background->getVertexArray());
osg::Vec3Array* array = static_cast<osg::Vec3Array*>(_background->getVertexArray());
float y = (*array)[0][1];
y = y - (pos.y() + backgroundMargin); //(2 * backgroundMargin + (size.size() * (characterSize + graphSpacing)));
(*array)[1][1] = pos.y();
@ -482,6 +483,9 @@ StatsHandler::StatsHandler():
_keyEventPrintsOutStats('A'),
_statsType(NO_STATS),
_initialized(false),
_frameRateChildNum(0),
_numBlocks(0),
_blockMultiplier(double(1.0)),
_statsWidth(1280.0f),
_statsHeight(1024.0f)
{
@ -497,7 +501,7 @@ bool StatsHandler::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdap
osgViewer::Viewer* viewer = dynamic_cast<osgViewer::Viewer*>(myview->getViewerBase());
if (!viewer->getSceneData())
if (!viewer || !viewer->getSceneData())
return false;
if (ea.getHandled()) return false;
@ -621,7 +625,8 @@ void StatsHandler::setUpHUDCamera(osgViewer::ViewerBase* viewer)
_camera->setAllowEventFocus(false);
_camera->setCullMask(0x1);
osgViewer::Viewer* v = dynamic_cast<osgViewer::Viewer*>(viewer);
v->getSceneData()->asGroup()->addChild(_camera.get());
if(v)
v->getSceneData()->asGroup()->addChild(_camera.get());
_initialized = true;
}
@ -688,12 +693,11 @@ void StatAction::init(osg::Stats* stats, const std::string& name, const osg::Vec
void StatAction::setAlpha(float v)
{
std::cout << this << " color alpha " << v << std::endl;
StatsGraph* gfx = dynamic_cast<StatsGraph*>(_graph.get());
osg::Vec4 color = _textLabel->getColor();
color[3] = v;
_textLabel->setColor(color);
for (int i = 0; i < (int) gfx->_statsGraphGeode->getNumDrawables(); i++) {
StatsGraph::Graph* g = dynamic_cast<StatsGraph::Graph*>(gfx->_statsGraphGeode->getDrawable(0));
for (int i = 0; i < (int) _graph->_statsGraphGeode->getNumDrawables(); i++) {
StatsGraph::Graph* g = static_cast<StatsGraph::Graph*>(_graph->_statsGraphGeode->getDrawable(0));
g->setColor(color);
}
}
@ -701,12 +705,9 @@ void StatAction::setAlpha(float v)
void StatAction::setPosition(const osg::Vec3& pos)
{
float characterSize = 20.0f;
StatsGraph* gfx = dynamic_cast<StatsGraph*>(_graph.get());
gfx->changeYposition(pos[1]);
_graph->changeYposition(pos[1]);
_textLabel->setPosition(pos - osg::Vec3(0, characterSize,0));
}

View File

@ -16,6 +16,23 @@
using namespace osgDB;
static long long prev_tellg = 0;
void InputIterator::checkStream() const
{
if (_in->rdstate()&_in->failbit)
{
OSG_NOTICE<<"InputIterator::checkStream() : _in->rdstate() "<<_in->rdstate()<<", "<<_in->failbit<<std::endl;
OSG_NOTICE<<" _in->tellg() = "<<_in->tellg()<<std::endl;
OSG_NOTICE<<" prev_tellg = "<<prev_tellg<<std::endl;
_failed = true;
}
else
{
prev_tellg = _in->tellg();
}
}
void InputIterator::readComponentArray( char* s, unsigned int numElements, unsigned int numComponentsPerElements, unsigned int componentSizeInBytes)
{
unsigned int size = numElements * numComponentsPerElements * componentSizeInBytes;

View File

@ -25,7 +25,7 @@ osg::Quat makeQuat(const osg::Vec3& radians, EFbxRotationOrder fbxRotOrder)
void readKeys(FbxAnimCurve* curveX, FbxAnimCurve* curveY, FbxAnimCurve* curveZ,
const FbxDouble3& defaultValue,
std::vector<osgAnimation::TemplateKeyframe<osg::Vec3> >& keyFrameCntr, float scalar = 1.0f)
osgAnimation::TemplateKeyframeContainer<osg::Vec3f>& keyFrameCntr, float scalar = 1.0f)
{
FbxAnimCurve* curves[3] = {curveX, curveY, curveZ};
@ -73,7 +73,7 @@ void readKeys(FbxAnimCurve* curveX, FbxAnimCurve* curveY, FbxAnimCurve* curveZ,
void readKeys(FbxAnimCurve* curveX, FbxAnimCurve* curveY, FbxAnimCurve* curveZ,
const FbxDouble3& defaultValue,
std::vector<osgAnimation::Vec3CubicBezierKeyframe>& keyFrameCntr, float scalar = 1.0f)
osgAnimation::TemplateKeyframeContainer<osgAnimation::TemplateCubicBezier<osg::Vec3f> >& keyFrameCntr, float scalar = 1.0f)
{
FbxAnimCurve* curves[3] = {curveX, curveY, curveZ};
@ -257,7 +257,7 @@ osgAnimation::Channel* readFbxChannelsQuat(
osgAnimation::QuatSphericalLinearChannel* pChannel = new osgAnimation::QuatSphericalLinearChannel;
pChannel->setTargetName(targetName);
pChannel->setName("quaternion");
typedef std::vector<osgAnimation::TemplateKeyframe<osg::Vec3> > KeyFrameCntr;
typedef osgAnimation::TemplateKeyframeContainer<osg::Vec3f> KeyFrameCntr;
KeyFrameCntr eulerFrameCntr;
readKeys(curveX, curveY, curveZ, defaultValue, eulerFrameCntr, static_cast<float>(osg::PI / 180.0));

View File

@ -413,7 +413,7 @@ void readAnimation(FbxNode* pNode, FbxScene& fbxScene, const std::string& target
}
osgAnimation::FloatLinearChannel* pChannel = new osgAnimation::FloatLinearChannel;
std::vector<osgAnimation::TemplateKeyframe<float> >& keyFrameCntr = *pChannel->getOrCreateSampler()->getOrCreateKeyframeContainer();
osgAnimation::TemplateKeyframeContainer<float> & keyFrameCntr = *pChannel->getOrCreateSampler()->getOrCreateKeyframeContainer();
for (int k = 0; k < nKeys; ++k)
{