| "version": "0.0.43", | "version": "0.0.43", | ||||
| "license": "Apache-2.0", | "license": "Apache-2.0", | ||||
| "dependencies": { | "dependencies": { | ||||
| "@types/three": "https://github.com/repalash/three-ts-types/releases/download/v0.157.1006/package.tgz", | |||||
| "@types/three": "https://github.com/repalash/three-ts-types/releases/download/v0.158.1002/package.tgz", | |||||
| "@types/webxr": "^0.5.1", | "@types/webxr": "^0.5.1", | ||||
| "@types/wicg-file-system-access": "^2020.9.5", | "@types/wicg-file-system-access": "^2020.9.5", | ||||
| "popmotion": "^11.0.5", | "popmotion": "^11.0.5", | ||||
| "rimraf": "^5.0.1", | "rimraf": "^5.0.1", | ||||
| "rollup-plugin-glsl": "^1.3.0", | "rollup-plugin-glsl": "^1.3.0", | ||||
| "rollup-plugin-license": "^3.0.1", | "rollup-plugin-license": "^3.0.1", | ||||
| "three": "https://github.com/repalash/three.js-modded/releases/download/v0.157.1007/package.tgz", | |||||
| "three": "https://github.com/repalash/three.js-modded/releases/download/v0.158.1001/package.tgz", | |||||
| "tslib": "^2.5.0", | "tslib": "^2.5.0", | ||||
| "typedoc": "^0.28.4", | "typedoc": "^0.28.4", | ||||
| "typescript": "5.8.3", | "typescript": "5.8.3", | ||||
| "win-node-env": "^0.6.1" | "win-node-env": "^0.6.1" | ||||
| }, | }, | ||||
| "peerDependencies": { | "peerDependencies": { | ||||
| "three": "https://github.com/repalash/three.js-modded/releases/download/v0.157.1007/package.tgz" | |||||
| "three": "https://github.com/repalash/three.js-modded/releases/download/v0.158.1001/package.tgz" | |||||
| }, | }, | ||||
| "peerDependenciesMeta": { | "peerDependenciesMeta": { | ||||
| "three": { | "three": { | ||||
| "version": "0.17.3", | "version": "0.17.3", | ||||
| "resolved": "https://registry.npmjs.org/@types/stats.js/-/stats.js-0.17.3.tgz", | "resolved": "https://registry.npmjs.org/@types/stats.js/-/stats.js-0.17.3.tgz", | ||||
| "integrity": "sha512-pXNfAD3KHOdif9EQXZ9deK82HVNaXP5ZIF5RP2QG6OQFNTaY2YIetfrE9t528vEreGQvEPRDDc8muaoYeK0SxQ==", | "integrity": "sha512-pXNfAD3KHOdif9EQXZ9deK82HVNaXP5ZIF5RP2QG6OQFNTaY2YIetfrE9t528vEreGQvEPRDDc8muaoYeK0SxQ==", | ||||
| "dev": true, | |||||
| "license": "MIT" | "license": "MIT" | ||||
| }, | }, | ||||
| "node_modules/@types/three": { | "node_modules/@types/three": { | ||||
| "version": "0.157.1006", | |||||
| "resolved": "https://github.com/repalash/three-ts-types/releases/download/v0.157.1006/package.tgz", | |||||
| "integrity": "sha512-WiV0kRvPyPK3KEOGshnPDbgJzfa/YozkFSSfVu32WgFYp9hiSSVQK8wROq5We/DTWs8BmnyWuh7lzbz/4DC3jQ==", | |||||
| "version": "0.158.1002", | |||||
| "resolved": "https://github.com/repalash/three-ts-types/releases/download/v0.158.1002/package.tgz", | |||||
| "integrity": "sha512-oS0ZcdGgVafCcZRgLi3c6+dS/7lrw3BsIfDbDoWINeu5PylZy/VRljGpFj13K/bQ7KT1RfUhNlrKW7LBLgNYcQ==", | |||||
| "dependencies": { | "dependencies": { | ||||
| "@types/stats.js": "*", | |||||
| "@types/webxr": "*", | |||||
| "fflate": "~0.6.10", | "fflate": "~0.6.10", | ||||
| "meshoptimizer": "~0.18.1" | "meshoptimizer": "~0.18.1" | ||||
| } | } | ||||
| "license": "MIT" | "license": "MIT" | ||||
| }, | }, | ||||
| "node_modules/three": { | "node_modules/three": { | ||||
| "version": "0.157.1007", | |||||
| "resolved": "https://github.com/repalash/three.js-modded/releases/download/v0.157.1007/package.tgz", | |||||
| "integrity": "sha512-VjnxBF9JRjkFrqnHcrpa6VuOHSPyQzzLSYBUrPq0qJZmHhTVo4ns6MmZ8TA0v0kCu9pPNILDH9ZBY5d84v4UPA==", | |||||
| "version": "0.158.1001", | |||||
| "resolved": "https://github.com/repalash/three.js-modded/releases/download/v0.158.1001/package.tgz", | |||||
| "integrity": "sha512-yrzyMBxiKMIsr3gVD+K27L62soJHSDqAihpU+FokWGQGZ01+8jW1BdBb5zkC1Jwt6J7izY2/706t64uZu95wMw==", | |||||
| "dev": true, | "dev": true, | ||||
| "license": "MIT" | "license": "MIT" | ||||
| }, | }, |
| "rimraf": "^5.0.1", | "rimraf": "^5.0.1", | ||||
| "rollup-plugin-glsl": "^1.3.0", | "rollup-plugin-glsl": "^1.3.0", | ||||
| "rollup-plugin-license": "^3.0.1", | "rollup-plugin-license": "^3.0.1", | ||||
| "three": "https://github.com/repalash/three.js-modded/releases/download/v0.157.1007/package.tgz", | |||||
| "three": "https://github.com/repalash/three.js-modded/releases/download/v0.158.1001/package.tgz", | |||||
| "tslib": "^2.5.0", | "tslib": "^2.5.0", | ||||
| "typedoc": "^0.28.4", | "typedoc": "^0.28.4", | ||||
| "typescript": "5.8.3", | "typescript": "5.8.3", | ||||
| "vitepress-plugin-nprogress": "^0.0.4" | "vitepress-plugin-nprogress": "^0.0.4" | ||||
| }, | }, | ||||
| "dependencies": { | "dependencies": { | ||||
| "@types/three": "https://github.com/repalash/three-ts-types/releases/download/v0.157.1006/package.tgz", | |||||
| "@types/three": "https://github.com/repalash/three-ts-types/releases/download/v0.158.1002/package.tgz", | |||||
| "@types/webxr": "^0.5.1", | "@types/webxr": "^0.5.1", | ||||
| "@types/wicg-file-system-access": "^2020.9.5", | "@types/wicg-file-system-access": "^2020.9.5", | ||||
| "popmotion": "^11.0.5", | "popmotion": "^11.0.5", | ||||
| "uiconfig.js": "^0.1.3" | "uiconfig.js": "^0.1.3" | ||||
| }, | }, | ||||
| "peerDependencies": { | "peerDependencies": { | ||||
| "three": "https://github.com/repalash/three.js-modded/releases/download/v0.157.1007/package.tgz" | |||||
| "three": "https://github.com/repalash/three.js-modded/releases/download/v0.158.1001/package.tgz" | |||||
| }, | }, | ||||
| "peerDependenciesMeta": { | "peerDependenciesMeta": { | ||||
| "three": { | "three": { | ||||
| "dependencies": { | "dependencies": { | ||||
| "uiconfig.js": "^0.1.3", | "uiconfig.js": "^0.1.3", | ||||
| "ts-browser-helpers": "^0.16.2", | "ts-browser-helpers": "^0.16.2", | ||||
| "three": "https://github.com/repalash/three.js-modded/releases/download/v0.157.1007/package.tgz", | |||||
| "three-f": "https://github.com/repalash/three.js-modded/archive/refs/tags/v0.157.1007.tar.gz", | |||||
| "@types/three": "https://github.com/repalash/three-ts-types/releases/download/v0.157.1006/package.tgz", | |||||
| "@types/three-f": "https://github.com/repalash/three-ts-types/archive/refs/tags/v0.157.1006.tar.gz", | |||||
| "three": "https://github.com/repalash/three.js-modded/releases/download/v0.158.1001/package.tgz", | |||||
| "three-f": "https://github.com/repalash/three.js-modded/archive/refs/tags/v0.158.1002.tar.gz", | |||||
| "@types/three": "https://github.com/repalash/three-ts-types/releases/download/v0.158.1002/package.tgz", | |||||
| "@types/three-f": "https://github.com/repalash/three-ts-types/archive/refs/tags/v0.158.1002.tar.gz", | |||||
| "@types/three-pkg": "https://gitpkg.now.sh/repalash/three-ts-types/types/three?modded_three" | "@types/three-pkg": "https://gitpkg.now.sh/repalash/three-ts-types/types/three?modded_three" | ||||
| }, | }, | ||||
| "local_dependencies": { | "local_dependencies": { |
| const lastColorManagementEnabled = ColorManagement.enabled | const lastColorManagementEnabled = ColorManagement.enabled | ||||
| if (legacyColors) ColorManagement.enabled = false | if (legacyColors) ColorManagement.enabled = false | ||||
| // bump map scale fix | |||||
| // https://github.com/repalash/three.js/commit/7b13bb515866f6a002928bd28d0a793cafeaeb1a | |||||
| const legacyBumpScale = (oldMaterial as any)?.metadata && (oldMaterial as any)?.metadata.version <= 4.6 | |||||
| if (legacyBumpScale && (oldMaterial as any)?.bumpScale !== undefined && (oldMaterial as any)?.bumpMap) { | |||||
| // if (Math.abs((oldMaterial as any).bumpScale) > 0.01) { | |||||
| // (oldMaterial as any).bumpScale *= 430 // test model - http://asset-samples.threepipe.org/tests/bumpmap_normalize_migrate.glb | |||||
| // console.warn('MaterialManager: Old format material loaded, bump map scaled by 430, it might be incorrect.', (oldMaterial as any).bumpScale) | |||||
| // } else { | |||||
| console.warn('MaterialManager: Old format material loaded, bump map might be incorrect.', oldMaterial, (oldMaterial as any).bumpScale) | |||||
| // } | |||||
| } | |||||
| const material = template.generator(template.params || {}) | const material = template.generator(template.params || {}) | ||||
| if (oldMaterial && material) material.setValues(oldMaterial, true) | if (oldMaterial && material) material.setValues(oldMaterial, true) | ||||
| GLTFObject3DExtrasExtension, | GLTFObject3DExtrasExtension, | ||||
| GLTFViewerConfigExtension, | GLTFViewerConfigExtension, | ||||
| } from '../gltf' | } from '../gltf' | ||||
| import {GLTFMeshGpuInstancingExporter} from '../../three/utils/gpu-instancing' | |||||
| export interface GLTFExporter2Options { | export interface GLTFExporter2Options { | ||||
| /** | /** | ||||
| GLTFMaterialsDisplacementMapExtension.Export, | GLTFMaterialsDisplacementMapExtension.Export, | ||||
| GLTFMaterialsLightMapExtension.Export, | GLTFMaterialsLightMapExtension.Export, | ||||
| GLTFMaterialsAlphaMapExtension.Export, | GLTFMaterialsAlphaMapExtension.Export, | ||||
| (w)=>new GLTFMeshGpuInstancingExporter(w), | |||||
| // (w)=>new GLTFMeshGpuInstancingExporter(w), | |||||
| ] | ] | ||||
| setup(viewer: ThreeViewer, extraExtensions?: ((parser: GLTFWriter2) => GLTFExporterPlugin)[]): this { | setup(viewer: ThreeViewer, extraExtensions?: ((parser: GLTFWriter2) => GLTFExporterPlugin)[]): this { |
| export class GLTFWriter2 extends GLTFExporter.Utils.GLTFWriter { | export class GLTFWriter2 extends GLTFExporter.Utils.GLTFWriter { | ||||
| protected _assetVersion: number | |||||
| readonly TPAssetVersion = 1 | |||||
| constructor() { | |||||
| super() | |||||
| // slightly increment the version to be safe if three.js forgot to update the version | |||||
| this._assetVersion = parseFloat(this.json.asset.version) + 0.001 * this.TPAssetVersion | |||||
| this.json.asset.version = this._assetVersion.toString() | |||||
| } | |||||
| declare options: GLTFExporterOptions & { | declare options: GLTFExporterOptions & { | ||||
| externalImagesInExtras: boolean, | externalImagesInExtras: boolean, | ||||
| exporterOptions: GLTFExporter2Options | exporterOptions: GLTFExporter2Options |
| import type {GLTF, GLTFLoaderPlugin, GLTFParser} from 'three/examples/jsm/loaders/GLTFLoader' | import type {GLTF, GLTFLoaderPlugin, GLTFParser} from 'three/examples/jsm/loaders/GLTFLoader' | ||||
| import {ThreeSerialization} from '../../utils/serialization' | import {ThreeSerialization} from '../../utils/serialization' | ||||
| import {DoubleSide, Material} from 'three' | |||||
| import {Color, DoubleSide, Material} from 'three' | |||||
| import type {GLTFExporterPlugin, GLTFWriter} from 'three/examples/jsm/exporters/GLTFExporter' | import type {GLTFExporterPlugin, GLTFWriter} from 'three/examples/jsm/exporters/GLTFExporter' | ||||
| import {ITexture} from '../../core' | import {ITexture} from '../../core' | ||||
| if (ext.envMapIntensity !== undefined) o.envMapIntensity = ext.envMapIntensity // for when separateEnvMapIntensity is true | if (ext.envMapIntensity !== undefined) o.envMapIntensity = ext.envMapIntensity // for when separateEnvMapIntensity is true | ||||
| // if (ext.envMapSlotKey !== undefined) o.envMapSlotKey = ext.envMapSlotKey // in userdata | // if (ext.envMapSlotKey !== undefined) o.envMapSlotKey = ext.envMapSlotKey // in userdata | ||||
| if (ext.blendSrc !== undefined) o.blendSrc = ext.blendSrc | |||||
| if (ext.blendDst !== undefined) o.blendDst = ext.blendDst | |||||
| if (ext.blendEquation !== undefined) o.blendEquation = ext.blendEquation | |||||
| if (ext.blendSrcAlpha !== undefined) o.blendSrcAlpha = ext.blendSrcAlpha | |||||
| if (ext.blendDstAlpha !== undefined) o.blendDstAlpha = ext.blendDstAlpha | |||||
| if (ext.blendEquationAlpha !== undefined) o.blendEquationAlpha = ext.blendEquationAlpha | |||||
| if (ext.blendColor !== undefined && o.blendColor !== undefined) (o.blendColor as Color).setHex(ext.blendColor) | |||||
| if (ext.blendAlpha !== undefined) o.blendAlpha = ext.blendAlpha | |||||
| // if (ext.stencilWrite !== undefined) o.stencilWrite = ext.stencilWrite | // if (ext.stencilWrite !== undefined) o.stencilWrite = ext.stencilWrite | ||||
| // if (ext.stencilWriteMask !== undefined) o.stencilWriteMask = ext.stencilWriteMask | // if (ext.stencilWriteMask !== undefined) o.stencilWriteMask = ext.stencilWriteMask | ||||
| // if (ext.stencilFunc !== undefined) o.stencilFunc = ext.stencilFunc | // if (ext.stencilFunc !== undefined) o.stencilFunc = ext.stencilFunc | ||||
| if (material.envMapIntensity !== undefined) dat.envMapIntensity = material.envMapIntensity // for when separateEnvMapIntensity is true | if (material.envMapIntensity !== undefined) dat.envMapIntensity = material.envMapIntensity // for when separateEnvMapIntensity is true | ||||
| // if (material.envMapSlotKey !== undefined) dat.envMapSlotKey = material.envMapSlotKey // in userData | // if (material.envMapSlotKey !== undefined) dat.envMapSlotKey = material.envMapSlotKey // in userData | ||||
| if (material.blendSrc !== undefined) dat.blendSrc = material.blendSrc | |||||
| if (material.blendDst !== undefined) dat.blendDst = material.blendDst | |||||
| if (material.blendEquation !== undefined) dat.blendEquation = material.blendEquation | |||||
| if (material.blendSrcAlpha !== undefined) dat.blendSrcAlpha = material.blendSrcAlpha | |||||
| if (material.blendDstAlpha !== undefined) dat.blendDstAlpha = material.blendDstAlpha | |||||
| if (material.blendEquationAlpha !== undefined) dat.blendEquationAlpha = material.blendEquationAlpha | |||||
| if (material.blendColor !== undefined) dat.blendColor = (material.blendColor as Color).getHex() | |||||
| if (material.blendAlpha !== undefined) dat.blendAlpha = material.blendAlpha | |||||
| // if (material.stencilWrite !== undefined) dat.stencilWrite = material.stencilWrite | // if (material.stencilWrite !== undefined) dat.stencilWrite = material.stencilWrite | ||||
| // if (material.stencilWriteMask !== undefined) dat.stencilWriteMask = material.stencilWriteMask | // if (material.stencilWriteMask !== undefined) dat.stencilWriteMask = material.stencilWriteMask | ||||
| // if (material.stencilFunc !== undefined) dat.stencilFunc = material.stencilFunc | // if (material.stencilFunc !== undefined) dat.stencilFunc = material.stencilFunc |
| if (res.userData) scene.userData.gltfExtras = res.userData // todo: put back in gltf in GLTFExporter2 | if (res.userData) scene.userData.gltfExtras = res.userData // todo: put back in gltf in GLTFExporter2 | ||||
| if (res.cameras) res.cameras.forEach(c => !c.parent && scene.add(c)) | if (res.cameras) res.cameras.forEach(c => !c.parent && scene.add(c)) | ||||
| if (res.asset) scene.userData.gltfAsset = res.asset // todo: put back in gltf in GLTFExporter2 | if (res.asset) scene.userData.gltfAsset = res.asset // todo: put back in gltf in GLTFExporter2 | ||||
| // todo | |||||
| if (res.asset?.version) { | |||||
| const version = parseFloat(res.asset.version) | |||||
| if (version <= 2.0) { | |||||
| // bump map scale fix | |||||
| // https://github.com/repalash/three.js/commit/7b13bb515866f6a002928bd28d0a793cafeaeb1a | |||||
| // const bounds = new Box3B().expandByObject(scene) | |||||
| // const size = bounds.getSize(new Vector3()).length() / 2 | |||||
| const fixBump = (material: any) => { | |||||
| if (!material || !material.bumpMap || material.bumpScale === undefined) return | |||||
| // if (Math.abs(material.bumpScale) > 0.01) { | |||||
| // material.bumpScale *= 430 / Math.max(size, 0.1) // test model - http://asset-samples.threepipe.org/tests/bumpmap_normalize_migrate.glb | |||||
| // console.warn(`GLTFLoader2: Old format material loaded, bump map scaled by ${430 / Math.max(size, 0.1)}, it might be incorrect.`, material, material.bumpScale) | |||||
| // } else { | |||||
| console.warn('GLTFLoader2: Old format material loaded, bump map might be incorrect.', material, material.bumpScale) | |||||
| // } | |||||
| } | |||||
| scene?.traverse((obj: any)=>{ | |||||
| if (!obj?.material) return | |||||
| const mats = Array.isArray(obj.material) ? obj.material : [obj.material] | |||||
| mats.forEach(fixBump) | |||||
| }) | |||||
| } | |||||
| } | |||||
| return scene | return scene | ||||
| } | } | ||||
| AdditiveBlending, | AdditiveBlending, | ||||
| AlwaysDepth, | AlwaysDepth, | ||||
| BackSide, | BackSide, | ||||
| Blending, | |||||
| Blending, CustomBlending, | |||||
| DepthModes, | DepthModes, | ||||
| DoubleSide, | DoubleSide, | ||||
| EqualDepth, | EqualDepth, | ||||
| NormalMapTypes, | NormalMapTypes, | ||||
| NotEqualDepth, | NotEqualDepth, | ||||
| ObjectSpaceNormalMap, | ObjectSpaceNormalMap, | ||||
| OneFactor, | |||||
| OneMinusDstAlphaFactor, | |||||
| OneMinusDstColorFactor, | |||||
| OneMinusSrcAlphaFactor, | |||||
| OneMinusSrcColorFactor, | |||||
| Side, | Side, | ||||
| SrcAlphaFactor, | |||||
| SrcAlphaSaturateFactor, | |||||
| SrcColorFactor, | |||||
| SubtractiveBlending, | SubtractiveBlending, | ||||
| TangentSpaceNormalMap, | TangentSpaceNormalMap, | ||||
| ZeroFactor, | |||||
| BlendingEquation, | |||||
| BlendingSrcFactor, | |||||
| MinEquation, | |||||
| ConstantAlphaFactor, ConstantColorFactor, OneMinusConstantAlphaFactor, OneMinusConstantColorFactor, | |||||
| ReverseSubtractEquation, | |||||
| SubtractEquation, AddEquation, MaxEquation, DstAlphaFactor, DstColorFactor, | |||||
| } from 'three' | } from 'three' | ||||
| import {downloadBlob, uploadFile} from 'ts-browser-helpers' | import {downloadBlob, uploadFile} from 'ts-browser-helpers' | ||||
| import {PhysicalMaterial} from './PhysicalMaterial' | import {PhysicalMaterial} from './PhysicalMaterial' | ||||
| ['Additive', AdditiveBlending], | ['Additive', AdditiveBlending], | ||||
| ['Subtractive', SubtractiveBlending], | ['Subtractive', SubtractiveBlending], | ||||
| ['Multiply', MultiplyBlending], | ['Multiply', MultiplyBlending], | ||||
| ['Custom', CustomBlending], | |||||
| ] as [string, Blending][]).map(value => ({ | ] as [string, Blending][]).map(value => ({ | ||||
| label: value[0], | label: value[0], | ||||
| value: value[1], | value: value[1], | ||||
| })), | })), | ||||
| }, | }, | ||||
| { | |||||
| type: 'dropdown', | |||||
| hidden: ()=>material.blending !== CustomBlending, | |||||
| property: [material, 'blendingEquation'], | |||||
| children: ([ | |||||
| ['Add', AddEquation], | |||||
| ['Subtract', SubtractEquation], | |||||
| ['Reverse Subtract', ReverseSubtractEquation], | |||||
| ['Min', MinEquation], | |||||
| ['Max', MaxEquation], | |||||
| ] as [string, BlendingEquation][]).map(value => ({ | |||||
| label: value[0], | |||||
| value: value[1], | |||||
| })), | |||||
| }, | |||||
| { | |||||
| type: 'dropdown', | |||||
| property: [material, 'blendSrc'], | |||||
| hidden: ()=>material.blending !== CustomBlending, | |||||
| children: ([ | |||||
| ['Zero', ZeroFactor], | |||||
| ['One', OneFactor], | |||||
| ['Src Color', SrcColorFactor], | |||||
| ['One Minus Src Color', OneMinusSrcColorFactor], | |||||
| ['Src Alpha', SrcAlphaFactor], | |||||
| ['One Minus Src Alpha', OneMinusSrcAlphaFactor], | |||||
| ['Dst Alpha', DstAlphaFactor], | |||||
| ['One Minus Dst Alpha', OneMinusDstAlphaFactor], | |||||
| ['Dst Color', DstColorFactor], | |||||
| ['One Minus Dst Color', OneMinusDstColorFactor], | |||||
| ['Src Alpha Saturate', SrcAlphaSaturateFactor], | |||||
| ['Constant Color', ConstantColorFactor], | |||||
| ['One Minus Constant Color', OneMinusConstantColorFactor], | |||||
| ['Constant Alpha', ConstantAlphaFactor], | |||||
| ['One Minus Constant Alpha', OneMinusConstantAlphaFactor], | |||||
| ] as [string, BlendingSrcFactor][]).map(value => ({ | |||||
| label: value[0], | |||||
| value: value[1], | |||||
| })), | |||||
| }, | |||||
| { | |||||
| type: 'dropdown', | |||||
| property: [material, 'blendDst'], | |||||
| hidden: ()=>material.blending !== CustomBlending, | |||||
| children: ([ | |||||
| ['Zero', ZeroFactor], | |||||
| ['One', OneFactor], | |||||
| ['Src Color', SrcColorFactor], | |||||
| ['One Minus Src Color', OneMinusSrcColorFactor], | |||||
| ['Src Alpha', SrcAlphaFactor], | |||||
| ['One Minus Src Alpha', OneMinusSrcAlphaFactor], | |||||
| ['Dst Alpha', DstAlphaFactor], | |||||
| ['One Minus Dst Alpha', OneMinusDstAlphaFactor], | |||||
| ['Dst Color', DstColorFactor], | |||||
| ['One Minus Dst Color', OneMinusDstColorFactor], | |||||
| // ['Src Alpha Saturate', SrcAlphaSaturateFactor], | |||||
| ['Constant Color', ConstantColorFactor], | |||||
| ['One Minus Constant Color', OneMinusConstantColorFactor], | |||||
| ['Constant Alpha', ConstantAlphaFactor], | |||||
| ['One Minus Constant Alpha', OneMinusConstantAlphaFactor], | |||||
| ] as [string, BlendingSrcFactor][]).map(value => ({ | |||||
| label: value[0], | |||||
| value: value[1], | |||||
| })), | |||||
| }, | |||||
| { | |||||
| type: 'slider', | |||||
| bounds: [0, 1], | |||||
| hidden: ()=>material.blending !== CustomBlending, | |||||
| property: [material, 'blendSrcAlpha'], | |||||
| }, | |||||
| { | |||||
| type: 'slider', | |||||
| bounds: [0, 1], | |||||
| hidden: ()=>material.blending !== CustomBlending, | |||||
| property: [material, 'blendDstAlpha'], | |||||
| }, | |||||
| { | |||||
| type: 'color', | |||||
| hidden: ()=>material.blending !== CustomBlending || | |||||
| material.blendSrc !== ConstantColorFactor && | |||||
| material.blendSrc !== OneMinusConstantColorFactor && | |||||
| material.blendDst !== ConstantColorFactor && | |||||
| material.blendDst !== OneMinusConstantColorFactor, | |||||
| property: [material, 'blendColor'], | |||||
| }, | |||||
| { | |||||
| type: 'slider', | |||||
| hidden: ()=>material.blending !== CustomBlending || | |||||
| material.blendSrc !== ConstantAlphaFactor && | |||||
| material.blendSrc !== OneMinusConstantAlphaFactor && | |||||
| material.blendDst !== ConstantAlphaFactor && | |||||
| material.blendDst !== OneMinusConstantAlphaFactor, | |||||
| bounds: [0, 1], | |||||
| property: [material, 'blendAlpha'], | |||||
| }, | |||||
| material.alphaMap !== undefined ? { | material.alphaMap !== undefined ? { | ||||
| type: 'image', | type: 'image', | ||||
| property: [material, 'alphaMap'], | property: [material, 'alphaMap'], | ||||
| { | { | ||||
| type: 'checkbox', | type: 'checkbox', | ||||
| label: 'Override Environment', | label: 'Override Environment', | ||||
| // property: [this.userData, 'separateEnvMapIntensity'], | |||||
| // property: [material.userData, 'separateEnvMapIntensity'], | |||||
| getValue: ()=>material.userData.separateEnvMapIntensity === true, | getValue: ()=>material.userData.separateEnvMapIntensity === true, | ||||
| setValue: (v: boolean)=>{ | setValue: (v: boolean)=>{ | ||||
| material.userData.separateEnvMapIntensity = v | material.userData.separateEnvMapIntensity = v | ||||
| children: [ | children: [ | ||||
| { | { | ||||
| type: 'slider', | type: 'slider', | ||||
| bounds: [-1, 1], | |||||
| bounds: [-500, 500], | |||||
| stepSize: 0.001, | stepSize: 0.001, | ||||
| property: [material, 'bumpScale'], | property: [material, 'bumpScale'], | ||||
| hidden: ()=>!material.bumpMap, | hidden: ()=>!material.bumpMap, |
| specularColor: new Color(1, 1, 1), | specularColor: new Color(1, 1, 1), | ||||
| specularColorMap: null, | specularColorMap: null, | ||||
| anisotropy: 0, | |||||
| anisotropyRotation: 0, | |||||
| anisotropyMap: null, | |||||
| } | } | ||||
| static MaterialTemplate: IMaterialTemplate<PhysicalMaterial, Partial<typeof PhysicalMaterial.MaterialProperties>> = { | static MaterialTemplate: IMaterialTemplate<PhysicalMaterial, Partial<typeof PhysicalMaterial.MaterialProperties>> = { |
| blendSrcAlpha: null, | blendSrcAlpha: null, | ||||
| blendDstAlpha: null, | blendDstAlpha: null, | ||||
| blendEquationAlpha: null, | blendEquationAlpha: null, | ||||
| blendColor: '#000000', | |||||
| blendAlpha: 0, | |||||
| depthFunc: LessEqualDepth, | depthFunc: LessEqualDepth, | ||||
| depthTest: true, | depthTest: true, | ||||
| depthWrite: true, | depthWrite: true, |
| #ifndef USE_BUMPMAP | #ifndef USE_BUMPMAP | ||||
| vec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy, float faceDirection ) { | vec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy, float faceDirection ) { | ||||
| vec3 vSigmaX = dFdx( surf_pos.xyz ); | |||||
| vec3 vSigmaY = dFdy( surf_pos.xyz ); | |||||
| // normalize is done to ensure that the bump map looks the same regardless of the texture's scale | |||||
| vec3 vSigmaX = normalize( dFdx( surf_pos.xyz ) ); | |||||
| vec3 vSigmaY = normalize( dFdy( surf_pos.xyz ) ); | |||||
| vec3 vN = surf_norm; // normalized | vec3 vN = surf_norm; // normalized | ||||
| vec3 R1 = cross( vSigmaY, vN ); | vec3 R1 = cross( vSigmaY, vN ); |
| vec3 perturbNormalArb_nb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy, float faceDirection ) { | vec3 perturbNormalArb_nb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy, float faceDirection ) { | ||||
| vec3 vSigmaX = dFdx( surf_pos.xyz ); | |||||
| vec3 vSigmaY = dFdy( surf_pos.xyz ); | |||||
| // normalize is done to ensure that the bump map looks the same regardless of the texture's scale | |||||
| vec3 vSigmaX = normalize( dFdx( surf_pos.xyz ) ); | |||||
| vec3 vSigmaY = normalize( dFdy( surf_pos.xyz ) ); | |||||
| vec3 vN = surf_norm; // normalized | vec3 vN = surf_norm; // normalized | ||||
| vec3 R1 = cross( vSigmaY, vN ); | vec3 R1 = cross( vSigmaY, vN ); |
| import {IGeometry, IMaterial, IObject3D} from '../../core' | import {IGeometry, IMaterial, IObject3D} from '../../core' | ||||
| import {BufferAttribute, InstancedMesh, Matrix4, Quaternion, Vector3} from 'three' | |||||
| import {BufferAttribute, InstancedMesh} from 'three' | |||||
| // noinspection ES6PreferShortImport | // noinspection ES6PreferShortImport | ||||
| import {copyObject3DUserData} from '../../utils/serialization' | import {copyObject3DUserData} from '../../utils/serialization' | ||||
| import {GLTFWriter2} from '../../assetmanager' | |||||
| import {GLTFExporterPlugin} from 'three/examples/jsm/exporters/GLTFExporter' | |||||
| export function autoGPUInstanceMeshes(matOrGeom: IMaterial|IGeometry) { | export function autoGPUInstanceMeshes(matOrGeom: IMaterial|IGeometry) { | ||||
| if (!(<IMaterial>matOrGeom).isMaterial && !(<IGeometry>matOrGeom).isBufferGeometry) return | if (!(<IMaterial>matOrGeom).isMaterial && !(<IGeometry>matOrGeom).isBufferGeometry) return | ||||
| } | } | ||||
| } | } | ||||
| export class GLTFMeshGpuInstancingExporter implements GLTFExporterPlugin { | |||||
| name = 'EXT_mesh_gpu_instancing' | |||||
| constructor(public writer: GLTFWriter2) { | |||||
| } | |||||
| writeNode(object: any, nodeDef: any): void { | |||||
| if (!object.isInstancedMesh) return | |||||
| const writer = this.writer | |||||
| const mesh = object as InstancedMesh | |||||
| // @ts-expect-error not in ts | |||||
| let attributes: any = mesh.sourceTrs | |||||
| if (!attributes) { | |||||
| const translationAttr = new Float32Array(mesh.count * 3) | |||||
| const rotationAttr = new Float32Array(mesh.count * 4) | |||||
| const scaleAttr = new Float32Array(mesh.count * 3) | |||||
| const matrix = new Matrix4() | |||||
| const position = new Vector3() | |||||
| const quaternion = new Quaternion() | |||||
| const scale = new Vector3() | |||||
| for (let i = 0; i < mesh.count; i++) { | |||||
| mesh.getMatrixAt(i, matrix) | |||||
| matrix.decompose(position, quaternion, scale) | |||||
| position.toArray(translationAttr, i * 3) | |||||
| quaternion.toArray(rotationAttr, i * 4) | |||||
| scale.toArray(scaleAttr, i * 3) | |||||
| } | |||||
| attributes = { | |||||
| TRANSLATION: new BufferAttribute(translationAttr, 3), | |||||
| ROTATION: new BufferAttribute(rotationAttr, 4), | |||||
| SCALE: new BufferAttribute(scaleAttr, 3), | |||||
| } | |||||
| } | |||||
| attributes = { | |||||
| // @ts-expect-error todo add to ts | |||||
| TRANSLATION: writer.processAccessor(attributes.TRANSLATION), | |||||
| ROTATION: (writer as any).processAccessor(attributes.ROTATION), | |||||
| SCALE: (writer as any).processAccessor(attributes.SCALE), | |||||
| } | |||||
| if (mesh.instanceColor) | |||||
| attributes._COLOR_0 = (writer as any).processAccessor(mesh.instanceColor) | |||||
| writer.extensionsUsed[ this.name ] = true | |||||
| // @ts-expect-error todo add to ts | |||||
| writer.extensionsRequired[ this.name ] = true | |||||
| nodeDef.extensions = nodeDef.extensions || {} | |||||
| nodeDef.extensions[ this.name ] = {attributes} | |||||
| } | |||||
| } | |||||
| // added to three.js | |||||
| // export class GLTFMeshGpuInstancingExporter implements GLTFExporterPlugin { | |||||
| // name = 'EXT_mesh_gpu_instancing' | |||||
| // constructor(public writer: GLTFWriter2) { | |||||
| // } | |||||
| // | |||||
| // writeNode(object: any, nodeDef: any): void { | |||||
| // if (!object.isInstancedMesh) return | |||||
| // | |||||
| // const writer = this.writer | |||||
| // | |||||
| // const mesh = object as InstancedMesh | |||||
| // | |||||
| // // @ts-expect-error not in ts | |||||
| // let attributes: any = mesh.sourceTrs | |||||
| // if (!attributes) { | |||||
| // const translationAttr = new Float32Array(mesh.count * 3) | |||||
| // const rotationAttr = new Float32Array(mesh.count * 4) | |||||
| // const scaleAttr = new Float32Array(mesh.count * 3) | |||||
| // | |||||
| // const matrix = new Matrix4() | |||||
| // const position = new Vector3() | |||||
| // const quaternion = new Quaternion() | |||||
| // const scale = new Vector3() | |||||
| // | |||||
| // for (let i = 0; i < mesh.count; i++) { | |||||
| // mesh.getMatrixAt(i, matrix) | |||||
| // matrix.decompose(position, quaternion, scale) | |||||
| // | |||||
| // position.toArray(translationAttr, i * 3) | |||||
| // quaternion.toArray(rotationAttr, i * 4) | |||||
| // scale.toArray(scaleAttr, i * 3) | |||||
| // } | |||||
| // attributes = { | |||||
| // TRANSLATION: new BufferAttribute(translationAttr, 3), | |||||
| // ROTATION: new BufferAttribute(rotationAttr, 4), | |||||
| // SCALE: new BufferAttribute(scaleAttr, 3), | |||||
| // } | |||||
| // } | |||||
| // | |||||
| // attributes = { | |||||
| // // @ts-expect-error todo add to ts | |||||
| // TRANSLATION: writer.processAccessor(attributes.TRANSLATION), | |||||
| // ROTATION: (writer as any).processAccessor(attributes.ROTATION), | |||||
| // SCALE: (writer as any).processAccessor(attributes.SCALE), | |||||
| // } | |||||
| // | |||||
| // if (mesh.instanceColor) | |||||
| // attributes._COLOR_0 = (writer as any).processAccessor(mesh.instanceColor) | |||||
| // | |||||
| // writer.extensionsUsed[ this.name ] = true | |||||
| // // @ts-expect-error todo add to ts | |||||
| // writer.extensionsRequired[ this.name ] = true | |||||
| // | |||||
| // nodeDef.extensions = nodeDef.extensions || {} | |||||
| // nodeDef.extensions[ this.name ] = {attributes} | |||||
| // } | |||||
| // } |