bind method

dynamic bind()

Implementation

bind() {
  var targetObject = node;
  var parsedPath = this.parsedPath;

  var objectName = parsedPath["objectName"];
  propertyName = parsedPath["propertyName"];
  var propertyIndex = parsedPath["propertyIndex"];

  if (targetObject == null) {
    targetObject = PropertyBinding.findNode(rootNode, parsedPath["nodeName"]) || rootNode;

    node = targetObject;
  }

  // set fail state so we can just 'return' on error
  getValue = _getValueUnavailable;
  setValue = _setValueUnavailable;

  // ensure there is a value node
  if (targetObject == null) {
    print('three.PropertyBinding: Trying to update node for track: $path but it wasn\'t found.');
    return;
  }

  if (objectName != null) {
    var objectIndex = parsedPath["objectIndex"];

    // special cases were we need to reach deeper into the hierarchy to get the face materials....
    switch (objectName) {
      case 'materials':
        if (!targetObject.material) {
          print('three.PropertyBinding: Can not bind to material as node does not have a material. ${this}');
          return;
        }

        if (!targetObject.material.materials) {
          print(
              'three.PropertyBinding: Can not bind to material.materials as node.material does not have a materials array. ${this}');
          return;
        }

        targetObject = targetObject.material.materials;

        break;

      case 'bones':
        if (!targetObject.skeleton) {
          print('three.PropertyBinding: Can not bind to bones as node does not have a skeleton. ${this}');
          return;
        }

        // potential future optimization: skip this if propertyIndex is already an integer
        // and convert the integer string to a true integer.

        targetObject = targetObject.skeleton.bones;

        // support resolving morphTarget names into indices.
        for (var i = 0; i < targetObject.length; i++) {
          if (targetObject[i].name == objectIndex) {
            objectIndex = i;
            break;
          }
        }

        break;

      default:
        if (targetObject.getProperty(objectName) == null) {
          print('three.PropertyBinding: Can not bind to objectName of node null. ${this}');
          return;
        }

        // targetObject = targetObject[ objectName ];
        targetObject = targetObject.getProperty(objectName);
    }

    if (objectIndex != null) {
      if (targetObject[objectIndex] == null) {
        print(
            'three.PropertyBinding: Trying to bind to objectIndex of objectName, but is null.${this} $targetObject');
        return;
      }

      targetObject = targetObject[objectIndex];
    }
  }

  // resolve property
  var nodeProperty = targetObject.getProperty(propertyName);

  if (nodeProperty == null) {
    var nodeName = parsedPath["nodeName"];

    print(
        'three.PropertyBinding: Trying to update property for track: $nodeName $propertyName  but it wasn\'t found. $targetObject');
    return;
  }

  // determine versioning scheme
  var versioning = versioningObject["None"];

  this.targetObject = targetObject;

  if (targetObject is Material) {
    // material
    versioning = versioningObject["NeedsUpdate"];
  } else if (targetObject is Object3D) {
    // node transform

    versioning = versioningObject["MatrixWorldNeedsUpdate"];
  }

  // determine how the property gets bound
  var bindingType = bindingTypeObject["Direct"];

  if (propertyIndex != null) {
    // access a sub element of the property array (only primitives are supported right now)

    if (propertyName == 'morphTargetInfluences') {
      // potential optimization, skip this if propertyIndex is already an integer, and convert the integer string to a true integer.

      // support resolving morphTarget names into indices.
      if (!targetObject.geometry) {
        print(
            'three.PropertyBinding: Can not bind to morphTargetInfluences because node does not have a geometry. ${this}');
        return;
      }

      if (targetObject.geometry is BufferGeometry) {
        if (!targetObject.geometry.morphAttributes) {
          print(
              'three.PropertyBinding: Can not bind to morphTargetInfluences because node does not have a geometry.morphAttributes. ${this}');
          return;
        }

        if (targetObject.morphTargetDictionary[propertyIndex] != null) {
          propertyIndex = targetObject.morphTargetDictionary[propertyIndex];
        }
      } else {
        print(
            'three.PropertyBinding: Can not bind to morphTargetInfluences on three.Geometry. Use three.BufferGeometry instead. ${this}');
        return;
      }
    }

    bindingType = bindingTypeObject["ArrayElement"];

    resolvedProperty = nodeProperty;
    this.propertyIndex = propertyIndex;
  } else if (nodeProperty is Color || nodeProperty is Vector3 || nodeProperty is Quaternion) {
    // must use copy for Object3D.Euler/Quaternion

    bindingType = bindingTypeObject["HasFromToArray"];

    resolvedProperty = nodeProperty;
  } else if (nodeProperty is List) {
    bindingType = bindingTypeObject["EntireArray"];

    resolvedProperty = nodeProperty;
  } else {
    propertyName = propertyName;
  }

  // select getter / setter
  getValue = getterByBindingType(bindingType!);
  setValue = setterByBindingTypeAndVersioning(bindingType, versioning);
}