mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-02 01:44:06 -04:00
introduce 2-d TransformStates
This commit is contained in:
parent
d4faa62ea5
commit
65458d9edd
@ -2242,21 +2242,6 @@ do_issue_texture() {
|
|||||||
TexGenAttrib::Mode mode = _current_tex_gen->get_mode(stage);
|
TexGenAttrib::Mode mode = _current_tex_gen->get_mode(stage);
|
||||||
bool any_point_sprite = false;
|
bool any_point_sprite = false;
|
||||||
|
|
||||||
// These transforms are used in the below to invert certain
|
|
||||||
// computed component values in various modes, to emulate the
|
|
||||||
// behavior of OpenGL, so we get a consistent behavior between the
|
|
||||||
// two of them.
|
|
||||||
static CPT(TransformState) invert_z =
|
|
||||||
TransformState::make_mat(LMatrix4f(1.0f, 0.0f, 0.0f, 0.0f,
|
|
||||||
0.0f, 1.0f, 0.0f, 0.0f,
|
|
||||||
0.0f, 0.0f, -1.0f, 0.0f,
|
|
||||||
0.0f, 0.0f, 0.0f, 1.0f));
|
|
||||||
static CPT(TransformState) invert_y =
|
|
||||||
TransformState::make_mat(LMatrix4f(1.0f, 0.0f, 0.0f, 0.0f,
|
|
||||||
0.0f, -1.0f, 0.0f, 0.0f,
|
|
||||||
0.0f, 0.0f, 1.0f, 0.0f,
|
|
||||||
0.0f, 0.0f, 0.0f, 1.0f));
|
|
||||||
|
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case TexGenAttrib::M_off:
|
case TexGenAttrib::M_off:
|
||||||
case TexGenAttrib::M_light_vector:
|
case TexGenAttrib::M_light_vector:
|
||||||
@ -2352,18 +2337,19 @@ do_issue_texture() {
|
|||||||
_d3d_device->SetRenderState(D3DRS_POINTSPRITEENABLE, any_point_sprite);
|
_d3d_device->SetRenderState(D3DRS_POINTSPRITEENABLE, any_point_sprite);
|
||||||
|
|
||||||
if (!tex_mat->is_identity()) {
|
if (!tex_mat->is_identity()) {
|
||||||
LMatrix4f m = tex_mat->get_mat();
|
if (tex_mat->is_2d() && !texcoords_3d) {
|
||||||
_d3d_device->SetTransform(get_tex_mat_sym(i), (D3DMATRIX *)m.get_data());
|
|
||||||
|
|
||||||
if (!texcoords_3d) {
|
|
||||||
// For 2-d texture coordinates, we have to reorder the matrix.
|
// For 2-d texture coordinates, we have to reorder the matrix.
|
||||||
|
LMatrix4f m = tex_mat->get_mat();
|
||||||
m.set(m(0, 0), m(0, 1), m(0, 3), 0.0f,
|
m.set(m(0, 0), m(0, 1), m(0, 3), 0.0f,
|
||||||
m(1, 0), m(1, 1), m(1, 3), 0.0f,
|
m(1, 0), m(1, 1), m(1, 3), 0.0f,
|
||||||
m(3, 0), m(3, 1), m(3, 3), 0.0f,
|
m(3, 0), m(3, 1), m(3, 3), 0.0f,
|
||||||
0.0f, 0.0f, 0.0f, 1.0f);
|
0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
_d3d_device->SetTransform(get_tex_mat_sym(i), (D3DMATRIX *)m.get_data());
|
||||||
_d3d_device->SetTextureStageState(i, D3DTSS_TEXTURETRANSFORMFLAGS,
|
_d3d_device->SetTextureStageState(i, D3DTSS_TEXTURETRANSFORMFLAGS,
|
||||||
D3DTTFF_COUNT2);
|
D3DTTFF_COUNT2);
|
||||||
} else {
|
} else {
|
||||||
|
LMatrix4f m = tex_mat->get_mat();
|
||||||
|
_d3d_device->SetTransform(get_tex_mat_sym(i), (D3DMATRIX *)m.get_data());
|
||||||
_d3d_device->SetTextureStageState(i, D3DTSS_TEXTURETRANSFORMFLAGS,
|
_d3d_device->SetTextureStageState(i, D3DTSS_TEXTURETRANSFORMFLAGS,
|
||||||
D3DTTFF_COUNT3);
|
D3DTTFF_COUNT3);
|
||||||
}
|
}
|
||||||
|
@ -1314,7 +1314,7 @@ INLINE void NodePath::
|
|||||||
set_tex_offset(TextureStage *stage, float u, float v) {
|
set_tex_offset(TextureStage *stage, float u, float v) {
|
||||||
nassertv_always(!is_empty());
|
nassertv_always(!is_empty());
|
||||||
set_tex_transform(stage,
|
set_tex_transform(stage,
|
||||||
get_tex_transform(stage)->set_pos(LVecBase3f(u, v, 0.0f)));
|
get_tex_transform(stage)->set_pos2d(LVecBase2f(u, v)));
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -1328,7 +1328,7 @@ INLINE void NodePath::
|
|||||||
set_tex_rotate(TextureStage *stage, float r) {
|
set_tex_rotate(TextureStage *stage, float r) {
|
||||||
nassertv_always(!is_empty());
|
nassertv_always(!is_empty());
|
||||||
set_tex_transform(stage,
|
set_tex_transform(stage,
|
||||||
get_tex_transform(stage)->set_hpr(LVecBase3f(r, 0.0f, 0.0f)));
|
get_tex_transform(stage)->set_rotate2d(r));
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -1352,7 +1352,7 @@ INLINE void NodePath::
|
|||||||
set_tex_scale(TextureStage *stage, float su, float sv) {
|
set_tex_scale(TextureStage *stage, float su, float sv) {
|
||||||
nassertv_always(!is_empty());
|
nassertv_always(!is_empty());
|
||||||
set_tex_transform(stage,
|
set_tex_transform(stage,
|
||||||
get_tex_transform(stage)->set_scale(LVecBase3f(su, sv, 1.0f)));
|
get_tex_transform(stage)->set_scale2d(LVecBase2f(su, sv)));
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -1364,8 +1364,7 @@ set_tex_scale(TextureStage *stage, float su, float sv) {
|
|||||||
INLINE LVecBase2f NodePath::
|
INLINE LVecBase2f NodePath::
|
||||||
get_tex_offset(TextureStage *stage) const {
|
get_tex_offset(TextureStage *stage) const {
|
||||||
nassertr_always(!is_empty(), LVecBase2f::zero());
|
nassertr_always(!is_empty(), LVecBase2f::zero());
|
||||||
const LVecBase3f &pos = get_tex_transform(stage)->get_pos();
|
return get_tex_transform(stage)->get_pos2d();
|
||||||
return LVecBase2f(pos[0], pos[1]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -1377,7 +1376,7 @@ get_tex_offset(TextureStage *stage) const {
|
|||||||
INLINE float NodePath::
|
INLINE float NodePath::
|
||||||
get_tex_rotate(TextureStage *stage) const {
|
get_tex_rotate(TextureStage *stage) const {
|
||||||
nassertr_always(!is_empty(), 0.0f);
|
nassertr_always(!is_empty(), 0.0f);
|
||||||
return get_tex_transform(stage)->get_hpr()[0];
|
return get_tex_transform(stage)->get_rotate2d();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -1389,8 +1388,7 @@ get_tex_rotate(TextureStage *stage) const {
|
|||||||
INLINE LVecBase2f NodePath::
|
INLINE LVecBase2f NodePath::
|
||||||
get_tex_scale(TextureStage *stage) const {
|
get_tex_scale(TextureStage *stage) const {
|
||||||
nassertr_always(!is_empty(), LVecBase2f(1.0f, 1.0f));
|
nassertr_always(!is_empty(), LVecBase2f(1.0f, 1.0f));
|
||||||
const LVecBase3f &scale = get_tex_transform(stage)->get_scale();
|
return get_tex_transform(stage)->get_scale2d();
|
||||||
return LVecBase2f(scale[0], scale[1]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -1414,7 +1412,7 @@ INLINE void NodePath::
|
|||||||
set_tex_offset(const NodePath &other, TextureStage *stage, float u, float v) {
|
set_tex_offset(const NodePath &other, TextureStage *stage, float u, float v) {
|
||||||
nassertv_always(!is_empty());
|
nassertv_always(!is_empty());
|
||||||
set_tex_transform(other, stage,
|
set_tex_transform(other, stage,
|
||||||
get_tex_transform(other, stage)->set_pos(LVecBase3f(u, v, 0.0f)));
|
get_tex_transform(other, stage)->set_pos2d(LVecBase2f(u, v)));
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -1428,7 +1426,7 @@ INLINE void NodePath::
|
|||||||
set_tex_rotate(const NodePath &other, TextureStage *stage, float r) {
|
set_tex_rotate(const NodePath &other, TextureStage *stage, float r) {
|
||||||
nassertv_always(!is_empty());
|
nassertv_always(!is_empty());
|
||||||
set_tex_transform(other, stage,
|
set_tex_transform(other, stage,
|
||||||
get_tex_transform(other, stage)->set_hpr(LVecBase3f(r, 0.0f, 0.0f)));
|
get_tex_transform(other, stage)->set_rotate2d(r));
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -1452,7 +1450,7 @@ INLINE void NodePath::
|
|||||||
set_tex_scale(const NodePath &other, TextureStage *stage, float su, float sv) {
|
set_tex_scale(const NodePath &other, TextureStage *stage, float su, float sv) {
|
||||||
nassertv_always(!is_empty());
|
nassertv_always(!is_empty());
|
||||||
set_tex_transform(other, stage,
|
set_tex_transform(other, stage,
|
||||||
get_tex_transform(stage)->set_scale(LVecBase3f(su, sv, 1.0f)));
|
get_tex_transform(stage)->set_scale2d(LVecBase2f(su, sv)));
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -1464,8 +1462,7 @@ set_tex_scale(const NodePath &other, TextureStage *stage, float su, float sv) {
|
|||||||
INLINE LVecBase2f NodePath::
|
INLINE LVecBase2f NodePath::
|
||||||
get_tex_offset(const NodePath &other, TextureStage *stage) const {
|
get_tex_offset(const NodePath &other, TextureStage *stage) const {
|
||||||
nassertr_always(!is_empty(), LVecBase2f::zero());
|
nassertr_always(!is_empty(), LVecBase2f::zero());
|
||||||
const LVecBase3f &pos = get_tex_transform(other, stage)->get_pos();
|
return get_tex_transform(other, stage)->get_pos2d();
|
||||||
return LVecBase2f(pos[0], pos[1]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -1477,7 +1474,7 @@ get_tex_offset(const NodePath &other, TextureStage *stage) const {
|
|||||||
INLINE float NodePath::
|
INLINE float NodePath::
|
||||||
get_tex_rotate(const NodePath &other, TextureStage *stage) const {
|
get_tex_rotate(const NodePath &other, TextureStage *stage) const {
|
||||||
nassertr_always(!is_empty(), 0.0f);
|
nassertr_always(!is_empty(), 0.0f);
|
||||||
return get_tex_transform(other, stage)->get_hpr()[0];
|
return get_tex_transform(other, stage)->get_rotate2d();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -1489,8 +1486,7 @@ get_tex_rotate(const NodePath &other, TextureStage *stage) const {
|
|||||||
INLINE LVecBase2f NodePath::
|
INLINE LVecBase2f NodePath::
|
||||||
get_tex_scale(const NodePath &other, TextureStage *stage) const {
|
get_tex_scale(const NodePath &other, TextureStage *stage) const {
|
||||||
nassertr_always(!is_empty(), LVecBase2f(1.0f, 1.0f));
|
nassertr_always(!is_empty(), LVecBase2f(1.0f, 1.0f));
|
||||||
const LVecBase3f &scale = get_tex_transform(other, stage)->get_scale();
|
return get_tex_transform(other, stage)->get_scale2d();
|
||||||
return LVecBase2f(scale[0], scale[1]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
@ -57,10 +57,13 @@ make() {
|
|||||||
// Function: TexMatrixAttrib::make
|
// Function: TexMatrixAttrib::make
|
||||||
// Access: Published, Static
|
// Access: Published, Static
|
||||||
// Description: Constructs a TexMatrixAttrib that applies the
|
// Description: Constructs a TexMatrixAttrib that applies the
|
||||||
// indicated matrix to the default texture stage.
|
// indicated matrix to the default texture stage. This
|
||||||
|
// interface is deprecated.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
CPT(RenderAttrib) TexMatrixAttrib::
|
CPT(RenderAttrib) TexMatrixAttrib::
|
||||||
make(const LMatrix4f &mat) {
|
make(const LMatrix4f &mat) {
|
||||||
|
pgraph_cat.warning()
|
||||||
|
<< "Using deprecated TexMatrixAttrib interface.\n";
|
||||||
if (mat == LMatrix4f::ident_mat()) {
|
if (mat == LMatrix4f::ident_mat()) {
|
||||||
return make();
|
return make();
|
||||||
}
|
}
|
||||||
@ -68,20 +71,6 @@ make(const LMatrix4f &mat) {
|
|||||||
return make(TextureStage::get_default(), transform);
|
return make(TextureStage::get_default(), transform);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: TexMatrixAttrib::make
|
|
||||||
// Access: Published, Static
|
|
||||||
// Description: Constructs a TexMatrixAttrib that applies the
|
|
||||||
// indicated transform to the default texture stage.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
CPT(RenderAttrib) TexMatrixAttrib::
|
|
||||||
make(const TransformState *transform) {
|
|
||||||
if (transform->is_identity()) {
|
|
||||||
return make();
|
|
||||||
}
|
|
||||||
return make(TextureStage::get_default(), transform);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: TexMatrixAttrib::make
|
// Function: TexMatrixAttrib::make
|
||||||
// Access: Published, Static
|
// Access: Published, Static
|
||||||
|
@ -45,7 +45,6 @@ public:
|
|||||||
PUBLISHED:
|
PUBLISHED:
|
||||||
static CPT(RenderAttrib) make();
|
static CPT(RenderAttrib) make();
|
||||||
static CPT(RenderAttrib) make(const LMatrix4f &mat);
|
static CPT(RenderAttrib) make(const LMatrix4f &mat);
|
||||||
static CPT(RenderAttrib) make(const TransformState *transform);
|
|
||||||
static CPT(RenderAttrib) make(TextureStage *stage, const TransformState *transform);
|
static CPT(RenderAttrib) make(TextureStage *stage, const TransformState *transform);
|
||||||
|
|
||||||
CPT(RenderAttrib) add_stage(TextureStage *stage, const TransformState *transform) const;
|
CPT(RenderAttrib) add_stage(TextureStage *stage, const TransformState *transform) const;
|
||||||
|
@ -76,9 +76,9 @@ make_pos_hpr(const LVecBase3f &pos, const LVecBase3f &hpr) {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE CPT(TransformState) TransformState::
|
INLINE CPT(TransformState) TransformState::
|
||||||
make_scale(float scale) {
|
make_scale(float scale) {
|
||||||
return make_pos_hpr_scale(LVecBase3f(0.0f, 0.0f, 0.0f),
|
// We actually map this 3-d uniform make_scale() to the 2-d
|
||||||
LVecBase3f(0.0f, 0.0f, 0.0f),
|
// version--might as well call it a 2-d scale.
|
||||||
LVecBase3f(scale, scale, scale));
|
return make_scale2d(scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -132,6 +132,88 @@ make_pos_quat_scale(const LVecBase3f &pos, const LQuaternionf &quat,
|
|||||||
return make_pos_quat_scale_shear(pos, quat, scale, LVecBase3f::zero());
|
return make_pos_quat_scale_shear(pos, quat, scale, LVecBase3f::zero());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: TransformState::make_pos2d
|
||||||
|
// Access: Published, Static
|
||||||
|
// Description: Makes a new 2-d TransformState with the specified
|
||||||
|
// components.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE CPT(TransformState) TransformState::
|
||||||
|
make_pos2d(const LVecBase2f &pos) {
|
||||||
|
return make_pos_rotate_scale2d(pos, 0.0f, LVecBase2f(1.0f, 1.0f));
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: TransformState::make_rotate2d
|
||||||
|
// Access: Published, Static
|
||||||
|
// Description: Makes a new 2-d TransformState with the specified
|
||||||
|
// components.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE CPT(TransformState) TransformState::
|
||||||
|
make_rotate2d(float rotate) {
|
||||||
|
return make_pos_rotate_scale2d(LVecBase2f(0.0f, 0.0f), rotate,
|
||||||
|
LVecBase2f(1.0f, 1.0f));
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: TransformState::make_pos_rotate2d
|
||||||
|
// Access: Published, Static
|
||||||
|
// Description: Makes a new 2-d TransformState with the specified
|
||||||
|
// components.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE CPT(TransformState) TransformState::
|
||||||
|
make_pos_rotate2d(const LVecBase2f &pos, float rotate) {
|
||||||
|
return make_pos_rotate_scale2d(pos, rotate,
|
||||||
|
LVecBase2f(1.0, 1.0f));
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: TransformState::make_scale2d
|
||||||
|
// Access: Published, Static
|
||||||
|
// Description: Makes a new 2-d TransformState with the specified
|
||||||
|
// components.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE CPT(TransformState) TransformState::
|
||||||
|
make_scale2d(float scale) {
|
||||||
|
return make_pos_rotate_scale2d(LVecBase2f(0.0f, 0.0f), 0.0f,
|
||||||
|
LVecBase2f(scale, scale));
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: TransformState::make_scale2d
|
||||||
|
// Access: Published, Static
|
||||||
|
// Description: Makes a new 2-d TransformState with the specified
|
||||||
|
// components.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE CPT(TransformState) TransformState::
|
||||||
|
make_scale2d(const LVecBase2f &scale) {
|
||||||
|
return make_pos_rotate_scale2d(LVecBase2f(0.0f, 0.0f), 0.0f, scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: TransformState::make_shear2d
|
||||||
|
// Access: Published, Static
|
||||||
|
// Description: Makes a new 2-d TransformState with the specified
|
||||||
|
// components.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE CPT(TransformState) TransformState::
|
||||||
|
make_shear2d(float shear) {
|
||||||
|
return make_pos_rotate_scale_shear2d(LVecBase2f(0.0f, 0.0f), 0.0f,
|
||||||
|
LVecBase2f(1.0f, 1.0f), shear);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: TransformState::make_pos_rotate_scale2d
|
||||||
|
// Access: Published, Static
|
||||||
|
// Description: Makes a new 2-d TransformState with the specified
|
||||||
|
// components.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE CPT(TransformState) TransformState::
|
||||||
|
make_pos_rotate_scale2d(const LVecBase2f &pos, float rotate,
|
||||||
|
const LVecBase2f &scale) {
|
||||||
|
return make_pos_rotate_scale_shear2d(pos, rotate, scale, 0.0f);
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: TransformState::is_identity
|
// Function: TransformState::is_identity
|
||||||
// Access: Published
|
// Access: Published
|
||||||
@ -168,6 +250,19 @@ is_singular() const {
|
|||||||
return ((_flags & F_is_singular) != 0);
|
return ((_flags & F_is_singular) != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: TransformState::is_2d
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns true if the transform has been constructed
|
||||||
|
// entirely using the 2-d transform operations,
|
||||||
|
// e.g. make_pos2d(), and therefore operates strictly in
|
||||||
|
// two-dimensional space on X and Y only.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE bool TransformState::
|
||||||
|
is_2d() const {
|
||||||
|
return ((_flags & F_is_2d) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: TransformState::has_components
|
// Function: TransformState::has_components
|
||||||
// Access: Published
|
// Access: Published
|
||||||
@ -446,6 +541,89 @@ get_mat() const {
|
|||||||
return _mat;
|
return _mat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: TransformState::get_pos2d
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns the pos component of the 2-d transform. It
|
||||||
|
// is an error to call this if has_pos() or is_2d()
|
||||||
|
// returned false.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE LVecBase2f TransformState::
|
||||||
|
get_pos2d() const {
|
||||||
|
check_components();
|
||||||
|
nassertr(has_pos() && is_2d(), LVecBase2f::zero());
|
||||||
|
return LVecBase2f(_pos[0], _pos[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: TransformState::get_rotate2d
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns the rotation component of the 2-d transform
|
||||||
|
// as an angle in degrees clockwise about the origin.
|
||||||
|
// It is an error to call this if has_components() or
|
||||||
|
// is_2d() returned false.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE float TransformState::
|
||||||
|
get_rotate2d() const {
|
||||||
|
check_hpr();
|
||||||
|
nassertr(!is_invalid() && is_2d(), 0);
|
||||||
|
switch (get_default_coordinate_system()) {
|
||||||
|
default:
|
||||||
|
case CS_zup_right:
|
||||||
|
return _hpr[0];
|
||||||
|
case CS_zup_left:
|
||||||
|
return -_hpr[0];
|
||||||
|
case CS_yup_right:
|
||||||
|
return -_hpr[2];
|
||||||
|
case CS_yup_left:
|
||||||
|
return _hpr[2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: TransformState::get_scale2d
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns the scale component of the 2-d transform. It
|
||||||
|
// is an error to call this if has_components() or
|
||||||
|
// is_2d() returned false.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE LVecBase2f TransformState::
|
||||||
|
get_scale2d() const {
|
||||||
|
check_components();
|
||||||
|
nassertr(!is_invalid() && is_2d(), LVecBase2f::zero());
|
||||||
|
return LVecBase2f(_scale[0], _scale[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: TransformState::get_shear2d
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns the shear component of the 2-d transform. It
|
||||||
|
// is an error to call this if has_components() or
|
||||||
|
// is_2d() returned false.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE float TransformState::
|
||||||
|
get_shear2d() const {
|
||||||
|
check_components();
|
||||||
|
nassertr(!is_invalid() && is_2d(), 0.0f);
|
||||||
|
return _shear[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: TransformState::get_mat3
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns the 3x3 matrix that describes the 2-d
|
||||||
|
// transform. It is an error to call this if is_2d()
|
||||||
|
// returned false.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE LMatrix3f TransformState::
|
||||||
|
get_mat3() const {
|
||||||
|
nassertr(has_mat() && is_2d(), LMatrix3f::ident_mat());
|
||||||
|
check_mat();
|
||||||
|
return LMatrix3f(_mat(0, 0), _mat(0, 1), _mat(0, 3),
|
||||||
|
_mat(1, 0), _mat(1, 1), _mat(1, 3),
|
||||||
|
_mat(3, 0), _mat(3, 1), _mat(3, 3));
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: TransformState::get_geom_rendering
|
// Function: TransformState::get_geom_rendering
|
||||||
// Access: Published
|
// Access: Published
|
||||||
@ -631,6 +809,29 @@ check_uniform_scale() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: TransformState::check_uniform_scale2d
|
||||||
|
// Access: Private
|
||||||
|
// Description: Should be called immediately after _scale (and
|
||||||
|
// F_has_components) is set, for a known 2-d scale, this
|
||||||
|
// checks for a identity and/or uniform scale (as well
|
||||||
|
// as a non-zero shear) and sets the bit appropriately.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE void TransformState::
|
||||||
|
check_uniform_scale2d() {
|
||||||
|
if (IS_NEARLY_EQUAL(_scale[0], _scale[1])) {
|
||||||
|
_scale[2] = _scale[0];
|
||||||
|
_flags |= F_uniform_scale;
|
||||||
|
if (IS_NEARLY_EQUAL(_scale[0], 1.0f)) {
|
||||||
|
_flags |= F_identity_scale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_shear.almost_equal(LVecBase3f::zero())) {
|
||||||
|
_flags |= F_has_nonzero_shear;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: TransformState::set_destructing
|
// Function: TransformState::set_destructing
|
||||||
// Access: Private
|
// Access: Private
|
||||||
|
@ -55,7 +55,7 @@ TransformState() {
|
|||||||
_states = new States;
|
_states = new States;
|
||||||
}
|
}
|
||||||
_saved_entry = _states->end();
|
_saved_entry = _states->end();
|
||||||
_flags = F_is_identity | F_singular_known;
|
_flags = F_is_identity | F_singular_known | F_is_2d;
|
||||||
_inv_mat = (LMatrix4f *)NULL;
|
_inv_mat = (LMatrix4f *)NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,7 +120,7 @@ TransformState::
|
|||||||
bool TransformState::
|
bool TransformState::
|
||||||
operator < (const TransformState &other) const {
|
operator < (const TransformState &other) const {
|
||||||
static const int significant_flags =
|
static const int significant_flags =
|
||||||
(F_is_invalid | F_is_identity | F_components_given | F_hpr_given | F_quat_given);
|
(F_is_invalid | F_is_identity | F_components_given | F_hpr_given | F_quat_given | F_is_2d);
|
||||||
|
|
||||||
int flags = (_flags & significant_flags);
|
int flags = (_flags & significant_flags);
|
||||||
int other_flags = (other._flags & significant_flags);
|
int other_flags = (other._flags & significant_flags);
|
||||||
@ -185,7 +185,7 @@ get_hash() const {
|
|||||||
size_t hash = 0;
|
size_t hash = 0;
|
||||||
|
|
||||||
static const int significant_flags =
|
static const int significant_flags =
|
||||||
(F_is_invalid | F_is_identity | F_components_given | F_hpr_given);
|
(F_is_invalid | F_is_identity | F_components_given | F_hpr_given | F_is_2d);
|
||||||
|
|
||||||
int flags = (_flags & significant_flags);
|
int flags = (_flags & significant_flags);
|
||||||
hash = int_hash::add_hash(hash, flags);
|
hash = int_hash::add_hash(hash, flags);
|
||||||
@ -327,6 +327,74 @@ make_mat(const LMatrix4f &mat) {
|
|||||||
return return_new(state);
|
return return_new(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: TransformState::make_pos_rotate_scale_shear2d
|
||||||
|
// Access: Published, Static
|
||||||
|
// Description: Makes a new two-dimensional TransformState with the
|
||||||
|
// specified components.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
CPT(TransformState) TransformState::
|
||||||
|
make_pos_rotate_scale_shear2d(const LVecBase2f &pos, float rotate,
|
||||||
|
const LVecBase2f &scale,
|
||||||
|
float shear) {
|
||||||
|
nassertr(!(pos.is_nan() || cnan(rotate) || scale.is_nan() || cnan(shear)) , make_invalid());
|
||||||
|
// Make a special-case check for the identity transform.
|
||||||
|
if (pos == LVecBase2f(0.0f, 0.0f) &&
|
||||||
|
rotate == 0.0f &&
|
||||||
|
scale == LVecBase2f(1.0f, 1.0f) &&
|
||||||
|
shear == 0.0f) {
|
||||||
|
return make_identity();
|
||||||
|
}
|
||||||
|
|
||||||
|
TransformState *state = new TransformState;
|
||||||
|
state->_pos.set(pos[0], pos[1], 0.0f);
|
||||||
|
switch (get_default_coordinate_system()) {
|
||||||
|
default:
|
||||||
|
case CS_zup_right:
|
||||||
|
state->_hpr.set(rotate, 0.0f, 0.0f);
|
||||||
|
break;
|
||||||
|
case CS_zup_left:
|
||||||
|
state->_hpr.set(-rotate, 0.0f, 0.0f);
|
||||||
|
break;
|
||||||
|
case CS_yup_right:
|
||||||
|
state->_hpr.set(0.0f, 0.0f, -rotate);
|
||||||
|
break;
|
||||||
|
case CS_yup_left:
|
||||||
|
state->_hpr.set(0.0, 0.0f, rotate);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
state->_scale.set(scale[0], scale[1], 1.0f);
|
||||||
|
state->_shear.set(shear, 0.0f, 0.0f);
|
||||||
|
state->_flags = F_components_given | F_hpr_given | F_components_known | F_hpr_known | F_has_components | F_is_2d;
|
||||||
|
state->check_uniform_scale2d();
|
||||||
|
return return_new(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: TransformState::make_mat3
|
||||||
|
// Access: Published, Static
|
||||||
|
// Description: Makes a new two-dimensional TransformState with the
|
||||||
|
// specified 3x3 transformation matrix.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
CPT(TransformState) TransformState::
|
||||||
|
make_mat3(const LMatrix3f &mat) {
|
||||||
|
nassertr(!mat.is_nan(), make_invalid());
|
||||||
|
// Make a special-case check for the identity matrix.
|
||||||
|
if (mat == LMatrix3f::ident_mat()) {
|
||||||
|
return make_identity();
|
||||||
|
}
|
||||||
|
|
||||||
|
TransformState *state = new TransformState;
|
||||||
|
state->_mat.set(mat(0, 0), mat(0, 1), 0.0f, mat(0, 2),
|
||||||
|
mat(1, 0), mat(1, 1), 0.0f, mat(1, 2),
|
||||||
|
0.0f, 0.0f, 1.0f, 0.0f,
|
||||||
|
mat(2, 0), mat(2, 1), 0.0f, mat(2, 2));
|
||||||
|
state->_flags = F_mat_known | F_is_2d;
|
||||||
|
return return_new(state);
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: TransformState::set_pos
|
// Function: TransformState::set_pos
|
||||||
// Access: Published
|
// Access: Published
|
||||||
@ -423,6 +491,102 @@ set_shear(const LVecBase3f &shear) const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: TransformState::set_pos2d
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns a new TransformState object that represents the
|
||||||
|
// original 2-d TransformState with its pos component
|
||||||
|
// replaced with the indicated value.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
CPT(TransformState) TransformState::
|
||||||
|
set_pos2d(const LVecBase2f &pos) const {
|
||||||
|
nassertr(!pos.is_nan(), this);
|
||||||
|
nassertr(!is_invalid(), this);
|
||||||
|
if (!is_2d()) {
|
||||||
|
return set_pos(LVecBase3f(pos[0], pos[1], 0.0f));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_identity() || components_given()) {
|
||||||
|
// If we started with a componentwise transform, we keep it that
|
||||||
|
// way.
|
||||||
|
return make_pos_rotate_scale_shear2d(pos, get_rotate2d(), get_scale2d(),
|
||||||
|
get_shear2d());
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Otherwise, we have a matrix transform, and we keep it that way.
|
||||||
|
LMatrix3f mat = get_mat3();
|
||||||
|
mat.set_row(2, pos);
|
||||||
|
return make_mat3(mat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: TransformState::set_rotate2d
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns a new TransformState object that represents the
|
||||||
|
// original 2-d TransformState with its rotation component
|
||||||
|
// replaced with the indicated value, if possible.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
CPT(TransformState) TransformState::
|
||||||
|
set_rotate2d(float rotate) const {
|
||||||
|
nassertr(!cnan(rotate), this);
|
||||||
|
nassertr(!is_invalid(), this);
|
||||||
|
|
||||||
|
if (!is_2d()) {
|
||||||
|
switch (get_default_coordinate_system()) {
|
||||||
|
default:
|
||||||
|
case CS_zup_right:
|
||||||
|
return set_hpr(LVecBase3f(rotate, 0.0f, 0.0f));
|
||||||
|
case CS_zup_left:
|
||||||
|
return set_hpr(LVecBase3f(-rotate, 0.0f, 0.0f));
|
||||||
|
case CS_yup_right:
|
||||||
|
return set_hpr(LVecBase3f(0.0f, 0.0f, -rotate));
|
||||||
|
case CS_yup_left:
|
||||||
|
return set_hpr(LVecBase3f(0.0f, 0.0f, rotate));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return make_pos_rotate_scale_shear2d(get_pos2d(), rotate, get_scale2d(),
|
||||||
|
get_shear2d());
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: TransformState::set_scale2d
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns a new TransformState object that represents the
|
||||||
|
// original 2-d TransformState with its scale component
|
||||||
|
// replaced with the indicated value, if possible.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
CPT(TransformState) TransformState::
|
||||||
|
set_scale2d(const LVecBase2f &scale) const {
|
||||||
|
nassertr(!scale.is_nan(), this);
|
||||||
|
nassertr(!is_invalid(), this);
|
||||||
|
|
||||||
|
if (!is_2d()) {
|
||||||
|
return set_scale(LVecBase3f(scale[0], scale[1], 1.0f));
|
||||||
|
}
|
||||||
|
return make_pos_rotate_scale_shear2d(get_pos2d(), get_rotate2d(),
|
||||||
|
scale, get_shear2d());
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: TransformState::set_shear2d
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns a new TransformState object that represents the
|
||||||
|
// original 2-d TransformState with its shear component
|
||||||
|
// replaced with the indicated value, if possible.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
CPT(TransformState) TransformState::
|
||||||
|
set_shear2d(float shear) const {
|
||||||
|
nassertr(!cnan(shear), this);
|
||||||
|
nassertr(!is_invalid(), this);
|
||||||
|
if (!is_2d()) {
|
||||||
|
return set_shear(LVecBase3f(shear, 0.0f, 0.0f));
|
||||||
|
}
|
||||||
|
return make_pos_rotate_scale_shear2d(get_pos2d(), get_rotate2d(),
|
||||||
|
get_scale2d(), shear);
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: TransformState::compose
|
// Function: TransformState::compose
|
||||||
// Access: Published
|
// Access: Published
|
||||||
@ -672,26 +836,50 @@ output(ostream &out) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
char lead = '(';
|
char lead = '(';
|
||||||
if (!get_pos().almost_equal(LVecBase3f(0.0f, 0.0f, 0.0f))) {
|
if (is_2d()) {
|
||||||
out << lead << "pos " << get_pos();
|
if (!get_pos2d().almost_equal(LVecBase2f(0.0f, 0.0f))) {
|
||||||
lead = ' ';
|
out << lead << "pos " << get_pos2d();
|
||||||
}
|
lead = ' ';
|
||||||
if (output_hpr) {
|
}
|
||||||
out << lead << "hpr " << get_hpr();
|
if (output_hpr) {
|
||||||
lead = ' ';
|
out << lead << "rotate " << get_rotate2d();
|
||||||
}
|
lead = ' ';
|
||||||
if (!get_scale().almost_equal(LVecBase3f(1.0f, 1.0f, 1.0f))) {
|
}
|
||||||
if (has_uniform_scale()) {
|
if (!get_scale2d().almost_equal(LVecBase2f(1.0f, 1.0f))) {
|
||||||
out << lead << "scale " << get_uniform_scale();
|
if (has_uniform_scale()) {
|
||||||
lead = ' ';
|
out << lead << "scale " << get_uniform_scale();
|
||||||
} else {
|
lead = ' ';
|
||||||
out << lead << "scale " << get_scale();
|
} else {
|
||||||
|
out << lead << "scale " << get_scale2d();
|
||||||
|
lead = ' ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (has_nonzero_shear()) {
|
||||||
|
out << lead << "shear " << get_shear2d();
|
||||||
|
lead = ' ';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!get_pos().almost_equal(LVecBase3f(0.0f, 0.0f, 0.0f))) {
|
||||||
|
out << lead << "pos " << get_pos();
|
||||||
|
lead = ' ';
|
||||||
|
}
|
||||||
|
if (output_hpr) {
|
||||||
|
out << lead << "hpr " << get_hpr();
|
||||||
|
lead = ' ';
|
||||||
|
}
|
||||||
|
if (!get_scale().almost_equal(LVecBase3f(1.0f, 1.0f, 1.0f))) {
|
||||||
|
if (has_uniform_scale()) {
|
||||||
|
out << lead << "scale " << get_uniform_scale();
|
||||||
|
lead = ' ';
|
||||||
|
} else {
|
||||||
|
out << lead << "scale " << get_scale();
|
||||||
|
lead = ' ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (has_nonzero_shear()) {
|
||||||
|
out << lead << "shear " << get_shear();
|
||||||
lead = ' ';
|
lead = ' ';
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (has_nonzero_shear()) {
|
|
||||||
out << lead << "shear " << get_shear();
|
|
||||||
lead = ' ';
|
|
||||||
}
|
}
|
||||||
if (lead == '(') {
|
if (lead == '(') {
|
||||||
out << "(almost identity)";
|
out << "(almost identity)";
|
||||||
@ -700,7 +888,11 @@ output(ostream &out) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
out << get_mat();
|
if (is_2d()) {
|
||||||
|
out << get_mat3();
|
||||||
|
} else {
|
||||||
|
out << get_mat();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1082,18 +1274,36 @@ do_compose(const TransformState *other) const {
|
|||||||
// was given componentwise (and there is no non-uniform scale in
|
// was given componentwise (and there is no non-uniform scale in
|
||||||
// the way).
|
// the way).
|
||||||
|
|
||||||
LVecBase3f pos = get_pos();
|
CPT(TransformState) result;
|
||||||
LQuaternionf quat = get_quat();
|
if (is_2d() && other->is_2d()) {
|
||||||
float scale = get_uniform_scale();
|
// Do a 2-d compose.
|
||||||
|
LVecBase2f pos = get_pos2d();
|
||||||
|
float rotate = get_rotate2d();
|
||||||
|
LQuaternionf quat = get_quat();
|
||||||
|
float scale = get_uniform_scale();
|
||||||
|
|
||||||
pos += quat.xform(other->get_pos()) * scale;
|
LPoint3f op = quat.xform(other->get_pos());
|
||||||
quat = other->get_quat() * quat;
|
pos += LVecBase2f(op[0], op[1]) * scale;
|
||||||
quat.normalize();
|
|
||||||
LVecBase3f new_scale = other->get_scale() * scale;
|
|
||||||
|
|
||||||
CPT(TransformState) result =
|
rotate += other->get_rotate2d();
|
||||||
make_pos_quat_scale(pos, quat, new_scale);
|
LVecBase2f new_scale = other->get_scale2d() * scale;
|
||||||
|
|
||||||
|
result = make_pos_rotate_scale2d(pos, rotate, new_scale);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// A normal 3-d compose.
|
||||||
|
LVecBase3f pos = get_pos();
|
||||||
|
LQuaternionf quat = get_quat();
|
||||||
|
float scale = get_uniform_scale();
|
||||||
|
|
||||||
|
pos += quat.xform(other->get_pos()) * scale;
|
||||||
|
quat = other->get_quat() * quat;
|
||||||
|
quat.normalize();
|
||||||
|
LVecBase3f new_scale = other->get_scale() * scale;
|
||||||
|
|
||||||
|
result = make_pos_quat_scale(pos, quat, new_scale);
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
if (paranoid_compose) {
|
if (paranoid_compose) {
|
||||||
// Now verify against the matrix.
|
// Now verify against the matrix.
|
||||||
@ -1113,8 +1323,13 @@ do_compose(const TransformState *other) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Do the operation with matrices.
|
// Do the operation with matrices.
|
||||||
LMatrix4f new_mat = other->get_mat() * get_mat();
|
if (is_2d()) {
|
||||||
return make_mat(new_mat);
|
LMatrix3f new_mat = other->get_mat3() * get_mat3();
|
||||||
|
return make_mat3(new_mat);
|
||||||
|
} else {
|
||||||
|
LMatrix4f new_mat = other->get_mat() * get_mat();
|
||||||
|
return make_mat(new_mat);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -1138,30 +1353,63 @@ do_invert_compose(const TransformState *other) const {
|
|||||||
// was given componentwise (and there is no non-uniform scale in
|
// was given componentwise (and there is no non-uniform scale in
|
||||||
// the way).
|
// the way).
|
||||||
|
|
||||||
LVecBase3f pos = get_pos();
|
CPT(TransformState) result;
|
||||||
LQuaternionf quat = get_quat();
|
if (is_2d() && other->is_2d()) {
|
||||||
float scale = get_uniform_scale();
|
// Do a 2-d invert compose.
|
||||||
|
LVecBase2f pos = get_pos2d();
|
||||||
|
float rotate = get_rotate2d();
|
||||||
|
LQuaternionf quat = get_quat();
|
||||||
|
float scale = get_uniform_scale();
|
||||||
|
|
||||||
|
// First, invert our own transform.
|
||||||
|
if (scale == 0.0f) {
|
||||||
|
((TransformState *)this)->_flags |= F_is_singular | F_singular_known;
|
||||||
|
return make_invalid();
|
||||||
|
}
|
||||||
|
scale = 1.0f / scale;
|
||||||
|
quat.invert_in_place();
|
||||||
|
rotate = -rotate;
|
||||||
|
LVecBase3f mp = quat.xform(-LVecBase3f(pos[0], pos[1], 0.0f));
|
||||||
|
pos = LVecBase2f(mp[0], mp[1]) * scale;
|
||||||
|
LVecBase2f new_scale(scale, scale);
|
||||||
|
|
||||||
|
// Now compose the inverted transform with the other transform.
|
||||||
|
if (!other->is_identity()) {
|
||||||
|
LPoint3f op = quat.xform(other->get_pos());
|
||||||
|
pos += LVecBase2f(op[0], op[1]) * scale;
|
||||||
|
|
||||||
// First, invert our own transform.
|
rotate += other->get_rotate2d();
|
||||||
if (scale == 0.0f) {
|
new_scale = other->get_scale2d() * scale;
|
||||||
((TransformState *)this)->_flags |= F_is_singular | F_singular_known;
|
}
|
||||||
return make_invalid();
|
|
||||||
|
result = make_pos_rotate_scale2d(pos, rotate, new_scale);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Do a normal, 3-d invert compose.
|
||||||
|
LVecBase3f pos = get_pos();
|
||||||
|
LQuaternionf quat = get_quat();
|
||||||
|
float scale = get_uniform_scale();
|
||||||
|
|
||||||
|
// First, invert our own transform.
|
||||||
|
if (scale == 0.0f) {
|
||||||
|
((TransformState *)this)->_flags |= F_is_singular | F_singular_known;
|
||||||
|
return make_invalid();
|
||||||
|
}
|
||||||
|
scale = 1.0f / scale;
|
||||||
|
quat.invert_in_place();
|
||||||
|
pos = quat.xform(-pos) * scale;
|
||||||
|
LVecBase3f new_scale(scale, scale, scale);
|
||||||
|
|
||||||
|
// Now compose the inverted transform with the other transform.
|
||||||
|
if (!other->is_identity()) {
|
||||||
|
pos += quat.xform(other->get_pos()) * scale;
|
||||||
|
quat = other->get_quat() * quat;
|
||||||
|
quat.normalize();
|
||||||
|
new_scale = other->get_scale() * scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = make_pos_quat_scale(pos, quat, new_scale);
|
||||||
}
|
}
|
||||||
scale = 1.0f / scale;
|
|
||||||
quat.invert_in_place();
|
|
||||||
pos = quat.xform(-pos) * scale;
|
|
||||||
LVecBase3f new_scale(scale, scale, scale);
|
|
||||||
|
|
||||||
// Now compose the inverted transform with the other transform.
|
|
||||||
if (!other->is_identity()) {
|
|
||||||
pos += quat.xform(other->get_pos()) * scale;
|
|
||||||
quat = other->get_quat() * quat;
|
|
||||||
quat.normalize();
|
|
||||||
new_scale = other->get_scale() * scale;
|
|
||||||
}
|
|
||||||
|
|
||||||
CPT(TransformState) result =
|
|
||||||
make_pos_quat_scale(pos, quat, new_scale);
|
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
if (paranoid_compose) {
|
if (paranoid_compose) {
|
||||||
@ -1195,10 +1443,22 @@ do_invert_compose(const TransformState *other) const {
|
|||||||
// _inv_mat has been allocated and filled in.
|
// _inv_mat has been allocated and filled in.
|
||||||
nassertr(_inv_mat != (LMatrix4f *)NULL, make_invalid());
|
nassertr(_inv_mat != (LMatrix4f *)NULL, make_invalid());
|
||||||
|
|
||||||
if (other->is_identity()) {
|
if (is_2d()) {
|
||||||
return make_mat(*_inv_mat);
|
const LMatrix4f &i = *_inv_mat;
|
||||||
|
LMatrix3f inv3(i(0, 0), i(0, 1), i(0, 3),
|
||||||
|
i(1, 0), i(1, 1), i(1, 3),
|
||||||
|
i(3, 0), i(3, 1), i(3, 3));
|
||||||
|
if (other->is_identity()) {
|
||||||
|
return make_mat3(inv3);
|
||||||
|
} else {
|
||||||
|
return make_mat3(other->get_mat3() * inv3);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return make_mat(other->get_mat() * (*_inv_mat));
|
if (other->is_identity()) {
|
||||||
|
return make_mat(*_inv_mat);
|
||||||
|
} else {
|
||||||
|
return make_mat(other->get_mat() * (*_inv_mat));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1547,24 +1807,25 @@ write_datagram(BamWriter *manager, Datagram &dg) {
|
|||||||
|
|
||||||
if ((_flags & F_is_identity) != 0) {
|
if ((_flags & F_is_identity) != 0) {
|
||||||
// Identity, nothing much to that.
|
// Identity, nothing much to that.
|
||||||
int flags = F_is_identity | F_singular_known;
|
int flags = F_is_identity | F_singular_known | F_is_2d;
|
||||||
dg.add_uint16(flags);
|
dg.add_uint32(flags);
|
||||||
|
|
||||||
} else if ((_flags & F_is_invalid) != 0) {
|
} else if ((_flags & F_is_invalid) != 0) {
|
||||||
// Invalid, nothing much to that either.
|
// Invalid, nothing much to that either.
|
||||||
int flags = F_is_invalid | F_singular_known | F_is_singular | F_components_known | F_mat_known;
|
int flags = F_is_invalid | F_singular_known | F_is_singular | F_components_known | F_mat_known;
|
||||||
dg.add_uint16(flags);
|
dg.add_uint32(flags);
|
||||||
|
|
||||||
} else if ((_flags & F_components_given) != 0) {
|
} else if ((_flags & F_components_given) != 0) {
|
||||||
// A component-based transform.
|
// A component-based transform.
|
||||||
int flags = F_components_given | F_components_known | F_has_components;
|
int flags = F_components_given | F_components_known | F_has_components;
|
||||||
|
flags |= (_flags & F_is_2d);
|
||||||
if ((_flags & F_quat_given) != 0) {
|
if ((_flags & F_quat_given) != 0) {
|
||||||
flags |= (F_quat_given | F_quat_known);
|
flags |= (F_quat_given | F_quat_known);
|
||||||
} else if ((_flags & F_hpr_given) != 0) {
|
} else if ((_flags & F_hpr_given) != 0) {
|
||||||
flags |= (F_hpr_given | F_hpr_known);
|
flags |= (F_hpr_given | F_hpr_known);
|
||||||
}
|
}
|
||||||
|
|
||||||
dg.add_uint16(flags);
|
dg.add_uint32(flags);
|
||||||
|
|
||||||
_pos.write_datagram(dg);
|
_pos.write_datagram(dg);
|
||||||
if ((_flags & F_quat_given) != 0) {
|
if ((_flags & F_quat_given) != 0) {
|
||||||
@ -1579,7 +1840,8 @@ write_datagram(BamWriter *manager, Datagram &dg) {
|
|||||||
// A general matrix.
|
// A general matrix.
|
||||||
nassertv((_flags & F_mat_known) != 0);
|
nassertv((_flags & F_mat_known) != 0);
|
||||||
int flags = F_mat_known;
|
int flags = F_mat_known;
|
||||||
dg.add_uint16(flags);
|
flags |= (_flags & F_is_2d);
|
||||||
|
dg.add_uint32(flags);
|
||||||
_mat.write_datagram(dg);
|
_mat.write_datagram(dg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1668,7 +1930,11 @@ void TransformState::
|
|||||||
fillin(DatagramIterator &scan, BamReader *manager) {
|
fillin(DatagramIterator &scan, BamReader *manager) {
|
||||||
TypedWritable::fillin(scan, manager);
|
TypedWritable::fillin(scan, manager);
|
||||||
|
|
||||||
_flags = scan.get_uint16();
|
if (manager->get_file_minor_ver() < 2) {
|
||||||
|
_flags = scan.get_uint16();
|
||||||
|
} else {
|
||||||
|
_flags = scan.get_uint32();
|
||||||
|
}
|
||||||
|
|
||||||
if ((_flags & F_components_given) != 0) {
|
if ((_flags & F_components_given) != 0) {
|
||||||
// Componentwise transform.
|
// Componentwise transform.
|
||||||
@ -1677,9 +1943,6 @@ fillin(DatagramIterator &scan, BamReader *manager) {
|
|||||||
_quat.read_datagram(scan);
|
_quat.read_datagram(scan);
|
||||||
} else {
|
} else {
|
||||||
_hpr.read_datagram(scan);
|
_hpr.read_datagram(scan);
|
||||||
// Holdover support for bams 4.0 or older: add these bits that
|
|
||||||
// should have been added when the bam was written.
|
|
||||||
_flags |= (F_hpr_given | F_hpr_known);
|
|
||||||
}
|
}
|
||||||
_scale.read_datagram(scan);
|
_scale.read_datagram(scan);
|
||||||
_shear.read_datagram(scan);
|
_shear.read_datagram(scan);
|
||||||
|
@ -79,7 +79,7 @@ PUBLISHED:
|
|||||||
const LVecBase3f &hpr);
|
const LVecBase3f &hpr);
|
||||||
INLINE static CPT(TransformState) make_scale(float scale);
|
INLINE static CPT(TransformState) make_scale(float scale);
|
||||||
INLINE static CPT(TransformState) make_scale(const LVecBase3f &scale);
|
INLINE static CPT(TransformState) make_scale(const LVecBase3f &scale);
|
||||||
INLINE static CPT(TransformState) make_shear(const LVecBase3f &scale);
|
INLINE static CPT(TransformState) make_shear(const LVecBase3f &shear);
|
||||||
INLINE static CPT(TransformState) make_pos_hpr_scale(const LVecBase3f &pos,
|
INLINE static CPT(TransformState) make_pos_hpr_scale(const LVecBase3f &pos,
|
||||||
const LVecBase3f &hpr,
|
const LVecBase3f &hpr,
|
||||||
const LVecBase3f &scale);
|
const LVecBase3f &scale);
|
||||||
@ -96,9 +96,29 @@ PUBLISHED:
|
|||||||
const LVecBase3f &shear);
|
const LVecBase3f &shear);
|
||||||
static CPT(TransformState) make_mat(const LMatrix4f &mat);
|
static CPT(TransformState) make_mat(const LMatrix4f &mat);
|
||||||
|
|
||||||
|
|
||||||
|
INLINE static CPT(TransformState) make_pos2d(const LVecBase2f &pos);
|
||||||
|
INLINE static CPT(TransformState) make_rotate2d(float rotate);
|
||||||
|
INLINE static CPT(TransformState) make_pos_rotate2d(const LVecBase2f &pos,
|
||||||
|
float rotate);
|
||||||
|
INLINE static CPT(TransformState) make_scale2d(float scale);
|
||||||
|
INLINE static CPT(TransformState) make_scale2d(const LVecBase2f &scale);
|
||||||
|
INLINE static CPT(TransformState) make_shear2d(float shear);
|
||||||
|
INLINE static CPT(TransformState) make_pos_rotate_scale2d(const LVecBase2f &pos,
|
||||||
|
float rotate,
|
||||||
|
const LVecBase2f &scale);
|
||||||
|
static CPT(TransformState) make_pos_rotate_scale_shear2d(const LVecBase2f &pos,
|
||||||
|
float rotate,
|
||||||
|
const LVecBase2f &scale,
|
||||||
|
float shear);
|
||||||
|
static CPT(TransformState) make_mat3(const LMatrix3f &mat);
|
||||||
|
|
||||||
|
|
||||||
INLINE bool is_identity() const;
|
INLINE bool is_identity() const;
|
||||||
INLINE bool is_invalid() const;
|
INLINE bool is_invalid() const;
|
||||||
INLINE bool is_singular() const;
|
INLINE bool is_singular() const;
|
||||||
|
INLINE bool is_2d() const;
|
||||||
|
|
||||||
INLINE bool has_components() const;
|
INLINE bool has_components() const;
|
||||||
INLINE bool components_given() const;
|
INLINE bool components_given() const;
|
||||||
INLINE bool hpr_given() const;
|
INLINE bool hpr_given() const;
|
||||||
@ -112,6 +132,7 @@ PUBLISHED:
|
|||||||
INLINE bool has_shear() const;
|
INLINE bool has_shear() const;
|
||||||
INLINE bool has_nonzero_shear() const;
|
INLINE bool has_nonzero_shear() const;
|
||||||
INLINE bool has_mat() const;
|
INLINE bool has_mat() const;
|
||||||
|
|
||||||
INLINE const LVecBase3f &get_pos() const;
|
INLINE const LVecBase3f &get_pos() const;
|
||||||
INLINE const LVecBase3f &get_hpr() const;
|
INLINE const LVecBase3f &get_hpr() const;
|
||||||
INLINE const LQuaternionf &get_quat() const;
|
INLINE const LQuaternionf &get_quat() const;
|
||||||
@ -120,12 +141,23 @@ PUBLISHED:
|
|||||||
INLINE const LVecBase3f &get_shear() const;
|
INLINE const LVecBase3f &get_shear() const;
|
||||||
INLINE const LMatrix4f &get_mat() const;
|
INLINE const LMatrix4f &get_mat() const;
|
||||||
|
|
||||||
|
INLINE LVecBase2f get_pos2d() const;
|
||||||
|
INLINE float get_rotate2d() const;
|
||||||
|
INLINE LVecBase2f get_scale2d() const;
|
||||||
|
INLINE float get_shear2d() const;
|
||||||
|
INLINE LMatrix3f get_mat3() const;
|
||||||
|
|
||||||
CPT(TransformState) set_pos(const LVecBase3f &pos) const;
|
CPT(TransformState) set_pos(const LVecBase3f &pos) const;
|
||||||
CPT(TransformState) set_hpr(const LVecBase3f &hpr) const;
|
CPT(TransformState) set_hpr(const LVecBase3f &hpr) const;
|
||||||
CPT(TransformState) set_quat(const LQuaternionf &quat) const;
|
CPT(TransformState) set_quat(const LQuaternionf &quat) const;
|
||||||
CPT(TransformState) set_scale(const LVecBase3f &scale) const;
|
CPT(TransformState) set_scale(const LVecBase3f &scale) const;
|
||||||
CPT(TransformState) set_shear(const LVecBase3f &shear) const;
|
CPT(TransformState) set_shear(const LVecBase3f &shear) const;
|
||||||
|
|
||||||
|
CPT(TransformState) set_pos2d(const LVecBase2f &pos) const;
|
||||||
|
CPT(TransformState) set_rotate2d(float rotate) const;
|
||||||
|
CPT(TransformState) set_scale2d(const LVecBase2f &scale) const;
|
||||||
|
CPT(TransformState) set_shear2d(float shear) const;
|
||||||
|
|
||||||
CPT(TransformState) compose(const TransformState *other) const;
|
CPT(TransformState) compose(const TransformState *other) const;
|
||||||
CPT(TransformState) invert_compose(const TransformState *other) const;
|
CPT(TransformState) invert_compose(const TransformState *other) const;
|
||||||
|
|
||||||
@ -229,6 +261,7 @@ private:
|
|||||||
void calc_mat();
|
void calc_mat();
|
||||||
|
|
||||||
INLINE void check_uniform_scale();
|
INLINE void check_uniform_scale();
|
||||||
|
INLINE void check_uniform_scale2d();
|
||||||
|
|
||||||
INLINE void set_destructing();
|
INLINE void set_destructing();
|
||||||
INLINE bool is_destructing() const;
|
INLINE bool is_destructing() const;
|
||||||
@ -237,29 +270,30 @@ private:
|
|||||||
static void update_pstats(int old_referenced_bits, int new_referenced_bits);
|
static void update_pstats(int old_referenced_bits, int new_referenced_bits);
|
||||||
|
|
||||||
enum Flags {
|
enum Flags {
|
||||||
F_is_identity = 0x0001,
|
F_is_identity = 0x00000001,
|
||||||
F_is_singular = 0x0002,
|
F_is_singular = 0x00000002,
|
||||||
F_singular_known = 0x0004, // set if we know F_is_singular
|
F_singular_known = 0x00000004, // set if we know F_is_singular
|
||||||
F_components_given = 0x0008,
|
F_components_given = 0x00000008,
|
||||||
F_components_known = 0x0010, // set if we know F_has_components
|
F_components_known = 0x00000010, // set if we know F_has_components
|
||||||
F_has_components = 0x0020,
|
F_has_components = 0x00000020,
|
||||||
F_mat_known = 0x0040, // set if _mat is defined
|
F_mat_known = 0x00000040, // set if _mat is defined
|
||||||
F_is_invalid = 0x0080,
|
F_is_invalid = 0x00000080,
|
||||||
F_quat_given = 0x0100,
|
F_quat_given = 0x00000100,
|
||||||
F_quat_known = 0x0200, // set if _quat is defined
|
F_quat_known = 0x00000200, // set if _quat is defined
|
||||||
F_hpr_given = 0x0400,
|
F_hpr_given = 0x00000400,
|
||||||
F_hpr_known = 0x0800, // set if _hpr is defined
|
F_hpr_known = 0x00000800, // set if _hpr is defined
|
||||||
F_uniform_scale = 0x1000,
|
F_uniform_scale = 0x00001000,
|
||||||
F_identity_scale = 0x2000,
|
F_identity_scale = 0x00002000,
|
||||||
F_has_nonzero_shear = 0x4000,
|
F_has_nonzero_shear = 0x00004000,
|
||||||
F_is_destructing = 0x8000,
|
F_is_destructing = 0x00008000,
|
||||||
|
F_is_2d = 0x00010000,
|
||||||
};
|
};
|
||||||
LVecBase3f _pos, _hpr, _scale, _shear;
|
LVecBase3f _pos, _hpr, _scale, _shear;
|
||||||
LQuaternionf _quat;
|
LQuaternionf _quat;
|
||||||
LMatrix4f _mat;
|
LMatrix4f _mat;
|
||||||
LMatrix4f *_inv_mat;
|
LMatrix4f *_inv_mat;
|
||||||
|
|
||||||
unsigned short _flags;
|
unsigned int _flags;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static void register_with_read_factory();
|
static void register_with_read_factory();
|
||||||
|
@ -35,8 +35,9 @@ static const unsigned short _bam_major_ver = 5;
|
|||||||
// Bumped to major version 4 on 4/10/02 to store new scene graph.
|
// Bumped to major version 4 on 4/10/02 to store new scene graph.
|
||||||
// Bumped to major version 5 on 5/6/05 for new Geom implementation.
|
// Bumped to major version 5 on 5/6/05 for new Geom implementation.
|
||||||
|
|
||||||
static const unsigned short _bam_minor_ver = 1;
|
static const unsigned short _bam_minor_ver = 2;
|
||||||
// Bumped to minor version 1 on 7/14/05 to add TextureStage::_saved_result.
|
// Bumped to minor version 1 on 7/14/05 to add TextureStage::_saved_result.
|
||||||
|
// Bumped to minor version 2 on 7/21/05 to add TransformState::is_2d.
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user