mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-02 09:52:27 -04:00
more pgraph refinements
This commit is contained in:
parent
7ac1742772
commit
29e70407b5
@ -160,6 +160,30 @@ update_internals(PartGroup *parent, bool self_changed, bool parent_changed) {
|
||||
}
|
||||
}
|
||||
|
||||
if (net_changed && !_net_transform_nodes.empty()) {
|
||||
CPT(TransformState) t = TransformState::make_mat(_net_transform);
|
||||
|
||||
NodeList::iterator ai;
|
||||
ai = _net_transform_nodes.begin();
|
||||
while (ai != _net_transform_nodes.end()) {
|
||||
PandaNode *node = *ai;
|
||||
node->set_transform(t);
|
||||
++ai;
|
||||
}
|
||||
}
|
||||
|
||||
if (self_changed && !_local_transform_nodes.empty()) {
|
||||
CPT(TransformState) t = TransformState::make_mat(_value);
|
||||
|
||||
NodeList::iterator ai;
|
||||
ai = _local_transform_nodes.begin();
|
||||
while (ai != _local_transform_nodes.end()) {
|
||||
PandaNode *node = *ai;
|
||||
node->set_transform(t);
|
||||
++ai;
|
||||
}
|
||||
}
|
||||
|
||||
return self_changed || net_changed;
|
||||
}
|
||||
|
||||
@ -203,18 +227,6 @@ has_net_transform(NodeRelation *arc) const {
|
||||
return (_net_transform_arcs.count(arc) > 0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CharacterJoint::clear_net_transforms
|
||||
// Access: Public
|
||||
// Description: Removes all arcs from the list of arcs that will be
|
||||
// updated each frame with the joint's net transform
|
||||
// from the root.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CharacterJoint::
|
||||
clear_net_transforms() {
|
||||
_net_transform_arcs.clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CharacterJoint::add_local_transform
|
||||
// Access: Public
|
||||
@ -255,16 +267,110 @@ has_local_transform(NodeRelation *arc) const {
|
||||
return (_local_transform_arcs.count(arc) > 0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CharacterJoint::add_net_transform
|
||||
// Access: Public
|
||||
// Description: Adds the indicated node to the list of nodes that will
|
||||
// be updated each frame with the joint's net transform
|
||||
// from the root. Returns true if the node is
|
||||
// successfully added, false if it had already been
|
||||
// added.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool CharacterJoint::
|
||||
add_net_transform(PandaNode *node) {
|
||||
return _net_transform_nodes.insert(node).second;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CharacterJoint::remove_net_transform
|
||||
// Access: Public
|
||||
// Description: Removes the indicated node from the list of nodes that
|
||||
// will be updated each frame with the joint's net
|
||||
// transform from the root. Returns true if the node is
|
||||
// successfully removed, false if it was not on the
|
||||
// list.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool CharacterJoint::
|
||||
remove_net_transform(PandaNode *node) {
|
||||
return (_net_transform_nodes.erase(node) > 0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CharacterJoint::has_net_transform
|
||||
// Access: Public
|
||||
// Description: Returns true if the node is on the list of nodes that
|
||||
// will be updated each frame with the joint's net
|
||||
// transform from the root, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool CharacterJoint::
|
||||
has_net_transform(PandaNode *node) const {
|
||||
return (_net_transform_nodes.count(node) > 0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CharacterJoint::clear_net_transforms
|
||||
// Access: Public
|
||||
// Description: Removes all nodes from the list of nodes that will be
|
||||
// updated each frame with the joint's net transform
|
||||
// from the root.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CharacterJoint::
|
||||
clear_net_transforms() {
|
||||
_net_transform_arcs.clear();
|
||||
_net_transform_nodes.clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CharacterJoint::add_local_transform
|
||||
// Access: Public
|
||||
// Description: Adds the indicated node to the list of nodes that will
|
||||
// be updated each frame with the joint's local
|
||||
// transform from its parent. Returns true if the node
|
||||
// is successfully added, false if it had already been
|
||||
// added.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool CharacterJoint::
|
||||
add_local_transform(PandaNode *node) {
|
||||
return _local_transform_nodes.insert(node).second;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CharacterJoint::remove_local_transform
|
||||
// Access: Public
|
||||
// Description: Removes the indicated node from the list of nodes that
|
||||
// will be updated each frame with the joint's local
|
||||
// transform from its parent. Returns true if the node
|
||||
// is successfully removed, false if it was not on the
|
||||
// list.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool CharacterJoint::
|
||||
remove_local_transform(PandaNode *node) {
|
||||
return (_local_transform_nodes.erase(node) > 0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CharacterJoint::has_local_transform
|
||||
// Access: Public
|
||||
// Description: Returns true if the node is on the list of nodes that
|
||||
// will be updated each frame with the joint's local
|
||||
// transform from its parent, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool CharacterJoint::
|
||||
has_local_transform(PandaNode *node) const {
|
||||
return (_local_transform_nodes.count(node) > 0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CharacterJoint::clear_local_transforms
|
||||
// Access: Public
|
||||
// Description: Removes all arcs from the list of arcs that will be
|
||||
// Description: Removes all nodes from the list of nodes that will be
|
||||
// updated each frame with the joint's local transform
|
||||
// from its parent.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CharacterJoint::
|
||||
clear_local_transforms() {
|
||||
_local_transform_arcs.clear();
|
||||
_local_transform_nodes.clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -50,11 +50,19 @@ PUBLISHED:
|
||||
bool add_net_transform(NodeRelation *arc);
|
||||
bool remove_net_transform(NodeRelation *arc);
|
||||
bool has_net_transform(NodeRelation *arc) const;
|
||||
void clear_net_transforms();
|
||||
|
||||
bool add_local_transform(NodeRelation *arc);
|
||||
bool remove_local_transform(NodeRelation *arc);
|
||||
bool has_local_transform(NodeRelation *arc) const;
|
||||
|
||||
bool add_net_transform(PandaNode *node);
|
||||
bool remove_net_transform(PandaNode *node);
|
||||
bool has_net_transform(PandaNode *node) const;
|
||||
void clear_net_transforms();
|
||||
|
||||
bool add_local_transform(PandaNode *node);
|
||||
bool remove_local_transform(PandaNode *node);
|
||||
bool has_local_transform(PandaNode *node) const;
|
||||
void clear_local_transforms();
|
||||
|
||||
private:
|
||||
@ -62,6 +70,10 @@ private:
|
||||
ArcList _net_transform_arcs;
|
||||
ArcList _local_transform_arcs;
|
||||
|
||||
typedef pset< PT(PandaNode) > NodeList;
|
||||
NodeList _net_transform_nodes;
|
||||
NodeList _local_transform_nodes;
|
||||
|
||||
public:
|
||||
static void register_with_read_factory(void);
|
||||
virtual void write_datagram(BamWriter* manager, Datagram &me);
|
||||
|
@ -39,6 +39,8 @@ qpCollisionNode(const string &name) :
|
||||
_into_collide_mask(CollideMask::all_on()),
|
||||
_collide_geom(false)
|
||||
{
|
||||
// CollisionNodes are hidden by default.
|
||||
set_draw_mask(DrawMask::all_off());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -129,8 +129,17 @@ convert_mat(CoordinateSystem from, CoordinateSystem to) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int FLOATNAME(LMatrix4)::
|
||||
compare_to(const FLOATNAME(LMatrix4) &other, FLOATTYPE threshold) const {
|
||||
for (int i = 0; i < 16; i++) {
|
||||
if (!IS_THRESHOLD_EQUAL(_m.data[i], other._m.data[i], threshold)) {
|
||||
FLOATTYPE scale = 1.0f / threshold;
|
||||
|
||||
// We compare values in reverse order, since the last row of the
|
||||
// matrix is most likely to be different between different matrices.
|
||||
for (int i = 15; i >= 0; i--) {
|
||||
// We scale both elements into the same range and truncate, rather
|
||||
// than comparing the absolute values of their differences with
|
||||
// IS_THRESHOLD_EQUAL. This prevents a slippery-slope effect
|
||||
// where a == b and b == c but a != c.
|
||||
if (cfloor(_m.data[i] * scale + 0.5) !=
|
||||
cfloor(other._m.data[i] * scale + 0.5)) {
|
||||
return (_m.data[i] < other._m.data[i]) ? -1 : 1;
|
||||
}
|
||||
}
|
||||
|
@ -98,7 +98,14 @@ int FogAttrib::
|
||||
compare_to_impl(const RenderAttrib *other) const {
|
||||
const FogAttrib *ta;
|
||||
DCAST_INTO_R(ta, other, 0);
|
||||
return (int)(_fog - ta->_fog);
|
||||
|
||||
// Comparing pointers by subtraction is problematic. Instead of
|
||||
// doing this, we'll just depend on the built-in != and < operators
|
||||
// for comparing pointers.
|
||||
if (_fog != ta->_fog) {
|
||||
return _fog < ta->_fog ? -1 : 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -98,7 +98,14 @@ int MaterialAttrib::
|
||||
compare_to_impl(const RenderAttrib *other) const {
|
||||
const MaterialAttrib *ta;
|
||||
DCAST_INTO_R(ta, other, 0);
|
||||
return (int)(_material - ta->_material);
|
||||
|
||||
// Comparing pointers by subtraction is problematic. Instead of
|
||||
// doing this, we'll just depend on the built-in != and < operators
|
||||
// for comparing pointers.
|
||||
if (_material != ta->_material) {
|
||||
return _material < ta->_material ? -1 : 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -398,6 +398,7 @@ PandaNode(const PandaNode ©) :
|
||||
cdata->_state = copy_cdata->_state;
|
||||
cdata->_effects = copy_cdata->_effects;
|
||||
cdata->_transform = copy_cdata->_transform;
|
||||
cdata->_draw_mask = copy_cdata->_draw_mask;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -1261,12 +1262,6 @@ children_changed() {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(PandaNode) PandaNode::
|
||||
r_copy_subgraph(PandaNode::InstanceMap &inst_map) const {
|
||||
if (!safe_to_flatten()) {
|
||||
// If this kind of node cannot be copied, quietly return the same
|
||||
// pointer, making an instance instead of a copy.
|
||||
return (PandaNode *)this;
|
||||
}
|
||||
|
||||
PT(PandaNode) copy = make_copy();
|
||||
nassertr(copy != (PandaNode *)NULL, NULL);
|
||||
if (copy->get_type() != get_type()) {
|
||||
|
@ -131,19 +131,21 @@ traverse_below(PandaNode *node, const CullTraverserData &data) {
|
||||
}
|
||||
}
|
||||
|
||||
// Now visit all the node's children.
|
||||
PandaNode::Children cr = node->get_children();
|
||||
int num_children = cr.get_num_children();
|
||||
// Now visit all the node's children. We cannot use the
|
||||
// node->get_children() interface, because that will keep a read
|
||||
// pointer open, and we might end up changing this node during the
|
||||
// traversal.
|
||||
int num_children = node->get_num_children();
|
||||
if (node->has_selective_visibility()) {
|
||||
int i = node->get_first_visible_child();
|
||||
while (i < num_children) {
|
||||
traverse(cr.get_child(i), data);
|
||||
traverse(node->get_child(i), data);
|
||||
i = node->get_next_visible_child(i);
|
||||
}
|
||||
|
||||
} else {
|
||||
for (int i = 0; i < num_children; i++) {
|
||||
traverse(cr.get_child(i), data);
|
||||
traverse(node->get_child(i), data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -713,7 +713,7 @@ do_flatten_siblings(PandaNode *parent_node, PandaNode *child1,
|
||||
<< "Collapsing " << *child1 << " and " << *child2 << "\n";
|
||||
}
|
||||
|
||||
PT(PandaNode) new_child = collapse_nodes(child1, child2, true);
|
||||
PT(PandaNode) new_child = collapse_nodes(child2, child1, true);
|
||||
if (new_child == (PandaNode *)NULL) {
|
||||
if (pgraph_cat.is_debug()) {
|
||||
pgraph_cat.debug()
|
||||
@ -722,7 +722,7 @@ do_flatten_siblings(PandaNode *parent_node, PandaNode *child1,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
choose_name(new_child, child1, child2);
|
||||
choose_name(new_child, child2, child1);
|
||||
|
||||
if (new_child == child1) {
|
||||
new_child->steal_children(child2);
|
||||
|
@ -20,7 +20,7 @@
|
||||
#include "bamReader.h"
|
||||
#include "indent.h"
|
||||
|
||||
RenderAttrib::Attribs RenderAttrib::_attribs;
|
||||
RenderAttrib::Attribs *RenderAttrib::_attribs = NULL;
|
||||
TypeHandle RenderAttrib::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -30,7 +30,15 @@ TypeHandle RenderAttrib::_type_handle;
|
||||
////////////////////////////////////////////////////////////////////
|
||||
RenderAttrib::
|
||||
RenderAttrib() {
|
||||
_saved_entry = _attribs.end();
|
||||
if (_attribs == (Attribs *)NULL) {
|
||||
// Make sure the global _attribs map is allocated. This only has
|
||||
// to be done once. We could make this map static, but then we
|
||||
// run into problems if anyone creates a RenderState object at
|
||||
// static init time; it also seems to cause problems when the
|
||||
// Panda shared library is unloaded at application exit time.
|
||||
_attribs = new Attribs;
|
||||
}
|
||||
_saved_entry = _attribs->end();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -61,9 +69,23 @@ operator = (const RenderAttrib &) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
RenderAttrib::
|
||||
~RenderAttrib() {
|
||||
if (_saved_entry != _attribs.end()) {
|
||||
_attribs.erase(_saved_entry);
|
||||
_saved_entry = _attribs.end();
|
||||
if (_saved_entry != _attribs->end()) {
|
||||
// We cannot make this assertion, because the RenderAttrib has
|
||||
// already partially destructed--this means we cannot look up the
|
||||
// object in the map. In fact, the map is temporarily invalid
|
||||
// until we finish destructing, since we screwed up the ordering
|
||||
// when we changed the return value of get_type().
|
||||
// nassertv(_attribs->find(this) == _saved_entry);
|
||||
|
||||
// Note: this isn't thread-safe, because once the derived class
|
||||
// destructor exits and before this destructor completes, the map
|
||||
// is invalid, and other threads may inadvertently attempt to read
|
||||
// the invalid map. To make it thread-safe, we need to move this
|
||||
// functionality to a separate method, that is to be called from
|
||||
// *each* derived class's destructor (and then we can put the
|
||||
// above assert back in).
|
||||
_attribs->erase(_saved_entry);
|
||||
_saved_entry = _attribs->end();
|
||||
}
|
||||
}
|
||||
|
||||
@ -120,13 +142,13 @@ return_new(RenderAttrib *attrib) {
|
||||
|
||||
// This should be a newly allocated pointer, not one that was used
|
||||
// for anything else.
|
||||
nassertr(attrib->_saved_entry == _attribs.end(), attrib);
|
||||
nassertr(attrib->_saved_entry == _attribs->end(), attrib);
|
||||
|
||||
// Save the attrib in a local PointerTo so that it will be freed at
|
||||
// the end of this function if no one else uses it.
|
||||
CPT(RenderAttrib) pt_attrib = attrib;
|
||||
|
||||
pair<Attribs::iterator, bool> result = _attribs.insert(attrib);
|
||||
pair<Attribs::iterator, bool> result = _attribs->insert(attrib);
|
||||
if (result.second) {
|
||||
// The attribute was inserted; save the iterator and return the
|
||||
// input attribute.
|
||||
|
@ -85,7 +85,7 @@ protected:
|
||||
|
||||
private:
|
||||
typedef pset<const RenderAttrib *, IndirectCompareTo<RenderAttrib> > Attribs;
|
||||
static Attribs _attribs;
|
||||
static Attribs *_attribs;
|
||||
|
||||
Attribs::iterator _saved_entry;
|
||||
|
||||
|
@ -62,6 +62,7 @@ operator = (const RenderEffect &) {
|
||||
RenderEffect::
|
||||
~RenderEffect() {
|
||||
if (_saved_entry != _effects.end()) {
|
||||
nassertv(_effects.find(this) == _saved_entry);
|
||||
_effects.erase(_saved_entry);
|
||||
_saved_entry = _effects.end();
|
||||
}
|
||||
@ -153,6 +154,7 @@ return_new(RenderEffect *effect) {
|
||||
// The effect was inserted; save the iterator and return the
|
||||
// input effect.
|
||||
effect->_saved_entry = result.first;
|
||||
effect->ref(); // **** TEMPORARY HACK
|
||||
return pt_effect;
|
||||
}
|
||||
|
||||
|
@ -113,7 +113,7 @@ compare_to(const Attribute &other) const {
|
||||
return _type.get_index() - other._type.get_index();
|
||||
}
|
||||
if (_attrib != other._attrib) {
|
||||
return _attrib - other._attrib;
|
||||
return _attrib < other._attrib ? -1 : 1;
|
||||
}
|
||||
return _override - other._override;
|
||||
}
|
||||
|
@ -27,10 +27,11 @@
|
||||
#include "indent.h"
|
||||
#include "compareTo.h"
|
||||
|
||||
RenderState::States RenderState::_states;
|
||||
RenderState::States *RenderState::_states = NULL;
|
||||
CPT(RenderState) RenderState::_empty_state;
|
||||
TypeHandle RenderState::_type_handle;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RenderState::Constructor
|
||||
// Access: Protected
|
||||
@ -40,7 +41,15 @@ TypeHandle RenderState::_type_handle;
|
||||
////////////////////////////////////////////////////////////////////
|
||||
RenderState::
|
||||
RenderState() {
|
||||
_saved_entry = _states.end();
|
||||
if (_states == (States *)NULL) {
|
||||
// Make sure the global _states map is allocated. This only has
|
||||
// to be done once. We could make this map static, but then we
|
||||
// run into problems if anyone creates a RenderState object at
|
||||
// static init time; it also seems to cause problems when the
|
||||
// Panda shared library is unloaded at application exit time.
|
||||
_states = new States;
|
||||
}
|
||||
_saved_entry = _states->end();
|
||||
_self_compose = (RenderState *)NULL;
|
||||
_flags = 0;
|
||||
}
|
||||
@ -73,10 +82,10 @@ operator = (const RenderState &) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
RenderState::
|
||||
~RenderState() {
|
||||
// Remove the deleted RenderState object from the global pool.
|
||||
if (_saved_entry != _states.end()) {
|
||||
_states.erase(_saved_entry);
|
||||
_saved_entry = _states.end();
|
||||
if (_saved_entry != _states->end()) {
|
||||
nassertv(_states->find(this) == _saved_entry);
|
||||
_states->erase(_saved_entry);
|
||||
_saved_entry = _states->end();
|
||||
}
|
||||
|
||||
// Now make sure we clean up all other floating pointers to the
|
||||
@ -725,20 +734,21 @@ return_new(RenderState *state) {
|
||||
|
||||
// This should be a newly allocated pointer, not one that was used
|
||||
// for anything else.
|
||||
nassertr(state->_saved_entry == _states.end(), state);
|
||||
nassertr(state->_saved_entry == _states->end(), state);
|
||||
|
||||
// Save the state in a local PointerTo so that it will be freed at
|
||||
// the end of this function if no one else uses it.
|
||||
CPT(RenderState) pt_state = state;
|
||||
|
||||
pair<States::iterator, bool> result = _states.insert(state);
|
||||
pair<States::iterator, bool> result = _states->insert(state);
|
||||
|
||||
if (result.second) {
|
||||
// The state was inserted; save the iterator and return the
|
||||
// input state.
|
||||
state->_saved_entry = result.first;
|
||||
return pt_state;
|
||||
}
|
||||
|
||||
|
||||
// The state was not inserted; there must be an equivalent one
|
||||
// already in the set. Return that one.
|
||||
return *(result.first);
|
||||
@ -976,8 +986,8 @@ complete_pointers(TypedWritable **p_list, BamReader *manager) {
|
||||
|
||||
// Now make sure the array is properly sorted. (It won't
|
||||
// necessarily preserve its correct sort after being read from bam,
|
||||
// because the sort is based on TypeHandle indices, which can change
|
||||
// from session to session.)
|
||||
// because the sort is based on TypeHandle indices and raw pointers,
|
||||
// both of which can change from session to session.)
|
||||
_attributes.sort();
|
||||
|
||||
return pi;
|
||||
|
@ -106,7 +106,7 @@ private:
|
||||
|
||||
private:
|
||||
typedef pset<const RenderState *, IndirectLess<RenderState> > States;
|
||||
static States _states;
|
||||
static States *_states;
|
||||
static CPT(RenderState) _empty_state;
|
||||
|
||||
// This iterator records the entry corresponding to this RenderState
|
||||
|
@ -98,7 +98,14 @@ int TextureAttrib::
|
||||
compare_to_impl(const RenderAttrib *other) const {
|
||||
const TextureAttrib *ta;
|
||||
DCAST_INTO_R(ta, other, 0);
|
||||
return (int)(_texture - ta->_texture);
|
||||
|
||||
// Comparing pointers by subtraction is problematic. Instead of
|
||||
// doing this, we'll just depend on the built-in != and < operators
|
||||
// for comparing pointers.
|
||||
if (_texture != ta->_texture) {
|
||||
return _texture < ta->_texture ? -1 : 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -24,7 +24,7 @@
|
||||
#include "indent.h"
|
||||
#include "compareTo.h"
|
||||
|
||||
TransformState::States TransformState::_states;
|
||||
TransformState::States *TransformState::_states = NULL;
|
||||
CPT(TransformState) TransformState::_identity_state;
|
||||
TypeHandle TransformState::_type_handle;
|
||||
|
||||
@ -37,7 +37,15 @@ TypeHandle TransformState::_type_handle;
|
||||
////////////////////////////////////////////////////////////////////
|
||||
TransformState::
|
||||
TransformState() {
|
||||
_saved_entry = _states.end();
|
||||
if (_states == (States *)NULL) {
|
||||
// Make sure the global _states map is allocated. This only has
|
||||
// to be done once. We could make this map static, but then we
|
||||
// run into problems if anyone creates a RenderState object at
|
||||
// static init time; it also seems to cause problems when the
|
||||
// Panda shared library is unloaded at application exit time.
|
||||
_states = new States;
|
||||
}
|
||||
_saved_entry = _states->end();
|
||||
_self_compose = (TransformState *)NULL;
|
||||
_flags = F_is_identity | F_singular_known;
|
||||
_inv_mat = (LMatrix4f *)NULL;
|
||||
@ -77,9 +85,10 @@ TransformState::
|
||||
}
|
||||
|
||||
// Remove the deleted TransformState object from the global pool.
|
||||
if (_saved_entry != _states.end()) {
|
||||
_states.erase(_saved_entry);
|
||||
_saved_entry = _states.end();
|
||||
if (_saved_entry != _states->end()) {
|
||||
nassertv(_states->find(this) == _saved_entry);
|
||||
_states->erase(_saved_entry);
|
||||
_saved_entry = _states->end();
|
||||
}
|
||||
|
||||
// Now make sure we clean up all other floating pointers to the
|
||||
@ -540,13 +549,13 @@ return_new(TransformState *state) {
|
||||
|
||||
// This should be a newly allocated pointer, not one that was used
|
||||
// for anything else.
|
||||
nassertr(state->_saved_entry == _states.end(), state);
|
||||
nassertr(state->_saved_entry == _states->end(), state);
|
||||
|
||||
// Save the state in a local PointerTo so that it will be freed at
|
||||
// the end of this function if no one else uses it.
|
||||
CPT(TransformState) pt_state = state;
|
||||
|
||||
pair<States::iterator, bool> result = _states.insert(state);
|
||||
pair<States::iterator, bool> result = _states->insert(state);
|
||||
if (result.second) {
|
||||
// The state was inserted; save the iterator and return the
|
||||
// input state.
|
||||
|
@ -109,7 +109,7 @@ private:
|
||||
|
||||
private:
|
||||
typedef pset<const TransformState *, IndirectLess<TransformState> > States;
|
||||
static States _states;
|
||||
static States *_states;
|
||||
static CPT(TransformState) _identity_state;
|
||||
|
||||
// This iterator records the entry corresponding to this TransformState
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "pgItem.h"
|
||||
#include "pgMouseWatcherGroup.h"
|
||||
#include "pgCullTraverser.h"
|
||||
#include "cullBinAttrib.h"
|
||||
|
||||
#include "omniBoundingVolume.h"
|
||||
|
||||
@ -40,6 +41,14 @@ qpPGTop(const string &name) :
|
||||
// culling.
|
||||
set_bound(OmniBoundingVolume());
|
||||
set_final(true);
|
||||
|
||||
// Also, screw state sorting. By default, everything under PGTop
|
||||
// will be unsorted: rendered in scene graph order. This is closer
|
||||
// to what the user wants anyway in a 2-d scene graph.
|
||||
|
||||
// This override of 1000 should really be a system constant
|
||||
// somewhere.
|
||||
set_attrib(CullBinAttrib::make("unsorted", 0), 1000);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -81,10 +81,13 @@ init_libtext() {
|
||||
string text_encoding = config_text.GetString("text-encoding", "iso8859");
|
||||
if (text_encoding == "iso8859") {
|
||||
TextNode::_default_encoding = TextNode::E_iso8859;
|
||||
qpTextNode::_default_encoding = qpTextNode::E_iso8859;
|
||||
} else if (text_encoding == "utf8") {
|
||||
TextNode::_default_encoding = TextNode::E_utf8;
|
||||
qpTextNode::_default_encoding = qpTextNode::E_utf8;
|
||||
} else if (text_encoding == "unicode") {
|
||||
TextNode::_default_encoding = TextNode::E_unicode;
|
||||
qpTextNode::_default_encoding = qpTextNode::E_unicode;
|
||||
} else {
|
||||
text_cat.error()
|
||||
<< "Invalid text-encoding: " << text_encoding << "\n";
|
||||
|
Loading…
x
Reference in New Issue
Block a user