Procházet zdrojové kódy

Minor changes and fixes

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

+ 6
- 3
rollup.config.mjs Zobrazit soubor

import resolve from '@rollup/plugin-node-resolve'; import resolve from '@rollup/plugin-node-resolve';
import typescript from '@rollup/plugin-typescript'; import typescript from '@rollup/plugin-typescript';
import packageJson from './package.json' assert {type: 'json'}; import packageJson from './package.json' assert {type: 'json'};
import path from 'path'
import {fileURLToPath} from 'url';
import path from 'node:path'
import {fileURLToPath} from 'node:url';
import postcss from 'rollup-plugin-postcss' import postcss from 'rollup-plugin-postcss'
import glsl from "rollup-plugin-glsl" import glsl from "rollup-plugin-glsl"
import replace from "@rollup/plugin-replace"; import replace from "@rollup/plugin-replace";
import terser from "@rollup/plugin-terser";
import commonjs from "@rollup/plugin-commonjs"; import commonjs from "@rollup/plugin-commonjs";
import license from "rollup-plugin-license"; import license from "rollup-plugin-license";
import terser from "@rollup/plugin-terser";


const __filename = fileURLToPath(import.meta.url); const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename); const __dirname = path.dirname(__filename);
plugins: [ plugins: [
replace({ replace({
'process.env.NODE_ENV': JSON.stringify( 'production' ), 'process.env.NODE_ENV': JSON.stringify( 'production' ),
'.css?inline': '.css',
preventAssignment: true,
}), }),
// replace({ // replace({
// exclude: 'src/**', // exclude: 'src/**',
include: "src/**/*.glsl" include: "src/**/*.glsl"
}), }),
postcss({ postcss({
extensions: ['.css', '.css?inline'],
modules: false, modules: false,
autoModules: true, // todo; issues with typescript import css, because inject is false autoModules: true, // todo; issues with typescript import css, because inject is false
inject: false, inject: false,

+ 16
- 6
src/assetmanager/MaterialManager.ts Zobrazit soubor

// return object // return object
// } // }
// protected abstract _processModel(object: any, options: AnyOptions): any // protected abstract _processModel(object: any, options: AnyOptions): any
convertToIMaterial(material: Material&{assetType?:'material', iMaterial?: IMaterial}, options: {useSourceMaterial?:boolean, materialTemplate?: string} = {}): IMaterial|undefined {
/**
* Creates a new material if a compatible template is found or apply minimal upgrades and returns the original material.
* Also checks from the registered materials, if one with the same uuid is found, it is returned instead with the new parameters.
* Also caches the response.
* Returns the same material if its already upgraded.
* @param material - the material to upgrade/check
* @param useSourceMaterial - if false, will not use the source material parameters in the new material. default = true
* @param materialTemplate - any specific material template to use instead of detecting from the material type.
* @param createFromTemplate - if false, will not create a new material from the template, but will apply minimal upgrades to the material instead. default = true
*/
convertToIMaterial(material: Material&{assetType?:'material', iMaterial?: IMaterial}, {useSourceMaterial = true, materialTemplate, createFromTemplate = true}: {useSourceMaterial?:boolean, materialTemplate?: string, createFromTemplate?: boolean} = {}): IMaterial|undefined {
if (!material) return if (!material) return
if (material.assetType) return <IMaterial>material if (material.assetType) return <IMaterial>material
if (material.iMaterial?.assetType) return material.iMaterial if (material.iMaterial?.assetType) return material.iMaterial
const uuid = material.userData?.uuid || material.uuid const uuid = material.userData?.uuid || material.uuid
let mat = this.findMaterial(uuid) let mat = this.findMaterial(uuid)
if (!mat) {
const ignoreSource = options.useSourceMaterial === false || !material.isMaterial
const template = options.materialTemplate || (!ignoreSource && material.type ? material.type || 'physical' : 'physical')
if (!mat && createFromTemplate !== false) {
const ignoreSource = useSourceMaterial === false || !material.isMaterial
const template = materialTemplate || (!ignoreSource && material.type ? material.type || 'physical' : 'physical')
mat = this.create(template, ignoreSource ? undefined : material) mat = this.create(template, ignoreSource ? undefined : material)
} else {
} else if (mat) {
// if ((mat as any).iMaterial) mat = (mat as any).iMaterial // if ((mat as any).iMaterial) mat = (mat as any).iMaterial
console.warn('Material with the same uuid already exists, copying properties') console.warn('Material with the same uuid already exists, copying properties')
if (material.type !== mat!.type) console.error('Material type mismatch, delete previous material first?', material, mat) if (material.type !== mat!.type) console.error('Material type mismatch, delete previous material first?', material, mat)
mat.userData.uuid = uuid mat.userData.uuid = uuid
material.iMaterial = mat material.iMaterial = mat
} else { } else {
console.warn('Failed to convert material to IMaterial, just upgrading', material, options)
console.warn('Failed to convert material to IMaterial, just upgrading', material, useSourceMaterial, materialTemplate)
mat = iMaterialCommons.upgradeMaterial.call(material) mat = iMaterialCommons.upgradeMaterial.call(material)
} }
return mat return mat

+ 1
- 1
src/assetmanager/import/OBJLoader2.ts Zobrazit soubor



} }


declare loadAsync(url: string, onProgress?: (event: ProgressEvent) => void): Promise<any>
loadAsync(url: string, onProgress?: (event: ProgressEvent) => void): Promise<any>


setMaterials( materials ) { setMaterials( materials ) {



+ 3
- 4
src/core/IObject.ts Zobrazit soubor



autoScaleRadius?: number autoScaleRadius?: number
autoScaled?: boolean autoScaled?: boolean
geometriesCentered?: boolean geometriesCentered?: boolean


/** /**
* @param isCentered - optional (taken from userData.isCentered by default) * @param isCentered - optional (taken from userData.isCentered by default)
* @param setDirty - true by default * @param setDirty - true by default
*/ */
autoScale?<T extends IObject3D>(autoScaleRadius?: number, isCentered?: boolean, setDirty?: boolean): T
autoScale?(autoScaleRadius?: number, isCentered?: boolean, setDirty?: boolean): this


/** /**
* *
* @param setDirty - calls {@link setDirty} @default true * @param setDirty - calls {@link setDirty} @default true
*/ */
autoCenter?<T extends IObject3D>(setDirty?: boolean): T
autoCenter?(setDirty?: boolean): this


/** /**
* @deprecated use object directly * @deprecated use object directly


// __disposed?: boolean // __disposed?: boolean
/** /**
*
* @param removeFromParent - remove from parent. Default true * @param removeFromParent - remove from parent. Default true
*/ */
dispose(removeFromParent?: boolean): void; dispose(removeFromParent?: boolean): void;

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

clock: Clock clock: Clock


blit(destination: IRenderTarget|undefined|null, options?: RendererBlitOptions): void blit(destination: IRenderTarget|undefined|null, options?: RendererBlitOptions): void
clearColor({r, g, b, a, target, depth = true, stencil = true, viewport}:
clearColor({r, g, b, a, target, depth, stencil, viewport}:
{r?: number, g?: number, b?: number, a?: number, target?: IRenderTarget, depth?: boolean, stencil?: boolean, viewport?: Vector4}): void {r?: number, g?: number, b?: number, a?: number, target?: IRenderTarget, depth?: boolean, stencil?: boolean, viewport?: Vector4}): void


renderTargetToDataUrl(target: WebGLRenderTarget, mimeType?: string, quality?: number): string renderTargetToDataUrl(target: WebGLRenderTarget, mimeType?: string, quality?: number): string

+ 6
- 1
src/core/IScene.ts Zobrazit soubor

attach(object: any): this; attach(object: any): this;
detach(): this; detach(): this;
isWidget: true; isWidget: true;

object: any
update?(): void

dispose?(): void
} }


export interface IScene<E extends ISceneEvent = ISceneEvent, ET extends ISceneEventTypes = ISceneEventTypes> export interface IScene<E extends ISceneEvent = ISceneEvent, ET extends ISceneEventTypes = ISceneEventTypes>
// region deprecated // region deprecated


/** /**
@deprecated use {@link getObjectByName} instead
* @deprecated use {@link getObjectByName} instead
* @param name * @param name
* @param parent * @param parent
*/ */

+ 42
- 4
src/core/camera/PerspectiveCamera2.ts Zobrazit soubor

import type {ICamera, ICameraEvent, ICameraUserData, TCameraControlsMode} from '../ICamera' import type {ICamera, ICameraEvent, ICameraUserData, TCameraControlsMode} from '../ICamera'
import {ICameraSetDirtyOptions} from '../ICamera' import {ICameraSetDirtyOptions} from '../ICamera'
import type {ICameraControls, TControlsCtor} from './ICameraControls' import type {ICameraControls, TControlsCtor} from './ICameraControls'
import {OrbitControls3} from '../../three'
import {OrbitControls3} from '../../three/controls/OrbitControls3'
import {IObject3D} from '../IObject' import {IObject3D} from '../IObject'
import {ThreeSerialization} from '../../utils' import {ThreeSerialization} from '../../utils'
import {iCameraCommons} from '../object/iCameraCommons' import {iCameraCommons} from '../object/iCameraCommons'
@serialize() readonly position: Vector3 @serialize() readonly position: Vector3


/** /**
* The target position of the camera (where the camera looks at). Also syncs with the controls.target, so it's not required to set that separately.
* Note: this is always in world-space * Note: this is always in world-space
* Note: {@link autoLookAtTarget} must be set to trye to make the camera look at the target when no controls are enabled
*/ */
@uiVector('Target', undefined, undefined, (that:PerspectiveCamera2)=>({onChange: ()=>that.setDirty()})) @uiVector('Target', undefined, undefined, (that:PerspectiveCamera2)=>({onChange: ()=>that.setDirty()}))
@serialize() readonly target: Vector3 = new Vector3(0, 0, 0) @serialize() readonly target: Vector3 = new Vector3(0, 0, 0)
@onChange2(PerspectiveCamera2.prototype._nearFarChanged) @onChange2(PerspectiveCamera2.prototype._nearFarChanged)
far = 50 far = 50


/**
* Automatically make the camera look at the {@link target} on {@link setDirty} call
* Defaults to false. Note that this must be set to true to make the camera look at the target without any controls
*/
@bindToValue({obj: 'userData', onChange: 'setDirty'})
autoLookAtTarget = false // bound to userData so that it's saved in the glb.

/** /**
* Automatically manage near and far clipping planes based on scene size. * Automatically manage near and far clipping planes based on scene size.
*/ */


/** /**
* Minimum near clipping plane allowed. (Distance from camera) * Minimum near clipping plane allowed. (Distance from camera)
* Used in RootScene when {@link autoNearFar} is true.
* @default 0.2 * @default 0.2
*/ */
@bindToValue({obj: 'userData', onChange: 'setDirty'}) @bindToValue({obj: 'userData', onChange: 'setDirty'})
minNearPlane = 0.5 minNearPlane = 0.5
/** /**
* Maximum far clipping plane allowed. (Distance from camera) * Maximum far clipping plane allowed. (Distance from camera)
* Used in RootScene when {@link autoNearFar} is true.
*/ */
@bindToValue({obj: 'userData', onChange: 'setDirty'}) @bindToValue({obj: 'userData', onChange: 'setDirty'})
maxFarPlane = 1000 maxFarPlane = 1000


private _interactionsDisabledBy = new Set<string>() private _interactionsDisabledBy = new Set<string>()


/**
* If interactions are enabled for this camera. It can be disabled by some code or plugin.
* see also {@link setInteractions}
* @deprecated use {@link canUserInteract} to check if the user can interact with this camera
* @readonly
*/
get interactionsEnabled(): boolean { get interactionsEnabled(): boolean {
return this._interactionsDisabledBy.size === 0 return this._interactionsDisabledBy.size === 0
} }
} }


get canUserInteract() { get canUserInteract() {
return this.interactionsEnabled && this.isMainCamera && this.controlsMode !== ''
return this._interactionsDisabledBy.size === 0 && this.isMainCamera && this.controlsMode !== ''
} }


// endregion // endregion


// todo: only for orbit control like controls? // todo: only for orbit control like controls?
if (this._controls) { if (this._controls) {
const ce = this.interactionsEnabled
const ce = this.canUserInteract
this._controls.enabled = ce this._controls.enabled = ce
if (ce) this.up.copy(Object3D.DEFAULT_UP) if (ce) this.up.copy(Object3D.DEFAULT_UP)
} }
getObjectById: <T extends IObject3D = IObject3D>(id: number) => T | undefined getObjectById: <T extends IObject3D = IObject3D>(id: number) => T | undefined
getObjectByName: <T extends IObject3D = IObject3D>(name: string) => T | undefined getObjectByName: <T extends IObject3D = IObject3D>(name: string) => T | undefined
getObjectByProperty: <T extends IObject3D = IObject3D>(name: string, value: string) => T | undefined getObjectByProperty: <T extends IObject3D = IObject3D>(name: string, value: string) => T | undefined
copy: (source: ICamera|Camera, recursive?: boolean, distanceFromTarget?: number, worldSpace?: boolean) => this
copy: (source: ICamera|Camera|IObject3D, recursive?: boolean, distanceFromTarget?: number, worldSpace?: boolean) => this
clone: (recursive?: boolean) => this clone: (recursive?: boolean) => this
add: (...object: IObject3D[]) => this add: (...object: IObject3D[]) => this
remove: (...object: IObject3D[]) => this remove: (...object: IObject3D[]) => this
// endregion // endregion


} }

