00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include <float.h>
00018 #include "GenSkinWeightsPrimFunc.h"
00019 #include "Primitive.h"
00020 #include "SceneGraph.h"
00021 #include "Geometry.h"
00022
00023 using namespace Fluxus;
00024
00025 GenSkinWeightsPrimFunc::GenSkinWeightsPrimFunc()
00026 {
00027 }
00028
00029 GenSkinWeightsPrimFunc::~GenSkinWeightsPrimFunc()
00030 {
00031 }
00032
00033 void GenSkinWeightsPrimFunc::Run(Primitive &prim, const SceneGraph &world)
00034 {
00035 int rootid = GetArg<int>("skeleton-root",0);
00036 float sharpness = GetArg<float>("sharpness",0);
00037 vector<dVector> *p = prim.GetDataVec<dVector>("p");
00038 vector<TypedPData<float> *> weights;
00039 int bone=0;
00040 vector<pair<const SceneNode*,const SceneNode*> > skeleton;
00041
00042 const SceneNode *root = static_cast<const SceneNode *>(world.FindNode(rootid));
00043 if (!root)
00044 {
00045 Trace::Stream<<"GenSkinWeightsPrimFunc::Run: couldn't find skeleton root node"<<endl;
00046 return;
00047 }
00048
00049 world.GetConnections(root, skeleton);
00050
00051
00052 for (vector<pair<const SceneNode*,const SceneNode*> >::iterator i=skeleton.begin();
00053 i!=skeleton.end(); i++)
00054 {
00055 assert(i->first && i->second);
00056
00057
00058 weights.push_back(new TypedPData<float>(prim.Size()));
00059
00060
00061 dVector startbone = world.GetGlobalTransform(i->first).transform(dVector(0,0,0));
00062 dVector endbone = world.GetGlobalTransform(i->second).transform(dVector(0,0,0));
00063
00064 for (unsigned int n=0; n<prim.Size(); n++)
00065 {
00066 float d=PointLineDist((*p)[n],startbone,endbone);
00067 if (d==0) weights[bone]->m_Data[n]=2;
00068 else weights[bone]->m_Data[n]=(1/d);
00069 }
00070
00071 bone++;
00072 }
00073
00074 weights.push_back(new TypedPData<float>(prim.Size()));
00075 for (unsigned int n=0; n<prim.Size(); n++)
00076 {
00077 weights[bone]->m_Data[n]=0;
00078 }
00079
00080
00081
00082 for (unsigned int n=0; n<prim.Size(); n++)
00083 {
00084 for (unsigned int bone=0; bone<weights.size(); bone++)
00085 {
00086 weights[bone]->m_Data[n]=powf(weights[bone]->m_Data[n],sharpness);
00087 }
00088 }
00089
00090
00091 for (unsigned int n=0; n<prim.Size(); n++)
00092 {
00093 float m=0;
00094 for (unsigned int bone=0; bone<weights.size(); bone++)
00095 {
00096 m+=weights[bone]->m_Data[n];
00097 }
00098
00099 for (unsigned int bone=0; bone<weights.size(); bone++)
00100 {
00101 weights[bone]->m_Data[n]/=m;
00102 }
00103 }
00104
00105
00106
00107 for (unsigned int bone=0; bone<weights.size(); bone++)
00108 {
00109 char wname[256];
00110 snprintf(wname,256,"w%d",bone);
00111 prim.AddData(wname, weights[bone]);
00112 }
00113 }