1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
|
#pragma once
#include "Core/Object.h"
#include "Core/EnginePtr.h"
#include "Vector.h"
#include "Angle.h"
namespace storm {
namespace geometry {
STORM_PKG(core.geometry);
/**
* Transform in 2 or 3 dimensions. 2d-coordinates are assumed to lie in the xy-plane.
*
* We assume that points on the screen take the form of a row vector that is multiplied with
* the matrix from the left. Transforms may therefore be combined by multiplying them from
* left to right as follows:
*
* a * b * c
*
* Which means that a is applied first, then b and finally c.
*
* Note: we generally view transformations as being applied on the geometry. I.e. that we
* transform from world space to screen space.
*/
class Transform : public Object {
STORM_CLASS;
public:
// Unit transform.
STORM_CTOR Transform();
// Copy.
Transform(const Transform &o);
// Create and initialize. Row by row.
typedef Float FData[16];
Transform(FData data);
// Multiply two transforms, creates a transform that performs both original transforms
// in sequence.
Transform *STORM_FN operator *(Transform *o);
// Invert the transform.
Transform *STORM_FN inverted();
// Get a single element.
inline Float STORM_FN at(Nat row, Nat col) const { return (&v00)[row + 4*col]; }
// To string.
virtual void STORM_FN toS(StrBuf *to) const;
private:
typedef Float FArray[4][4];
Transform(FArray data);
inline Float &v(Nat row, Nat col) {
return (&v00)[row + 4*col];
}
// Data (y, x) (row, col). In memory, this is row-by-row.
Float v00;
Float v10;
Float v20;
Float v30;
Float v01;
Float v11;
Float v21;
Float v31;
Float v02;
Float v12;
Float v22;
Float v32;
Float v03;
Float v13;
Float v23;
Float v33;
friend Vector operator *(Vector o, Transform *tfm);
friend Point operator *(Point o, Transform *tfm);
};
// Transform a vector using a transform.
Vector STORM_FN operator *(Vector o, Transform *tfm);
// Transform a point using a transform.
Point STORM_FN operator *(Point o, Transform *tfm);
// Translation.
Transform *STORM_FN translate(EnginePtr e, Vector v);
Transform *STORM_FN translate(EnginePtr e, Point v);
Transform *STORM_FN translate(EnginePtr e, Size v);
// Rotation.
Transform *STORM_FN rotateX(EnginePtr e, Angle angle);
Transform *STORM_FN rotateY(EnginePtr e, Angle angle);
Transform *STORM_FN rotateZ(EnginePtr e, Angle angle);
// Rotate around the specified point.
Transform *STORM_FN rotateX(EnginePtr e, Angle angle, Vector origin);
Transform *STORM_FN rotateY(EnginePtr e, Angle angle, Vector origin);
Transform *STORM_FN rotateZ(EnginePtr e, Angle angle, Vector origin);
// Rotation around the Z axis (in 2D).
Transform *STORM_FN rotate(EnginePtr e, Angle angle);
Transform *STORM_FN rotate(EnginePtr e, Angle angle, Point origin);
// Scale.
Transform *STORM_FN scale(EnginePtr e, Float scale);
Transform *STORM_FN scale(EnginePtr e, Vector scale);
Transform *STORM_FN scale(EnginePtr e, Size scale);
// Scale, keeping the point 'origin' unchanged (i.e. scaling around 'origin').
Transform *STORM_FN scale(EnginePtr e, Size scale, Point origin);
Transform *STORM_FN scale(EnginePtr e, Float scale, Vector origin);
Transform *STORM_FN scale(EnginePtr e, Vector scale, Vector origin);
// Skew.
Transform *STORM_FN skewX(EnginePtr e, Angle angle);
Transform *STORM_FN skewY(EnginePtr e, Angle angle);
Transform *STORM_FN skewZ(EnginePtr e, Angle angle);
}
}
|