genBuffers method

dynamic genBuffers(
  1. 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;
}