@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
197 lines (196 loc) • 5.56 kB
JavaScript
;
import { Texture } from "three";
import { Matrix3 } from "three";
import { MaterialLoader } from "three";
import { Material } from "three";
import { ShaderMaterial } from "three";
import { MaterialUserDataUniforms, OnBeforeCompileDataHandler } from "../gl/code/assemblers/materials/OnBeforeCompile";
import { MeshDepthMaterial } from "three";
import {
ShadowMaterial,
SpriteMaterial,
RawShaderMaterial,
PointsMaterial,
MeshPhysicalMaterial,
MeshStandardMaterial,
MeshPhongMaterial,
MeshToonMaterial,
MeshNormalMaterial,
MeshLambertMaterial,
MeshDistanceMaterial,
MeshBasicMaterial,
MeshMatcapMaterial,
LineDashedMaterial,
LineBasicMaterial
} from "three";
function MonkeyPatchMaterial() {
const materialLib = {
ShadowMaterial,
SpriteMaterial,
RawShaderMaterial,
ShaderMaterial,
PointsMaterial,
MeshPhysicalMaterial,
MeshStandardMaterial,
MeshPhongMaterial,
MeshToonMaterial,
MeshNormalMaterial,
MeshLambertMaterial,
MeshDepthMaterial,
MeshDistanceMaterial,
MeshBasicMaterial,
MeshMatcapMaterial,
LineDashedMaterial,
LineBasicMaterial,
Material
};
Material.fromType = function(type) {
return new materialLib[type]();
};
}
const ENTRY_NAMES_TO_REMOVE = /* @__PURE__ */ new Set(["shaders", "functionBody"]);
export class BasePersistedConfig {
constructor(node) {
this.node = node;
}
load(data) {
}
async toDataWithoutShaders() {
const data = await this.toData();
if (!data) {
return;
}
const dataWithoutShaders = {};
const entryNames = Object.keys(data);
for (const entryName of entryNames) {
if (!ENTRY_NAMES_TO_REMOVE.has(entryName)) {
dataWithoutShaders[entryName] = data[entryName];
}
}
return dataWithoutShaders;
}
//
//
// SAVE MAT
//
//
_materialToJson(material, options) {
let material_data = void 0;
this._withPreparedMaterial(material, () => {
try {
material_data = material.toJSON();
if (material_data) {
const depthPacking = material.depthPacking;
material_data.depthPacking = depthPacking;
}
} catch (err) {
console.error("failed to save material data");
console.log(material);
console.log(err);
}
if (material_data && material.lights != null) {
material_data.lights = material.lights;
}
if (material_data) {
material_data.uuid = `${options.node.path()}-${options.suffix}`;
}
});
return material_data;
}
_withPreparedMaterial(material, callback) {
this._withUnassignedUniformTextures(material, () => {
this._withUnassignedBasePropertyTextures(material, () => {
this._withUnassignedOnBeforeCompileData(material, () => {
callback();
});
});
});
}
_withUnassignedOnBeforeCompileData(material, callback) {
const uniforms = MaterialUserDataUniforms.removeUniforms(material);
const onBeforeCompileData = OnBeforeCompileDataHandler.removeData(material);
callback();
if (uniforms) {
MaterialUserDataUniforms.setUniforms(material, uniforms);
}
if (onBeforeCompileData) {
OnBeforeCompileDataHandler.setData(material, onBeforeCompileData);
}
}
_withUnassignedUniformTextures(material, callback) {
const textureByUniformName = /* @__PURE__ */ new Map();
const uniforms = material.uniforms;
if (uniforms) {
const uniformNames = Object.keys(uniforms);
for (const uniformName of uniformNames) {
const value = uniforms[uniformName].value;
if (value && value.uuid) {
const texture = value;
textureByUniformName.set(uniformName, texture);
uniforms[uniformName].value = null;
}
}
}
callback();
if (uniforms) {
textureByUniformName.forEach((texture, uniformName) => {
uniforms[uniformName].value = texture;
});
}
}
_withUnassignedBasePropertyTextures(material, callback) {
const textureByPropertyName = /* @__PURE__ */ new Map();
const propertyNames = Object.keys(material);
for (const propertyName of propertyNames) {
const value = material[propertyName];
if (value && value.uuid && value instanceof Texture) {
textureByPropertyName.set(propertyName, value);
material[propertyName] = null;
}
}
callback();
textureByPropertyName.forEach((texture, uniformName) => {
material[uniformName] = texture;
});
}
//
//
// LOAD MAT
//
//
_loadMaterial(data) {
data.color = void 0;
const loader = new MaterialLoader();
MonkeyPatchMaterial();
const material = loader.parse(data);
if (data.depthPacking) {
material.depthPacking = data.depthPacking;
}
if (data.lights != null) {
material.lights = data.lights;
}
const uniforms = material.uniforms;
if (uniforms) {
const uv2Transform = uniforms.uv2Transform;
if (uv2Transform) {
this.mat4ToMat3(uv2Transform);
}
const uvTransform = uniforms.uvTransform;
if (uvTransform) {
this.mat4ToMat3(uvTransform);
}
}
return material;
}
mat4ToMat3(uniform) {
const mat4 = uniform.value;
const last_element = mat4.elements[mat4.elements.length - 1];
if (last_element == null) {
const mat3 = new Matrix3();
for (let i = 0; i < mat3.elements.length; i++) {
mat3.elements[i] = mat4.elements[i];
}
uniform.value = mat3;
}
}
}