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 = new 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 = new 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 = new PointLight(color, intensity, distance, decay);
        break;

      case 1: // Directional
        model = new 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 =
            new SpotLight(color, intensity, distance, angle, penumbra, decay);
        break;

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

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

  return model;
}