Author Topic: Object Rotation feature: looking for opinions  (Read 610 times)

Crimson Wizard

  • Local Moderator
    • Lifetime Achievement Award Winner
    • Best Innovation Award Winner 2013, for spearheading the AGS 3.3.0 project
    • Crimson Wizard worked on one or more games that won an AGS Award!
    •  
    • Crimson Wizard worked on one or more games that was nominated for an AGS Award!
Object Rotation feature: looking for opinions
« on: 01 Apr 2021, 15:21 »
So, I have a object rotation feature in works, as may be seen here.

Currently it adds Rotation property to several object types, which define angle rotation of rotation in degrees. Rotation is performed around the center of the image at the moment, but I also had thought of adding configurable Pivot position at least for some of them.

There are few images demonstrating it in action (includes GIFs, so may take time to load) -
Spoiler: ShowHide









A working test version:
Spoiler: ShowHide

A working test version, if anyone want to try out how it works:
https://www.mediafire.com/file/zn338ao4mhgtxwu/AGS-3.99.99.0-ROTATION.zip/file

Warning!!!: this is an experimental version of AGS 4 that has number of other changes, and saving game project there will make it incompatible with current official releases.
Also it's not final, so not 100% guaranteed to keep things as they are.


Rotation is done using following properties:
* GUI.Rotation
* Overlay.Rotation
* Camera.Rotation
* Character.GraphicRotation
* Object.GraphicRotation


Technically all this works, and may be adjusted further. There is a number of problems related to this. I have my own ideas, but would like to know other people opinions too.
But I must explain few things first.



Sprite rotation vs full object rotation

Most of the game objects are more than just a sprite, they contain several "functions".
For example: Room Object displays a sprite, but also can calculate path and move along walkable area, and also block walkable areas and collide with other objects and characters.
Characters can move in walkable areas, they can block and collide, but they may also turn around switching to different loops, have speech, inventory, and so on.

If we take geometrical transformation, such as Scale and Rotation, these may be applied strictly to object's sprite, but they may be also applied to other object's functions where makes sense.
For example, Objects and Characters have a blocking rectangle which tells which part of walkable area they block. When Scaling is applied, this blocking rectangle is also scaled along with the sprite. But what if you don't want blocking to be aligned with the sprite? then you may override that with BlockingWidth/BlockingHeight properties (I'd leave convenience question out in this topic).
So, technically, blocking rectangle and sprite are not same thing, they are separate components of an object, that optionally may be aligned, but not necessarily.
In ideal world we may say that there is a Object's or Character's own scaling which defines its "physical" contact with the room, and there's sprite's scaling which defines only its visual representation.
Spoiler: ShowHide

I say "in ideal world", because in AGS these things are never fully consistent. For example "Object.IsCollidingWithObject" ignores blocking rectangle and test only sprites. "Character.IsCollidingWithChar" tests sprite widths but not heights, and only succeeds if their Y coordinates are close enough.
And "Character.IsCollidingWithObject" is the weirdest of all, because it also tests for object's transparent pixels, which none of above does.
This is why it's difficult to compare what AGS does with contemporary game engines 1:1.


Now we come to Rotation.
If we take sprite-only rotation, that's seemingly easy case, as we may rotate it as we please and that supposedly should not affect anything but the visuals.
The following image demonstrates rotation of character sprite by 90 degrees around its center.


