import {AdvancedShape} from "../../../core/shapes/AdvancedShape.js";
import smoothMaxPoly from "../../imports/smoothMaxPoly.glsl";
import sdfRegular from "./shaders/sdfRegular.glsl.mustache";
import gradientRegular from "./shaders/gradientRegular.glsl.mustache";
import sdfPoly from "./shaders/sdfPoly.glsl.mustache";
import gradientPoly from "./shaders/gradientPoly.glsl.mustache";
import uv from "./shaders/uv.glsl.mustache";
import struct from "./shaders/struct.glsl";
export const REGULAR_MAX = 0;
export const SMOOTH_MAX_POLY = 1;
export const SMOOTH_MAX_EXP = 2;
export const SMOOTH_MAX_POWER = 3;
/**
* @class
*
* @classdesc
* Intersection of two shapes
*/
export class IntersectionShape extends AdvancedShape {
/**
* Constructor.
* The two shapes should be both local or both global
* @param {Shape} shape1 - the first shape
* @param {Shape} shape2 - the second shape
* @param {Object} params - parameters (basically which kind of max is used)
*/
constructor(shape1, shape2, params = {}) {
if (shape1.isGlobal !== shape2.isGlobal) {
throw new Error('IntersectionShape: the two shapes should be both local or both global');
}
super();
this.shape1 = shape1;
this.shape2 = shape2;
this.shape1.parent = this;
this.shape2.parent = this;
this.maxType = params.maxType !== undefined ? params.maxType : REGULAR_MAX;
this.maxCoeff = 0;
switch (this.maxType) {
case SMOOTH_MAX_POLY:
this.addImport(smoothMaxPoly);
this.maxCoeff = params.maxCoeff !== undefined ? params.maxCoeff : 0.1;
break;
}
}
updateAbsoluteIsom() {
super.updateAbsoluteIsom();
this.shape1.updateAbsoluteIsom();
this.shape2.updateAbsoluteIsom();
}
updateData() {
super.updateData();
this.shape1.updateData();
this.shape2.updateData();
}
get uniformType() {
return 'IntersectionShape';
}
static glslClass() {
return struct;
}
get isGlobal() {
return this.shape1.isGlobal;
}
get hasUVMap() {
return this.shape1.hasUVMap && this.shape2.hasUVMap;
}
glslSDF() {
switch (this.maxType) {
case SMOOTH_MAX_POLY:
return sdfPoly(this);
default:
return sdfRegular(this);
}
}
glslGradient() {
switch (this.maxType) {
case SMOOTH_MAX_POLY:
return gradientPoly(this);
default:
return gradientRegular(this);
}
}
glslUVMap() {
return uv(this);
}
/**
* Set the ID of the shape.
* Propagate the call.
* @param {Scene} scene - the scene to which the object is added.
*/
setId(scene) {
this.shape1.setId(scene);
this.shape2.setId(scene);
super.setId(scene);
}
/**
* Additional actions to perform when the object is added to the scene.
* Propagate the call.
* @param {Scene} scene - the scene to which the object is added.
*/
onAdd(scene) {
this.shape1.onAdd(scene);
this.shape2.onAdd(scene);
super.onAdd(scene);
}
shader(shaderBuilder) {
this.shape1.shader(shaderBuilder);
this.shape2.shader(shaderBuilder);
super.shader(shaderBuilder);
}
}
/**
* The intersection of an arbitrary number of shapes
*/
export function intersection() {
let res;
let params = {};
const n = arguments.length;
if (n === 0) {
throw new Error('union: the function expect at least one argument');
}
if (!arguments[n - 1].isShape) {
params = arguments[n - 1];
}
res = arguments[0];
for (let i = 1; i < n; i++) {
if (arguments[i].isShape) {
res = new IntersectionShape(res, arguments[i], params);
}
}
return res;
}