import {Raycaster as Raycaster2} from "three/src/core/Raycaster";
import {MeshBasicMaterial as MeshBasicMaterial2} from "three/src/materials/MeshBasicMaterial";
import {DoubleSide} from "three/src/constants";
import {TypedSopNode} from "./_Base";
import {InputCloneMode as InputCloneMode2} from "../../poly/InputCloneMode";
const MAT_DOUBLE_SIDED = new MeshBasicMaterial2({
  side: DoubleSide
});
import {NodeParamsConfig, ParamConfig} from "../utils/params/ParamsConfig";
class RaySopParamsConfig extends NodeParamsConfig {
  constructor() {
    super(...arguments);
    this.useNormals = ParamConfig.BOOLEAN(1);
    this.direction = ParamConfig.VECTOR3([0, -1, 0], {
      visibleIf: {useNormals: 0}
    });
    this.transferFaceNormals = ParamConfig.BOOLEAN(1);
  }
}
const ParamsConfig2 = new RaySopParamsConfig();
export class RaySopNode extends TypedSopNode {
  constructor() {
    super(...arguments);
    this.params_config = ParamsConfig2;
    this._bound_assign_mat = this._assign_double_sided_material_to_object.bind(this);
    this._raycaster = new Raycaster2();
  }
  static type() {
    return "ray";
  }
  static double_sided_material() {
    return MAT_DOUBLE_SIDED;
  }
  static displayedInputNames() {
    return ["geometry to move", "geometry to ray onto"];
  }
  initializeNode() {
    this.io.inputs.setCount(2);
    this.io.inputs.initInputsClonedState([
      InputCloneMode2.FROM_NODE,
      InputCloneMode2.ALWAYS
    ]);
  }
  create_params() {
  }
  cook(input_contents) {
    const core_group = input_contents[0];
    const core_group_collision = input_contents[1];
    this.ray(core_group, core_group_collision);
  }
  ray(core_group, core_group_collision) {
    this._assign_double_sided_material_to_core_group(core_group_collision);
    let direction, first_intersect;
    for (let point of core_group.points()) {
      direction = this.pv.useNormals ? point.normal() : this.pv.direction;
      this._raycaster.set(point.position(), direction);
      first_intersect = this._raycaster.intersectObjects(core_group_collision.objects(), true)[0];
      if (first_intersect) {
        point.setPosition(first_intersect.point);
        if (this.pv.transferFaceNormals && first_intersect.face) {
          point.setNormal(first_intersect.face.normal);
        }
      }
    }
    this.setCoreGroup(core_group);
  }
  _assign_double_sided_material_to_core_group(core_group) {
    for (let object of core_group.objects()) {
      object.traverse(this._bound_assign_mat);
    }
  }
  _assign_double_sided_material_to_object(object) {
    object.material = RaySopNode.double_sided_material();
  }
}
