285 lines
10 KiB
C++
285 lines
10 KiB
C++
// Filename: transformState.h
|
|
// Created by: drose (25Feb02)
|
|
//
|
|
////////////////////////////////////////////////////////////////////
|
|
//
|
|
// PANDA 3D SOFTWARE
|
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
|
//
|
|
// All use of this software is subject to the terms of the Panda 3d
|
|
// Software license. You should have received a copy of this license
|
|
// along with this source code; you will also find a current copy of
|
|
// the license at http://www.panda3d.org/license.txt .
|
|
//
|
|
// To contact the maintainers of this program write to
|
|
// panda3d@yahoogroups.com .
|
|
//
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
#ifndef TRANSFORMSTATE_H
|
|
#define TRANSFORMSTATE_H
|
|
|
|
#include "pandabase.h"
|
|
|
|
#include "typedWritableReferenceCount.h"
|
|
#include "pointerTo.h"
|
|
#include "indirectLess.h"
|
|
#include "luse.h"
|
|
#include "pset.h"
|
|
#include "event.h"
|
|
|
|
class GraphicsStateGuardianBase;
|
|
class FactoryParams;
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Class : TransformState
|
|
// Description : Indicates a coordinate-system transform on vertices.
|
|
// TransformStates are the primary means for storing
|
|
// transformations on the scene graph.
|
|
//
|
|
// Transforms may be specified in one of two ways:
|
|
// componentwise, with a pos-hpr-scale, or with an
|
|
// arbitrary transform matrix. If you specify a
|
|
// transform componentwise, it will remember its
|
|
// original components.
|
|
//
|
|
// TransformState objects are managed very much like
|
|
// RenderState objects. They are immutable and
|
|
// reference-counted automatically.
|
|
//
|
|
// You should not attempt to create or modify a
|
|
// TransformState object directly. Instead, call one of
|
|
// the make() functions to create one for you. And
|
|
// instead of modifying a TransformState object, create a
|
|
// new one.
|
|
////////////////////////////////////////////////////////////////////
|
|
class EXPCL_PANDA TransformState : public TypedWritableReferenceCount {
|
|
protected:
|
|
TransformState();
|
|
|
|
private:
|
|
TransformState(const TransformState ©);
|
|
void operator = (const TransformState ©);
|
|
|
|
public:
|
|
virtual ~TransformState();
|
|
|
|
bool operator < (const TransformState &other) const;
|
|
|
|
PUBLISHED:
|
|
static CPT(TransformState) make_identity();
|
|
static CPT(TransformState) make_invalid();
|
|
INLINE static CPT(TransformState) make_pos(const LVecBase3f &pos);
|
|
INLINE static CPT(TransformState) make_hpr(const LVecBase3f &hpr);
|
|
INLINE static CPT(TransformState) make_quat(const LQuaternionf &quat);
|
|
INLINE static CPT(TransformState) make_pos_hpr(const LVecBase3f &pos,
|
|
const LVecBase3f &hpr);
|
|
INLINE static CPT(TransformState) make_scale(float scale);
|
|
INLINE static CPT(TransformState) make_scale(const LVecBase3f &scale);
|
|
INLINE static CPT(TransformState) make_shear(const LVecBase3f &scale);
|
|
INLINE static CPT(TransformState) make_pos_hpr_scale(const LVecBase3f &pos,
|
|
const LVecBase3f &hpr,
|
|
const LVecBase3f &scale);
|
|
INLINE static CPT(TransformState) make_pos_quat_scale(const LVecBase3f &pos,
|
|
const LQuaternionf &quat,
|
|
const LVecBase3f &scale);
|
|
static CPT(TransformState) make_pos_hpr_scale_shear(const LVecBase3f &pos,
|
|
const LVecBase3f &hpr,
|
|
const LVecBase3f &scale,
|
|
const LVecBase3f &shear);
|
|
static CPT(TransformState) make_pos_quat_scale_shear(const LVecBase3f &pos,
|
|
const LQuaternionf &quat,
|
|
const LVecBase3f &scale,
|
|
const LVecBase3f &shear);
|
|
static CPT(TransformState) make_mat(const LMatrix4f &mat);
|
|
|
|
INLINE bool is_identity() const;
|
|
INLINE bool is_invalid() const;
|
|
INLINE bool is_singular() const;
|
|
INLINE bool has_components() const;
|
|
INLINE bool components_given() const;
|
|
INLINE bool hpr_given() const;
|
|
INLINE bool quat_given() const;
|
|
INLINE bool has_pos() const;
|
|
INLINE bool has_hpr() const;
|
|
INLINE bool has_quat() const;
|
|
INLINE bool has_scale() const;
|
|
INLINE bool has_uniform_scale() const;
|
|
INLINE bool has_shear() const;
|
|
INLINE bool has_nonzero_shear() const;
|
|
INLINE bool has_mat() const;
|
|
INLINE const LVecBase3f &get_pos() const;
|
|
INLINE const LVecBase3f &get_hpr() const;
|
|
INLINE const LQuaternionf &get_quat() const;
|
|
INLINE const LVecBase3f &get_scale() const;
|
|
INLINE float get_uniform_scale() const;
|
|
INLINE const LVecBase3f &get_shear() const;
|
|
INLINE const LMatrix4f &get_mat() const;
|
|
|
|
CPT(TransformState) set_pos(const LVecBase3f &pos) const;
|
|
CPT(TransformState) set_hpr(const LVecBase3f &hpr) const;
|
|
CPT(TransformState) set_quat(const LQuaternionf &quat) const;
|
|
CPT(TransformState) set_scale(const LVecBase3f &scale) const;
|
|
CPT(TransformState) set_shear(const LVecBase3f &shear) const;
|
|
|
|
CPT(TransformState) compose(const TransformState *other) const;
|
|
CPT(TransformState) invert_compose(const TransformState *other) const;
|
|
|
|
void output(ostream &out) const;
|
|
void write(ostream &out, int indent_level) const;
|
|
|
|
static int get_num_states();
|
|
static int get_num_unused_states();
|
|
static int clear_cache();
|
|
|
|
private:
|
|
static CPT(TransformState) return_new(TransformState *state);
|
|
CPT(TransformState) do_compose(const TransformState *other) const;
|
|
CPT(TransformState) do_invert_compose(const TransformState *other) const;
|
|
|
|
private:
|
|
typedef pset<const TransformState *, IndirectLess<TransformState> > States;
|
|
static States *_states;
|
|
static CPT(TransformState) _identity_state;
|
|
|
|
// This iterator records the entry corresponding to this TransformState
|
|
// object in the above global set. We keep the iterator around so
|
|
// we can remove it when the TransformState destructs.
|
|
States::iterator _saved_entry;
|
|
|
|
// This data structure manages the job of caching the composition of
|
|
// two TransformStates. It's complicated because we have to be sure to
|
|
// remove the entry if *either* of the input TransformStates destructs.
|
|
// To implement this, we always record Composition entries in pairs,
|
|
// one in each of the two involved TransformState objects.
|
|
class Composition {
|
|
public:
|
|
INLINE Composition();
|
|
INLINE Composition(const Composition ©);
|
|
|
|
CPT(TransformState) _result;
|
|
};
|
|
|
|
typedef pmap<const TransformState *, Composition> CompositionCache;
|
|
CompositionCache _composition_cache;
|
|
CompositionCache _invert_composition_cache;
|
|
|
|
// Thise pointer is used to cache the result of compose(this). This
|
|
// has to be a special case, because we have to handle the reference
|
|
// counts carefully so that we don't leak.
|
|
const TransformState *_self_compose;
|
|
|
|
private:
|
|
// This is the actual data within the TransformState.
|
|
INLINE void check_singular() const;
|
|
INLINE void check_components() const;
|
|
INLINE void check_hpr() const;
|
|
INLINE void check_quat() const;
|
|
INLINE void check_mat() const;
|
|
void calc_singular();
|
|
void calc_components();
|
|
void calc_hpr();
|
|
void calc_quat();
|
|
void calc_mat();
|
|
|
|
INLINE void check_uniform_scale();
|
|
|
|
INLINE void set_destructing();
|
|
INLINE bool is_destructing() const;
|
|
|
|
enum Flags {
|
|
F_is_identity = 0x0001,
|
|
F_is_singular = 0x0002,
|
|
F_singular_known = 0x0004, // set if we know F_is_singular
|
|
F_components_given = 0x0008,
|
|
F_components_known = 0x0010, // set if we know F_has_components
|
|
F_has_components = 0x0020,
|
|
F_mat_known = 0x0040, // set if _mat is defined
|
|
F_is_invalid = 0x0080,
|
|
F_quat_given = 0x0100,
|
|
F_quat_known = 0x0200, // set if _quat is defined
|
|
F_hpr_given = 0x0400,
|
|
F_hpr_known = 0x0800, // set if _hpr is defined
|
|
F_uniform_scale = 0x1000,
|
|
F_has_nonzero_shear = 0x2000,
|
|
F_is_destructing = 0x8000,
|
|
};
|
|
LVecBase3f _pos, _hpr, _scale, _shear;
|
|
LQuaternionf _quat;
|
|
LMatrix4f _mat;
|
|
LMatrix4f *_inv_mat;
|
|
|
|
unsigned short _flags;
|
|
|
|
public:
|
|
static void register_with_read_factory();
|
|
virtual void write_datagram(BamWriter *manager, Datagram &dg);
|
|
static TypedWritable *change_this(TypedWritable *old_ptr, BamReader *manager);
|
|
virtual void finalize();
|
|
|
|
protected:
|
|
static TypedWritable *make_from_bam(const FactoryParams ¶ms);
|
|
void fillin(DatagramIterator &scan, BamReader *manager);
|
|
|
|
public:
|
|
static TypeHandle get_class_type() {
|
|
return _type_handle;
|
|
}
|
|
static void init_type() {
|
|
TypedWritableReferenceCount::init_type();
|
|
register_type(_type_handle, "TransformState",
|
|
TypedWritableReferenceCount::get_class_type());
|
|
}
|
|
virtual TypeHandle get_type() const {
|
|
return get_class_type();
|
|
}
|
|
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
|
|
|
|
private:
|
|
static TypeHandle _type_handle;
|
|
};
|
|
|
|
INLINE ostream &operator << (ostream &out, const TransformState &state) {
|
|
state.output(out);
|
|
return out;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Class : EventStoreTransform
|
|
// Description : This class is used to pass TransformState pointers as
|
|
// parameters to events, or as elements on a data graph.
|
|
////////////////////////////////////////////////////////////////////
|
|
class EXPCL_PANDA EventStoreTransform : public EventStoreValueBase {
|
|
public:
|
|
INLINE EventStoreTransform(const TransformState *value);
|
|
INLINE void set_value(const TransformState *value);
|
|
INLINE const TransformState *get_value() const;
|
|
|
|
virtual void output(ostream &out) const;
|
|
|
|
CPT(TransformState) _value;
|
|
|
|
public:
|
|
virtual TypeHandle get_type() const {
|
|
return get_class_type();
|
|
}
|
|
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
|
|
static TypeHandle get_class_type() {
|
|
return _type_handle;
|
|
}
|
|
static void init_type() {
|
|
EventStoreValueBase::init_type();
|
|
register_type(_type_handle, "EventStoreTransform",
|
|
EventStoreValueBase::get_class_type());
|
|
}
|
|
|
|
private:
|
|
static TypeHandle _type_handle;
|
|
};
|
|
|
|
#include "transformState.I"
|
|
|
|
#endif
|
|
|