/* -*-c++-*- * Copyright (C) 2008 Cedric Pinson * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Authors: * * Cedric Pinson * */ #include using namespace osgAnimation; RigGeometry::RigGeometry() { setUseDisplayList(false); setUpdateCallback(new UpdateVertex); setDataVariance(osg::Object::DYNAMIC); _needToComputeMatrix = true; _matrixFromSkeletonToGeometry = _invMatrixFromSkeletonToGeometry = osg::Matrix::identity(); } RigGeometry::RigGeometry(const osg::Geometry& b) : osg::Geometry(b, osg::CopyOp::SHALLOW_COPY) { setUseDisplayList(false); setUpdateCallback(new UpdateVertex); setDataVariance(osg::Object::DYNAMIC); _needToComputeMatrix = true; _matrixFromSkeletonToGeometry = _invMatrixFromSkeletonToGeometry = osg::Matrix::identity(); } RigGeometry::RigGeometry(const RigGeometry& b, const osg::CopyOp& copyop) : osg::Geometry(b,copyop), _positionSource(b._positionSource), _normalSource(b._normalSource), _vertexInfluenceSet(b._vertexInfluenceSet), _vertexInfluenceMap(b._vertexInfluenceMap), _transformVertexes(b._transformVertexes), _needToComputeMatrix(b._needToComputeMatrix) { } void RigGeometry::buildTransformer(Skeleton* root) { Bone::BoneMap bm = root->getBoneMap(); _transformVertexes.init(bm, _vertexInfluenceSet.getUniqVertexSetToBoneSetList()); _root = root; } void RigGeometry::buildVertexSet() { if (!_vertexInfluenceMap.valid()) { osg::notify(osg::WARN) << "buildVertexSet can't be called without VertexInfluence already set to the RigGeometry ( " << getName() << " ) " << std::endl; return; } _vertexInfluenceSet.clear(); for (osgAnimation::VertexInfluenceMap::iterator it = _vertexInfluenceMap->begin(); it != _vertexInfluenceMap->end(); it++) _vertexInfluenceSet.addVertexInfluence(it->second); _vertexInfluenceSet.buildVertex2BoneList(); _vertexInfluenceSet.buildUniqVertexSetToBoneSetList(); std::cout << "uniq groups " << _vertexInfluenceSet.getUniqVertexSetToBoneSetList().size() << " for " << getName() << std::endl; } void RigGeometry::computeMatrixFromRootSkeleton() { if (!_root.valid()) { 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; return; } osg::MatrixList mtxList = getParent(0)->getWorldMatrices(_root.get()); _matrixFromSkeletonToGeometry = mtxList[0]; _invMatrixFromSkeletonToGeometry = osg::Matrix::inverse(_matrixFromSkeletonToGeometry); _needToComputeMatrix = false; } void RigGeometry::transformSoftwareMethod() { setUseDisplayList(false); setUseVertexBufferObjects(true); // std::cout << getName() << " _matrixFromSkeletonToGeometry" << _matrixFromSkeletonToGeometry << std::endl; osg::Vec3Array* pos = dynamic_cast(getVertexArray()); if (pos && _positionSource.size() != pos->size()) { _positionSource = std::vector(pos->begin(),pos->end()); getVertexArray()->setDataVariance(osg::Object::DYNAMIC); } osg::Vec3Array* normal = dynamic_cast(getNormalArray()); if (normal && _normalSource.size() != normal->size()) { _normalSource = std::vector(normal->begin(),normal->end()); getNormalArray()->setDataVariance(osg::Object::DYNAMIC); } if (!_positionSource.empty()) { _transformVertexes.compute(_matrixFromSkeletonToGeometry, _invMatrixFromSkeletonToGeometry, &_positionSource.front(), &pos->front()); pos->dirty(); } if (!_normalSource.empty()) { _transformVertexes.computeNormal(_matrixFromSkeletonToGeometry, _invMatrixFromSkeletonToGeometry, &_normalSource.front(), &normal->front()); normal->dirty(); } if (getUseDisplayList()) dirtyDisplayList(); dirtyBound(); } const osgAnimation::Skeleton* RigGeometry::getSkeleton() const { return _root.get(); } osgAnimation::Skeleton* RigGeometry::getSkeleton() { return _root.get(); }