more mutex protection; more current_thread passing
This commit is contained in:
parent
5a6f625009
commit
fade04905d
|
|
@ -99,14 +99,15 @@ write_with_value(ostream &out, int indent_level) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
bool MovingPartBase::
|
||||
do_update(PartBundle *root, PartGroup *parent,
|
||||
bool parent_changed, bool anim_changed) {
|
||||
bool parent_changed, bool anim_changed,
|
||||
Thread *current_thread) {
|
||||
bool any_changed = false;
|
||||
bool needs_update = anim_changed;
|
||||
|
||||
// See if any of the channel values have changed since last time.
|
||||
|
||||
{
|
||||
PartBundle::CDReader cdata(root->_cycler);
|
||||
PartBundle::CDReader cdata(root->_cycler, current_thread);
|
||||
PartBundle::ChannelBlend::const_iterator bci;
|
||||
for (bci = cdata->_blend.begin();
|
||||
!needs_update && bci != cdata->_blend.end();
|
||||
|
|
@ -127,14 +128,15 @@ do_update(PartBundle *root, PartGroup *parent,
|
|||
}
|
||||
|
||||
if (parent_changed || needs_update) {
|
||||
any_changed = update_internals(parent, needs_update, parent_changed);
|
||||
any_changed = update_internals(parent, needs_update, parent_changed,
|
||||
current_thread);
|
||||
}
|
||||
|
||||
// Now recurse.
|
||||
Children::iterator ci;
|
||||
for (ci = _children.begin(); ci != _children.end(); ++ci) {
|
||||
if ((*ci)->do_update(root, this, parent_changed || needs_update,
|
||||
anim_changed)) {
|
||||
anim_changed, current_thread)) {
|
||||
any_changed = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -155,7 +157,7 @@ do_update(PartBundle *root, PartGroup *parent,
|
|||
// result of the update, or false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool MovingPartBase::
|
||||
update_internals(PartGroup *, bool, bool) {
|
||||
update_internals(PartGroup *, bool, bool, Thread *) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -57,11 +57,12 @@ PUBLISHED:
|
|||
|
||||
public:
|
||||
virtual bool do_update(PartBundle *root, PartGroup *parent,
|
||||
bool parent_changed, bool anim_changed);
|
||||
bool parent_changed, bool anim_changed,
|
||||
Thread *current_thread);
|
||||
|
||||
virtual void get_blend_value(const PartBundle *root)=0;
|
||||
virtual bool update_internals(PartGroup *parent, bool self_changed,
|
||||
bool parent_changed);
|
||||
bool parent_changed, Thread *current_thread);
|
||||
|
||||
protected:
|
||||
MovingPartBase();
|
||||
|
|
|
|||
|
|
@ -240,15 +240,16 @@ bind_anim(AnimBundle *anim, int hierarchy_match_flags,
|
|||
////////////////////////////////////////////////////////////////////
|
||||
bool PartBundle::
|
||||
update() {
|
||||
Thread *current_thread = Thread::get_current_thread();
|
||||
bool anim_changed;
|
||||
{
|
||||
CDReader cdata(_cycler);
|
||||
CDReader cdata(_cycler, current_thread);
|
||||
anim_changed = cdata->_anim_changed;
|
||||
}
|
||||
bool any_changed = do_update(this, NULL, false, anim_changed);
|
||||
bool any_changed = do_update(this, NULL, false, anim_changed, current_thread);
|
||||
|
||||
// Now update all the controls for next time.
|
||||
CDWriter cdata(_cycler, false);
|
||||
CDWriter cdata(_cycler, false, current_thread);
|
||||
ChannelBlend::const_iterator cbi;
|
||||
for (cbi = cdata->_blend.begin(); cbi != cdata->_blend.end(); ++cbi) {
|
||||
AnimControl *control = (*cbi).first;
|
||||
|
|
@ -269,10 +270,11 @@ update() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
bool PartBundle::
|
||||
force_update() {
|
||||
bool any_changed = do_update(this, NULL, true, true);
|
||||
Thread *current_thread = Thread::get_current_thread();
|
||||
bool any_changed = do_update(this, NULL, true, true, current_thread);
|
||||
|
||||
// Now update all the controls for next time.
|
||||
CDWriter cdata(_cycler, false);
|
||||
CDWriter cdata(_cycler, false, current_thread);
|
||||
ChannelBlend::const_iterator cbi;
|
||||
for (cbi = cdata->_blend.begin(); cbi != cdata->_blend.end(); ++cbi) {
|
||||
AnimControl *control = (*cbi).first;
|
||||
|
|
@ -428,7 +430,8 @@ clear_and_stop_intersecting(AnimControl *control, CData *cdata) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void PartBundle::
|
||||
finalize(BamReader *) {
|
||||
do_update(this, NULL, true, true);
|
||||
Thread *current_thread = Thread::get_current_thread();
|
||||
do_update(this, NULL, true, true, current_thread);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -361,12 +361,13 @@ write_with_value(ostream &out, int indent_level) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
bool PartGroup::
|
||||
do_update(PartBundle *root, PartGroup *,
|
||||
bool parent_changed, bool anim_changed) {
|
||||
bool parent_changed, bool anim_changed, Thread *current_thread) {
|
||||
bool any_changed = false;
|
||||
|
||||
Children::iterator ci;
|
||||
for (ci = _children.begin(); ci != _children.end(); ++ci) {
|
||||
if ((*ci)->do_update(root, this, parent_changed, anim_changed)) {
|
||||
if ((*ci)->do_update(root, this, parent_changed, anim_changed,
|
||||
current_thread)) {
|
||||
any_changed = true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
#include "pointerTo.h"
|
||||
#include "namable.h"
|
||||
#include "typedef.h"
|
||||
|
||||
#include "thread.h"
|
||||
#include "plist.h"
|
||||
|
||||
class AnimControl;
|
||||
|
|
@ -86,7 +86,8 @@ public:
|
|||
int hierarchy_match_flags = 0) const;
|
||||
|
||||
virtual bool do_update(PartBundle *root, PartGroup *parent,
|
||||
bool parent_changed, bool anim_changed);
|
||||
bool parent_changed, bool anim_changed,
|
||||
Thread *current_thread);
|
||||
|
||||
protected:
|
||||
void write_descendants(ostream &out, int indent_level) const;
|
||||
|
|
|
|||
|
|
@ -60,9 +60,11 @@ CharacterJoint(PartGroup *parent, const string &name,
|
|||
const LMatrix4f &initial_value)
|
||||
: MovingPartMatrix(parent, name, initial_value)
|
||||
{
|
||||
Thread *current_thread = Thread::get_current_thread();
|
||||
|
||||
// Now that we've constructed and we're in the tree, let's call
|
||||
// update_internals() to get our _net_transform set properly.
|
||||
update_internals(parent, true, false);
|
||||
update_internals(parent, true, false, current_thread);
|
||||
|
||||
// And then compute its inverse. This is needed for
|
||||
// ComputedVertices, during animation.
|
||||
|
|
@ -106,7 +108,9 @@ make_copy() const {
|
|||
// transforms for this particular joint.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool CharacterJoint::
|
||||
update_internals(PartGroup *parent, bool self_changed, bool parent_changed) {
|
||||
update_internals(PartGroup *parent, bool self_changed, bool parent_changed,
|
||||
Thread *current_thread) {
|
||||
|
||||
nassertr(parent != (PartGroup *)NULL, false);
|
||||
|
||||
bool net_changed = false;
|
||||
|
|
@ -137,7 +141,7 @@ update_internals(PartGroup *parent, bool self_changed, bool parent_changed) {
|
|||
ai = _net_transform_nodes.begin();
|
||||
while (ai != _net_transform_nodes.end()) {
|
||||
PandaNode *node = *ai;
|
||||
node->set_transform(t);
|
||||
node->set_transform(t, current_thread);
|
||||
++ai;
|
||||
}
|
||||
}
|
||||
|
|
@ -147,7 +151,7 @@ update_internals(PartGroup *parent, bool self_changed, bool parent_changed) {
|
|||
VertexTransforms::iterator vti;
|
||||
for (vti = _vertex_transforms.begin(); vti != _vertex_transforms.end(); ++vti) {
|
||||
(*vti)->_matrix_stale = true;
|
||||
(*vti)->mark_modified();
|
||||
(*vti)->mark_modified(current_thread);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -158,7 +162,7 @@ update_internals(PartGroup *parent, bool self_changed, bool parent_changed) {
|
|||
ai = _local_transform_nodes.begin();
|
||||
while (ai != _local_transform_nodes.end()) {
|
||||
PandaNode *node = *ai;
|
||||
node->set_transform(t);
|
||||
node->set_transform(t, current_thread);
|
||||
++ai;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ public:
|
|||
virtual PartGroup *make_copy() const;
|
||||
|
||||
virtual bool update_internals(PartGroup *parent, bool self_changed,
|
||||
bool parent_changed);
|
||||
bool parent_changed, Thread *current_thread);
|
||||
|
||||
PUBLISHED:
|
||||
bool add_net_transform(PandaNode *node);
|
||||
|
|
|
|||
|
|
@ -88,12 +88,12 @@ make_copy() const {
|
|||
// result of the update, or false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool CharacterSlider::
|
||||
update_internals(PartGroup *, bool, bool) {
|
||||
update_internals(PartGroup *, bool, bool, Thread *current_thread) {
|
||||
// Tell our related CharacterVertexSliders that they now need to
|
||||
// recompute themselves.
|
||||
VertexSliders::iterator vsi;
|
||||
for (vsi = _vertex_sliders.begin(); vsi != _vertex_sliders.end(); ++vsi) {
|
||||
(*vsi)->mark_modified();
|
||||
(*vsi)->mark_modified(current_thread);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ public:
|
|||
virtual PartGroup *make_copy() const;
|
||||
|
||||
virtual bool update_internals(PartGroup *parent, bool self_changed,
|
||||
bool parent_changed);
|
||||
bool parent_changed, Thread *current_thread);
|
||||
|
||||
private:
|
||||
typedef pset<CharacterVertexSlider *> VertexSliders;
|
||||
|
|
|
|||
|
|
@ -37,7 +37,9 @@ GeomMunger() :
|
|||
_is_registered(false)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
_registered_key = get_registry()->_mungers.end();
|
||||
Registry *registry = get_registry();
|
||||
MutexHolder holder(registry->_registry_lock);
|
||||
_registered_key = registry->_mungers.end();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -51,7 +53,9 @@ GeomMunger(const GeomMunger ©) :
|
|||
_is_registered(false)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
_registered_key = get_registry()->_mungers.end();
|
||||
Registry *registry = get_registry();
|
||||
MutexHolder holder(registry->_registry_lock);
|
||||
_registered_key = registry->_mungers.end();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -180,6 +184,8 @@ do_munge_format(const GeomVertexFormat *format,
|
|||
nassertr(_is_registered, NULL);
|
||||
nassertr(format->is_registered(), NULL);
|
||||
|
||||
MutexHolder holder(_formats_lock);
|
||||
|
||||
Formats &formats = _formats_by_animation[animation];
|
||||
|
||||
Formats::iterator fi;
|
||||
|
|
@ -373,6 +379,8 @@ register_munger(GeomMunger *munger, Thread *current_thread) {
|
|||
// will be automatically deleted when this function returns.
|
||||
PT(GeomMunger) pt_munger = munger;
|
||||
|
||||
MutexHolder holder(_registry_lock);
|
||||
|
||||
Mungers::iterator mi = _mungers.insert(munger).first;
|
||||
GeomMunger *new_munger = (*mi);
|
||||
if (!new_munger->is_registered()) {
|
||||
|
|
@ -392,6 +400,8 @@ register_munger(GeomMunger *munger, Thread *current_thread) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void GeomMunger::Registry::
|
||||
unregister_munger(GeomMunger *munger) {
|
||||
MutexHolder holder(_registry_lock);
|
||||
|
||||
nassertv(munger->is_registered());
|
||||
nassertv(munger->_registered_key != _mungers.end());
|
||||
_mungers.erase(munger->_registered_key);
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#include "geomCacheEntry.h"
|
||||
#include "indirectCompareTo.h"
|
||||
#include "pStatCollector.h"
|
||||
#include "pmutex.h"
|
||||
#include "pointerTo.h"
|
||||
#include "pmap.h"
|
||||
#include "pset.h"
|
||||
|
|
@ -111,6 +112,9 @@ private:
|
|||
typedef pmap<GeomVertexAnimationSpec, Formats> FormatsByAnimation;
|
||||
FormatsByAnimation _formats_by_animation;
|
||||
|
||||
// This mutex protects the above.
|
||||
Mutex _formats_lock;
|
||||
|
||||
bool _is_registered;
|
||||
typedef pset<GeomMunger *, IndirectCompareTo<GeomMunger> > Mungers;
|
||||
class EXPCL_PANDA Registry {
|
||||
|
|
@ -120,6 +124,7 @@ private:
|
|||
void unregister_munger(GeomMunger *munger);
|
||||
|
||||
Mungers _mungers;
|
||||
Mutex _registry_lock;
|
||||
};
|
||||
|
||||
// We store the iterator into the above registry, while we are
|
||||
|
|
|
|||
|
|
@ -425,13 +425,14 @@ offset_vertices(int offset) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void GeomPrimitive::
|
||||
make_nonindexed(GeomVertexData *dest, const GeomVertexData *source) {
|
||||
Thread *current_thread = Thread::get_current_thread();
|
||||
int num_vertices = get_num_vertices();
|
||||
int dest_start = dest->get_num_rows();
|
||||
|
||||
dest->set_num_rows(dest_start + num_vertices);
|
||||
for (int i = 0; i < num_vertices; ++i) {
|
||||
int v = get_vertex(i);
|
||||
dest->copy_row_from(dest_start + i, source, v);
|
||||
dest->copy_row_from(dest_start + i, source, v, current_thread);
|
||||
}
|
||||
|
||||
set_nonindexed_vertices(dest_start, num_vertices);
|
||||
|
|
@ -446,6 +447,7 @@ make_nonindexed(GeomVertexData *dest, const GeomVertexData *source) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void GeomPrimitive::
|
||||
pack_vertices(GeomVertexData *dest, const GeomVertexData *source) {
|
||||
Thread *current_thread = Thread::get_current_thread();
|
||||
if (!is_indexed()) {
|
||||
// If the primitive is nonindexed, packing is the same as
|
||||
// converting (again) to nonindexed.
|
||||
|
|
@ -475,7 +477,7 @@ pack_vertices(GeomVertexData *dest, const GeomVertexData *source) {
|
|||
|
||||
if (result.second) {
|
||||
// This is the first time we've seen vertex v.
|
||||
dest->copy_row_from(v2, source, v);
|
||||
dest->copy_row_from(v2, source, v, current_thread);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -240,9 +240,10 @@ set_usage_hint(GeomVertexData::UsageHint usage_hint) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void GeomVertexData::
|
||||
set_format(const GeomVertexFormat *format) {
|
||||
Thread *current_thread = Thread::get_current_thread();
|
||||
nassertv(format->is_registered());
|
||||
|
||||
CDReader cdata(_cycler);
|
||||
CDReader cdata(_cycler, current_thread);
|
||||
|
||||
if (format == cdata->_format) {
|
||||
// Trivially no-op.
|
||||
|
|
@ -269,7 +270,7 @@ set_format(const GeomVertexFormat *format) {
|
|||
|
||||
// Now copy the original data back in. This will automatically
|
||||
// convert it to the new format.
|
||||
copy_from(orig_data, false);
|
||||
copy_from(orig_data, false, current_thread);
|
||||
|
||||
clear_cache_stage();
|
||||
cdataw->_modified = Geom::get_next_modified();
|
||||
|
|
@ -289,7 +290,8 @@ set_format(const GeomVertexFormat *format) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void GeomVertexData::
|
||||
clear_rows() {
|
||||
CDWriter cdata(_cycler, true);
|
||||
Thread *current_thread = Thread::get_current_thread();
|
||||
CDWriter cdata(_cycler, true, current_thread);
|
||||
nassertv(cdata->_format->get_num_arrays() == (int)cdata->_arrays.size());
|
||||
|
||||
Arrays::iterator ai;
|
||||
|
|
@ -321,9 +323,10 @@ clear_rows() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void GeomVertexData::
|
||||
set_transform_table(const TransformTable *table) {
|
||||
Thread *current_thread = Thread::get_current_thread();
|
||||
nassertv(table == (TransformTable *)NULL || table->is_registered());
|
||||
|
||||
CDWriter cdata(_cycler, true);
|
||||
CDWriter cdata(_cycler, true, current_thread);
|
||||
cdata->_transform_table = (TransformTable *)table;
|
||||
clear_cache_stage();
|
||||
cdata->_modified = Geom::get_next_modified();
|
||||
|
|
@ -428,7 +431,8 @@ set_slider_table(const SliderTable *table) {
|
|||
// have recently made in an upstream thread.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GeomVertexData::
|
||||
copy_from(const GeomVertexData *source, bool keep_data_objects) {
|
||||
copy_from(const GeomVertexData *source, bool keep_data_objects,
|
||||
Thread *current_thread) {
|
||||
const GeomVertexFormat *source_format = source->get_format();
|
||||
const GeomVertexFormat *dest_format = get_format();
|
||||
|
||||
|
|
@ -626,7 +630,7 @@ copy_from(const GeomVertexData *source, bool keep_data_objects) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void GeomVertexData::
|
||||
copy_row_from(int dest_row, const GeomVertexData *source,
|
||||
int source_row) {
|
||||
int source_row, Thread *current_thread) {
|
||||
const GeomVertexFormat *source_format = source->get_format();
|
||||
const GeomVertexFormat *dest_format = get_format();
|
||||
nassertv(source_format == dest_format);
|
||||
|
|
@ -896,14 +900,14 @@ animate_vertices(Thread *current_thread) const {
|
|||
if (cdata->_transform_blend_table != (TransformBlendTable *)NULL) {
|
||||
if (cdata->_slider_table != (SliderTable *)NULL) {
|
||||
modified =
|
||||
max(cdata->_transform_blend_table->get_modified(),
|
||||
cdata->_slider_table->get_modified());
|
||||
max(cdata->_transform_blend_table->get_modified(current_thread),
|
||||
cdata->_slider_table->get_modified(current_thread));
|
||||
} else {
|
||||
modified = cdata->_transform_blend_table->get_modified();
|
||||
modified = cdata->_transform_blend_table->get_modified(current_thread);
|
||||
}
|
||||
|
||||
} else if (cdata->_slider_table != (SliderTable *)NULL) {
|
||||
modified = cdata->_slider_table->get_modified();
|
||||
modified = cdata->_slider_table->get_modified(current_thread);
|
||||
|
||||
} else {
|
||||
// No transform blend table or slider table--ergo, no vertex
|
||||
|
|
@ -918,7 +922,7 @@ animate_vertices(Thread *current_thread) const {
|
|||
}
|
||||
CDWriter cdataw(((GeomVertexData *)this)->_cycler, cdata, false);
|
||||
cdataw->_animated_vertices_modified = modified;
|
||||
((GeomVertexData *)this)->update_animated_vertices(cdataw);
|
||||
((GeomVertexData *)this)->update_animated_vertices(cdataw, current_thread);
|
||||
return cdataw->_animated_vertices;
|
||||
}
|
||||
|
||||
|
|
@ -1186,7 +1190,7 @@ uint8_rgba_to_packed_argb(unsigned char *to, int to_stride,
|
|||
// existing animated_vertices object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GeomVertexData::
|
||||
update_animated_vertices(GeomVertexData::CData *cdata) {
|
||||
update_animated_vertices(GeomVertexData::CData *cdata, Thread *current_thread) {
|
||||
int num_rows = get_num_rows();
|
||||
|
||||
if (gobj_cat.is_debug()) {
|
||||
|
|
@ -1195,7 +1199,7 @@ update_animated_vertices(GeomVertexData::CData *cdata) {
|
|||
<< "\n";
|
||||
}
|
||||
|
||||
PStatTimer timer(_char_pcollector);
|
||||
PStatTimer timer(_char_pcollector, current_thread);
|
||||
|
||||
const GeomVertexFormat *orig_format = cdata->_format;
|
||||
|
||||
|
|
@ -1203,7 +1207,7 @@ update_animated_vertices(GeomVertexData::CData *cdata) {
|
|||
CPT(GeomVertexFormat) new_format = orig_format->get_post_animated_format();
|
||||
cdata->_animated_vertices =
|
||||
new GeomVertexData(get_name(), new_format,
|
||||
min(get_usage_hint(), UH_dynamic));
|
||||
min(get_usage_hint(), UH_dynamic));
|
||||
}
|
||||
PT(GeomVertexData) new_data = cdata->_animated_vertices;
|
||||
|
||||
|
|
@ -1275,7 +1279,7 @@ update_animated_vertices(GeomVertexData::CData *cdata) {
|
|||
int num_blends = tb_table->get_num_blends();
|
||||
int bi;
|
||||
for (bi = 0; bi < num_blends; bi++) {
|
||||
tb_table->get_blend(bi).update_blend();
|
||||
tb_table->get_blend(bi).update_blend(current_thread);
|
||||
}
|
||||
|
||||
// Now go through and apply the transforms.
|
||||
|
|
@ -1296,14 +1300,14 @@ update_animated_vertices(GeomVertexData::CData *cdata) {
|
|||
for (int i = 0; i < num_rows; i++) {
|
||||
LPoint4f vertex = data.get_data4f();
|
||||
int bi = blendi.get_data1i();
|
||||
tb_table->get_blend(bi).transform_point(vertex);
|
||||
tb_table->get_blend(bi).transform_point(vertex, current_thread);
|
||||
data.set_data4f(vertex);
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < num_rows; i++) {
|
||||
LPoint3f vertex = data.get_data3f();
|
||||
int bi = blendi.get_data1i();
|
||||
tb_table->get_blend(bi).transform_point(vertex);
|
||||
tb_table->get_blend(bi).transform_point(vertex, current_thread);
|
||||
data.set_data3f(vertex);
|
||||
}
|
||||
}
|
||||
|
|
@ -1315,7 +1319,7 @@ update_animated_vertices(GeomVertexData::CData *cdata) {
|
|||
for (int i = 0; i < num_rows; i++) {
|
||||
LVector3f vertex = data.get_data3f();
|
||||
int bi = blendi.get_data1i();
|
||||
tb_table->get_blend(bi).transform_vector(vertex);
|
||||
tb_table->get_blend(bi).transform_vector(vertex, current_thread);
|
||||
data.set_data3f(vertex);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -124,9 +124,10 @@ PUBLISHED:
|
|||
INLINE int get_num_bytes() const;
|
||||
INLINE UpdateSeq get_modified(Thread *current_thread = Thread::get_current_thread()) const;
|
||||
|
||||
void copy_from(const GeomVertexData *source, bool keep_data_objects);
|
||||
void copy_from(const GeomVertexData *source, bool keep_data_objects,
|
||||
Thread *current_thread = Thread::get_current_thread());
|
||||
void copy_row_from(int dest_row, const GeomVertexData *source,
|
||||
int source_row);
|
||||
int source_row, Thread *current_thread);
|
||||
CPT(GeomVertexData) convert_to(const GeomVertexFormat *new_format) const;
|
||||
CPT(GeomVertexData)
|
||||
scale_color(const LVecBase4f &color_scale) const;
|
||||
|
|
@ -253,7 +254,7 @@ private:
|
|||
Cache _cache;
|
||||
|
||||
private:
|
||||
void update_animated_vertices(CData *cdata);
|
||||
void update_animated_vertices(CData *cdata, Thread *current_thread);
|
||||
|
||||
static PStatCollector _convert_pcollector;
|
||||
static PStatCollector _scale_color_pcollector;
|
||||
|
|
|
|||
|
|
@ -131,8 +131,8 @@ is_empty() const {
|
|||
// changes.)
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE UpdateSeq SliderTable::
|
||||
get_modified() const {
|
||||
CDReader cdata(_cycler);
|
||||
get_modified(Thread *current_thread) const {
|
||||
CDReader cdata(_cycler, current_thread);
|
||||
return cdata->_modified;
|
||||
}
|
||||
|
||||
|
|
@ -143,8 +143,8 @@ get_modified() const {
|
|||
// reports that it has been modified.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void SliderTable::
|
||||
update_modified(UpdateSeq modified) {
|
||||
CDWriter cdata(_cycler, true);
|
||||
update_modified(UpdateSeq modified, Thread *current_thread) {
|
||||
CDWriter cdata(_cycler, true, current_thread);
|
||||
cdata->_modified = modified;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -316,5 +316,6 @@ write_datagram(BamWriter *manager, Datagram &dg) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void SliderTable::CData::
|
||||
fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
_modified = VertexTransform::get_next_modified();
|
||||
Thread *current_thread = Thread::get_current_thread();
|
||||
_modified = VertexTransform::get_next_modified(current_thread);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ PUBLISHED:
|
|||
INLINE const VertexSlider *find_slider(const InternalName *name) const;
|
||||
INLINE bool has_slider(const InternalName *name) const;
|
||||
INLINE bool is_empty() const;
|
||||
INLINE UpdateSeq get_modified() const;
|
||||
INLINE UpdateSeq get_modified(Thread *current_thread) const;
|
||||
|
||||
void set_slider(int n, const VertexSlider *slider);
|
||||
void remove_slider(int n);
|
||||
|
|
@ -70,7 +70,7 @@ PUBLISHED:
|
|||
private:
|
||||
void do_register();
|
||||
void do_unregister();
|
||||
INLINE void update_modified(UpdateSeq modified);
|
||||
INLINE void update_modified(UpdateSeq modified, Thread *current_thread);
|
||||
|
||||
private:
|
||||
bool _is_registered;
|
||||
|
|
|
|||
|
|
@ -100,7 +100,8 @@ TransformBlend(const TransformBlend ©) :
|
|||
INLINE void TransformBlend::
|
||||
operator = (const TransformBlend ©) {
|
||||
_entries = copy._entries;
|
||||
clear_result();
|
||||
Thread *current_thread = Thread::get_current_thread();
|
||||
clear_result(current_thread);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -209,11 +210,11 @@ set_weight(int n, float weight) {
|
|||
// calling get_blend() or transform_point().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void TransformBlend::
|
||||
update_blend() const {
|
||||
CDReader cdata(_cycler);
|
||||
if (cdata->_global_modified != VertexTransform::get_global_modified()) {
|
||||
update_blend(Thread *current_thread) const {
|
||||
CDReader cdata(_cycler, current_thread);
|
||||
if (cdata->_global_modified != VertexTransform::get_global_modified(current_thread)) {
|
||||
CDWriter cdataw(((TransformBlend *)this)->_cycler, cdata, false);
|
||||
((TransformBlend *)this)->recompute_result(cdataw);
|
||||
((TransformBlend *)this)->recompute_result(cdataw, current_thread);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -228,9 +229,8 @@ update_blend() const {
|
|||
// cache is up-to-date before calling this.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void TransformBlend::
|
||||
get_blend(LMatrix4f &result) const {
|
||||
CDReader cdata(_cycler);
|
||||
nassertv(cdata->_global_modified == VertexTransform::get_global_modified());
|
||||
get_blend(LMatrix4f &result, Thread *current_thread) const {
|
||||
CDReader cdata(_cycler, current_thread);
|
||||
result = cdata->_result;
|
||||
}
|
||||
|
||||
|
|
@ -243,10 +243,9 @@ get_blend(LMatrix4f &result) const {
|
|||
// cache is up-to-date before calling this.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void TransformBlend::
|
||||
transform_point(LPoint4f &point) const {
|
||||
transform_point(LPoint4f &point, Thread *current_thread) const {
|
||||
if (!_entries.empty()) {
|
||||
CDReader cdata(_cycler);
|
||||
nassertv(cdata->_global_modified == VertexTransform::get_global_modified());
|
||||
CDReader cdata(_cycler, current_thread);
|
||||
point = point * cdata->_result;
|
||||
}
|
||||
}
|
||||
|
|
@ -260,10 +259,9 @@ transform_point(LPoint4f &point) const {
|
|||
// cache is up-to-date before calling this.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void TransformBlend::
|
||||
transform_point(LPoint3f &point) const {
|
||||
transform_point(LPoint3f &point, Thread *current_thread) const {
|
||||
if (!_entries.empty()) {
|
||||
CDReader cdata(_cycler);
|
||||
nassertv(cdata->_global_modified == VertexTransform::get_global_modified());
|
||||
CDReader cdata(_cycler, current_thread);
|
||||
point = point * cdata->_result;
|
||||
}
|
||||
}
|
||||
|
|
@ -277,10 +275,9 @@ transform_point(LPoint3f &point) const {
|
|||
// cache is up-to-date before calling this.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void TransformBlend::
|
||||
transform_vector(LVector3f &vector) const {
|
||||
transform_vector(LVector3f &vector, Thread *current_thread) const {
|
||||
if (!_entries.empty()) {
|
||||
CDReader cdata(_cycler);
|
||||
nassertv(cdata->_global_modified == VertexTransform::get_global_modified());
|
||||
CDReader cdata(_cycler, current_thread);
|
||||
vector = vector * cdata->_result;
|
||||
}
|
||||
}
|
||||
|
|
@ -292,11 +289,11 @@ transform_vector(LVector3f &vector) const {
|
|||
// least as often as the result of get_blend() changes.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE UpdateSeq TransformBlend::
|
||||
get_modified() const {
|
||||
CDReader cdata(_cycler);
|
||||
if (cdata->_global_modified != VertexTransform::get_global_modified()) {
|
||||
get_modified(Thread *current_thread) const {
|
||||
CDReader cdata(_cycler, current_thread);
|
||||
if (cdata->_global_modified != VertexTransform::get_global_modified(current_thread)) {
|
||||
CDWriter cdataw(((TransformBlend *)this)->_cycler, cdata, false);
|
||||
((TransformBlend *)this)->recompute_result(cdataw);
|
||||
((TransformBlend *)this)->recompute_result(cdataw, current_thread);
|
||||
return cdataw->_modified;
|
||||
} else {
|
||||
return cdata->_modified;
|
||||
|
|
|
|||
|
|
@ -75,7 +75,8 @@ add_transform(const VertexTransform *transform, float weight) {
|
|||
_entries.erase(ei);
|
||||
}
|
||||
}
|
||||
clear_result();
|
||||
Thread *current_thread = Thread::get_current_thread();
|
||||
clear_result(current_thread);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -93,7 +94,8 @@ remove_transform(const VertexTransform *transform) {
|
|||
if (ei != _entries.end()) {
|
||||
_entries.erase(ei);
|
||||
}
|
||||
clear_result();
|
||||
Thread *current_thread = Thread::get_current_thread();
|
||||
clear_result(current_thread);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -116,7 +118,8 @@ normalize_weights() {
|
|||
(*ei)._weight /= net_weight;
|
||||
}
|
||||
}
|
||||
clear_result();
|
||||
Thread *current_thread = Thread::get_current_thread();
|
||||
clear_result(current_thread);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -180,6 +183,7 @@ output(ostream &out) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void TransformBlend::
|
||||
write(ostream &out, int indent_level) const {
|
||||
Thread *current_thread = Thread::get_current_thread();
|
||||
Entries::const_iterator ei;
|
||||
for (ei = _entries.begin(); ei != _entries.end(); ++ei) {
|
||||
indent(out, indent_level)
|
||||
|
|
@ -189,7 +193,7 @@ write(ostream &out, int indent_level) const {
|
|||
mat.write(out, indent_level + 4);
|
||||
}
|
||||
LMatrix4f blend;
|
||||
get_blend(blend);
|
||||
get_blend(blend, current_thread);
|
||||
indent(out, indent_level)
|
||||
<< "Blended result =\n";
|
||||
blend.write(out, indent_level + 2);
|
||||
|
|
@ -202,16 +206,16 @@ write(ostream &out, int indent_level) const {
|
|||
// VertexTransform objects, if necessary.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void TransformBlend::
|
||||
recompute_result(CData *cdata) {
|
||||
recompute_result(CData *cdata, Thread *current_thread) {
|
||||
// Update the global_modified sequence number first, to prevent race
|
||||
// conditions.
|
||||
cdata->_global_modified = VertexTransform::get_global_modified();
|
||||
cdata->_global_modified = VertexTransform::get_global_modified(current_thread);
|
||||
|
||||
// Now see if we really need to recompute.
|
||||
UpdateSeq seq;
|
||||
Entries::const_iterator ei;
|
||||
for (ei = _entries.begin(); ei != _entries.end(); ++ei) {
|
||||
seq = max(seq, (*ei)._transform->get_modified());
|
||||
seq = max(seq, (*ei)._transform->get_modified(current_thread));
|
||||
}
|
||||
|
||||
if (cdata->_modified != seq) {
|
||||
|
|
@ -235,8 +239,8 @@ recompute_result(CData *cdata) {
|
|||
// recomputed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void TransformBlend::
|
||||
clear_result() {
|
||||
CDWriter cdata(_cycler, true);
|
||||
clear_result(Thread *current_thread) {
|
||||
CDWriter cdata(_cycler, true, current_thread);
|
||||
cdata->_global_modified = UpdateSeq();
|
||||
if (cdata->_modified != UpdateSeq()) {
|
||||
cdata->_modified = UpdateSeq();
|
||||
|
|
|
|||
|
|
@ -70,13 +70,13 @@ PUBLISHED:
|
|||
INLINE void set_transform(int n, const VertexTransform *transform);
|
||||
INLINE void set_weight(int n, float weight);
|
||||
|
||||
INLINE void update_blend() const;
|
||||
INLINE void update_blend(Thread *current_thread) const;
|
||||
|
||||
INLINE void get_blend(LMatrix4f &result) const;
|
||||
INLINE void transform_point(LPoint4f &point) const;
|
||||
INLINE void transform_point(LPoint3f &point) const;
|
||||
INLINE void transform_vector(LVector3f &point) const;
|
||||
INLINE UpdateSeq get_modified() const;
|
||||
INLINE void get_blend(LMatrix4f &result, Thread *current_thread) const;
|
||||
INLINE void transform_point(LPoint4f &point, Thread *current_thread) const;
|
||||
INLINE void transform_point(LPoint3f &point, Thread *current_thread) const;
|
||||
INLINE void transform_vector(LVector3f &point, Thread *current_thread) const;
|
||||
INLINE UpdateSeq get_modified(Thread *current_thread) const;
|
||||
|
||||
void output(ostream &out) const;
|
||||
void write(ostream &out, int indent_level) const;
|
||||
|
|
@ -84,8 +84,8 @@ PUBLISHED:
|
|||
private:
|
||||
class CData;
|
||||
|
||||
void recompute_result(CData *cdata);
|
||||
void clear_result();
|
||||
void recompute_result(CData *cdata, Thread *current_thread);
|
||||
void clear_result(Thread *current_thread);
|
||||
|
||||
class TransformEntry {
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -47,11 +47,11 @@ get_blend(int n) const {
|
|||
// have changed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE UpdateSeq TransformBlendTable::
|
||||
get_modified() const {
|
||||
get_modified(Thread *current_thread) const {
|
||||
CDReader cdata(_cycler);
|
||||
if (cdata->_global_modified != VertexTransform::get_global_modified()) {
|
||||
if (cdata->_global_modified != VertexTransform::get_global_modified(current_thread)) {
|
||||
CDWriter cdataw(((TransformBlendTable *)this)->_cycler, cdata, false);
|
||||
((TransformBlendTable *)this)->recompute_modified(cdataw);
|
||||
((TransformBlendTable *)this)->recompute_modified(cdataw, current_thread);
|
||||
return cdataw->_modified;
|
||||
} else {
|
||||
return cdata->_modified;
|
||||
|
|
|
|||
|
|
@ -174,16 +174,16 @@ rebuild_index() {
|
|||
// TransformBlend objects, if necessary.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void TransformBlendTable::
|
||||
recompute_modified(TransformBlendTable::CData *cdata) {
|
||||
recompute_modified(TransformBlendTable::CData *cdata, Thread *current_thread) {
|
||||
// Update the global_modified sequence number first, to prevent race
|
||||
// conditions.
|
||||
cdata->_global_modified = VertexTransform::get_global_modified();
|
||||
cdata->_global_modified = VertexTransform::get_global_modified(current_thread);
|
||||
|
||||
// Now get the local modified number.
|
||||
UpdateSeq seq;
|
||||
Blends::const_iterator bi;
|
||||
for (bi = _blends.begin(); bi != _blends.end(); ++bi) {
|
||||
seq = max(seq, (*bi).get_modified());
|
||||
seq = max(seq, (*bi).get_modified(current_thread));
|
||||
}
|
||||
|
||||
cdata->_modified = seq;
|
||||
|
|
@ -196,8 +196,8 @@ recompute_modified(TransformBlendTable::CData *cdata) {
|
|||
// recomputed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void TransformBlendTable::
|
||||
clear_modified() {
|
||||
CDWriter cdata(_cycler, true);
|
||||
clear_modified(Thread *current_thread) {
|
||||
CDWriter cdata(_cycler, true, current_thread);
|
||||
cdata->_global_modified = UpdateSeq();
|
||||
cdata->_modified = UpdateSeq();
|
||||
}
|
||||
|
|
@ -323,6 +323,7 @@ write_datagram(BamWriter *manager, Datagram &dg) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void TransformBlendTable::CData::
|
||||
fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
_modified = VertexTransform::get_next_modified();
|
||||
_global_modified = VertexTransform::get_global_modified();
|
||||
Thread *current_thread = Thread::get_current_thread();
|
||||
_modified = VertexTransform::get_next_modified(current_thread);
|
||||
_global_modified = VertexTransform::get_global_modified(current_thread);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ PUBLISHED:
|
|||
|
||||
INLINE int get_num_blends() const;
|
||||
INLINE const TransformBlend &get_blend(int n) const;
|
||||
INLINE UpdateSeq get_modified() const;
|
||||
INLINE UpdateSeq get_modified(Thread *current_thread) const;
|
||||
|
||||
void set_blend(int n, const TransformBlend &blend);
|
||||
void remove_blend(int n);
|
||||
|
|
@ -76,8 +76,8 @@ private:
|
|||
INLINE void consider_rebuild_index() const;
|
||||
void rebuild_index();
|
||||
|
||||
void recompute_modified(CData *cdata);
|
||||
void clear_modified();
|
||||
void recompute_modified(CData *cdata, Thread *current_thread);
|
||||
void clear_modified(Thread *current_thread);
|
||||
|
||||
private:
|
||||
// We don't bother with registering the table, or protecting its
|
||||
|
|
|
|||
|
|
@ -93,8 +93,8 @@ get_transform(int n) const {
|
|||
// changes.)
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE UpdateSeq TransformTable::
|
||||
get_modified() const {
|
||||
CDReader cdata(_cycler);
|
||||
get_modified(Thread *current_thread) const {
|
||||
CDReader cdata(_cycler, current_thread);
|
||||
return cdata->_modified;
|
||||
}
|
||||
|
||||
|
|
@ -105,8 +105,8 @@ get_modified() const {
|
|||
// reports that it has been modified.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void TransformTable::
|
||||
update_modified(UpdateSeq modified) {
|
||||
CDWriter cdata(_cycler, true);
|
||||
update_modified(UpdateSeq modified, Thread *current_thread) {
|
||||
CDWriter cdata(_cycler, true, current_thread);
|
||||
cdata->_modified = modified;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -282,5 +282,6 @@ write_datagram(BamWriter *manager, Datagram &dg) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void TransformTable::CData::
|
||||
fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
_modified = VertexTransform::get_next_modified();
|
||||
Thread *current_thread = Thread::get_current_thread();
|
||||
_modified = VertexTransform::get_next_modified(current_thread);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ PUBLISHED:
|
|||
|
||||
INLINE int get_num_transforms() const;
|
||||
INLINE const VertexTransform *get_transform(int n) const;
|
||||
INLINE UpdateSeq get_modified() const;
|
||||
INLINE UpdateSeq get_modified(Thread *current_thread) const;
|
||||
|
||||
void set_transform(int n, const VertexTransform *transform);
|
||||
void remove_transform(int n);
|
||||
|
|
@ -66,7 +66,7 @@ PUBLISHED:
|
|||
private:
|
||||
void do_register();
|
||||
void do_unregister();
|
||||
INLINE void update_modified(UpdateSeq modified);
|
||||
INLINE void update_modified(UpdateSeq modified, Thread *current_thread);
|
||||
|
||||
private:
|
||||
bool _is_registered;
|
||||
|
|
|
|||
|
|
@ -24,9 +24,10 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void UserVertexSlider::
|
||||
set_slider(float slider) {
|
||||
CDWriter cdata(_cycler, true);
|
||||
Thread *current_thread = Thread::get_current_thread();
|
||||
CDWriter cdata(_cycler, true, current_thread);
|
||||
cdata->_slider = slider;
|
||||
mark_modified();
|
||||
mark_modified(current_thread);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -35,9 +35,10 @@ get_name() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void UserVertexTransform::
|
||||
set_matrix(const LMatrix4f &matrix) {
|
||||
CDWriter cdata(_cycler, true);
|
||||
Thread *current_thread = Thread::get_current_thread();
|
||||
CDWriter cdata(_cycler, true, current_thread);
|
||||
cdata->_matrix = matrix;
|
||||
mark_modified();
|
||||
mark_modified(current_thread);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -38,8 +38,8 @@ get_name() const {
|
|||
// get_slider() changes.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE UpdateSeq VertexSlider::
|
||||
get_modified() const {
|
||||
CDReader cdata(_cycler);
|
||||
get_modified(Thread *current_thread) const {
|
||||
CDReader cdata(_cycler, current_thread);
|
||||
return cdata->_modified;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -76,13 +76,13 @@ write(ostream &out, int indent_level) const {
|
|||
// be propagated through the system.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void VertexSlider::
|
||||
mark_modified() {
|
||||
CDWriter cdata(_cycler, true);
|
||||
cdata->_modified = VertexTransform::get_next_modified();
|
||||
mark_modified(Thread *current_thread) {
|
||||
CDWriter cdata(_cycler, true, current_thread);
|
||||
cdata->_modified = VertexTransform::get_next_modified(current_thread);
|
||||
|
||||
Tables::iterator ti;
|
||||
for (ti = _tables.begin(); ti != _tables.end(); ++ti) {
|
||||
(*ti)->update_modified(cdata->_modified);
|
||||
(*ti)->update_modified(cdata->_modified, current_thread);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -50,13 +50,13 @@ PUBLISHED:
|
|||
INLINE const InternalName *get_name() const;
|
||||
|
||||
virtual float get_slider() const=0;
|
||||
INLINE UpdateSeq get_modified() const;
|
||||
INLINE UpdateSeq get_modified(Thread *current_thread) const;
|
||||
|
||||
virtual void output(ostream &out) const;
|
||||
virtual void write(ostream &out, int indent_level) const;
|
||||
|
||||
protected:
|
||||
void mark_modified();
|
||||
void mark_modified(Thread *current_thread);
|
||||
|
||||
protected:
|
||||
CPT(InternalName) _name;
|
||||
|
|
|
|||
|
|
@ -25,8 +25,8 @@
|
|||
// get_matrix() changes.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE UpdateSeq VertexTransform::
|
||||
get_modified() const {
|
||||
CDReader cdata(_cycler);
|
||||
get_modified(Thread *current_thread) const {
|
||||
CDReader cdata(_cycler, current_thread);
|
||||
return cdata->_modified;
|
||||
}
|
||||
|
||||
|
|
@ -39,8 +39,8 @@ get_modified() const {
|
|||
// VertexTransforms have changed value recently.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE UpdateSeq VertexTransform::
|
||||
get_global_modified() {
|
||||
CDReader cdata(_global_cycler);
|
||||
get_global_modified(Thread *current_thread) {
|
||||
CDReader cdata(_global_cycler, current_thread);
|
||||
return cdata->_modified;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -139,10 +139,9 @@ write(ostream &out, int indent_level) const {
|
|||
// different space.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
UpdateSeq VertexTransform::
|
||||
get_next_modified() {
|
||||
get_next_modified(Thread *current_thread) {
|
||||
CDWriter cdatag(_global_cycler, true, current_thread);
|
||||
++_next_modified;
|
||||
|
||||
CDWriter cdatag(_global_cycler, true);
|
||||
cdatag->_modified = _next_modified;
|
||||
|
||||
return _next_modified;
|
||||
|
|
@ -157,13 +156,13 @@ get_next_modified() {
|
|||
// be propagated through the system.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void VertexTransform::
|
||||
mark_modified() {
|
||||
CDWriter cdata(_cycler, true);
|
||||
cdata->_modified = get_next_modified();
|
||||
mark_modified(Thread *current_thread) {
|
||||
CDWriter cdata(_cycler, true, current_thread);
|
||||
cdata->_modified = get_next_modified(current_thread);
|
||||
|
||||
Palettes::iterator pi;
|
||||
for (pi = _tables.begin(); pi != _tables.end(); ++pi) {
|
||||
(*pi)->update_modified(cdata->_modified);
|
||||
(*pi)->update_modified(cdata->_modified, current_thread);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -49,16 +49,16 @@ PUBLISHED:
|
|||
virtual void mult_matrix(LMatrix4f &result, const LMatrix4f &previous) const;
|
||||
virtual void accumulate_matrix(LMatrix4f &accum, float weight) const;
|
||||
|
||||
INLINE UpdateSeq get_modified() const;
|
||||
INLINE UpdateSeq get_modified(Thread *current_thread) const;
|
||||
|
||||
virtual void output(ostream &out) const;
|
||||
virtual void write(ostream &out, int indent_level) const;
|
||||
|
||||
static UpdateSeq get_next_modified();
|
||||
INLINE static UpdateSeq get_global_modified();
|
||||
static UpdateSeq get_next_modified(Thread *current_thread);
|
||||
INLINE static UpdateSeq get_global_modified(Thread *current_thread);
|
||||
|
||||
protected:
|
||||
void mark_modified();
|
||||
void mark_modified(Thread *current_thread);
|
||||
|
||||
private:
|
||||
typedef pset<TransformTable *> Palettes;
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#include "indent.h"
|
||||
#include "compareTo.h"
|
||||
#include "reMutexHolder.h"
|
||||
#include "mutexHolder.h"
|
||||
#include "thread.h"
|
||||
|
||||
ReMutex *RenderEffects::_states_lock = NULL;
|
||||
|
|
@ -44,7 +45,7 @@ TypeHandle RenderEffects::_type_handle;
|
|||
// spurious warning if all constructors are private.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
RenderEffects::
|
||||
RenderEffects() {
|
||||
RenderEffects() : _lock("RenderEffects") {
|
||||
if (_states == (States *)NULL) {
|
||||
init_states();
|
||||
}
|
||||
|
|
@ -608,6 +609,12 @@ return_new(RenderEffects *state) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void RenderEffects::
|
||||
determine_decal() {
|
||||
MutexHolder holder(_lock);
|
||||
if ((_flags & F_checked_decal) != 0) {
|
||||
// Someone else checked it first.
|
||||
return;
|
||||
}
|
||||
|
||||
const RenderEffect *effect = get_effect(DecalEffect::get_class_type());
|
||||
if (effect != (const RenderEffect *)NULL) {
|
||||
_flags |= F_has_decal;
|
||||
|
|
@ -622,6 +629,12 @@ determine_decal() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void RenderEffects::
|
||||
determine_show_bounds() {
|
||||
MutexHolder holder(_lock);
|
||||
if ((_flags & F_checked_show_bounds) != 0) {
|
||||
// Someone else checked it first.
|
||||
return;
|
||||
}
|
||||
|
||||
const RenderEffect *effect = get_effect(ShowBoundsEffect::get_class_type());
|
||||
if (effect != (const RenderEffect *)NULL) {
|
||||
_flags |= F_has_show_bounds;
|
||||
|
|
@ -640,6 +653,12 @@ determine_show_bounds() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void RenderEffects::
|
||||
determine_cull_callback() {
|
||||
MutexHolder holder(_lock);
|
||||
if ((_flags & F_checked_cull_callback) != 0) {
|
||||
// Someone else checked it first.
|
||||
return;
|
||||
}
|
||||
|
||||
_flags |= F_checked_cull_callback;
|
||||
|
||||
Effects::const_iterator ei;
|
||||
|
|
@ -658,6 +677,12 @@ determine_cull_callback() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void RenderEffects::
|
||||
determine_adjust_transform() {
|
||||
MutexHolder holder(_lock);
|
||||
if ((_flags & F_checked_adjust_transform) != 0) {
|
||||
// Someone else checked it first.
|
||||
return;
|
||||
}
|
||||
|
||||
_flags |= F_checked_adjust_transform;
|
||||
|
||||
Effects::const_iterator ei;
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#include "pointerTo.h"
|
||||
#include "ordered_vector.h"
|
||||
#include "reMutex.h"
|
||||
#include "pmutex.h"
|
||||
|
||||
class CullTraverser;
|
||||
class CullTraverserData;
|
||||
|
|
@ -164,6 +165,9 @@ private:
|
|||
};
|
||||
int _flags;
|
||||
|
||||
// This mutex protects _flags, and all of the above computed values.
|
||||
Mutex _lock;
|
||||
|
||||
|
||||
public:
|
||||
static void register_with_read_factory();
|
||||
|
|
|
|||
|
|
@ -389,6 +389,28 @@ get_shader() const {
|
|||
return _shader;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RenderState::determine_bin
|
||||
// Access: Private
|
||||
// Description: This is the private implementation of get_bin().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void RenderState::
|
||||
determine_bin() {
|
||||
MutexHolder holder(_lock);
|
||||
do_determine_bin();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RenderState::determine_transparency
|
||||
// Access: Private
|
||||
// Description: This is the private implementation of get_transparency().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void RenderState::
|
||||
determine_transparency() {
|
||||
MutexHolder holder(_lock);
|
||||
do_determine_transparency();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RenderState::set_destructing
|
||||
// Access: Private
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@
|
|||
#include "indent.h"
|
||||
#include "compareTo.h"
|
||||
#include "reMutexHolder.h"
|
||||
#include "mutexHolder.h"
|
||||
#include "thread.h"
|
||||
#include "attribSlots.h"
|
||||
|
||||
|
|
@ -61,7 +62,7 @@ TypeHandle RenderState::_type_handle;
|
|||
// spurious warning if all constructors are private.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
RenderState::
|
||||
RenderState() {
|
||||
RenderState() : _lock("RenderState") {
|
||||
if (_states == (States *)NULL) {
|
||||
init_states();
|
||||
}
|
||||
|
|
@ -1444,13 +1445,22 @@ remove_cache_pointers() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void RenderState::
|
||||
determine_bin_index() {
|
||||
MutexHolder holder(_lock);
|
||||
if ((_flags & F_checked_bin_index) != 0) {
|
||||
// Someone else checked it first.
|
||||
return;
|
||||
}
|
||||
|
||||
string bin_name;
|
||||
_draw_order = 0;
|
||||
|
||||
const CullBinAttrib *bin_attrib = get_bin();
|
||||
if (bin_attrib != (const CullBinAttrib *)NULL) {
|
||||
bin_name = bin_attrib->get_bin_name();
|
||||
_draw_order = bin_attrib->get_draw_order();
|
||||
if ((_flags & F_checked_bin) == 0) {
|
||||
do_determine_bin();
|
||||
}
|
||||
|
||||
if (_bin != (const CullBinAttrib *)NULL) {
|
||||
bin_name = _bin->get_bin_name();
|
||||
_draw_order = _bin->get_draw_order();
|
||||
}
|
||||
|
||||
if (bin_name.empty()) {
|
||||
|
|
@ -1458,9 +1468,13 @@ determine_bin_index() {
|
|||
// either opaque or transparent, based on the transparency
|
||||
// setting.
|
||||
bin_name = "opaque";
|
||||
const TransparencyAttrib *trans = get_transparency();
|
||||
if (trans != (const TransparencyAttrib *)NULL) {
|
||||
switch (trans->get_mode()) {
|
||||
|
||||
if ((_flags & F_checked_transparency) == 0) {
|
||||
do_determine_transparency();
|
||||
}
|
||||
|
||||
if (_transparency != (const TransparencyAttrib *)NULL) {
|
||||
switch (_transparency->get_mode()) {
|
||||
case TransparencyAttrib::M_alpha:
|
||||
case TransparencyAttrib::M_dual:
|
||||
// These transparency modes require special back-to-front sorting.
|
||||
|
|
@ -1490,6 +1504,12 @@ determine_bin_index() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void RenderState::
|
||||
determine_fog() {
|
||||
MutexHolder holder(_lock);
|
||||
if ((_flags & F_checked_fog) != 0) {
|
||||
// Someone else checked it first.
|
||||
return;
|
||||
}
|
||||
|
||||
const RenderAttrib *attrib = get_attrib(FogAttrib::get_class_type());
|
||||
_fog = (const FogAttrib *)NULL;
|
||||
if (attrib != (const RenderAttrib *)NULL) {
|
||||
|
|
@ -1499,12 +1519,18 @@ determine_fog() {
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RenderState::determine_bin
|
||||
// Function: RenderState::do_determine_bin
|
||||
// Access: Private
|
||||
// Description: This is the private implementation of get_bin().
|
||||
// Description: This is the implementation of determine_bin(); it
|
||||
// assumes the lock is already held.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void RenderState::
|
||||
determine_bin() {
|
||||
do_determine_bin() {
|
||||
if ((_flags & F_checked_bin) != 0) {
|
||||
// Someone else checked it first.
|
||||
return;
|
||||
}
|
||||
|
||||
const RenderAttrib *attrib = get_attrib(CullBinAttrib::get_class_type());
|
||||
_bin = (const CullBinAttrib *)NULL;
|
||||
if (attrib != (const RenderAttrib *)NULL) {
|
||||
|
|
@ -1514,12 +1540,19 @@ determine_bin() {
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RenderState::determine_transparency
|
||||
// Function: RenderState::do_determine_transparency
|
||||
// Access: Private
|
||||
// Description: This is the private implementation of get_transparency().
|
||||
// Description: This is the implementation of
|
||||
// determine_transparency(); it assumes the lock is
|
||||
// already held.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void RenderState::
|
||||
determine_transparency() {
|
||||
do_determine_transparency() {
|
||||
if ((_flags & F_checked_transparency) != 0) {
|
||||
// Someone else checked it first.
|
||||
return;
|
||||
}
|
||||
|
||||
const RenderAttrib *attrib =
|
||||
get_attrib(TransparencyAttrib::get_class_type());
|
||||
_transparency = (const TransparencyAttrib *)NULL;
|
||||
|
|
@ -1536,6 +1569,12 @@ determine_transparency() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void RenderState::
|
||||
determine_color() {
|
||||
MutexHolder holder(_lock);
|
||||
if ((_flags & F_checked_color) != 0) {
|
||||
// Someone else checked it first.
|
||||
return;
|
||||
}
|
||||
|
||||
const RenderAttrib *attrib = get_attrib(ColorAttrib::get_class_type());
|
||||
_color = (const ColorAttrib *)NULL;
|
||||
if (attrib != (const RenderAttrib *)NULL) {
|
||||
|
|
@ -1551,6 +1590,12 @@ determine_color() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void RenderState::
|
||||
determine_color_scale() {
|
||||
MutexHolder holder(_lock);
|
||||
if ((_flags & F_checked_color_scale) != 0) {
|
||||
// Someone else checked it first.
|
||||
return;
|
||||
}
|
||||
|
||||
const RenderAttrib *attrib = get_attrib(ColorScaleAttrib::get_class_type());
|
||||
_color_scale = (const ColorScaleAttrib *)NULL;
|
||||
if (attrib != (const RenderAttrib *)NULL) {
|
||||
|
|
@ -1566,6 +1611,12 @@ determine_color_scale() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void RenderState::
|
||||
determine_texture() {
|
||||
MutexHolder holder(_lock);
|
||||
if ((_flags & F_checked_texture) != 0) {
|
||||
// Someone else checked it first.
|
||||
return;
|
||||
}
|
||||
|
||||
const RenderAttrib *attrib = get_attrib(TextureAttrib::get_class_type());
|
||||
_texture = (const TextureAttrib *)NULL;
|
||||
if (attrib != (const RenderAttrib *)NULL) {
|
||||
|
|
@ -1581,6 +1632,12 @@ determine_texture() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void RenderState::
|
||||
determine_tex_gen() {
|
||||
MutexHolder holder(_lock);
|
||||
if ((_flags & F_checked_tex_gen) != 0) {
|
||||
// Someone else checked it first.
|
||||
return;
|
||||
}
|
||||
|
||||
const RenderAttrib *attrib = get_attrib(TexGenAttrib::get_class_type());
|
||||
_tex_gen = (const TexGenAttrib *)NULL;
|
||||
if (attrib != (const RenderAttrib *)NULL) {
|
||||
|
|
@ -1596,6 +1653,12 @@ determine_tex_gen() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void RenderState::
|
||||
determine_tex_matrix() {
|
||||
MutexHolder holder(_lock);
|
||||
if ((_flags & F_checked_tex_matrix) != 0) {
|
||||
// Someone else checked it first.
|
||||
return;
|
||||
}
|
||||
|
||||
const RenderAttrib *attrib = get_attrib(TexMatrixAttrib::get_class_type());
|
||||
_tex_matrix = (const TexMatrixAttrib *)NULL;
|
||||
if (attrib != (const RenderAttrib *)NULL) {
|
||||
|
|
@ -1611,6 +1674,12 @@ determine_tex_matrix() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void RenderState::
|
||||
determine_render_mode() {
|
||||
MutexHolder holder(_lock);
|
||||
if ((_flags & F_checked_render_mode) != 0) {
|
||||
// Someone else checked it first.
|
||||
return;
|
||||
}
|
||||
|
||||
const RenderAttrib *attrib = get_attrib(RenderModeAttrib::get_class_type());
|
||||
_render_mode = (const RenderModeAttrib *)NULL;
|
||||
if (attrib != (const RenderAttrib *)NULL) {
|
||||
|
|
@ -1626,6 +1695,12 @@ determine_render_mode() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void RenderState::
|
||||
determine_clip_plane() {
|
||||
MutexHolder holder(_lock);
|
||||
if ((_flags & F_checked_clip_plane) != 0) {
|
||||
// Someone else checked it first.
|
||||
return;
|
||||
}
|
||||
|
||||
const RenderAttrib *attrib = get_attrib(ClipPlaneAttrib::get_class_type());
|
||||
_clip_plane = (const ClipPlaneAttrib *)NULL;
|
||||
if (attrib != (const RenderAttrib *)NULL) {
|
||||
|
|
@ -1641,6 +1716,12 @@ determine_clip_plane() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void RenderState::
|
||||
determine_shader() {
|
||||
MutexHolder holder(_lock);
|
||||
if ((_flags & F_checked_shader) != 0) {
|
||||
// Someone else checked it first.
|
||||
return;
|
||||
}
|
||||
|
||||
const RenderAttrib *attrib = get_attrib(ShaderAttrib::get_class_type());
|
||||
_shader = (const ShaderAttrib *)NULL;
|
||||
if (attrib != (const RenderAttrib *)NULL) {
|
||||
|
|
@ -1656,6 +1737,12 @@ determine_shader() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void RenderState::
|
||||
determine_cull_callback() {
|
||||
MutexHolder holder(_lock);
|
||||
if ((_flags & F_checked_cull_callback) != 0) {
|
||||
// Someone else checked it first.
|
||||
return;
|
||||
}
|
||||
|
||||
Attributes::const_iterator ai;
|
||||
for (ai = _attributes.begin(); ai != _attributes.end(); ++ai) {
|
||||
const Attribute &attrib = *ai;
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
#include "weakPointerTo.h"
|
||||
#include "shaderExpansion.h"
|
||||
#include "reMutex.h"
|
||||
#include "pmutex.h"
|
||||
#include "deletedChain.h"
|
||||
|
||||
class GraphicsStateGuardianBase;
|
||||
|
|
@ -182,8 +183,10 @@ private:
|
|||
|
||||
void determine_bin_index();
|
||||
void determine_fog();
|
||||
void determine_bin();
|
||||
void determine_transparency();
|
||||
INLINE void determine_bin();
|
||||
void do_determine_bin();
|
||||
INLINE void determine_transparency();
|
||||
void do_determine_transparency();
|
||||
void determine_color();
|
||||
void determine_color_scale();
|
||||
void determine_texture();
|
||||
|
|
@ -324,6 +327,9 @@ private:
|
|||
};
|
||||
unsigned short _flags;
|
||||
|
||||
// This mutex protects _flags, and all of the above computed values.
|
||||
Mutex _lock;
|
||||
|
||||
public:
|
||||
static void register_with_read_factory();
|
||||
virtual void write_datagram(BamWriter *manager, Datagram &dg);
|
||||
|
|
|
|||
|
|
@ -824,6 +824,40 @@ check_mat() const {
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TransformState::calc_components
|
||||
// Access: Private
|
||||
// Description: Derives the components from the matrix, if possible.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void TransformState::
|
||||
calc_components() {
|
||||
MutexHolder holder(_lock);
|
||||
do_calc_components();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TransformState::calc_hpr
|
||||
// Access: Private
|
||||
// Description: Derives the hpr, from the matrix if necessary, or
|
||||
// from the quat.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void TransformState::
|
||||
calc_hpr() {
|
||||
MutexHolder holder(_lock);
|
||||
do_calc_hpr();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TransformState::calc_mat
|
||||
// Access: Private
|
||||
// Description: Computes the matrix from the components.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void TransformState::
|
||||
calc_mat() {
|
||||
MutexHolder holder(_lock);
|
||||
do_calc_mat();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TransformState::check_uniform_scale
|
||||
// Access: Private
|
||||
|
|
@ -831,6 +865,9 @@ check_mat() const {
|
|||
// F_has_components) is set, this checks for a
|
||||
// identity and/or uniform scale (as well as a non-zero
|
||||
// shear) and sets the bit appropriately.
|
||||
//
|
||||
// It does not matter whether the lock is or is not held
|
||||
// before calling this method.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void TransformState::
|
||||
check_uniform_scale() {
|
||||
|
|
@ -854,6 +891,9 @@ check_uniform_scale() {
|
|||
// F_has_components) is set, for a known 2-d scale, this
|
||||
// checks for a identity and/or uniform scale (as well
|
||||
// as a non-zero shear) and sets the bit appropriately.
|
||||
//
|
||||
// It does not matter whether the lock is or is not held
|
||||
// before calling this method.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void TransformState::
|
||||
check_uniform_scale2d() {
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
#include "pStatTimer.h"
|
||||
#include "config_pgraph.h"
|
||||
#include "reMutexHolder.h"
|
||||
#include "mutexHolder.h"
|
||||
#include "thread.h"
|
||||
|
||||
ReMutex *TransformState::_states_lock = NULL;
|
||||
|
|
@ -48,7 +49,7 @@ TypeHandle TransformState::_type_handle;
|
|||
// spurious warning if all constructors are private.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
TransformState::
|
||||
TransformState() {
|
||||
TransformState() : _lock("TransformState") {
|
||||
if (_states == (States *)NULL) {
|
||||
init_states();
|
||||
}
|
||||
|
|
@ -1743,6 +1744,11 @@ remove_cache_pointers() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void TransformState::
|
||||
calc_singular() {
|
||||
MutexHolder holder(_lock);
|
||||
if ((_flags & F_singular_known) != 0) {
|
||||
// Someone else computed it first.
|
||||
return;
|
||||
}
|
||||
nassertv((_flags & F_is_invalid) == 0);
|
||||
|
||||
// We determine if a matrix is singular by attempting to invert it
|
||||
|
|
@ -1753,7 +1759,11 @@ calc_singular() {
|
|||
// This should be NULL if no one has called calc_singular() yet.
|
||||
nassertv(_inv_mat == (LMatrix4f *)NULL);
|
||||
_inv_mat = new LMatrix4f;
|
||||
bool inverted = _inv_mat->invert_from(get_mat());
|
||||
|
||||
if ((_flags & F_mat_known) == 0) {
|
||||
do_calc_mat();
|
||||
}
|
||||
bool inverted = _inv_mat->invert_from(_mat);
|
||||
|
||||
if (!inverted) {
|
||||
_flags |= F_is_singular;
|
||||
|
|
@ -1764,12 +1774,18 @@ calc_singular() {
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TransformState::calc_components
|
||||
// Function: TransformState::do_calc_components
|
||||
// Access: Private
|
||||
// Description: Derives the components from the matrix, if possible.
|
||||
// Description: This is the implementation of calc_components(); it
|
||||
// assumes the lock is already held.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void TransformState::
|
||||
calc_components() {
|
||||
do_calc_components() {
|
||||
if ((_flags & F_components_known) != 0) {
|
||||
// Someone else computed it first.
|
||||
return;
|
||||
}
|
||||
|
||||
nassertv((_flags & F_is_invalid) == 0);
|
||||
if ((_flags & F_is_identity) != 0) {
|
||||
_scale.set(1.0f, 1.0f, 1.0f);
|
||||
|
|
@ -1784,8 +1800,10 @@ calc_components() {
|
|||
// other explanation is that we were constructed via a matrix.
|
||||
nassertv((_flags & F_mat_known) != 0);
|
||||
|
||||
const LMatrix4f &mat = get_mat();
|
||||
bool possible = decompose_matrix(mat, _scale, _shear, _hpr, _pos);
|
||||
if ((_flags & F_mat_known) == 0) {
|
||||
do_calc_mat();
|
||||
}
|
||||
bool possible = decompose_matrix(_mat, _scale, _shear, _hpr, _pos);
|
||||
if (!possible) {
|
||||
// Some matrices can't be decomposed into scale, hpr, pos. In
|
||||
// this case, we now know that we cannot compute the components;
|
||||
|
|
@ -1799,20 +1817,27 @@ calc_components() {
|
|||
}
|
||||
|
||||
// However, we can always get at least the pos.
|
||||
mat.get_row3(_pos, 3);
|
||||
_mat.get_row3(_pos, 3);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TransformState::calc_hpr
|
||||
// Function: TransformState::do_calc_hpr
|
||||
// Access: Private
|
||||
// Description: Derives the hpr, from the matrix if necessary, or
|
||||
// from the quat.
|
||||
// Description: This is the implementation of calc_hpr(); it
|
||||
// assumes the lock is already held.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void TransformState::
|
||||
calc_hpr() {
|
||||
do_calc_hpr() {
|
||||
if ((_flags & F_hpr_known) != 0) {
|
||||
// Someone else computed it first.
|
||||
return;
|
||||
}
|
||||
|
||||
nassertv((_flags & F_is_invalid) == 0);
|
||||
check_components();
|
||||
if ((_flags & F_components_known) == 0) {
|
||||
do_calc_components();
|
||||
}
|
||||
if ((_flags & F_hpr_known) == 0) {
|
||||
// If we don't know the hpr yet, we must have been given a quat.
|
||||
// Decompose it.
|
||||
|
|
@ -1829,8 +1854,16 @@ calc_hpr() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void TransformState::
|
||||
calc_quat() {
|
||||
MutexHolder holder(_lock);
|
||||
if ((_flags & F_quat_known) != 0) {
|
||||
// Someone else computed it first.
|
||||
return;
|
||||
}
|
||||
|
||||
nassertv((_flags & F_is_invalid) == 0);
|
||||
check_components();
|
||||
if ((_flags & F_components_known) == 0) {
|
||||
do_calc_components();
|
||||
}
|
||||
if ((_flags & F_quat_known) == 0) {
|
||||
// If we don't know the quat yet, we must have been given a hpr.
|
||||
// Decompose it.
|
||||
|
|
@ -1841,12 +1874,18 @@ calc_quat() {
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TransformState::calc_mat
|
||||
// Function: TransformState::do_calc_mat
|
||||
// Access: Private
|
||||
// Description: Computes the matrix from the components.
|
||||
// Description: This is the implementation of calc_mat(); it
|
||||
// assumes the lock is already held.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void TransformState::
|
||||
calc_mat() {
|
||||
do_calc_mat() {
|
||||
if ((_flags & F_mat_known) != 0) {
|
||||
// Someone else computed it first.
|
||||
return;
|
||||
}
|
||||
|
||||
nassertv((_flags & F_is_invalid) == 0);
|
||||
if ((_flags & F_is_identity) != 0) {
|
||||
_mat = LMatrix4f::ident_mat();
|
||||
|
|
@ -1855,6 +1894,10 @@ calc_mat() {
|
|||
// If we don't have a matrix and we're not identity, the only
|
||||
// other explanation is that we were constructed via components.
|
||||
nassertv((_flags & F_components_known) != 0);
|
||||
if ((_flags & F_hpr_known) == 0) {
|
||||
do_calc_hpr();
|
||||
}
|
||||
|
||||
compose_matrix(_mat, _scale, _shear, get_hpr(), _pos);
|
||||
}
|
||||
_flags |= F_mat_known;
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
#include "pStatCollector.h"
|
||||
#include "geomEnums.h"
|
||||
#include "reMutex.h"
|
||||
#include "pmutex.h"
|
||||
#include "config_pgraph.h"
|
||||
#include "deletedChain.h"
|
||||
|
||||
|
|
@ -271,10 +272,13 @@ private:
|
|||
INLINE void check_quat() const;
|
||||
INLINE void check_mat() const;
|
||||
void calc_singular();
|
||||
void calc_components();
|
||||
void calc_hpr();
|
||||
INLINE void calc_components();
|
||||
void do_calc_components();
|
||||
INLINE void calc_hpr();
|
||||
void do_calc_hpr();
|
||||
void calc_quat();
|
||||
void calc_mat();
|
||||
INLINE void calc_mat();
|
||||
void do_calc_mat();
|
||||
|
||||
INLINE void check_uniform_scale();
|
||||
INLINE void check_uniform_scale2d();
|
||||
|
|
@ -312,6 +316,9 @@ private:
|
|||
|
||||
unsigned int _flags;
|
||||
|
||||
// This mutex protects _flags, and all of the above computed values.
|
||||
Mutex _lock;
|
||||
|
||||
public:
|
||||
static void register_with_read_factory();
|
||||
virtual void write_datagram(BamWriter *manager, Datagram &dg);
|
||||
|
|
|
|||
Loading…
Reference in New Issue