DriveInterface sends componentwise transforms instead of composed matrices

This commit is contained in:
David Rose 2002-06-20 23:07:38 +00:00
parent 4a86946583
commit 2dd29ce829
8 changed files with 39 additions and 168 deletions

View File

@ -221,6 +221,8 @@ init_libpgraph() {
ColorLerpFunctor::init_type(); ColorLerpFunctor::init_type();
ColorScaleLerpFunctor::init_type(); ColorScaleLerpFunctor::init_type();
EventStoreTransform::init_type("EventStoreTransform");
AlphaTestAttrib::register_with_read_factory(); AlphaTestAttrib::register_with_read_factory();
AmbientLight::register_with_read_factory(); AmbientLight::register_with_read_factory();
BillboardEffect::register_with_read_factory(); BillboardEffect::register_with_read_factory();

View File

@ -26,6 +26,7 @@
#include "indirectLess.h" #include "indirectLess.h"
#include "luse.h" #include "luse.h"
#include "pset.h" #include "pset.h"
#include "event.h"
class GraphicsStateGuardianBase; class GraphicsStateGuardianBase;
class FactoryParams; class FactoryParams;
@ -225,6 +226,12 @@ INLINE ostream &operator << (ostream &out, const TransformState &state) {
return out; return out;
} }
// This class is used to pass TransformState pointers as parameters to
// events, or as elements on a data graph.
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, EventStoreValue<CPT(TransformState)>);
typedef EventStoreValue<CPT(TransformState)> EventStoreTransform;
#include "transformState.I" #include "transformState.I"
#endif #endif

View File

