mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 02:15:43 -04:00
steps toward async flatten
This commit is contained in:
parent
301e051f35
commit
9b575fbe58
@ -146,15 +146,27 @@ get_root_xform() const {
|
||||
return cdata->_root_xform;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PartBundle::get_num_nodes
|
||||
// Access: Published
|
||||
// Description: Returns the number of PartBundleNodes that contain a
|
||||
// pointer to this PartBundle.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int PartBundle::
|
||||
get_num_nodes() const {
|
||||
return _nodes.size();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PartBundle::get_node
|
||||
// Access: Published
|
||||
// Description: Returns the PartBundleNode associated with this
|
||||
// PartBundle.
|
||||
// Description: Returns the nth PartBundleNode associated with
|
||||
// this PartBundle.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PartBundleNode *PartBundle::
|
||||
get_node() const {
|
||||
return _node;
|
||||
get_node(int n) const {
|
||||
nassertr(n >= 0 && n < (int)_nodes.size(), NULL);
|
||||
return _nodes[n];
|
||||
}
|
||||
|
||||
|
||||
|
@ -30,6 +30,8 @@
|
||||
#include "bamWriter.h"
|
||||
#include "configVariableEnum.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
TypeHandle PartBundle::_type_handle;
|
||||
|
||||
|
||||
@ -64,8 +66,7 @@ PartBundle(const PartBundle ©) :
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PartBundle::
|
||||
PartBundle(const string &name) :
|
||||
PartGroup(name),
|
||||
_node(NULL)
|
||||
PartGroup(name)
|
||||
{
|
||||
}
|
||||
|
||||
@ -319,16 +320,33 @@ control_activated(AnimControl *control) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PartBundle::set_node
|
||||
// Function: PartBundle::add_node
|
||||
// Access: Protected, Virtual
|
||||
// Description: Changes the PartBundleNode pointer associated with
|
||||
// the PartBundle. Normally called only by the
|
||||
// PartBundleNode itself, for instance when the bundle
|
||||
// is flattened with another node.
|
||||
// Description: Adds the PartBundleNode pointer to the set of nodes
|
||||
// associated with the PartBundle. Normally called only
|
||||
// by the PartBundleNode itself, for instance when the
|
||||
// bundle is flattened with another node.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PartBundle::
|
||||
set_node(PartBundleNode *node) {
|
||||
_node = node;
|
||||
add_node(PartBundleNode *node) {
|
||||
nassertv(find(_nodes.begin(), _nodes.end(), node) == _nodes.end());
|
||||
_nodes.push_back(node);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PartBundle::remove_node
|
||||
// Access: Protected, Virtual
|
||||
// Description: Removes the PartBundleNode pointer from the set of
|
||||
// nodes associated with the PartBundle. Normally
|
||||
// called only by the PartBundleNode itself, for
|
||||
// instance when the bundle is flattened with another
|
||||
// node.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PartBundle::
|
||||
remove_node(PartBundleNode *node) {
|
||||
Nodes::iterator ni = find(_nodes.begin(), _nodes.end(), node);
|
||||
nassertv(ni != _nodes.end());
|
||||
_nodes.erase(ni);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "cycleDataReader.h"
|
||||
#include "cycleDataWriter.h"
|
||||
#include "luse.h"
|
||||
#include "pvector.h"
|
||||
|
||||
class AnimBundle;
|
||||
class PartBundleNode;
|
||||
@ -105,7 +106,8 @@ PUBLISHED:
|
||||
INLINE void xform(const LMatrix4f &mat);
|
||||
INLINE const LMatrix4f &get_root_xform() const;
|
||||
|
||||
INLINE PartBundleNode *get_node() const;
|
||||
INLINE int get_num_nodes() const;
|
||||
INLINE PartBundleNode *get_node(int n) const;
|
||||
|
||||
void clear_control_effects();
|
||||
INLINE void set_control_effect(AnimControl *control, float effect);
|
||||
@ -128,7 +130,8 @@ public:
|
||||
virtual void control_activated(AnimControl *control);
|
||||
|
||||
protected:
|
||||
virtual void set_node(PartBundleNode *node);
|
||||
virtual void add_node(PartBundleNode *node);
|
||||
virtual void remove_node(PartBundleNode *node);
|
||||
|
||||
private:
|
||||
class CData;
|
||||
@ -138,7 +141,8 @@ private:
|
||||
void recompute_net_blend(CData *cdata);
|
||||
void clear_and_stop_intersecting(AnimControl *control, CData *cdata);
|
||||
|
||||
PartBundleNode *_node;
|
||||
typedef pvector<PartBundleNode *> Nodes;
|
||||
Nodes _nodes;
|
||||
|
||||
// This is the data that must be cycled between pipeline stages.
|
||||
class CData : public CycleData {
|
||||
|
@ -33,24 +33,30 @@ PartBundleNode::
|
||||
~PartBundleNode() {
|
||||
Bundles::iterator bi;
|
||||
for (bi = _bundles.begin(); bi != _bundles.end(); ++bi) {
|
||||
nassertv((*bi)->_node == this);
|
||||
(*bi)->_node = NULL;
|
||||
(*bi)->remove_node(this);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PartBundleNode::safe_to_flatten
|
||||
// Function: PartBundleNode::safe_to_transform
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns true if it is generally safe to flatten out
|
||||
// this particular kind of Node by duplicating
|
||||
// instances, false otherwise (for instance, a Camera
|
||||
// cannot be safely flattened, because the Camera
|
||||
// pointer itself is meaningful).
|
||||
// Description: Returns true if it is generally safe to transform
|
||||
// this particular kind of PandaNode by calling the
|
||||
// xform() method, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool PartBundleNode::
|
||||
safe_to_flatten() const {
|
||||
safe_to_transform() const {
|
||||
// If any of our bundles appear on multiple nodes, we can't
|
||||
// transform any of them without transforming all of them at once.
|
||||
Bundles::const_iterator bi;
|
||||
for (bi = _bundles.begin(); bi != _bundles.end(); ++bi) {
|
||||
if ((*bi)->get_num_nodes() > 1) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PartBundleNode::xform
|
||||
@ -61,6 +67,11 @@ safe_to_flatten() const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PartBundleNode::
|
||||
xform(const LMatrix4f &mat) {
|
||||
if (mat.almost_equal(LMatrix4f::ident_mat())) {
|
||||
// Don't bother.
|
||||
return;
|
||||
}
|
||||
|
||||
Bundles::iterator bi;
|
||||
for (bi = _bundles.begin(); bi != _bundles.end(); ++bi) {
|
||||
(*bi)->xform(mat);
|
||||
@ -74,9 +85,8 @@ xform(const LMatrix4f &mat) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PartBundleNode::
|
||||
add_bundle(PartBundle *bundle) {
|
||||
nassertv(bundle->_node == NULL);
|
||||
_bundles.push_back(bundle);
|
||||
bundle->set_node(this);
|
||||
bundle->add_node(this);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -91,7 +101,8 @@ steal_bundles(PartBundleNode *other) {
|
||||
for (bi = other->_bundles.begin(); bi != other->_bundles.end(); ++bi) {
|
||||
PartBundle *bundle = (*bi);
|
||||
_bundles.push_back(bundle);
|
||||
bundle->set_node(this);
|
||||
bundle->remove_node(other);
|
||||
bundle->add_node(this);
|
||||
}
|
||||
other->_bundles.clear();
|
||||
}
|
||||
@ -127,7 +138,7 @@ complete_pointers(TypedWritable **p_list, BamReader* manager) {
|
||||
Bundles::iterator bi;
|
||||
for (bi = _bundles.begin(); bi != _bundles.end(); ++bi) {
|
||||
(*bi) = DCAST(PartBundle, p_list[pi++]);
|
||||
(*bi)->_node = this;
|
||||
(*bi)->add_node(this);
|
||||
}
|
||||
|
||||
return pi;
|
||||
|
@ -43,7 +43,7 @@ protected:
|
||||
|
||||
public:
|
||||
virtual ~PartBundleNode();
|
||||
virtual bool safe_to_flatten() const;
|
||||
virtual bool safe_to_transform() const;
|
||||
virtual void xform(const LMatrix4f &mat);
|
||||
|
||||
PUBLISHED:
|
||||
|
@ -40,25 +40,29 @@ PStatCollector Character::_animation_pcollector("*:Animation");
|
||||
// Description: Use make_copy() or copy_subgraph() to copy a Character.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
Character::
|
||||
Character(const Character ©) :
|
||||
Character(const Character ©, bool copy_bundles) :
|
||||
PartBundleNode(copy),
|
||||
_joints_pcollector(copy._joints_pcollector),
|
||||
_skinning_pcollector(copy._skinning_pcollector)
|
||||
{
|
||||
set_cull_callback();
|
||||
|
||||
if (copy_bundles) {
|
||||
// Copy the bundle(s).
|
||||
int num_bundles = copy.get_num_bundles();
|
||||
for (int i = 0; i < num_bundles; ++i) {
|
||||
PartBundle *orig_bundle = copy.get_bundle(i);
|
||||
PartBundle *new_bundle =
|
||||
new CharacterJointBundle(orig_bundle->get_name());
|
||||
PT(PartBundle) new_bundle = DCAST(PartBundle, orig_bundle->copy_subgraph());
|
||||
add_bundle(new_bundle);
|
||||
|
||||
// Make a copy of the joint/slider hierarchy.
|
||||
copy_joints(new_bundle, orig_bundle);
|
||||
}
|
||||
|
||||
} else {
|
||||
// Share the bundles.
|
||||
int num_bundles = copy.get_num_bundles();
|
||||
for (int i = 0; i < num_bundles; ++i) {
|
||||
PartBundle *orig_bundle = copy.get_bundle(i);
|
||||
add_bundle(orig_bundle);
|
||||
}
|
||||
}
|
||||
_last_auto_update = -1.0;
|
||||
}
|
||||
|
||||
@ -102,7 +106,22 @@ Character::
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PandaNode *Character::
|
||||
make_copy() const {
|
||||
return new Character(*this);
|
||||
return new Character(*this, true);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Character::dupe_for_flatten
|
||||
// Access: Public, Virtual
|
||||
// Description: This is similar to make_copy(), but it makes a copy
|
||||
// for the specific purpose of flatten. Typically, this
|
||||
// will be a new PandaNode with a new pointer, but all
|
||||
// of the internal data will always be shared with the
|
||||
// original; whereas the new node returned by
|
||||
// make_copy() might not share the internal data.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PandaNode *Character::
|
||||
dupe_for_flatten() const {
|
||||
return new Character(*this, false);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -352,31 +371,6 @@ do_update() {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Character::copy_joints
|
||||
// Access: Private
|
||||
// Description: Recursively walks the joint/slider hierarchy and
|
||||
// creates a new copy of the hierarchy.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void Character::
|
||||
copy_joints(PartGroup *copy, PartGroup *orig) {
|
||||
if (copy->get_type() != orig->get_type()) {
|
||||
char_cat.warning()
|
||||
<< "Don't know how to copy " << orig->get_type() << "\n";
|
||||
}
|
||||
|
||||
PartGroup::Children::const_iterator ci;
|
||||
for (ci = orig->_children.begin(); ci != orig->_children.end(); ++ci) {
|
||||
PartGroup *orig_child = (*ci);
|
||||
PartGroup *copy_child = orig_child->make_copy();
|
||||
if (copy_child->is_of_type(CharacterJoint::get_class_type())) {
|
||||
DCAST(CharacterJoint, copy_child)->set_character(this);
|
||||
}
|
||||
copy->_children.push_back(copy_child);
|
||||
copy_joints(copy_child, orig_child);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Character::r_copy_children
|
||||
// Access: Protected, Virtual
|
||||
|
@ -44,13 +44,14 @@ class ComputedVertices;
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA Character : public PartBundleNode {
|
||||
protected:
|
||||
Character(const Character ©);
|
||||
Character(const Character ©, bool copy_bundles);
|
||||
|
||||
public:
|
||||
Character(const string &name);
|
||||
virtual ~Character();
|
||||
|
||||
virtual PandaNode *make_copy() const;
|
||||
virtual PandaNode *dupe_for_flatten() const;
|
||||
|
||||
virtual PandaNode *combine_with(PandaNode *other);
|
||||
virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data);
|
||||
@ -76,7 +77,6 @@ PUBLISHED:
|
||||
|
||||
private:
|
||||
void do_update();
|
||||
void copy_joints(PartGroup *copy, PartGroup *orig);
|
||||
|
||||
typedef pmap<const PandaNode *, PandaNode *> NodeMap;
|
||||
typedef pmap<const PartGroup *, PartGroup *> JointMap;
|
||||
|
@ -37,10 +37,10 @@ CharacterJointBundle(const CharacterJointBundle ©) :
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CharacterJointBundle::get_node
|
||||
// Access: Public
|
||||
// Description: Returns the Character node associated with this
|
||||
// PartBundle.
|
||||
// Description: Returns the nth Character associated with
|
||||
// this PartBundle.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE Character *CharacterJointBundle::
|
||||
get_node() const {
|
||||
return DCAST(Character, PartBundle::get_node());
|
||||
get_node(int n) const {
|
||||
return DCAST(Character, PartBundle::get_node(n));
|
||||
}
|
||||
|
@ -45,22 +45,42 @@ make_copy() const {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CharacterJointBundle::set_node
|
||||
// Function: CharacterJointBundle::add_node
|
||||
// Access: Protected, Virtual
|
||||
// Description: Changes the PartBundleNode pointer associated with
|
||||
// the PartBundle. Normally called only by the
|
||||
// PartBundleNode itself, for instance when the bundle
|
||||
// is flattened with another node.
|
||||
// Description: Adds the PartBundleNode pointer to the set of nodes
|
||||
// associated with the PartBundle. Normally called only
|
||||
// by the PartBundleNode itself, for instance when the
|
||||
// bundle is flattened with another node.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CharacterJointBundle::
|
||||
set_node(PartBundleNode *node) {
|
||||
PartBundle::set_node(node);
|
||||
add_node(PartBundleNode *node) {
|
||||
PartBundle::add_node(node);
|
||||
if (node->is_of_type(Character::get_class_type())) {
|
||||
Character *character = DCAST(Character, node);
|
||||
r_set_character(this, character);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CharacterJointBundle::remove_node
|
||||
// Access: Protected, Virtual
|
||||
// Description: Removes the PartBundleNode pointer from the set of
|
||||
// nodes associated with the PartBundle. Normally
|
||||
// called only by the PartBundleNode itself, for
|
||||
// instance when the bundle is flattened with another
|
||||
// node.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CharacterJointBundle::
|
||||
remove_node(PartBundleNode *node) {
|
||||
PartBundle::remove_node(node);
|
||||
|
||||
// If there is still a Character on the list, assign that one to all
|
||||
// of the joints.
|
||||
if (get_num_nodes() > 0) {
|
||||
r_set_character(this, get_node(get_num_nodes() - 1));
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CharacterJointBundle::r_set_character
|
||||
// Access: Private
|
||||
|
@ -40,11 +40,12 @@ public:
|
||||
CharacterJointBundle(const string &name = "");
|
||||
|
||||
PUBLISHED:
|
||||
INLINE Character *get_node() const;
|
||||
INLINE Character *get_node(int n) const;
|
||||
|
||||
protected:
|
||||
virtual PartGroup *make_copy() const;
|
||||
virtual void set_node(PartBundleNode *node);
|
||||
virtual void add_node(PartBundleNode *node);
|
||||
virtual void remove_node(PartBundleNode *node);
|
||||
|
||||
private:
|
||||
void r_set_character(PartGroup *group, Character *character);
|
||||
|
@ -315,7 +315,7 @@ add_render_texture(Texture *tex, RenderTextureMode mode,
|
||||
tex->set_x_size(Texture::up_to_power_2(get_x_size()));
|
||||
tex->set_y_size(Texture::up_to_power_2(get_y_size()));
|
||||
|
||||
if ((mode == RTM_bind_or_copy)&&(support_render_texture==0)) {
|
||||
if (mode == RTM_bind_or_copy && !support_render_texture) {
|
||||
mode = RTM_copy_texture;
|
||||
}
|
||||
else {
|
||||
|
@ -1043,7 +1043,7 @@ make_camera() {
|
||||
|
||||
PT(Lens) lens = new PerspectiveLens;
|
||||
|
||||
if (aspect_ratio != 0.0f) {
|
||||
if (aspect_ratio != 0.0) {
|
||||
// If we're given an explict aspect ratio, use it
|
||||
lens->set_aspect_ratio(aspect_ratio);
|
||||
|
||||
|
@ -69,6 +69,7 @@
|
||||
lodNode.I lodNode.h \
|
||||
materialAttrib.I materialAttrib.h \
|
||||
materialCollection.I materialCollection.h \
|
||||
modelFlattenRequest.I modelFlattenRequest.h \
|
||||
modelLoadRequest.I modelLoadRequest.h \
|
||||
modelNode.I modelNode.h \
|
||||
modelPool.I modelPool.h \
|
||||
@ -176,6 +177,7 @@
|
||||
lodNode.cxx \
|
||||
materialAttrib.cxx \
|
||||
materialCollection.cxx \
|
||||
modelFlattenRequest.cxx \
|
||||
modelLoadRequest.cxx \
|
||||
modelNode.cxx \
|
||||
modelPool.cxx \
|
||||
@ -278,6 +280,7 @@
|
||||
lodNode.I lodNode.h \
|
||||
materialAttrib.I materialAttrib.h \
|
||||
materialCollection.I materialCollection.h \
|
||||
modelFlattenRequest.I modelFlattenRequest.h \
|
||||
modelLoadRequest.I modelLoadRequest.h \
|
||||
modelNode.I modelNode.h \
|
||||
modelPool.I modelPool.h \
|
||||
|
@ -60,6 +60,7 @@
|
||||
#include "loaderFileTypeRegistry.h"
|
||||
#include "lodNode.h"
|
||||
#include "materialAttrib.h"
|
||||
#include "modelFlattenRequest.h"
|
||||
#include "modelLoadRequest.h"
|
||||
#include "modelNode.h"
|
||||
#include "modelRoot.h"
|
||||
@ -127,6 +128,12 @@ ConfigVariableBool unambiguous_graph
|
||||
"assertion failure instead of just a warning (which can then be "
|
||||
"trapped with assert-abort)."));
|
||||
|
||||
ConfigVariableBool no_unsupported_copy
|
||||
("no-unsupported-copy", false,
|
||||
PRC_DESC("Set this true to make an attempt to copy an unsupported type "
|
||||
"generate an assertion failure instead of just a warning (which "
|
||||
"can then be trapped with assert-abort)."));
|
||||
|
||||
ConfigVariableBool allow_unrelated_wrt
|
||||
("allow-unrelated-wrt", true,
|
||||
PRC_DESC("Set this true to allow unrelated NodePaths (that is, nodes which "
|
||||
@ -341,6 +348,7 @@ init_libpgraph() {
|
||||
LoaderFileType::init_type();
|
||||
LoaderFileTypeBam::init_type();
|
||||
MaterialAttrib::init_type();
|
||||
ModelFlattenRequest::init_type();
|
||||
ModelLoadRequest::init_type();
|
||||
ModelNode::init_type();
|
||||
ModelRoot::init_type();
|
||||
|
@ -37,6 +37,7 @@ NotifyCategoryDecl(portal, EXPCL_PANDA, EXPTP_PANDA);
|
||||
extern ConfigVariableBool fake_view_frustum_cull;
|
||||
extern ConfigVariableBool allow_portal_cull;
|
||||
extern ConfigVariableBool unambiguous_graph;
|
||||
extern ConfigVariableBool no_unsupported_copy;
|
||||
extern ConfigVariableBool allow_unrelated_wrt;
|
||||
extern ConfigVariableBool paranoid_compose;
|
||||
extern ConfigVariableBool compose_componentwise;
|
||||
|
@ -47,6 +47,7 @@ FindApproxLevelEntry(const FindApproxLevelEntry &parent,
|
||||
_approx_path(parent._approx_path),
|
||||
_next(next)
|
||||
{
|
||||
nassertv(validate_ptr(this) && validate_ptr(&parent));
|
||||
nassertv(_node_path.is_valid());
|
||||
}
|
||||
|
||||
|
66
panda/src/pgraph/modelFlattenRequest.I
Normal file
66
panda/src/pgraph/modelFlattenRequest.I
Normal file
@ -0,0 +1,66 @@
|
||||
// Filename: modelFlattenRequest.I
|
||||
// Created by: drose (30Mar07)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, 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://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ModelFlattenRequest::Constructor
|
||||
// Access: Published
|
||||
// Description: Create a new ModelFlattenRequest, and add it to the loader
|
||||
// via load_async(), to begin an asynchronous load.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE ModelFlattenRequest::
|
||||
ModelFlattenRequest(PandaNode *orig) :
|
||||
AsyncTask(orig->get_name()),
|
||||
_orig(orig),
|
||||
_is_ready(false)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ModelFlattenRequest::get_orig
|
||||
// Access: Published
|
||||
// Description: Returns the original, unflattened node.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PandaNode *ModelFlattenRequest::
|
||||
get_orig() const {
|
||||
return _orig;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ModelFlattenRequest::is_ready
|
||||
// Access: Published
|
||||
// Description: Returns true if this request has completed, false if
|
||||
// it is still pending. When this returns true, you may
|
||||
// retrieve the model loaded by calling get_result().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool ModelFlattenRequest::
|
||||
is_ready() const {
|
||||
return _is_ready;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ModelFlattenRequest::get_model
|
||||
// Access: Published
|
||||
// Description: Returns the flattened copy of the model. It is an
|
||||
// error to call this unless is_ready() returns true.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PandaNode *ModelFlattenRequest::
|
||||
get_model() const {
|
||||
nassertr(_is_ready, NULL);
|
||||
return _model;
|
||||
}
|
42
panda/src/pgraph/modelFlattenRequest.cxx
Normal file
42
panda/src/pgraph/modelFlattenRequest.cxx
Normal file
@ -0,0 +1,42 @@
|
||||
// Filename: modelFlattenRequest.cxx
|
||||
// Created by: drose (30Mar07)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, 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://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "modelFlattenRequest.h"
|
||||
#include "nodePath.h"
|
||||
|
||||
TypeHandle ModelFlattenRequest::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ModelFlattenRequest::do_task
|
||||
// Access: Protected, Virtual
|
||||
// Description: Performs the task: that is, copies and flattens the
|
||||
// model.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool ModelFlattenRequest::
|
||||
do_task() {
|
||||
// We make another instance of the original node, so we can safely
|
||||
// flatten that without affecting the original copy.
|
||||
NodePath np("flatten_root");
|
||||
np.attach_new_node(_orig);
|
||||
np.flatten_strong();
|
||||
_model = np.get_child(0).node();
|
||||
_is_ready = true;
|
||||
|
||||
// Don't continue the task; we're done.
|
||||
return false;
|
||||
}
|
74
panda/src/pgraph/modelFlattenRequest.h
Normal file
74
panda/src/pgraph/modelFlattenRequest.h
Normal file
@ -0,0 +1,74 @@
|
||||
// Filename: modelFlattenRequest.h
|
||||
// Created by: drose (30Mar07)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, 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://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef MODELFLATTENREQUEST
|
||||
#define MODELFLATTENREQUEST
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "asyncTask.h"
|
||||
#include "pandaNode.h"
|
||||
#include "pointerTo.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : ModelFlattenRequest
|
||||
// Description : This class object manages a single asynchronous
|
||||
// request to flatten a model. The model will be
|
||||
// duplicated and flattened in a sub-thread (if
|
||||
// threading is available), without affecting the
|
||||
// original model; and when the result is done it may be
|
||||
// retrieved from this object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA ModelFlattenRequest : public AsyncTask {
|
||||
PUBLISHED:
|
||||
INLINE ModelFlattenRequest(PandaNode *orig);
|
||||
|
||||
INLINE PandaNode *get_orig() const;
|
||||
|
||||
INLINE bool is_ready() const;
|
||||
INLINE PandaNode *get_model() const;
|
||||
|
||||
protected:
|
||||
virtual bool do_task();
|
||||
|
||||
private:
|
||||
PT(PandaNode) _orig;
|
||||
bool _is_ready;
|
||||
PT(PandaNode) _model;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
AsyncTask::init_type();
|
||||
register_type(_type_handle, "ModelFlattenRequest",
|
||||
AsyncTask::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;
|
||||
};
|
||||
|
||||
#include "modelFlattenRequest.I"
|
||||
|
||||
#endif
|
@ -196,14 +196,30 @@ make_copy() const {
|
||||
return new PandaNode(*this);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::dupe_for_flatten
|
||||
// Access: Public, Virtual
|
||||
// Description: This is similar to make_copy(), but it makes a copy
|
||||
// for the specific purpose of flatten. Typically, this
|
||||
// will be a new PandaNode with a new pointer, but all
|
||||
// of the internal data will always be shared with the
|
||||
// original; whereas the new node returned by
|
||||
// make_copy() might not share the internal data.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PandaNode *PandaNode::
|
||||
dupe_for_flatten() const {
|
||||
return make_copy();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::safe_to_flatten
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns true if it is generally safe to flatten out
|
||||
// this particular kind of PandaNode by duplicating
|
||||
// instances, false otherwise (for instance, a Camera
|
||||
// cannot be safely flattened, because the Camera
|
||||
// pointer itself is meaningful).
|
||||
// instances (by calling dupe_for_flatten()), false
|
||||
// otherwise (for instance, a Camera cannot be safely
|
||||
// flattened, because the Camera pointer itself is
|
||||
// meaningful).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool PandaNode::
|
||||
safe_to_flatten() const {
|
||||
@ -2397,6 +2413,10 @@ r_copy_subgraph(PandaNode::InstanceMap &inst_map, Thread *current_thread) const
|
||||
if (copy->get_type() != get_type()) {
|
||||
pgraph_cat.warning()
|
||||
<< "Don't know how to copy nodes of type " << get_type() << "\n";
|
||||
|
||||
if (no_unsupported_copy) {
|
||||
nassertr(false, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
copy->r_copy_children(this, inst_map, current_thread);
|
||||
|
@ -83,6 +83,7 @@ private:
|
||||
|
||||
public:
|
||||
virtual PandaNode *make_copy() const;
|
||||
virtual PandaNode *dupe_for_flatten() const;
|
||||
|
||||
virtual bool safe_to_flatten() const;
|
||||
virtual bool safe_to_transform() const;
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "lodNode.cxx"
|
||||
#include "materialAttrib.cxx"
|
||||
#include "materialCollection.cxx"
|
||||
#include "modelFlattenRequest.cxx"
|
||||
#include "modelLoadRequest.cxx"
|
||||
#include "modelNode.cxx"
|
||||
#include "modelPool.cxx"
|
||||
|
@ -175,15 +175,19 @@ r_apply_attribs(PandaNode *node, const AccumulatedAttribs &attribs,
|
||||
pgraph_cat.spam()
|
||||
<< "Cannot duplicate nodes of type " << child_node->get_type()
|
||||
<< ".\n";
|
||||
resist_copy = true;
|
||||
}
|
||||
resist_copy = true;
|
||||
|
||||
} else {
|
||||
PT(PandaNode) new_node = child_node->make_copy();
|
||||
PT(PandaNode) new_node = child_node->dupe_for_flatten();
|
||||
if (new_node->get_type() != child_node->get_type()) {
|
||||
pgraph_cat.error()
|
||||
<< "Don't know how to copy nodes of type "
|
||||
<< child_node->get_type() << "\n";
|
||||
|
||||
if (no_unsupported_copy) {
|
||||
nassertv(false);
|
||||
}
|
||||
resist_copy = true;
|
||||
|
||||
} else {
|
||||
|
@ -74,7 +74,7 @@ private:
|
||||
const WorkingNodePath *_next;
|
||||
PT(NodePathComponent) _start;
|
||||
|
||||
PandaNode *_node;
|
||||
PT(PandaNode) _node;
|
||||
};
|
||||
|
||||
INLINE ostream &operator << (ostream &out, const WorkingNodePath &node_path);
|
||||
|
@ -32,6 +32,13 @@ ConfigureFn(config_pipeline) {
|
||||
init_libpipeline();
|
||||
}
|
||||
|
||||
ConfigVariableBool support_threads
|
||||
("support-threads", true,
|
||||
PRC_DESC("Set this false to disallow the creation of threads using Panda's "
|
||||
"Thread interface, even if threading support is compiled in. This "
|
||||
"does not affect the operation of mutexes and other synchronization "
|
||||
"primitives, just the creation of threads."));
|
||||
|
||||
ConfigVariableInt thread_stack_size
|
||||
("thread-stack-size", 4194304,
|
||||
PRC_DESC("Specifies the minimum size, in bytes, of the stack that will be "
|
||||
|
@ -29,6 +29,7 @@ ConfigureDecl(config_pipeline, EXPCL_PANDA, EXPTP_PANDA);
|
||||
NotifyCategoryDecl(pipeline, EXPCL_PANDA, EXPTP_PANDA);
|
||||
NotifyCategoryDecl(thread, EXPCL_PANDA, EXPTP_PANDA);
|
||||
|
||||
extern ConfigVariableBool support_threads;
|
||||
extern ConfigVariableInt thread_stack_size;
|
||||
extern ConfigVariableBool threads_always_global;
|
||||
extern ConfigVariableBool threads_never_global;
|
||||
|
@ -233,6 +233,9 @@ get_current_pipeline_stage() {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool Thread::
|
||||
is_threading_supported() {
|
||||
if (!support_threads) {
|
||||
return false;
|
||||
}
|
||||
return ThreadImpl::is_threading_supported();
|
||||
}
|
||||
|
||||
|
@ -146,6 +146,12 @@ bool Thread::
|
||||
start(ThreadPriority priority, bool global, bool joinable) {
|
||||
nassertr(!_started, false);
|
||||
|
||||
if (!support_threads) {
|
||||
thread_cat.warning()
|
||||
<< *this << " could not be started: support-threads is false.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (threads_always_global) {
|
||||
global = true;
|
||||
} else if (threads_never_global) {
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "threadPriority.h"
|
||||
#include "threadImpl.h"
|
||||
#include "pnotify.h"
|
||||
#include "config_pipeline.h"
|
||||
|
||||
class Mutex;
|
||||
class ReMutex;
|
||||
|
@ -29,9 +29,6 @@
|
||||
#include "mutexWin32Impl.h"
|
||||
#include "conditionVarWin32Impl.h"
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN 1
|
||||
#include <windows.h>
|
||||
|
||||
class Thread;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
Loading…
x
Reference in New Issue
Block a user