Procházet zdrojové kódy

Fix for loaderCreate in AssetImporter, add regex support in MaterialManager.findMaterialsByName, add autoGPUInstanceMeshes util, add Auto GPU Instances and Center Geometry to Geometry UI, three ref update, minor fixes.

master
Palash Bansal před 2 roky
rodič
revize
ee46c311dd
Žádný účet není propojen s e-mailovou adresou tvůrce revize

+ 12
- 12
package-lock.json Zobrazit soubor

@@ -9,7 +9,7 @@
"version": "0.0.13",
"license": "Apache-2.0",
"dependencies": {
"@types/three": "https://github.com/repalash/three-ts-types/releases/download/v0.152.1014/package.tgz",
"@types/three": "https://github.com/repalash/three-ts-types/releases/download/v0.152.1016/package.tgz",
"@types/webxr": "^0.5.1",
"@types/wicg-file-system-access": "^2020.9.5",
"ts-browser-helpers": "^0.8.0"
@@ -39,7 +39,7 @@
"rollup-plugin-license": "^3.0.1",
"rollup-plugin-postcss": "^4.0.2",
"stats.js": "^0.17.0",
"three": "https://github.com/repalash/three.js-modded/releases/download/v0.152.2012/package.tgz",
"three": "https://github.com/repalash/three.js-modded/releases/download/v0.152.2015/package.tgz",
"tslib": "^2.5.0",
"typedoc": "^0.24.7",
"typescript": "^5.0.4",
@@ -684,9 +684,9 @@
"dev": true
},
"node_modules/@types/three": {
"version": "0.152.1014",
"resolved": "https://github.com/repalash/three-ts-types/releases/download/v0.152.1014/package.tgz",
"integrity": "sha512-1sR9iALwIFtfSXxJshAglvMjLy5litWF2hTbh0JQ+44d+21D2t0nppRZBnWtNQP5XsBYdhCNygnDQNeF6kd+NQ==",
"version": "0.152.1016",
"resolved": "https://github.com/repalash/three-ts-types/releases/download/v0.152.1016/package.tgz",
"integrity": "sha512-S4AczoUaWTfyh7ApgEXZWhhusqF9DGX8ynfIa8OzS0+ES0DmD1UQuyVQUmwOTxgTDGO10vc7zWrObZGPvM88NQ==",
"dependencies": {
"@tweenjs/tween.js": "~18.6.4",
"fflate": "~0.6.9",
@@ -9533,9 +9533,9 @@
}
},
"node_modules/three": {
"version": "0.152.2011",
"resolved": "https://github.com/repalash/three.js-modded/releases/download/v0.152.2012/package.tgz",
"integrity": "sha512-f2WKlSeuz9uvpfHNngEJMrQtKbyuE2iHjvpBaF1Wl8LcoMT3WUs7nmJzbEeheEr+J8BYnyRLNMDzR2xU0l1+Yw==",
"version": "0.152.2015",
"resolved": "https://github.com/repalash/three.js-modded/releases/download/v0.152.2015/package.tgz",
"integrity": "sha512-qON7KCzBCV2cWH4uOg6rfSJw5otIRk3JK7i8VtRq9K0KWaD/c3aW2Uz/WRqOJDxW/ENNrKhb171nqlToJIkgcg==",
"dev": true,
"license": "MIT"
},
@@ -10874,8 +10874,8 @@
"dev": true
},
"@types/three": {
"version": "https://github.com/repalash/three-ts-types/releases/download/v0.152.1014/package.tgz",
"integrity": "sha512-1sR9iALwIFtfSXxJshAglvMjLy5litWF2hTbh0JQ+44d+21D2t0nppRZBnWtNQP5XsBYdhCNygnDQNeF6kd+NQ==",
"version": "https://github.com/repalash/three-ts-types/releases/download/v0.152.1016/package.tgz",
"integrity": "sha512-S4AczoUaWTfyh7ApgEXZWhhusqF9DGX8ynfIa8OzS0+ES0DmD1UQuyVQUmwOTxgTDGO10vc7zWrObZGPvM88NQ==",
"requires": {
"@tweenjs/tween.js": "~18.6.4",
"fflate": "~0.6.9",
@@ -17285,8 +17285,8 @@
}
},
"three": {
"version": "https://github.com/repalash/three.js-modded/releases/download/v0.152.2012/package.tgz",
"integrity": "sha512-f2WKlSeuz9uvpfHNngEJMrQtKbyuE2iHjvpBaF1Wl8LcoMT3WUs7nmJzbEeheEr+J8BYnyRLNMDzR2xU0l1+Yw==",
"version": "https://github.com/repalash/three.js-modded/releases/download/v0.152.2015/package.tgz",
"integrity": "sha512-qON7KCzBCV2cWH4uOg6rfSJw5otIRk3JK7i8VtRq9K0KWaD/c3aW2Uz/WRqOJDxW/ENNrKhb171nqlToJIkgcg==",
"dev": true
},
"through": {

+ 6
- 6
package.json Zobrazit soubor

@@ -92,7 +92,7 @@
"rollup-plugin-glsl": "^1.3.0",
"rollup-plugin-postcss": "^4.0.2",
"stats.js": "^0.17.0",
"three": "https://github.com/repalash/three.js-modded/releases/download/v0.152.2012/package.tgz",
"three": "https://github.com/repalash/three.js-modded/releases/download/v0.152.2015/package.tgz",
"tslib": "^2.5.0",
"typedoc": "^0.24.7",
"typescript": "^5.0.4",
@@ -102,7 +102,7 @@
"popmotion": "^11.0.5"
},
"dependencies": {
"@types/three": "https://github.com/repalash/three-ts-types/releases/download/v0.152.1014/package.tgz",
"@types/three": "https://github.com/repalash/three-ts-types/releases/download/v0.152.1016/package.tgz",
"@types/webxr": "^0.5.1",
"@types/wicg-file-system-access": "^2020.9.5",
"ts-browser-helpers": "^0.8.0"
@@ -111,10 +111,10 @@
"dependencies": {
"uiconfig.js": "^0.0.6",
"ts-browser-helpers": "^0.8.0",
"three": "https://github.com/repalash/three.js-modded/releases/download/v0.152.2012/package.tgz",
"three-f": "https://github.com/repalash/three.js-modded/archive/refs/tags/v0.152.2012.tar.gz",
"@types/three": "https://github.com/repalash/three-ts-types/releases/download/v0.152.1014/package.tgz",
"@types/three-f": "https://github.com/repalash/three-ts-types/archive/refs/tags/v0.152.1014.tar.gz",
"three": "https://github.com/repalash/three.js-modded/releases/download/v0.152.2015/package.tgz",
"three-f": "https://github.com/repalash/three.js-modded/archive/refs/tags/v0.152.2015.tar.gz",
"@types/three": "https://github.com/repalash/three-ts-types/releases/download/v0.152.1016/package.tgz",
"@types/three-f": "https://github.com/repalash/three-ts-types/archive/refs/tags/v0.152.1016.tar.gz",
"@types/three-pkg": "https://gitpkg.now.sh/repalash/three-ts-types/types/three?modded_three"
},
"local_dependencies": {

+ 10
- 1
src/assetmanager/AssetImporter.ts Zobrazit soubor

@@ -1,4 +1,4 @@
import {Event, EventDispatcher, FileLoader, LoaderUtils, LoadingManager} from 'three'
import {Event, EventDispatcher, EventListener, FileLoader, LoaderUtils, LoadingManager} from 'three'
import {
IAssetImporter,
IAssetImporterEventTypes,
@@ -543,6 +543,15 @@ export class AssetImporter extends EventDispatcher<IAssetImporterEvent, IAssetIm
return loader
}

addEventListener<T extends IAssetImporterEvent['type'] & IAssetImporterEventTypes>(type: T, listener: EventListener<IAssetImporterEvent, T, this>) {
super.addEventListener(type, listener)
if (type === 'loaderCreate') {
for (const loaderCacheElement of this._loaderCache) {
this.dispatchEvent({type: 'loaderCreate', loader: loaderCacheElement.loader})
}
}
}

// endregion

// region Loader Event Dispatchers

+ 2
- 2
src/assetmanager/MaterialManager.ts Zobrazit soubor

@@ -213,8 +213,8 @@ export class MaterialManager<T = ''> extends EventDispatcher<BaseEvent, T> {
return !uuid ? undefined : this._materials.find(v=>v.uuid === uuid)
}

public findMaterialsByName(name: string): IMaterial[] {
return this._materials.filter(v=>v.name === name)
public findMaterialsByName(name: string|RegExp, regex = false): IMaterial[] {
return this._materials.filter(v=>typeof name !== 'string' || regex ? v.name.match(name) !== null : v.name === name)
}

public getMaterialsOfType<TM extends IMaterial = IMaterial>(typeSlug: string | undefined): TM[] {

+ 1
- 1
src/core/IObject.ts Zobrazit soubor

@@ -227,7 +227,7 @@ export interface IObject3D<E extends Event = IObject3DEvent, ET = IObject3DEvent
getObjectByProperty<T extends IObject3D = IObject3D>(name: string, value: string): T | undefined
copy(source: this, recursive?: boolean, ...args: any[]): this
clone(recursive?: boolean): this
add(...object: IObject3D[]): this
add(...object: Object3D[]): this
remove(...object: IObject3D[]): this
parent: IObject3D | null
children: IObject3D[]

+ 24
- 2
src/core/geometry/iGeometryCommons.ts Zobrazit soubor

@@ -1,7 +1,7 @@
import {UiObjectConfig} from 'uiconfig.js'
import {IGeometry, IGeometrySetDirtyOptions} from '../IGeometry'
import {isInScene, toIndexedGeometry} from '../../three'
import {BufferGeometry} from 'three'
import {autoGPUInstanceMeshes, isInScene, toIndexedGeometry} from '../../three'
import {BufferGeometry, Vector3} from 'three'

export const iGeometryCommons = {
setDirty: function(this: IGeometry, options?: IGeometrySetDirtyOptions): void {
@@ -40,6 +40,19 @@ export const iGeometryCommons = {
this.setDirty()
},
},
{
type: 'button',
label: 'Center Geometry (keep position)',
value: () => {
const offset = new Vector3()
this.center(offset)
const meshes = this.appliedMeshes
meshes.forEach(m=>{
m.position.sub(offset)
m.setDirty && m.setDirty()
})
},
},
{
type: 'button',
label: 'Compute vertex normals',
@@ -112,6 +125,15 @@ export const iGeometryCommons = {
this.setDirty()
},
},
{
type: 'button',
label: 'Auto GPU Instances',
hidden: ()=> !this.appliedMeshes || this.appliedMeshes.size < 2,
value: ()=>{
if (!confirm('This action is irreversible, do you want to continue?')) return
autoGPUInstanceMeshes(this)
},
},
{
type: 'input',
label: 'Mesh count',

+ 1
- 0
src/core/material/IMaterialUi.ts Zobrazit soubor

@@ -106,6 +106,7 @@ export const iMaterialUI = {
{
type: 'slider',
bounds: [0, 1],
stepSize: 0.001,
property: [material, 'alphaTest'],
},
{

+ 1
- 1
src/core/material/PhysicalMaterial.ts Zobrazit soubor

@@ -171,7 +171,7 @@ export class PhysicalMaterial extends MeshPhysicalMaterial<IMaterialEvent, Physi

if (!isFinite(this.attenuationDistance)) this.attenuationDistance = 0 // hack for ui

this.userData.uuid = this.uuid // just in case
this.userData.uuid = this.uuid
return this
}


+ 2
- 1
src/core/material/UnlitMaterial.ts Zobrazit soubor

@@ -118,7 +118,8 @@ export class UnlitMaterial extends MeshBasicMaterial<IMaterialEvent, UnlitMateri
if (clearCurrentUserData === undefined) clearCurrentUserData = (<Material>parameters).isMaterial
if (clearCurrentUserData) this.userData = {}
iMaterialCommons.setValues(super.setValues).call(this, parameters)
this.userData.uuid = this.uuid // just in case

this.userData.uuid = this.uuid
return this
}
copy(source: Material|any): this {

+ 85
- 0
src/three/utils/gpu-instancing.ts Zobrazit soubor

@@ -0,0 +1,85 @@
import {IGeometry, IMaterial, IObject3D} from '../../core'
import {BufferAttribute, InstancedMesh} from 'three'
import {copyObject3DUserData} from '../../utils'

export function autoGPUInstanceMeshes(matOrGeom: IMaterial|IGeometry) {
if (!(<IMaterial>matOrGeom).isMaterial && !(<IGeometry>matOrGeom).isBufferGeometry) return
const meshes = Array.from(matOrGeom.appliedMeshes).filter((m: any) =>
!m.isInstancedMesh &&
!!m.parent &&
m.children.length === 0 &&
!Array.isArray(m.material)
)
if (meshes.length < 2) return
const getKey = (m: IObject3D) => {
return m.parent!.uuid + '_' + m.geometry?.uuid + '_' + (m.material as IMaterial)?.uuid // + '_' + (m.matrix.determinant()<0)
}
const keyMeshMap = new Map<string, IObject3D[]>()
for (const mesh1 of meshes) {
const key = getKey(mesh1)
if (!keyMeshMap.has(key)) keyMeshMap.set(key, [])
keyMeshMap.get(key)!.push(mesh1)
mesh1.updateMatrix()
}
const keys = keyMeshMap.keys()
for (const key of keys) {
const iMeshes = keyMeshMap.get(key)!
const baseMesh = iMeshes[0]
if (!baseMesh) continue
if (iMeshes.length < 2) continue
const inst = new InstancedMesh(baseMesh.geometry, baseMesh.material, iMeshes.length)
const ud = baseMesh.userData
baseMesh.userData = {}
inst.copy(baseMesh)
copyObject3DUserData(inst.userData, ud)
const parent = baseMesh.parent!
inst.position.set(0, 0, 0)
inst.rotation.set(0, 0, 0)
inst.scale.set(1, 1, 1)
inst.updateMatrix()

const translationAttr = new Float32Array(inst.count * 3)
const rotationAttr = new Float32Array(inst.count * 4)
const scaleAttr = new Float32Array(inst.count * 3)

// const pos = new Vector3()
// const quat = new Quaternion()
// const scale = new Vector3()

for (let i = 0; i < iMeshes.length; i++) {
const m = iMeshes[i]
// const mat = inst.matrix.clone().invert().multiply(m.matrix)
const mat = m.matrix
// mat.decompose(pos, quat, scale)
if (mat.determinant() < 0) {
mat.elements[0] *= -1
mat.elements[1] *= -1
mat.elements[2] *= -1
}
inst.setMatrixAt(i, mat)
m.position.toArray(translationAttr, i * 3)
m.quaternion.toArray(rotationAttr, i * 4)
m.scale.toArray(scaleAttr, i * 3)
m.removeFromParent()
// ;(m.material as any)?.appliedMeshes?.delete(m)
// m.geometry?.appliedMeshes?.delete(m)
m.material = undefined
m.geometry = undefined
}
// (inst.material as IMaterial).appliedMeshes?.add(inst)
// inst.geometry.userData.__appliedMeshes.add(inst)

// todo set position to center of all instances

// @ts-expect-error todo not in ts
inst.sourceTrs = {
TRANSLATION: new BufferAttribute(translationAttr, 3),
ROTATION: new BufferAttribute(rotationAttr, 4),
SCALE: new BufferAttribute(scaleAttr, 3),
}

inst.instanceMatrix.needsUpdate = true
parent.add(inst)
;(parent as any).setDirty()
}
}

+ 1
- 0
src/three/utils/index.ts Zobrazit soubor

@@ -8,5 +8,6 @@ export {getTextureDataType, textureToCanvas, textureDataToImageData, textureToDa
export {threeConstMappings} from './const-mappings'
export {ObjectPicker} from './ObjectPicker'
export {SelectionWidget, BoxSelectionWidget} from './SelectionWidget'
export {autoGPUInstanceMeshes} from './gpu-instancing'

// export {} from './constants'

+ 2
- 2
src/utils/serialization.ts Zobrazit soubor

@@ -719,12 +719,12 @@ export class MetaImporter {
}


static async LoadRootPathTextures({textures, images}: Pick<SerializationMetaType, 'textures'|'images'>, importer: IAssetImporter) {
static async LoadRootPathTextures({textures, images}: Pick<SerializationMetaType, 'textures'|'images'>, importer: IAssetImporter, usePreviewImages = true) {
const pms = []

for (const inpTexture of Array.isArray(textures) ? textures : Object.values(textures ?? {} as any) as any as any[]) {
const path = inpTexture?.userData?.rootPath
const hasImage = inpTexture.image && images[inpTexture.image] // its possible to have both image and rootPath, then the image will be preview image.
const hasImage = usePreviewImages && inpTexture.image && images[inpTexture.image] // its possible to have both image and rootPath, then the image will be preview image.
if (!path) continue
// console.warn(path, inpTexture, images)
const promise = importer.importSingle<ITexture>(path, {processRaw: false}).then((texture) => {

Načítá se…
Zrušit
Uložit