@ -300,31 +300,26 @@ get_z() const {
INLINE void DriveInterface:: INLINE void DriveInterface::
set_pos(const LVecBase3f &vec) { set_pos(const LVecBase3f &vec) {
_xyz = vec; _xyz = vec;
recompute();
} }
INLINE void DriveInterface:: INLINE void DriveInterface::
set_pos(float x, float y, float z) { set_pos(float x, float y, float z) {
_xyz.set(x, y, z); _xyz.set(x, y, z);
recompute();
} }
INLINE void DriveInterface:: INLINE void DriveInterface::
set_x(float x) { set_x(float x) {
_xyz[0] = x; _xyz[0] = x;
recompute();
} }
INLINE void DriveInterface:: INLINE void DriveInterface::
set_y(float y) { set_y(float y) {
_xyz[1] = y; _xyz[1] = y;
recompute();
} }
INLINE void DriveInterface:: INLINE void DriveInterface::
set_z(float z) { set_z(float z) {
_xyz[2] = z; _xyz[2] = z;
recompute();
} }
@ -362,90 +357,26 @@ get_r() const {
INLINE void DriveInterface:: INLINE void DriveInterface::
set_hpr(const LVecBase3f &hpr) { set_hpr(const LVecBase3f &hpr) {
_hpr = hpr; _hpr = hpr;
recompute();
} }
INLINE void DriveInterface:: INLINE void DriveInterface::
set_hpr(float h, float p, float r) { set_hpr(float h, float p, float r) {
_hpr.set(h, p, r); _hpr.set(h, p, r);
recompute();
if (_is_force_roll && r != _force_roll) {
reextract();
}
} }
INLINE void DriveInterface:: INLINE void DriveInterface::
set_h(float h) { set_h(float h) {
_hpr[0] = h; _hpr[0] = h;
recompute();
} }
INLINE void DriveInterface:: INLINE void DriveInterface::
set_p(float p) { set_p(float p) {
_hpr[1] = p; _hpr[1] = p;
recompute();
} }
INLINE void DriveInterface:: INLINE void DriveInterface::
set_r(float r) { set_r(float r) {
_hpr[2] = r; _hpr[2] = r;
recompute();
if (_is_force_roll && r != _force_roll) {
reextract();
}
}
////////////////////////////////////////////////////////////////////
// Function: DriveInterface::is_force_roll
// Access: Published
// Description: Returns true if the force_roll state is in effect,
// e.g. because of a previous call to set_force_roll().
// In this state, the roll cannot be set to any value
// other than what the force_roll value indicates.
////////////////////////////////////////////////////////////////////
INLINE bool DriveInterface::
is_force_roll() const {
return _is_force_roll;
}
////////////////////////////////////////////////////////////////////
// Function: DriveInterface::clear_force_roll
// Access: Published
// Description: Disables the force_roll state. See set_force_roll().
////////////////////////////////////////////////////////////////////
INLINE void DriveInterface::
clear_force_roll() {
_is_force_roll = false;
}
////////////////////////////////////////////////////////////////////
// Function: DriveInterface::set_coordinate_system
// Access: Published
// Description: Sets the coordinate system of the DriveInterface.
// Normally, this is the default coordinate system.
// This changes the plane the user drives around in;
// it's normally the horizontal plane (e.g. the X-Y
// plane in a Z-up coordinate system, or the X-Z plane
// in a Y-up coordinate system).
////////////////////////////////////////////////////////////////////
INLINE void DriveInterface::
set_coordinate_system(CoordinateSystem cs) {
_cs = cs;
recompute();
}
////////////////////////////////////////////////////////////////////
// Function: DriveInterface::get_coordinate_system
// Access: Published
// Description: Returns the coordinate system of the DriveInterface.
// See set_coordinate_system().
////////////////////////////////////////////////////////////////////
INLINE CoordinateSystem DriveInterface::
get_coordinate_system() const {
return _cs;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////

View File

@ -111,10 +111,10 @@ DriveInterface(const string &name) :
_xy_input = define_input("xy", EventStoreVec2::get_class_type()); _xy_input = define_input("xy", EventStoreVec2::get_class_type());
_button_events_input = define_input("button_events", ButtonEventList::get_class_type()); _button_events_input = define_input("button_events", ButtonEventList::get_class_type());
_transform_output = define_output("transform", EventStoreMat4::get_class_type()); _transform_output = define_output("transform", EventStoreTransform::get_class_type());
_velocity_output = define_output("velocity", EventStoreVec3::get_class_type()); _velocity_output = define_output("velocity", EventStoreVec3::get_class_type());
_transform = new EventStoreMat4(LMatrix4f::ident_mat()); _transform = new EventStoreTransform(TransformState::make_identity());
_velocity = new EventStoreVec3(LVector3f::zero()); _velocity = new EventStoreVec3(LVector3f::zero());
_forward_speed = drive_forward_speed; _forward_speed = drive_forward_speed;
@ -135,11 +135,7 @@ DriveInterface(const string &name) :
_xyz.set(0.0f, 0.0f, 0.0f); _xyz.set(0.0f, 0.0f, 0.0f);
_hpr.set(0.0f, 0.0f, 0.0f); _hpr.set(0.0f, 0.0f, 0.0f);
_mat = LMatrix4f::ident_mat();
_force_roll = 0.0f;
_is_force_roll = true;
_cs = default_coordinate_system;
_ignore_mouse = false; _ignore_mouse = false;
_force_mouse = false; _force_mouse = false;
@ -169,8 +165,6 @@ void DriveInterface::
reset() { reset() {
_xyz.set(0.0f, 0.0f, 0.0f); _xyz.set(0.0f, 0.0f, 0.0f);
_hpr.set(0.0f, 0.0f, 0.0f); _hpr.set(0.0f, 0.0f, 0.0f);
_force_roll = 0.0f;
_mat = LMatrix4f::ident_mat();
_up_arrow.clear(); _up_arrow.clear();
_down_arrow.clear(); _down_arrow.clear();
_left_arrow.clear(); _left_arrow.clear();
@ -183,49 +177,32 @@ reset() {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: DriveInterface::set_force_roll // Function: DriveInterface::set_force_roll
// Access: Published // Access: Published
// Description: Sets the force_roll state. In this state, roll is // Description: This function is no longer used and does nothing. It
// always fixed to a particular value (typically zero), // will be removed soon.
// regardless of what it is explicitly set to via
// set_hpr().
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void DriveInterface:: void DriveInterface::
set_force_roll(float force_roll) { set_force_roll(float) {
if (_is_force_roll) {
// If we already had force_roll() in effect, we have to
// recompensate for it.
if (_force_roll != force_roll) {
_force_roll = force_roll;
reextract();
}
} else {
_force_roll = force_roll;
_is_force_roll = true;
}
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: DriveInterface::set_mat // Function: DriveInterface::set_mat
// Access: Published // Access: Published
// Description: Stores the indicated transform in the DriveInterface. // Description: Stores the indicated transform in the DriveInterface.
// This is a transform in global space, regardless of
// the rel_to node.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void DriveInterface:: void DriveInterface::
set_mat(const LMatrix4f &mat) { set_mat(const LMatrix4f &mat) {
_mat = mat; LVecBase3f scale;
reextract(); decompose_matrix(mat, scale, _hpr, _xyz);
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: DriveInterface::get_mat // Function: DriveInterface::get_mat
// Access: Published // Access: Published
// Description: Returns the net transformation applied by the // Description: Returns the current transform.
// current state.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
const LMatrix4f &DriveInterface:: const LMatrix4f &DriveInterface::
get_mat() const { get_mat() {
compose_matrix(_mat, LVecBase3f(1.0f, 1.0f, 1.0f), _hpr, _xyz);
return _mat; return _mat;
} }
@ -240,7 +217,7 @@ get_mat() const {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void DriveInterface:: void DriveInterface::
force_dgraph() { force_dgraph() {
_transform->set_value(_mat); _transform->set_value(TransformState::make_pos_hpr(_xyz, _hpr));
_velocity->set_value(_vel); _velocity->set_value(_vel);
DataNodeTransmit output; DataNodeTransmit output;
@ -373,16 +350,16 @@ apply(double x, double y, bool any_button) {
// rot_mat is the rotation matrix corresponding to our previous // rot_mat is the rotation matrix corresponding to our previous
// heading. // heading.
LMatrix3f rot_mat = LMatrix3f rot_mat =
LMatrix3f::rotate_mat_normaxis(_hpr[0], LVector3f::up(_cs), _cs); LMatrix3f::rotate_mat_normaxis(_hpr[0], LVector3f::up());
// Take a step in the direction of our previous heading. // Take a step in the direction of our previous heading.
_vel = LVector3f::forward(_cs) * distance; _vel = LVector3f::forward() * distance;
LVector3f step = (_vel * rot_mat); LVector3f step = (_vel * rot_mat);
// To prevent upward drift due to numerical errors, force the // To prevent upward drift due to numerical errors, force the
// vertical component of our step to zero (it should be pretty near // vertical component of our step to zero (it should be pretty near
// zero anyway). // zero anyway).
switch (_cs) { switch (default_coordinate_system) {
case CS_zup_right: case CS_zup_right:
case CS_zup_left: case CS_zup_left:
step[2] = 0.0f; step[2] = 0.0f;
@ -399,44 +376,6 @@ apply(double x, double y, bool any_button) {
_xyz += step; _xyz += step;
_hpr[0] -= rotation; _hpr[0] -= rotation;
recompute();
}
////////////////////////////////////////////////////////////////////
// Function: DriveInterface::reextract
// Access: Private
// Description: Given a correctly computed _mat matrix, rederive the
// translation and rotation elements.
////////////////////////////////////////////////////////////////////
void DriveInterface::
reextract() {
LVecBase3f scale;
if (_is_force_roll) {
// We strongly discourage a roll other than _force_roll.
decompose_matrix(_mat, scale, _hpr, _xyz, _force_roll);
} else {
decompose_matrix(_mat, scale, _hpr, _xyz);
}
if (tform_cat.is_debug()) {
tform_cat.debug()
<< "Reextract " << _hpr << ", " << _xyz << " from:\n";
_mat.write(tform_cat.debug(false), 2);
}
}
////////////////////////////////////////////////////////////////////
// Function: DriveInterface::recompute
// Access: Private
// Description: Rebuilds the matrix according to the stored rotation
// and translation components.
////////////////////////////////////////////////////////////////////
void DriveInterface::
recompute() {
compose_matrix(_mat, LVecBase3f(1.0f, 1.0f, 1.0f), _hpr, _xyz, _cs);
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -508,7 +447,7 @@ do_transmit_data(const DataNodeTransmit &input, DataNodeTransmit &output) {
} }
apply(x, y, _mods.is_any_down()); apply(x, y, _mods.is_any_down());
_transform->set_value(_mat); _transform->set_value(TransformState::make_pos_hpr(_xyz, _hpr));
_velocity->set_value(_vel); _velocity->set_value(_vel);
output.set_data(_transform_output, EventParameter(_transform)); output.set_data(_transform_output, EventParameter(_transform));
output.set_data(_velocity_output, EventParameter(_velocity)); output.set_data(_velocity_output, EventParameter(_velocity));

View File

@ -25,6 +25,7 @@
#include "modifierButtons.h" #include "modifierButtons.h"
#include "luse.h" #include "luse.h"
#include "linmath_events.h" #include "linmath_events.h"
#include "transformState.h"
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -89,11 +90,6 @@ PUBLISHED:
INLINE void set_r(float r); INLINE void set_r(float r);
void set_force_roll(float force_roll); void set_force_roll(float force_roll);
INLINE bool is_force_roll() const;
INLINE void clear_force_roll();
INLINE void set_coordinate_system(CoordinateSystem cs);
INLINE CoordinateSystem get_coordinate_system() const;
INLINE void set_ignore_mouse(bool ignore_mouse); INLINE void set_ignore_mouse(bool ignore_mouse);
INLINE bool get_ignore_mouse() const; INLINE bool get_ignore_mouse() const;
@ -102,16 +98,13 @@ PUBLISHED:
INLINE bool get_force_mouse() const; INLINE bool get_force_mouse() const;
void set_mat(const LMatrix4f &mat); void set_mat(const LMatrix4f &mat);
const LMatrix4f &get_mat() const; const LMatrix4f &get_mat();
void force_dgraph(); void force_dgraph();
private: private:
void apply(double x, double y, bool any_button); void apply(double x, double y, bool any_button);
void reextract();
void recompute();
float _forward_speed; // units / sec, mouse all the way up float _forward_speed; // units / sec, mouse all the way up
float _reverse_speed; // units / sec, mouse all the way down float _reverse_speed; // units / sec, mouse all the way down
float _rotate_speed; // degrees / sec, mouse all the way over float _rotate_speed; // degrees / sec, mouse all the way over
@ -132,14 +125,13 @@ private:
LPoint3f _xyz; LPoint3f _xyz;
LVecBase3f _hpr; LVecBase3f _hpr;
LMatrix4f _mat;
LVector3f _vel; LVector3f _vel;
float _force_roll;
bool _is_force_roll;
CoordinateSystem _cs;
bool _ignore_mouse; bool _ignore_mouse;
bool _force_mouse; bool _force_mouse;
// This is only used to return a temporary value in get_mat().
LMatrix4f _mat;
// Remember which mouse buttons are being held down. // Remember which mouse buttons are being held down.
ModifierButtons _mods; ModifierButtons _mods;
@ -176,7 +168,7 @@ private:
int _transform_output; int _transform_output;
int _velocity_output; int _velocity_output;
PT(EventStoreMat4) _transform; PT(EventStoreTransform) _transform;
PT(EventStoreVec3) _velocity; PT(EventStoreVec3) _velocity;
public: public:

View File

@ -43,9 +43,9 @@ Trackball(const string &name) :
_pixel_xy_input = define_input("pixel_xy", EventStoreVec2::get_class_type()); _pixel_xy_input = define_input("pixel_xy", EventStoreVec2::get_class_type());
_button_events_input = define_input("button_events", ButtonEventList::get_class_type()); _button_events_input = define_input("button_events", ButtonEventList::get_class_type());
_transform_output = define_output("transform", EventStoreMat4::get_class_type()); _transform_output = define_output("transform", EventStoreTransform::get_class_type());
_transform = new EventStoreMat4(LMatrix4f::ident_mat()); _transform = new EventStoreTransform(TransformState::make_identity());
_rotscale = 0.3f; _rotscale = 0.3f;
_fwdscale = 0.3f; _fwdscale = 0.3f;
@ -570,6 +570,6 @@ do_transmit_data(const DataNodeTransmit &input, DataNodeTransmit &output) {
} }
// Now send our matrix down the pipe. // Now send our matrix down the pipe.
_transform->set_value(_mat); _transform->set_value(TransformState::make_mat(_mat));
output.set_data(_transform_output, EventParameter(_transform)); output.set_data(_transform_output, EventParameter(_transform));
} }

View File

@ -25,7 +25,7 @@
#include "nodePath.h" #include "nodePath.h"
#include "modifierButtons.h" #include "modifierButtons.h"
#include "luse.h" #include "luse.h"
#include "linmath_events.h" #include "transformState.h"
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -135,7 +135,7 @@ private:
// outputs // outputs
int _transform_output; int _transform_output;
PT(EventStoreMat4) _transform; PT(EventStoreTransform) _transform;
public: public:
static TypeHandle get_class_type() { static TypeHandle get_class_type() {

View File

@ -31,7 +31,7 @@ Transform2SG::
Transform2SG(const string &name) : Transform2SG(const string &name) :
DataNode(name) DataNode(name)
{ {
_transform_input = define_input("transform", EventStoreMat4::get_class_type()); _transform_input = define_input("transform", EventStoreTransform::get_class_type());
_velocity_input = define_input("velocity", EventStoreVec3::get_class_type()); _velocity_input = define_input("velocity", EventStoreVec3::get_class_type());
_node = NULL; _node = NULL;
@ -103,11 +103,11 @@ get_velocity_node() const {
void Transform2SG:: void Transform2SG::
do_transmit_data(const DataNodeTransmit &input, DataNodeTransmit &) { do_transmit_data(const DataNodeTransmit &input, DataNodeTransmit &) {
if (input.has_data(_transform_input)) { if (input.has_data(_transform_input)) {
const EventStoreMat4 *transform; const EventStoreTransform *transform;
DCAST_INTO_V(transform, input.get_data(_transform_input).get_ptr()); DCAST_INTO_V(transform, input.get_data(_transform_input).get_ptr());
const LMatrix4f &mat = transform->get_value(); CPT(TransformState) ts = transform->get_value();
if (_node != (PandaNode *)NULL) { if (_node != (PandaNode *)NULL) {
_node->set_transform(TransformState::make_mat(mat)); _node->set_transform(ts);
} }
} }