Skip to content
This repository was archived by the owner on Aug 21, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion packages/engine/src/assets/exporters/gltf/GLTFExporter.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ Ethereal Engine. All Rights Reserved.

//https://github.com/DefinitelyTyped/DefinitelyTyped/blob/5b452194a34f86bb35532340ec19582a88337de2/types/three/examples/jsm/exporters/GLTFExporter.d.ts
import { Object3D, AnimationClip, Texture, Material, Mesh, Camera, BufferAttribute, BufferGeometry, Scene } from 'three'
import { Entity } from '../../../ecs/classes/Entity';

export interface GLTFExporterOptions {
/**
Expand Down Expand Up @@ -79,6 +80,8 @@ export interface GLTFExporterOptions {
resourceURI?: string;

flipY?: boolean;

srcEntity?: Entity;
}

export class GLTFExporter {
Expand Down Expand Up @@ -141,7 +144,7 @@ export class GLTFWriter {
truncateDrawRange?: boolean,
maxTextureSize?: number,
resourceURI?: string

srcEntity?: Entity
}
pending: Promise<any>[]
extensionsUsed : {[key:string] : any}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ export default class BufferHandlerExtension extends ExporterExtension implements
)
//make uris relative to model src
for (const image of images) {
if (!image.uri) continue
image.uri = image.uri.replace(basePath, '')
}
writer.buffers.map((buffer, index) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { Object3D } from 'three'
import { Entity } from '../../../../ecs/classes/Entity'
import { getComponent, setComponent } from '../../../../ecs/functions/ComponentFunctions'
import { EntityTreeComponent, iterateEntityNode } from '../../../../ecs/functions/EntityTree'
import { Object3DWithEntity } from '../../../../scene/components/GroupComponent'
import { SourceComponent } from '../../../../scene/components/SourceComponent'
import { getModelSceneID } from '../../../../scene/functions/loaders/ModelFunctions'
import { SceneID } from '../../../../schemas/projects/scene.schema'
import { GLTFExporterPlugin, GLTFWriter } from '../GLTFExporter'
import { ExporterExtension } from './ExporterExtension'

export default class SourceHandlerExtension extends ExporterExtension implements GLTFExporterPlugin {
entitySet: { entity: Entity; parent: Entity }[]
constructor(writer: GLTFWriter) {
super(writer)
this.name = 'EE_sourceHandler'
this.entitySet = [] as { entity: Entity; parent: Entity }[]
}

beforeParse(input: Object3D | Object3D[]) {
//we allow saving of any object that has a source equal to or parent of the root's source
const validSrcs: Set<SceneID> = new Set()
validSrcs.add(getModelSceneID(this.writer.options.srcEntity!))
const root = (Array.isArray(input) ? input[0] : input) as Object3DWithEntity
let walker: Entity | null = root.entity
while (walker !== null) {
const src = getComponent(walker, SourceComponent)
if (src) validSrcs.add(src)
walker = getComponent(walker, EntityTreeComponent)?.parentEntity ?? null
}
iterateEntityNode(
root.entity,
(entity) => {
const entityTree = getComponent(entity, EntityTreeComponent)
if (!entityTree || !entityTree.parentEntity) return
this.entitySet.push({ entity, parent: entityTree.parentEntity })
setComponent(entity, EntityTreeComponent, { parentEntity: null })
},
(entity) => {
const src = getComponent(entity, SourceComponent)
return src && !validSrcs.has(src)
}
)
}

afterParse(input: Object3D) {
this.entitySet.forEach(({ entity, parent }) => {
setComponent(entity, EntityTreeComponent, { parentEntity: parent })
})
}
}
4 changes: 3 additions & 1 deletion packages/engine/src/assets/functions/createGLTFExporter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { EEECSExporterExtension } from '../exporters/gltf/extensions/EEECSExport
import EEMaterialExporterExtension from '../exporters/gltf/extensions/EEMaterialExporterExtension'
import GPUInstancingExporterExtension from '../exporters/gltf/extensions/GPUInstancingExporterExtension'
import ResourceIDExtension from '../exporters/gltf/extensions/ResourceIDExtension'
import SourceHandlerExtension from '../exporters/gltf/extensions/SourceHandlerExtension'
import { GLTFExporter, GLTFWriter } from '../exporters/gltf/GLTFExporter'

export default function createGLTFExporter() {
Expand All @@ -38,7 +39,8 @@ export default function createGLTFExporter() {
GPUInstancingExporterExtension,
EEMaterialExporterExtension,
EEECSExporterExtension,
ResourceIDExtension
ResourceIDExtension,
SourceHandlerExtension
//ImageProcessingExtension
]
extensions.forEach((extension) => exporter.register((writer) => new extension(writer)))
Expand Down
3 changes: 2 additions & 1 deletion packages/engine/src/assets/functions/exportModelGLTF.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ export default async function exportModelGLTF(
...options,
animations: scene.animations ?? [],
flipY: !!scene.userData.src?.endsWith('.usdz'),
resourceURI
resourceURI,
srcEntity: entity
}
)
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { InstancedMesh, Material, Object3D, Vector3 } from 'three'
import { DistanceFromCameraComponent } from '@etherealengine/engine/src/transform/components/DistanceComponents'

import { AssetLoader } from '../../../assets/classes/AssetLoader'
import { pathResolver } from '../../../assets/functions/pathResolver'
import { addOBCPlugin } from '../../../common/functions/OnBeforeCompilePlugin'
import { isMobile } from '../../../common/functions/isMobile'
import { Engine } from '../../../ecs/classes/Engine'
Expand Down Expand Up @@ -54,9 +55,9 @@ export function setModelVariant(entity: Entity) {
const targetDevice = isMobile || isMobileXRHeadset ? 'MOBILE' : 'DESKTOP'
//set model src to mobile variant src
const deviceVariant = variantComponent.levels.find((level) => level.value.metadata['device'] === targetDevice)
deviceVariant &&
modelComponent.src.value !== deviceVariant.src.value &&
modelComponent.src.set(deviceVariant.src.value)
const modelRelativePath = pathResolver().exec(modelComponent.src.value)?.[2]
const deviceRelativePath = deviceVariant ? pathResolver().exec(deviceVariant.src.value)?.[2] : ''
deviceVariant && modelRelativePath !== deviceRelativePath && modelComponent.src.set(deviceVariant.src.value)
} else if (variantComponent.heuristic.value === 'DISTANCE') {
const distance = DistanceFromCameraComponent.squaredDistance[entity]
for (let i = 0; i < variantComponent.levels.length; i++) {
Expand Down