/**
* Empty class with the constructor same as PerspectiveCamera in three.js.
* This can be used to remain compatible with three.js construct signature.
*/
export class PerspectiveCamera0 extends PerspectiveCamera2 {
constructor(fov?: number, aspect?: number, near?: number, far?: number) {
super(undefined, undefined, undefined, fov, aspect || 1)
if (near || far) {
this.autoNearFar = false
if (near) {
this.near = near
this.minNearPlane = near
}
if (far) {
this.far = far
this.maxFarPlane = far
}
}
}
}

+ 1
- 1
src/core/geometry/iGeometryCommons.ts Zobrazit soubor

import {UiObjectConfig} from 'uiconfig.js' import {UiObjectConfig} from 'uiconfig.js'
import {IGeometry, IGeometrySetDirtyOptions} from '../IGeometry' import {IGeometry, IGeometrySetDirtyOptions} from '../IGeometry'
import {autoGPUInstanceMeshes, isInScene, toIndexedGeometry} from '../../three'
import {autoGPUInstanceMeshes, isInScene, toIndexedGeometry} from '../../three/utils'
import {BufferGeometry, Vector3} from 'three' import {BufferGeometry, Vector3} from 'three'


export const iGeometryCommons = { export const iGeometryCommons = {

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

import {PhysicalMaterial} from './PhysicalMaterial' import {PhysicalMaterial} from './PhysicalMaterial'
import {getEmptyMeta} from '../../utils' import {getEmptyMeta} from '../../utils'
import {LegacyPhongMaterial} from './LegacyPhongMaterial' import {LegacyPhongMaterial} from './LegacyPhongMaterial'
import {generateUUID} from '../../three'
import {generateUUID} from '../../three/utils'


declare module '../IMaterial' { declare module '../IMaterial' {
interface IMaterial { interface IMaterial {

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

return new LineMaterial2(params) return new LineMaterial2(params)
}, },
} }

} }

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

