-
Notifications
You must be signed in to change notification settings - Fork 10
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
Fewer allocations in Frame classes #44
Comments
I'm not sure I follow the part about not being able to inline getter calls. Other than the fact that you're using interfaces, which are obviously going to prevent it. Do you think users will need to switch between I've never been one to try to tie mathematical constructs to a game engine's objects. I'd rather keep them in sync by hand. Though part of that might be that I don't use Flixel or similar. I write all the code to move, rotate, and so on, then once per frame send it to the engine for rendering. If I was relying on the engine to handle more of the logic, I might actually care about integration. Anyway, how about a couple more design options?
|
It has been a while since I thought about this. Coming back to it, I think I was trying to do too many things with a single type. Frames were supposed to accomplish two things:
6+ years later, I think these two concerns should be decoupled. The "Frame" types should only solve representation, and some static adapter class should solve the "sync with existing engines" problem. @player-03 I agree that storing the offset as a Vector2 makes the most sense. All the convenience methods live there already. I also agree that storing it as an explicit member rather than a getter (with slightly weird semantics: see cons of design A) is more straightforward. The performance tradeoff is probably moot in Haxe 4. As for the rotation part, 2x2 matrices don't convert nicely into angles for all cases. FlxSpriteFrame2 is a (admittedly heavy-handed) attempt to have both and keep them in sync with the downside that you can never set the matrix directly. Exposing the matrix means non-uniform scales, reflections, shears, etc. may be specified. Extracting the angle by using atan2 on one of the basis vectors would give a useless result. One of the principles behind hxmath was to design the APIs so that the client code author doesn't need to know about the edge cases to get the math right. There's another option for rotations: rotors, which are generalized quaternions. In 2D they look like one of the basis vectors from the rotation matrix. See http://geocalc.clas.asu.edu/GA_Primer/GA_Primer/introduction-to-geometric/rotors-and-rotations-in-the.html for a short derivation. There are fewer degrees of freedom to deal with, though it is still possible to build a rotor that isn't normalized. Building a rotation matrix of a rotor is trivial as well. The downside is that most engines don't work with rotors, so it might just result in more allocations than it is worth. Summary of options: Option 1: Matrices for concat
Option 2: Motors for concat
|
Wow, that was a rabbit hole. Geometric algebra certainly opens up options. I'd recommend linking to this introductory article as documentation, in addition to or instead of the one you linked above.
But those weird semantics resulted from using a getter, right? If the vector is a normal variable (or
That's why I suggested storing multiple I definitely see where you're coming from - don't give users the option to shoot themselves in the foot if you can avoid it.
More so in 2D than in 3D, but yeah.
From what I've read so far, it sounds like you can use the same underlying type for
I don't think that's true.
As for the big question, I think we should consider use cases. Why go to the trouble of constructing a frame at all? Maybe it's just to store an offset plus rotation and retrieve them later. But more likely, it's for the transformation functionality: you want to convert to/from local coordinates. This functionality either requires a matrix or something equivalent to it (a rotor, a vector's
All of the games I've made thus far fall under use case 3. And even if I made a game where the angle was constantly changing, it'd actually change exactly once per frame, and there would always be at least one coordinate conversion in between, resulting in use case 2. I can't think of an example of use case 1 at the moment (and even if I could, it's easy to store your own float and work around the problem). Conclusion: Option 2C gets my vote. |
I'm weighing the following possible approaches. Design A is what is implemented now. Tangentially related to issue #23 :)
Design A: Complex objects instantiated when getting translation/rotation
Design B: Get/set function adapters for (x, y, rotation) components
Design C: Frame is not an interface but instead contains the (x, y, rotation) components directly
The text was updated successfully, but these errors were encountered: