void SkinCluster::SetWeights(double inSigma, double outSigma){ //0.007 0.01 for(int k1=0;k1<mSize;k1++){ for(int k2=k1;k2<mSize;k2++){ double dn = mDistance(k1,k2); mWeights(k1,k2) = mWeights(k2,k1) = ((exp(-(dn*dn)/(2.0*inSigma*inSigma))-exp(-(dn*dn)/(2.0*outSigma*outSigma)))); } mWeights.SetRow(mWeights.GetRow(k1) - mWeights.GetRow(k1).Max(),k1); mWeights.SetRow(mWeights.GetRow(k1) * (-double(mSize)/mWeights.GetRow(k1).Sum()),k1); } mWeights*=0.05; }
void CpuShortestPath::Compute(std::stack<std::pair<int, int>>& path) { // Compute the distances on the top of the grid. These are simply partial // sums of weights along a linear path. float distance = 0.0f; mNodes(0, 0) = Node(distance, -1, -1); for (int x = 1; x < mSize; ++x) { distance += mWeights(x - 1, 0).w1; mNodes(x, 0) = Node(distance, x - 1, 0); } // Compute the distances on the left edge of the grid. distance = 0.0f; for (int y = 1; y < mSize; ++y) { distance += mWeights(0, y - 1).w2; mNodes(0, y) = Node(distance, 0, y - 1); } // The update function for computing the minimum distance at a node using // the three incoming edges from its neighbors. std::function<void(int, int)> Update = [this](int x, int y) { float dmin = mNodes(x - 1, y).distance + mWeights(x - 1, y).w1; mNodes(x, y) = Node(dmin, x - 1, y); float d = mNodes(x, y - 1).distance + mWeights(x, y - 1).w2; if (d < dmin) { dmin = d; mNodes(x, y) = Node(dmin, x, y - 1); } d = mNodes(x - 1, y - 1).distance + mWeights(x - 1, y - 1).w3; if (d < dmin) { dmin = d; mNodes(x, y) = Node(dmin, x - 1, y - 1); } }; // Compute the distances on the segments x+y=z. NOTE: The construction // uses knowledge that the grid is a square. The logic is slightly more // complicated for a nonsquare grid, because you have to know when the // segments transition from an endpoint on the left edge to an endpoint // on the bottom edge (width > height) or from an endpoint on the top // edge to an endpoint on the right edge (width < height). In the case // of a square, the endpoints are on left-top and transition to // bottom-right at the same time. for (int z = 2; z < mSize; ++z) { for (int x = 1, y = z - x; y > 0; ++x, --y) { Update(x, y); } } for (int z = mSize; z <= 2 * (mSize - 1); ++z) { for (int y = mSize - 1, x = z - y; x < mSize; --y, ++x) { Update(x, y); } } // Create the path by starting at (mXSize-1,mYSize-1) and following the // previous links. int x = mSize - 1, y = mSize - 1; while (x != -1) { path.push(std::make_pair(x, y)); Node n = mNodes(x, y); x = n.xPrevious; y = n.yPrevious; } }