-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement rotate and scale button functions with bitecs #5993
Conversation
df0c441
to
8ce57a6
Compare
8ce57a6
to
48863f4
Compare
48863f4
to
3c897c0
Compare
Ready for review. |
|
||
AFRAME.registerComponent("scale-button", { | ||
init() { | ||
this.handler = new ScalingHandler(this.el.object3D, this.el.sceneEl.systems["transform-selected-object"]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not familiar with A-Frame component/system lifecycles. Is it safe to assume that transform-selected-object
system is already registered here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks.
And if I'm right, system seems to be registered to sceneEl.systems
when AFRAME.registerSystem
is called (when a file is imported) while Component.init()
seems to be called later (when the component first initialized?). So probably it is safe to assume here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, just a few nits. The menu placement improvements can probably be addressed in a follow-up.
src/bit-systems/object-menu.ts
Outdated
@@ -1,7 +1,15 @@ | |||
import { defineQuery, entityExists, hasComponent } from "bitecs"; | |||
import { Matrix4, Vector3 } from "three"; | |||
import { addComponent, defineQuery, enterQuery, entityExists, exitQuery, hasComponent } from "bitecs"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
addComponent
and path
import are not used anymore
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, updated.
src/bit-systems/object-menu.ts
Outdated
const _mat4 = new Matrix4(); | ||
|
||
// TODO: Avoid any |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why can't this be of type ScalingHandler
?
let scalingHandler: ScalingHandler | null = null;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch, updated.
@@ -39,10 +54,69 @@ function moveToTarget(world: HubsWorld, menu: EntityID) { | |||
const targetObj = world.eid2obj.get(ObjectMenu.targetRef[menu])!; | |||
targetObj.updateMatrices(); | |||
|
|||
// TODO: position the menu more carefully... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should probably do this before removing the newLoader flag, the menu interesects with the objects pretty easily. We can do it in follow-up PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can do it in follow-up PR.
Yes, that's the plan.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should probably just aim for roughly what we have now in terms of menu positioning, we still would like to ultimately not have these in world object menus in their current form on most platforms. On desktop and mobile we likely end up with more traditional 2d context menus, and in VR we likely don't need most of what the menus do since direct manipulation is perdurable (we still need to figure out what to do with the rest of the options)
src/bit-systems/object-menu.ts
Outdated
} | ||
|
||
// TODO: startRotation/Scaling() and stopRotation/Scaling() are | ||
// temporarl implementation that rely on the old systems. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
temporarl -> temporary
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, updated.
src/bit-systems/object-menu.ts
Outdated
// TODO: Don't use any | ||
// TODO: Remove the dependency with AFRAME |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you want avoid using any and avoid using the AFRAME
symbol you can also use:
APP.scene!
and the add the type to the aframe.d.ts
:
interface TransformSelectedObjectSystem extends ASystem {
startTransform(Object3D, EntityID, any): void;
stopTransform(): void;
}
interface AScene extends AElement {
object3D: Scene;
renderStarted: boolean;
renderer: WebGLRenderer;
tick(time: number, delta: number): void;
isPlaying: boolean;
behaviors: {
tick: AComponent[];
tock: AComponent[];
};
systemNames: Array<keyof AScene["systems"]>;
systems: {
"hubs-systems": HubsSystems;
"personal-space-bubble": PersonalSpaceBubbleSystem;
"transform-selected-object": TransformSelectedObjectSystem;
userinput: UserInputSystem;
/** @deprecated see bit-interaction-system */
interaction: InteractionSystem;
nav: NavSystem;
};
emit(string, any?): void;
addState(string): void;
is(string): boolean;
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are some other bitecs systems that have AFRAME dependency. I hope we will work on it when we remove the dependency.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree with Manuel that just adding the type to the aframe.d.ts would be nice. Its fairly minor either way but prevents from making some accidental mistakes leaking the any around.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, two developers suggested the same thing. And the change is minor. Updated.
src/bit-systems/object-menu.ts
Outdated
// TODO: Don't use any | ||
// TODO: Remove the dependency with AFRAME |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here
src/bit-systems/object-menu.ts
Outdated
scalingHandler.startScaling(world.eid2obj.get(rightCursorEid)); | ||
} | ||
|
||
function stopScaling(world: HubsWorld, targetEid: EntityID) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
targetEid
doens't seem to be needed anymore.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch, updated.
3f33f1a
to
326fb66
Compare
This PR needs to be unlocked by the reviewers to get merged. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good. Made a few comments but most are just observations or thoughts I had while reviewing and not really suggestions for changes.
@@ -39,10 +54,69 @@ function moveToTarget(world: HubsWorld, menu: EntityID) { | |||
const targetObj = world.eid2obj.get(ObjectMenu.targetRef[menu])!; | |||
targetObj.updateMatrices(); | |||
|
|||
// TODO: position the menu more carefully... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should probably just aim for roughly what we have now in terms of menu positioning, we still would like to ultimately not have these in world object menus in their current form on most platforms. On desktop and mobile we likely end up with more traditional 2d context menus, and in VR we likely don't need most of what the menus do since direct manipulation is perdurable (we still need to figure out what to do with the rest of the options)
src/bit-systems/object-menu.ts
Outdated
// TODO: Don't use any | ||
// TODO: Remove the dependency with AFRAME |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree with Manuel that just adding the type to the aframe.d.ts would be nice. Its fairly minor either way but prevents from making some accidental mistakes leaking the any around.
// TODO: Remove the dependency with AFRAME | ||
const transformSystem = (AFRAME as any).scenes[0].systems["transform-selected-object"]; | ||
const physicsSystem = AFRAME.scenes[0].systems["hubs-systems"].physicsSystem; | ||
physicsSystem.updateBodyOptions(Rigidbody.bodyId[targetEid], { type: "kinematic" }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not something to address here but just to get it bouncing around in everyone's head. We change these physics properties pretty arbitrarily all over and its very easy for things to end up in weird states and to overwrite one system's desired physics settings with another. We need to think of how to manage that. It mostly comes about when something wants to set the position/rotation of a physics object since it must be kinematic or static to do so, but then it needs to be able to return to its previous state.
handleClicks(world, menu, hubChannel); | ||
|
||
heldExitQuery(world).forEach(eid => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My first thought would have been to do hasComponent(world, Held, ObjectMenu.rotateButtonRef[menuEid)
comparison to the current transform system state.
Using quires is fine, and maybe its nice that the previous frame state is handled by the enter/exit queries but just noting. Not sure which I like better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can understand.
Using hasComponent(world, Held, ObjectMenu.rotateButtonRef[menuEid])
may be more efficient because Held
component may be a common Component so heldQuery
might include a way more entity ids than needed here.
But it required to manage previous frame state. I want to avoid to manage a previous frame state in a system for simplicity.
Using queries may be inefficient but we don't need to manually manage previous frame state so it is simpler.
I want to go as is for now. We may revisit later if we face performance problem.
src/prefabs/object-menu.tsx
Outdated
@@ -198,6 +199,8 @@ function ScaleButton(props: Attrs) { | |||
height={buttonHeight} | |||
type={BUTTON_TYPES.ACTION} | |||
text={"scale"} | |||
holdable | |||
holdableButton |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bit weird to have to specify holdableButton
on a Button3D
should probably be handled in Button3D
based on just holdable
.
The disconnect between things being components and things just being properties to a JSX function here is definitely something I don't love, but its just how JSX works. Like here "height" is not a component nor is "text".
I think mixing components "holdable" and "holdableButton" into it makes it even more confusing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated to remove holdableButton
here.
if (!(NAF.utils.isMine(this.networkedEl) || NAF.utils.takeOwnership(this.networkedEl))) { | ||
return; | ||
} | ||
startScaling(object3D) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is temporary transition code so it doesn't really matter much, but we might try to name this parameter a bit better. Maybe cursorObj? interactor?
} | ||
|
||
function stopScaling(world: HubsWorld) { | ||
const rightCursorEid = anyEntityWith(world, RemoteRight)!; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not a suggestion for here but reminds me of an observation I want us to think about.
I find it annoying that we don't have a good way to statically define references like this and have to "look them up" every frame with a query like this. Its not particularly expensive or anything, just silly because we actually know what number entity this is going to be every time. The only thing really stopping us from doing it is module loading order.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't love anyEntityWith()
. Added this topic in the internal design document.
96bc1c1
to
a76fef2
Compare
a76fef2
to
ee1eeed
Compare
This commit adds the implementations of Object menu rotate and scale button functions. Note that this commit focuses on making them just functional with minimal change. The implementation relys on the old systems to save development time. It should be rewritten more elegantly to fit more to bitECS. The main logic of src/components/scale-button is exposed to be reused from the new and old systems.
ee1eeed
to
aa42562
Compare
This commit adds the implementations of Object menu rotate and scale button functions.
Note that this commit focuses on making them just functional with minimal change.
The implementation relys on the old systems to save development time. It should be rewritten more elegantly to fit more to bitECS.
The main logic of src/components/scale-button is exposed to be reused from the new and old systems.