(sorry if it's not precise, I was just making crude mockups to save time)
(NOTE: all images are posted using imgzoom so you may select their zoom multiplier by hovering mouse under them)

Notice the character's "origin" point though - that's the point aligned with Character's own coordinates (x and y). It remains on same place, and if we change character's position that will be position of origin point, not the chacter's feet anymore.
Human-like sprite may not be the simpliest to realize how this works as we used to have its feet aligned to its position in the room. So let's change it to this "wheel" like character that rotates as it moves around (this is just a random example).



We may also introduce something called "Pivot". That's a relative point which serves a center of rotation. Good example is this bell object. Compare sprite rotation around its center and around custom pivot:



Notice still the object's origin does not change, it's positioned same way, then the sprite is positioned relatively to object's origin using pivot and rotation.



Now, above only sprite was rotated. This means that, for example, blocking rectangle won't be. This is a difference between whole object rotation and sprite rotation in practice.
If we rotate whole object then all of its components that have geometric meaning will be affected as well.

But how do we rotate whole object, do we use sprite's center as a point of rotation too? The thing is that sprite's center is an arbitrary point, not really related to object's position.
Previously I mentioned "origin" point - that's the point at object's coordinates. The sprite is aligned to that origin according to engine rules. For example, for Room Object sprite is aligned to origin by its left-bottom corner, for Character sprite is aligned to origin by its middle-bottom point. GUI surface is aligned by left-top corner.

This "origin" is the main point of an object, and all object's geometry is placed around it. Therefore, if we rotate whole object, it should be rotated also around same "origin" point. And there cannot be any custom pivots in this case.
For example, this is how the full rotation of a Character would look like:



Notice blocking rectangle (painted with blue lines) is also rotated.

Continuing, we may actually imagine applying both object rotation and sprite rotation simultaneously. In such case sprite rotation will be applied relative to object rotation.
For example, this is how it would look like if we rotate full object by 90 degrees and then sprite by 90 degrees (using sprite center as a pivot):




To sum up, theoretically there may be purpose for separating object own rotation and its sprite rotation, and use cases for both.
In some cases combining these two may look pretty unusual and confusing. One example is GUI. Controls are part of the object itself, therefore their position should depend on GUI own rotation. Thus in case of GUI the "sprite rotation" is perhaps applied not to whole GUI visuals, but only to its background image.
In case of GUI rotation there's another problem though related to its origin, which I discuss separately below.


There's also a question of how to distinct object's own transformation properties and it's sprite transformation properties.
Supposing we already have Character.Scaling and as mentioned above this property results not only in scaled sprite but also in scaled blocking rectangle.
If we keep same naming idea, the Character.Rotation should mean full object rotation.
Then properties for transforming sprite only could be named SpriteScaling and SpriteRotation, or for slightly shorter names - SpriteScale and SpriteRotate (NOTE: actually it could be SpriteScaleX and SpriteScaleY for separate scaling by X and Y axes, but that's another topic).



Object's own pivot problem

As said before each game object has its own "origin" - this is a point that corresponds to its coordinate properties (x,y). Everything else is aligned in relation to this origin somehow.

For historical reasons, and also because AGS was meant to simulate classic P'n'C games, objects are refering to origin like this:
* GUI, gui Controls, Overlays (also Viewport and Camera since AGS 3.5.0): as a left-top corner;
* Room Objects: as a left-bottom corner;
* Characters: as a middle-bottom point.

Or, if we look at it from opposite perspective, object components are positioned:
* GUI etc: right-below from origin;
* Room Objects: right-above from origin;
* Characters: centered horizontally and above origin.

In the example of Character's own rotation posted above I showed what would happen if own rotation was using origin as a pivot. In case of Character, and maybe Object too, that seem to make sense and is convenient at first, as their origin is logically where they touch "floor" in a side-view games. So rotating Character by 90 degrees would make it work like its walking on a vertical wall, and rotating Character by 180 degrees would make it work like its walking on a celing.

Things become bit more complicated if, for instance, we want a top-down game. In such case side-view logic no longer makes sense. Even now without any rotation one would have to adjust sprite relative to character's position to make it centered around it. Vertically this may be done using "z" property which conveniently exists and works as a vertical sprite offset. There's also Character.LockViewOffset that allows to set both X and Y sprite offsets, which would be convenient if we also rotate the object.
Thankfully blocking rectangle is positioned centered on Character's origin, which is very convenient actually (not that rectangle itself is conveniently customized though). So we don't have to worry to offset it also. It even will keep working when rotating. For Room Object situation may be different, as blocking rect is positioned to the right from the origin, just like its sprite.

However, if we take GUI, or Overlay, or even Camera, here rotating around origin becomes quite questionable. Because their origin is at the top-left corner, and this is how we visually imagine them being moved around, rotating around same point would produce... unexpected and inconvenient results. Basically, GUI rotated around origin may suddenly appear above it, or to the opposite side horizontally, which makes its positioning on screen one hell of a job.

This makes me wonder if GUI and GUI-like objects should rather have not their origin, but their geometric center as a pivot of rotation. Conveniently these have explicit Width and Height properties; unlike Character or Room Object which do not have any persistent "size", and depend on their current sprite.
« Last Edit: 23 Apr 2021, 00:54 by Crimson Wizard »

eri0o

Re: Object Rotation feature: looking for opinions
« Reply #1 on: 01 Apr 2021, 17:24 »
About sprite rotation, maybe instead if it's on a viewframe (like flipped), it would work like that? (Say if a viewframe had an angle and pivot property...)

I liked your bell example because I think someone here in the forums actually did something like that in a game - but using the DynamicSprite feature.

If defaults are preferable instead of manual configuration, then geometric center for everything may be the best option, with the Angle being in Radians so it's easy to interface with current Maths functions!
« Last Edit: 01 Apr 2021, 17:56 by eri0o »

Re: Object Rotation feature: looking for opinions
« Reply #2 on: 04 Apr 2021, 02:59 »
Objects and GUIs live in different, incomparable worlds. As we know, objects are part of a 3-d world, which is "filmed" into a 2-d screen. Then, the GUIs are placed ("overlaid") onto this 2-d screen. In this 2-d screen, we have a "desktop/icons" type of environment whilst in the game proper, we have a 3-d environment (represented in 2-d).

In an analogue world, designing a GUI would be akin to designing a scrap book or photo album page. The "video screen", in which the game proper plays, is akin to the album page background. You can tape paper flowers on top of this or photos or write spiffy texts. Those would be akin to the GUIs or GUI elements. The "origin" of a button is a point to reference the button by; it's a convenient way to specify where the button is located in relation to other buttons on the "album page".

But there's no reason whatsoever to assume that this point of all points should be preferable as a pivot for rotation. It even seems far-fetched and contrived: I can imagine writing some tilted text into a photo album. I can imagine conceptualizing this as writing it upright and then tilting it. But in this case I'd never think of of it as tilting the text by its upper-left corner. Most "natural" for me would probably be the centre point, but I can imagine other situations where I'd want to turn around another pivots. But never around the top-left corner.


A point can be made that designers might prefer the origin of a character as a turning pivot in the 3-d world. But you've already pointed out that it wouldn't be so natural with, e.g., church bells. And even a human character that is turning cartwheels or doing gymnastics at a bar would have another pivot than the middle of their base line.

Probably the simplest and sanest would be to not assume anything and to always ask the user, i.e., make the pivot an argument of the rotation function. If it turns out to be hard to fill this parameter, e.g., because characters can be scaled, then _this_ is the underlying problem that needs to be solved. Instead of assuming that characters would "want" to be rotated around their origin, we should introduce Character.Width and Character.Height attributes so that the pivot parameters of the rotating function can be filled sensibly.

(Ceterum censeo: And we should strive in AGS 4, to make all those pesky differences between objects and characters go away. For instance, Character should have capitalized X, Y, Z fields -- all the fields of all AGS entities should be uniformly in capitalized camel case without exceptions --; Character.on should be capitalized (!) and renamed/repurposed to something like Character.Enabled and Character.Visible -- or else Objects given a Transparency; Object.IgnoreScaling and Character.ManualScaling should be unified to the same field name; the origin of characters and objects should be made the same -- probably middle of base in both cases --, etc. That's been bugging me for years.)
« Last Edit: 04 Apr 2021, 05:14 by fernewelten »

Cassiebsg

  • Cavefish
  • Fleeing the Cylon tyrrany...
    • Cassiebsg worked on one or more games that won an AGS Award!
    •  
    • Cassiebsg worked on one or more games that was nominated for an AGS Award!
Re: Object Rotation feature: looking for opinions
« Reply #3 on: 04 Apr 2021, 09:16 »
Actually I think it should default to center, but have the option to pick x,y relation to the sprite (maybe from it's center, for easy reference), if the dev does not want to use the center.

Why? Cause it's easier to make your sprite ready to rotate in the middle (when designing it) and will of course simplify ones coding. But allowing to specify a x,y will allow the dev to rotate it from wherever he wants/needs it to rotate... even if it's outside the sprite... imagine your object/character got stuck on a giant wheel and it's now rotating around the center of that wheel. It can allow for creating easy rotations with a lot less complicated code.  ;)
There are those who believe that life here began out there...

Crimson Wizard

  • Local Moderator
    • Lifetime Achievement Award Winner
    • Best Innovation Award Winner 2013, for spearheading the AGS 3.3.0 project
    • Crimson Wizard worked on one or more games that won an AGS Award!
    •  
    • Crimson Wizard worked on one or more games that was nominated for an AGS Award!
Re: Object Rotation feature: looking for opinions
« Reply #4 on: 06 Apr 2021, 13:49 »
Thank you for feedback.

About sprite rotation, maybe instead if it's on a viewframe (like flipped), it would work like that? (Say if a viewframe had an angle and pivot property...)

This is an interesting proposal. Such frame configuration may be useful on its own, but there's a reason I doubt this may be an equivalent to having sprite rotation on an object itself. If user will want to just smoothly rotate the object's sprite, with view frames they would have to either:
- make 1 frame and programmatically change that frame's angle; this is kind of clunky approach, plus will complicate things if same view may be shared by several objects.
- make several frames with gradually changing angle; this is extra work (and extra view/loop/frames) compared to simply having a property on object.
Then, Room Objects also have Graphic property for setting single sprite, as opposed to a View.

Still, speaking hypothetically, frames may have rotation and other settings too as a way to accomodate certain sprite for different kinds of situations, similar to how flip works. There may even be kind of inheritance of transformations defined by view -> loop -> frame each adding something.

with the Angle being in Radians so it's easy to interface with current Maths functions!

This is a tough choice...  I did rotation property in degrees now as that seemed more convenient for users to put literal values in editor and with script commands. I guess majority of people who use AGS can imagine angles like 45, 60, 90, 180 degrees etc, but don't think they would like to enter this in radians (i only know 3.14 is half circle and 6.28 is full circle, because Pi). For math calculations in script degress may be still converted to radians and vice versa.
Then again, maybe it's possible to make two-variant property editor for entering either degrees or radians, and make them use DegreesToRadians when setting rotation in script... idk if it's a good idea.


A point can be made that designers might prefer the origin of a character as a turning pivot in the 3-d world. But you've already pointed out that it wouldn't be so natural with, e.g., church bells. And even a human character that is turning cartwheels or doing gymnastics at a bar would have another pivot than the middle of their base line.

I got bit concerned that there may be misunderstanding here, so would like to clarify just in case. I've been talking about two kinds or types of rotations: full object rotation and sprite-only rotation, with full-object rotation pivoting around origin and sprite rotation pivoting around custom point which defaults to center (at least according to the initial idea).

Probably the simplest and sanest would be to not assume anything and to always ask the user, i.e., make the pivot an argument of the rotation function.

Well, Rotation is made not as a function but as a property, otherwise it will be impossible to set in editor. Of course if pivot is a property too, then there's always an accessible argument for user to set if they want to. The question is mostly in convenient defaults.
In regards to pivot property, there are other considerations...

If it turns out to be hard to fill this parameter, e.g., because characters can be scaled, then _this_ is the underlying problem that needs to be solved. Instead of assuming that characters would "want" to be rotated around their origin, we should introduce Character.Width and Character.Height attributes so that the pivot parameters of the rotating function can be filled sensibly.

First of all, this is an interesting question of whether pivot is set in unscaled or scaled sprite coordinates. I did not think about this earlier. Guess if it's set in scaled coordinates then it may be more precise.

But there's another method of setting a pivot, which is used in most modern engines: instead of using pixel position it's set in relative floating-point range from 0,0 to 1,1. For example 0.5,0.5 would mean center, 0.5,0.0 would mean top-center, 1.0,0.5 - right-middle, and so on. Such format would let user to quickly set up most common pivot positions without manually calculating pixels.
We were discussing this with Alan Drake a while ago, and wonder if it's possible to let user enter pivot position in both of these formats (precise pixel and relative). The only issue is to find a good API for this.

Speaking of Character.Width and Character.Height, these may be an interesting addition, and also  would make it easier to manually scale characters by setting wanted final size rather than trying to guess percentage of scaling. The problem with this is that these would require changing how character visual size is determined, because right now their width and height is fully dependent on immediate sprite, and if View frames have sprites of different sizes the character will enlarge and shrink as it animates.


One last thing that I might add, we also spoke about introducing sprite's Anchor property. Basically it's the point in sprite which corresponds to game object's origin. This is what is currently defined as center-bottom for characters, for instance. If this was also a property then user would be able to make character sprites attached from different "side" to its origin (like, make it be below character's coordinates, instead of above).
« Last Edit: 06 Apr 2021, 13:52 by Crimson Wizard »

eri0o

Re: Object Rotation feature: looking for opinions
« Reply #5 on: 06 Apr 2021, 18:20 »
Oh, this anchor point would be useful for scale! (scaling am object in ags4 are weird since left corner is the "origin" in it)
« Last Edit: 06 Apr 2021, 19:36 by eri0o »

Crimson Wizard

  • Local Moderator
    • Lifetime Achievement Award Winner
    • Best Innovation Award Winner 2013, for spearheading the AGS 3.3.0 project
    • Crimson Wizard worked on one or more games that won an AGS Award!
    •  
    • Crimson Wizard worked on one or more games that was nominated for an AGS Award!
Re: Object Rotation feature: looking for opinions
« Reply #6 on: 06 Apr 2021, 20:40 »
Oh, this anchor point would be useful for scale! (scaling am object in ags4 are weird since left corner is the "origin" in it)

I was actually wondering about fernewelten's proposal to make Room Object have same origin as a character, horizontally centering by default. That would solve autoscaling issue for objects. But on the other hand it will require user to readjust room design process. And in many cases it could be simplier to set up object position by the corner, maybe even top-left corner depending on the scene.

Crimson Wizard

  • Local Moderator
    • Lifetime Achievement Award Winner
    • Best Innovation Award Winner 2013, for spearheading the AGS 3.3.0 project
    • Crimson Wizard worked on one or more games that won an AGS Award!
    •  
    • Crimson Wizard worked on one or more games that was nominated for an AGS Award!
Re: Object Rotation feature: looking for opinions
« Reply #7 on: 16 Apr 2021, 03:05 »
Perhaps, considering idea of division between object rotation and sprite rotation, I could do following for now:

GUI, Overlays and Cameras will have property Rotation, because they are rotated as whole objects. But their default pivot is at object center, because it's just easier to align them that way.
Characters and Room Objects will have property GraphicRotation, because they rotate only their graphical representation at the moment. This is to keep free property name "Rotation" in case we'll support full object rotation someday (with blocking box etc). The graphic rotation of chars and roomobjects will also have default pivot at their center, as that again seems like easiest to expect and accomodate.

I do not add pivot property at the moment, because it's bit complicated, we need to think how to conveniently support two methods of setting pivot (mentioned above). But maybe that will come too after a short term.

Meanwhile it will be still possible to "simulate" rotation around different pivot if you rotate by default and adjust object's position using math. Not the ideal solution, but should work with proper formula.
« Last Edit: 16 Apr 2021, 03:13 by Crimson Wizard »

eri0o

Re: Object Rotation feature: looking for opinions
« Reply #8 on: 16 Apr 2021, 13:28 »
About the origin point, when objects are used for actual small objects in the room, the middle bottom is more convenient. When objects are used for things that are not in the same "plane" of characters, meaning things on the background or in the foreground, then the current left corner is more convenient.

Crimson Wizard

  • Local Moderator
    • Lifetime Achievement Award Winner
    • Best Innovation Award Winner 2013, for spearheading the AGS 3.3.0 project
    • Crimson Wizard worked on one or more games that won an AGS Award!
    •  
    • Crimson Wizard worked on one or more games that was nominated for an AGS Award!
Re: Object Rotation feature: looking for opinions
« Reply #9 on: 23 Apr 2021, 00:51 »
A working test version, if anyone want to try out how it works:
https://www.mediafire.com/file/zn338ao4mhgtxwu/AGS-3.99.99.0-ROTATION.zip/file

Warning!!!: this is an experimental version of AGS 4 that has number of other changes, and saving game project there will make it incompatible with current official releases.
Also it's not final, so not 100% guaranteed to keep things as they are.


Rotation is done using following properties:
* GUI.Rotation
* Overlay.Rotation
* Camera.Rotation
* Character.GraphicRotation
* Object.GraphicRotation

« Last Edit: 23 Apr 2021, 00:53 by Crimson Wizard »

eri0o

Re: Object Rotation feature: looking for opinions
« Reply #10 on: Today at 11:08 »
Hey, you know how the character scaling has an option to make it pixel perfect? Is there a way to have such option for the rotation too? (Or use the same option for this)

Edit: Scratch that, it's already working like this! Just tested and it's beautiful!

A heads up, the package requires placing the SDL2.dll file in the Compiled/Windows directory on Windows. You can download from here: https://www.libsdl.org/release/SDL2-2.0.14-win32-x86.zip
« Last Edit: Today at 13:06 by eri0o »

Crimson Wizard

  • Local Moderator
    • Lifetime Achievement Award Winner
    • Best Innovation Award Winner 2013, for spearheading the AGS 3.3.0 project
    • Crimson Wizard worked on one or more games that won an AGS Award!
    •  
    • Crimson Wizard worked on one or more games that was nominated for an AGS Award!
Re: Object Rotation feature: looking for opinions
« Reply #11 on: Today at 15:03 »
Hey, you know how the character scaling has an option to make it pixel perfect? Is there a way to have such option for the rotation too? (Or use the same option for this)

"Render sprites at screen resolution" should control this, "smooth scaled sprites" is an option that passes a sprite through linear filter but I haven't tested it for a while. I now wonder if these options duplicate each other by result, and if it may make sense to remove the latter (because "smooth scaled sprites" likely not work well if sprites are rendered in native res).
« Last Edit: Today at 15:04 by Crimson Wizard »

eri0o

Re: Object Rotation feature: looking for opinions
« Reply #12 on: Today at 15:20 »
Yeahp, it's Render sprites at screen resolution (render_at_screenres) the right name, and it does work! When I asked I hadn't tried it yet but just after that I correctly used and it worked!