polygonjs-engine
Version:
node-based webgl 3D engine https://polygonjs.com
99 lines (93 loc) • 3.09 kB
text/typescript
import {BaseSopOperation} from './_Base';
import {DefaultOperationParams} from '../_Base';
import {CoreGroup} from '../../geometry/Group';
import {Mesh} from 'three/src/objects/Mesh';
import {Material} from 'three/src/materials/Material';
import {Texture} from 'three/src/textures/Texture';
import {InputCloneMode} from '../../../engine/poly/InputCloneMode';
import {Poly} from '../../../engine/Poly';
import {MAG_FILTER_DEFAULT_VALUE, MIN_FILTER_DEFAULT_VALUE} from '../../../core/cop/ConstantFilter';
interface TexturePropertiesSopParams extends DefaultOperationParams {
applyToChildren: boolean;
// anisotropy
tanisotropy: boolean;
useRendererMaxAnisotropy: boolean;
anisotropy: number;
// filters
tminFilter: boolean;
minFilter: number;
tmagFilter: boolean;
magFilter: number;
}
export class TexturePropertiesSopOperation extends BaseSopOperation {
static readonly DEFAULT_PARAMS: TexturePropertiesSopParams = {
applyToChildren: false,
// anisotropy
tanisotropy: false,
useRendererMaxAnisotropy: false,
anisotropy: 1,
// filters
tminFilter: false,
minFilter: MIN_FILTER_DEFAULT_VALUE,
tmagFilter: false,
magFilter: MAG_FILTER_DEFAULT_VALUE,
};
static readonly INPUT_CLONED_STATE = InputCloneMode.FROM_NODE;
static type(): Readonly<'textureProperties'> {
return 'textureProperties';
}
async cook(input_contents: CoreGroup[], params: TexturePropertiesSopParams) {
const core_group = input_contents[0];
const objects: Mesh[] = [];
for (let object of core_group.objects() as Mesh[]) {
if (params.applyToChildren) {
object.traverse((child) => {
objects.push(child as Mesh);
});
} else {
objects.push(object);
}
}
const promises = objects.map((object) => this._update_object(object, params));
await Promise.all(promises);
return core_group;
}
private async _update_object(object: Mesh, params: TexturePropertiesSopParams) {
const material = object.material as Material;
if (material) {
await this._update_material(material, params);
}
}
private async _update_material(material: Material, params: TexturePropertiesSopParams) {
let texture: Texture = (material as any).map;
if (texture) {
await this._update_texture(texture, params);
}
}
private async _update_texture(texture: Texture, params: TexturePropertiesSopParams) {
if (params.tanisotropy) {
await this._update_anisotropy(texture, params);
}
if (params.tminFilter || params.tmagFilter) {
this._update_filter(texture, params);
}
}
private async _update_anisotropy(texture: Texture, params: TexturePropertiesSopParams) {
if (params.useRendererMaxAnisotropy) {
const renderer = await Poly.renderersController.firstRenderer();
if (renderer) {
texture.anisotropy = renderer.capabilities.getMaxAnisotropy();
}
} else {
texture.anisotropy = params.anisotropy;
}
}
private _update_filter(texture: Texture, params: TexturePropertiesSopParams) {
if (params.tminFilter) {
texture.minFilter = params.minFilter;
}
if (params.tmagFilter) {
texture.magFilter = params.magFilter;
}
}
}