Open donmccurdy opened 2 years ago
Hey @donmccurdy, this makes sense! The PR is definitely welcome! So to summarize, we take input in degrees and store and sterilize in radians, right?
Ultimately the goal is that while we should always serialize to a canonical unit (in this case radians), we could support data entry and display in different units, like degrees for rotation, km for translation, or F for temperature, if someone makes a custom prop for that sometime. :D
So to summarize, we take input in degrees and store and sterilize in radians, right?
If there's some reason it's better to store degrees (I don't know of any) I'd be open to that approach too. But yes — "input and display in degrees, store in radians" sounds great.
This isn't my use case at the moment, but I could easily imagine needing a similar solution for interpolating color, e.g. input and display in sRGB, store and interpolate in Linear-sRGB or ACEScg.
Glad you mentioned this, I already made an internal design doc for the future architecture of props, the current one is only there to serve the most immediate needs. Basically I see 3 different individually configurable aspects to props:
For example in the case of colors, you might want to input it in HLS, interpolate in LAB, and have the output be in sRGB, so even the interpolation could have its own bespoke space to happen in.
None of this is set in stone, just something we are thinking about.
The easy fix of updating a couple lines in @theatre/r3f
would result in storing degrees rather than radians, and I guess would also be backward-incompatible... that's not ideal, correct? Did you have new options in mind for the property API, like this?
export const number = (
defaultValue: number,
opts?: {
nudgeFn?: PropTypeConfig_Number['nudgeFn']
range?: PropTypeConfig_Number['range']
nudgeMultiplier?: number
label?: string
sanitize?: Sanitizer<number>
interpolate?: Interpolator<number>
// ✨ NEW
transformInput: Transform<number>
transformOutput: Transform<number>
},
...
...Or something deeper in the architecture?
Considering this would be a bandaid until we overhaul the deeper architecture a little, which is a bit down the road, it best be arranged at extension level for now. I'd hide it behind a configuration option that defaults to radians to take care of backwards compatibility, should be enough imo.
Just to share another possible difference in handling rotations vs. vectors here – I'm finding it much more natural to keyframe rotations on cameras using the ZYX (roll, yaw, pitch) order rather than XYZ (pitch, yaw, roll). For example, camera.rotation.set(x, y, z, 'ZYX')
.
Using radians to keyframe Euler rotations feels less natural to me, coming from software like Blender where these edits are done in degrees. For example, keyframing to Y=90º is easier than Y=1.5707963. We could change the
@theatre/r3f
bindings to work with Euler rotations (e.g.THREE.Euler
) in degrees, instead. This could potentially just be a UI change, where the keyframe data is still serialized and stored in radians. Would a PR for this change be welcome? Thanks!