import {MaterialExtender, MaterialExtension} from '../../materials' import {MaterialExtender, MaterialExtension} from '../../materials'
import {IScene} from '../IScene' import {IScene} from '../IScene'
import {IMaterial, IMaterialEvent, IMaterialSetDirtyOptions} from '../IMaterial' import {IMaterial, IMaterialEvent, IMaterialSetDirtyOptions} from '../IMaterial'
import {isInScene} from '../../three'
import {isInScene} from '../../three/utils'


/** /**
* Map of all material properties and their default values in three.js - Material.js * Map of all material properties and their default values in three.js - Material.js

+ 0
- 18
src/core/object/IObjectUi.ts Zobrazit soubor



// todo: lights? // todo: lights?


// todo: issue when selected object is moved to picking from SceneUI
// (config.children as UiObjectConfig[]).push(makeHierarchyUi(object))
this.uiConfig = config this.uiConfig = config
return config return config


} }

// function makeHierarchyUi(object: Object3D, root?: Object3D): UiObjectConfig {
// const dispatch = ()=>(root || object).dispatchEvent({type: 'select', ui: true, value: object})
// if (object.children.length === 0) return {
// type: 'button',
// label: 'Select ' + (object.name || 'unnamed'),
// value: dispatch,
// }
// return {
// type: 'folder',
// label: 'Select ' + (object.name || 'unnamed'),
// children: object.children.map((child)=>makeHierarchyUi(child, root || object)),
// value: dispatch,
// onExpand: dispatch,
// }
// }

+ 6
- 6
src/global.d.ts Zobrazit soubor

export default content export default content
export const stylesheet: string export const stylesheet: string
} }
declare module '*.module.css' {
const content: any
export default content
export const stylesheet: string
}
declare module '*.css' {
// declare module '*.module.css' {
// const content: any
// export default content
// export const stylesheet: string
// }
declare module '*.css?inline' {
const content: string const content: string
export default content export default content
} }

+ 1
- 1
src/materials/MaterialExtender.ts Zobrazit soubor

import {shaderReplaceString, shaderUtils} from '../utils' import {shaderReplaceString, shaderUtils} from '../utils'
import {Object3D, Shader, ShaderChunk, WebGLRenderer} from 'three' import {Object3D, Shader, ShaderChunk, WebGLRenderer} from 'three'
import {MaterialExtension} from './MaterialExtension' import {MaterialExtension} from './MaterialExtension'
import {generateUUID} from '../three'
import {generateUUID} from '../three/utils'


export class MaterialExtender { export class MaterialExtender {



+ 15
- 5
src/three/utils/texture.ts Zobrazit soubor

} }


export function texImageToCanvas(image: TexImageSource, maxWidth: number, flipY = false) { export function texImageToCanvas(image: TexImageSource, maxWidth: number, flipY = false) {
let width, height
if (!window.VideoFrame) window.VideoFrame = HTMLVideoElement as any
if (image instanceof window.VideoFrame) {
width = image.displayWidth
height = image.displayHeight
} else {
width = image.width
height = image.height
}
if (window.VideoFrame as any === HTMLVideoElement) delete (window as any).VideoFrame
const canvas = document.createElement('canvas') const canvas = document.createElement('canvas')
// resize it to the size of our image // resize it to the size of our image
canvas.width = Math.min(maxWidth, image.width as number)
canvas.height = Math.floor(1.0 + canvas.width * (image.height as number) / (image.width as number))
canvas.width = Math.min(maxWidth, width)
canvas.height = Math.floor(1.0 + canvas.width * height / width)


const ctx = canvas.getContext('2d') const ctx = canvas.getContext('2d')
if (!ctx) { if (!ctx) {
if ((image as ImageData).data !== undefined) { // THREE.DataTexture if ((image as ImageData).data !== undefined) { // THREE.DataTexture
const imageData = image as ImageData const imageData = image as ImageData


if (image.width !== canvas.width || image.height !== canvas.height) {
if (width !== canvas.width || height !== canvas.height) {
const tempCanvas = document.createElement('canvas') const tempCanvas = document.createElement('canvas')
tempCanvas.width = image.width
tempCanvas.height = image.height
tempCanvas.width = width
tempCanvas.height = height
const tempCtx = tempCanvas.getContext('2d') const tempCtx = tempCanvas.getContext('2d')
if (!tempCtx) { if (!tempCtx) {
console.error('textureToDataUrl: could not get temp canvas context') console.error('textureToDataUrl: could not get temp canvas context')

+ 1
- 1
src/utils/CustomContextMenu.ts Zobrazit soubor

import styles from './CustomContextMenu.css'
import styles from './CustomContextMenu.css?inline'


/** /**
* Represents a custom context menu that can be created and managed dynamically. * Represents a custom context menu that can be created and managed dynamically.

+ 1
- 1
src/utils/camera-anim.ts Zobrazit soubor

import {Quaternion, Spherical, Vector3} from 'three' import {Quaternion, Spherical, Vector3} from 'three'
import {worldToLocalQuaternion} from '../three'
import {worldToLocalQuaternion} from '../three/utils'
import {CameraView, ICamera, ICameraView} from '../core' import {CameraView, ICamera, ICameraView} from '../core'
import {AnimationOptions} from 'popmotion' import {AnimationOptions} from 'popmotion'
import {lerp, lerpAngle} from './animation' import {lerp, lerpAngle} from './animation'

+ 1
- 0
src/viewer/ThreeViewer.ts Zobrazit soubor

const camera = new PerspectiveCamera2('orbit', this._canvas) const camera = new PerspectiveCamera2('orbit', this._canvas)
camera.name = 'Default Camera' camera.name = 'Default Camera'
camera.position.set(0, 0, 5) camera.position.set(0, 0, 5)
camera.target.set(0, 0, 0)
camera.userData.autoLookAtTarget = true // only for when controls are disabled / not available camera.userData.autoLookAtTarget = true // only for when controls are disabled / not available


// Update camera controls postFrame if allowed to interact // Update camera controls postFrame if allowed to interact

+ 1
- 1
src/viewer/version.ts Zobrazit soubor

export const VERSION = '0.0.19'
export const VERSION = '0.0.20-dev.1'

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