Skip to content

Commit

Permalink
fix: selection box after prop deselect
Browse files Browse the repository at this point in the history
  • Loading branch information
7185 committed Dec 28, 2024
1 parent 240cdcd commit 7f1f633
Show file tree
Hide file tree
Showing 16 changed files with 245 additions and 274 deletions.
2 changes: 1 addition & 1 deletion action-parser/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
},
"devDependencies": {
"@eslint/js": "^9.10.0",
"@swc/core": "^1.10.1",
"@swc/core": "^1.10.3",
"@vitest/coverage-v8": "^2.1.8",
"eslint": "^9.17.0",
"globals": "^15.14.0",
Expand Down
1 change: 1 addition & 0 deletions backend-py/app.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#!/usr/bin/env python
"""App module"""

import quart_flask_patch
import asyncio
import tomllib

Expand Down
7 changes: 4 additions & 3 deletions backend-py/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
aiofiles~=24.1.0
Flask-Caching~=2.3.0
httpx~=0.27.2
orjson~=3.10.10
httpx~=0.28.1
orjson~=3.10.12
prisma~=0.15.0
Quart~=0.19.8
Quart~=0.20.0
Quart-Flask-Patch~=0.3.0
Quart-JWT-Extended~=0.1.0
uvloop~=0.21.0
2 changes: 1 addition & 1 deletion backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
"@nestjs/schematics": "^10.2.3",
"@nestjs/testing": "^10.4.15",
"@swc/cli": "^0.5.2",
"@swc/core": "^1.10.1",
"@swc/core": "^1.10.3",
"@types/node": "^20.17.7",
"@types/supertest": "^6.0.2",
"@types/ws": "^8.5.13",
Expand Down
6 changes: 3 additions & 3 deletions bot-py/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
httpx
trio
trio-websocket
httpx~=0.28.1
trio~=0.28.0
trio-websocket~=0.11.1
23 changes: 10 additions & 13 deletions frontend/src/app/animation/avatar-animation.service.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {effect, inject, Injectable} from '@angular/core'
import {computed, inject, Injectable} from '@angular/core'
import parseSequence, {FileType, getJointTag} from 'aw-sequence-parser'
import {EngineService} from '../engine/engine.service'
import {PropService} from '../world/prop.service'
Expand Down Expand Up @@ -83,15 +83,14 @@ export class AvatarAnimationService {
fileType: FileType.AUTO,
fflate
}
private frameRate = 60
private readonly engineSvc = inject(EngineService)
private readonly propSvc = inject(PropService)

constructor() {
effect(() => {
this.setFrameRate(this.engineSvc.maxFps())
})
}
private frameRate = computed(() => {
const newFrameRate = this.engineSvc.maxFps()
this.handleFrameRateChange(newFrameRate)
return newFrameRate
})

async loadSequence(name: string, uri: string) {
if (this.sequences.has(name)) {
Expand Down Expand Up @@ -132,9 +131,7 @@ export class AvatarAnimationService {
return mgrPromise
}

async setFrameRate(frameRate: number) {
this.frameRate = frameRate

async handleFrameRateChange(frameRate: number) {
if (!this.sequences) {
return
}
Expand Down Expand Up @@ -244,8 +241,8 @@ export class AvatarAnimationService {

private interpolate(sequence: ThreeSequence): ThreeSequence {
// Upscale if needed
if (sequence.frameRate < this.frameRate) {
const ratio = this.frameRate / sequence.frameRate
if (sequence.frameRate < this.frameRate()) {
const ratio = this.frameRate() / sequence.frameRate
const threeFrames = Array.from(
{length: Math.floor(sequence.frames.length * ratio)},
() => ({joints: {}, location: new Vector3()})
Expand All @@ -258,7 +255,7 @@ export class AvatarAnimationService {
threeFrames[id] = sequence.frames[sequence.keyFrameIDs[index]]
})

sequence.frameRate = this.frameRate
sequence.frameRate = this.frameRate()
sequence.frames = threeFrames
sequence.keyFrameIDs = keyFrameIDs
}
Expand Down
129 changes: 65 additions & 64 deletions frontend/src/app/engine/build.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,12 @@ import {X_AXIS, Y_AXIS, Z_AXIS} from '../utils/constants'
})
export class BuildService {
buildMode = false
selectedProp: Group | null = null
selectedCellSignal = signal<{
selectedCell = signal<{
height?: number
texture?: number
hole?: boolean
}>({})
selectedPropSignal = signal<Group>(null)
selectedProp = signal<Group>(null)
private axesHelper: AxesHelper | null = null
private cellSelection: Group | null = null
private propSelection: Group | null = null
Expand All @@ -53,14 +52,13 @@ export class BuildService {

selectProp(prop: Group, buildNode: Group) {
if (this.cellSelection != null) {
this.deselectCell(buildNode)
this.deselectCell()
}
if (this.propSelection != null) {
this.deselectProp(buildNode)
this.deselectProp()
}
this.buildMode = true
this.selectedProp = prop
this.selectedPropSignal.set(prop)
this.selectedProp.set(prop)
console.log(prop)

const geometry = new BoxGeometry(
Expand All @@ -83,35 +81,38 @@ export class BuildService {
buildNode.add(this.propSelection)
}

deselectProp(buildNode: Group) {
deselectProp() {
if (this.propSelectionBox == null) {
return
}
this.axesHelper?.dispose()
this.propSelection?.parent.remove(this.propSelection)
this.axesHelper = null
this.propSelection = null
this.propSelectionBox?.geometry.dispose()
;(this.propSelectionBox?.material as Material)?.dispose()
this.propSelectionBox = null
const prop = this.selectedProp()
this.selectedProp.set(null)
this.buildMode = false
if (prop == null) {
return
}
// Track the parent chunk in case of prop deletion since the code is async
const chunk = this.selectedProp.parent
this.propActionSvc.parseActions(this.selectedProp).then(() => {
this.propActionSvc.showProp(this.selectedProp)
const chunk = prop.parent
this.propActionSvc.parseActions(prop).then(() => {
this.propActionSvc.showProp(prop)
chunk.userData.bvhUpdate.next()
this.buildMode = false
this.selectedProp = null
this.selectedPropSignal.set(null)
this.propSelectionBox.geometry.dispose()
;(this.propSelectionBox.material as Material).dispose()
this.axesHelper?.dispose()
buildNode.remove(this.propSelection)
this.propSelectionBox = null
this.axesHelper = null
this.propSelection = null
})
}

moveProp(action: PropCtl, cameraDirection: Vector3, buildNode: Group) {
moveProp(action: PropCtl, cameraDirection: Vector3) {
if (action === 'deselect') {
this.deselectProp(buildNode)
this.deselectProp()
return
}
const allowRotation =
this.selectedProp.userData.rwx?.axisAlignment === 'none'
this.selectedProp().userData.rwx?.axisAlignment === 'none'
let moveStep = 0.5
let rotStep = Math.PI / 12
if (this.inputSysSvc.controls['clip']) {
Expand All @@ -130,103 +131,103 @@ export class BuildService {
}
switch (action) {
case 'up': {
this.selectedProp.position.add(new Vector3(0, moveStep, 0))
this.selectedProp().position.add(new Vector3(0, moveStep, 0))
this.updatePropSelectionBox()
break
}
case 'down': {
this.selectedProp.position.add(new Vector3(0, -moveStep, 0))
this.selectedProp().position.add(new Vector3(0, -moveStep, 0))
this.updatePropSelectionBox()
break
}
case 'forward': {
this.selectedProp.position.add(v.multiplyScalar(moveStep))
this.selectedProp().position.add(v.multiplyScalar(moveStep))
this.updatePropSelectionBox()
break
}
case 'backward': {
this.selectedProp.position.add(v.multiplyScalar(-moveStep))
this.selectedProp().position.add(v.multiplyScalar(-moveStep))
this.updatePropSelectionBox()
break
}
case 'left': {
this.selectedProp.position.add(
this.selectedProp().position.add(
new Vector3(v.z * moveStep, 0, v.x * -moveStep)
)
this.updatePropSelectionBox()
break
}
case 'right': {
this.selectedProp.position.add(
this.selectedProp().position.add(
new Vector3(v.z * -moveStep, 0, v.x * moveStep)
)
this.updatePropSelectionBox()
break
}
case 'rotY': {
if (allowRotation) {
this.selectedProp.rotateOnAxis(Y_AXIS, rotStep)
this.selectedProp().rotateOnAxis(Y_AXIS, rotStep)
this.updatePropSelectionBox()
}
break
}
case 'rotnY': {
if (allowRotation) {
this.selectedProp.rotateOnAxis(Y_AXIS, -rotStep)
this.selectedProp().rotateOnAxis(Y_AXIS, -rotStep)
this.updatePropSelectionBox()
}
break
}
case 'rotX': {
if (allowRotation) {
this.selectedProp.rotateOnAxis(X_AXIS, rotStep)
this.selectedProp().rotateOnAxis(X_AXIS, rotStep)
this.updatePropSelectionBox()
}
break
}
case 'rotnX': {
if (allowRotation) {
this.selectedProp.rotateOnAxis(X_AXIS, -rotStep)
this.selectedProp().rotateOnAxis(X_AXIS, -rotStep)
this.updatePropSelectionBox()
}
break
}
case 'rotZ': {
if (allowRotation) {
this.selectedProp.rotateOnAxis(Z_AXIS, rotStep)
this.selectedProp().rotateOnAxis(Z_AXIS, rotStep)
this.updatePropSelectionBox()
}
break
}
case 'rotnZ': {
if (allowRotation) {
this.selectedProp.rotateOnAxis(Z_AXIS, -rotStep)
this.selectedProp().rotateOnAxis(Z_AXIS, -rotStep)
this.updatePropSelectionBox()
}
break
}
case 'snapGrid': {
this.selectedProp.position.set(
Math.round(this.selectedProp.position.x * 2) / 2,
Math.round(this.selectedProp.position.y * 2) / 2,
Math.round(this.selectedProp.position.z * 2) / 2
this.selectedProp().position.set(
Math.round(this.selectedProp().position.x * 2) / 2,
Math.round(this.selectedProp().position.y * 2) / 2,
Math.round(this.selectedProp().position.z * 2) / 2
)
this.updatePropSelectionBox()
break
}
case 'rotReset': {
if (allowRotation) {
this.selectedProp.rotation.set(0, 0, 0)
this.selectedProp().rotation.set(0, 0, 0)
this.updatePropSelectionBox()
}
break
}
case 'copy': {
const {parent} = this.selectedProp
this.selectedProp = this.selectedProp.clone()
this.initPropCallbacks(this.selectedProp)
this.selectedProp.position.add(v.multiplyScalar(moveStep))
parent.add(this.selectedProp)
const {parent} = this.selectedProp()
this.selectedProp.set(this.selectedProp().clone())
this.initPropCallbacks(this.selectedProp())
this.selectedProp().position.add(v.multiplyScalar(moveStep))
parent.add(this.selectedProp())
this.updatePropSelectionBox()
break
}
Expand All @@ -236,25 +237,25 @@ export class BuildService {
}

private updatePropSelectionBox(): void {
this.selectedProp.updateMatrix()
const chunkData = this.selectedProp.parent.userData.world.chunk
this.selectedProp().updateMatrix()
const chunkData = this.selectedProp().parent.userData.world.chunk
const center = new Vector3(
this.selectedProp.userData.boxCenter.x,
this.selectedProp.userData.boxCenter.y,
this.selectedProp.userData.boxCenter.z
this.selectedProp().userData.boxCenter.x,
this.selectedProp().userData.boxCenter.y,
this.selectedProp().userData.boxCenter.z
)
this.propSelectionBox.position.copy(center)
center.applyAxisAngle(Y_AXIS, this.selectedProp.rotation.y)
center.applyAxisAngle(Z_AXIS, this.selectedProp.rotation.z)
center.applyAxisAngle(X_AXIS, this.selectedProp.rotation.x)
center.applyAxisAngle(Y_AXIS, this.selectedProp().rotation.y)
center.applyAxisAngle(Z_AXIS, this.selectedProp().rotation.z)
center.applyAxisAngle(X_AXIS, this.selectedProp().rotation.x)
this.propSelection.position.copy(
new Vector3(
chunkData.x + this.selectedProp.position.x,
this.selectedProp.position.y,
chunkData.z + this.selectedProp.position.z
chunkData.x + this.selectedProp().position.x,
this.selectedProp().position.y,
chunkData.z + this.selectedProp().position.z
)
)
this.propSelection.rotation.copy(this.selectedProp.rotation)
this.propSelection.rotation.copy(this.selectedProp().rotation)
this.propSelection.updateMatrix()
}

Expand All @@ -275,9 +276,9 @@ export class BuildService {
* | / | N
* seZ---seX
*/
this.deselectProp(buildNode)
this.deselectProp()
if (this.cellSelection != null) {
this.deselectCell(buildNode)
this.deselectCell()
}

this.cellSelection = new Group()
Expand Down Expand Up @@ -328,19 +329,19 @@ export class BuildService {
)
this.cellSelection.add(cell, square)
buildNode.add(this.cellSelection)
this.selectedCellSignal.set({height: cellSE.y})
this.selectedCell.set({height: cellSE.y})
}

deselectCell(buildNode: Group) {
deselectCell() {
if (this.cellSelection == null) {
return
}
for (const line of this.cellSelection.children as Line[]) {
line.geometry.dispose()
;(line.material as Material).dispose()
}
buildNode.remove(this.cellSelection)
this.cellSelection.parent.remove(this.cellSelection)
this.cellSelection = null
this.selectedCellSignal.set({})
this.selectedCell.set({})
}
}
Loading

0 comments on commit 7f1f633

Please sign in to comment.