createLight method

dynamic createLight(
  1. dynamic relationships
)

Implementation

createLight(relationships) {
  var model;
  var lightAttribute;

  relationships.children.forEach((child) {
    var attr = fbxTree.objects["NodeAttribute"][child["ID"]];

    if (attr != null) {
      lightAttribute = attr;
    }
  });

  if (lightAttribute == null) {
    model = Object3D();
  } else {
    var type;

    // LightType can be null for Point lights
    if (lightAttribute.LightType == null) {
      type = 0;
    } else {
      type = lightAttribute.LightType.value;
    }

    var color = Color.fromHex(0xffffff);

    if (lightAttribute.Color != null) {
      color = Color().fromArray(lightAttribute.Color.value);
    }

    var intensity = (lightAttribute.Intensity == null) ? 1 : lightAttribute.Intensity.value / 100;

    // light disabled
    if (lightAttribute.CastLightOnObject != null && lightAttribute.CastLightOnObject.value == 0) {
      intensity = 0;
    }

    double distance = 0.0;
    if (lightAttribute.FarAttenuationEnd != null) {
      if (lightAttribute.EnableFarAttenuation != null && lightAttribute.EnableFarAttenuation.value == 0) {
        distance = 0.0;
      } else {
        distance = lightAttribute.FarAttenuationEnd.value;
      }
    }

    // TODO: could this be calculated linearly from FarAttenuationStart to FarAttenuationEnd?
    double decay = 1.0;

    switch (type) {
      case 0: // Point
        model = PointLight(color, intensity, distance, decay);
        break;

      case 1: // Directional
        model = DirectionalLight(color, intensity);
        break;

      case 2: // Spot
        num angle = Math.pi / 3;

        if (lightAttribute.InnerAngle != null) {
          angle = MathUtils.degToRad(lightAttribute.InnerAngle.value);
        }

        num penumbra = 0;
        if (lightAttribute.OuterAngle != null) {
          // TODO: this is not correct - FBX calculates outer and inner angle in degrees
          // with OuterAngle > InnerAngle && OuterAngle <= Math.pi
          // while three.js uses a penumbra between (0, 1) to attenuate the inner angle
          penumbra = MathUtils.degToRad(lightAttribute.OuterAngle.value);
          penumbra = Math.max(penumbra, 1);
        }

        model = SpotLight(color, intensity, distance, angle, penumbra, decay);
        break;

      default:
        print('THREE.FBXLoader: Unknown light type ${lightAttribute.LightType.value}, defaulting to a PointLight.');
        model = PointLight(color, intensity);
        break;
    }

    if (lightAttribute.CastShadows != null && lightAttribute.CastShadows.value == 1) {
      model.castShadow = true;
    }
  }

  return model;
}