import { pause, checkPropTypes, UUIDRegex } from '../../lib.js';
import { Matrix4, Object3D, Vector2, Vector3, Quaternion, Group, Mesh, Vector4, Math, Euler } from '../../../node_modules/three/build/three.module.js';
import { Reporter } from '../../reporter/reporter.js';
import { Project } from '../../project.js';
import { BuildableComponent } from './buildable_component.js';
import { Export } from '../../export/export.js';
/**
* Situates components; provides them with a position and quaternion
*/
class PositionedComponent extends BuildableComponent {
/**
* @param {Reporter} reporter
* @param {Object} settings
* @param {UUID} [settings.id]
* @param {Vector3} settings.position
* @param {Quaternion} settings.quaternion
* @param {Boolean} [settings.assignable = false]
* @param {BuildableComponent} settings.component
*/
constructor(reporter, settings) {
settings.assignable = settings.assignable === true ? true : false;
super(
reporter,
settings,
);
checkPropTypes(
settings,
{
component: [
{
test: BuildableComponent,
msg: 'must be buildable'
},
{
test: val => !(val instanceof PositionedComponent),
msg: 'Do not nest positioned components'
},
],
quaternion: Quaternion,
position: Vector3
},
{}
);
// fucking typescript
if (!Object.getOwnPropertyDescriptor(this, 'component')) {
/** @type {BuildableComponent} */
this.component = settings.component;
}
if (!Object.getOwnPropertyDescriptor(this, 'assignable')) { //['get']) {
/** @type {Boolean} */
Object.defineProperty(
this,
'assignable',
{
get : () => settings.component.assignable
}
);
}
}
/** @type {ExportLevel} */
static _exportLevel = 'inline';
/** @type {Boolean} */
get materializable() {
return this.component.settings.materialVariantGroup !== undefined;
}
async _build(part, quality, dependencies) {
switch (part) {
case 'UI':
this._setContent(
'UI',
quality,
this._settings.component.content.UI[quality]
);
break;
case 'main':
const depContent = this._settings.component.content.main[quality];
const clonableContent = depContent instanceof Object3D ? depContent : Object.values(depContent).find(depObjVal => depObjVal instanceof Object3D);
const clonedObject3D = clonableContent.clone();
clonedObject3D.castShadow = true;
clonedObject3D.receiveShadow = true;
clonedObject3D.layers.set( Project.layerMap.visibleActors );
// LOCAL - OBJECT - WORLD SPACE TRANSFORMS
// transforms need to be done in world space!
//-------------------- JSON TRANSFROMS TRANSLATION--------------------------
// Apply specified translation from json
clonedObject3D.translateX(this._settings.position.x);
clonedObject3D.translateY(this._settings.position.y);
clonedObject3D.translateZ(this._settings.position.z);
//-------------------- GLTF BASIS TRANSFROMS --------------------------
// Apply the quaternion from the imported file axes
if (depContent.transformMatrix instanceof Matrix4) {
//clonedObject3D.applyMatrix4( depContent.transformMatrix); //transformMatrix toepassen voor de juiste import in et assenstelesel
clonedObject3D.setRotationFromMatrix(depContent.transformMatrix); //transformMatrix toepassen voor de juiste import in et assenstelesel
}
//------------------- JSON TRANSFORM ROTATION ------------
//console.log( this._settings.quaternion )
clonedObject3D.quaternion.multiply(this._settings.quaternion)
clonedObject3D.updateMatrixWorld();
// console.log( this.label, Object.keys( this ) );
// THREE.js clone function does JSON.stringify(JSON.parse)
// and since this engine relies heavily on the clone function
// storing a direct reference to an object is not possible
// clonedObject3D.userData.origin = this; // <-- does not work, unfortunately
// so we can use Object3D.findByName in the scene
clonedObject3D.name = this.id;
// let's deprecate this:
Object.defineProperty(
clonedObject3D.userData,
'origin',
{
get: () => {
console.log( 'DEPRECATED! Use userData.PB.origin' );
return this.id;
}
}
);
// in favor of this:
clonedObject3D.userData.PB = {
origin: this.id,
type: this.constructor.name
};
this._setContent(
'main',
quality,
clonedObject3D
);
break;
default:
this._setContent(part, quality, null);
break;
}
return this;
}
}
export { PositionedComponent };