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