genBuffers method
dynamic
genBuffers(
- dynamic geoInfo
Implementation
genBuffers(geoInfo) {
var buffers = {
"vertex": [],
"normal": [],
"colors": [],
"uvs": [],
"materialIndex": [],
"vertexWeights": [],
"weightsIndices": [],
};
var polygonIndex = 0;
var faceLength = 0;
var displayedWeightsWarning = false;
// these will hold data for a single face
var facePositionIndexes = [];
var faceNormals = [];
var faceColors = [];
var faceUVs = [];
var faceWeights = [];
var faceWeightIndices = [];
var scope = this;
geoInfo["vertexIndices"].asMap().forEach((polygonVertexIndex, vertexIndex) {
var materialIndex;
var endOfFace = false;
// Face index and vertex index arrays are combined in a single array
// A cube with quad faces looks like this:
// PolygonVertexIndex: *24 {
// a: 0, 1, 3, -3, 2, 3, 5, -5, 4, 5, 7, -7, 6, 7, 1, -1, 1, 7, 5, -4, 6, 0, 2, -5
// }
// Negative numbers mark the end of a face - first face here is 0, 1, 3, -3
// to find index of last vertex bit shift the index: ^ - 1
if (vertexIndex < 0) {
vertexIndex = vertexIndex ^ -1; // equivalent to ( x * -1 ) - 1
endOfFace = true;
}
var weightIndices = [];
var weights = [];
facePositionIndexes.addAll([vertexIndex * 3, vertexIndex * 3 + 1, vertexIndex * 3 + 2]);
if (geoInfo["color"] != null) {
var data = getData(polygonVertexIndex, polygonIndex, vertexIndex, geoInfo["color"]);
faceColors.addAll([data[0], data[1], data[2]]);
}
if (geoInfo["skeleton"] != null) {
if (geoInfo["weightTable"][vertexIndex] != null) {
geoInfo["weightTable"][vertexIndex].forEach((wt) {
weights.add(wt["weight"]);
weightIndices.add(wt["id"]);
});
}
if (weights.length > 4) {
if (!displayedWeightsWarning) {
print(
'THREE.FBXLoader: Vertex has more than 4 skinning weights assigned to vertex. Deleting additional weights.');
displayedWeightsWarning = true;
}
var wIndex = [0, 0, 0, 0];
var w = [0, 0, 0, 0];
weights.asMap().forEach((weightIndex, weight) {
var currentWeight = weight;
var currentIndex = weightIndices[weightIndex];
var comparedWeightArray = w;
w.asMap().forEach((comparedWeightIndex, comparedWeight) {
if (currentWeight > comparedWeight) {
comparedWeightArray[comparedWeightIndex] = currentWeight;
currentWeight = comparedWeight;
var tmp = wIndex[comparedWeightIndex];
wIndex[comparedWeightIndex] = currentIndex;
currentIndex = tmp;
}
});
});
weightIndices = wIndex;
weights = w;
}
// if the weight array is shorter than 4 pad with 0s
while (weights.length < 4) {
weights.add(0);
weightIndices.add(0);
}
for (var i = 0; i < 4; ++i) {
faceWeights.add(weights[i]);
faceWeightIndices.add(weightIndices[i]);
}
}
if (geoInfo["normal"] != null) {
var data = getData(polygonVertexIndex, polygonIndex, vertexIndex, geoInfo["normal"]);
faceNormals.addAll([data[0], data[1], data[2]]);
}
if (geoInfo["material"] != null && geoInfo["material"]["mappingType"] != 'AllSame') {
materialIndex = getData(polygonVertexIndex, polygonIndex, vertexIndex, geoInfo["material"])[0];
}
if (geoInfo["uv"] != null) {
geoInfo["uv"].asMap().forEach((i, uv) {
var data = getData(polygonVertexIndex, polygonIndex, vertexIndex, uv);
if (faceUVs.length == i) {
faceUVs.add([]);
}
faceUVs[i].add(data[0]);
faceUVs[i].add(data[1]);
});
}
faceLength++;
if (endOfFace) {
scope.genFace(buffers, geoInfo, facePositionIndexes, materialIndex, faceNormals, faceColors, faceUVs,
faceWeights, faceWeightIndices, faceLength);
polygonIndex++;
faceLength = 0;
// reset arrays for the next face
facePositionIndexes = [];
faceNormals = [];
faceColors = [];
faceUVs = [];
faceWeights = [];
faceWeightIndices = [];
}
});
return buffers;
}