SkinningPrimFunc.cpp

Go to the documentation of this file.
00001 // Copyright (C) 2005 Dave Griffiths
00002 //
00003 // This program is free software; you can redistribute it and/or modify
00004 // it under the terms of the GNU General Public License as published by
00005 // the Free Software Foundation; either version 2 of the License, or
00006 // (at your option) any later version.
00007 //
00008 // This program is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011 // GNU General Public License for more details.
00012 //
00013 // You should have received a copy of the GNU General Public License
00014 // along with this program; if not, write to the Free Software
00015 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00016 
00017 #include "SkinningPrimFunc.h"
00018 #include "Primitive.h"
00019 #include "SceneGraph.h"
00020 
00021 using namespace Fluxus;
00022 
00023 SkinningPrimFunc::SkinningPrimFunc()
00024 {
00025 }
00026 
00027 SkinningPrimFunc::~SkinningPrimFunc()
00028 {
00029 }
00030 
00031 void SkinningPrimFunc::Run(Primitive &prim, const SceneGraph &world)
00032 {
00033     int rootid = GetArg<int>("skeleton-root",0);
00034     int bindposerootid = GetArg<int>("bindpose-root",0);
00035     bool skinnormals = GetArg<int>("skin-normals",0);
00036     vector<dVector> *p = prim.GetDataVec<dVector>("p");
00037     vector<dVector> *pref = prim.GetDataVec<dVector>("pref");
00038     vector<dVector> *n = NULL;
00039     vector<dVector> *nref = NULL;
00040     
00041     if (!pref)
00042     {
00044         Trace::Stream<<"SkinningPrimFunc::Run: aborting: primitive needs a pref (copy of p)"<<endl;
00045         return;
00046     }
00047     
00048     if (skinnormals)
00049     {
00050         n = prim.GetDataVec<dVector>("n");
00051         nref = prim.GetDataVec<dVector>("nref");
00052         if (!nref)
00053         {
00054             Trace::Stream<<"SkinningPrimFunc::Run: aborting: primitive needs an nref (copy of n)"<<endl;
00055             return;
00056         }
00057     }
00058     
00059     const SceneNode *root = static_cast<const SceneNode *>(world.FindNode(rootid));
00060     if (!root)
00061     {
00062         Trace::Stream<<"GenSkinWeightsPrimFunc::Run: couldn't find skeleton root node "<<rootid<<endl;
00063         return;
00064     }
00065     
00066     const SceneNode *bindposeroot = static_cast<const SceneNode *>(world.FindNode(bindposerootid));
00067     if (!root)
00068     {
00069         Trace::Stream<<"GenSkinWeightsPrimFunc::Run: couldn't find bindopose skeleton root node "<<bindposerootid<<endl;
00070         return;
00071     }
00072     
00073     // get the nodes as flat lists
00074     vector<const SceneNode*> skeleton;
00075     world.GetNodes(root, skeleton);
00076     vector<const SceneNode*> bindposeskeleton;
00077     world.GetNodes(bindposeroot, bindposeskeleton);
00078 
00079     if (skeleton.size()!=bindposeskeleton.size())
00080     {
00081         Trace::Stream<<"SkinningPrimFunc::Run: aborting: skeleton sizes do not match! "<<
00082             skeleton.size()<<" vs "<<bindposeskeleton.size()<<endl;
00083         return;
00084     }
00085     
00086     // make a vector of all the transforms
00087     vector<dMatrix> transforms;
00088     for (unsigned int i=0; i<skeleton.size(); i++)
00089     {
00090         transforms.push_back(world.GetGlobalTransform(skeleton[i])*
00091                              world.GetGlobalTransform(bindposeskeleton[i]).inverse());
00092     }
00093     
00094     // get pointers to all the weights
00095     vector<vector<float>*> weights;
00096     for (unsigned int bone=0; bone<skeleton.size(); bone++)
00097     {
00098         char wname[235];
00099         snprintf(wname,256,"w%d",bone);
00100         vector<float> *w = prim.GetDataVec<float>(wname);
00101         if (w==NULL)
00102         {
00103             Trace::Stream<<"SkinningPrimFunc::Run: can't find weights, aborting"<<endl;
00104             return;
00105         }
00106         weights.push_back(w);
00107     }
00108     
00109     for (unsigned int i=0; i<prim.Size(); i++)
00110     {
00111         dMatrix mat;
00112         mat.zero();
00113         for (unsigned int bone=0; bone<skeleton.size(); bone++)
00114         {
00115             mat+=(transforms[bone]*(*weights[bone])[i]);
00116         }
00117         
00118         (*p)[i]=mat.transform((*pref)[i]);
00119         
00120         if (skinnormals)
00121         {
00122             (*n)[i]=mat.transform_no_trans((*nref)[i]);
00123         }
00124     }
00125 }

Generated on Tue Sep 4 23:22:18 2007 for The Fluxus Renderer (libfluxus) by  doxygen 1.5.1