Skip to content

Commit

Permalink
perf(troika-xr): avoid full update pass every frame in WristMountedUI
Browse files Browse the repository at this point in the history
  • Loading branch information
lojjic committed Mar 30, 2020
1 parent 61cb4f8 commit 4a4cd16
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 24 deletions.
11 changes: 11 additions & 0 deletions packages/troika-3d-ui/src/facade/UIBlock3DFacade.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ class UIBlock3DFacade extends Group3DFacade {
}
}

updateMatrices() {
super.updateMatrices()
this.layers.traverse(updateMatrices)
}

afterUpdate() {
let {
layers,
Expand Down Expand Up @@ -437,6 +442,12 @@ function isTextNodeChild(child) {
return typeof child === 'string' || typeof child === 'number'
}

function updateMatrices(obj) {
if (obj.updateMatrices) {
obj.updateMatrices()
}
}



export default UIBlock3DFacade
35 changes: 26 additions & 9 deletions packages/troika-xr/src/facade/wrist-mounted-ui/ContentContainer.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,11 @@ export class ContentContainer extends Object3DFacade {
this.active = false
}

afterUpdate() {
const {gripPose} = this
/**
* Sync to the current XRFrame's gripPose - all matrix syncing is localized here
* to avoid a full afterUpdate pass on every frame.
*/
syncPose(gripPose) {
if (gripPose) {
// Get current posed camera position, relative to the parent
let cam = this.getCameraFacade().threeObject
Expand Down Expand Up @@ -49,13 +52,22 @@ export class ContentContainer extends Object3DFacade {
this.scale += (targetScale - this.scale) * 0.3
this.visible = this.scale > 0.01 //hide below a certain size

// Rotate to face camera
this.rotateY = Math.atan2(camPos.x - pos.x, camPos.z - pos.z)
if (this.visible) {
// Rotate to face camera
this.rotateY = Math.atan2(camPos.x - pos.x, camPos.z - pos.z)

// Update projection cone's source position
let proj = this.getChildByKey('$projection')
if (proj) {
proj.syncSourcePosition()
}

// Sync all matrices
this.traverse(updateMatrices)
}
} else {
this.visible = false
}

super.afterUpdate()
}

shouldUpdateChildren () {
Expand Down Expand Up @@ -93,9 +105,7 @@ export class ContentContainer extends Object3DFacade {
kids[0].scale = kids[1].scale = this.platformRadius

// Update projection source
if (this.gripPose && this.visible) {
kids[1].sourceWorldPosition = this.projectionSourcePosition
}
kids[1].sourceWorldPosition = this.projectionSourcePosition

// Colors
kids[0]['material.color'] = this.platformColor
Expand All @@ -105,3 +115,10 @@ export class ContentContainer extends Object3DFacade {
}
}

function updateMatrices(obj) {
if (obj.updateMatrices) {
obj.updateMatrices()
obj._checkBoundsChange() //TODO ugh shouldn't have to call private method
}
}

20 changes: 14 additions & 6 deletions packages/troika-xr/src/facade/wrist-mounted-ui/Projection.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,20 @@ export class Projection extends MeshFacade {
this.material = createMaterial()
}

syncSourcePosition() {
// Sync the geometry from the current sourceWorldPosition value
let {sourceWorldPosition:srcPos} = this
let posAttr = this.threeObject.geometry.getAttribute('position')
if (srcPos && posAttr && (
srcPos.x !== posAttr.getX(0) || srcPos.y !== posAttr.getY(0) || srcPos.z !== posAttr.getZ(0)
)) {
posAttr.setXYZ(0, srcPos.x, srcPos.y, srcPos.z)
posAttr.needsUpdate = true
}
}

afterUpdate() {
let {sourceWorldPosition:srcPos, targetVertices, geometry, color} = this
let {targetVertices, geometry, color} = this

// Update geometry vertices
let posAttr = this.geometry.getAttribute('position')
Expand Down Expand Up @@ -127,11 +139,7 @@ export class Projection extends MeshFacade {
}

// Handle changing sourceWorldPosition
if (srcPos.x !== posAttr.getX(0) || srcPos.y !== posAttr.getY(0)
|| srcPos.z !== posAttr.getZ(0)) {
posAttr.setXYZ(0, srcPos.x, srcPos.y, srcPos.z)
posAttr.needsUpdate = true
}
this.syncSourcePosition()

// Material
if (color == null) {
Expand Down
12 changes: 9 additions & 3 deletions packages/troika-xr/src/facade/wrist-mounted-ui/WristMountedUI.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export class WristMountedUI extends Group3DFacade {

let [wristbandDef, contentDef] = children
wristbandDef.active = contentDef.active = this.active
wristbandDef.gripPose = contentDef.gripPose = this.gripPose
//wristbandDef.gripPose = contentDef.gripPose = this.gripPose
contentDef.platformRadius = this.platformRadius
contentDef.platformColor = this.platformColor
contentDef.projectionColor = this.projectionColor
Expand Down Expand Up @@ -97,13 +97,19 @@ export class WristMountedUI extends Group3DFacade {
tempVec3.set(1, 0, 0).applyQuaternion(
tempQuat.setFromRotationMatrix(tempMat4.fromArray(gripPose.transform.matrix))
)
this.active = tempVec3.angleTo(upVec3) < this.activeUpAngle
let active = tempVec3.angleTo(upVec3) < this.activeUpAngle
if (active !== this.active) {
this.active = active
this.afterUpdate()
}
}
}

if (gripPose || !this.gripPose) {
this.gripPose = gripPose
this.afterUpdate()
// Skip full afterUpdate pass, just give the gripPose to children - they both have
// a syncPose method to handle syncing matrices without a full afterUpdate.
this.forEachChild(child => child.syncPose(gripPose))
}
}

Expand Down
20 changes: 14 additions & 6 deletions packages/troika-xr/src/facade/wrist-mounted-ui/Wristband.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,18 @@ const strapWidth = 0.025


export class Wristband extends Group3DFacade {
set gripPose(gripPose) {
/**
* Sync to the current XRFrame's gripPose - all matrix syncing is localized here
* to avoid a full afterUpdate pass on every frame.
*/
syncPose(gripPose) {
if (gripPose) {
this.visible = true
copyXRPoseToFacadeProps(gripPose, this)
this.traverse(updateMatrices)
if (this.onCogMove && this._cogFacade) {
this.onCogMove(this._cogFacade.getWorldPosition(tempVec3))
}
} else {
this.visible = false
}
Expand Down Expand Up @@ -77,11 +85,11 @@ export class Wristband extends Group3DFacade {

return groupDef
}
}

afterUpdate() {
super.afterUpdate()
if (this.onCogMove && this._cogFacade) {
this.onCogMove(this._cogFacade.getWorldPosition(tempVec3))
}

function updateMatrices(obj) {
if (obj.updateMatrices) {
obj.updateMatrices()
}
}

0 comments on commit 4a4cd16

Please sign in to comment.