root/OpenSceneGraph/trunk/src/osgAnimation/RigGeometry.cpp @ 10877

Revision 10877, 6.2 kB (checked in by cedricpinson, 5 years ago)

From Cedric Pinson,
Add check in RigTransformSoftware? if bones are null
Indent TimelineAnimationManager?
Add check for NaN in UpdateCallback?.cpp
Fix TimelineAnimationManager? clear target (a refactore of Timeline is require for futur)
Fix Computation of bounding box for RigGeometry?

RevLine 
[9093]1/*  -*-c++-*-
[10693]2 *  Copyright (C) 2008 Cedric Pinson <cedric.pinson@plopbyte.net>
[9093]3 *
[10693]4 * This library is open source and may be redistributed and/or modified under 
5 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
6 * (at your option) any later version.  The full license is in LICENSE file
7 * included with this distribution, and on the openscenegraph.org website.
[9093]8 *
[10693]9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 * OpenSceneGraph Public License for more details.
[9093]13 */
[10693]14
[9093]15#include <osgAnimation/RigGeometry>
[10693]16#include <osgAnimation/RigTransformSoftware>
17#include <sstream>
18#include <osg/GL2Extensions>
[9093]19
[9370]20using namespace osgAnimation;
21
[10877]22// The idea is to compute a bounding box with a factor x of the first step we compute the bounding box
23class RigComputeBoundingBoxCallback : public osg::Drawable::ComputeBoundingBoxCallback
24{
25public:
26    RigComputeBoundingBoxCallback(double factor = 2.0) : _computed(false), _factor(factor) {}
27    void reset() { _computed = false; }
28    virtual osg::BoundingBox computeBound(const osg::Drawable& drawable) const
29    {
30        const osgAnimation::RigGeometry& rig = dynamic_cast<const osgAnimation::RigGeometry&>(drawable);
31
32        // if a valid inital bounding box is set we use it without asking more
33        if (rig.getInitialBound().valid())
34            return rig.getInitialBound();
35
36        if (_computed)
37            return _boundingBox;
38
39        // if the computing of bb is invalid (like no geometry inside)
40        // then dont tag the bounding box as computed
41        osg::BoundingBox bb = rig.computeBound();
42        if (!bb.valid())
43            return bb;
44
45
46        _boundingBox.expandBy(bb);
47        osg::Vec3 center = _boundingBox.center();
48        osg::Vec3 vec = (_boundingBox._max-center)*_factor;
49        _boundingBox.expandBy(center + vec);
50        _boundingBox.expandBy(center - vec);
51        _computed = true;
52//        osg::notify(osg::NOTICE) << "build the bounding box for RigGeometry " << rig.getName() << " " << _boundingBox._min << " " << _boundingBox._max << std::endl;
53        return _boundingBox;
54    }
55protected:
56    mutable bool _computed;
57    double _factor;
58    mutable osg::BoundingBox _boundingBox;
59};
60
[9370]61RigGeometry::RigGeometry()
[9093]62{
[10693]63    _supportsDisplayList = false;
64    setUseVertexBufferObjects(true);
[9370]65    setUpdateCallback(new UpdateVertex);
66    setDataVariance(osg::Object::DYNAMIC);
67    _needToComputeMatrix = true;
68    _matrixFromSkeletonToGeometry = _invMatrixFromSkeletonToGeometry = osg::Matrix::identity();
[10693]69
70    // disable the computation of boundingbox for the rig mesh
[10877]71    setComputeBoundingBoxCallback(new RigComputeBoundingBoxCallback);
[9370]72}
73
74RigGeometry::RigGeometry(const osg::Geometry& b) : osg::Geometry(b, osg::CopyOp::SHALLOW_COPY)
75{
[10693]76    _supportsDisplayList = false;
77    setUseVertexBufferObjects(true);
[9370]78    setUpdateCallback(new UpdateVertex);
79    setDataVariance(osg::Object::DYNAMIC);
80    _needToComputeMatrix = true;
81    _matrixFromSkeletonToGeometry = _invMatrixFromSkeletonToGeometry = osg::Matrix::identity();
[10693]82
83    // disable the computation of boundingbox for the rig mesh
[10877]84    setComputeBoundingBoxCallback(new RigComputeBoundingBoxCallback);
[9370]85}
86
[10693]87RigGeometry::RigGeometry(const RigGeometry& b, const osg::CopyOp& copyop) :
[9370]88    osg::Geometry(b,copyop),
89    _vertexInfluenceSet(b._vertexInfluenceSet),
90    _vertexInfluenceMap(b._vertexInfluenceMap),
[10693]91    _needToComputeMatrix(b._needToComputeMatrix)
[9370]92{
[10693]93    // we dont copy the RigImplementation yet. because the RigImplementation need to be initialized in a valid graph, with a skeleton ...
94    // dont know yet what to do with a clone of a RigGeometry
[9370]95}
96
[10693]97
98const osg::Matrix& RigGeometry::getMatrixFromSkeletonToGeometry() const { return _matrixFromSkeletonToGeometry; }
99const osg::Matrix& RigGeometry::getInvMatrixFromSkeletonToGeometry() const { return _invMatrixFromSkeletonToGeometry;}
100
101
102void RigGeometry::drawImplementation(osg::RenderInfo& renderInfo) const
[9370]103{
[10693]104    osg::Geometry::drawImplementation(renderInfo);
[9093]105}
106
[10693]107void RigGeometry::buildVertexInfluenceSet()
[9093]108{
[10693]109    if (!_vertexInfluenceMap.valid())
[9093]110    {
[10693]111        osg::notify(osg::WARN) << "buildVertexInfluenceSet can't be called without VertexInfluence already set to the RigGeometry ( " << getName() << " ) " << std::endl;
[9093]112        return;
113    }
114    _vertexInfluenceSet.clear();
115    for (osgAnimation::VertexInfluenceMap::iterator it = _vertexInfluenceMap->begin();
116         it != _vertexInfluenceMap->end();
117         it++)
118        _vertexInfluenceSet.addVertexInfluence(it->second);
119
120    _vertexInfluenceSet.buildVertex2BoneList();
121    _vertexInfluenceSet.buildUniqVertexSetToBoneSetList();
[10693]122    osg::notify(osg::NOTICE) << "uniq groups " << _vertexInfluenceSet.getUniqVertexSetToBoneSetList().size() << " for " << getName() << std::endl;
[9093]123}
124
[10693]125void RigGeometry::computeMatrixFromRootSkeleton()
[9093]126{
[10693]127    if (!_root.valid())
[9093]128    {
129        osg::notify(osg::WARN) << "Warning " << className() <<"::computeMatrixFromRootSkeleton if you have this message it means you miss to call buildTransformer(Skeleton* root), or your RigGeometry (" << getName() <<") is not attached to a Skeleton subgraph" << std::endl;
130        return;
131    }
132    osg::MatrixList mtxList = getParent(0)->getWorldMatrices(_root.get());
133    _matrixFromSkeletonToGeometry = mtxList[0];
134    _invMatrixFromSkeletonToGeometry = osg::Matrix::inverse(_matrixFromSkeletonToGeometry);
135    _needToComputeMatrix = false;
136}
137
[10693]138void RigGeometry::update()
[9093]139{
[10693]140    if (!getRigTransformImplementation())
[9093]141    {
[10693]142        _rigTransformImplementation = new RigTransformSoftware;
[9093]143    }
144
[10693]145    if (getRigTransformImplementation()->needInit())
146        if (!getRigTransformImplementation()->init(*this))
147            return;
148    getRigTransformImplementation()->update(*this);
[9093]149}
150
[10693]151const VertexInfluenceSet& RigGeometry::getVertexInfluenceSet() const { return _vertexInfluenceSet;}
152
153const Skeleton* RigGeometry::getSkeleton() const { return _root.get(); }
154Skeleton* RigGeometry::getSkeleton() { return _root.get(); }
155void RigGeometry::setSkeleton(Skeleton* root) { _root = root;}
156RigTransform* RigGeometry::getRigTransformImplementation() { return _rigTransformImplementation.get(); }
157void RigGeometry::setRigTransformImplementation(RigTransform* rig) { _rigTransformImplementation = rig; }
Note: See TracBrowser for help on using the browser.