Przeglądaj źródła

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 2 lat temu
rodzic
commit
ee46c311dd
No account linked to committer's email address

+ 12
- 12
package-lock.json Wyświetl plik

@@ -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 Wyświetl plik

@@ -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 Wyświetl plik

@@ -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 Wyświetl plik

@@ -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 Wyświetl plik

@@ -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 Wyświetl plik

@@ -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 Wyświetl plik

@@ -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 Wyświetl plik

@@ -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 Wyświetl plik

@@ -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 Wyświetl plik

@@ -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 Wyświetl plik

@@ -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 Wyświetl plik

@@ -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) => {

Ładowanie…
Anuluj
Zapisz