23 #include "FCDocument/FCDEntity.h"
24 #include "FCDocument/FCDGeometryMesh.h"
25 #include "FCDocument/FCDGeometryPolygons.h"
26 #include "FCDocument/FCDGeometryPolygonsInput.h"
27 #include "FCDocument/FCDGeometrySource.h"
28 #include "FCDocument/FCDSkinController.h"
39 VertexData(
const float* pos,
const float* norm,
const std::vector<uv_pair_type> &
uvs,
40 const std::vector<FCDJointWeightPair>&
weights)
41 :
x(pos[0]),
y(pos[1]),
z(pos[2]),
42 nx(norm[0]),
ny(norm[1]),
nz(norm[2]),
50 std::vector<uv_pair_type>
uvs;
56 return (fabsf(a - b) < 0.000001f);
59 bool operator==(
const FCDJointWeightPair& a,
const FCDJointWeightPair& b)
61 return (a.jointIndex == b.jointIndex &&
similar(a.weight, b.weight));
64 bool operator<(
const FCDJointWeightPair& a,
const FCDJointWeightPair& b)
67 if (a.weight > b.weight)
69 else if (a.weight < b.weight)
71 else if (a.jointIndex < b.jointIndex)
92 #define CMP(f) if (a.f < b.f) return true; if (a.f > b.f) return false
101 template <
typename T>
110 typename std::map<T, size_t>::iterator it =
btree.find(val);
111 if (it !=
btree.end())
114 size_t idx =
vec.size();
116 btree.insert(std::make_pair(val, idx));
131 std::sort(weights.begin(), weights.end());
141 FCDGeometryPolygonsInput* inputPosition = polys->FindInput(FUDaeGeometryInput::POSITION);
142 FCDGeometryPolygonsInput* inputNormal = polys->FindInput(FUDaeGeometryInput::NORMAL);
143 FCDGeometryPolygonsInput* inputTexcoord = polys->FindInput(FUDaeGeometryInput::TEXCOORD);
145 size_t numVertices = polys->GetFaceVertexCount();
147 assert(inputPosition->GetIndexCount() == numVertices);
148 assert(inputNormal ->GetIndexCount() == numVertices);
149 assert(inputTexcoord->GetIndexCount() == numVertices);
151 const uint32* indicesPosition = inputPosition->GetIndices();
152 const uint32* indicesNormal = inputNormal->GetIndices();
153 const uint32* indicesTexcoord = inputTexcoord->GetIndices();
155 assert(indicesPosition);
156 assert(indicesNormal);
157 assert(indicesTexcoord);
159 FCDGeometrySourceList texcoordSources;
160 polys->GetParent()->FindSourcesByType(FUDaeGeometryInput::TEXCOORD, texcoordSources);
162 FCDGeometrySource* sourcePosition = inputPosition->GetSource();
163 FCDGeometrySource* sourceNormal = inputNormal ->GetSource();
165 const float* dataPosition = sourcePosition->GetData();
166 const float* dataNormal = sourceNormal ->GetData();
171 size_t numVertexPositions = sourcePosition->GetDataCount() / sourcePosition->GetStride();
172 assert(skin->GetInfluenceCount() == numVertexPositions);
176 uint32 stridePosition = sourcePosition->GetStride();
177 uint32 strideNormal = sourceNormal ->GetStride();
179 std::vector<uint32> indicesCombined;
180 std::vector<VertexData> vertexes;
183 for (
size_t i = 0; i < numVertices; ++i)
185 std::vector<FCDJointWeightPair> weights;
188 FCDSkinControllerVertex* influences = skin->GetVertexInfluence(indicesPosition[i]);
189 assert(influences != NULL);
190 for (
size_t j = 0; j < influences->GetPairCount(); ++j)
192 FCDJointWeightPair* pair = influences->GetPair(j);
193 assert(pair != NULL);
194 weights.push_back(*pair);
199 std::vector<uv_pair_type> uvs;
200 for (
size_t set = 0; set < texcoordSources.size(); ++set)
202 const float* dataTexcoord = texcoordSources[set]->GetData();
203 uint32 strideTexcoord = texcoordSources[set]->GetStride();
206 p.first = dataTexcoord[indicesTexcoord[i]*strideTexcoord];
207 p.second = dataTexcoord[indicesTexcoord[i]*strideTexcoord + 1];
212 &dataPosition[indicesPosition[i]*stridePosition],
213 &dataNormal [indicesNormal [i]*strideNormal],
217 size_t idx = inserter.
add(vtx);
218 indicesCombined.push_back((uint32)idx);
225 FloatList newDataPosition;
226 FloatList newDataNormal;
227 FloatList newDataTexcoord;
228 std::vector<std::vector<FCDJointWeightPair> > newWeightedMatches;
230 for (
size_t i = 0; i < vertexes.size(); ++i)
232 newDataPosition.push_back(vertexes[i].x);
233 newDataPosition.push_back(vertexes[i].y);
234 newDataPosition.push_back(vertexes[i].z);
235 newDataNormal .push_back(vertexes[i].nx);
236 newDataNormal .push_back(vertexes[i].ny);
237 newDataNormal .push_back(vertexes[i].nz);
238 newWeightedMatches.push_back(vertexes[i].weights);
243 inputPosition->SetIndices(&indicesCombined.front(), indicesCombined.size());
244 inputNormal ->SetIndices(&indicesCombined.front(), indicesCombined.size());
245 inputTexcoord->SetIndices(&indicesCombined.front(), indicesCombined.size());
247 for (
size_t set = 0; set < texcoordSources.size(); ++set)
249 newDataTexcoord.clear();
250 for (
size_t i = 0; i < vertexes.size(); ++i)
252 newDataTexcoord.push_back(vertexes[i].uvs[set].first);
253 newDataTexcoord.push_back(vertexes[i].uvs[set].second);
255 texcoordSources[set]->SetData(newDataTexcoord, 2);
258 sourcePosition->SetData(newDataPosition, 3);
259 sourceNormal ->SetData(newDataNormal, 3);
263 skin->SetInfluenceCount(newWeightedMatches.size());
264 for (
size_t i = 0; i < newWeightedMatches.size(); ++i)
266 skin->GetVertexInfluence(i)->SetPairCount(0);
267 for (
size_t j = 0; j < newWeightedMatches[i].size(); ++j)
268 skin->GetVertexInfluence(i)->AddPair(newWeightedMatches[i][j].jointIndex, newWeightedMatches[i][j].weight);
bool operator==(const FCDJointWeightPair &a, const FCDJointWeightPair &b)
void ReindexGeometry(FCDGeometryPolygons *polys, FCDSkinController *skin)
std::pair< float, float > uv_pair_type
bool similar(float a, float b)
void CanonicaliseWeights(std::vector< FCDJointWeightPair > &weights)
#define T(string_literal)
std::map< T, size_t > btree
std::vector< uv_pair_type > uvs
InserterWithoutDuplicates & operator=(const InserterWithoutDuplicates &)
std::vector< FCDJointWeightPair > weights
InserterWithoutDuplicates(std::vector< T > &vec)
VertexData(const float *pos, const float *norm, const std::vector< uv_pair_type > &uvs, const std::vector< FCDJointWeightPair > &weights)
bool operator<(const FCDJointWeightPair &a, const FCDJointWeightPair &b)