Skip to content

Commit

Permalink
feat: texture with tags
Browse files Browse the repository at this point in the history
  • Loading branch information
7185 committed Feb 18, 2024
1 parent c35d7cf commit bbd0d61
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 38 deletions.
2 changes: 1 addition & 1 deletion frontend/src/app/engine/engine.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1175,7 +1175,7 @@ export class EngineService {
this.raycaster.set(cameraPosition, cameraToSpriteDirection)

// Ignore the current prop during raycasting to prevent self-intersection
const ignoreList = [corona, corona.parent]
const ignoreList = Utils.getMeshes(corona.parent)
const intersects = this.raycaster
.intersectObjects(
this.objectsNode.children
Expand Down
23 changes: 22 additions & 1 deletion frontend/src/app/utils/utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {Vector3} from 'three'
import {Mesh, Vector3} from 'three'
import type {Object3D} from 'three'

export class Utils {
Expand Down Expand Up @@ -127,4 +127,25 @@ export class Utils {
})
return objs
}

/**
* Get all children objects recursively
* @param object Object3D to traverse
* @param children Array of the children (empty by default)
* @returns Array of children
*/
static getMeshes(object: Object3D, children = []) {
if (object instanceof Mesh) {
children.push(object)
}
object.children.forEach((child) => {
if (child instanceof Mesh) {
children.push(child)
}
if (child.children.length > 0) {
Utils.getMeshes(child, children)
}
})
return children
}
}
44 changes: 33 additions & 11 deletions frontend/src/app/world/prop-action.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
AdditiveBlending,
AudioLoader,
Mesh,
Group,
CanvasTexture,
TextureLoader,
SRGBColorSpace,
Expand All @@ -24,7 +25,7 @@ import {
SpriteMaterial,
Vector3
} from 'three'
import type {Group, MeshPhongMaterial, Object3D, Texture} from 'three'
import type {MeshPhongMaterial, Object3D, Texture} from 'three'
import {pictureTag as PICTURE_TAG, signTag as SIGN_TAG} from 'three-rwx-loader'
import {Action} from '@lemuria/action-parser'
import {environment} from '../../environments/environment'
Expand Down Expand Up @@ -492,6 +493,9 @@ export class PropActionService {
* try to look for an archived version
*/
private makePicture(prop: Group, url: string, fallbackArchive = true) {
if (!this.hasTaggedMaterial(prop, PICTURE_TAG)) {
return
}
let remote = ''
if (this.remoteUrl.test(url)) {
remote = url
Expand Down Expand Up @@ -574,18 +578,17 @@ export class PropActionService {
* @param picture Image
*/
private pictureToProp(prop: Group, picture: Texture) {
if (!prop.userData.taggedMaterials[PICTURE_TAG]) {
return
}

picture.colorSpace = SRGBColorSpace
picture.wrapS = RepeatWrapping
picture.wrapT = RepeatWrapping
prop.traverse((child: Object3D) => {
if (child instanceof Mesh) {
if (
child instanceof Mesh &&
Object.keys(child.userData.taggedMaterials).length
) {
const newMaterials = []
newMaterials.push(...child.material)
for (const i of prop.userData.taggedMaterials[PICTURE_TAG]) {
for (const i of child.userData.taggedMaterials[PICTURE_TAG]) {
if (child.material[i].userData.rwx.material != null) {
newMaterials[i] = child.material[i].clone()
// Rebuild userData like the loader
Expand Down Expand Up @@ -636,7 +639,7 @@ export class PropActionService {
color: {r: number; g: number; b: number},
bcolor: {r: number; g: number; b: number}
) {
if (!prop.userData.taggedMaterials[SIGN_TAG]) {
if (!this.hasTaggedMaterial(prop, SIGN_TAG)) {
return
}

Expand All @@ -651,10 +654,13 @@ export class PropActionService {
}

prop.traverse((child: Object3D) => {
if (child instanceof Mesh) {
if (
child instanceof Mesh &&
Object.keys(child.userData.taggedMaterials).length
) {
const newMaterials = []
newMaterials.push(...child.material)
for (const i of prop.userData.taggedMaterials[SIGN_TAG]) {
for (const i of child.userData.taggedMaterials[SIGN_TAG]) {
if (child.material[i].userData.rwx.material != null) {
newMaterials[i] = child.material[i].clone()
// Rebuild userData like the loader
Expand Down Expand Up @@ -696,13 +702,19 @@ export class PropActionService {
prop: Group,
textureName: string = null,
maskName: string = null,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
tag: string = null,
color: {r: number; g: number; b: number} = null
): Observable<unknown> {
const promises: Observable<unknown>[] = []
let currentTag = null
prop.traverse((child: Object3D) => {
if (tag && child instanceof Group) {
currentTag = child.parent.userData.rwx?.tag
}
if (child instanceof Mesh) {
if (tag && currentTag !== +tag) {
return
}
const newMaterials = []
child.material.forEach((m: MeshPhongMaterial) => {
if (m.userData.rwx.material != null) {
Expand Down Expand Up @@ -854,6 +866,16 @@ export class PropActionService {
}).click()
}

private hasTaggedMaterial(prop: Group, tag: string) {
let hasTag = false
prop.traverse((child: Object3D) => {
if (child instanceof Mesh && child.userData.taggedMaterials[tag]) {
hasTag = true
}
})
return hasTag
}

/**
* Teleport the player according to the teleport data
* @param teleport Parsed teleport data
Expand Down
39 changes: 14 additions & 25 deletions frontend/src/app/world/prop.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
MeshBasicMaterial,
SRGBColorSpace
} from 'three'
import RWXLoader, {RWXMaterialManager} from 'three-rwx-loader'
import RWXLoader, {RWXMaterialManager, flattenGroup} from 'three-rwx-loader'
import * as fflate from 'fflate'
import {Utils} from '../utils'

Expand Down Expand Up @@ -46,7 +46,6 @@ export class PropService {
private rwxPath = computed(() => `${this.path()}/rwx`)
private unknown: Group
private rwxPropLoader = new RWXLoader(new LoadingManager())
private rwxAvatarLoader = new RWXLoader(new LoadingManager())
private basicLoader = new RWXLoader(new LoadingManager())
private objects: Map<string, Observable<Group>> = new Map()
private avatars: Map<string, Observable<Group>> = new Map()
Expand Down Expand Up @@ -74,10 +73,7 @@ export class PropService {
false,
SRGBColorSpace
)
this.rwxPropLoader
.setRWXMaterialManager(this.rwxMaterialManager)
.setFlatten(true)
this.rwxAvatarLoader.setRWXMaterialManager(this.rwxMaterialManager)
this.rwxPropLoader.setRWXMaterialManager(this.rwxMaterialManager)
this.basicLoader
.setFflate(fflate)
.setFlatten(true)
Expand All @@ -88,9 +84,6 @@ export class PropService {
this.rwxMaterialManager.folder = this.resPath()
this.basicLoader.setPath(this.rwxPath()).setResourcePath(this.resPath())
this.rwxPropLoader.setPath(this.rwxPath()).setResourcePath(this.resPath())
this.rwxAvatarLoader
.setPath(this.rwxPath())
.setResourcePath(this.resPath())
})
}

Expand All @@ -99,7 +92,7 @@ export class PropService {
}

public loadAvatar(name: string): Observable<Group> {
return this.loadRwxObject(name, this.avatars, 'avatar')
return this.loadRwxObject(name, this.avatars, 'prop')
}

public cleanCache() {
Expand Down Expand Up @@ -140,25 +133,21 @@ export class PropService {
return object
}

let loader: RWXLoader
switch (loaderType) {
case 'prop':
loader = this.rwxPropLoader
break
case 'avatar':
loader = this.rwxAvatarLoader
break
default:
loader = this.basicLoader
if (loader.path !== this.rwxPath()) {
// Dirty fix for skybox loading too fast
loader.setPath(this.rwxPath()).setResourcePath(this.resPath())
}
}
const loader = loaderType === 'prop' ? this.rwxPropLoader : this.basicLoader
const observable = new Observable<Group>((observer) => {
loader.load(
name,
(rwx: Group) => {
// We flatten everything except RWX with tags (usually avatars)
let hasTag = false
rwx.traverse((child) => {
if (child.userData.rwx?.tag) {
hasTag = true
}
})
if (!hasTag) {
rwx = flattenGroup(rwx)
}
if (rwx instanceof Mesh) {
// Caching should probably be done by the loader
// but this is still better than nothing
Expand Down

0 comments on commit bbd0d61

Please sign in to comment.