factor out Thread::get_current_thread() some more

This commit is contained in:
David Rose 2006-04-26 07:31:23 +00:00
parent e45a6a875a
commit ddd1046462
127 changed files with 1375 additions and 1118 deletions

View File

@ -277,7 +277,8 @@ copy_joints(PartGroup *copy, PartGroup *orig) {
// override this function.
////////////////////////////////////////////////////////////////////
void Character::
r_copy_children(const PandaNode *from, PandaNode::InstanceMap &inst_map) {
r_copy_children(const PandaNode *from, PandaNode::InstanceMap &inst_map,
Thread *current_thread) {
// We assume there will be no instancing going on below the
// Character node. If there is, too bad; it will get flattened out.

View File

@ -82,7 +82,8 @@ private:
typedef pmap<const VertexTransform *, PT(JointVertexTransform) > GeomJointMap;
typedef pmap<const VertexSlider *, PT(CharacterVertexSlider) > GeomSliderMap;
virtual void r_copy_children(const PandaNode *from, InstanceMap &inst_map);
virtual void r_copy_children(const PandaNode *from, InstanceMap &inst_map,
Thread *current_thread);
void fill_joint_map(JointMap &joint_map, PartGroup *copy, PartGroup *orig);
void r_copy_char(PandaNode *dest, const PandaNode *source,
const Character *from, NodeMap &node_map,

View File

@ -371,9 +371,9 @@ get_collide_geom() const {
// thing.
////////////////////////////////////////////////////////////////////
PT(BoundingVolume) CollisionNode::
compute_internal_bounds(int pipeline_stage) const {
compute_internal_bounds(int pipeline_stage, Thread *current_thread) const {
// First, get ourselves a fresh, empty bounding volume.
PT(BoundingVolume) bound = PandaNode::compute_internal_bounds(pipeline_stage);
PT(BoundingVolume) bound = PandaNode::compute_internal_bounds(pipeline_stage, current_thread);
nassertr(bound != (BoundingVolume *)NULL, bound);
// Now actually compute the bounding volume by putting it around all

View File

@ -75,7 +75,7 @@ PUBLISHED:
INLINE static CollideMask get_default_collide_mask();
protected:
virtual PT(BoundingVolume) compute_internal_bounds(int pipeline_stage) const;
virtual PT(BoundingVolume) compute_internal_bounds(int pipeline_stage, Thread *current_thread) const;
private:
CPT(RenderState) get_last_pos_state();

View File

@ -59,7 +59,7 @@ make_bin(const string &name, GraphicsStateGuardianBase *gsg) {
// the bin for rendering.
////////////////////////////////////////////////////////////////////
void CullBinBackToFront::
add_object(CullableObject *object) {
add_object(CullableObject *object, Thread *current_thread) {
// Determine the center of the bounding volume.
CPT(BoundingVolume) volume = object->_geom->get_bounds();
@ -86,8 +86,8 @@ add_object(CullableObject *object) {
// draw.
////////////////////////////////////////////////////////////////////
void CullBinBackToFront::
finish_cull(SceneSetup *) {
PStatTimer timer(_cull_this_pcollector);
finish_cull(SceneSetup *, Thread *current_thread) {
PStatTimer timer(_cull_this_pcollector, current_thread);
sort(_objects.begin(), _objects.end());
}
@ -99,7 +99,7 @@ finish_cull(SceneSetup *) {
////////////////////////////////////////////////////////////////////
void CullBinBackToFront::
draw(Thread *current_thread) {
PStatTimer timer(_draw_this_pcollector);
PStatTimer timer(_draw_this_pcollector, current_thread);
Objects::const_iterator oi;
for (oi = _objects.begin(); oi != _objects.end(); ++oi) {
CullableObject *object = (*oi)._object;

View File

@ -43,8 +43,8 @@ public:
static CullBin *make_bin(const string &name, GraphicsStateGuardianBase *gsg);
virtual void add_object(CullableObject *object);
virtual void finish_cull(SceneSetup *scene_setup);
virtual void add_object(CullableObject *object, Thread *current_thread);
virtual void finish_cull(SceneSetup *scene_setup, Thread *current_thread);
virtual void draw(Thread *current_thread);
private:

View File

@ -59,7 +59,7 @@ make_bin(const string &name, GraphicsStateGuardianBase *gsg) {
// the bin for rendering.
////////////////////////////////////////////////////////////////////
void CullBinFixed::
add_object(CullableObject *object) {
add_object(CullableObject *object, Thread *current_thread) {
int draw_order = object->_state->get_draw_order();
_objects.push_back(ObjectData(object, draw_order));
}
@ -74,8 +74,8 @@ add_object(CullableObject *object) {
// draw.
////////////////////////////////////////////////////////////////////
void CullBinFixed::
finish_cull(SceneSetup *) {
PStatTimer timer(_cull_this_pcollector);
finish_cull(SceneSetup *, Thread *current_thread) {
PStatTimer timer(_cull_this_pcollector, current_thread);
stable_sort(_objects.begin(), _objects.end());
}
@ -87,7 +87,7 @@ finish_cull(SceneSetup *) {
////////////////////////////////////////////////////////////////////
void CullBinFixed::
draw(Thread *current_thread) {
PStatTimer timer(_draw_this_pcollector);
PStatTimer timer(_draw_this_pcollector, current_thread);
Objects::const_iterator oi;
for (oi = _objects.begin(); oi != _objects.end(); ++oi) {
CullableObject *object = (*oi)._object;

View File

@ -45,8 +45,8 @@ public:
static CullBin *make_bin(const string &name, GraphicsStateGuardianBase *gsg);
virtual void add_object(CullableObject *object);
virtual void finish_cull(SceneSetup *scene_setup);
virtual void add_object(CullableObject *object, Thread *current_thread);
virtual void finish_cull(SceneSetup *scene_setup, Thread *current_thread);
virtual void draw(Thread *current_thread);
private:

View File

@ -59,7 +59,7 @@ make_bin(const string &name, GraphicsStateGuardianBase *gsg) {
// the bin for rendering.
////////////////////////////////////////////////////////////////////
void CullBinFrontToBack::
add_object(CullableObject *object) {
add_object(CullableObject *object, Thread *current_thread) {
// Determine the center of the bounding volume.
CPT(BoundingVolume) volume = object->_geom->get_bounds();
@ -86,8 +86,8 @@ add_object(CullableObject *object) {
// draw.
////////////////////////////////////////////////////////////////////
void CullBinFrontToBack::
finish_cull(SceneSetup *) {
PStatTimer timer(_cull_this_pcollector);
finish_cull(SceneSetup *, Thread *current_thread) {
PStatTimer timer(_cull_this_pcollector, current_thread);
sort(_objects.begin(), _objects.end());
}
@ -99,7 +99,7 @@ finish_cull(SceneSetup *) {
////////////////////////////////////////////////////////////////////
void CullBinFrontToBack::
draw(Thread *current_thread) {
PStatTimer timer(_draw_this_pcollector);
PStatTimer timer(_draw_this_pcollector, current_thread);
Objects::const_iterator oi;
for (oi = _objects.begin(); oi != _objects.end(); ++oi) {
CullableObject *object = (*oi)._object;

View File

@ -43,8 +43,8 @@ public:
static CullBin *make_bin(const string &name, GraphicsStateGuardianBase *gsg);
virtual void add_object(CullableObject *object);
virtual void finish_cull(SceneSetup *scene_setup);
virtual void add_object(CullableObject *object, Thread *current_thread);
virtual void finish_cull(SceneSetup *scene_setup, Thread *current_thread);
virtual void draw(Thread *current_thread);
private:

View File

@ -116,7 +116,7 @@ make_next() const {
// the bin for rendering.
////////////////////////////////////////////////////////////////////
void CullBinOcclusionTest::
add_object(CullableObject *object) {
add_object(CullableObject *object, Thread *current_thread) {
// Determine the world-space bounding sphere for the object.
CPT(BoundingVolume) volume = object->_geom->get_bounds();
if (volume->is_empty()) {
@ -151,8 +151,8 @@ add_object(CullableObject *object) {
// draw.
////////////////////////////////////////////////////////////////////
void CullBinOcclusionTest::
finish_cull(SceneSetup *scene_setup) {
PStatTimer timer(_cull_this_pcollector);
finish_cull(SceneSetup *scene_setup, Thread *current_thread) {
PStatTimer timer(_cull_this_pcollector, current_thread);
// Now we have a loose list of objects that are to be rendered.
// We'd rather have them in an octree, which has much better
@ -196,7 +196,7 @@ finish_cull(SceneSetup *scene_setup) {
////////////////////////////////////////////////////////////////////
void CullBinOcclusionTest::
draw(Thread *current_thread) {
PStatTimer timer(_draw_this_pcollector);
PStatTimer timer(_draw_this_pcollector, current_thread);
// We'll want to know the near plane distance.
_near_distance = _gsg->get_scene()->get_lens()->get_near();
@ -494,7 +494,7 @@ occlusion_test(CullBinOcclusionTest &bin, Thread *current_thread) {
CPT(Geom) viz = get_octree_solid_test();
CPT(GeomVertexData) munged_data = viz->get_vertex_data();
munger->munge_geom(viz, munged_data);
munger->munge_geom(viz, munged_data, current_thread);
bin._gsg->set_state_and_transform(state, internal_transform);
@ -632,7 +632,7 @@ draw_wireframe(CullBinOcclusionTest &bin, Thread *current_thread) {
CPT(Geom) viz = get_octree_wireframe_viz();
CPT(GeomVertexData) munged_data = viz->get_vertex_data();
munger->munge_geom(viz, munged_data);
munger->munge_geom(viz, munged_data, current_thread);
bin._gsg->set_state_and_transform(state, internal_transform);
viz->draw(bin._gsg, munger, munged_data, current_thread);

View File

@ -57,8 +57,8 @@ public:
static CullBin *make_bin(const string &name, GraphicsStateGuardianBase *gsg);
virtual PT(CullBin) make_next() const;
virtual void add_object(CullableObject *object);
virtual void finish_cull(SceneSetup *scene_setup);
virtual void add_object(CullableObject *object, Thread *current_thread);
virtual void finish_cull(SceneSetup *scene_setup, Thread *current_thread);
virtual void draw(Thread *current_thread);
private:

View File

@ -58,7 +58,7 @@ make_bin(const string &name, GraphicsStateGuardianBase *gsg) {
// the bin for rendering.
////////////////////////////////////////////////////////////////////
void CullBinStateSorted::
add_object(CullableObject *object) {
add_object(CullableObject *object, Thread *current_thread) {
_objects.push_back(ObjectData(object));
}
@ -72,8 +72,8 @@ add_object(CullableObject *object) {
// draw.
////////////////////////////////////////////////////////////////////
void CullBinStateSorted::
finish_cull(SceneSetup *) {
PStatTimer timer(_cull_this_pcollector);
finish_cull(SceneSetup *, Thread *current_thread) {
PStatTimer timer(_cull_this_pcollector, current_thread);
sort(_objects.begin(), _objects.end());
}
@ -86,7 +86,7 @@ finish_cull(SceneSetup *) {
////////////////////////////////////////////////////////////////////
void CullBinStateSorted::
draw(Thread *current_thread) {
PStatTimer timer(_draw_this_pcollector);
PStatTimer timer(_draw_this_pcollector, current_thread);
Objects::const_iterator oi;
for (oi = _objects.begin(); oi != _objects.end(); ++oi) {
CullableObject *object = (*oi)._object;

View File

@ -47,8 +47,8 @@ public:
static CullBin *make_bin(const string &name, GraphicsStateGuardianBase *gsg);
virtual void add_object(CullableObject *object);
virtual void finish_cull(SceneSetup *scene_setup);
virtual void add_object(CullableObject *object, Thread *current_thread);
virtual void finish_cull(SceneSetup *scene_setup, Thread *current_thread);
virtual void draw(Thread *current_thread);
private:

View File

@ -55,7 +55,7 @@ make_bin(const string &name, GraphicsStateGuardianBase *gsg) {
// the bin for rendering.
////////////////////////////////////////////////////////////////////
void CullBinUnsorted::
add_object(CullableObject *object) {
add_object(CullableObject *object, Thread *current_thread) {
_objects.push_back(object);
}
@ -67,7 +67,7 @@ add_object(CullableObject *object) {
////////////////////////////////////////////////////////////////////
void CullBinUnsorted::
draw(Thread *current_thread) {
PStatTimer timer(_draw_this_pcollector);
PStatTimer timer(_draw_this_pcollector, current_thread);
Objects::iterator oi;
for (oi = _objects.begin(); oi != _objects.end(); ++oi) {
CullableObject *object = (*oi);

View File

@ -38,7 +38,7 @@ public:
static CullBin *make_bin(const string &name, GraphicsStateGuardianBase *gsg);
virtual void add_object(CullableObject *object);
virtual void add_object(CullableObject *object, Thread *current_thread);
virtual void draw(Thread *current_thread);
private:

View File

@ -38,6 +38,6 @@ record_object(CullableObject *object, const CullTraverser *traverser) {
object->munge_geom(_gsg, _gsg->get_geom_munger(object->_state), traverser);
// And draw the object, then dispense with it.
draw(object, _gsg, Thread::get_current_thread());
draw(object, _gsg, traverser->get_current_thread());
delete object;
}

View File

@ -47,7 +47,7 @@ set_data(int parent_index, const DataNodeTransmit &data) {
// Description:
////////////////////////////////////////////////////////////////////
DataGraphTraverser::
DataGraphTraverser() {
DataGraphTraverser(Thread *current_thread) : _current_thread(current_thread) {
}
////////////////////////////////////////////////////////////////////
@ -69,9 +69,8 @@ void DataGraphTraverser::
traverse(PandaNode *node) {
if (node->is_of_type(DataNode::get_class_type())) {
DataNode *data_node = DCAST(DataNode, node);
int num_parents = data_node->get_num_parents();
// We must start the traversal at the root of the graph.
nassertv(num_parents == 0);
nassertv(data_node->get_num_parents(_current_thread) == 0);
r_transmit(data_node, (DataNodeTransmit *)NULL);
@ -91,7 +90,7 @@ traverse(PandaNode *node) {
////////////////////////////////////////////////////////////////////
void DataGraphTraverser::
traverse_below(PandaNode *node, const DataNodeTransmit &output) {
PandaNode::Children cr = node->get_children();
PandaNode::Children cr = node->get_children(_current_thread);
int num_children = cr.get_num_children();
for (int i = 0; i < num_children; i++) {
@ -101,7 +100,7 @@ traverse_below(PandaNode *node, const DataNodeTransmit &output) {
// If it's a DataNode-type child, we need to pass it the data.
// Maybe it has only one parent, and can accept the data
// immediately.
int num_parents = data_node->get_num_parents();
int num_parents = data_node->get_num_parents(_current_thread);
if (num_parents == 1) {
// The easy, common case: only one parent. We make our output
// into a one-element array of inputs by turning it into a
@ -112,7 +111,7 @@ traverse_below(PandaNode *node, const DataNodeTransmit &output) {
// instances together, meaning we must hold onto this node
// until we have reached it through all paths.
CollectedData &collected_data = _multipass_data[data_node];
int parent_index = data_node->find_parent(node);
int parent_index = data_node->find_parent(node, _current_thread);
nassertv(parent_index != -1);
collected_data.set_data(parent_index, output);

View File

@ -38,7 +38,7 @@ class PandaNode;
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA DataGraphTraverser {
PUBLISHED:
DataGraphTraverser();
DataGraphTraverser(Thread *current_thread);
~DataGraphTraverser();
void traverse(PandaNode *node);
@ -50,6 +50,8 @@ private:
typedef pvector<DataNodeTransmit> DataVector;
Thread *_current_thread;
class CollectedData {
public:
INLINE CollectedData();

View File

@ -305,8 +305,9 @@ get_pixel_height() const {
// to all upstream pipeline stages.
////////////////////////////////////////////////////////////////////
INLINE void DisplayRegion::
set_cull_result(CullResult *cull_result, SceneSetup *scene_setup) {
CDCullWriter cdata(_cycler_cull, true);
set_cull_result(CullResult *cull_result, SceneSetup *scene_setup,
Thread *current_thread) {
CDCullWriter cdata(_cycler_cull, true, current_thread);
cdata->_cull_result = cull_result;
cdata->_scene_setup = scene_setup;
}
@ -321,8 +322,8 @@ set_cull_result(CullResult *cull_result, SceneSetup *scene_setup) {
// directly.
////////////////////////////////////////////////////////////////////
INLINE CullResult *DisplayRegion::
get_cull_result() const {
CDCullReader cdata(_cycler_cull);
get_cull_result(Thread *current_thread) const {
CDCullReader cdata(_cycler_cull, current_thread);
return cdata->_cull_result;
}
@ -336,8 +337,8 @@ get_cull_result() const {
// directly.
////////////////////////////////////////////////////////////////////
INLINE SceneSetup *DisplayRegion::
get_scene_setup() const {
CDCullReader cdata(_cycler_cull);
get_scene_setup(Thread *current_thread) const {
CDCullReader cdata(_cycler_cull, current_thread);
return cdata->_scene_setup;
}

View File

@ -470,13 +470,15 @@ save_screenshot(const Filename &filename, const string &image_comment) {
////////////////////////////////////////////////////////////////////
bool DisplayRegion::
get_screenshot(PNMImage &image) {
Thread *current_thread = Thread::get_current_thread();
GraphicsOutput *window = get_window();
nassertr(window != (GraphicsOutput *)NULL, false);
GraphicsStateGuardian *gsg = window->get_gsg();
nassertr(gsg != (GraphicsStateGuardian *)NULL, false);
if (!window->begin_frame(GraphicsOutput::FM_refresh)) {
if (!window->begin_frame(GraphicsOutput::FM_refresh, current_thread)) {
return false;
}
@ -489,7 +491,7 @@ get_screenshot(PNMImage &image) {
return false;
}
window->end_frame(GraphicsOutput::FM_refresh);
window->end_frame(GraphicsOutput::FM_refresh, current_thread);
if (!tex->store(image)) {
return false;

View File

@ -119,10 +119,10 @@ PUBLISHED:
bool get_screenshot(PNMImage &image);
public:
INLINE void set_cull_result(
CullResult *cull_result, SceneSetup *scene_setup);
INLINE CullResult *get_cull_result() const;
INLINE SceneSetup *get_scene_setup() const;
INLINE void set_cull_result(CullResult *cull_result, SceneSetup *scene_setup,
Thread *current_thread);
INLINE CullResult *get_cull_result(Thread *current_thread) const;
INLINE SceneSetup *get_scene_setup(Thread *current_thread) const;
private:
class CData;

View File

@ -478,7 +478,7 @@ remove_all_windows() {
_app.do_close(this, current_thread);
_app.do_pending(this, current_thread);
terminate_threads();
terminate_threads(current_thread);
}
////////////////////////////////////////////////////////////////////
@ -623,7 +623,7 @@ render_frame() {
// Grab each thread's mutex again after all windows have flipped,
// and wait for the thread to finish.
{
PStatTimer timer(_wait_pcollector);
PStatTimer timer(_wait_pcollector, current_thread);
Threads::const_iterator ti;
for (ti = _threads.begin(); ti != _threads.end(); ++ti) {
RenderThread *thread = (*ti).second;
@ -652,7 +652,7 @@ render_frame() {
// between frames.
ObjectDeletor *deletor = ObjectDeletor::get_global_ptr();
if (deletor != (ObjectDeletor *)NULL) {
PStatTimer timer(_delete_pcollector);
PStatTimer timer(_delete_pcollector, current_thread);
deletor->flush();
}
@ -664,13 +664,13 @@ render_frame() {
// Now cycle the pipeline and officially begin the next frame.
#ifdef THREADED_PIPELINE
{
PStatTimer timer(_cycle_pcollector);
PStatTimer timer(_cycle_pcollector, current_thread);
_pipeline->cycle();
}
#endif // THREADED_PIPELINE
global_clock->tick();
if (global_clock->check_errors()) {
global_clock->tick(current_thread);
if (global_clock->check_errors(current_thread)) {
throw_event("clock_error");
}
@ -735,7 +735,7 @@ render_frame() {
if (yield_timeslice) {
// Nap for a moment to yield the timeslice, to be polite to other
// running applications.
PStatTimer timer(_yield_pcollector);
PStatTimer timer(_yield_pcollector, current_thread);
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 0;
@ -776,7 +776,7 @@ open_windows() {
_app.do_windows(this, current_thread);
_app.do_pending(this, current_thread);
PStatTimer timer(_wait_pcollector);
PStatTimer timer(_wait_pcollector, current_thread);
Threads::const_iterator ti;
for (ti = _threads.begin(); ti != _threads.end(); ++ti) {
RenderThread *thread = (*ti).second;
@ -964,13 +964,13 @@ set_window_sort(GraphicsOutput *window, int sort) {
void GraphicsEngine::
cull_and_draw_together(const GraphicsEngine::Windows &wlist,
Thread *current_thread) {
PStatTimer timer(_cull_pcollector);
PStatTimer timer(_cull_pcollector, current_thread);
Windows::const_iterator wi;
for (wi = wlist.begin(); wi != wlist.end(); ++wi) {
GraphicsOutput *win = (*wi);
if (win->is_active() && win->get_gsg()->is_active()) {
if (win->begin_frame(GraphicsOutput::FM_render)) {
if (win->begin_frame(GraphicsOutput::FM_render, current_thread)) {
win->clear(current_thread);
int num_display_regions = win->get_num_active_display_regions();
@ -980,16 +980,16 @@ cull_and_draw_together(const GraphicsEngine::Windows &wlist,
cull_and_draw_together(win, dr, current_thread);
}
}
win->end_frame(GraphicsOutput::FM_render);
win->end_frame(GraphicsOutput::FM_render, current_thread);
if (_auto_flip) {
if (win->flip_ready()) {
{
PStatTimer timer(GraphicsEngine::_flip_begin_pcollector);
PStatTimer timer(GraphicsEngine::_flip_begin_pcollector, current_thread);
win->begin_flip();
}
{
PStatTimer timer(GraphicsEngine::_flip_end_pcollector);
PStatTimer timer(GraphicsEngine::_flip_end_pcollector, current_thread);
win->end_flip();
}
}
@ -1052,7 +1052,7 @@ cull_and_draw_together(GraphicsOutput *win, DisplayRegion *dr,
////////////////////////////////////////////////////////////////////
void GraphicsEngine::
cull_to_bins(const GraphicsEngine::Windows &wlist, Thread *current_thread) {
PStatTimer timer(_cull_pcollector);
PStatTimer timer(_cull_pcollector, current_thread);
// Keep track of the cameras we have already used in this thread to
// render DisplayRegions.
@ -1088,8 +1088,9 @@ cull_to_bins(const GraphicsEngine::Windows &wlist, Thread *current_thread) {
// result will be the same, so just use the result from
// the other DisplayRegion.
DisplayRegion *other_dr = (*aci).second;
dr->set_cull_result(other_dr->get_cull_result(),
setup_scene(win->get_gsg(), dr_reader));
dr->set_cull_result(other_dr->get_cull_result(current_thread),
setup_scene(win->get_gsg(), dr_reader),
current_thread);
}
if (dr_reader != (DisplayRegionPipelineReader *)NULL) {
@ -1115,8 +1116,8 @@ cull_to_bins(GraphicsOutput *win, DisplayRegion *dr, Thread *current_thread) {
PT(CullResult) cull_result;
PT(SceneSetup) scene_setup;
{
PStatTimer timer(_cull_setup_pcollector);
cull_result = dr->get_cull_result();
PStatTimer timer(_cull_setup_pcollector, current_thread);
cull_result = dr->get_cull_result(current_thread);
if (cull_result != (CullResult *)NULL) {
cull_result = cull_result->make_next();
} else {
@ -1131,10 +1132,10 @@ cull_to_bins(GraphicsOutput *win, DisplayRegion *dr, Thread *current_thread) {
do_cull(&cull_handler, scene_setup, gsg, current_thread);
{
PStatTimer timer(_cull_sort_pcollector);
cull_result->finish_cull(scene_setup);
PStatTimer timer(_cull_sort_pcollector, current_thread);
cull_result->finish_cull(scene_setup, current_thread);
// Save the results for next frame.
dr->set_cull_result(cull_result, scene_setup);
dr->set_cull_result(cull_result, scene_setup, current_thread);
}
}
}
@ -1154,7 +1155,7 @@ draw_bins(const GraphicsEngine::Windows &wlist, Thread *current_thread) {
for (wi = wlist.begin(); wi != wlist.end(); ++wi) {
GraphicsOutput *win = (*wi);
if (win->is_active() && win->get_gsg()->is_active()) {
if (win->begin_frame(GraphicsOutput::FM_render)) {
if (win->begin_frame(GraphicsOutput::FM_render, current_thread)) {
win->clear(current_thread);
int num_display_regions = win->get_num_active_display_regions();
@ -1164,16 +1165,16 @@ draw_bins(const GraphicsEngine::Windows &wlist, Thread *current_thread) {
draw_bins(win, dr, current_thread);
}
}
win->end_frame(GraphicsOutput::FM_render);
win->end_frame(GraphicsOutput::FM_render, current_thread);
if (_auto_flip) {
if (win->flip_ready()) {
{
PStatTimer timer(GraphicsEngine::_flip_begin_pcollector);
PStatTimer timer(GraphicsEngine::_flip_begin_pcollector, current_thread);
win->begin_flip();
}
{
PStatTimer timer(GraphicsEngine::_flip_end_pcollector);
PStatTimer timer(GraphicsEngine::_flip_end_pcollector, current_thread);
win->end_flip();
}
}
@ -1195,8 +1196,8 @@ draw_bins(GraphicsOutput *win, DisplayRegion *dr, Thread *current_thread) {
GraphicsStateGuardian *gsg = win->get_gsg();
nassertv(gsg != (GraphicsStateGuardian *)NULL);
PT(CullResult) cull_result = dr->get_cull_result();
PT(SceneSetup) scene_setup = dr->get_scene_setup();
PT(CullResult) cull_result = dr->get_cull_result(current_thread);
PT(SceneSetup) scene_setup = dr->get_scene_setup(current_thread);
if (cull_result != (CullResult *)NULL && scene_setup != (SceneSetup *)NULL) {
do_draw(cull_result, scene_setup, win, dr, current_thread);
}
@ -1214,8 +1215,8 @@ make_contexts(const GraphicsEngine::Windows &wlist, Thread *current_thread) {
Windows::const_iterator wi;
for (wi = wlist.begin(); wi != wlist.end(); ++wi) {
GraphicsOutput *win = (*wi);
if (win->begin_frame(GraphicsOutput::FM_refresh)) {
win->end_frame(GraphicsOutput::FM_refresh);
if (win->begin_frame(GraphicsOutput::FM_refresh, current_thread)) {
win->end_frame(GraphicsOutput::FM_refresh, current_thread);
}
}
}
@ -1249,14 +1250,14 @@ flip_windows(const GraphicsEngine::Windows &wlist, Thread *current_thread) {
for (wi = wlist.begin(); wi != wlist.end(); ++wi) {
GraphicsOutput *win = (*wi);
if (win->flip_ready()) {
PStatTimer timer(GraphicsEngine::_flip_begin_pcollector);
PStatTimer timer(GraphicsEngine::_flip_begin_pcollector, current_thread);
win->begin_flip();
}
}
for (wi = wlist.begin(); wi != wlist.end(); ++wi) {
GraphicsOutput *win = (*wi);
if (win->flip_ready()) {
PStatTimer timer(GraphicsEngine::_flip_end_pcollector);
PStatTimer timer(GraphicsEngine::_flip_end_pcollector, current_thread);
win->end_flip();
}
}
@ -1273,7 +1274,7 @@ do_sync_frame(Thread *current_thread) {
nassertv(_lock.debug_is_locked());
// Statistics
PStatTimer timer(_sync_pcollector);
PStatTimer timer(_sync_pcollector, current_thread);
nassertv(_flip_state == FS_draw);
@ -1300,7 +1301,7 @@ do_flip_frame(Thread *current_thread) {
nassertv(_lock.debug_is_locked());
// Statistics
PStatTimer timer(_flip_pcollector);
PStatTimer timer(_flip_pcollector, current_thread);
nassertv(_flip_state == FS_draw || _flip_state == FS_sync);
@ -1308,7 +1309,7 @@ do_flip_frame(Thread *current_thread) {
// necessary. Grabbing the mutex (and waiting for TS_wait) should
// achieve that.
{
PStatTimer timer(_wait_pcollector);
PStatTimer timer(_wait_pcollector, current_thread);
Threads::const_iterator ti;
for (ti = _threads.begin(); ti != _threads.end(); ++ti) {
RenderThread *thread = (*ti).second;
@ -1347,7 +1348,7 @@ do_flip_frame(Thread *current_thread) {
////////////////////////////////////////////////////////////////////
PT(SceneSetup) GraphicsEngine::
setup_scene(GraphicsStateGuardian *gsg, DisplayRegionPipelineReader *dr) {
PStatTimer timer(_cull_setup_pcollector);
PStatTimer timer(_cull_setup_pcollector, dr->get_current_thread());
GraphicsOutput *window = dr->get_window();
// The window pointer shouldn't be NULL, since we presumably got to
@ -1431,7 +1432,7 @@ setup_scene(GraphicsStateGuardian *gsg, DisplayRegionPipelineReader *dr) {
void GraphicsEngine::
do_cull(CullHandler *cull_handler, SceneSetup *scene_setup,
GraphicsStateGuardian *gsg, Thread *current_thread) {
CullTraverser trav(gsg);
CullTraverser trav(gsg, current_thread);
trav.set_cull_handler(cull_handler);
trav.set_depth_offset_decals(depth_offset_decals && gsg->depth_offset_decals());
trav.set_scene(scene_setup);
@ -1471,7 +1472,7 @@ void GraphicsEngine::
do_draw(CullResult *cull_result, SceneSetup *scene_setup,
GraphicsOutput *win, DisplayRegion *dr, Thread *current_thread) {
// Statistics
PStatTimer timer(_draw_pcollector);
PStatTimer timer(_draw_pcollector, current_thread);
DisplayRegionPipelineReader *dr_reader =
new DisplayRegionPipelineReader(dr, current_thread);
@ -1662,12 +1663,12 @@ do_resort_windows() {
// them to clean up.
////////////////////////////////////////////////////////////////////
void GraphicsEngine::
terminate_threads() {
terminate_threads(Thread *current_thread) {
MutexHolder holder(_lock);
// We spend almost our entire time in this method just waiting for
// threads. Time it appropriately.
PStatTimer timer(_wait_pcollector);
PStatTimer timer(_wait_pcollector, current_thread);
// First, wait for all the threads to finish their current frame.
// Grabbing the mutex should achieve that.
@ -1903,7 +1904,7 @@ resort_windows() {
////////////////////////////////////////////////////////////////////
void GraphicsEngine::WindowRenderer::
do_frame(GraphicsEngine *engine, Thread *current_thread) {
PStatTimer timer(engine->_do_frame_pcollector);
PStatTimer timer(engine->_do_frame_pcollector, current_thread);
MutexHolder holder(_wl_lock);
do_callbacks(CB_pre_frame);
@ -2165,7 +2166,7 @@ thread_main() {
_cv_done.signal();
{
PStatTimer timer(_wait_pcollector);
PStatTimer timer(_wait_pcollector, current_thread);
_cv_start.wait();
}
}

View File

@ -179,7 +179,7 @@ private:
const GraphicsThreadingModel &threading_model);
void do_remove_window(GraphicsOutput *window, Thread *current_thread);
void do_resort_windows();
void terminate_threads();
void terminate_threads(Thread *current_thread);
#ifdef DO_PSTATS
typedef map<TypeHandle, PStatCollector> CyclerTypeCounters;

View File

@ -914,7 +914,7 @@ reset_window(bool swapchain) {
// should be skipped.
////////////////////////////////////////////////////////////////////
bool GraphicsOutput::
begin_frame(FrameMode mode) {
begin_frame(FrameMode mode, Thread *current_thread) {
return false;
}
@ -926,7 +926,7 @@ begin_frame(FrameMode mode) {
// should do whatever finalization is required.
////////////////////////////////////////////////////////////////////
void GraphicsOutput::
end_frame(FrameMode mode) {
end_frame(FrameMode mode, Thread *current_thread) {
}
////////////////////////////////////////////////////////////////////

View File

@ -209,8 +209,8 @@ public:
// thread other than the draw thread. These methods are normally
// called by the GraphicsEngine.
void clear(Thread *current_thread);
virtual bool begin_frame(FrameMode mode);
virtual void end_frame(FrameMode mode);
virtual bool begin_frame(FrameMode mode, Thread *current_thread);
virtual void end_frame(FrameMode mode, Thread *current_thread);
// These entry points have been removed. Use begin_frame/end_frame instead.
// virtual void begin_render_texture();

View File

@ -1015,8 +1015,8 @@ prepare_lens() {
// be called).
////////////////////////////////////////////////////////////////////
bool GraphicsStateGuardian::
begin_frame() {
_prepared_objects->begin_frame(this);
begin_frame(Thread *current_thread) {
_prepared_objects->begin_frame(this, current_thread);
#ifdef DO_PSTATS
// For Pstats to track our current texture memory usage, we have to
@ -1121,8 +1121,8 @@ end_scene() {
// rendering the frame, and before the window flips.
////////////////////////////////////////////////////////////////////
void GraphicsStateGuardian::
end_frame() {
_prepared_objects->end_frame();
end_frame(Thread *current_thread) {
_prepared_objects->end_frame(current_thread);
// Flush any PStatCollectors.
_data_transferred_pcollector.flush_level();

View File

@ -181,10 +181,10 @@ public:
virtual CPT(TransformState) calc_projection_mat(const Lens *lens);
virtual bool prepare_lens();
virtual bool begin_frame();
virtual bool begin_frame(Thread *current_thread);
virtual bool begin_scene();
virtual void end_scene();
virtual void end_frame();
virtual void end_frame(Thread *current_thread);
void set_current_properties(FrameBufferProperties *properties);

View File

@ -107,10 +107,10 @@ get_host() {
// should be skipped.
////////////////////////////////////////////////////////////////////
bool ParasiteBuffer::
begin_frame(FrameMode mode) {
begin_frame(FrameMode mode, Thread *current_thread) {
begin_frame_spam();
if (!_host->begin_frame(FM_parasite)) {
if (!_host->begin_frame(FM_parasite, current_thread)) {
return false;
}
@ -134,7 +134,7 @@ begin_frame(FrameMode mode) {
// should do whatever finalization is required.
////////////////////////////////////////////////////////////////////
void ParasiteBuffer::
end_frame(FrameMode mode) {
end_frame(FrameMode mode, Thread *current_thread) {
end_frame_spam();
nassertv(_gsg != (GraphicsStateGuardian *)NULL);
@ -143,7 +143,7 @@ end_frame(FrameMode mode) {
return;
}
_host->end_frame(FM_parasite);
_host->end_frame(FM_parasite, current_thread);
if (mode == FM_render) {
for (int i=0; i<count_textures(); i++) {

View File

@ -63,8 +63,8 @@ PUBLISHED:
virtual bool is_active() const;
public:
virtual bool begin_frame(FrameMode mode);
virtual void end_frame(FrameMode mode);
virtual bool begin_frame(FrameMode mode, Thread *current_thread);
virtual void end_frame(FrameMode mode, Thread *current_thread);
virtual GraphicsOutput *get_host();
private:

View File

@ -169,7 +169,8 @@ munge_data_impl(const GeomVertexData *data) {
// Description: Converts a Geom and/or its data as necessary.
////////////////////////////////////////////////////////////////////
bool StandardMunger::
munge_geom_impl(CPT(Geom) &geom, CPT(GeomVertexData) &vertex_data) {
munge_geom_impl(CPT(Geom) &geom, CPT(GeomVertexData) &vertex_data,
Thread *current_thread) {
int supported_geom_rendering = _gsg->get_supported_geom_rendering();
int unsupported_bits = geom->get_geom_rendering() & ~supported_geom_rendering;

View File

@ -46,7 +46,8 @@ public:
protected:
virtual CPT(GeomVertexData) munge_data_impl(const GeomVertexData *data);
virtual int compare_to_impl(const GeomMunger *other) const;
virtual bool munge_geom_impl(CPT(Geom) &geom, CPT(GeomVertexData) &data);
virtual bool munge_geom_impl(CPT(Geom) &geom, CPT(GeomVertexData) &data,
Thread *current_thread);
virtual int geom_compare_to_impl(const GeomMunger *other) const;
virtual CPT(RenderState) munge_state_impl(const RenderState *state);

View File

@ -519,6 +519,8 @@ recompute_geom(Geom *geom, const LMatrix4f &rel_mat) {
0.0f, 0.0f, 0.5f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f);
Thread *current_thread = Thread::get_current_thread();
Lens *lens = _projector_node->get_lens();
nassertv(lens != (Lens *)NULL);
@ -546,11 +548,11 @@ recompute_geom(Geom *geom, const LMatrix4f &rel_mat) {
PT(GeomVertexData) modify_vdata = geom->modify_vertex_data();
// Maybe the vdata has animation that we should consider.
CPT(GeomVertexData) animated_vdata = geom->get_vertex_data()->animate_vertices();
CPT(GeomVertexData) animated_vdata = geom->get_vertex_data(current_thread)->animate_vertices(current_thread);
GeomVertexWriter texcoord(modify_vdata, _texcoord_name);
GeomVertexWriter color(modify_vdata);
GeomVertexReader vertex(animated_vdata, InternalName::get_vertex());
GeomVertexWriter texcoord(modify_vdata, _texcoord_name, current_thread);
GeomVertexWriter color(modify_vdata, current_thread);
GeomVertexReader vertex(animated_vdata, InternalName::get_vertex(), current_thread);
if (_vignette_on) {
color.set_column(InternalName::get_color());

View File

@ -672,8 +672,8 @@ prepare_lens() {
// be called).
////////////////////////////////////////////////////////////////////
bool DXGraphicsStateGuardian8::
begin_frame() {
return GraphicsStateGuardian::begin_frame();
begin_frame(Thread *current_thread) {
return GraphicsStateGuardian::begin_frame(current_thread);
}
////////////////////////////////////////////////////////////////////
@ -759,7 +759,7 @@ end_scene() {
// rendering the frame, and before the window flips.
////////////////////////////////////////////////////////////////////
void DXGraphicsStateGuardian8::
end_frame() {
end_frame(Thread *current_thread) {
#if defined(DO_PSTATS)
if (_texmgrmem_total_pcollector.is_active()) {
@ -777,7 +777,7 @@ end_frame() {
// Note: regular GraphicsWindow::end_frame is being called,
// but we override gsg::end_frame, so need to explicitly call it here
// (currently it's an empty fn)
GraphicsStateGuardian::end_frame();
GraphicsStateGuardian::end_frame(current_thread);
}
////////////////////////////////////////////////////////////////////

View File

@ -71,8 +71,8 @@ public:
virtual CPT(TransformState) calc_projection_mat(const Lens *lens);
virtual bool prepare_lens();
virtual bool begin_frame();
virtual bool begin_scene();
virtual bool begin_frame(Thread *current_thread, Thread *current_thread);
virtual bool begin_scene(Thread *current_thread, Thread *current_thread);
virtual void end_scene();
virtual void end_frame();

View File

@ -83,7 +83,7 @@ wdxGraphicsBuffer8::
// should be skipped.
////////////////////////////////////////////////////////////////////
bool wdxGraphicsBuffer8::
begin_frame(FrameMode mode) {
begin_frame(FrameMode mode, Thread *current_thread) {
begin_frame_spam();
if (_gsg == (GraphicsStateGuardian *)NULL) {
@ -96,7 +96,7 @@ begin_frame(FrameMode mode) {
}
_gsg->set_current_properties(&get_fb_properties());
return _gsg->begin_frame();
return _gsg->begin_frame(current_thread);
}
////////////////////////////////////////////////////////////////////
@ -107,7 +107,7 @@ begin_frame(FrameMode mode) {
// should do whatever finalization is required.
////////////////////////////////////////////////////////////////////
void wdxGraphicsBuffer8::
end_frame(FrameMode mode) {
end_frame(FrameMode mode, Thread *current_thread) {
end_frame_spam();
nassertv(_gsg != (GraphicsStateGuardian *)NULL);
@ -117,7 +117,7 @@ end_frame(FrameMode mode) {
copy_to_textures();
}
_gsg->end_frame();
_gsg->end_frame(current_thread);
if (mode == FM_render) {
trigger_flip();

View File

@ -44,8 +44,8 @@ public:
GraphicsOutput *host);
virtual ~wdxGraphicsBuffer8();
virtual bool begin_frame(FrameMode mode);
virtual void end_frame(FrameMode mode);
virtual bool begin_frame(FrameMode mode, Thread *current_thread);
virtual void end_frame(FrameMode mode, Thread *current_thread);
virtual void select_cube_map(int cube_map_index);

View File

@ -76,7 +76,7 @@ wdxGraphicsWindow8::
// should be skipped.
////////////////////////////////////////////////////////////////////
bool wdxGraphicsWindow8::
begin_frame(FrameMode mode) {
begin_frame(FrameMode mode, Thread *current_thread) {
begin_frame_spam();
if (_gsg == (GraphicsStateGuardian *)NULL) {
return false;
@ -100,7 +100,7 @@ begin_frame(FrameMode mode) {
}
_gsg->set_current_properties(&get_fb_properties());
bool return_val = _gsg->begin_frame();
bool return_val = _gsg->begin_frame(current_thread);
_dxgsg->set_render_target();
return return_val;
}

View File

@ -893,11 +893,11 @@ prepare_lens() {
// be called).
////////////////////////////////////////////////////////////////////
bool DXGraphicsStateGuardian9::
begin_frame() {
begin_frame(Thread *current_thread) {
DBG_S dxgsg9_cat.debug ( ) << "^^^^^^^^^^^ begin_frame \n"; DBG_E
GraphicsStateGuardian::begin_frame();
GraphicsStateGuardian::begin_frame(current_thread);
if (_lru)
{
@ -1020,7 +1020,7 @@ DBG_S dxgsg9_cat.debug ( ) << "DXGraphicsStateGuardian9::end_scene\n"; DBG_E
// rendering the frame, and before the window flips.
////////////////////////////////////////////////////////////////////
void DXGraphicsStateGuardian9::
end_frame() {
end_frame(Thread *current_thread) {
DBG_S dxgsg9_cat.debug ( ) << "@@@@@@@@@@ end_frame \n"; DBG_E
@ -1133,7 +1133,7 @@ DBG_S dxgsg9_cat.debug ( ) << "@@@@@@@@@@ end_frame \n"; DBG_E
// Note: regular GraphicsWindow::end_frame is being called,
// but we override gsg::end_frame, so need to explicitly call it here
// (currently it's an empty fn)
GraphicsStateGuardian::end_frame();
GraphicsStateGuardian::end_frame(current_thread);
}
////////////////////////////////////////////////////////////////////

View File

@ -107,8 +107,8 @@ public:
virtual CPT(TransformState) calc_projection_mat(const Lens *lens);
virtual bool prepare_lens();
virtual bool begin_frame();
virtual bool begin_scene();
virtual bool begin_frame(Thread *current_thread, Thread *current_thread);
virtual bool begin_scene(Thread *current_thread, Thread *current_thread);
virtual void end_scene();
virtual void end_frame();

View File

@ -80,7 +80,7 @@ wdxGraphicsBuffer9::
// should be skipped.
////////////////////////////////////////////////////////////////////
bool wdxGraphicsBuffer9::
begin_frame(FrameMode mode) {
begin_frame(FrameMode mode, Thread *current_thread) {
DBG_S dxgsg9_cat.debug ( ) << "wdxGraphicsBuffer9::begin_frame\n"; DBG_E
begin_frame_spam();
@ -94,7 +94,7 @@ begin_frame(FrameMode mode) {
}
_gsg->set_current_properties(&get_fb_properties());
return _gsg->begin_frame();
return _gsg->begin_frame(current_thread);
}
////////////////////////////////////////////////////////////////////
@ -105,7 +105,7 @@ begin_frame(FrameMode mode) {
// should do whatever finalization is required.
////////////////////////////////////////////////////////////////////
void wdxGraphicsBuffer9::
end_frame(FrameMode mode) {
end_frame(FrameMode mode, Thread *current_thread) {
end_frame_spam();
nassertv(_gsg != (GraphicsStateGuardian *)NULL);
@ -115,7 +115,7 @@ end_frame(FrameMode mode) {
copy_to_textures();
}
_gsg->end_frame();
_gsg->end_frame(current_thread);
if (mode == FM_render) {
trigger_flip();

View File

@ -44,8 +44,8 @@ public:
GraphicsOutput *host);
virtual ~wdxGraphicsBuffer9();
virtual bool begin_frame(FrameMode mode);
virtual void end_frame(FrameMode mode);
virtual bool begin_frame(FrameMode mode, Thread *current_thread);
virtual void end_frame(FrameMode mode, Thread *current_thread);
virtual void select_cube_map(int cube_map_index);
virtual void process_events();

View File

@ -96,7 +96,7 @@ make_current() {
// should be skipped.
////////////////////////////////////////////////////////////////////
bool wdxGraphicsWindow9::
begin_frame(FrameMode mode) {
begin_frame(FrameMode mode, Thread *current_thread) {
begin_frame_spam();
if (_gsg == (GraphicsStateGuardian *)NULL) {
return false;
@ -120,7 +120,7 @@ begin_frame(FrameMode mode) {
}
_gsg->set_current_properties(&get_fb_properties());
bool return_val = _gsg->begin_frame();
bool return_val = _gsg->begin_frame(current_thread);
_dxgsg->set_render_target();
return return_val;
}
@ -133,7 +133,7 @@ begin_frame(FrameMode mode) {
// should do whatever finalization is required.
////////////////////////////////////////////////////////////////////
void wdxGraphicsWindow9::
end_frame(FrameMode mode) {
end_frame(FrameMode mode, Thread *current_thread) {
end_frame_spam();
nassertv(_gsg != (GraphicsStateGuardian *)NULL);
@ -142,7 +142,7 @@ end_frame(FrameMode mode) {
copy_to_textures();
}
_gsg->end_frame();
_gsg->end_frame(current_thread);
if (mode == FM_render) {
trigger_flip();

View File

@ -744,9 +744,9 @@ enable_default_keys() {
// called only from main_loop().
////////////////////////////////////////////////////////////////////
bool PandaFramework::
do_frame() {
do_frame(Thread *current_thread) {
nassertr(_is_open, false);
DataGraphTraverser dg_trav;
DataGraphTraverser dg_trav(current_thread);
dg_trav.traverse(_data_root.node());
throw_event("NewFrame");
@ -783,7 +783,8 @@ do_frame() {
////////////////////////////////////////////////////////////////////
void PandaFramework::
main_loop() {
while (do_frame()) {
Thread *current_thread = Thread::get_current_thread();
while (do_frame(current_thread)) {
}
}

View File

@ -108,7 +108,7 @@ public:
void enable_default_keys();
virtual bool do_frame();
virtual bool do_frame(Thread *current_thread);
void main_loop();
INLINE void set_exit_flag();

View File

@ -66,12 +66,12 @@ CLP(GraphicsBuffer)::
// should be skipped.
////////////////////////////////////////////////////////////////////
bool CLP(GraphicsBuffer)::
begin_frame(FrameMode mode) {
begin_frame(FrameMode mode, Thread *current_thread) {
if (!_is_valid) {
return false;
}
if (!_host->begin_frame(FM_parasite)) {
if (!_host->begin_frame(FM_parasite, current_thread)) {
return false;
}
@ -366,7 +366,7 @@ generate_mipmaps() {
// should do whatever finalization is required.
////////////////////////////////////////////////////////////////////
void CLP(GraphicsBuffer)::
end_frame(FrameMode mode) {
end_frame(FrameMode mode, Thread *current_thread) {
end_frame_spam();
nassertv(_gsg != (GraphicsStateGuardian *)NULL);
@ -383,7 +383,7 @@ end_frame(FrameMode mode) {
generate_mipmaps();
}
_host->end_frame(FM_parasite);
_host->end_frame(FM_parasite, current_thread);
if (mode == FM_render) {
trigger_flip();

View File

@ -64,8 +64,8 @@ public:
GraphicsOutput *host);
virtual ~CLP(GraphicsBuffer)();
virtual bool begin_frame(FrameMode mode);
virtual void end_frame(FrameMode mode);
virtual bool begin_frame(FrameMode mode, Thread *current_thread);
virtual void end_frame(FrameMode mode, Thread *current_thread);
virtual void select_cube_map(int cube_map_index);

View File

@ -1253,8 +1253,8 @@ prepare_lens() {
// be called).
////////////////////////////////////////////////////////////////////
bool CLP(GraphicsStateGuardian)::
begin_frame() {
if (!GraphicsStateGuardian::begin_frame()) {
begin_frame(Thread *current_thread) {
if (!GraphicsStateGuardian::begin_frame(current_thread)) {
return false;
}
@ -1276,7 +1276,7 @@ begin_frame() {
// rendering the frame, and before the window flips.
////////////////////////////////////////////////////////////////////
void CLP(GraphicsStateGuardian)::
end_frame() {
end_frame(Thread *current_thread) {
#ifdef DO_PSTATS
// Check for textures, etc., that are no longer resident. These
// calls might be measurably expensive, and they don't have any
@ -1295,7 +1295,7 @@ end_frame() {
}
#endif
GraphicsStateGuardian::end_frame();
GraphicsStateGuardian::end_frame(current_thread);
// Flush any PCollectors specific to this kind of GSG.
_primitive_batches_display_list_pcollector.flush_level();
@ -1867,7 +1867,7 @@ disable_standard_vertex_arrays()
////////////////////////////////////////////////////////////////////
void CLP(GraphicsStateGuardian)::
draw_triangles(const GeomPrimitivePipelineReader *reader) {
PStatTimer timer(_draw_primitive_pcollector);
PStatTimer timer(_draw_primitive_pcollector, reader->get_current_thread());
#ifndef NDEBUG
if (GLCAT.is_spam()) {
@ -1912,7 +1912,7 @@ draw_triangles(const GeomPrimitivePipelineReader *reader) {
////////////////////////////////////////////////////////////////////
void CLP(GraphicsStateGuardian)::
draw_tristrips(const GeomPrimitivePipelineReader *reader) {
PStatTimer timer(_draw_primitive_pcollector);
PStatTimer timer(_draw_primitive_pcollector, reader->get_current_thread());
report_my_gl_errors();
@ -1996,7 +1996,7 @@ draw_tristrips(const GeomPrimitivePipelineReader *reader) {
////////////////////////////////////////////////////////////////////
void CLP(GraphicsStateGuardian)::
draw_trifans(const GeomPrimitivePipelineReader *reader) {
PStatTimer timer(_draw_primitive_pcollector);
PStatTimer timer(_draw_primitive_pcollector, reader->get_current_thread());
#ifndef NDEBUG
if (GLCAT.is_spam()) {
GLCAT.spam() << "draw_trifans: " << *(reader->get_object()) << "\n";
@ -2053,7 +2053,7 @@ draw_trifans(const GeomPrimitivePipelineReader *reader) {
////////////////////////////////////////////////////////////////////
void CLP(GraphicsStateGuardian)::
draw_lines(const GeomPrimitivePipelineReader *reader) {
PStatTimer timer(_draw_primitive_pcollector);
PStatTimer timer(_draw_primitive_pcollector, reader->get_current_thread());
#ifndef NDEBUG
if (GLCAT.is_spam()) {
GLCAT.spam() << "draw_lines: " << *(reader->get_object()) << "\n";
@ -2095,7 +2095,7 @@ draw_lines(const GeomPrimitivePipelineReader *reader) {
////////////////////////////////////////////////////////////////////
void CLP(GraphicsStateGuardian)::
draw_linestrips(const GeomPrimitivePipelineReader *reader) {
PStatTimer timer(_draw_primitive_pcollector);
PStatTimer timer(_draw_primitive_pcollector, reader->get_current_thread());
#ifndef NDEBUG
if (GLCAT.is_spam()) {
GLCAT.spam() << "draw_linestrips: " << *(reader->get_object()) << "\n";
@ -2111,7 +2111,7 @@ draw_linestrips(const GeomPrimitivePipelineReader *reader) {
////////////////////////////////////////////////////////////////////
void CLP(GraphicsStateGuardian)::
draw_points(const GeomPrimitivePipelineReader *reader) {
PStatTimer timer(_draw_primitive_pcollector);
PStatTimer timer(_draw_primitive_pcollector, reader->get_current_thread());
#ifndef NDEBUG
if (GLCAT.is_spam()) {
GLCAT.spam() << "draw_points: " << *(reader->get_object()) << "\n";
@ -2617,9 +2617,10 @@ prepare_vertex_buffer(GeomVertexArrayData *data) {
// rendering.
////////////////////////////////////////////////////////////////////
void CLP(GraphicsStateGuardian)::
apply_vertex_buffer(VertexBufferContext *vbc) {
apply_vertex_buffer(VertexBufferContext *vbc,
const GeomVertexArrayDataPipelineReader *reader) {
nassertv(_supports_buffers);
nassertv(vbc->get_data()->get_modified() != UpdateSeq::initial());
nassertv(reader->get_modified() != UpdateSeq::initial());
CLP(VertexBufferContext) *gvbc = DCAST(CLP(VertexBufferContext), vbc);
@ -2634,8 +2635,8 @@ apply_vertex_buffer(VertexBufferContext *vbc) {
}
if (gvbc->was_modified()) {
PStatTimer timer(_load_vertex_buffer_pcollector);
int num_bytes = gvbc->get_data()->get_data_size_bytes();
PStatTimer timer(_load_vertex_buffer_pcollector, reader->get_current_thread());
int num_bytes = reader->get_data_size_bytes();
if (GLCAT.is_spam()) {
GLCAT.spam()
<< "copying " << num_bytes
@ -2644,12 +2645,12 @@ apply_vertex_buffer(VertexBufferContext *vbc) {
if (num_bytes != 0) {
if (gvbc->changed_size() || gvbc->changed_usage_hint()) {
_glBufferData(GL_ARRAY_BUFFER, num_bytes,
gvbc->get_data()->get_data(),
get_usage(gvbc->get_data()->get_usage_hint()));
reader->get_data(),
get_usage(reader->get_usage_hint()));
} else {
_glBufferSubData(GL_ARRAY_BUFFER, 0, num_bytes,
gvbc->get_data()->get_data());
reader->get_data());
}
_data_transferred_pcollector.add_level(num_bytes);
}
@ -2738,7 +2739,7 @@ setup_array_data(const GeomVertexArrayDataPipelineReader *array_reader) {
// Prepare the buffer object and bind it.
VertexBufferContext *vbc = ((GeomVertexArrayData *)array_reader->get_object())->prepare_now(get_prepared_objects(), this);
nassertr(vbc != (VertexBufferContext *)NULL, array_reader->get_data());
apply_vertex_buffer(vbc);
apply_vertex_buffer(vbc, array_reader);
// NULL is the OpenGL convention for the first byte of the buffer object.
return NULL;
@ -2803,7 +2804,7 @@ apply_index_buffer(IndexBufferContext *ibc,
}
if (gibc->was_modified()) {
PStatTimer timer(_load_index_buffer_pcollector);
PStatTimer timer(_load_index_buffer_pcollector, reader->get_current_thread());
int num_bytes = reader->get_data_size_bytes();
if (GLCAT.is_spam()) {
GLCAT.spam()

View File

@ -100,8 +100,8 @@ public:
virtual CPT(TransformState) calc_projection_mat(const Lens *lens);
virtual bool prepare_lens();
virtual bool begin_frame();
virtual void end_frame();
virtual bool begin_frame(Thread *current_thread);
virtual void end_frame(Thread *current_thread);
virtual bool begin_draw_primitives(const GeomPipelineReader *geom_reader,
const GeomMunger *munger,
@ -129,7 +129,8 @@ public:
void record_deleted_display_list(GLuint index);
virtual VertexBufferContext *prepare_vertex_buffer(GeomVertexArrayData *data);
void apply_vertex_buffer(VertexBufferContext *vbc);
void apply_vertex_buffer(VertexBufferContext *vbc,
const GeomVertexArrayDataPipelineReader *reader);
virtual void release_vertex_buffer(VertexBufferContext *vbc);
const unsigned char *setup_array_data(const GeomVertexArrayDataPipelineReader *data);

View File

@ -75,8 +75,8 @@ glxGraphicsBuffer::
// should be skipped.
////////////////////////////////////////////////////////////////////
bool glxGraphicsBuffer::
begin_frame(FrameMode mode) {
PStatTimer timer(_make_current_pcollector);
begin_frame(FrameMode mode, Thread *current_thread) {
PStatTimer timer(_make_current_pcollector, current_thread);
begin_frame_spam();
if (_gsg == (GraphicsStateGuardian *)NULL) {
@ -99,7 +99,7 @@ begin_frame(FrameMode mode) {
}
_gsg->set_current_properties(&get_fb_properties());
return _gsg->begin_frame();
return _gsg->begin_frame(current_thread);
}
////////////////////////////////////////////////////////////////////
@ -110,7 +110,7 @@ begin_frame(FrameMode mode) {
// should do whatever finalization is required.
////////////////////////////////////////////////////////////////////
void glxGraphicsBuffer::
end_frame(FrameMode mode) {
end_frame(FrameMode mode, Thread *current_thread) {
end_frame_spam();
nassertv(_gsg != (GraphicsStateGuardian *)NULL);
@ -119,7 +119,7 @@ end_frame(FrameMode mode) {
copy_to_textures();
}
_gsg->end_frame();
_gsg->end_frame(current_thread);
if (mode == FM_render) {
trigger_flip();

View File

@ -43,8 +43,8 @@ public:
GraphicsOutput *host);
virtual ~glxGraphicsBuffer();
virtual bool begin_frame(FrameMode mode);
virtual void end_frame(FrameMode mode);
virtual bool begin_frame(FrameMode mode, Thread *current_thread);
virtual void end_frame(FrameMode mode, Thread *current_thread);
protected:
virtual void close_buffer();

View File

@ -116,8 +116,8 @@ move_pointer(int device, int x, int y) {
// should be skipped.
////////////////////////////////////////////////////////////////////
bool glxGraphicsWindow::
begin_frame(FrameMode mode) {
PStatTimer timer(_make_current_pcollector);
begin_frame(FrameMode mode, Thread *current_thread) {
PStatTimer timer(_make_current_pcollector, current_thread);
begin_frame_spam();
if (_gsg == (GraphicsStateGuardian *)NULL) {
@ -145,7 +145,7 @@ begin_frame(FrameMode mode) {
}
_gsg->set_current_properties(&get_fb_properties());
return _gsg->begin_frame();
return _gsg->begin_frame(current_thread);
}
////////////////////////////////////////////////////////////////////
@ -156,7 +156,7 @@ begin_frame(FrameMode mode) {
// should do whatever finalization is required.
////////////////////////////////////////////////////////////////////
void glxGraphicsWindow::
end_frame(FrameMode mode) {
end_frame(FrameMode mode, Thread *current_thread) {
end_frame_spam();
nassertv(_gsg != (GraphicsStateGuardian *)NULL);
@ -165,7 +165,7 @@ end_frame(FrameMode mode) {
copy_to_textures();
}
_gsg->end_frame();
_gsg->end_frame(current_thread);
if (mode == FM_render) {
trigger_flip();

View File

@ -41,8 +41,8 @@ public:
virtual ~glxGraphicsWindow();
virtual bool move_pointer(int device, int x, int y);
virtual bool begin_frame(FrameMode mode);
virtual void end_frame(FrameMode mode);
virtual bool begin_frame(FrameMode mode, Thread *current_thread);
virtual void end_frame(FrameMode mode, Thread *current_thread);
virtual void begin_flip();
virtual void process_events();

View File

@ -45,9 +45,9 @@ BufferResidencyTracker(const string &pgo_name, const string &type_name) :
// initializes the active/inactive status.
////////////////////////////////////////////////////////////////////
void BufferResidencyTracker::
begin_frame() {
begin_frame(Thread *current_thread) {
#ifdef DO_PSTATS
int this_frame = ClockObject::get_global_clock()->get_frame_count();
int this_frame = ClockObject::get_global_clock()->get_frame_count(current_thread);
if (_active_frame != this_frame) {
_active_frame = this_frame;
@ -68,7 +68,7 @@ begin_frame() {
// updates the PStatCollectors appropriately.
////////////////////////////////////////////////////////////////////
void BufferResidencyTracker::
end_frame() {
end_frame(Thread *current_thread) {
_inactive_nonresident_collector.set_level(_chains[S_inactive_nonresident].get_total_size());
_active_nonresident_collector.set_level(_chains[S_active_nonresident].get_total_size());
_inactive_resident_collector.set_level(_chains[S_inactive_resident].get_total_size());

View File

@ -41,8 +41,8 @@ class EXPCL_PANDA BufferResidencyTracker {
public:
BufferResidencyTracker(const string &pgo_name, const string &type_name);
void begin_frame();
void end_frame();
void begin_frame(Thread *current_thread);
void end_frame(Thread *current_thread);
INLINE BufferContextChain &get_inactive_nonresident();
INLINE BufferContextChain &get_active_nonresident();

View File

@ -86,8 +86,8 @@ get_usage_hint() const {
// modify) the geom's underlying data.
////////////////////////////////////////////////////////////////////
INLINE CPT(GeomVertexData) Geom::
get_vertex_data() const {
CDReader cdata(_cycler);
get_vertex_data(Thread *current_thread) const {
CDReader cdata(_cycler, current_thread);
return cdata->_data;
}
@ -279,11 +279,11 @@ INLINE void Geom::
calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point,
bool &found_any,
const GeomVertexData *vertex_data,
bool got_mat, const LMatrix4f &mat) const {
int pipeline_stage = Thread::get_current_pipeline_stage();
bool got_mat, const LMatrix4f &mat,
Thread *current_thread) const {
do_calc_tight_bounds(min_point, max_point, found_any,
vertex_data, got_mat, mat,
pipeline_stage);
current_thread);
}
////////////////////////////////////////////////////////////////////
@ -301,9 +301,11 @@ calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point,
////////////////////////////////////////////////////////////////////
INLINE void Geom::
calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point,
bool &found_any) const {
bool &found_any, Thread *current_thread) const {
calc_tight_bounds(min_point, max_point, found_any,
get_vertex_data(), false, LMatrix4f::ident_mat());
get_vertex_data(current_thread), false,
LMatrix4f::ident_mat(),
current_thread);
}
////////////////////////////////////////////////////////////////////

View File

@ -715,15 +715,14 @@ check_valid(const GeomVertexData *vertex_data) const {
// Description: Returns the bounding volume for the Geom.
////////////////////////////////////////////////////////////////////
CPT(BoundingVolume) Geom::
get_bounds() const {
int pipeline_stage = Thread::get_current_pipeline_stage();
CDStageReader cdata(_cycler, pipeline_stage);
get_bounds(Thread *current_thread) const {
CDReader cdata(_cycler, current_thread);
if (cdata->_internal_bounds_stale) {
CDStageWriter cdataw(((Geom *)this)->_cycler, pipeline_stage, cdata);
CDWriter cdataw(((Geom *)this)->_cycler, cdata, false);
if (cdataw->_user_bounds != (BoundingVolume *)NULL) {
cdataw->_internal_bounds = cdataw->_user_bounds;
} else {
cdataw->_internal_bounds = compute_internal_bounds(pipeline_stage);
cdataw->_internal_bounds = compute_internal_bounds(current_thread);
}
cdataw->_internal_bounds_stale = false;
return cdataw->_internal_bounds;
@ -966,7 +965,7 @@ get_next_modified() {
// This includes all of the vertices.
////////////////////////////////////////////////////////////////////
PT(BoundingVolume) Geom::
compute_internal_bounds(int pipeline_stage) const {
compute_internal_bounds(Thread *current_thread) const {
// First, get ourselves a fresh, empty bounding volume.
PT(BoundingVolume) bound = new BoundingSphere;
GeometricBoundingVolume *gbv = DCAST(GeometricBoundingVolume, bound);
@ -975,8 +974,9 @@ compute_internal_bounds(int pipeline_stage) const {
// calc_tight_bounds to determine our minmax first.
LPoint3f points[2];
bool found_any = false;
do_calc_tight_bounds(points[0], points[1], found_any, get_vertex_data(),
false, LMatrix4f::ident_mat(), pipeline_stage);
do_calc_tight_bounds(points[0], points[1], found_any,
get_vertex_data(current_thread),
false, LMatrix4f::ident_mat(), current_thread);
if (found_any) {
// Then we put the bounding volume around both of those points.
// Technically, we should put it around the eight points at the
@ -1002,15 +1002,15 @@ do_calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point,
bool &found_any,
const GeomVertexData *vertex_data,
bool got_mat, const LMatrix4f &mat,
int pipeline_stage) const {
CDStageReader cdata(_cycler, pipeline_stage);
Thread *current_thread) const {
CDReader cdata(_cycler, current_thread);
Primitives::const_iterator pi;
for (pi = cdata->_primitives.begin();
pi != cdata->_primitives.end();
++pi) {
(*pi)->calc_tight_bounds(min_point, max_point, found_any, vertex_data,
got_mat, mat);
got_mat, mat, current_thread);
}
}

View File

@ -74,7 +74,7 @@ PUBLISHED:
INLINE UsageHint get_usage_hint() const;
void set_usage_hint(UsageHint usage_hint);
INLINE CPT(GeomVertexData) get_vertex_data() const;
INLINE CPT(GeomVertexData) get_vertex_data(Thread *current_thread = Thread::get_current_thread()) const;
PT(GeomVertexData) modify_vertex_data();
void set_vertex_data(const GeomVertexData *data);
void offset_vertices(const GeomVertexData *data, int offset);
@ -105,7 +105,7 @@ PUBLISHED:
bool check_valid() const;
bool check_valid(const GeomVertexData *vertex_data) const;
CPT(BoundingVolume) get_bounds() const;
CPT(BoundingVolume) get_bounds(Thread *current_thread = Thread::get_current_thread()) const;
INLINE void mark_bounds_stale() const;
INLINE void set_bounds(const BoundingVolume *volume);
INLINE void clear_bounds();
@ -132,9 +132,10 @@ public:
INLINE void calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point,
bool &found_any,
const GeomVertexData *vertex_data,
bool got_mat, const LMatrix4f &mat) const;
bool got_mat, const LMatrix4f &mat,
Thread *current_thread) const;
INLINE void calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point,
bool &found_any) const;
bool &found_any, Thread *current_thread) const;
static UpdateSeq get_next_modified();
@ -146,13 +147,13 @@ private:
class CData;
INLINE void mark_internal_bounds_stale(CData *cdata);
PT(BoundingVolume) compute_internal_bounds(int pipeline_stage) const;
PT(BoundingVolume) compute_internal_bounds(Thread *current_thread) const;
void do_calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point,
bool &found_any,
const GeomVertexData *vertex_data,
bool got_mat, const LMatrix4f &mat,
int pipeline_stage) const;
Thread *current_thread) const;
void clear_prepared(PreparedGraphicsObjects *prepared_objects);
bool check_will_be_valid(const GeomVertexData *vertex_data) const;

View File

@ -103,7 +103,8 @@ remove_data(const GeomVertexData *data) {
// same; so this result may be cached.
////////////////////////////////////////////////////////////////////
void GeomMunger::
munge_geom(CPT(Geom) &geom, CPT(GeomVertexData) &data) {
munge_geom(CPT(Geom) &geom, CPT(GeomVertexData) &data,
Thread *current_thread) {
CPT(GeomVertexData) source_data = data;
// Look up the munger in the geom's cache--maybe we've recently
@ -123,7 +124,7 @@ munge_geom(CPT(Geom) &geom, CPT(GeomVertexData) &data) {
entry->refresh();
// Now check that it's fresh.
Geom::CDCacheReader cdata(entry->_cycler);
Geom::CDCacheReader cdata(entry->_cycler, current_thread);
nassertv(cdata->_source == geom);
if (cdata->_geom_result != (Geom *)NULL &&
geom->get_modified() <= cdata->_geom_result->get_modified() &&
@ -142,11 +143,11 @@ munge_geom(CPT(Geom) &geom, CPT(GeomVertexData) &data) {
}
// Ok, invoke the munger.
PStatTimer timer(_munge_pcollector);
PStatTimer timer(_munge_pcollector, current_thread);
CPT(Geom) orig_geom = geom;
data = munge_data(data);
munge_geom_impl(geom, data);
munge_geom_impl(geom, data, current_thread);
// Record the new result in the cache.
if (entry == (Geom::CacheEntry *)NULL) {
@ -162,7 +163,7 @@ munge_geom(CPT(Geom) &geom, CPT(GeomVertexData) &data) {
}
// Finally, store the cached result on the entry.
Geom::CDCacheWriter cdata(entry->_cycler, true);
Geom::CDCacheWriter cdata(entry->_cycler, true, current_thread);
cdata->_source = (Geom *)orig_geom.p();
cdata->set_result(geom, data);
}
@ -239,7 +240,7 @@ munge_data_impl(const GeomVertexData *data) {
// Description: Converts a Geom and/or its data as necessary.
////////////////////////////////////////////////////////////////////
bool GeomMunger::
munge_geom_impl(CPT(Geom) &, CPT(GeomVertexData) &) {
munge_geom_impl(CPT(Geom) &, CPT(GeomVertexData) &, Thread *) {
// The default implementation does nothing (the work has already
// been done in munge_format_impl() and munge_data_impl()).
return true;

View File

@ -72,7 +72,8 @@ public:
INLINE CPT(GeomVertexData) munge_data(const GeomVertexData *data) const;
void remove_data(const GeomVertexData *data);
void munge_geom(CPT(Geom) &geom, CPT(GeomVertexData) &data);
void munge_geom(CPT(Geom) &geom, CPT(GeomVertexData) &data,
Thread *current_thread);
public:
INLINE int compare_to(const GeomMunger &other) const;
@ -85,7 +86,8 @@ protected:
virtual CPT(GeomVertexFormat) munge_format_impl(const GeomVertexFormat *orig,
const GeomVertexAnimationSpec &animation);
virtual CPT(GeomVertexData) munge_data_impl(const GeomVertexData *data);
virtual bool munge_geom_impl(CPT(Geom) &geom, CPT(GeomVertexData) &data);
virtual bool munge_geom_impl(CPT(Geom) &geom, CPT(GeomVertexData) &data,
Thread *current_thread);
virtual int compare_to_impl(const GeomMunger *other) const;
virtual int geom_compare_to_impl(const GeomMunger *other) const;

View File

@ -1122,14 +1122,16 @@ void GeomPrimitive::
calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point,
bool &found_any,
const GeomVertexData *vertex_data,
bool got_mat, const LMatrix4f &mat) const {
GeomVertexReader reader(vertex_data, InternalName::get_vertex());
bool got_mat, const LMatrix4f &mat,
Thread *current_thread) const {
GeomVertexReader reader(vertex_data, InternalName::get_vertex(),
current_thread);
if (!reader.has_column()) {
// No vertex data.
return;
}
CDReader cdata(_cycler);
CDReader cdata(_cycler, current_thread);
if (cdata->_vertices == (GeomVertexArrayData *)NULL) {
// Nonindexed case.
@ -1173,7 +1175,7 @@ calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point,
} else {
// Indexed case.
GeomVertexReader index(cdata->_vertices, 0);
GeomVertexReader index(cdata->_vertices, 0, current_thread);
if (got_mat) {
while (!index.is_at_end()) {

View File

@ -192,7 +192,8 @@ public:
void calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point,
bool &found_any,
const GeomVertexData *vertex_data,
bool got_mat, const LMatrix4f &mat) const;
bool got_mat, const LMatrix4f &mat,
Thread *current_thread) const;
protected:
virtual CPT(GeomPrimitive) decompose_impl() const;

View File

@ -883,8 +883,8 @@ set_color(const Colorf &color, int num_components,
// graphics backend to update vertex buffers optimally).
////////////////////////////////////////////////////////////////////
CPT(GeomVertexData) GeomVertexData::
animate_vertices() const {
CDReader cdata(_cycler);
animate_vertices(Thread *current_thread) const {
CDReader cdata(_cycler, current_thread);
if (cdata->_format->get_animation().get_animation_type() != AT_panda) {
return this;
@ -1717,7 +1717,6 @@ make_array_readers() {
}
_got_array_readers = true;
nassertv(get_array_reader(0)->get_data_size_bytes() == get_array(0)->get_data_size_bytes());
}
////////////////////////////////////////////////////////////////////

View File

@ -139,7 +139,7 @@ PUBLISHED:
set_color(const Colorf &color, int num_components,
NumericType numeric_type, Contents contents) const;
CPT(GeomVertexData) animate_vertices() const;
CPT(GeomVertexData) animate_vertices(Thread *current_thread) const;
PT(GeomVertexData)
replace_column(InternalName *name, int num_components,

View File

@ -26,9 +26,9 @@
// it.
////////////////////////////////////////////////////////////////////
INLINE GeomVertexReader::
GeomVertexReader() :
GeomVertexReader(Thread *current_thread) :
_vertex_data(NULL),
_current_thread(Thread::get_current_thread())
_current_thread(current_thread)
{
initialize();
}
@ -40,9 +40,10 @@ GeomVertexReader() :
// the indicated data object.
////////////////////////////////////////////////////////////////////
INLINE GeomVertexReader::
GeomVertexReader(const GeomVertexData *vertex_data) :
GeomVertexReader(const GeomVertexData *vertex_data,
Thread *current_thread) :
_vertex_data(vertex_data),
_current_thread(Thread::get_current_thread())
_current_thread(current_thread)
{
initialize();
}
@ -55,9 +56,10 @@ GeomVertexReader(const GeomVertexData *vertex_data) :
// reader specifically to process the named data type.
////////////////////////////////////////////////////////////////////
INLINE GeomVertexReader::
GeomVertexReader(const GeomVertexData *vertex_data, const string &name) :
GeomVertexReader(const GeomVertexData *vertex_data, const string &name,
Thread *current_thread) :
_vertex_data(vertex_data),
_current_thread(Thread::get_current_thread())
_current_thread(current_thread)
{
initialize();
set_column(name);
@ -72,9 +74,10 @@ GeomVertexReader(const GeomVertexData *vertex_data, const string &name) :
////////////////////////////////////////////////////////////////////
INLINE GeomVertexReader::
GeomVertexReader(const GeomVertexData *vertex_data,
const InternalName *name) :
const InternalName *name,
Thread *current_thread) :
_vertex_data(vertex_data),
_current_thread(Thread::get_current_thread())
_current_thread(current_thread)
{
initialize();
set_column(name);
@ -87,9 +90,10 @@ GeomVertexReader(const GeomVertexData *vertex_data,
// the indicated array only.
////////////////////////////////////////////////////////////////////
INLINE GeomVertexReader::
GeomVertexReader(const GeomVertexArrayData *array_data) :
GeomVertexReader(const GeomVertexArrayData *array_data,
Thread *current_thread) :
_array_data(array_data),
_current_thread(Thread::get_current_thread())
_current_thread(current_thread)
{
initialize();
}
@ -101,9 +105,10 @@ GeomVertexReader(const GeomVertexArrayData *array_data) :
// the indicated array only.
////////////////////////////////////////////////////////////////////
INLINE GeomVertexReader::
GeomVertexReader(const GeomVertexArrayData *array_data, int column) :
GeomVertexReader(const GeomVertexArrayData *array_data, int column,
Thread *current_thread) :
_array_data(array_data),
_current_thread(Thread::get_current_thread())
_current_thread(current_thread)
{
initialize();
set_column(column);

View File

@ -59,15 +59,20 @@
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA GeomVertexReader : public GeomEnums {
PUBLISHED:
INLINE GeomVertexReader();
INLINE GeomVertexReader(const GeomVertexData *vertex_data);
INLINE GeomVertexReader(Thread *current_thread = Thread::get_current_thread());
INLINE GeomVertexReader(const GeomVertexData *vertex_data,
const string &name);
Thread *current_thread = Thread::get_current_thread());
INLINE GeomVertexReader(const GeomVertexData *vertex_data,
const InternalName *name);
INLINE GeomVertexReader(const GeomVertexArrayData *array_data);
const string &name,
Thread *current_thread = Thread::get_current_thread());
INLINE GeomVertexReader(const GeomVertexData *vertex_data,
const InternalName *name,
Thread *current_thread = Thread::get_current_thread());
INLINE GeomVertexReader(const GeomVertexArrayData *array_data,
Thread *current_thread = Thread::get_current_thread());
INLINE GeomVertexReader(const GeomVertexArrayData *array_data,
int column);
int column,
Thread *current_thread = Thread::get_current_thread());
public:
INLINE GeomVertexReader(const GeomVertexDataPipelineReader *data_reader,

View File

@ -26,9 +26,9 @@
// it.
////////////////////////////////////////////////////////////////////
INLINE GeomVertexWriter::
GeomVertexWriter() :
GeomVertexWriter(Thread *current_thread) :
_vertex_data(NULL),
_current_thread(Thread::get_current_thread())
_current_thread(current_thread)
{
initialize();
}
@ -40,9 +40,9 @@ GeomVertexWriter() :
// the indicated data object.
////////////////////////////////////////////////////////////////////
INLINE GeomVertexWriter::
GeomVertexWriter(GeomVertexData *vertex_data) :
GeomVertexWriter(GeomVertexData *vertex_data, Thread *current_thread) :
_vertex_data(vertex_data),
_current_thread(Thread::get_current_thread())
_current_thread(current_thread)
{
initialize();
}
@ -55,9 +55,10 @@ GeomVertexWriter(GeomVertexData *vertex_data) :
// writer specifically to process the named data type.
////////////////////////////////////////////////////////////////////
INLINE GeomVertexWriter::
GeomVertexWriter(GeomVertexData *vertex_data, const string &name) :
GeomVertexWriter(GeomVertexData *vertex_data, const string &name,
Thread *current_thread) :
_vertex_data(vertex_data),
_current_thread(Thread::get_current_thread())
_current_thread(current_thread)
{
initialize();
set_column(name);
@ -71,9 +72,10 @@ GeomVertexWriter(GeomVertexData *vertex_data, const string &name) :
// writer specifically to process the named data type.
////////////////////////////////////////////////////////////////////
INLINE GeomVertexWriter::
GeomVertexWriter(GeomVertexData *vertex_data, const InternalName *name) :
GeomVertexWriter(GeomVertexData *vertex_data, const InternalName *name,
Thread *current_thread) :
_vertex_data(vertex_data),
_current_thread(Thread::get_current_thread())
_current_thread(current_thread)
{
initialize();
set_column(name);
@ -86,9 +88,10 @@ GeomVertexWriter(GeomVertexData *vertex_data, const InternalName *name) :
// the indicated array only.
////////////////////////////////////////////////////////////////////
INLINE GeomVertexWriter::
GeomVertexWriter(GeomVertexArrayData *array_data) :
GeomVertexWriter(GeomVertexArrayData *array_data,
Thread *current_thread) :
_array_data(array_data),
_current_thread(Thread::get_current_thread())
_current_thread(current_thread)
{
initialize();
}
@ -100,9 +103,10 @@ GeomVertexWriter(GeomVertexArrayData *array_data) :
// the indicated array only.
////////////////////////////////////////////////////////////////////
INLINE GeomVertexWriter::
GeomVertexWriter(GeomVertexArrayData *array_data, int column) :
GeomVertexWriter(GeomVertexArrayData *array_data, int column,
Thread *current_thread) :
_array_data(array_data),
_current_thread(Thread::get_current_thread())
_current_thread(current_thread)
{
initialize();
set_column(column);

View File

@ -72,15 +72,20 @@
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA GeomVertexWriter : public GeomEnums {
PUBLISHED:
INLINE GeomVertexWriter();
INLINE GeomVertexWriter(GeomVertexData *vertex_data);
INLINE GeomVertexWriter(Thread *current_thread = Thread::get_current_thread());
INLINE GeomVertexWriter(GeomVertexData *vertex_data,
const string &name);
Thread *current_thread = Thread::get_current_thread());
INLINE GeomVertexWriter(GeomVertexData *vertex_data,
const InternalName *name);
INLINE GeomVertexWriter(GeomVertexArrayData *array_data);
const string &name,
Thread *current_thread = Thread::get_current_thread());
INLINE GeomVertexWriter(GeomVertexData *vertex_data,
const InternalName *name,
Thread *current_thread = Thread::get_current_thread());
INLINE GeomVertexWriter(GeomVertexArrayData *array_data,
Thread *current_thread = Thread::get_current_thread());
INLINE GeomVertexWriter(GeomVertexArrayData *array_data,
int column);
int column,
Thread *current_thread = Thread::get_current_thread());
public:
INLINE GeomVertexWriter(GeomVertexDataPipelineWriter *data_writer,

View File

@ -834,8 +834,8 @@ prepare_index_buffer_now(GeomPrimitive *data, GraphicsStateGuardianBase *gsg) {
// passed to prepare_texture are actually loaded.
////////////////////////////////////////////////////////////////////
void PreparedGraphicsObjects::
begin_frame(GraphicsStateGuardianBase *gsg) {
ReMutexHolder holder(_lock);
begin_frame(GraphicsStateGuardianBase *gsg, Thread *current_thread) {
ReMutexHolder holder(_lock, current_thread);
// First, release all the textures, geoms, and buffers awaiting
// release.
@ -890,9 +890,9 @@ begin_frame(GraphicsStateGuardianBase *gsg) {
_released_index_buffers.clear();
// Reset the residency trackers.
_texture_residency.begin_frame();
_vbuffer_residency.begin_frame();
_ibuffer_residency.begin_frame();
_texture_residency.begin_frame(current_thread);
_vbuffer_residency.begin_frame(current_thread);
_ibuffer_residency.begin_frame(current_thread);
// Now prepare all the textures, geoms, and buffers awaiting
// preparation.
@ -955,12 +955,12 @@ begin_frame(GraphicsStateGuardianBase *gsg) {
// frame.
////////////////////////////////////////////////////////////////////
void PreparedGraphicsObjects::
end_frame() {
ReMutexHolder holder(_lock);
end_frame(Thread *current_thread) {
ReMutexHolder holder(_lock, current_thread);
_texture_residency.end_frame();
_vbuffer_residency.end_frame();
_ibuffer_residency.end_frame();
_texture_residency.end_frame(current_thread);
_vbuffer_residency.end_frame(current_thread);
_ibuffer_residency.end_frame(current_thread);
}
////////////////////////////////////////////////////////////////////

View File

@ -106,8 +106,9 @@ public:
prepare_index_buffer_now(GeomPrimitive *data,
GraphicsStateGuardianBase *gsg);
void begin_frame(GraphicsStateGuardianBase *gsg);
void end_frame();
void begin_frame(GraphicsStateGuardianBase *gsg,
Thread *current_thread);
void end_frame(Thread *current_thread);
private:
static string init_name();

View File

@ -883,6 +883,7 @@ void MultitexReducer::
transfer_geom(GeomNode *geom_node, const InternalName *texcoord_name,
const MultitexReducer::GeomList &geom_list,
bool preserve_color) {
Thread *current_thread = Thread::get_current_thread();
GeomList::const_iterator gi;
for (gi = geom_list.begin(); gi != geom_list.end(); ++gi) {
const GeomInfo &geom_info = (*gi);
@ -893,7 +894,7 @@ transfer_geom(GeomNode *geom_node, const InternalName *texcoord_name,
PT(Geom) geom = orig_geom->make_copy();
// Ensure that any vertex animation has been applied.
geom->set_vertex_data(geom->get_vertex_data()->animate_vertices());
geom->set_vertex_data(geom->get_vertex_data(current_thread)->animate_vertices(current_thread));
// Now get a modifiable pointer to the vertex data in the new
// Geom. This will actually perform a deep copy of the vertex
@ -902,8 +903,8 @@ transfer_geom(GeomNode *geom_node, const InternalName *texcoord_name,
vdata->set_usage_hint(Geom::UH_stream);
if (vdata->has_column(_target_stage->get_texcoord_name())) {
GeomVertexWriter vertex(vdata, InternalName::get_vertex());
GeomVertexReader texcoord(vdata, _target_stage->get_texcoord_name());
GeomVertexWriter vertex(vdata, InternalName::get_vertex(), current_thread);
GeomVertexReader texcoord(vdata, _target_stage->get_texcoord_name(), current_thread);
while (!texcoord.is_at_end()) {
const LVecBase2f &tc = texcoord.get_data2f();
@ -923,8 +924,8 @@ transfer_geom(GeomNode *geom_node, const InternalName *texcoord_name,
column->get_numeric_type(), column->get_contents());
geom->set_vertex_data(vdata);
GeomVertexReader from(vdata, texcoord_name);
GeomVertexWriter to(vdata, InternalName::get_texcoord());
GeomVertexReader from(vdata, texcoord_name, current_thread);
GeomVertexWriter to(vdata, InternalName::get_texcoord(), current_thread);
while (!from.is_at_end()) {
to.add_data2f(from.get_data2f());
}

View File

@ -233,9 +233,10 @@ write(ostream &out, int indent_level) const {
////////////////////////////////////////////////////////////////////
void RopeNode::
reset_bound(const NodePath &rel_to) {
int pipeline_stage = Thread::get_current_pipeline_stage();
do_recompute_bounds(rel_to, pipeline_stage);
mark_internal_bounds_stale();
Thread *current_thread = Thread::get_current_thread();
int pipeline_stage = current_thread->get_pipeline_stage();
do_recompute_bounds(rel_to, pipeline_stage, current_thread);
mark_internal_bounds_stale(current_thread);
}
////////////////////////////////////////////////////////////////////
@ -247,8 +248,9 @@ reset_bound(const NodePath &rel_to) {
// thing.
////////////////////////////////////////////////////////////////////
PT(BoundingVolume) RopeNode::
compute_internal_bounds(int pipeline_stage) const {
return do_recompute_bounds(NodePath((PandaNode *)this), pipeline_stage);
compute_internal_bounds(int pipeline_stage, Thread *current_thread) const {
return do_recompute_bounds(NodePath((PandaNode *)this), pipeline_stage,
current_thread);
}
////////////////////////////////////////////////////////////////////
@ -289,13 +291,14 @@ get_format(bool support_normals) const {
// Description: Does the actual internal recompute.
////////////////////////////////////////////////////////////////////
PT(BoundingVolume) RopeNode::
do_recompute_bounds(const NodePath &rel_to, int pipeline_stage) const {
do_recompute_bounds(const NodePath &rel_to, int pipeline_stage,
Thread *current_thread) const {
// TODO: fix the bounds so that it properly reflects the indicated
// pipeline stage. At the moment, we cheat and get some of the
// properties from the current pipeline stage, the lazy way.
// First, get ourselves a fresh, empty bounding volume.
PT(BoundingVolume) bound = PandaNode::compute_internal_bounds(pipeline_stage);
PT(BoundingVolume) bound = PandaNode::compute_internal_bounds(pipeline_stage, current_thread);
nassertr(bound != (BoundingVolume *)NULL, bound);
NurbsCurveEvaluator *curve = get_curve();

View File

@ -142,13 +142,14 @@ PUBLISHED:
void reset_bound(const NodePath &rel_to);
protected:
virtual PT(BoundingVolume) compute_internal_bounds(int pipeline_stage) const;
virtual PT(BoundingVolume) compute_internal_bounds(int pipeline_stage, Thread *current_thread) const;
private:
CPT(GeomVertexFormat) get_format(bool support_normals) const;
PT(BoundingVolume) do_recompute_bounds(const NodePath &rel_to,
int pipeline_stage) const;
int pipeline_stage,
Thread *current_thread) const;
void render_thread(CullTraverser *trav, CullTraverserData &data,
NurbsCurveResult *result) const;
void render_tape(CullTraverser *trav, CullTraverserData &data,

View File

@ -215,9 +215,10 @@ write(ostream &out, int indent_level) const {
////////////////////////////////////////////////////////////////////
void SheetNode::
reset_bound(const NodePath &rel_to) {
int pipeline_stage = Thread::get_current_pipeline_stage();
do_recompute_bounds(rel_to, pipeline_stage);
mark_internal_bounds_stale();
Thread *current_thread = Thread::get_current_thread();
int pipeline_stage = current_thread->get_pipeline_stage();
do_recompute_bounds(rel_to, pipeline_stage, current_thread);
mark_internal_bounds_stale(current_thread);
}
////////////////////////////////////////////////////////////////////
@ -229,8 +230,9 @@ reset_bound(const NodePath &rel_to) {
// thing.
////////////////////////////////////////////////////////////////////
PT(BoundingVolume) SheetNode::
compute_internal_bounds(int pipeline_stage) const {
return do_recompute_bounds(NodePath((PandaNode *)this), pipeline_stage);
compute_internal_bounds(int pipeline_stage, Thread *current_thread) const {
return do_recompute_bounds(NodePath((PandaNode *)this), pipeline_stage,
current_thread);
}
////////////////////////////////////////////////////////////////////
@ -239,13 +241,14 @@ compute_internal_bounds(int pipeline_stage) const {
// Description: Does the actual internal recompute.
////////////////////////////////////////////////////////////////////
PT(BoundingVolume) SheetNode::
do_recompute_bounds(const NodePath &rel_to, int pipeline_stage) const {
do_recompute_bounds(const NodePath &rel_to, int pipeline_stage,
Thread *current_thread) const {
// TODO: fix the bounds so that it properly reflects the indicated
// pipeline stage. At the moment, we cheat and get some of the
// properties from the current pipeline stage, the lazy way.
// First, get ourselves a fresh, empty bounding volume.
PT(BoundingVolume) bound = PandaNode::compute_internal_bounds(pipeline_stage);
PT(BoundingVolume) bound = PandaNode::compute_internal_bounds(pipeline_stage, current_thread);
nassertr(bound != (BoundingVolume *)NULL, bound);
NurbsSurfaceEvaluator *surface = get_surface();

View File

@ -68,11 +68,12 @@ PUBLISHED:
void reset_bound(const NodePath &rel_to);
protected:
virtual PT(BoundingVolume) compute_internal_bounds(int pipeline_stage) const;
virtual PT(BoundingVolume) compute_internal_bounds(int pipeline_stage, Thread *current_thread) const;
private:
PT(BoundingVolume) do_recompute_bounds(const NodePath &rel_to,
int pipeline_stage) const;
int pipeline_stage,
Thread *current_thread) const;
void render_sheet(CullTraverser *trav, CullTraverserData &data,
NurbsSurfaceResult *result);

View File

@ -51,16 +51,6 @@ make_next() const {
return (CullBin *)NULL;
}
////////////////////////////////////////////////////////////////////
// Function: CullBin::add_object
// Access: Public, Virtual
// Description: Adds a geom, along with its associated state, to
// the bin for rendering.
////////////////////////////////////////////////////////////////////
void CullBin::
add_object(CullableObject *) {
}
////////////////////////////////////////////////////////////////////
// Function: CullBin::finish_cull
// Access: Public, Virtual
@ -71,7 +61,7 @@ add_object(CullableObject *) {
// draw.
////////////////////////////////////////////////////////////////////
void CullBin::
finish_cull(SceneSetup *) {
finish_cull(SceneSetup *, Thread *) {
}
////////////////////////////////////////////////////////////////////

View File

@ -54,8 +54,8 @@ public:
virtual PT(CullBin) make_next() const;
virtual void add_object(CullableObject *object)=0;
virtual void finish_cull(SceneSetup *scene_setup);
virtual void add_object(CullableObject *object, Thread *current_thread)=0;
virtual void finish_cull(SceneSetup *scene_setup, Thread *current_thread);
virtual void draw(Thread *current_thread)=0;

View File

@ -98,6 +98,8 @@ add_object(CullableObject *object, const CullTraverser *traverser) {
static const Colorf flash_multisample_color(0.78f, 0.05f, 0.81f, 1.0f);
static const Colorf flash_dual_color(0.92f, 0.01f, 0.01f, 1.0f);
Thread *current_thread = traverser->get_current_thread();
// Check to see if there's a special transparency setting.
const RenderState *state = object->_state;
nassertv(state != (const RenderState *)NULL);
@ -172,7 +174,7 @@ add_object(CullableObject *object, const CullTraverser *traverser) {
#ifndef NDEBUG
check_flash_bin(transparent_part->_state, bin);
#endif
bin->add_object(transparent_part);
bin->add_object(transparent_part, current_thread);
}
// Now we can draw the opaque part, with decals. This will
@ -206,8 +208,7 @@ add_object(CullableObject *object, const CullTraverser *traverser) {
// Munge vertices as needed for the GSG's requirements, and the
// object's current state.
object->munge_geom(_gsg, _gsg->get_geom_munger(object->_state), traverser);
bin->add_object(object);
bin->add_object(object, current_thread);
}
////////////////////////////////////////////////////////////////////
@ -220,7 +221,7 @@ add_object(CullableObject *object, const CullTraverser *traverser) {
// draw.
////////////////////////////////////////////////////////////////////
void CullResult::
finish_cull(SceneSetup *scene_setup) {
finish_cull(SceneSetup *scene_setup, Thread *current_thread) {
CullBinManager *bin_manager = CullBinManager::get_global_ptr();
for (size_t i = 0; i < _bins.size(); ++i) {
@ -232,7 +233,7 @@ finish_cull(SceneSetup *scene_setup) {
} else {
CullBin *bin = _bins[i];
if (bin != (CullBin *)NULL) {
bin->finish_cull(scene_setup);
bin->finish_cull(scene_setup, current_thread);
}
}
}

View File

@ -59,7 +59,7 @@ public:
INLINE CullBin *get_bin(int bin_index);
void add_object(CullableObject *object, const CullTraverser *traverser);
void finish_cull(SceneSetup *scene_setup);
void finish_cull(SceneSetup *scene_setup, Thread *current_thread);
void draw(Thread *current_thread);
public:

View File

@ -27,6 +27,17 @@ get_gsg() const {
return _gsg;
}
////////////////////////////////////////////////////////////////////
// Function: CullTraverser::get_current_thread
// Access: Public
// Description: Returns the currently-executing thread object, as
// passed to the CullTraverser constructor.
////////////////////////////////////////////////////////////////////
INLINE Thread *CullTraverser::
get_current_thread() const {
return _current_thread;
}
////////////////////////////////////////////////////////////////////
// Function: CullTraverser::set_scene
// Access: Public

View File

@ -50,8 +50,9 @@ TypeHandle CullTraverser::_type_handle;
// Description:
////////////////////////////////////////////////////////////////////
CullTraverser::
CullTraverser(GraphicsStateGuardianBase *gsg) :
_gsg(gsg)
CullTraverser(GraphicsStateGuardianBase *gsg, Thread *current_thread) :
_gsg(gsg),
_current_thread(current_thread)
{
_camera_mask = DrawMask::all_on();
_has_tag_state_key = false;
@ -151,7 +152,7 @@ traverse(CullTraverserData &data) {
// optimization, we should tag nodes with these properties as
// being "fancy", and skip this processing for non-fancy nodes.
if (data.is_in_view(_camera_mask)) {
if (data.is_in_view(_camera_mask, _current_thread)) {
if (pgraph_cat.is_spam()) {
pgraph_cat.spam()
<< "\n" << data._node_path
@ -378,12 +379,14 @@ make_tight_bounds_viz(PandaNode *node) {
LPoint3f n, x;
bool found_any = false;
node->calc_tight_bounds(n, x, found_any, TransformState::make_identity());
node->calc_tight_bounds(n, x, found_any, TransformState::make_identity(),
_current_thread);
if (found_any) {
PT(GeomVertexData) vdata = new GeomVertexData
("bounds", GeomVertexFormat::get_v3(),
Geom::UH_stream);
GeomVertexWriter vertex(vdata, InternalName::get_vertex());
GeomVertexWriter vertex(vdata, InternalName::get_vertex(),
_current_thread);
vertex.add_data3f(n[0], n[1], n[2]);
vertex.add_data3f(n[0], n[1], x[2]);
@ -586,7 +589,7 @@ start_decal(const CullTraverserData &data) {
////////////////////////////////////////////////////////////////////
CullableObject *CullTraverser::
r_get_decals(CullTraverserData &data, CullableObject *decals) {
if (data.is_in_view(_camera_mask)) {
if (data.is_in_view(_camera_mask, _current_thread)) {
PandaNode *node = data.node();
const RenderEffects *node_effects = node->get_effects();

View File

@ -50,10 +50,11 @@ class NodePath;
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA CullTraverser : public TypedObject {
public:
CullTraverser(GraphicsStateGuardianBase *gsg);
CullTraverser(GraphicsStateGuardianBase *gsg, Thread *current_thread);
CullTraverser(const CullTraverser &copy);
INLINE GraphicsStateGuardianBase *get_gsg() const;
INLINE Thread *get_current_thread() const;
INLINE void set_scene(SceneSetup *scene_setup);
INLINE SceneSetup *get_scene() const;
@ -111,6 +112,7 @@ private:
CullableObject *decals);
GraphicsStateGuardianBase *_gsg;
Thread *_current_thread;
PT(SceneSetup) _scene_setup;
DrawMask _camera_mask;
bool _has_tag_state_key;

View File

@ -128,13 +128,13 @@ get_net_transform(const CullTraverser *) const {
// work for future nodes.
////////////////////////////////////////////////////////////////////
INLINE bool CullTraverserData::
is_in_view(const DrawMask &camera_mask) {
if (node()->get_transform()->is_invalid()) {
is_in_view(const DrawMask &camera_mask, Thread *current_thread) {
if (node()->get_transform(current_thread)->is_invalid()) {
// If the transform is invalid, forget it.
return false;
}
if (!node()->compare_draw_mask(_draw_mask, camera_mask)) {
if (!node()->compare_draw_mask(_draw_mask, camera_mask, current_thread)) {
// If there are no draw bits in common with the camera, the node
// is out.
return false;

View File

@ -63,7 +63,7 @@ public:
CPT(TransformState) get_modelview_transform(const CullTraverser *trav) const;
INLINE const TransformState *get_net_transform(const CullTraverser *trav) const;
INLINE bool is_in_view(const DrawMask &camera_mask);
INLINE bool is_in_view(const DrawMask &camera_mask, Thread *current_thread);
INLINE bool is_this_node_hidden(const CullTraverser *trav) const;
void apply_transform_and_state(CullTraverser *trav);

View File

@ -50,11 +50,21 @@ void CullableObject::
munge_geom(GraphicsStateGuardianBase *gsg,
GeomMunger *munger, const CullTraverser *traverser) {
if (_geom != (Geom *)NULL) {
Thread *current_thread = traverser->get_current_thread();
_munger = munger;
_munged_data = _geom->get_vertex_data();
nassertv(_geom->check_valid(_munged_data));
int geom_rendering = _geom->get_geom_rendering();
GeomPipelineReader geom_reader(_geom, current_thread);
_munged_data = geom_reader.get_vertex_data();
#ifndef NDEBUG
{
GeomVertexDataPipelineReader data_reader(_munged_data, current_thread);
data_reader.check_array_readers();
nassertv(geom_reader.check_valid(&data_reader));
}
#endif // NDEBUG
int geom_rendering = geom_reader.get_geom_rendering();
geom_rendering = _state->get_geom_rendering(geom_rendering);
geom_rendering = _modelview_transform->get_geom_rendering(geom_rendering);
@ -89,7 +99,7 @@ munge_geom(GraphicsStateGuardianBase *gsg,
// the vertices in the CPU--and we have to do it before we call
// munge_geom(), which might lose the tangent and binormal.
CPT(GeomVertexData) animated_vertices =
_munged_data->animate_vertices();
_munged_data->animate_vertices(current_thread);
if (animated_vertices != _munged_data) {
cpu_animated = true;
_munged_data = animated_vertices;
@ -99,7 +109,7 @@ munge_geom(GraphicsStateGuardianBase *gsg,
// Now invoke the munger to ensure the resulting geometry is in
// a GSG-friendly form.
munger->munge_geom(_geom, _munged_data);
munger->munge_geom(_geom, _munged_data, current_thread);
StateMunger *state_munger;
DCAST_INTO_V(state_munger, munger);
@ -111,7 +121,7 @@ munge_geom(GraphicsStateGuardianBase *gsg,
// animation in hardware--then we have to calculate that
// animation now.
CPT(GeomVertexData) animated_vertices =
_munged_data->animate_vertices();
_munged_data->animate_vertices(current_thread);
if (animated_vertices != _munged_data) {
cpu_animated = true;
_munged_data = animated_vertices;
@ -120,7 +130,8 @@ munge_geom(GraphicsStateGuardianBase *gsg,
#ifndef NDEBUG
if (show_vertex_animation) {
bool hardware_animated = (_munged_data->get_format()->get_animation().get_animation_type() == Geom::AT_hardware);
GeomVertexDataPipelineReader data_reader(_munged_data, current_thread);
bool hardware_animated = (data_reader.get_format()->get_animation().get_animation_type() == Geom::AT_hardware);
if (cpu_animated || hardware_animated) {
// These vertices were animated, so flash them red or blue.
static const double flash_rate = 1.0; // 1 state change per second
@ -178,17 +189,25 @@ output(ostream &out) const {
////////////////////////////////////////////////////////////////////
void CullableObject::
munge_points_to_quads(const CullTraverser *traverser) {
PStatTimer timer(_munge_points_pcollector);
Thread *current_thread = traverser->get_current_thread();
PStatTimer timer(_munge_points_pcollector, current_thread);
GraphicsStateGuardianBase *gsg = traverser->get_gsg();
GeomVertexReader vertex(_munged_data, InternalName::get_vertex());
GeomVertexReader normal(_munged_data, InternalName::get_normal());
GeomVertexReader color(_munged_data, InternalName::get_color());
GeomVertexReader texcoord(_munged_data, InternalName::get_texcoord());
GeomVertexReader rotate(_munged_data, InternalName::get_rotate());
GeomVertexReader size(_munged_data, InternalName::get_size());
GeomVertexReader aspect_ratio(_munged_data, InternalName::get_aspect_ratio());
GeomVertexReader vertex(_munged_data, InternalName::get_vertex(),
current_thread);
GeomVertexReader normal(_munged_data, InternalName::get_normal(),
current_thread);
GeomVertexReader color(_munged_data, InternalName::get_color(),
current_thread);
GeomVertexReader texcoord(_munged_data, InternalName::get_texcoord(),
current_thread);
GeomVertexReader rotate(_munged_data, InternalName::get_rotate(),
current_thread);
GeomVertexReader size(_munged_data, InternalName::get_size(),
current_thread);
GeomVertexReader aspect_ratio(_munged_data, InternalName::get_aspect_ratio(),
current_thread);
bool has_normal = (normal.has_column());
bool has_color = (color.has_column());
@ -301,9 +320,11 @@ munge_points_to_quads(const CullTraverser *traverser) {
// CullFaceAttrib but will always render all of the vertices of the
// polygons. This is certainly a bug, but in order to fix it we'd
// have to do the face culling ourselves--not sure if it's worth it.
int num_primitives = _geom->get_num_primitives();
GeomPipelineReader geom_reader(_geom, current_thread);
int num_primitives = geom_reader.get_num_primitives();
for (int pi = 0; pi < num_primitives; ++pi) {
const GeomPrimitive *primitive = _geom->get_primitive(pi);
const GeomPrimitive *primitive = geom_reader.get_primitive(pi);
if (primitive->get_num_vertices() != 0) {
// We must first convert all of the points to eye space.
int num_points = primitive->get_max_vertex() + 1;
@ -314,7 +335,7 @@ munge_points_to_quads(const CullTraverser *traverser) {
unsigned int *vertices_end = vertices + num_vertices;
if (primitive->is_indexed()) {
GeomVertexReader index(primitive->get_vertices(), 0);
GeomVertexReader index(primitive->get_vertices(), 0, current_thread);
for (unsigned int *vi = vertices; vi != vertices_end; ++vi) {
// Get the point in eye-space coordinates.
unsigned int v = index.get_data1i();
@ -475,7 +496,8 @@ munge_points_to_quads(const CullTraverser *traverser) {
////////////////////////////////////////////////////////////////////
void CullableObject::
munge_texcoord_light_vector(const CullTraverser *traverser) {
PStatTimer timer(_munge_light_vector_pcollector);
Thread *current_thread = traverser->get_current_thread();
PStatTimer timer(_munge_light_vector_pcollector, current_thread);
if (_net_transform->is_singular()) {
// If we're under a singular transform, never mind.
@ -547,11 +569,13 @@ munge_texcoord_light_vector(const CullTraverser *traverser) {
_net_transform->invert_compose(light.get_net_transform());
const LMatrix4f &light_mat = light_transform->get_mat();
GeomVertexWriter texcoord(new_data, texcoord_name);
GeomVertexReader vertex(new_data, InternalName::get_vertex());
GeomVertexReader tangent(new_data, tangent_name);
GeomVertexReader binormal(new_data, binormal_name);
GeomVertexReader normal(new_data, InternalName::get_normal());
GeomVertexWriter texcoord(new_data, texcoord_name, current_thread);
GeomVertexReader vertex(new_data, InternalName::get_vertex(),
current_thread);
GeomVertexReader tangent(new_data, tangent_name, current_thread);
GeomVertexReader binormal(new_data, binormal_name, current_thread);
GeomVertexReader normal(new_data, InternalName::get_normal(),
current_thread);
while (!vertex.is_at_end()) {
LPoint3f p = vertex.get_data3f();

View File

@ -349,17 +349,21 @@ combine_with(PandaNode *other) {
////////////////////////////////////////////////////////////////////
CPT(TransformState) GeomNode::
calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point, bool &found_any,
const TransformState *transform) const {
const TransformState *transform, Thread *current_thread) const {
CPT(TransformState) next_transform =
PandaNode::calc_tight_bounds(min_point, max_point, found_any, transform);
PandaNode::calc_tight_bounds(min_point, max_point, found_any, transform,
current_thread);
const LMatrix4f &mat = next_transform->get_mat();
int num_geoms = get_num_geoms();
for (int i = 0; i < num_geoms; i++) {
const Geom *geom = get_geom(i);
CDReader cdata(_cycler, current_thread);
Geoms::const_iterator gi;
for (gi = cdata->_geoms.begin(); gi != cdata->_geoms.end(); ++gi) {
const Geom *geom = (*gi)._geom;
geom->calc_tight_bounds(min_point, max_point, found_any,
geom->get_vertex_data()->animate_vertices(),
!next_transform->is_identity(), mat);
geom->get_vertex_data(current_thread)->animate_vertices(current_thread),
!next_transform->is_identity(), mat,
current_thread);
}
return next_transform;
@ -661,16 +665,16 @@ is_geom_node() const {
// something internally.
////////////////////////////////////////////////////////////////////
PT(BoundingVolume) GeomNode::
compute_internal_bounds(int pipeline_stage) const {
compute_internal_bounds(int pipeline_stage, Thread *current_thread) const {
// First, get ourselves a fresh, empty bounding volume.
PT(BoundingVolume) bound = PandaNode::compute_internal_bounds(pipeline_stage);
PT(BoundingVolume) bound = PandaNode::compute_internal_bounds(pipeline_stage, current_thread);
nassertr(bound != (BoundingVolume *)NULL, bound);
// Now actually compute the bounding volume by putting it around all
// of our geoms' bounding volumes.
pvector<const BoundingVolume *> child_volumes;
CDStageReader cdata(_cycler, pipeline_stage);
CDStageReader cdata(_cycler, pipeline_stage, current_thread);
Geoms::const_iterator gi;
for (gi = cdata->_geoms.begin(); gi != cdata->_geoms.end(); ++gi) {
const GeomEntry &entry = (*gi);

View File

@ -52,7 +52,8 @@ public:
virtual CPT(TransformState)
calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point,
bool &found_any,
const TransformState *transform) const;
const TransformState *transform,
Thread *current_thread) const;
virtual bool is_renderable() const;
virtual CollideMask get_legal_collide_mask() const;
@ -84,7 +85,7 @@ public:
virtual bool is_geom_node() const;
protected:
virtual PT(BoundingVolume) compute_internal_bounds(int pipeline_stage) const;
virtual PT(BoundingVolume) compute_internal_bounds(int pipeline_stage, Thread *current_thread) const;
public:
// This must be declared public so that VC6 will allow the nested

View File

@ -36,12 +36,12 @@ NodePath() :
// with the indicated name.
////////////////////////////////////////////////////////////////////
INLINE NodePath::
NodePath(const string &top_node_name) :
NodePath(const string &top_node_name, Thread *current_thread) :
_error_type(ET_ok)
{
PandaNode *top_node = new PandaNode(top_node_name);
int pipeline_stage = Thread::get_current_pipeline_stage();
_head = top_node->get_generic_component(false, pipeline_stage);
int pipeline_stage = current_thread->get_pipeline_stage();
_head = top_node->get_generic_component(false, pipeline_stage, current_thread);
_backup_key = 0;
}
@ -57,12 +57,12 @@ NodePath(const string &top_node_name) :
// also NodePath::any_path(), below).
////////////////////////////////////////////////////////////////////
INLINE NodePath::
NodePath(PandaNode *node) :
NodePath(PandaNode *node, Thread *current_thread) :
_error_type(ET_ok)
{
if (node != (PandaNode *)NULL) {
int pipeline_stage = Thread::get_current_pipeline_stage();
_head = node->get_generic_component(false, pipeline_stage);
int pipeline_stage = current_thread->get_pipeline_stage();
_head = node->get_generic_component(false, pipeline_stage, current_thread);
}
_backup_key = 0;
}
@ -77,11 +77,12 @@ NodePath(PandaNode *node) :
// the path is ambiguous.
////////////////////////////////////////////////////////////////////
INLINE NodePath NodePath::
any_path(PandaNode *node) {
any_path(PandaNode *node, Thread *current_thread) {
NodePath result;
if (node != (PandaNode *)NULL) {
int pipeline_stage = Thread::get_current_pipeline_stage();
result._head = node->get_generic_component(true, pipeline_stage);
int pipeline_stage = current_thread->get_pipeline_stage();
result._head = node->get_generic_component(true, pipeline_stage,
current_thread);
}
return result;
}
@ -94,13 +95,15 @@ any_path(PandaNode *node) {
// stashed or unstashed child of the parent.
////////////////////////////////////////////////////////////////////
INLINE NodePath::
NodePath(const NodePath &parent, PandaNode *child_node) :
NodePath(const NodePath &parent, PandaNode *child_node,
Thread *current_thread) :
_error_type(ET_fail)
{
nassertv(!parent.is_empty());
nassertv(child_node != (PandaNode *)NULL);
int pipeline_stage = Thread::get_current_pipeline_stage();
_head = PandaNode::get_component(parent._head, child_node, pipeline_stage);
int pipeline_stage = current_thread->get_pipeline_stage();
_head = PandaNode::get_component(parent._head, child_node, pipeline_stage,
current_thread);
nassertv(_head != (NodePathComponent *)NULL);
if (_head != (NodePathComponent *)NULL) {
@ -229,9 +232,9 @@ is_empty() const {
// node.
////////////////////////////////////////////////////////////////////
INLINE bool NodePath::
is_singleton() const {
int pipeline_stage = Thread::get_current_pipeline_stage();
return (_head != (NodePathComponent *)NULL && _head->is_top_node(pipeline_stage));
is_singleton(Thread *current_thread) const {
int pipeline_stage = current_thread->get_pipeline_stage();
return (_head != (NodePathComponent *)NULL && _head->is_top_node(pipeline_stage, current_thread));
}
////////////////////////////////////////////////////////////////////
@ -252,12 +255,12 @@ get_error_type() const {
// is empty. This requires iterating through the path.
////////////////////////////////////////////////////////////////////
INLINE PandaNode *NodePath::
get_top_node() const {
get_top_node(Thread *current_thread) const {
if (is_empty()) {
return (PandaNode *)NULL;
}
return get_top().node();
return get_top(current_thread).node();
}
////////////////////////////////////////////////////////////////////
@ -306,7 +309,7 @@ get_key() const {
// same (e.g., both "render").
////////////////////////////////////////////////////////////////////
INLINE bool NodePath::
is_same_graph(const NodePath &other) const {
is_same_graph(const NodePath &other, Thread *current_thread) const {
// Actually, it's possible for the top nodes to be the same, but the
// NodePaths still to be considered in different graphs. But even
// in this case, get_top() will be different for each one. (They'll
@ -318,7 +321,7 @@ is_same_graph(const NodePath &other) const {
// returns a different instance of render that appears to have the
// same top node. But this is a very rare thing to do.
int a_count, b_count;
return (find_common_ancestor(*this, other, a_count, b_count) != (NodePathComponent *)NULL);
return (find_common_ancestor(*this, other, a_count, b_count, current_thread) != (NodePathComponent *)NULL);
}
////////////////////////////////////////////////////////////////////
@ -329,9 +332,9 @@ is_same_graph(const NodePath &other) const {
// or false if it is not.
////////////////////////////////////////////////////////////////////
INLINE bool NodePath::
is_ancestor_of(const NodePath &other) const {
is_ancestor_of(const NodePath &other, Thread *current_thread) const {
int a_count, b_count;
if (find_common_ancestor(*this, other, a_count, b_count) == (NodePathComponent *)NULL) {
if (find_common_ancestor(*this, other, a_count, b_count, current_thread) == (NodePathComponent *)NULL) {
// Not related.
return false;
}
@ -350,9 +353,9 @@ is_ancestor_of(const NodePath &other) const {
// unrelated, returns NodePath::not_found().
////////////////////////////////////////////////////////////////////
INLINE NodePath NodePath::
get_common_ancestor(const NodePath &other) const {
get_common_ancestor(const NodePath &other, Thread *current_thread) const {
int a_count, b_count;
NodePathComponent *common = find_common_ancestor(*this, other, a_count, b_count);
NodePathComponent *common = find_common_ancestor(*this, other, a_count, b_count, current_thread);
if (common == (NodePathComponent *)NULL) {
return NodePath::not_found();
}
@ -368,9 +371,9 @@ get_common_ancestor(const NodePath &other) const {
// Description: Returns the number of children of the referenced node.
////////////////////////////////////////////////////////////////////
INLINE int NodePath::
get_num_children() const {
get_num_children(Thread *current_thread) const {
nassertr_always(!is_empty(), 0);
return _head->get_node()->get_num_children();
return _head->get_node()->get_num_children(current_thread);
}
////////////////////////////////////////////////////////////////////
@ -380,12 +383,12 @@ get_num_children() const {
// referenced node.
////////////////////////////////////////////////////////////////////
INLINE NodePath NodePath::
get_child(int n) const {
nassertr(n >= 0 && n < get_num_children(), NodePath());
get_child(int n, Thread *current_thread) const {
nassertr(n >= 0 && n < get_num_children(current_thread), NodePath());
NodePath child;
int pipeline_stage = Thread::get_current_pipeline_stage();
child._head = PandaNode::get_component(_head, _head->get_node()->get_child(n),
pipeline_stage);
int pipeline_stage = current_thread->get_pipeline_stage();
child._head = PandaNode::get_component(_head, _head->get_node()->get_child(n, current_thread),
pipeline_stage, current_thread);
return child;
}
@ -396,8 +399,8 @@ get_child(int n) const {
// i.e. the NodePath chain contains at least two nodes.
////////////////////////////////////////////////////////////////////
INLINE bool NodePath::
has_parent() const {
return !is_empty() && !is_singleton();
has_parent(Thread *current_thread) const {
return !is_empty() && !is_singleton(current_thread);
}
////////////////////////////////////////////////////////////////////
@ -409,15 +412,15 @@ has_parent() const {
// the empty NodePath.
////////////////////////////////////////////////////////////////////
INLINE NodePath NodePath::
get_parent() const {
if (!has_parent()) {
get_parent(Thread *current_thread) const {
if (!has_parent(current_thread)) {
return NodePath();
}
int pipeline_stage = Thread::get_current_pipeline_stage();
int pipeline_stage = current_thread->get_pipeline_stage();
NodePath parent;
parent._head = _head->get_next(pipeline_stage);
parent._head = _head->get_next(pipeline_stage, current_thread);
return parent;
}
@ -429,10 +432,10 @@ get_parent() const {
// references it.
////////////////////////////////////////////////////////////////////
INLINE NodePath NodePath::
attach_new_node(const string &name, int sort) const {
nassertr(verify_complete(), NodePath::fail());
attach_new_node(const string &name, int sort, Thread *current_thread) const {
nassertr(verify_complete(current_thread), NodePath::fail());
return attach_new_node(new PandaNode(name), sort);
return attach_new_node(new PandaNode(name), sort, current_thread);
}
////////////////////////////////////////////////////////////////////
@ -492,9 +495,9 @@ reverse_ls(ostream &out, int indent_level) const {
// Description: Changes the complete state object on this node.
////////////////////////////////////////////////////////////////////
INLINE void NodePath::
set_state(const RenderState *state) {
set_state(const RenderState *state, Thread *current_thread) {
nassertv_always(!is_empty());
node()->set_state(state);
node()->set_state(state, current_thread);
}
////////////////////////////////////////////////////////////////////
@ -503,9 +506,9 @@ set_state(const RenderState *state) {
// Description: Returns the net state on this node from the root.
////////////////////////////////////////////////////////////////////
INLINE CPT(RenderState) NodePath::
get_net_state() const {
get_net_state(Thread *current_thread) const {
nassertr(_error_type == ET_ok, RenderState::make_empty());
return r_get_net_state(_head);
return r_get_net_state(_head, current_thread);
}
////////////////////////////////////////////////////////////////////
@ -657,8 +660,8 @@ clear_effects() {
// Description: Sets the transform object on this node to identity.
////////////////////////////////////////////////////////////////////
INLINE void NodePath::
clear_transform() {
set_transform(TransformState::make_identity());
clear_transform(Thread *current_thread) {
set_transform(TransformState::make_identity(), current_thread);
}
////////////////////////////////////////////////////////////////////
@ -667,9 +670,9 @@ clear_transform() {
// Description: Changes the complete transform object on this node.
////////////////////////////////////////////////////////////////////
INLINE void NodePath::
set_transform(const TransformState *transform) {
set_transform(const TransformState *transform, Thread *current_thread) {
nassertv_always(!is_empty());
node()->set_transform(transform);
node()->set_transform(transform, current_thread);
}
////////////////////////////////////////////////////////////////////
@ -680,8 +683,8 @@ set_transform(const TransformState *transform) {
// this node at the same position as the other node.
////////////////////////////////////////////////////////////////////
INLINE void NodePath::
clear_transform(const NodePath &other) {
set_transform(other, TransformState::make_identity());
clear_transform(const NodePath &other, Thread *current_thread) {
set_transform(other, TransformState::make_identity(), current_thread);
}
////////////////////////////////////////////////////////////////////
@ -690,9 +693,9 @@ clear_transform(const NodePath &other) {
// Description: Returns the net transform on this node from the root.
////////////////////////////////////////////////////////////////////
INLINE CPT(TransformState) NodePath::
get_net_transform() const {
get_net_transform(Thread *current_thread) const {
nassertr(_error_type == ET_ok, TransformState::make_identity());
return r_get_net_transform(_head);
return r_get_net_transform(_head, current_thread);
}
////////////////////////////////////////////////////////////////////
@ -704,9 +707,9 @@ get_net_transform() const {
// calculations.
////////////////////////////////////////////////////////////////////
INLINE void NodePath::
set_prev_transform(const TransformState *transform) {
set_prev_transform(const TransformState *transform, Thread *current_thread) {
nassertv_always(!is_empty());
node()->set_prev_transform(transform);
node()->set_prev_transform(transform, current_thread);
}
////////////////////////////////////////////////////////////////////
@ -716,9 +719,9 @@ set_prev_transform(const TransformState *transform) {
// from the root. See set_prev_transform().
////////////////////////////////////////////////////////////////////
INLINE CPT(TransformState) NodePath::
get_net_prev_transform() const {
get_net_prev_transform(Thread *current_thread) const {
nassertr(_error_type == ET_ok, TransformState::make_identity());
return r_get_net_prev_transform(_head);
return r_get_net_prev_transform(_head, current_thread);
}
////////////////////////////////////////////////////////////////////

View File

@ -77,12 +77,12 @@ TypeHandle NodePath::_type_handle;
// Description: Returns the number of nodes in the path.
////////////////////////////////////////////////////////////////////
int NodePath::
get_num_nodes() const {
get_num_nodes(Thread *current_thread) const {
if (is_empty()) {
return 0;
}
int pipeline_stage = Thread::get_current_pipeline_stage();
return _head->get_length(pipeline_stage);
int pipeline_stage = current_thread->get_pipeline_stage();
return _head->get_length(pipeline_stage, current_thread);
}
////////////////////////////////////////////////////////////////////
@ -99,17 +99,17 @@ get_num_nodes() const {
// NodePath, and is the one most frequently referenced).
////////////////////////////////////////////////////////////////////
PandaNode *NodePath::
get_node(int index) const {
get_node(int index, Thread *current_thread) const {
nassertr(index >= 0 && index < get_num_nodes(), NULL);
int pipeline_stage = Thread::get_current_pipeline_stage();
int pipeline_stage = current_thread->get_pipeline_stage();
NodePathComponent *comp = _head;
while (index > 0) {
// If this assertion fails, the index was out of range; the
// component's length must have been invalid.
nassertr(comp != (NodePathComponent *)NULL, NULL);
comp = comp->get_next(pipeline_stage);
comp = comp->get_next(pipeline_stage, current_thread);
index--;
}
@ -126,16 +126,16 @@ get_node(int index) const {
// of the path, or empty NodePath if this path is empty.
////////////////////////////////////////////////////////////////////
NodePath NodePath::
get_top() const {
get_top(Thread *current_thread) const {
if (is_empty()) {
return *this;
}
int pipeline_stage = Thread::get_current_pipeline_stage();
int pipeline_stage = current_thread->get_pipeline_stage();
NodePathComponent *comp = _head;
while (!comp->is_top_node(pipeline_stage)) {
comp = comp->get_next(pipeline_stage);
while (!comp->is_top_node(pipeline_stage, current_thread)) {
comp = comp->get_next(pipeline_stage, current_thread);
nassertr(comp != (NodePathComponent *)NULL, NULL);
}
@ -152,20 +152,20 @@ get_top() const {
// node.
////////////////////////////////////////////////////////////////////
NodePathCollection NodePath::
get_children() const {
get_children(Thread *current_thread) const {
NodePathCollection result;
nassertr_always(!is_empty(), result);
PandaNode *bottom_node = node();
int pipeline_stage = Thread::get_current_pipeline_stage();
int pipeline_stage = current_thread->get_pipeline_stage();
PandaNode::Children cr = bottom_node->get_children();
int num_children = cr.get_num_children();
for (int i = 0; i < num_children; i++) {
NodePath child;
child._head = PandaNode::get_component(_head, cr.get_child(i),
pipeline_stage);
pipeline_stage, current_thread);
result.add_path(child);
}
@ -181,19 +181,19 @@ get_children() const {
// the list returned by get_children().
////////////////////////////////////////////////////////////////////
NodePathCollection NodePath::
get_stashed_children() const {
get_stashed_children(Thread *current_thread) const {
NodePathCollection result;
nassertr_always(!is_empty(), result);
PandaNode *bottom_node = node();
int pipeline_stage = Thread::get_current_pipeline_stage();
int pipeline_stage = current_thread->get_pipeline_stage();
int num_stashed = bottom_node->get_num_stashed();
for (int i = 0; i < num_stashed; i++) {
NodePath stashed;
stashed._head = PandaNode::get_component(_head, bottom_node->get_stashed(i),
pipeline_stage);
pipeline_stage, current_thread);
result.add_path(stashed);
}
@ -210,14 +210,14 @@ get_stashed_children() const {
// list of children.
////////////////////////////////////////////////////////////////////
int NodePath::
get_sort() const {
get_sort(Thread *current_thread) const {
if (!has_parent()) {
return 0;
}
int pipeline_stage = Thread::get_current_pipeline_stage();
int pipeline_stage = current_thread->get_pipeline_stage();
PandaNode *parent = _head->get_next(pipeline_stage)->get_node();
PandaNode *parent = _head->get_next(pipeline_stage, current_thread)->get_node();
PandaNode *child = node();
nassertr(parent != (PandaNode *)NULL && child != (PandaNode *)NULL, 0);
int child_index = parent->find_child(child);
@ -328,7 +328,7 @@ find_all_paths_to(PandaNode *node) const {
// same thing as detach_node().
////////////////////////////////////////////////////////////////////
void NodePath::
reparent_to(const NodePath &other, int sort) {
reparent_to(const NodePath &other, int sort, Thread *current_thread) {
nassertv(verify_complete());
nassertv(other.verify_complete());
nassertv_always(!is_empty());
@ -337,9 +337,9 @@ reparent_to(const NodePath &other, int sort) {
// Reparenting implicitly resets the delta vector.
node()->reset_prev_transform();
int pipeline_stage = Thread::get_current_pipeline_stage();
int pipeline_stage = current_thread->get_pipeline_stage();
bool reparented = PandaNode::reparent(other._head, _head, sort, false,
pipeline_stage);
pipeline_stage, current_thread);
nassertv(reparented);
}
@ -353,21 +353,21 @@ reparent_to(const NodePath &other, int sort) {
// different coordinate system.
////////////////////////////////////////////////////////////////////
void NodePath::
wrt_reparent_to(const NodePath &other, int sort) {
nassertv(verify_complete());
nassertv(other.verify_complete());
wrt_reparent_to(const NodePath &other, int sort, Thread *current_thread) {
nassertv(verify_complete(current_thread));
nassertv(other.verify_complete(current_thread));
nassertv_always(!is_empty());
nassertv(other._error_type == ET_ok);
if (get_transform() == get_prev_transform()) {
set_transform(get_transform(other));
node()->reset_prev_transform();
if (get_transform(current_thread) == get_prev_transform(current_thread)) {
set_transform(get_transform(other, current_thread), current_thread);
node()->reset_prev_transform(current_thread);
} else {
set_transform(get_transform(other));
set_prev_transform(get_prev_transform(other));
set_transform(get_transform(other, current_thread), current_thread);
set_prev_transform(get_prev_transform(other, current_thread), current_thread);
}
reparent_to(other, sort);
reparent_to(other, sort, current_thread);
}
////////////////////////////////////////////////////////////////////
@ -395,7 +395,7 @@ wrt_reparent_to(const NodePath &other, int sort) {
// return a different get_id() value.
////////////////////////////////////////////////////////////////////
NodePath NodePath::
instance_to(const NodePath &other, int sort) const {
instance_to(const NodePath &other, int sort, Thread *current_thread) const {
nassertr(verify_complete(), NodePath::fail());
nassertr(other.verify_complete(), NodePath::fail());
nassertr_always(!is_empty(), NodePath::fail());
@ -405,12 +405,14 @@ instance_to(const NodePath &other, int sort) const {
// First, we'll attach to NULL, to guarantee we get a brand new
// instance.
int pipeline_stage = Thread::get_current_pipeline_stage();
new_instance._head = PandaNode::attach(NULL, node(), sort, pipeline_stage);
int pipeline_stage = current_thread->get_pipeline_stage();
new_instance._head = PandaNode::attach(NULL, node(), sort, pipeline_stage,
current_thread);
// Now, we'll reparent the new instance to the target node.
bool reparented = PandaNode::reparent(other._head, new_instance._head,
sort, false, pipeline_stage);
sort, false, pipeline_stage,
current_thread);
nassertr(reparented, new_instance);
// instance_to() doesn't reset the velocity delta, unlike most of
@ -431,11 +433,12 @@ instance_to(const NodePath &other, int sort) const {
// this instance.
////////////////////////////////////////////////////////////////////
NodePath NodePath::
instance_under_node(const NodePath &other, const string &name, int sort) const {
NodePath new_node = other.attach_new_node(name, sort);
NodePath instance = instance_to(new_node);
instance_under_node(const NodePath &other, const string &name, int sort,
Thread *current_thread) const {
NodePath new_node = other.attach_new_node(name, sort, current_thread);
NodePath instance = instance_to(new_node, 0, current_thread);
if (instance.is_empty()) {
new_node.remove_node();
new_node.remove_node(current_thread);
return instance;
}
return new_node;
@ -451,19 +454,19 @@ instance_under_node(const NodePath &other, const string &name, int sort) const {
// returned.
////////////////////////////////////////////////////////////////////
NodePath NodePath::
copy_to(const NodePath &other, int sort) const {
nassertr(verify_complete(), fail());
nassertr(other.verify_complete(), fail());
copy_to(const NodePath &other, int sort, Thread *current_thread) const {
nassertr(verify_complete(current_thread), fail());
nassertr(other.verify_complete(current_thread), fail());
nassertr_always(!is_empty(), fail());
nassertr(other._error_type == ET_ok, fail());
PandaNode *source_node = node();
PT(PandaNode) copy_node = source_node->copy_subgraph();
PT(PandaNode) copy_node = source_node->copy_subgraph(current_thread);
nassertr(copy_node != (PandaNode *)NULL, fail());
copy_node->reset_prev_transform();
copy_node->reset_prev_transform(current_thread);
return other.attach_new_node(copy_node, sort);
return other.attach_new_node(copy_node, sort, current_thread);
}
////////////////////////////////////////////////////////////////////
@ -483,14 +486,15 @@ copy_to(const NodePath &other, int sort) const {
// returned.
////////////////////////////////////////////////////////////////////
NodePath NodePath::
attach_new_node(PandaNode *node, int sort) const {
nassertr(verify_complete(), NodePath::fail());
attach_new_node(PandaNode *node, int sort, Thread *current_thread) const {
nassertr(verify_complete(current_thread), NodePath::fail());
nassertr(_error_type == ET_ok, NodePath::fail());
nassertr(node != (PandaNode *)NULL, NodePath::fail());
NodePath new_path(*this);
int pipeline_stage = Thread::get_current_pipeline_stage();
new_path._head = PandaNode::attach(_head, node, sort, pipeline_stage);
int pipeline_stage = current_thread->get_pipeline_stage();
new_path._head = PandaNode::attach(_head, node, sort, pipeline_stage,
current_thread);
return new_path;
}
@ -516,17 +520,17 @@ attach_new_node(PandaNode *node, int sort) const {
// as the NodePath exists.
////////////////////////////////////////////////////////////////////
void NodePath::
remove_node() {
remove_node(Thread *current_thread) {
nassertv(_error_type != ET_not_found);
// If we have no parents, remove_node() is just a do-nothing
// operation; if we have no nodes, maybe we were already removed.
// In either case, quietly do nothing except to ensure the
// NodePath is clear.
if (!is_empty() && !is_singleton()) {
node()->reset_prev_transform();
int pipeline_stage = Thread::get_current_pipeline_stage();
PandaNode::detach(_head, pipeline_stage);
if (!is_empty() && !is_singleton(current_thread)) {
node()->reset_prev_transform(current_thread);
int pipeline_stage = current_thread->get_pipeline_stage();
PandaNode::detach(_head, pipeline_stage, current_thread);
}
if (is_empty() || _head->has_key()) {
@ -563,12 +567,12 @@ remove_node() {
// as the NodePath exists.
////////////////////////////////////////////////////////////////////
void NodePath::
detach_node() {
detach_node(Thread *current_thread) {
nassertv(_error_type != ET_not_found);
if (!is_empty() && !is_singleton()) {
node()->reset_prev_transform();
int pipeline_stage = Thread::get_current_pipeline_stage();
PandaNode::detach(_head, pipeline_stage);
int pipeline_stage = current_thread->get_pipeline_stage();
PandaNode::detach(_head, pipeline_stage, current_thread);
}
}
@ -607,11 +611,11 @@ output(ostream &out) const {
// Description: Returns the complete state object set on this node.
////////////////////////////////////////////////////////////////////
const RenderState *NodePath::
get_state() const {
get_state(Thread *current_thread) const {
// This method is declared non-inline to avoid a compiler bug in
// gcc-3.4 and gcc-4.0.
nassertr_always(!is_empty(), RenderState::make_empty());
return node()->get_state();
return node()->get_state(current_thread);
}
////////////////////////////////////////////////////////////////////
@ -622,21 +626,21 @@ get_state() const {
// render state of the other node.
////////////////////////////////////////////////////////////////////
CPT(RenderState) NodePath::
get_state(const NodePath &other) const {
get_state(const NodePath &other, Thread *current_thread) const {
nassertr(_error_type == ET_ok && other._error_type == ET_ok, RenderState::make_empty());
if (other.is_empty()) {
return get_net_state();
return get_net_state(current_thread);
}
if (is_empty()) {
return other.get_net_state()->invert_compose(RenderState::make_empty());
return other.get_net_state(current_thread)->invert_compose(RenderState::make_empty());
}
nassertr(verify_complete(), RenderState::make_empty());
nassertr(other.verify_complete(), RenderState::make_empty());
nassertr(verify_complete(current_thread), RenderState::make_empty());
nassertr(other.verify_complete(current_thread), RenderState::make_empty());
int a_count, b_count;
if (find_common_ancestor(*this, other, a_count, b_count) == (NodePathComponent *)NULL) {
if (find_common_ancestor(*this, other, a_count, b_count, current_thread) == (NodePathComponent *)NULL) {
if (allow_unrelated_wrt) {
pgraph_cat.debug()
<< *this << " is not related to " << other << "\n";
@ -647,8 +651,8 @@ get_state(const NodePath &other) const {
}
}
CPT(RenderState) a_state = r_get_partial_state(_head, a_count);
CPT(RenderState) b_state = r_get_partial_state(other._head, b_count);
CPT(RenderState) a_state = r_get_partial_state(_head, a_count, current_thread);
CPT(RenderState) b_state = r_get_partial_state(other._head, b_count, current_thread);
return b_state->invert_compose(a_state);
}
@ -661,20 +665,21 @@ get_state(const NodePath &other) const {
// other node.
////////////////////////////////////////////////////////////////////
void NodePath::
set_state(const NodePath &other, const RenderState *state) {
set_state(const NodePath &other, const RenderState *state,
Thread *current_thread) {
nassertv(_error_type == ET_ok && other._error_type == ET_ok);
nassertv_always(!is_empty());
// First, we perform a wrt to the parent, to get the conversion.
CPT(RenderState) rel_state;
if (has_parent()) {
rel_state = other.get_state(get_parent());
rel_state = other.get_state(get_parent(current_thread), current_thread);
} else {
rel_state = other.get_state(NodePath());
rel_state = other.get_state(NodePath(), current_thread);
}
CPT(RenderState) new_state = rel_state->compose(state);
set_state(new_state);
set_state(new_state, current_thread);
}
////////////////////////////////////////////////////////////////////
@ -683,11 +688,11 @@ set_state(const NodePath &other, const RenderState *state) {
// Description: Returns the complete transform object set on this node.
////////////////////////////////////////////////////////////////////
const TransformState *NodePath::
get_transform() const {
get_transform(Thread *current_thread) const {
// This method is declared non-inline to avoid a compiler bug in
// gcc-3.4 and gcc-4.0.
nassertr_always(!is_empty(), TransformState::make_identity());
return node()->get_transform();
return node()->get_transform(current_thread);
}
////////////////////////////////////////////////////////////////////
@ -698,21 +703,21 @@ get_transform() const {
// as seen from the other node.
////////////////////////////////////////////////////////////////////
CPT(TransformState) NodePath::
get_transform(const NodePath &other) const {
get_transform(const NodePath &other, Thread *current_thread) const {
nassertr(_error_type == ET_ok && other._error_type == ET_ok, TransformState::make_identity());
if (other.is_empty()) {
return get_net_transform();
return get_net_transform(current_thread);
}
if (is_empty()) {
return other.get_net_transform()->invert_compose(TransformState::make_identity());
return other.get_net_transform(current_thread)->invert_compose(TransformState::make_identity());
}
nassertr(verify_complete(), TransformState::make_identity());
nassertr(other.verify_complete(), TransformState::make_identity());
nassertr(verify_complete(current_thread), TransformState::make_identity());
nassertr(other.verify_complete(current_thread), TransformState::make_identity());
int a_count, b_count;
if (find_common_ancestor(*this, other, a_count, b_count) == (NodePathComponent *)NULL) {
if (find_common_ancestor(*this, other, a_count, b_count, current_thread) == (NodePathComponent *)NULL) {
if (allow_unrelated_wrt) {
if (pgraph_cat.is_debug()) {
pgraph_cat.debug()
@ -727,16 +732,16 @@ get_transform(const NodePath &other) const {
CPT(TransformState) a_transform, b_transform;
a_transform = r_get_partial_transform(_head, a_count);
a_transform = r_get_partial_transform(_head, a_count, current_thread);
if (a_transform != (TransformState *)NULL) {
b_transform = r_get_partial_transform(other._head, b_count);
b_transform = r_get_partial_transform(other._head, b_count, current_thread);
}
if (b_transform == (TransformState *)NULL) {
// If either path involved a node with a net_transform
// RenderEffect applied, we have to go all the way up to the root
// to get the right answer.
a_transform = r_get_net_transform(_head);
b_transform = r_get_net_transform(other._head);
a_transform = r_get_net_transform(_head, current_thread);
b_transform = r_get_net_transform(other._head, current_thread);
}
return b_transform->invert_compose(a_transform);
}
@ -750,20 +755,21 @@ get_transform(const NodePath &other) const {
// other node.
////////////////////////////////////////////////////////////////////
void NodePath::
set_transform(const NodePath &other, const TransformState *transform) {
set_transform(const NodePath &other, const TransformState *transform,
Thread *current_thread) {
nassertv(_error_type == ET_ok && other._error_type == ET_ok);
nassertv_always(!is_empty());
// First, we perform a wrt to the parent, to get the conversion.
CPT(TransformState) rel_trans;
if (has_parent()) {
rel_trans = other.get_transform(get_parent());
rel_trans = other.get_transform(get_parent(current_thread), current_thread);
} else {
rel_trans = other.get_transform(NodePath());
rel_trans = other.get_transform(NodePath(), current_thread);
}
CPT(TransformState) new_trans = rel_trans->compose(transform);
set_transform(new_trans);
set_transform(new_trans, current_thread);
}
////////////////////////////////////////////////////////////////////
@ -774,11 +780,11 @@ set_transform(const NodePath &other, const TransformState *transform) {
// set_prev_transform().
////////////////////////////////////////////////////////////////////
const TransformState *NodePath::
get_prev_transform() const {
get_prev_transform(Thread *current_thread) const {
// This method is declared non-inline to avoid a compiler bug in
// gcc-3.4 and gcc-4.0.
nassertr_always(!is_empty(), TransformState::make_identity());
return node()->get_prev_transform();
return node()->get_prev_transform(current_thread);
}
////////////////////////////////////////////////////////////////////
@ -790,21 +796,21 @@ get_prev_transform() const {
// in the previous frame.
////////////////////////////////////////////////////////////////////
CPT(TransformState) NodePath::
get_prev_transform(const NodePath &other) const {
get_prev_transform(const NodePath &other, Thread *current_thread) const {
nassertr(_error_type == ET_ok && other._error_type == ET_ok, TransformState::make_identity());
if (other.is_empty()) {
return get_net_prev_transform();
return get_net_prev_transform(current_thread);
}
if (is_empty()) {
return other.get_net_prev_transform()->invert_compose(TransformState::make_identity());
return other.get_net_prev_transform(current_thread)->invert_compose(TransformState::make_identity());
}
nassertr(verify_complete(), TransformState::make_identity());
nassertr(other.verify_complete(), TransformState::make_identity());
nassertr(verify_complete(current_thread), TransformState::make_identity());
nassertr(other.verify_complete(current_thread), TransformState::make_identity());
int a_count, b_count;
if (find_common_ancestor(*this, other, a_count, b_count) == (NodePathComponent *)NULL) {
if (find_common_ancestor(*this, other, a_count, b_count, current_thread) == (NodePathComponent *)NULL) {
if (allow_unrelated_wrt) {
pgraph_cat.debug()
<< *this << " is not related to " << other << "\n";
@ -815,8 +821,8 @@ get_prev_transform(const NodePath &other) const {
}
}
CPT(TransformState) a_prev_transform = r_get_partial_prev_transform(_head, a_count);
CPT(TransformState) b_prev_transform = r_get_partial_prev_transform(other._head, b_count);
CPT(TransformState) a_prev_transform = r_get_partial_prev_transform(_head, a_count, current_thread);
CPT(TransformState) b_prev_transform = r_get_partial_prev_transform(other._head, b_count, current_thread);
return b_prev_transform->invert_compose(a_prev_transform);
}
@ -829,20 +835,21 @@ get_prev_transform(const NodePath &other) const {
// when seen from the other node.
////////////////////////////////////////////////////////////////////
void NodePath::
set_prev_transform(const NodePath &other, const TransformState *transform) {
set_prev_transform(const NodePath &other, const TransformState *transform,
Thread *current_thread) {
nassertv(_error_type == ET_ok && other._error_type == ET_ok);
nassertv_always(!is_empty());
// First, we perform a wrt to the parent, to get the conversion.
CPT(TransformState) rel_trans;
if (has_parent()) {
rel_trans = other.get_prev_transform(get_parent());
if (has_parent(current_thread)) {
rel_trans = other.get_prev_transform(get_parent(current_thread), current_thread);
} else {
rel_trans = other.get_prev_transform(NodePath());
rel_trans = other.get_prev_transform(NodePath(), current_thread);
}
CPT(TransformState) new_trans = rel_trans->compose(transform);
set_prev_transform(new_trans);
set_prev_transform(new_trans, current_thread);
}
////////////////////////////////////////////////////////////////////
@ -5146,13 +5153,13 @@ get_antialias() const {
// is hidden (and the node should be visible).
////////////////////////////////////////////////////////////////////
NodePath NodePath::
get_hidden_ancestor(DrawMask camera_mask) const {
int pipeline_stage = Thread::get_current_pipeline_stage();
get_hidden_ancestor(DrawMask camera_mask, Thread *current_thread) const {
int pipeline_stage = current_thread->get_pipeline_stage();
NodePathComponent *comp;
for (comp = _head;
comp != (NodePathComponent *)NULL;
comp = comp->get_next(pipeline_stage)) {
comp = comp->get_next(pipeline_stage, current_thread)) {
PandaNode *node = comp->get_node();
if (node->is_overall_hidden() ||
((node->get_draw_show_mask() | ~node->get_draw_control_mask()) & camera_mask).is_zero()) {
@ -5181,13 +5188,14 @@ get_hidden_ancestor(DrawMask camera_mask) const {
// retrieve it).
////////////////////////////////////////////////////////////////////
void NodePath::
stash(int sort) {
stash(int sort, Thread *current_thread) {
nassertv_always(!is_singleton() && !is_empty());
nassertv(verify_complete());
int pipeline_stage = Thread::get_current_pipeline_stage();
bool reparented = PandaNode::reparent(_head->get_next(pipeline_stage),
_head, sort, true, pipeline_stage);
int pipeline_stage = current_thread->get_pipeline_stage();
bool reparented = PandaNode::reparent(_head->get_next(pipeline_stage, current_thread),
_head, sort, true, pipeline_stage,
current_thread);
nassertv(reparented);
}
@ -5200,13 +5208,14 @@ stash(int sort) {
// scene graph.
////////////////////////////////////////////////////////////////////
void NodePath::
unstash(int sort) {
unstash(int sort, Thread *current_thread) {
nassertv_always(!is_singleton() && !is_empty());
nassertv(verify_complete());
int pipeline_stage = Thread::get_current_pipeline_stage();
bool reparented = PandaNode::reparent(_head->get_next(pipeline_stage),
_head, sort, false, pipeline_stage);
int pipeline_stage = current_thread->get_pipeline_stage();
bool reparented = PandaNode::reparent(_head->get_next(pipeline_stage, current_thread),
_head, sort, false, pipeline_stage,
current_thread);
nassertv(reparented);
}
@ -5216,10 +5225,10 @@ unstash(int sort) {
// Description: Unstashes this node and all stashed child nodes.
////////////////////////////////////////////////////////////////////
void NodePath::
unstash_all() {
unstash_all(Thread *current_thread) {
NodePathCollection stashed_descendents = find_all_matches("**/@@*");
stashed_descendents.unstash();
unstash();
unstash(0, current_thread);
}
////////////////////////////////////////////////////////////////////
@ -5231,11 +5240,11 @@ unstash_all() {
// be visible).
////////////////////////////////////////////////////////////////////
NodePath NodePath::
get_stashed_ancestor() const {
get_stashed_ancestor(Thread *current_thread) const {
NodePathComponent *comp = _head;
if (comp != (NodePathComponent *)NULL) {
int pipeline_stage = Thread::get_current_pipeline_stage();
NodePathComponent *next = comp->get_next(pipeline_stage);
int pipeline_stage = current_thread->get_pipeline_stage();
NodePathComponent *next = comp->get_next(pipeline_stage, current_thread);
while (next != (NodePathComponent *)NULL) {
PandaNode *node = comp->get_node();
@ -5248,7 +5257,7 @@ get_stashed_ancestor() const {
}
comp = next;
next = next->get_next(pipeline_stage);
next = next->get_next(pipeline_stage, current_thread);
}
}
@ -5262,7 +5271,7 @@ get_stashed_ancestor() const {
// NodePath are connected, or false otherwise.
////////////////////////////////////////////////////////////////////
bool NodePath::
verify_complete() const {
verify_complete(Thread *current_thread) const {
if (is_empty()) {
return true;
}
@ -5270,13 +5279,13 @@ verify_complete() const {
const NodePathComponent *comp = _head;
nassertr(comp != (const NodePathComponent *)NULL, false);
int pipeline_stage = Thread::get_current_pipeline_stage();
int pipeline_stage = current_thread->get_pipeline_stage();
PandaNode *node = comp->get_node();
nassertr(node != (const PandaNode *)NULL, false);
int length = comp->get_length(pipeline_stage);
int length = comp->get_length(pipeline_stage, current_thread);
comp = comp->get_next(pipeline_stage);
comp = comp->get_next(pipeline_stage, current_thread);
length--;
while (comp != (const NodePathComponent *)NULL) {
PandaNode *next_node = comp->get_node();
@ -5289,16 +5298,16 @@ verify_complete() const {
return false;
}
if (comp->get_length(pipeline_stage) != length) {
if (comp->get_length(pipeline_stage, current_thread) != length) {
pgraph_cat.warning()
<< *this << " is incomplete; length at " << *next_node
<< " indicates " << comp->get_length(pipeline_stage)
<< " indicates " << comp->get_length(pipeline_stage, current_thread)
<< " while length at " << *node << " indicates " << length << "\n";
return false;
}
node = next_node;
comp = comp->get_next(pipeline_stage);
comp = comp->get_next(pipeline_stage, current_thread);
length--;
}
@ -5434,14 +5443,16 @@ write_bounds(ostream &out) const {
// bounding volume, or false if none are.
////////////////////////////////////////////////////////////////////
bool NodePath::
calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point) {
calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point,
Thread *current_thread) {
min_point.set(0.0f, 0.0f, 0.0f);
max_point.set(0.0f, 0.0f, 0.0f);
nassertr_always(!is_empty(), false);
bool found_any = false;
node()->calc_tight_bounds(min_point, max_point, found_any,
TransformState::make_identity());
TransformState::make_identity(),
current_thread);
return found_any;
}
@ -5641,24 +5652,24 @@ write_bam_file(const string &filename) const {
////////////////////////////////////////////////////////////////////
NodePathComponent *NodePath::
find_common_ancestor(const NodePath &a, const NodePath &b,
int &a_count, int &b_count) {
int &a_count, int &b_count, Thread *current_thread) {
nassertr(!a.is_empty() && !b.is_empty(), NULL);
NodePathComponent *ac = a._head;
NodePathComponent *bc = b._head;
a_count = 0;
b_count = 0;
int pipeline_stage = Thread::get_current_pipeline_stage();
int pipeline_stage = current_thread->get_pipeline_stage();
// Shorten up the longer one until they are the same length.
while (ac->get_length(pipeline_stage) > bc->get_length(pipeline_stage)) {
while (ac->get_length(pipeline_stage, current_thread) > bc->get_length(pipeline_stage, current_thread)) {
nassertr(ac != (NodePathComponent *)NULL, NULL);
ac = ac->get_next(pipeline_stage);
ac = ac->get_next(pipeline_stage, current_thread);
a_count++;
}
while (bc->get_length(pipeline_stage) > ac->get_length(pipeline_stage)) {
while (bc->get_length(pipeline_stage, current_thread) > ac->get_length(pipeline_stage, current_thread)) {
nassertr(bc != (NodePathComponent *)NULL, NULL);
bc = bc->get_next(pipeline_stage);
bc = bc->get_next(pipeline_stage, current_thread);
b_count++;
}
@ -5667,9 +5678,9 @@ find_common_ancestor(const NodePath &a, const NodePath &b,
// These shouldn't go to NULL unless they both go there together.
nassertr(ac != (NodePathComponent *)NULL, NULL);
nassertr(bc != (NodePathComponent *)NULL, NULL);
ac = ac->get_next(pipeline_stage);
ac = ac->get_next(pipeline_stage, current_thread);
a_count++;
bc = bc->get_next(pipeline_stage);
bc = bc->get_next(pipeline_stage, current_thread);
b_count++;
}
@ -5683,13 +5694,13 @@ find_common_ancestor(const NodePath &a, const NodePath &b,
// indicated component node from the root of the graph.
////////////////////////////////////////////////////////////////////
CPT(RenderState) NodePath::
r_get_net_state(NodePathComponent *comp) const {
r_get_net_state(NodePathComponent *comp, Thread *current_thread) const {
if (comp == (NodePathComponent *)NULL) {
return RenderState::make_empty();
} else {
CPT(RenderState) state = comp->get_node()->get_state();
int pipeline_stage = Thread::get_current_pipeline_stage();
return r_get_net_state(comp->get_next(pipeline_stage))->compose(state);
int pipeline_stage = current_thread->get_pipeline_stage();
return r_get_net_state(comp->get_next(pipeline_stage, current_thread), current_thread)->compose(state);
}
}
@ -5702,13 +5713,14 @@ r_get_net_state(NodePathComponent *comp) const {
// net transform from the root of the graph.
////////////////////////////////////////////////////////////////////
CPT(RenderState) NodePath::
r_get_partial_state(NodePathComponent *comp, int n) const {
r_get_partial_state(NodePathComponent *comp, int n,
Thread *current_thread) const {
if (n == 0 || comp == (NodePathComponent *)NULL) {
return RenderState::make_empty();
} else {
CPT(RenderState) state = comp->get_node()->get_state();
int pipeline_stage = Thread::get_current_pipeline_stage();
return r_get_partial_state(comp->get_next(pipeline_stage), n - 1)->compose(state);
int pipeline_stage = current_thread->get_pipeline_stage();
return r_get_partial_state(comp->get_next(pipeline_stage, current_thread), n - 1, current_thread)->compose(state);
}
}
@ -5719,12 +5731,12 @@ r_get_partial_state(NodePathComponent *comp, int n) const {
// indicated component node from the root of the graph.
////////////////////////////////////////////////////////////////////
CPT(TransformState) NodePath::
r_get_net_transform(NodePathComponent *comp) const {
r_get_net_transform(NodePathComponent *comp, Thread *current_thread) const {
if (comp == (NodePathComponent *)NULL) {
return TransformState::make_identity();
} else {
int pipeline_stage = Thread::get_current_pipeline_stage();
CPT(TransformState) net_transform = r_get_net_transform(comp->get_next(pipeline_stage));
int pipeline_stage = current_thread->get_pipeline_stage();
CPT(TransformState) net_transform = r_get_net_transform(comp->get_next(pipeline_stage, current_thread), current_thread);
CPT(TransformState) transform = comp->get_node()->get_transform();
CPT(RenderEffects) effects = comp->get_node()->get_effects();
@ -5749,7 +5761,8 @@ r_get_net_transform(NodePathComponent *comp) const {
// transform cannot be easily determined.
////////////////////////////////////////////////////////////////////
CPT(TransformState) NodePath::
r_get_partial_transform(NodePathComponent *comp, int n) const {
r_get_partial_transform(NodePathComponent *comp, int n,
Thread *current_thread) const {
if (n == 0 || comp == (NodePathComponent *)NULL) {
return TransformState::make_identity();
} else {
@ -5757,8 +5770,8 @@ r_get_partial_transform(NodePathComponent *comp, int n) const {
return NULL;
}
CPT(TransformState) transform = comp->get_node()->get_transform();
int pipeline_stage = Thread::get_current_pipeline_stage();
CPT(TransformState) partial = r_get_partial_transform(comp->get_next(pipeline_stage), n - 1);
int pipeline_stage = current_thread->get_pipeline_stage();
CPT(TransformState) partial = r_get_partial_transform(comp->get_next(pipeline_stage, current_thread), n - 1, current_thread);
if (partial == (const TransformState *)NULL) {
return NULL;
}
@ -5774,13 +5787,13 @@ r_get_partial_transform(NodePathComponent *comp, int n) const {
// graph.
////////////////////////////////////////////////////////////////////
CPT(TransformState) NodePath::
r_get_net_prev_transform(NodePathComponent *comp) const {
r_get_net_prev_transform(NodePathComponent *comp, Thread *current_thread) const {
if (comp == (NodePathComponent *)NULL) {
return TransformState::make_identity();
} else {
CPT(TransformState) transform = comp->get_node()->get_prev_transform();
int pipeline_stage = Thread::get_current_pipeline_stage();
return r_get_net_prev_transform(comp->get_next(pipeline_stage))->compose(transform);
int pipeline_stage = current_thread->get_pipeline_stage();
return r_get_net_prev_transform(comp->get_next(pipeline_stage, current_thread), current_thread)->compose(transform);
}
}
@ -5794,13 +5807,13 @@ r_get_net_prev_transform(NodePathComponent *comp) const {
// the graph.
////////////////////////////////////////////////////////////////////
CPT(TransformState) NodePath::
r_get_partial_prev_transform(NodePathComponent *comp, int n) const {
r_get_partial_prev_transform(NodePathComponent *comp, int n, Thread *current_thread) const {
if (n == 0 || comp == (NodePathComponent *)NULL) {
return TransformState::make_identity();
} else {
CPT(TransformState) transform = comp->get_node()->get_prev_transform();
int pipeline_stage = Thread::get_current_pipeline_stage();
return r_get_partial_prev_transform(comp->get_next(pipeline_stage), n - 1)->compose(transform);
int pipeline_stage = current_thread->get_pipeline_stage();
return r_get_partial_prev_transform(comp->get_next(pipeline_stage, current_thread), n - 1, current_thread)->compose(transform);
}
}

View File

@ -163,10 +163,11 @@ PUBLISHED:
};
INLINE NodePath();
INLINE NodePath(const string &top_node_name);
INLINE NodePath(PandaNode *node);
INLINE static NodePath any_path(PandaNode *node);
INLINE NodePath(const NodePath &parent, PandaNode *child_node);
INLINE NodePath(const string &top_node_name, Thread *current_thread = Thread::get_current_thread());
INLINE NodePath(PandaNode *node, Thread *current_thread = Thread::get_current_thread());
INLINE static NodePath any_path(PandaNode *node, Thread *current_thread = Thread::get_current_thread());
INLINE NodePath(const NodePath &parent, PandaNode *child_node,
Thread *current_thread = Thread::get_current_thread());
INLINE NodePath(const NodePath &copy);
INLINE void operator = (const NodePath &copy);
@ -180,34 +181,34 @@ PUBLISHED:
// Methods to query a NodePath's contents.
INLINE bool is_empty() const;
INLINE bool is_singleton() const;
int get_num_nodes() const;
PandaNode *get_node(int index) const;
INLINE bool is_singleton(Thread *current_thread = Thread::get_current_thread()) const;
int get_num_nodes(Thread *current_thread = Thread::get_current_thread()) const;
PandaNode *get_node(int index, Thread *current_thread = Thread::get_current_thread()) const;
INLINE ErrorType get_error_type() const;
PandaNode *get_top_node() const;
NodePath get_top() const;
INLINE PandaNode *get_top_node(Thread *current_thread = Thread::get_current_thread()) const;
NodePath get_top(Thread *current_thread = Thread::get_current_thread()) const;
INLINE PandaNode *node() const;
INLINE int get_key() const;
INLINE bool is_same_graph(const NodePath &other) const;
INLINE bool is_ancestor_of(const NodePath &other) const;
INLINE NodePath get_common_ancestor(const NodePath &other) const;
INLINE bool is_same_graph(const NodePath &other, Thread *current_thread = Thread::get_current_thread()) const;
INLINE bool is_ancestor_of(const NodePath &other, Thread *current_thread = Thread::get_current_thread()) const;
INLINE NodePath get_common_ancestor(const NodePath &other, Thread *current_thread = Thread::get_current_thread()) const;
// Methods that return collections of NodePaths derived from or
// related to this one.
NodePathCollection get_children() const;
INLINE int get_num_children() const;
INLINE NodePath get_child(int n) const;
NodePathCollection get_stashed_children() const;
NodePathCollection get_children(Thread *current_thread = Thread::get_current_thread()) const;
INLINE int get_num_children(Thread *current_thread = Thread::get_current_thread()) const;
INLINE NodePath get_child(int n, Thread *current_thread = Thread::get_current_thread()) const;
NodePathCollection get_stashed_children(Thread *current_thread = Thread::get_current_thread()) const;
INLINE bool has_parent() const;
INLINE NodePath get_parent() const;
int get_sort() const;
INLINE bool has_parent(Thread *current_thread = Thread::get_current_thread()) const;
INLINE NodePath get_parent(Thread *current_thread = Thread::get_current_thread()) const;
int get_sort(Thread *current_thread = Thread::get_current_thread()) const;
NodePath find(const string &path) const;
NodePath find_path_to(PandaNode *node) const;
@ -219,16 +220,23 @@ PUBLISHED:
// ordering between sibling nodes, useful when dealing with LOD's
// and similar switch nodes. If the sort value is the same, nodes
// will be arranged in the order they were added.
void reparent_to(const NodePath &other, int sort = 0);
void wrt_reparent_to(const NodePath &other, int sort = 0);
NodePath instance_to(const NodePath &other, int sort = 0) const;
void reparent_to(const NodePath &other, int sort = 0,
Thread *current_thread = Thread::get_current_thread());
void wrt_reparent_to(const NodePath &other, int sort = 0,
Thread *current_thread = Thread::get_current_thread());
NodePath instance_to(const NodePath &other, int sort = 0,
Thread *current_thread = Thread::get_current_thread()) const;
NodePath instance_under_node(const NodePath &other, const string &name,
int sort = 0) const;
NodePath copy_to(const NodePath &other, int sort = 0) const;
NodePath attach_new_node(PandaNode *node, int sort = 0) const;
INLINE NodePath attach_new_node(const string &name, int sort = 0) const;
void remove_node();
void detach_node();
int sort = 0,
Thread *current_thread = Thread::get_current_thread()) const;
NodePath copy_to(const NodePath &other, int sort = 0,
Thread *current_thread = Thread::get_current_thread()) const;
NodePath attach_new_node(PandaNode *node, int sort = 0,
Thread *current_thread = Thread::get_current_thread()) const;
INLINE NodePath attach_new_node(const string &name, int sort = 0,
Thread *current_thread = Thread::get_current_thread()) const;
void remove_node(Thread *current_thread = Thread::get_current_thread());
void detach_node(Thread *current_thread = Thread::get_current_thread());
// Handy ways to look at what's there, and other miscellaneous
// operations.
@ -242,11 +250,11 @@ PUBLISHED:
// Aggregate transform and state information.
const RenderState *get_state() const;
INLINE void set_state(const RenderState *state);
CPT(RenderState) get_state(const NodePath &other) const;
void set_state(const NodePath &other, const RenderState *state);
INLINE CPT(RenderState) get_net_state() const;
const RenderState *get_state(Thread *current_thread = Thread::get_current_thread()) const;
INLINE void set_state(const RenderState *state, Thread *current_thread = Thread::get_current_thread());
CPT(RenderState) get_state(const NodePath &other, Thread *current_thread = Thread::get_current_thread()) const;
void set_state(const NodePath &other, const RenderState *state, Thread *current_thread = Thread::get_current_thread());
INLINE CPT(RenderState) get_net_state(Thread *current_thread = Thread::get_current_thread()) const;
INLINE void set_attrib(const RenderAttrib *attrib, int priority = 0);
INLINE const RenderAttrib *get_attrib(TypeHandle type) const;
@ -262,19 +270,19 @@ PUBLISHED:
INLINE const RenderEffects *get_effects() const;
INLINE void clear_effects();
const TransformState *get_transform() const;
INLINE void clear_transform();
INLINE void set_transform(const TransformState *transform);
CPT(TransformState) get_transform(const NodePath &other) const;
INLINE void clear_transform(const NodePath &other);
void set_transform(const NodePath &other, const TransformState *transform);
INLINE CPT(TransformState) get_net_transform() const;
const TransformState *get_transform(Thread *current_thread = Thread::get_current_thread()) const;
INLINE void clear_transform(Thread *current_thread = Thread::get_current_thread());
INLINE void set_transform(const TransformState *transform, Thread *current_thread = Thread::get_current_thread());
CPT(TransformState) get_transform(const NodePath &other, Thread *current_thread = Thread::get_current_thread()) const;
INLINE void clear_transform(const NodePath &other, Thread *current_thread = Thread::get_current_thread());
void set_transform(const NodePath &other, const TransformState *transform, Thread *current_thread = Thread::get_current_thread());
INLINE CPT(TransformState) get_net_transform(Thread *current_thread = Thread::get_current_thread()) const;
const TransformState *get_prev_transform() const;
INLINE void set_prev_transform(const TransformState *transform);
CPT(TransformState) get_prev_transform(const NodePath &other) const;
void set_prev_transform(const NodePath &other, const TransformState *transform);
INLINE CPT(TransformState) get_net_prev_transform() const;
const TransformState *get_prev_transform(Thread *current_thread = Thread::get_current_thread()) const;
INLINE void set_prev_transform(const TransformState *transform, Thread *current_thread = Thread::get_current_thread());
CPT(TransformState) get_prev_transform(const NodePath &other, Thread *current_thread = Thread::get_current_thread()) const;
void set_prev_transform(const NodePath &other, const TransformState *transform, Thread *current_thread = Thread::get_current_thread());
INLINE CPT(TransformState) get_net_prev_transform(Thread *current_thread = Thread::get_current_thread()) const;
// Methods that get and set the matrix transform: pos, hpr, scale,
@ -743,13 +751,14 @@ PUBLISHED:
INLINE void hide();
INLINE void hide(DrawMask camera_mask);
INLINE bool is_hidden(DrawMask camera_mask = PandaNode::get_overall_bit()) const;
NodePath get_hidden_ancestor(DrawMask camera_mask = PandaNode::get_overall_bit()) const;
NodePath get_hidden_ancestor(DrawMask camera_mask = PandaNode::get_overall_bit(),
Thread *current_thread = Thread::get_current_thread()) const;
void stash(int sort = 0);
void unstash(int sort = 0);
void unstash_all();
void stash(int sort = 0, Thread *current_thread = Thread::get_current_thread());
void unstash(int sort = 0, Thread *current_thread = Thread::get_current_thread());
void unstash_all(Thread *current_thread = Thread::get_current_thread());
INLINE bool is_stashed() const;
NodePath get_stashed_ancestor() const;
NodePath get_stashed_ancestor(Thread *current_thread = Thread::get_current_thread()) const;
INLINE CollideMask get_collide_mask() const;
INLINE void set_collide_mask(CollideMask new_mask, CollideMask bits_to_change = CollideMask::all_on(),
@ -762,7 +771,7 @@ PUBLISHED:
INLINE int compare_to(const NodePath &other) const;
// Miscellaneous
bool verify_complete() const;
bool verify_complete(Thread *current_thread = Thread::get_current_thread()) const;
void prepare_scene(GraphicsStateGuardianBase *gsg);
@ -772,7 +781,8 @@ PUBLISHED:
PT(BoundingVolume) get_bounds() const;
void force_recompute_bounds();
void write_bounds(ostream &out) const;
bool calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point);
bool calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point,
Thread *current_thread = Thread::get_current_thread());
void analyze() const;
@ -808,14 +818,21 @@ PUBLISHED:
private:
static NodePathComponent *
find_common_ancestor(const NodePath &a, const NodePath &b,
int &a_count, int &b_count);
int &a_count, int &b_count,
Thread *current_thread);
CPT(RenderState) r_get_net_state(NodePathComponent *comp) const;
CPT(RenderState) r_get_partial_state(NodePathComponent *comp, int n) const;
CPT(TransformState) r_get_net_transform(NodePathComponent *comp) const;
CPT(TransformState) r_get_partial_transform(NodePathComponent *comp, int n) const;
CPT(TransformState) r_get_net_prev_transform(NodePathComponent *comp) const;
CPT(TransformState) r_get_partial_prev_transform(NodePathComponent *comp, int n) const;
CPT(RenderState) r_get_net_state(NodePathComponent *comp,
Thread *current_thread) const;
CPT(RenderState) r_get_partial_state(NodePathComponent *comp, int n,
Thread *current_thread) const;
CPT(TransformState) r_get_net_transform(NodePathComponent *comp,
Thread *current_thread) const;
CPT(TransformState) r_get_partial_transform(NodePathComponent *comp, int n,
Thread *current_thread) const;
CPT(TransformState) r_get_net_prev_transform(NodePathComponent *comp,
Thread *current_thread) const;
CPT(TransformState) r_get_partial_prev_transform(NodePathComponent *comp,
int n, Thread *current_thread) const;
void find_matches(NodePathCollection &result,
const string &approx_path_str,

View File

@ -45,7 +45,7 @@ make_copy() const {
////////////////////////////////////////////////////////////////////
NodePathComponent::
NodePathComponent(PandaNode *node, NodePathComponent *next,
int pipeline_stage) :
int pipeline_stage, Thread *current_thread) :
_node(node),
_key(0)
{
@ -56,11 +56,11 @@ NodePathComponent(PandaNode *node, NodePathComponent *next,
for (int pipeline_stage_i = pipeline_stage;
pipeline_stage_i >= 0;
--pipeline_stage_i) {
CDStageWriter cdata(_cycler, pipeline_stage_i);
CDStageWriter cdata(_cycler, pipeline_stage_i, current_thread);
cdata->_next = next;
if (next != (NodePathComponent *)NULL) {
cdata->_length = next->get_length(pipeline_stage_i) + 1;
cdata->_length = next->get_length(pipeline_stage_i, current_thread) + 1;
}
}
}
@ -94,8 +94,8 @@ get_key() const {
// node in the path.
////////////////////////////////////////////////////////////////////
bool NodePathComponent::
is_top_node(int pipeline_stage) const {
CDStageReader cdata(_cycler, pipeline_stage);
is_top_node(int pipeline_stage, Thread *current_thread) const {
CDStageReader cdata(_cycler, pipeline_stage, current_thread);
return (cdata->_next == (NodePathComponent *)NULL);
}
@ -105,8 +105,8 @@ is_top_node(int pipeline_stage) const {
// Description: Returns the length of the path to this node.
////////////////////////////////////////////////////////////////////
int NodePathComponent::
get_length(int pipeline_stage) const {
CDStageReader cdata(_cycler, pipeline_stage);
get_length(int pipeline_stage, Thread *current_thread) const {
CDStageReader cdata(_cycler, pipeline_stage, current_thread);
return cdata->_length;
}
@ -116,8 +116,8 @@ get_length(int pipeline_stage) const {
// Description: Returns the next component in the path.
////////////////////////////////////////////////////////////////////
NodePathComponent *NodePathComponent::
get_next(int pipeline_stage) const {
CDStageReader cdata(_cycler, pipeline_stage);
get_next(int pipeline_stage, Thread *current_thread) const {
CDStageReader cdata(_cycler, pipeline_stage, current_thread);
NodePathComponent *next = cdata->_next;
return next;
@ -132,12 +132,12 @@ get_next(int pipeline_stage) const {
// component has been changed; otherwise, returns false.
////////////////////////////////////////////////////////////////////
bool NodePathComponent::
fix_length(int pipeline_stage) {
CDStageReader cdata(_cycler, pipeline_stage);
fix_length(int pipeline_stage, Thread *current_thread) {
CDStageReader cdata(_cycler, pipeline_stage, current_thread);
int length_should_be = 1;
if (cdata->_next != (NodePathComponent *)NULL) {
length_should_be = cdata->_next->get_length(pipeline_stage) + 1;
length_should_be = cdata->_next->get_length(pipeline_stage, current_thread) + 1;
}
if (cdata->_length == length_should_be) {
@ -159,10 +159,11 @@ fix_length(int pipeline_stage) {
////////////////////////////////////////////////////////////////////
void NodePathComponent::
output(ostream &out) const {
int pipeline_stage = Thread::get_current_pipeline_stage();
Thread *current_thread = Thread::get_current_thread();
int pipeline_stage = current_thread->get_pipeline_stage();
PandaNode *node = get_node();
NodePathComponent *next = get_next(pipeline_stage);
NodePathComponent *next = get_next(pipeline_stage, current_thread);
if (next != (NodePathComponent *)NULL) {
// This is not the head of the list; keep going up.
next->output(out);
@ -194,9 +195,9 @@ output(ostream &out) const {
// Description: Sets the next pointer in the path.
////////////////////////////////////////////////////////////////////
void NodePathComponent::
set_next(NodePathComponent *next, int pipeline_stage) {
set_next(NodePathComponent *next, int pipeline_stage, Thread *current_thread) {
nassertv(next != (NodePathComponent *)NULL);
CDStageWriter cdata(_cycler, pipeline_stage);
CDStageWriter cdata(_cycler, pipeline_stage, current_thread);
cdata->_next = next;
}
@ -207,7 +208,7 @@ set_next(NodePathComponent *next, int pipeline_stage) {
// path and makes this component a top node.
////////////////////////////////////////////////////////////////////
void NodePathComponent::
set_top_node(int pipeline_stage) {
CDStageWriter cdata(_cycler, pipeline_stage);
set_top_node(int pipeline_stage, Thread *current_thread) {
CDStageWriter cdata(_cycler, pipeline_stage, current_thread);
cdata->_next = (NodePathComponent *)NULL;
}

View File

@ -51,7 +51,7 @@
class EXPCL_PANDA NodePathComponent : public ReferenceCount {
private:
NodePathComponent(PandaNode *node, NodePathComponent *next,
int pipeline_stage);
int pipeline_stage, Thread *current_thread);
INLINE NodePathComponent(const NodePathComponent &copy);
INLINE void operator = (const NodePathComponent &copy);
@ -62,18 +62,18 @@ public:
INLINE PandaNode *get_node() const;
INLINE bool has_key() const;
int get_key() const;
bool is_top_node(int pipeline_stage) const;
bool is_top_node(int pipeline_stage, Thread *current_thread) const;
NodePathComponent *get_next(int pipeline_stage) const;
int get_length(int pipeline_stage) const;
NodePathComponent *get_next(int pipeline_stage, Thread *current_thread) const;
int get_length(int pipeline_stage, Thread *current_thread) const;
bool fix_length(int pipeline_stage);
bool fix_length(int pipeline_stage, Thread *current_thread);
void output(ostream &out) const;
private:
void set_next(NodePathComponent *next, int pipeline_stage);
void set_top_node(int pipeline_stage);
void set_next(NodePathComponent *next, int pipeline_stage, Thread *current_thread);
void set_top_node(int pipeline_stage, Thread *current_thread);
// We don't have to cycle the _node and _key elements, since these
// are permanent properties of this object. (Well, the _key is

View File

@ -40,15 +40,15 @@ compose_draw_mask(DrawMask &running_draw_mask) const {
// be visible to the indicated camera_mask.
////////////////////////////////////////////////////////////////////
INLINE bool PandaNode::
compare_draw_mask(DrawMask running_draw_mask, DrawMask camera_mask) const {
compare_draw_mask(DrawMask running_draw_mask, DrawMask camera_mask,
Thread *current_thread) const {
DrawMask net_draw_control_mask, net_draw_show_mask;
int pipeline_stage = Thread::get_current_pipeline_stage();
CDBoundsStageReader cdata(_cycler_bounds, pipeline_stage);
int pipeline_stage = current_thread->get_pipeline_stage();
CDBoundsStageReader cdata(_cycler_bounds, pipeline_stage, current_thread);
if (cdata->_last_update != cdata->_next_update) {
// The cache is stale; it needs to be rebuilt.
CDBoundsStageWriter cdataw =
((PandaNode *)this)->update_bounds(pipeline_stage, cdata);
CDBoundsStageWriter cdataw = ((PandaNode *)this)->update_bounds(pipeline_stage, cdata);
net_draw_control_mask = cdataw->_net_draw_control_mask;
net_draw_show_mask = cdataw->_net_draw_show_mask;
} else {
@ -84,8 +84,8 @@ compare_draw_mask(DrawMask running_draw_mask, DrawMask camera_mask) const {
// which the node was instanced to them.
////////////////////////////////////////////////////////////////////
INLINE int PandaNode::
get_num_parents() const {
CDLinksReader cdata(_cycler_links);
get_num_parents(Thread *current_thread) const {
CDLinksReader cdata(_cycler_links, current_thread);
return cdata->get_up()->size();
}
@ -98,8 +98,8 @@ get_num_parents() const {
// parents; get_parents() is preferable in this case.
////////////////////////////////////////////////////////////////////
INLINE PandaNode *PandaNode::
get_parent(int n) const {
CDLinksReader cdata(_cycler_links);
get_parent(int n, Thread *current_thread) const {
CDLinksReader cdata(_cycler_links, current_thread);
const Up &up = *cdata->get_up();
nassertr(n >= 0 && n < (int)up.size(), NULL);
return up[n].get_parent();
@ -112,8 +112,8 @@ get_parent(int n) const {
// is a parent, or -1 if it is not.
////////////////////////////////////////////////////////////////////
INLINE int PandaNode::
find_parent(PandaNode *node) const {
CDLinksReader cdata(_cycler_links);
find_parent(PandaNode *node, Thread *current_thread) const {
CDLinksReader cdata(_cycler_links, current_thread);
return do_find_parent(node, cdata);
}
@ -126,8 +126,8 @@ find_parent(PandaNode *node) const {
// and also on the order in which the nodes were added.
////////////////////////////////////////////////////////////////////
INLINE int PandaNode::
get_num_children() const {
CDLinksReader cdata(_cycler_links);
get_num_children(Thread *current_thread) const {
CDLinksReader cdata(_cycler_links, current_thread);
return cdata->get_down()->size();
}
@ -140,8 +140,8 @@ get_num_children() const {
// children; get_children() is preferable in this case.
////////////////////////////////////////////////////////////////////
INLINE PandaNode *PandaNode::
get_child(int n) const {
CDLinksReader cdata(_cycler_links);
get_child(int n, Thread *current_thread) const {
CDLinksReader cdata(_cycler_links, current_thread);
const Down &down = *cdata->get_down();
nassertr(n >= 0 && n < (int)down.size(), NULL);
return down[n].get_child();
@ -155,8 +155,8 @@ get_child(int n) const {
// add_child()). See get_num_children().
////////////////////////////////////////////////////////////////////
INLINE int PandaNode::
get_child_sort(int n) const {
CDLinksReader cdata(_cycler_links);
get_child_sort(int n, Thread *current_thread) const {
CDLinksReader cdata(_cycler_links, current_thread);
const Down &down = *cdata->get_down();
nassertr(n >= 0 && n < (int)down.size(), -1);
return down[n].get_sort();
@ -169,8 +169,8 @@ get_child_sort(int n) const {
// is a child, or -1 if it is not.
////////////////////////////////////////////////////////////////////
INLINE int PandaNode::
find_child(PandaNode *node) const {
CDLinksReader cdata(_cycler_links);
find_child(PandaNode *node, Thread *current_thread) const {
CDLinksReader cdata(_cycler_links, current_thread);
return do_find_child(node, cdata);
}
@ -191,12 +191,12 @@ find_child(PandaNode *node) const {
// previously stashed).
////////////////////////////////////////////////////////////////////
INLINE bool PandaNode::
stash_child(PandaNode *child_node) {
int child_index = find_child(child_node);
stash_child(PandaNode *child_node, Thread *current_thread) {
int child_index = find_child(child_node, current_thread);
if (child_index < 0) {
return false;
}
stash_child(child_index);
stash_child(child_index, current_thread);
return true;
}
@ -217,12 +217,12 @@ stash_child(PandaNode *child_node) {
// previously stashed).
////////////////////////////////////////////////////////////////////
INLINE bool PandaNode::
unstash_child(PandaNode *child_node) {
int stashed_index = find_stashed(child_node);
unstash_child(PandaNode *child_node, Thread *current_thread) {
int stashed_index = find_stashed(child_node, current_thread);
if (stashed_index < 0) {
return false;
}
unstash_child(stashed_index);
unstash_child(stashed_index, current_thread);
return true;
}
@ -234,8 +234,8 @@ unstash_child(PandaNode *child_node) {
// moved to the special stashed list via stash_child().
////////////////////////////////////////////////////////////////////
INLINE int PandaNode::
get_num_stashed() const {
CDLinksReader cdata(_cycler_links);
get_num_stashed(Thread *current_thread) const {
CDLinksReader cdata(_cycler_links, current_thread);
return cdata->get_stashed()->size();
}
@ -249,8 +249,8 @@ get_num_stashed() const {
// case.
////////////////////////////////////////////////////////////////////
INLINE PandaNode *PandaNode::
get_stashed(int n) const {
CDLinksReader cdata(_cycler_links);
get_stashed(int n, Thread *current_thread) const {
CDLinksReader cdata(_cycler_links, current_thread);
const Down &stashed = *cdata->get_stashed();
nassertr(n >= 0 && n < (int)stashed.size(), NULL);
return stashed[n].get_child();
@ -264,8 +264,8 @@ get_stashed(int n) const {
// add_child()). See get_num_stashed().
////////////////////////////////////////////////////////////////////
INLINE int PandaNode::
get_stashed_sort(int n) const {
CDLinksReader cdata(_cycler_links);
get_stashed_sort(int n, Thread *current_thread) const {
CDLinksReader cdata(_cycler_links, current_thread);
const Down &stashed = *cdata->get_stashed();
nassertr(n >= 0 && n < (int)stashed.size(), -1);
return stashed[n].get_sort();
@ -278,8 +278,8 @@ get_stashed_sort(int n) const {
// it is a stashed child, or -1 if it is not.
////////////////////////////////////////////////////////////////////
INLINE int PandaNode::
find_stashed(PandaNode *node) const {
CDLinksReader cdata(_cycler_links);
find_stashed(PandaNode *node, Thread *current_thread) const {
CDLinksReader cdata(_cycler_links, current_thread);
return do_find_stashed(node, cdata);
}
@ -356,8 +356,8 @@ has_effect(TypeHandle type) const {
// that might be inherited from above.
////////////////////////////////////////////////////////////////////
INLINE const RenderState *PandaNode::
get_state() const {
CDLightReader cdata(_cycler_light);
get_state(Thread *current_thread) const {
CDLightReader cdata(_cycler_light, current_thread);
return cdata->_state;
}
@ -370,8 +370,8 @@ get_state() const {
// this level.
////////////////////////////////////////////////////////////////////
INLINE void PandaNode::
clear_state() {
set_state(RenderState::make_empty());
clear_state(Thread *current_thread) {
set_state(RenderState::make_empty(), current_thread);
}
////////////////////////////////////////////////////////////////////
@ -405,8 +405,8 @@ clear_effects() {
// node.
////////////////////////////////////////////////////////////////////
INLINE const TransformState *PandaNode::
get_transform() const {
CDLightReader cdata(_cycler_light);
get_transform(Thread *current_thread) const {
CDLightReader cdata(_cycler_light, current_thread);
return cdata->_transform;
}
@ -417,8 +417,8 @@ get_transform() const {
// transform.
////////////////////////////////////////////////////////////////////
INLINE void PandaNode::
clear_transform() {
set_transform(TransformState::make_identity());
clear_transform(Thread *current_thread) {
set_transform(TransformState::make_identity(), current_thread);
}
////////////////////////////////////////////////////////////////////
@ -429,8 +429,8 @@ clear_transform() {
// set_prev_transform().
////////////////////////////////////////////////////////////////////
const TransformState *PandaNode::
get_prev_transform() const {
CDLightReader cdata(_cycler_light);
get_prev_transform(Thread *current_thread) const {
CDLightReader cdata(_cycler_light, current_thread);
return cdata->_prev_transform;
}
@ -620,8 +620,9 @@ clear_bounds() {
////////////////////////////////////////////////////////////////////
INLINE CPT(BoundingVolume) PandaNode::
get_internal_bounds() const {
int pipeline_stage = Thread::get_current_pipeline_stage();
return get_internal_bounds(pipeline_stage);
Thread *current_thread = Thread::get_current_thread();
return get_internal_bounds(current_thread->get_pipeline_stage(),
current_thread);
}
////////////////////////////////////////////////////////////////////
@ -670,8 +671,8 @@ is_final() const {
// never been set.
////////////////////////////////////////////////////////////////////
INLINE CPT(BoundingVolume) PandaNode::
get_user_bounds(int pipeline_stage) const {
CDHeavyStageReader cdata(_cycler_heavy, pipeline_stage);
get_user_bounds(int pipeline_stage, Thread *current_thread) const {
CDHeavyStageReader cdata(_cycler_heavy, pipeline_stage, current_thread);
return cdata->_user_bounds;
}
@ -685,16 +686,16 @@ get_user_bounds(int pipeline_stage) const {
// recomputed.
////////////////////////////////////////////////////////////////////
INLINE void PandaNode::
mark_bounds_stale(int pipeline_stage) const {
mark_bounds_stale(int pipeline_stage, Thread *current_thread) const {
// It's important that we don't hold the lock during the call to
// force_bounds_stale().
bool is_stale_bounds;
{
CDBoundsStageReader cdata(_cycler_bounds, pipeline_stage);
CDBoundsStageReader cdata(_cycler_bounds, pipeline_stage, current_thread);
is_stale_bounds = (cdata->_last_update != cdata->_next_update);
}
if (!is_stale_bounds) {
((PandaNode *)this)->force_bounds_stale(pipeline_stage);
((PandaNode *)this)->force_bounds_stale(pipeline_stage, current_thread);
}
}
@ -708,12 +709,12 @@ mark_bounds_stale(int pipeline_stage) const {
// bounding volume is next requested.
////////////////////////////////////////////////////////////////////
INLINE void PandaNode::
mark_internal_bounds_stale(int pipeline_stage) {
mark_internal_bounds_stale(int pipeline_stage, Thread *current_thread) {
{
CDHeavyWriter cdata(_cycler_heavy);
CDHeavyStageWriter cdata(_cycler_heavy, pipeline_stage, current_thread);
cdata->_internal_bounds_stale = true;
}
mark_bounds_stale(pipeline_stage);
mark_bounds_stale(pipeline_stage, current_thread);
}
////////////////////////////////////////////////////////////////////
@ -1048,7 +1049,16 @@ modify_up() {
// Description:
////////////////////////////////////////////////////////////////////
INLINE PandaNode::Children::
Children(const PandaNode::CDLinksReader &cdata) :
Children() {
}
////////////////////////////////////////////////////////////////////
// Function: PandaNode::Children::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE PandaNode::Children::
Children(const PandaNode::CDataLinks *cdata) :
_down(cdata->get_down())
{
}
@ -1081,6 +1091,7 @@ operator = (const PandaNode::Children &copy) {
////////////////////////////////////////////////////////////////////
INLINE int PandaNode::Children::
get_num_children() const {
nassertr(_down != (Down *)NULL, 0);
return _down->size();
}
@ -1091,17 +1102,41 @@ get_num_children() const {
////////////////////////////////////////////////////////////////////
INLINE PandaNode *PandaNode::Children::
get_child(int n) const {
nassertr(_down != (Down *)NULL, NULL);
nassertr(n >= 0 && n < (int)_down->size(), NULL);
return (*_down)[n].get_child();
}
////////////////////////////////////////////////////////////////////
// Function: PandaNode::Children::get_child_sort
// Access: Public
// Description: Returns the sort index of the nth child node of this
// node (that is, the number that was passed to
// add_child()). See get_num_children().
////////////////////////////////////////////////////////////////////
INLINE int PandaNode::Children::
get_child_sort(int n) const {
nassertr(_down != (Down *)NULL, -1);
nassertr(n >= 0 && n < (int)_down->size(), -1);
return (*_down)[n].get_sort();
}
////////////////////////////////////////////////////////////////////
// Function: PandaNode::Stashed::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE PandaNode::Stashed::
Stashed(const PandaNode::CDLinksReader &cdata) :
Stashed() {
}
////////////////////////////////////////////////////////////////////
// Function: PandaNode::Stashed::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE PandaNode::Stashed::
Stashed(const PandaNode::CDataLinks *cdata) :
_stashed(cdata->get_stashed())
{
}
@ -1134,6 +1169,7 @@ operator = (const PandaNode::Stashed &copy) {
////////////////////////////////////////////////////////////////////
INLINE int PandaNode::Stashed::
get_num_stashed() const {
nassertr(_stashed != (Down *)NULL, 0);
return _stashed->size();
}
@ -1144,17 +1180,41 @@ get_num_stashed() const {
////////////////////////////////////////////////////////////////////
INLINE PandaNode *PandaNode::Stashed::
get_stashed(int n) const {
nassertr(_stashed != (Down *)NULL, NULL);
nassertr(n >= 0 && n < (int)_stashed->size(), NULL);
return (*_stashed)[n].get_child();
}
////////////////////////////////////////////////////////////////////
// Function: PandaNode::Stashed::get_stashed_sort
// Access: Public
// Description: Returns the sort index of the nth child node of this
// node (that is, the number that was passed to
// add_child()). See get_num_stashed().
////////////////////////////////////////////////////////////////////
INLINE int PandaNode::Stashed::
get_stashed_sort(int n) const {
nassertr(_stashed != (Down *)NULL, -1);
nassertr(n >= 0 && n < (int)_stashed->size(), -1);
return (*_stashed)[n].get_sort();
}
////////////////////////////////////////////////////////////////////
// Function: PandaNode::Parents::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE PandaNode::Parents::
Parents(const PandaNode::CDLinksReader &cdata) :
Parents() {
}
////////////////////////////////////////////////////////////////////
// Function: PandaNode::Parents::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE PandaNode::Parents::
Parents(const PandaNode::CDataLinks *cdata) :
_up(cdata->get_up())
{
}
@ -1187,6 +1247,7 @@ operator = (const PandaNode::Parents &copy) {
////////////////////////////////////////////////////////////////////
INLINE int PandaNode::Parents::
get_num_parents() const {
nassertr(_up != (Up *)NULL, 0);
return _up->size();
}
@ -1197,6 +1258,7 @@ get_num_parents() const {
////////////////////////////////////////////////////////////////////
INLINE PandaNode *PandaNode::Parents::
get_parent(int n) const {
nassertr(_up != (Up *)NULL, NULL);
nassertr(n >= 0 && n < (int)_up->size(), NULL);
return (*_up)[n].get_parent();
}

File diff suppressed because it is too large Load Diff

View File

@ -98,7 +98,8 @@ public:
virtual CPT(TransformState)
calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point,
bool &found_any,
const TransformState *transform) const;
const TransformState *transform,
Thread *current_thread) const;
virtual bool has_cull_callback() const;
virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data);
@ -111,41 +112,48 @@ public:
INLINE void compose_draw_mask(DrawMask &running_draw_mask) const;
INLINE bool compare_draw_mask(DrawMask running_draw_mask,
DrawMask camera_mask) const;
DrawMask camera_mask,
Thread *current_thread) const;
PUBLISHED:
PT(PandaNode) copy_subgraph() const;
PT(PandaNode) copy_subgraph(Thread *current_thread = Thread::get_current_thread()) const;
INLINE int get_num_parents() const;
INLINE PandaNode *get_parent(int n) const;
INLINE int find_parent(PandaNode *node) const;
INLINE int get_num_parents(Thread *current_thread = Thread::get_current_thread()) const;
INLINE PandaNode *get_parent(int n, Thread *current_thread = Thread::get_current_thread()) const;
INLINE int find_parent(PandaNode *node, Thread *current_thread = Thread::get_current_thread()) const;
INLINE int get_num_children() const;
INLINE PandaNode *get_child(int n) const;
INLINE int get_child_sort(int n) const;
INLINE int find_child(PandaNode *node) const;
INLINE int get_num_children(Thread *current_thread = Thread::get_current_thread()) const;
INLINE PandaNode *get_child(int n, Thread *current_thread = Thread::get_current_thread()) const;
INLINE int get_child_sort(int n, Thread *current_thread = Thread::get_current_thread()) const;
INLINE int find_child(PandaNode *node, Thread *current_thread = Thread::get_current_thread()) const;
void add_child(PandaNode *child_node, int sort = 0);
void remove_child(int child_index);
bool remove_child(PandaNode *child_node);
bool replace_child(PandaNode *orig_child, PandaNode *new_child);
void add_child(PandaNode *child_node, int sort = 0,
Thread *current_thread = Thread::get_current_thread());
void remove_child(int child_index, Thread *current_thread = Thread::get_current_thread());
bool remove_child(PandaNode *child_node, Thread *current_thread = Thread::get_current_thread());
bool replace_child(PandaNode *orig_child, PandaNode *new_child,
Thread *current_thread = Thread::get_current_thread());
INLINE bool stash_child(PandaNode *child_node);
void stash_child(int child_index);
INLINE bool unstash_child(PandaNode *child_node);
void unstash_child(int stashed_index);
INLINE bool stash_child(PandaNode *child_node,
Thread *current_thread = Thread::get_current_thread());
void stash_child(int child_index,
Thread *current_thread = Thread::get_current_thread());
INLINE bool unstash_child(PandaNode *child_node,
Thread *current_thread = Thread::get_current_thread());
void unstash_child(int stashed_index,
Thread *current_thread = Thread::get_current_thread());
INLINE int get_num_stashed() const;
INLINE PandaNode *get_stashed(int n) const;
INLINE int get_stashed_sort(int n) const;
INLINE int find_stashed(PandaNode *node) const;
INLINE int get_num_stashed(Thread *current_thread = Thread::get_current_thread()) const;
INLINE PandaNode *get_stashed(int n, Thread *current_thread = Thread::get_current_thread()) const;
INLINE int get_stashed_sort(int n, Thread *current_thread = Thread::get_current_thread()) const;
INLINE int find_stashed(PandaNode *node, Thread *current_thread = Thread::get_current_thread()) const;
void add_stashed(PandaNode *child_node, int sort = 0);
void remove_stashed(int child_index);
void add_stashed(PandaNode *child_node, int sort = 0, Thread *current_thread = Thread::get_current_thread());
void remove_stashed(int child_index, Thread *current_thread = Thread::get_current_thread());
void remove_all_children();
void steal_children(PandaNode *other);
void copy_children(PandaNode *other);
void remove_all_children(Thread *current_thread = Thread::get_current_thread());
void steal_children(PandaNode *other, Thread *current_thread = Thread::get_current_thread());
void copy_children(PandaNode *other, Thread *current_thread = Thread::get_current_thread());
void set_attrib(const RenderAttrib *attrib, int override = 0);
INLINE const RenderAttrib *get_attrib(TypeHandle type) const;
@ -157,23 +165,23 @@ PUBLISHED:
INLINE bool has_effect(TypeHandle type) const;
void clear_effect(TypeHandle type);
void set_state(const RenderState *state);
INLINE const RenderState *get_state() const;
INLINE void clear_state();
void set_state(const RenderState *state, Thread *current_thread = Thread::get_current_thread());
INLINE const RenderState *get_state(Thread *current_thread = Thread::get_current_thread()) const;
INLINE void clear_state(Thread *current_thread = Thread::get_current_thread());
void set_effects(const RenderEffects *effects);
INLINE const RenderEffects *get_effects() const;
INLINE void clear_effects();
void set_transform(const TransformState *transform);
INLINE const TransformState *get_transform() const;
INLINE void clear_transform();
void set_transform(const TransformState *transform, Thread *current_thread = Thread::get_current_thread());
INLINE const TransformState *get_transform(Thread *current_thread = Thread::get_current_thread()) const;
INLINE void clear_transform(Thread *current_thread = Thread::get_current_thread());
void set_prev_transform(const TransformState *transform);
INLINE const TransformState *get_prev_transform() const;
void reset_prev_transform();
void set_prev_transform(const TransformState *transform, Thread *current_thread = Thread::get_current_thread());
INLINE const TransformState *get_prev_transform(Thread *current_thread = Thread::get_current_thread()) const;
void reset_prev_transform(Thread *current_thread = Thread::get_current_thread());
INLINE bool has_dirty_prev_transform() const;
static void reset_all_prev_transform();
static void reset_all_prev_transform(Thread *current_thread = Thread::get_current_thread());
void set_tag(const string &key, const string &value);
INLINE string get_tag(const string &key) const;
@ -233,7 +241,7 @@ PUBLISHED:
CPT(BoundingVolume) get_bounds() const;
INLINE CPT(BoundingVolume) get_internal_bounds() const;
void mark_bounds_stale() const;
void mark_bounds_stale(Thread *current_thread = Thread::get_current_thread()) const;
INLINE void set_final(bool flag);
INLINE bool is_final() const;
@ -243,17 +251,17 @@ PUBLISHED:
virtual Light *as_light();
protected:
INLINE CPT(BoundingVolume) get_user_bounds(int pipeline_stage) const;
CPT(BoundingVolume) get_internal_bounds(int pipeline_stage) const;
INLINE CPT(BoundingVolume) get_user_bounds(int pipeline_stage, Thread *current_thread) const;
CPT(BoundingVolume) get_internal_bounds(int pipeline_stage, Thread *current_thread) const;
void set_internal_bounds(const BoundingVolume *volume);
INLINE void mark_bounds_stale(int pipeline_stage) const;
void force_bounds_stale();
void force_bounds_stale(int pipeline_stage);
void mark_internal_bounds_stale();
INLINE void mark_internal_bounds_stale(int pipeline_stage);
INLINE void mark_bounds_stale(int pipeline_stage, Thread *current_thread) const;
void force_bounds_stale(Thread *current_thread = Thread::get_current_thread());
void force_bounds_stale(int pipeline_stage, Thread *current_thread);
void mark_internal_bounds_stale(Thread *current_thread = Thread::get_current_thread());
INLINE void mark_internal_bounds_stale(int pipeline_stage, Thread *current_thread);
virtual PT(BoundingVolume) compute_internal_bounds(int pipeline_stage) const;
virtual PT(BoundingVolume) compute_internal_bounds(int pipeline_stage, Thread *current_thread) const;
virtual void parents_changed();
virtual void children_changed();
virtual void transform_changed();
@ -261,8 +269,10 @@ protected:
virtual void draw_mask_changed();
typedef pmap<PandaNode *, PandaNode *> InstanceMap;
virtual PT(PandaNode) r_copy_subgraph(InstanceMap &inst_map) const;
virtual void r_copy_children(const PandaNode *from, InstanceMap &inst_map);
virtual PT(PandaNode) r_copy_subgraph(InstanceMap &inst_map,
Thread *current_thread) const;
virtual void r_copy_children(const PandaNode *from, InstanceMap &inst_map,
Thread *current_thread);
private:
class CDataLight;
@ -273,39 +283,40 @@ private:
INLINE int do_find_parent(PandaNode *node, const CDataLinks *cdata) const;
int do_find_child(PandaNode *node, const CDataLinks *cdata) const;
int do_find_stashed(PandaNode *node, const CDataLinks *cdata) const;
bool stage_remove_child(PandaNode *child_node, int pipeline_stage);
bool stage_remove_child(PandaNode *child_node, int pipeline_stage,
Thread *current_thread);
bool stage_replace_child(PandaNode *orig_child, PandaNode *new_child,
int pipeline_stage);
int pipeline_stage, Thread *current_thread);
// parent-child manipulation for NodePath support. Don't try to
// call these directly.
static PT(NodePathComponent) attach(NodePathComponent *parent,
PandaNode *child, int sort,
int pipeline_stage);
static void detach(NodePathComponent *child, int pipeline_stage);
static void detach_one_stage(NodePathComponent *child, int pipeline_stage);
int pipeline_stage, Thread *current_thread);
static void detach(NodePathComponent *child, int pipeline_stage, Thread *current_thread);
static void detach_one_stage(NodePathComponent *child, int pipeline_stage, Thread *current_thread);
static bool reparent(NodePathComponent *new_parent,
NodePathComponent *child, int sort, bool as_stashed,
int pipeline_stage);
int pipeline_stage, Thread *current_thread);
static bool reparent_one_stage(NodePathComponent *new_parent,
NodePathComponent *child, int sort,
bool as_stashed, int pipeline_stage);
bool as_stashed, int pipeline_stage, Thread *current_thread);
static PT(NodePathComponent) get_component(NodePathComponent *parent,
PandaNode *child,
int pipeline_stage);
int pipeline_stage, Thread *current_thread);
static PT(NodePathComponent) get_top_component(PandaNode *child, bool force,
int pipeline_stage);
int pipeline_stage, Thread *current_thread);
PT(NodePathComponent) get_generic_component(bool accept_ambiguity,
int pipeline_stage);
int pipeline_stage, Thread *current_thread);
PT(NodePathComponent) r_get_generic_component(bool accept_ambiguity,
bool &ambiguity_detected,
int pipeline_stage);
int pipeline_stage, Thread *current_thread);
void delete_component(NodePathComponent *component);
static void sever_connection(PandaNode *parent_node, PandaNode *child_node,
int pipeline_stage);
int pipeline_stage, Thread *current_thread);
static void new_connection(PandaNode *parent_node, PandaNode *child_node,
int pipeline_stage);
void fix_path_lengths(int pipeline_stage);
int pipeline_stage, Thread *current_thread);
void fix_path_lengths(int pipeline_stage, Thread *current_thread);
void r_list_descendants(ostream &out, int indent_level) const;
INLINE void set_dirty_prev_transform();
@ -561,8 +572,8 @@ private:
typedef CycleDataStageReader<CDataLinks> CDLinksStageReader;
typedef CycleDataStageWriter<CDataLinks> CDLinksStageWriter;
CDBoundsStageWriter update_bounds(int pipeline_stage,
CDBoundsStageReader &cdata);
CDBoundsStageWriter update_bounds(int pipeline_stage,
CDBoundsStageReader &cdata);
static DrawMask _overall_bit;
@ -578,12 +589,14 @@ public:
// pass.
class EXPCL_PANDA Children {
public:
INLINE Children(const CDLinksReader &cdata);
INLINE Children();
INLINE Children(const CDataLinks *cdata);
INLINE Children(const Children &copy);
INLINE void operator = (const Children &copy);
INLINE int get_num_children() const;
INLINE PandaNode *get_child(int n) const;
INLINE int get_child_sort(int n) const;
private:
CPT(Down) _down;
@ -592,12 +605,14 @@ public:
// Similarly for stashed children.
class EXPCL_PANDA Stashed {
public:
INLINE Stashed(const CDLinksReader &cdata);
INLINE Stashed();
INLINE Stashed(const CDataLinks *cdata);
INLINE Stashed(const Stashed &copy);
INLINE void operator = (const Stashed &copy);
INLINE int get_num_stashed() const;
INLINE PandaNode *get_stashed(int n) const;
INLINE int get_stashed_sort(int n) const;
private:
CPT(Down) _stashed;
@ -606,7 +621,8 @@ public:
// This class is returned from get_parents().
class EXPCL_PANDA Parents {
public:
INLINE Parents(const CDLinksReader &cdata);
INLINE Parents();
INLINE Parents(const CDataLinks *cdata);
INLINE Parents(const Parents &copy);
INLINE void operator = (const Parents &copy);

View File

@ -209,8 +209,8 @@ is_renderable() const {
// something internally.
////////////////////////////////////////////////////////////////////
PT(BoundingVolume) PlaneNode::
compute_internal_bounds(int pipeline_stage) const {
CDStageReader cdata(_cycler, pipeline_stage);
compute_internal_bounds(int pipeline_stage, Thread *current_thread) const {
CDStageReader cdata(_cycler, pipeline_stage, current_thread);
return new BoundingPlane(cdata->_plane);
}

View File

@ -69,7 +69,7 @@ public:
INLINE static UpdateSeq get_sort_seq();
protected:
virtual PT(BoundingVolume) compute_internal_bounds(int pipeline_stage) const;
virtual PT(BoundingVolume) compute_internal_bounds(int pipeline_stage, Thread *current_thread) const;
PT(Geom) get_viz(CullTraverser *trav, CullTraverserData &data);
private:

View File

@ -389,9 +389,9 @@ draw() const {
// thing.
////////////////////////////////////////////////////////////////////
PT(BoundingVolume) PortalNode::
compute_internal_bounds(int pipeline_stage) const {
compute_internal_bounds(int pipeline_stage, Thread *current_thread) const {
// First, get ourselves a fresh, empty bounding volume.
PT(BoundingVolume) bound = PandaNode::compute_internal_bounds(pipeline_stage);
PT(BoundingVolume) bound = PandaNode::compute_internal_bounds(pipeline_stage, current_thread);
nassertr(bound != (BoundingVolume *)NULL, bound);
GeometricBoundingVolume *gbv = DCAST(GeometricBoundingVolume, bound);

View File

@ -98,7 +98,7 @@ PUBLISHED:
// void draw () const;
protected:
virtual PT(BoundingVolume) compute_internal_bounds(int pipeline_stage) const;
virtual PT(BoundingVolume) compute_internal_bounds(int pipeline_stage, Thread *current_thread) const;
private:
CPT(RenderState) get_last_pos_state();

View File

@ -50,8 +50,9 @@ is_valid() const {
int WorkingNodePath::
get_num_nodes() const {
if (_next == (WorkingNodePath *)NULL) {
int pipeline_stage = Thread::get_current_pipeline_stage();
return _start->get_length(pipeline_stage);
Thread *current_thread = Thread::get_current_thread();
int pipeline_stage = current_thread->get_pipeline_stage();
return _start->get_length(pipeline_stage, current_thread);
}
return _next->get_num_nodes() + 1;
@ -111,15 +112,16 @@ r_get_node_path() const {
PT(NodePathComponent) comp = _next->r_get_node_path();
nassertr(comp != (NodePathComponent *)NULL, NULL);
int pipeline_stage = Thread::get_current_pipeline_stage();
PT(NodePathComponent) result = PandaNode::get_component(comp, _node,
pipeline_stage);
Thread *current_thread = Thread::get_current_thread();
int pipeline_stage = current_thread->get_pipeline_stage();
PT(NodePathComponent) result =
PandaNode::get_component(comp, _node, pipeline_stage, current_thread);
if (result == (NodePathComponent *)NULL) {
// This means we found a disconnected chain in the
// WorkingNodePath's ancestry: the node above this node isn't
// connected. In this case, don't attempt to go higher; just
// truncate the NodePath at the bottom of the disconnect.
return PandaNode::get_top_component(_node, true, pipeline_stage);
return PandaNode::get_top_component(_node, true, pipeline_stage, current_thread);
}
return result;

Some files were not shown because too many files have changed in this diff Show More