Merge branch 'release/1.10.x'
This commit is contained in:
commit
ed397b3ab8
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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__)
|
||||
|
|
|
|||
|
|
@ -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 = []
|
||||
|
|
|
|||
|
|
@ -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", "")
|
||||
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
|
|
|
|||
|
|
@ -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()) {
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Reference in New Issue