diff --git a/direct/src/interval/FunctionInterval.py b/direct/src/interval/FunctionInterval.py index 8f84ca9df8..db626c404e 100644 --- a/direct/src/interval/FunctionInterval.py +++ b/direct/src/interval/FunctionInterval.py @@ -77,7 +77,10 @@ class FunctionInterval(Interval.Interval): @staticmethod def makeUniqueName(func, suffix = ''): - name = 'Func-%s-%d' % (getattr(func, '__name__', str(func)), FunctionInterval.functionIntervalNum) + func_name = getattr(func, '__name__', None) + if func_name is None: + func_name = str(func) + name = 'Func-%s-%d' % (func_name, FunctionInterval.functionIntervalNum) FunctionInterval.functionIntervalNum += 1 if suffix: name = '%s-%s' % (name, str(suffix)) diff --git a/dtool/src/dtoolbase/dtoolbase.h b/dtool/src/dtoolbase/dtoolbase.h index f21e653695..2f8e7ca05d 100644 --- a/dtool/src/dtoolbase/dtoolbase.h +++ b/dtool/src/dtoolbase/dtoolbase.h @@ -63,8 +63,10 @@ /* Windows likes to define min() and max() macros, which will conflict with std::min() and std::max() respectively, unless we do this: */ #ifdef WIN32 +#ifndef NOMINMAX #define NOMINMAX #endif +#endif #ifndef __has_builtin #define __has_builtin(x) 0 diff --git a/dtool/src/interrogatedb/py_panda.cxx b/dtool/src/interrogatedb/py_panda.cxx index b2fa4ba3a1..0d99d85ea5 100644 --- a/dtool/src/interrogatedb/py_panda.cxx +++ b/dtool/src/interrogatedb/py_panda.cxx @@ -720,10 +720,13 @@ PyObject *Dtool_PyModuleInitHelper(LibraryDef *defs[], const char *modulename) { if (main_module == NULL) { interrogatedb_cat.warning() << "Unable to import __main__\n"; } - + // Extract the __file__ attribute, if present. Filename main_dir; - PyObject *file_attr = PyObject_GetAttrString(main_module, "__file__"); + PyObject *file_attr = nullptr; + if (main_module != nullptr) { + file_attr = PyObject_GetAttrString(main_module, "__file__"); + } if (file_attr == nullptr) { // Must be running in the interactive interpreter. Use the CWD. main_dir = ExecutionEnvironment::get_cwd(); diff --git a/makepanda/makepanda.py b/makepanda/makepanda.py index 8259c2af82..bcf0caefac 100755 --- a/makepanda/makepanda.py +++ b/makepanda/makepanda.py @@ -3255,10 +3255,10 @@ CopyAllHeaders('panda/src/movies') CopyAllHeaders('panda/src/pgraphnodes') CopyAllHeaders('panda/src/pgraph') CopyAllHeaders('panda/src/cull') +CopyAllHeaders('panda/src/display') CopyAllHeaders('panda/src/chan') CopyAllHeaders('panda/src/char') CopyAllHeaders('panda/src/dgraph') -CopyAllHeaders('panda/src/display') CopyAllHeaders('panda/src/device') CopyAllHeaders('panda/src/pnmtext') CopyAllHeaders('panda/src/text') @@ -3971,6 +3971,31 @@ if (not RUNTIME): TargetAdd('libp3cull.in', opts=['IMOD:panda3d.core', 'ILIB:libp3cull', 'SRCDIR:panda/src/cull']) TargetAdd('libp3cull_igate.obj', input='libp3cull.in', opts=["DEPENDENCYONLY"]) +# +# DIRECTORY: panda/src/display/ +# + +if (not RUNTIME): + OPTS=['DIR:panda/src/display', 'BUILDING:PANDA'] + TargetAdd('p3display_graphicsStateGuardian.obj', opts=OPTS, input='graphicsStateGuardian.cxx') + TargetAdd('p3display_composite1.obj', opts=OPTS, input='p3display_composite1.cxx') + TargetAdd('p3display_composite2.obj', opts=OPTS, input='p3display_composite2.cxx') + + OPTS=['DIR:panda/src/display', 'PYTHON'] + IGATEFILES=GetDirectoryContents('panda/src/display', ["*.h", "*_composite*.cxx"]) + IGATEFILES.remove("renderBuffer.h") + TargetAdd('libp3display.in', opts=OPTS, input=IGATEFILES) + TargetAdd('libp3display.in', opts=['IMOD:panda3d.core', 'ILIB:libp3display', 'SRCDIR:panda/src/display']) + TargetAdd('libp3display_igate.obj', input='libp3display.in', opts=["DEPENDENCYONLY"]) + TargetAdd('p3display_graphicsStateGuardian_ext.obj', opts=OPTS, input='graphicsStateGuardian_ext.cxx') + TargetAdd('p3display_graphicsWindow_ext.obj', opts=OPTS, input='graphicsWindow_ext.cxx') + TargetAdd('p3display_pythonGraphicsWindowProc.obj', opts=OPTS, input='pythonGraphicsWindowProc.cxx') + + if RTDIST and GetTarget() == 'darwin': + OPTS=['DIR:panda/src/display'] + TargetAdd('subprocessWindowBuffer.obj', opts=OPTS, input='subprocessWindowBuffer.cxx') + TargetAdd('libp3subprocbuffer.ilb', input='subprocessWindowBuffer.obj') + # # DIRECTORY: panda/src/chan/ # @@ -4018,30 +4043,6 @@ if (not RUNTIME): TargetAdd('libp3dgraph.in', opts=['IMOD:panda3d.core', 'ILIB:libp3dgraph', 'SRCDIR:panda/src/dgraph']) TargetAdd('libp3dgraph_igate.obj', input='libp3dgraph.in', opts=["DEPENDENCYONLY"]) -# -# DIRECTORY: panda/src/display/ -# - -if (not RUNTIME): - OPTS=['DIR:panda/src/display', 'BUILDING:PANDA'] - TargetAdd('p3display_composite1.obj', opts=OPTS, input='p3display_composite1.cxx') - TargetAdd('p3display_composite2.obj', opts=OPTS, input='p3display_composite2.cxx') - - OPTS=['DIR:panda/src/display', 'PYTHON'] - IGATEFILES=GetDirectoryContents('panda/src/display', ["*.h", "*_composite*.cxx"]) - IGATEFILES.remove("renderBuffer.h") - TargetAdd('libp3display.in', opts=OPTS, input=IGATEFILES) - TargetAdd('libp3display.in', opts=['IMOD:panda3d.core', 'ILIB:libp3display', 'SRCDIR:panda/src/display']) - TargetAdd('libp3display_igate.obj', input='libp3display.in', opts=["DEPENDENCYONLY"]) - TargetAdd('p3display_graphicsStateGuardian_ext.obj', opts=OPTS, input='graphicsStateGuardian_ext.cxx') - TargetAdd('p3display_graphicsWindow_ext.obj', opts=OPTS, input='graphicsWindow_ext.cxx') - TargetAdd('p3display_pythonGraphicsWindowProc.obj', opts=OPTS, input='pythonGraphicsWindowProc.cxx') - - if RTDIST and GetTarget() == 'darwin': - OPTS=['DIR:panda/src/display'] - TargetAdd('subprocessWindowBuffer.obj', opts=OPTS, input='subprocessWindowBuffer.cxx') - TargetAdd('libp3subprocbuffer.ilb', input='subprocessWindowBuffer.obj') - # # DIRECTORY: panda/src/device/ # @@ -4263,6 +4264,7 @@ if (not RUNTIME): TargetAdd('libpanda.dll', input='p3device_composite2.obj') TargetAdd('libpanda.dll', input='p3dgraph_composite1.obj') TargetAdd('libpanda.dll', input='p3dgraph_composite2.obj') + TargetAdd('libpanda.dll', input='p3display_graphicsStateGuardian.obj') TargetAdd('libpanda.dll', input='p3display_composite1.obj') TargetAdd('libpanda.dll', input='p3display_composite2.obj') TargetAdd('libpanda.dll', input='p3pipeline_composite1.obj') diff --git a/panda/src/chan/animControl.cxx b/panda/src/chan/animControl.cxx index aa47ea7486..df7fb26498 100644 --- a/panda/src/chan/animControl.cxx +++ b/panda/src/chan/animControl.cxx @@ -32,14 +32,14 @@ AnimControl(const std::string &name, PartBundle *part, Namable(name), _pending_lock(name), _pending_cvar(_pending_lock), - _bound_joints(BitArray::all_on()) + _bound_joints(BitArray::all_on()), + _part(part) { #ifdef DO_MEMORY_USAGE MemoryUsage::update_type(this, get_class_type()); #endif _pending = true; - _part = part; _anim = nullptr; _channel_index = -1; set_frame_rate(frame_rate); diff --git a/panda/src/chan/animControl.h b/panda/src/chan/animControl.h index bee9f7223b..d52b2e4835 100644 --- a/panda/src/chan/animControl.h +++ b/panda/src/chan/animControl.h @@ -39,6 +39,8 @@ class EXPCL_PANDA_CHAN AnimControl : public TypedReferenceCount, public AnimInte public: AnimControl(const std::string &name, PartBundle *part, double frame_rate, int num_frames); + AnimControl(const AnimControl ©) = delete; + void setup_anim(PartBundle *part, AnimBundle *anim, int channel_index, const BitArray &bound_joints); void set_bound_joints(const BitArray &bound_joints); @@ -82,7 +84,7 @@ private: // This is a PT(PartGroup) instead of a PT(PartBundle), just because we // can't include partBundle.h for circular reasons. But it actually keeps a // pointer to a PartBundle. - PT(PartGroup) _part; + const PT(PartGroup) _part; PT(AnimBundle) _anim; int _channel_index; diff --git a/panda/src/chan/partBundle.cxx b/panda/src/chan/partBundle.cxx index 966987995a..9d960f3e7d 100644 --- a/panda/src/chan/partBundle.cxx +++ b/panda/src/chan/partBundle.cxx @@ -556,8 +556,15 @@ control_removed(AnimControl *control) { CDStageWriter cdata(_cycler, pipeline_stage); ChannelBlend::iterator cbi = cdata->_blend.find(control); if (cbi != cdata->_blend.end()) { + cdata->_net_blend -= cbi->second; cdata->_blend.erase(cbi); cdata->_anim_changed = true; + + // We need to make sure that any _effective_channel pointers that point + // to this control are cleared. + if (pipeline_stage == 0) { + determine_effective_channels(cdata); + } } } CLOSE_ITERATE_ALL_STAGES(_cycler); diff --git a/panda/src/display/graphicsPipeSelection.cxx b/panda/src/display/graphicsPipeSelection.cxx index 9c4f52ff63..58866efef6 100644 --- a/panda/src/display/graphicsPipeSelection.cxx +++ b/panda/src/display/graphicsPipeSelection.cxx @@ -18,7 +18,6 @@ #include "load_dso.h" #include "config_display.h" #include "typeRegistry.h" -#include "pset.h" #include "config_putil.h" #include @@ -61,8 +60,8 @@ GraphicsPipeSelection() : _lock("GraphicsPipeSelection") { // Also get the set of modules named in the various aux-display Config // variables. We'll want to know this when we call load_modules() later. - int num_aux = aux_display.get_num_unique_values(); - for (int i = 0; i < num_aux; i++) { + size_t num_aux = aux_display.get_num_unique_values(); + for (size_t i = 0; i < num_aux; ++i) { string name = aux_display.get_unique_value(i); if (name != _default_display_module) { _display_modules.push_back(name); @@ -124,9 +123,7 @@ print_pipe_types() const { LightMutexHolder holder(_lock); nout << "Known pipe types:" << std::endl; - PipeTypes::const_iterator pi; - for (pi = _pipe_types.begin(); pi != _pipe_types.end(); ++pi) { - const PipeType &pipe_type = (*pi); + for (const PipeType &pipe_type : _pipe_types) { nout << " " << pipe_type._type << "\n"; } if (_display_modules.empty()) { @@ -187,11 +184,9 @@ make_pipe(const string &type_name, const string &module_name) { PT(GraphicsPipe) GraphicsPipeSelection:: make_pipe(TypeHandle type) { LightMutexHolder holder(_lock); - PipeTypes::const_iterator ti; // First, look for an exact match of the requested type. - for (ti = _pipe_types.begin(); ti != _pipe_types.end(); ++ti) { - const PipeType &ptype = (*ti); + for (const PipeType &ptype : _pipe_types) { if (ptype._type == type) { // Here's an exact match. PT(GraphicsPipe) pipe = (*ptype._constructor)(); @@ -202,8 +197,7 @@ make_pipe(TypeHandle type) { } // Now look for a more-specific type. - for (ti = _pipe_types.begin(); ti != _pipe_types.end(); ++ti) { - const PipeType &ptype = (*ti); + for (const PipeType &ptype : _pipe_types) { if (ptype._type.is_derived_from(type)) { // Here's an approximate match. PT(GraphicsPipe) pipe = (*ptype._constructor)(); @@ -215,8 +209,7 @@ make_pipe(TypeHandle type) { // Couldn't find any match; load the default module and try again. load_default_module(); - for (ti = _pipe_types.begin(); ti != _pipe_types.end(); ++ti) { - const PipeType &ptype = (*ti); + for (const PipeType &ptype : _pipe_types) { if (ptype._type.is_derived_from(type)) { // Here's an approximate match. PT(GraphicsPipe) pipe = (*ptype._constructor)(); @@ -260,13 +253,11 @@ make_default_pipe() { load_default_module(); LightMutexHolder holder(_lock); - PipeTypes::const_iterator ti; if (!_default_pipe_name.empty()) { // First, look for an exact match of the default type name from the // Configrc file (excepting case and hyphenunderscore). - for (ti = _pipe_types.begin(); ti != _pipe_types.end(); ++ti) { - const PipeType &ptype = (*ti); + for (const PipeType &ptype : _pipe_types) { if (cmp_nocase_uh(ptype._type.get_name(), _default_pipe_name) == 0) { // Here's an exact match. PT(GraphicsPipe) pipe = (*ptype._constructor)(); @@ -278,8 +269,7 @@ make_default_pipe() { // No match; look for a substring match. string preferred_name = downcase(_default_pipe_name); - for (ti = _pipe_types.begin(); ti != _pipe_types.end(); ++ti) { - const PipeType &ptype = (*ti); + for (const PipeType &ptype : _pipe_types) { string ptype_name = downcase(ptype._type.get_name()); if (ptype_name.find(preferred_name) != string::npos) { // Here's a substring match. @@ -292,8 +282,7 @@ make_default_pipe() { } // Couldn't find a matching pipe type; choose the first one on the list. - for (ti = _pipe_types.begin(); ti != _pipe_types.end(); ++ti) { - const PipeType &ptype = (*ti); + for (const PipeType &ptype : _pipe_types) { PT(GraphicsPipe) pipe = (*ptype._constructor)(); if (pipe != nullptr) { return pipe; @@ -310,9 +299,8 @@ make_default_pipe() { */ void GraphicsPipeSelection:: load_aux_modules() { - DisplayModules::iterator di; - for (di = _display_modules.begin(); di != _display_modules.end(); ++di) { - load_named_module(*di); + for (const string &module : _display_modules) { + load_named_module(module); } _display_modules.clear(); @@ -337,9 +325,7 @@ add_pipe_type(TypeHandle type, PipeConstructorFunc *func) { // First, make sure we don't already have a GraphicsPipe of this type. LightMutexHolder holder(_lock); - PipeTypes::const_iterator ti; - for (ti = _pipe_types.begin(); ti != _pipe_types.end(); ++ti) { - const PipeType &ptype = (*ti); + for (const PipeType &ptype : _pipe_types) { if (ptype._type == type) { display_cat->warning() << "Attempt to register GraphicsPipe type " << type @@ -375,8 +361,8 @@ do_load_default_module() { load_named_module(_default_display_module); DisplayModules::iterator di = - find(_display_modules.begin(), _display_modules.end(), - _default_display_module); + std::find(_display_modules.begin(), _display_modules.end(), + _default_display_module); if (di != _display_modules.end()) { _display_modules.erase(di); } diff --git a/panda/src/display/graphicsStateGuardian.cxx b/panda/src/display/graphicsStateGuardian.cxx index b76a7f751c..0e82a23f88 100644 --- a/panda/src/display/graphicsStateGuardian.cxx +++ b/panda/src/display/graphicsStateGuardian.cxx @@ -24,7 +24,6 @@ #include "renderBuffer.h" #include "light.h" #include "planeNode.h" -#include "ambientLight.h" #include "throw_event.h" #include "clockObject.h" #include "pStatTimer.h" @@ -60,7 +59,6 @@ #include "fogAttrib.h" #include "config_pstatclient.h" -#include #include using std::string; @@ -932,12 +930,12 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, } case Shader::SMO_frame_time: { PN_stdfloat time = ClockObject::get_global_clock()->get_frame_time(); - t = LMatrix4(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, time, time, time, time); + t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, time, time, time, time); return &t; } case Shader::SMO_frame_delta: { PN_stdfloat dt = ClockObject::get_global_clock()->get_dt(); - t = LMatrix4(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, dt, dt, dt, dt); + t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, dt, dt, dt, dt); return &t; } case Shader::SMO_texpad_x: { @@ -949,7 +947,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, double cx = (sx * 0.5) / tex->get_x_size(); double cy = (sy * 0.5) / tex->get_y_size(); double cz = (sz * 0.5) / tex->get_z_size(); - t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,cx,cy,cz,0); + t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, cx, cy, cz, 0); return &t; } case Shader::SMO_texpix_x: { @@ -958,7 +956,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, double px = 1.0 / tex->get_x_size(); double py = 1.0 / tex->get_y_size(); double pz = 1.0 / tex->get_z_size(); - t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,px,py,pz,0); + t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, px, py, pz, 0); return &t; } case Shader::SMO_attr_material: { @@ -966,7 +964,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, _target_rs->get_attrib_def(MaterialAttrib::get_class_slot()); // Material matrix contains AMBIENT, DIFFUSE, EMISSION, SPECULAR+SHININESS if (target_material->is_off()) { - t = LMatrix4(1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0); + t.set(1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0); return &t; } Material *m = target_material->get_material(); @@ -975,17 +973,17 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, LVecBase4 const &emm = m->get_emission(); LVecBase4 spc = m->get_specular(); spc[3] = m->get_shininess(); - t = LMatrix4(amb[0],amb[1],amb[2],amb[3], - dif[0],dif[1],dif[2],dif[3], - emm[0],emm[1],emm[2],emm[3], - spc[0],spc[1],spc[2],spc[3]); + t.set(amb[0], amb[1], amb[2], amb[3], + dif[0], dif[1], dif[2], dif[3], + emm[0], emm[1], emm[2], emm[3], + spc[0], spc[1], spc[2], spc[3]); return &t; } case Shader::SMO_attr_material2: { const MaterialAttrib *target_material = (const MaterialAttrib *) _target_rs->get_attrib_def(MaterialAttrib::get_class_slot()); if (target_material->is_off()) { - t = LMatrix4(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1); + t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1); return &t; } Material *m = target_material->get_material(); @@ -1000,7 +998,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, return &LMatrix4::ones_mat(); } LVecBase4 c = target_color->get_color(); - t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,c[0],c[1],c[2],c[3]); + t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, c[0], c[1], c[2], c[3]); return &t; } case Shader::SMO_attr_colorscale: { @@ -1010,7 +1008,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, return &LMatrix4::ones_mat(); } LVecBase4 cs = target_color->get_scale(); - t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,cs[0],cs[1],cs[2],cs[3]); + t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, cs[0], cs[1], cs[2], cs[3]); return &t; } case Shader::SMO_attr_fog: { @@ -1022,7 +1020,8 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, } PN_stdfloat start, end; fog->get_linear_range(start, end); - t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,fog->get_exp_density(),start,end,1.0f/(end-start)); + t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + fog->get_exp_density(), start, end, 1.0f / (end - start)); return &t; } case Shader::SMO_attr_fogcolor: { @@ -1033,7 +1032,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, return &LMatrix4::ones_mat(); } LVecBase4 c = fog->get_color(); - t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,c[0],c[1],c[2],c[3]); + t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, c[0], c[1], c[2], c[3]); return &t; } case Shader::SMO_alight_x: { @@ -1042,7 +1041,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, AmbientLight *lt; DCAST_INTO_R(lt, np.node(), &LMatrix4::zeros_mat()); LColor const &c = lt->get_color(); - t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,c[0],c[1],c[2],c[3]); + t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, c[0], c[1], c[2], c[3]); return &t; } case Shader::SMO_satten_x: { @@ -1052,7 +1051,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, DCAST_INTO_R(lt, np.node(), &LMatrix4::ones_mat()); LVecBase3 const &a = lt->get_attenuation(); PN_stdfloat x = lt->get_exponent(); - t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,a[0],a[1],a[2],x); + t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, a[0], a[1], a[2], x); return &t; } case Shader::SMO_dlight_x: { @@ -1069,7 +1068,10 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, d.normalize(); LVecBase3 h = d + LVecBase3(0,-1,0); h.normalize(); - t = LMatrix4(c[0],c[1],c[2],c[3],s[0],s[1],s[2],c[3],d[0],d[1],d[2],0,h[0],h[1],h[2],0); + t.set(c[0], c[1], c[2], c[3], + s[0], s[1], s[2], c[3], + d[0], d[1], d[2], 0, + h[0], h[1], h[2], 0); return &t; } case Shader::SMO_plight_x: { @@ -1087,7 +1089,10 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, Lens *lens = lt->get_lens(0); PN_stdfloat lnear = lens->get_near(); PN_stdfloat lfar = lens->get_far(); - t = LMatrix4(c[0],c[1],c[2],c[3],s[0],s[1],s[2],s[3],p[0],p[1],p[2],lnear,a[0],a[1],a[2],lfar); + t.set(c[0], c[1], c[2], c[3], + s[0], s[1], s[2], s[3], + p[0], p[1], p[2], lnear, + a[0], a[1], a[2], lfar); return &t; } case Shader::SMO_slight_x: { @@ -1105,7 +1110,10 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, _scene_setup->get_world_transform()->get_mat(); LVecBase3 p = t.xform_point(lens->get_nodal_point()); LVecBase3 d = -(t.xform_vec(lens->get_view_vector())); - t = LMatrix4(c[0],c[1],c[2],c[3],s[0],s[1],s[2],s[3],p[0],p[1],p[2],0,d[0],d[1],d[2],cutoff); + t.set(c[0], c[1], c[2], c[3], + s[0], s[1], s[2], s[3], + p[0], p[1], p[2], 0, + d[0], d[1], d[2], cutoff); return &t; } case Shader::SMO_light_ambient: { @@ -1149,7 +1157,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, if (_target_rs->get_attrib(ta) && _target_rs->get_attrib(tma) && index < ta->get_num_on_stages()) { LVecBase3 scale = tma->get_transform(ta->get_on_stage(index))->get_scale(); - t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,scale[0],scale[1],scale[2],0); + t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, scale[0], scale[1], scale[2], 0); return &t; } else { return &LMatrix4::ident_mat(); @@ -1173,7 +1181,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, index < ta->get_num_on_stages()) { TextureStage *ts = ta->get_on_stage(index); PN_stdfloat v = (ta->get_on_texture(ts)->get_format() == Texture::F_alpha); - t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,v,v,v,0); + t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, v, v, v, 0); return &t; } else { return &LMatrix4::zeros_mat(); @@ -1185,7 +1193,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, const PlaneNode *plane_node; DCAST_INTO_R(plane_node, np.node(), &LMatrix4::zeros_mat()); LPlane p = plane_node->get_plane(); - t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,p[0],p[1],p[2],p[3]); + t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, p[0], p[1], p[2], p[3]); return &t; } case Shader::SMO_clipplane_x: { @@ -1235,10 +1243,10 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, case Shader::SMO_vec_constant_x: { const LVecBase4 &input = _target_shader->get_shader_input_vector(name); const PN_stdfloat *data = input.get_data(); - t = LMatrix4(data[0],data[1],data[2],data[3], - data[0],data[1],data[2],data[3], - data[0],data[1],data[2],data[3], - data[0],data[1],data[2],data[3]); + t.set(data[0], data[1], data[2], data[3], + data[0], data[1], data[2], data[3], + data[0], data[1], data[2], data[3], + data[0], data[1], data[2], data[3]); return &t; } case Shader::SMO_world_to_view: { @@ -1394,10 +1402,10 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, // There is an input specifying precisely this whole thing, with dot and // all. Support this, even if only for backward compatibility. const LVecBase4 &data = _target_shader->get_shader_input_vector(name); - t = LMatrix4(data[0],data[1],data[2],data[3], - data[0],data[1],data[2],data[3], - data[0],data[1],data[2],data[3], - data[0],data[1],data[2],data[3]); + t.set(data[0], data[1], data[2], data[3], + data[0], data[1], data[2], data[3], + data[0], data[1], data[2], data[3], + data[0], data[1], data[2], data[3]); return &t; } @@ -1578,11 +1586,11 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t) } else if (attrib == IN_position) { if (np.is_empty()) { - t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0); + t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0); return &t; } else if (node->is_ambient_light()) { // Ambient light has no position. - t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); + t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); return &t; } else if (node->is_of_type(DirectionalLight::get_class_type())) { DirectionalLight *light; @@ -1591,7 +1599,7 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t) CPT(TransformState) transform = np.get_transform(_scene_setup->get_scene_root().get_parent()); LVector3 dir = -(light->get_direction() * transform->get_mat()); dir *= _scene_setup->get_cs_world_transform()->get_mat(); - t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,dir[0],dir[1],dir[2],0); + t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, dir[0], dir[1], dir[2], 0); return &t; } else { LightLensNode *light; @@ -1611,11 +1619,11 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t) } else if (attrib == IN_halfVector) { if (np.is_empty()) { - t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0); + t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0); return &t; } else if (node->is_ambient_light()) { // Ambient light has no half-vector. - t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); + t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); return &t; } else if (node->is_of_type(DirectionalLight::get_class_type())) { DirectionalLight *light; @@ -1627,7 +1635,7 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t) dir.normalize(); dir += LVector3(0, 0, 1); dir.normalize(); - t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,dir[0],dir[1],dir[2],1); + t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, dir[0], dir[1], dir[2], 1); return &t; } else { LightLensNode *light; @@ -1644,7 +1652,7 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t) pos.normalize(); pos += LVector3(0, 0, 1); pos.normalize(); - t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,pos[0],pos[1],pos[2],1); + t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, pos[0],pos[1],pos[2], 1); return &t; } diff --git a/panda/src/display/p3display_composite2.cxx b/panda/src/display/p3display_composite2.cxx index b3ba58995b..b9d33ab445 100644 --- a/panda/src/display/p3display_composite2.cxx +++ b/panda/src/display/p3display_composite2.cxx @@ -1,5 +1,4 @@ #include "graphicsPipeSelection.cxx" -#include "graphicsStateGuardian.cxx" #include "graphicsThreadingModel.cxx" #include "graphicsWindow.cxx" #include "graphicsWindowProc.cxx" diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index 616784e0cc..19594750c8 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -8925,6 +8925,9 @@ get_panda_wrap_mode(GLenum wm) { case GL_REPEAT: return SamplerState::WM_repeat; + case GL_MIRRORED_REPEAT: + return SamplerState::WM_mirror; + #ifndef OPENGLES case GL_MIRROR_CLAMP_EXT: case GL_MIRROR_CLAMP_TO_EDGE_EXT: diff --git a/panda/src/gobj/geomVertexData.I b/panda/src/gobj/geomVertexData.I index bd68fc4cf4..d0c6bba632 100644 --- a/panda/src/gobj/geomVertexData.I +++ b/panda/src/gobj/geomVertexData.I @@ -772,7 +772,9 @@ set_object(const GeomVertexData *object) { _cdata = (GeomVertexData::CData *)_object->_cycler.read_unlocked(_current_thread); _got_array_readers = false; +#ifdef DO_PIPELINING _cdata->ref(); +#endif // DO_PIPELINING } /** diff --git a/panda/src/pgraph/cullTraverserData.cxx b/panda/src/pgraph/cullTraverserData.cxx index 8d54308af8..a260dd3ebb 100644 --- a/panda/src/pgraph/cullTraverserData.cxx +++ b/panda/src/pgraph/cullTraverserData.cxx @@ -54,6 +54,9 @@ apply_transform_and_state(CullTraverser *trav) { CPT(TransformState) node_transform = _node_reader.get_transform(); node_effects->cull_callback(trav, *this, node_transform, node_state); apply_transform(node_transform); + + // The cull callback may have changed the node properties. + _node_reader.check_cached(false); } if (!node_state->is_empty()) { diff --git a/panda/src/pgraph/renderAttrib.cxx b/panda/src/pgraph/renderAttrib.cxx index 73b1e4b392..9bac4e666a 100644 --- a/panda/src/pgraph/renderAttrib.cxx +++ b/panda/src/pgraph/renderAttrib.cxx @@ -211,7 +211,7 @@ garbage_collect() { } num_this_pass = std::min(num_this_pass, size); - size_t stop_at_element = (_garbage_index + num_this_pass) % size; + size_t stop_at_element = (si + num_this_pass) % size; do { RenderAttrib *attrib = (RenderAttrib *)_attribs->get_key(si); @@ -229,6 +229,9 @@ garbage_collect() { // still need to visit. --size; --si; + if (stop_at_element > 0) { + --stop_at_element; + } } si = (si + 1) % size; diff --git a/panda/src/pgraph/renderState.cxx b/panda/src/pgraph/renderState.cxx index 927d1e7073..5ce1527247 100644 --- a/panda/src/pgraph/renderState.cxx +++ b/panda/src/pgraph/renderState.cxx @@ -950,6 +950,9 @@ garbage_collect() { // still need to visit. --size; --si; + if (stop_at_element > 0) { + --stop_at_element; + } } si = (si + 1) % size; diff --git a/panda/src/pgraph/transformState.cxx b/panda/src/pgraph/transformState.cxx index 453fb505b4..4d02425683 100644 --- a/panda/src/pgraph/transformState.cxx +++ b/panda/src/pgraph/transformState.cxx @@ -1216,6 +1216,9 @@ garbage_collect() { // still need to visit. --size; --si; + if (stop_at_element > 0) { + --stop_at_element; + } } si = (si + 1) % size; diff --git a/panda/src/pipeline/config_pipeline.cxx b/panda/src/pipeline/config_pipeline.cxx index 2e7bf6487e..4fd5214323 100644 --- a/panda/src/pipeline/config_pipeline.cxx +++ b/panda/src/pipeline/config_pipeline.cxx @@ -71,7 +71,10 @@ init_libpipeline() { } initialized = true; +#ifdef DO_PIPELINING CycleData::init_type(); +#endif + MainThread::init_type(); ExternalThread::init_type(); GenericThread::init_type(); diff --git a/panda/src/pipeline/cycleData.h b/panda/src/pipeline/cycleData.h index de90bdf226..ef21ad7a33 100644 --- a/panda/src/pipeline/cycleData.h +++ b/panda/src/pipeline/cycleData.h @@ -54,6 +54,9 @@ public: INLINE CycleData(const CycleData ©) = default; virtual ~CycleData(); + CycleData &operator = (CycleData &&from) = default; + CycleData &operator = (const CycleData ©) = default; + virtual CycleData *make_copy() const=0; virtual void write_datagram(BamWriter *, Datagram &) const; diff --git a/panda/src/pipeline/cycleDataLockedStageReader.I b/panda/src/pipeline/cycleDataLockedStageReader.I index 22b8785c82..a471aac0b7 100644 --- a/panda/src/pipeline/cycleDataLockedStageReader.I +++ b/panda/src/pipeline/cycleDataLockedStageReader.I @@ -47,6 +47,20 @@ CycleDataLockedStageReader(const CycleDataLockedStageReader © _cycler->increment_read(_pointer); } +/** + * + */ +template +INLINE CycleDataLockedStageReader:: +CycleDataLockedStageReader(CycleDataLockedStageReader &&from) noexcept : + _cycler(from._cycler), + _current_thread(from._current_thread), + _pointer(from._pointer), + _stage(from._stage) +{ + from._pointer = nullptr; +} + /** * */ @@ -64,20 +78,6 @@ operator = (const CycleDataLockedStageReader ©) { _cycler->increment_read(_pointer); } -/** - * - */ -template -INLINE CycleDataLockedStageReader:: -CycleDataLockedStageReader(CycleDataLockedStageReader &&from) noexcept : - _cycler(from._cycler), - _current_thread(from._current_thread), - _pointer(from._pointer), - _stage(from._stage) -{ - from._pointer = nullptr; -} - /** * */ @@ -174,6 +174,17 @@ CycleDataLockedStageReader(const CycleDataLockedStageReader © { } +/** + * + */ +template +INLINE CycleDataLockedStageReader:: +CycleDataLockedStageReader(CycleDataLockedStageReader &&from) noexcept : + _pointer(from._cycler) +{ + from._pointer = nullptr; +} + /** * */ @@ -183,6 +194,18 @@ operator = (const CycleDataLockedStageReader ©) { _pointer = copy._pointer; } +/** + * + */ +template +INLINE void CycleDataLockedStageReader:: +operator = (CycleDataLockedStageReader &&from) noexcept { + nassertv(_pointer == nullptr); + + _pointer = from._pointer; + from._pointer = nullptr; +} + /** * */ diff --git a/panda/src/pipeline/cycleDataStageWriter.I b/panda/src/pipeline/cycleDataStageWriter.I index a4c1851dde..cf25cf807a 100644 --- a/panda/src/pipeline/cycleDataStageWriter.I +++ b/panda/src/pipeline/cycleDataStageWriter.I @@ -62,23 +62,6 @@ CycleDataStageWriter(const CycleDataStageWriter ©) : _cycler->increment_write(_pointer); } -/** - * - */ -template -INLINE void CycleDataStageWriter:: -operator = (const CycleDataStageWriter ©) { - nassertv(_pointer == nullptr); - nassertv(_current_thread == copy._current_thread); - - _cycler = copy._cycler; - _pointer = copy._pointer; - _stage = copy._stage; - - nassertv(_pointer != nullptr); - _cycler->increment_write(_pointer); -} - /** * This flavor of the constructor elevates the pointer from the * CycleDataLockedStageReader from a read to a write pointer (and invalidates @@ -128,6 +111,23 @@ CycleDataStageWriter(CycleDataStageWriter &&from) noexcept : from._pointer = nullptr; } +/** + * + */ +template +INLINE void CycleDataStageWriter:: +operator = (const CycleDataStageWriter ©) { + nassertv(_pointer == nullptr); + nassertv(_current_thread == copy._current_thread); + + _cycler = copy._cycler; + _pointer = copy._pointer; + _stage = copy._stage; + + nassertv(_pointer != nullptr); + _cycler->increment_write(_pointer); +} + /** * */ @@ -227,6 +227,17 @@ CycleDataStageWriter(const CycleDataStageWriter ©) : { } +/** + * + */ +template +INLINE CycleDataStageWriter:: +CycleDataStageWriter(CycleDataStageWriter &&from) noexcept : + _pointer(from._pointer) +{ + from._pointer = nullptr; +} + /** * */ @@ -236,6 +247,18 @@ operator = (const CycleDataStageWriter ©) { _pointer = copy._pointer; } +/** + * + */ +template +INLINE void CycleDataStageWriter:: +operator = (CycleDataStageWriter &&from) noexcept { + nassertv(_pointer == nullptr); + + _pointer = from._pointer; + from._pointer = nullptr; +} + /** * This flavor of the constructor elevates the pointer from the * CycleDataLockedStageReader from a read to a write pointer (and invalidates diff --git a/tests/event/test_futures.py b/tests/event/test_futures.py index e120a2ab8e..adef5b33fc 100644 --- a/tests/event/test_futures.py +++ b/tests/event/test_futures.py @@ -1,6 +1,5 @@ from panda3d import core import pytest -import threading import time import sys @@ -39,7 +38,11 @@ def test_future_timeout(): fut.result(0.001) +@pytest.mark.skipif(not core.Thread.is_threading_supported(), + reason="Threading support disabled") def test_future_wait(): + threading = pytest.importorskip("direct.stdpy.threading") + fut = core.AsyncFuture() # Launch a thread to set the result value. @@ -59,7 +62,11 @@ def test_future_wait(): assert fut.result() is None +@pytest.mark.skipif(not core.Thread.is_threading_supported(), + reason="Threading support disabled") def test_future_wait_cancel(): + threading = pytest.importorskip("direct.stdpy.threading") + fut = core.AsyncFuture() # Launch a thread to cancel the future.