mirror of
https://forgejo.xatacraft.ru/Sunshine/mkxp-sunshine.git
synced 2026-08-19 13:29:54 +00:00
viewport rotation
This commit is contained in:
parent
116ba28508
commit
c7bbb02473
5 changed files with 105 additions and 44 deletions
|
|
@ -80,6 +80,7 @@ DEF_PROP_I(Viewport, OY)
|
||||||
|
|
||||||
DEF_PROP_F(Viewport, ScaleX)
|
DEF_PROP_F(Viewport, ScaleX)
|
||||||
DEF_PROP_F(Viewport, ScaleY)
|
DEF_PROP_F(Viewport, ScaleY)
|
||||||
|
DEF_PROP_F(Viewport, Rotation)
|
||||||
|
|
||||||
void viewportBindingInit(){
|
void viewportBindingInit(){
|
||||||
VALUE klass = rb_define_class("Viewport", rb_cObject);
|
VALUE klass = rb_define_class("Viewport", rb_cObject);
|
||||||
|
|
@ -91,12 +92,13 @@ void viewportBindingInit(){
|
||||||
|
|
||||||
_rb_define_method(klass, "initialize", viewportInitialize);
|
_rb_define_method(klass, "initialize", viewportInitialize);
|
||||||
|
|
||||||
INIT_PROP_BIND( Viewport, Rect, "rect" );
|
INIT_PROP_BIND( Viewport, Rect, "rect" );
|
||||||
INIT_PROP_BIND( Viewport, OX, "ox" );
|
INIT_PROP_BIND( Viewport, OX, "ox" );
|
||||||
INIT_PROP_BIND( Viewport, OY, "oy" );
|
INIT_PROP_BIND( Viewport, OY, "oy" );
|
||||||
INIT_PROP_BIND( Viewport, ScaleX, "scale_x");
|
INIT_PROP_BIND( Viewport, ScaleX, "scale_x" );
|
||||||
INIT_PROP_BIND( Viewport, ScaleY, "scale_y");
|
INIT_PROP_BIND( Viewport, ScaleY, "scale_y" );
|
||||||
INIT_PROP_BIND( Viewport, Color, "color" );
|
INIT_PROP_BIND( Viewport, Rotation, "rotation");
|
||||||
INIT_PROP_BIND( Viewport, Tone, "tone" );
|
INIT_PROP_BIND( Viewport, Color, "color" );
|
||||||
|
INIT_PROP_BIND( Viewport, Tone, "tone" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -623,10 +623,14 @@ void Sprite::onGeometryChange(const Scene::Geometry &geo){
|
||||||
* relative to screen origin */
|
* relative to screen origin */
|
||||||
p->trans.setGlobalOffset(geo.offset());
|
p->trans.setGlobalOffset(geo.offset());
|
||||||
Viewport* viewport = ViewportElement::getViewport();
|
Viewport* viewport = ViewportElement::getViewport();
|
||||||
if (viewport)
|
if (viewport) {
|
||||||
p->trans.setGlobalScale(Vec2(viewport->getScaleX(), viewport->getScaleY()));
|
p->trans.setGlobalScale(Vec2(viewport->getScaleX(), viewport->getScaleY()));
|
||||||
else
|
p->trans.setGlobalRotation(viewport->getRotation());
|
||||||
|
}
|
||||||
|
else {
|
||||||
p->trans.setGlobalScale(Vec2(1.0, 1.0));
|
p->trans.setGlobalScale(Vec2(1.0, 1.0));
|
||||||
|
p->trans.setGlobalRotation(0);
|
||||||
|
}
|
||||||
|
|
||||||
p->sceneRect.setSize(geo.rect.size());
|
p->sceneRect.setSize(geo.rect.size());
|
||||||
p->sceneOrig = geo.orig;
|
p->sceneOrig = geo.orig;
|
||||||
|
|
|
||||||
|
|
@ -43,15 +43,17 @@
|
||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// added global rotation and global scale, modified updateMatrix(), using SDL funcs instead of math.h
|
||||||
|
|
||||||
#ifndef TRANSFORM_H
|
#ifndef TRANSFORM_H
|
||||||
#define TRANSFORM_H
|
#define TRANSFORM_H
|
||||||
|
|
||||||
#include "etc-internal.h"
|
#include "etc-internal.h"
|
||||||
|
|
||||||
#include <math.h>
|
|
||||||
#include <SDL3/SDL_stdinc.h>
|
#include <SDL3/SDL_stdinc.h>
|
||||||
|
|
||||||
|
constexpr float PI = 3.14159265358979323846f;
|
||||||
|
|
||||||
class Transform{
|
class Transform{
|
||||||
public:
|
public:
|
||||||
Transform()
|
Transform()
|
||||||
|
|
@ -65,10 +67,12 @@ public:
|
||||||
matrix[15] = 1;
|
matrix[15] = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vec2 &getPosition() { return position; }
|
Vec2 &getPosition() { return position; }
|
||||||
Vec2 &getOrigin() { return origin; }
|
Vec2 &getOrigin() { return origin; }
|
||||||
Vec2 &getScale() { return scale; }
|
Vec2 &getScale() { return scale; }
|
||||||
float getRotation() { return rotation; }
|
Vec2 &getGlobalScale() { return globalScale; }
|
||||||
|
float getRotation() { return rotation; }
|
||||||
|
float getGlobalRotation() { return globalRotation; }
|
||||||
|
|
||||||
Vec2i getPositionI() const{
|
Vec2i getPositionI() const{
|
||||||
return Vec2i(position.x, position.y);
|
return Vec2i(position.x, position.y);
|
||||||
|
|
@ -98,6 +102,11 @@ public:
|
||||||
dirty = true;
|
dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setGlobalRotation(float value){
|
||||||
|
globalRotation = value;
|
||||||
|
dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
void setGlobalOffset(const Vec2i &value){
|
void setGlobalOffset(const Vec2i &value){
|
||||||
offset = value;
|
offset = value;
|
||||||
dirty = true;
|
dirty = true;
|
||||||
|
|
@ -119,33 +128,65 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateMatrix(){
|
void updateMatrix(){
|
||||||
if (rotation >= 360 || rotation < -360)
|
if (rotation >= 360 || rotation < -360)
|
||||||
rotation = (float) SDL_fmod(rotation, 360);
|
rotation = (float)SDL_fmod(rotation, 360);
|
||||||
if (rotation < 0)
|
|
||||||
rotation += 360;
|
if (globalRotation >= 360 || globalRotation < -360)
|
||||||
|
globalRotation = (float)SDL_fmod(globalRotation, 360);
|
||||||
float angle = rotation * 3.141592654f / 180.0f;
|
|
||||||
float cosine = (float) SDL_cos(angle);
|
// object rotation cos and sin
|
||||||
float sine = (float) SDL_sin(angle);
|
float angle = rotation * PI / 180.0f;
|
||||||
float sxc = scale.x * cosine;
|
float cosine = SDL_cos(angle);
|
||||||
float syc = scale.y * cosine;
|
float sine = SDL_sin(angle);
|
||||||
float sxs = scale.x * sine;
|
|
||||||
float sys = scale.y * sine;
|
float sxc = scale.x * cosine;
|
||||||
float tx = (-origin.x * sxc - origin.y * sys + position.x) * globalScale.x + offset.x;
|
float syc = scale.y * cosine;
|
||||||
float ty = ( origin.x * sxs - origin.y * syc + position.y) * globalScale.y + offset.y;
|
float sxs = scale.x * sine;
|
||||||
|
float sys = scale.y * sine;
|
||||||
matrix[0] = sxc * globalScale.x;
|
|
||||||
matrix[1] = -sxs * globalScale.y;
|
// object matrix
|
||||||
matrix[4] = sys * globalScale.x;
|
float a = sxc * globalScale.x;
|
||||||
matrix[5] = syc * globalScale.y;
|
float b = -sxs * globalScale.y;
|
||||||
matrix[12] = tx;
|
float c = sys * globalScale.x;
|
||||||
matrix[13] = ty;
|
float d = syc * globalScale.y;
|
||||||
|
|
||||||
|
float tx = (-origin.x * sxc - origin.y * sys + position.x)
|
||||||
|
* globalScale.x;
|
||||||
|
|
||||||
|
float ty = ( origin.x * sxs - origin.y * syc + position.y)
|
||||||
|
* globalScale.y;
|
||||||
|
|
||||||
|
// viewport rotation cos and sin
|
||||||
|
float globalAngle = globalRotation * PI / 180.0f;
|
||||||
|
float gc = SDL_cos(globalAngle);
|
||||||
|
float gs = SDL_sin(globalAngle);
|
||||||
|
|
||||||
|
// basis rotation
|
||||||
|
float na = a * gc - b * gs;
|
||||||
|
float nb = a * gs + b * gc;
|
||||||
|
float nc = c * gc - d * gs;
|
||||||
|
float nd = c * gs + d * gc;
|
||||||
|
|
||||||
|
float dx = tx;
|
||||||
|
float dy = ty;
|
||||||
|
|
||||||
|
// appling global rotation
|
||||||
|
tx = dx * gc - dy * gs + offset.x;
|
||||||
|
ty = dx * gs + dy * gc + offset.y;
|
||||||
|
|
||||||
|
matrix[0] = na;
|
||||||
|
matrix[1] = nb;
|
||||||
|
matrix[4] = nc;
|
||||||
|
matrix[5] = nd;
|
||||||
|
matrix[12] = tx;
|
||||||
|
matrix[13] = ty;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vec2 position;
|
Vec2 position;
|
||||||
Vec2 origin;
|
Vec2 origin;
|
||||||
Vec2 scale;
|
Vec2 scale;
|
||||||
float rotation;
|
float rotation;
|
||||||
|
float globalRotation;
|
||||||
|
|
||||||
/* Silently added to position */
|
/* Silently added to position */
|
||||||
Vec2i offset;
|
Vec2i offset;
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,7 @@ struct ViewportPrivate{
|
||||||
|
|
||||||
double scaleX;
|
double scaleX;
|
||||||
double scaleY;
|
double scaleY;
|
||||||
|
double rotation;
|
||||||
|
|
||||||
EtcTemps tmp;
|
EtcTemps tmp;
|
||||||
|
|
||||||
|
|
@ -56,6 +57,7 @@ struct ViewportPrivate{
|
||||||
tone(&tmp.tone),
|
tone(&tmp.tone),
|
||||||
scaleX(1.0),
|
scaleX(1.0),
|
||||||
scaleY(1.0),
|
scaleY(1.0),
|
||||||
|
rotation(0.0),
|
||||||
isOnScreen(false)
|
isOnScreen(false)
|
||||||
{
|
{
|
||||||
rect->set(x, y, width, height);
|
rect->set(x, y, width, height);
|
||||||
|
|
@ -139,8 +141,9 @@ void Viewport::update(){
|
||||||
DEF_ATTR_RD_SIMPLE(Viewport, OX, int, geometry.orig.x)
|
DEF_ATTR_RD_SIMPLE(Viewport, OX, int, geometry.orig.x)
|
||||||
DEF_ATTR_RD_SIMPLE(Viewport, OY, int, geometry.orig.y)
|
DEF_ATTR_RD_SIMPLE(Viewport, OY, int, geometry.orig.y)
|
||||||
|
|
||||||
DEF_ATTR_RD_SIMPLE(Viewport, ScaleX, double, p->scaleX)
|
DEF_ATTR_RD_SIMPLE(Viewport, ScaleX, double, p->scaleX)
|
||||||
DEF_ATTR_RD_SIMPLE(Viewport, ScaleY, double, p->scaleY)
|
DEF_ATTR_RD_SIMPLE(Viewport, ScaleY, double, p->scaleY)
|
||||||
|
DEF_ATTR_RD_SIMPLE(Viewport, Rotation, double, p->rotation)
|
||||||
|
|
||||||
DEF_ATTR_SIMPLE(Viewport, Rect, Rect&, *p->rect)
|
DEF_ATTR_SIMPLE(Viewport, Rect, Rect&, *p->rect)
|
||||||
DEF_ATTR_SIMPLE(Viewport, Color, Color&, *p->color)
|
DEF_ATTR_SIMPLE(Viewport, Color, Color&, *p->color)
|
||||||
|
|
@ -186,6 +189,16 @@ void Viewport::setScaleY(double value){
|
||||||
notifyGeometryChange();
|
notifyGeometryChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Viewport::setRotation(double value){
|
||||||
|
guardDisposed();
|
||||||
|
|
||||||
|
if (p->rotation == value)
|
||||||
|
return;
|
||||||
|
|
||||||
|
p->rotation = value;
|
||||||
|
notifyGeometryChange();
|
||||||
|
}
|
||||||
|
|
||||||
void Viewport::initDynAttribs(){
|
void Viewport::initDynAttribs(){
|
||||||
p->rect = new Rect(*p->rect);
|
p->rect = new Rect(*p->rect);
|
||||||
p->color = new Color;
|
p->color = new Color;
|
||||||
|
|
|
||||||
|
|
@ -38,13 +38,14 @@ public:
|
||||||
|
|
||||||
void update();
|
void update();
|
||||||
|
|
||||||
DECL_ATTR( Rect, Rect& )
|
DECL_ATTR( Rect, Rect& )
|
||||||
DECL_ATTR( OX, int )
|
DECL_ATTR( OX, int )
|
||||||
DECL_ATTR( OY, int )
|
DECL_ATTR( OY, int )
|
||||||
DECL_ATTR( ScaleX, double )
|
DECL_ATTR( ScaleX, double )
|
||||||
DECL_ATTR( ScaleY, double )
|
DECL_ATTR( ScaleY, double )
|
||||||
DECL_ATTR( Color, Color& )
|
DECL_ATTR( Rotation, double )
|
||||||
DECL_ATTR( Tone, Tone& )
|
DECL_ATTR( Color, Color& )
|
||||||
|
DECL_ATTR( Tone, Tone& )
|
||||||
|
|
||||||
void initDynAttribs();
|
void initDynAttribs();
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue