Merge branch 'release/1.10.x'

This commit is contained in:
rdb 2020-12-09 17:59:37 +01:00
commit ed397b3ab8
13 changed files with 181 additions and 21 deletions

View File

@ -529,7 +529,7 @@ class SelectionQueue(CollisionHandlerQueue):
# Well, no way to tell. Assume we're not backfacing.
return 0
if direct:
if base.direct:
cam = base.direct.cam
else:
cam = base.cam
@ -602,7 +602,7 @@ class SelectionRay(SelectionQueue):
if xy:
mx = xy[0]
my = xy[1]
elif direct:
elif base.direct:
mx = base.direct.dr.mouseX
my = base.direct.dr.mouseY
else:
@ -613,7 +613,7 @@ class SelectionRay(SelectionQueue):
mx = base.mouseWatcherNode.getMouseX()
my = base.mouseWatcherNode.getMouseY()
if direct:
if base.direct:
self.collider.setFromLens(base.direct.camNode, mx, my)
else:
self.collider.setFromLens(base.camNode, mx, my)

View File

@ -181,7 +181,12 @@ class VFSLoader:
filename = Filename(self.filename)
filename.setExtension('py')
filename.setText()
return open(self.filename, self.desc[1]).read()
# Use the tokenize module to detect the encoding.
import tokenize
fh = open(self.filename, 'rb')
encoding, lines = tokenize.detect_encoding(fh.readline)
return (b''.join(lines) + fh.read()).decode(encoding)
def _import_extension_module(self, fullname):
""" Loads the binary shared object as a Python module, and

View File

@ -39,6 +39,8 @@
#define DTOOL_PLATFORM "osx_i386"
#elif defined(__x86_64)
#define DTOOL_PLATFORM "osx_amd64"
#elif defined(__aarch64__)
#define DTOOL_PLATFORM "osx_aarch64"
#endif
#elif defined(__FreeBSD__)

View File

@ -87,7 +87,7 @@ PkgListSet(["PYTHON", "DIRECT", # Python support
"ARTOOLKIT", "OPENCV", "DIRECTCAM", "VISION", # Augmented Reality
"GTK2", # GTK2 is used for PStats on Unix
"MFC", "WX", "FLTK", # Used for web plug-in only
"COCOA", # Mac OS X toolkits
"COCOA", # macOS toolkits
"X11", # Unix platform support
"PANDATOOL", "PVIEW", "DEPLOYTOOLS", # Toolchain
"SKEL", # Example SKEL project
@ -132,7 +132,7 @@ def usage(problem):
print(" --distributor X (short string identifying the distributor of the build)")
print(" --outputdir X (use the specified directory instead of 'built')")
print(" --threads N (use the multithreaded build system. see manual)")
print(" --osxtarget N (the OS X version number to build for (OS X only))")
print(" --osxtarget N (the macOS version number to build for (macOS only))")
print(" --override \"O=V\" (override dtool_config/prc option value)")
print(" --static (builds libraries for static linking)")
print(" --target X (experimental cross-compilation (android only))")
@ -939,7 +939,7 @@ if (COMPILER=="GCC"):
if (PkgSkip(pkg)==0 and (pkg in SDK)):
if (GetHost() == "darwin"):
# Sheesh, Autodesk really can't make up their mind
# regarding the location of the Maya devkit on OS X.
# regarding the location of the Maya devkit on macOS.
if (os.path.isdir(SDK[pkg] + "/Maya.app/Contents/lib")):
LibDirectory(pkg, SDK[pkg] + "/Maya.app/Contents/lib")
if (os.path.isdir(SDK[pkg] + "/Maya.app/Contents/MacOS")):
@ -1480,7 +1480,7 @@ def CompileIgate(woutd,wsrc,opts):
target_arch = GetTargetArch()
if target_arch in ("x86_64", "amd64"):
cmd += ' -D_LP64'
elif target_arch == 'aarch64':
elif target_arch in ('aarch64', 'arm64'):
cmd += ' -D_LP64 -D__LP64__ -D__aarch64__'
else:
cmd += ' -D__i386__'
@ -1766,7 +1766,7 @@ def CompileLink(dll, obj, opts):
if (GetOrigExt(dll) == ".exe" and GetTarget() == 'windows' and "NOICON" not in opts):
cmd += " " + GetOutputDir() + "/tmp/pandaIcon.res"
# Mac OS X specific flags.
# macOS specific flags.
if GetTarget() == 'darwin':
cmd += " -headerpad_max_install_names"
if OSXTARGET is not None:
@ -2012,7 +2012,7 @@ def FreezePy(target, inputs, opts):
##########################################################################################
def CompileBundle(target, inputs, opts):
assert GetTarget() == "darwin", 'bundles can only be made for Mac OS X'
assert GetTarget() == "darwin", 'bundles can only be made for macOS'
plist = None
resources = []
objects = []

View File

@ -40,7 +40,7 @@ DEBUG_DEPENDENCIES = False
# Is the current Python a 32-bit or 64-bit build? There doesn't
# appear to be a universal test for this.
if sys.platform == 'darwin':
# On OSX, platform.architecture reports '64bit' even if it is
# On macOS, platform.architecture reports '64bit' even if it is
# currently running in 32-bit mode. But sys.maxint is a reliable
# indicator.
host_64 = (sys.maxsize > 0x100000000)
@ -365,11 +365,13 @@ def SetTarget(target, arch=None):
elif target == 'darwin':
if arch == 'amd64':
arch = 'x86_64'
if arch == 'aarch64':
arch = 'arm64'
if arch is not None:
choices = ('i386', 'x86_64', 'ppc', 'ppc64')
choices = ('i386', 'x86_64', 'ppc', 'ppc64', 'arm64')
if arch not in choices:
exit('Mac OS X architecture must be one of %s' % (', '.join(choices)))
exit('macOS architecture must be one of %s' % (', '.join(choices)))
elif target == 'android' or target.startswith('android-'):
if arch is None:
@ -1297,7 +1299,7 @@ def GetThirdpartyDir():
THIRDPARTYDIR = base + "/win-libs-vc" + vc + "/"
elif (target == 'darwin'):
# OSX thirdparty binaries are universal, where possible.
# macOS thirdparty binaries are universal, where possible.
THIRDPARTYDIR = base + "/darwin-libs-a/"
elif (target == 'linux'):
@ -3002,7 +3004,7 @@ def SetupBuildEnvironment(compiler):
dyldpath.insert(0, os.path.join(builtdir, 'lib'))
os.environ["DYLD_LIBRARY_PATH"] = os.pathsep.join(dyldpath)
# OS X 10.11 removed DYLD_LIBRARY_PATH, but we still need to pass
# macOS 10.11 removed DYLD_LIBRARY_PATH, but we still need to pass
# on our lib directory to ppackage, so add it to PATH instead.
os.environ["PATH"] = os.path.join(builtdir, 'lib') + ':' + os.environ.get("PATH", "")

View File

@ -381,7 +381,8 @@ class WheelFile(object):
# On macOS, if no fat wheel was requested, extract the right architecture.
if sys.platform == "darwin" and is_fat_file(source_path) \
and not self.platform.endswith("_intel") \
and "_fat" not in self.platform:
and "_fat" not in self.platform \
and "_universal" not in self.platform:
if self.platform.endswith("_x86_64"):
arch = 'x86_64'

View File

@ -187,14 +187,22 @@ transform_changed() {
// Offset between current approx center and current initial transform
btVector3 pos = LVecBase3_to_btVector3(this->do_get_aabb().get_approx_center());
#if BT_BULLET_VERSION >= 290
btVector3 origin = _soft->getWorldTransform().getOrigin();
#else
btVector3 origin = _soft->m_initialWorldTransform.getOrigin();
#endif
btVector3 offset = pos - origin;
// Subtract offset to get new transform for the body
trans.setOrigin(trans.getOrigin() - offset);
// Now apply the new transform
#if BT_BULLET_VERSION >= 290
_soft->transform(_soft->getWorldTransform().inverse());
#else
_soft->transform(_soft->m_initialWorldTransform.inverse());
#endif
_soft->transform(trans);
if (ts->has_scale()) {

View File

@ -42,6 +42,7 @@ get_num_non_ambient_lights() const {
*/
INLINE NodePath LightAttrib::
get_on_light(size_t n) const {
check_sorted();
nassertr(n < _sorted_on_lights.size(), NodePath::fail());
return _sorted_on_lights[n];
}

View File

@ -443,6 +443,36 @@ remove_on_light(const NodePath &light) const {
return return_new(attrib);
}
/**
* Returns a new LightAttrib, just like this one, but with the indicated light
* replaced with the given other light.
*/
CPT(RenderAttrib) LightAttrib::
replace_on_light(const NodePath &source, const NodePath &dest) const {
if (source == dest) {
return this;
}
nassertr(!source.is_empty(), this);
Light *slobj = source.node()->as_light();
nassertr(slobj != nullptr, this);
nassertr(!dest.is_empty(), this);
Light *dlobj = dest.node()->as_light();
nassertr(dlobj != nullptr, this);
LightAttrib *attrib = new LightAttrib(*this);
auto it = attrib->_on_lights.find(source);
if (it != attrib->_on_lights.end()) {
dlobj->attrib_ref();
slobj->attrib_unref();
*it = dest;
}
return return_new(attrib);
}
/**
* Returns a new LightAttrib, just like this one, but with the indicated light
* added to the list of lights turned off by this attrib.
@ -475,6 +505,36 @@ remove_off_light(const NodePath &light) const {
return return_new(attrib);
}
/**
* Returns a new LightAttrib, just like this one, but with the indicated light
* replaced with the given other light.
*/
CPT(RenderAttrib) LightAttrib::
replace_off_light(const NodePath &source, const NodePath &dest) const {
if (source == dest) {
return this;
}
nassertr(!source.is_empty(), this);
Light *slobj = source.node()->as_light();
nassertr(slobj != nullptr, this);
nassertr(!dest.is_empty(), this);
Light *dlobj = dest.node()->as_light();
nassertr(dlobj != nullptr, this);
LightAttrib *attrib = new LightAttrib(*this);
auto it = attrib->_off_lights.find(source);
if (it != attrib->_off_lights.end()) {
dlobj->attrib_ref();
slobj->attrib_unref();
*it = dest;
}
return return_new(attrib);
}
/**
* Returns the most important light (that is, the light with the highest
* priority) in the LightAttrib, excluding any ambient lights. Returns an

View File

@ -85,8 +85,10 @@ PUBLISHED:
CPT(RenderAttrib) add_on_light(const NodePath &light) const;
CPT(RenderAttrib) remove_on_light(const NodePath &light) const;
CPT(RenderAttrib) replace_on_light(const NodePath &source, const NodePath &dest) const;
CPT(RenderAttrib) add_off_light(const NodePath &light) const;
CPT(RenderAttrib) remove_off_light(const NodePath &light) const;
CPT(RenderAttrib) replace_off_light(const NodePath &source, const NodePath &dest) const;
NodePath get_most_important_light() const;
LColor get_ambient_contribution() const;

View File

@ -292,7 +292,7 @@ try_load_file(const Filename &pathname, const LoaderOptions &options,
<< "Model " << pathname << " found in ModelPool.\n";
}
// But return a deep copy of the shared model.
node = node->copy_subgraph();
node = NodePath(node).copy_to(NodePath()).node();
}
return node;
}
@ -329,7 +329,7 @@ try_load_file(const Filename &pathname, const LoaderOptions &options,
// from the RAM cached version.
ModelPool::add_model(pathname, model_root);
if ((options.get_flags() & LoaderOptions::LF_allow_instance) == 0) {
return model_root->copy_subgraph();
return NodePath(model_root).copy_to(NodePath()).node();
}
}
}
@ -398,7 +398,7 @@ try_load_file(const Filename &pathname, const LoaderOptions &options,
// cached version.
ModelPool::add_model(pathname, DCAST(ModelRoot, result.p()));
if ((options.get_flags() & LoaderOptions::LF_allow_instance) == 0) {
result = result->copy_subgraph();
result = NodePath(result).copy_to(NodePath()).node();
}
}

View File

@ -539,12 +539,45 @@ copy_to(const NodePath &other, int sort, Thread *current_thread) const {
nassertr(other._error_type == ET_ok, fail());
PandaNode *source_node = node();
PT(PandaNode) copy_node = source_node->copy_subgraph(current_thread);
PandaNode::InstanceMap inst_map;
PT(PandaNode) copy_node = source_node->r_copy_subgraph(inst_map, current_thread);
nassertr(copy_node != nullptr, fail());
copy_node->reset_prev_transform(current_thread);
return other.attach_new_node(copy_node, sort, current_thread);
NodePath result = other.attach_new_node(copy_node, sort, current_thread);
// Temporary hack fix: if this root NodePath had lights applied that are
// located inside this subgraph, we need to fix them.
const RenderState *state = source_node->get_state();
const LightAttrib *lattr;
if (state->get_attrib(lattr)) {
CPT(LightAttrib) new_lattr = lattr;
for (size_t i = 0; i < lattr->get_num_off_lights(); ++i) {
NodePath light = lattr->get_off_light(i);
NodePath light2 = light;
if (light2.replace_copied_nodes(*this, result, inst_map, current_thread)) {
new_lattr = DCAST(LightAttrib, new_lattr->replace_off_light(light, light2));
}
}
for (size_t i = 0; i < lattr->get_num_on_lights(); ++i) {
NodePath light = lattr->get_on_light(i);
NodePath light2 = light;
if (light2.replace_copied_nodes(*this, result, inst_map, current_thread)) {
new_lattr = DCAST(LightAttrib, new_lattr->replace_on_light(light, light2));
}
}
if (new_lattr != lattr) {
result.set_state(state->set_attrib(std::move(new_lattr)));
}
}
return result;
}
/**
@ -5803,6 +5836,48 @@ decode_from_bam_stream(vector_uchar data, BamReader *reader) {
return result;
}
/**
* If the given root node is an ancestor of this NodePath, replaces all
* components below it using the given instance map.
*
* This is a helper method used by copy_to().
*/
bool NodePath::
replace_copied_nodes(const NodePath &source, const NodePath &dest,
const PandaNode::InstanceMap &inst_map,
Thread *current_thread) {
nassertr(!dest.is_empty(), false);
int pipeline_stage = current_thread->get_pipeline_stage();
pvector<PandaNode *> nodes;
NodePathComponent *comp = _head;
while (comp != nullptr && comp != source._head) {
nodes.push_back(comp->get_node());
comp = comp->get_next(pipeline_stage, current_thread);
}
if (comp == nullptr) {
// The given source NodePath isn't an ancestor of this NodePath.
return false;
}
// Start at the dest NodePath and compose the new NodePath.
PT(NodePathComponent) new_comp = dest._head;
pvector<PandaNode *>::reverse_iterator it;
for (it = nodes.rbegin(); it != nodes.rend(); ++it) {
PandaNode::InstanceMap::const_iterator iit = inst_map.find(*it);
nassertr_always(iit != inst_map.end(), false);
new_comp = PandaNode::get_component(new_comp, iit->second, pipeline_stage, current_thread);
}
nassertr(new_comp != nullptr, false);
_head = std::move(new_comp);
return true;
}
/**
* Walks up from both NodePaths to find the first node that both have in
* common, if any. Fills a_count and b_count with the number of nodes below

View File

@ -952,6 +952,10 @@ PUBLISHED:
static NodePath decode_from_bam_stream(vector_uchar data, BamReader *reader = nullptr);
private:
bool replace_copied_nodes(const NodePath &source, const NodePath &dest,
const PandaNode::InstanceMap &inst_map,
Thread *current_thread);
static NodePathComponent *
find_common_ancestor(const NodePath &a, const NodePath &b,
int &a_count, int &b_count,