mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-01 01:07:51 -04:00
Merge branch 'master' into deploy-ng
This commit is contained in:
commit
bf1b486e5a
@ -2672,15 +2672,18 @@ class ShowBase(DirectObject.DirectObject):
|
||||
output file name (e.g. if sd = 4, movie_0001.png)
|
||||
- source is the Window, Buffer, DisplayRegion, or Texture from which
|
||||
to save the resulting images. The default is the main window.
|
||||
|
||||
The task is returned, so that it can be awaited.
|
||||
"""
|
||||
globalClock.setMode(ClockObject.MNonRealTime)
|
||||
globalClock.setDt(1.0/float(fps))
|
||||
t = taskMgr.add(self._movieTask, namePrefix + '_task')
|
||||
t = self.taskMgr.add(self._movieTask, namePrefix + '_task')
|
||||
t.frameIndex = 0 # Frame 0 is not captured.
|
||||
t.numFrames = int(duration * fps)
|
||||
t.source = source
|
||||
t.outputString = namePrefix + '_%0' + repr(sd) + 'd.' + format
|
||||
t.setUponDeath(lambda state: globalClock.setMode(ClockObject.MNormal))
|
||||
return t
|
||||
|
||||
def _movieTask(self, state):
|
||||
if state.frameIndex != 0:
|
||||
|
@ -23,7 +23,9 @@ class Transitions:
|
||||
scale=3.0,
|
||||
pos=Vec3(0, 0, 0)):
|
||||
self.transitionIval = None
|
||||
self.__transitionFuture = None
|
||||
self.letterboxIval = None
|
||||
self.__letterboxFuture = None
|
||||
self.iris = None
|
||||
self.fade = None
|
||||
self.letterbox = None
|
||||
@ -94,7 +96,9 @@ class Transitions:
|
||||
"""
|
||||
#self.noTransitions() masad: this creates a one frame pop, is it necessary?
|
||||
self.loadFade()
|
||||
transitionIval = Sequence(Func(self.fade.reparentTo, aspect2d, DGG.FADE_SORT_INDEX),
|
||||
|
||||
parent = aspect2d if self.fadeModel else render2d
|
||||
transitionIval = Sequence(Func(self.fade.reparentTo, parent, DGG.FADE_SORT_INDEX),
|
||||
Func(self.fade.showThrough), # in case aspect2d is hidden for some reason
|
||||
self.lerpFunc(self.fade, t,
|
||||
self.alphaOff,
|
||||
@ -115,7 +119,8 @@ class Transitions:
|
||||
self.noTransitions()
|
||||
self.loadFade()
|
||||
|
||||
transitionIval = Sequence(Func(self.fade.reparentTo,aspect2d,DGG.FADE_SORT_INDEX),
|
||||
parent = aspect2d if self.fadeModel else render2d
|
||||
transitionIval = Sequence(Func(self.fade.reparentTo, parent, DGG.FADE_SORT_INDEX),
|
||||
Func(self.fade.showThrough), # in case aspect2d is hidden for some reason
|
||||
self.lerpFunc(self.fade, t,
|
||||
self.alphaOn,
|
||||
@ -148,11 +153,17 @@ class Transitions:
|
||||
self.noTransitions()
|
||||
self.loadFade()
|
||||
self.fade.detachNode()
|
||||
fut = AsyncFuture()
|
||||
fut.setResult(None)
|
||||
return fut
|
||||
else:
|
||||
# Create a sequence that lerps the color out, then
|
||||
# parents the fade to hidden
|
||||
self.transitionIval = self.getFadeInIval(t, finishIval)
|
||||
self.transitionIval.append(Func(self.__finishTransition))
|
||||
self.__transitionFuture = AsyncFuture()
|
||||
self.transitionIval.start()
|
||||
return self.__transitionFuture
|
||||
|
||||
def fadeOut(self, t=0.5, finishIval=None):
|
||||
"""
|
||||
@ -167,7 +178,9 @@ class Transitions:
|
||||
# Fade out immediately with no lerp
|
||||
self.noTransitions()
|
||||
self.loadFade()
|
||||
self.fade.reparentTo(aspect2d, DGG.FADE_SORT_INDEX)
|
||||
|
||||
parent = aspect2d if self.fadeModel else render2d
|
||||
self.fade.reparentTo(parent, DGG.FADE_SORT_INDEX)
|
||||
self.fade.setColor(self.alphaOn)
|
||||
elif ConfigVariableBool('no-loading-screen', False):
|
||||
if finishIval:
|
||||
@ -176,8 +189,16 @@ class Transitions:
|
||||
else:
|
||||
# Create a sequence that lerps the color out, then
|
||||
# parents the fade to hidden
|
||||
self.transitionIval = self.getFadeOutIval(t,finishIval)
|
||||
self.transitionIval = self.getFadeOutIval(t, finishIval)
|
||||
self.transitionIval.append(Func(self.__finishTransition))
|
||||
self.__transitionFuture = AsyncFuture()
|
||||
self.transitionIval.start()
|
||||
return self.__transitionFuture
|
||||
|
||||
# Immediately done, so return a dummy future.
|
||||
fut = AsyncFuture()
|
||||
fut.setResult(None)
|
||||
return fut
|
||||
|
||||
def fadeOutActive(self):
|
||||
return self.fade and self.fade.getColor()[3] > 0
|
||||
@ -191,7 +212,9 @@ class Transitions:
|
||||
#print "transitiosn: fadeScreen"
|
||||
self.noTransitions()
|
||||
self.loadFade()
|
||||
self.fade.reparentTo(aspect2d, DGG.FADE_SORT_INDEX)
|
||||
|
||||
parent = aspect2d if self.fadeModel else render2d
|
||||
self.fade.reparentTo(parent, DGG.FADE_SORT_INDEX)
|
||||
self.fade.setColor(self.alphaOn[0],
|
||||
self.alphaOn[1],
|
||||
self.alphaOn[2],
|
||||
@ -206,7 +229,9 @@ class Transitions:
|
||||
#print "transitiosn: fadeScreenColor"
|
||||
self.noTransitions()
|
||||
self.loadFade()
|
||||
self.fade.reparentTo(aspect2d, DGG.FADE_SORT_INDEX)
|
||||
|
||||
parent = aspect2d if self.fadeModel else render2d
|
||||
self.fade.reparentTo(parent, DGG.FADE_SORT_INDEX)
|
||||
self.fade.setColor(color)
|
||||
|
||||
def noFade(self):
|
||||
@ -217,6 +242,9 @@ class Transitions:
|
||||
if self.transitionIval:
|
||||
self.transitionIval.pause()
|
||||
self.transitionIval = None
|
||||
if self.__transitionFuture:
|
||||
self.__transitionFuture.cancel()
|
||||
self.__transitionFuture = None
|
||||
if self.fade:
|
||||
# Make sure to reset the color, since fadeOutActive() is looking at it
|
||||
self.fade.setColor(self.alphaOff)
|
||||
@ -247,18 +275,25 @@ class Transitions:
|
||||
self.loadIris()
|
||||
if (t == 0):
|
||||
self.iris.detachNode()
|
||||
fut = AsyncFuture()
|
||||
fut.setResult(None)
|
||||
return fut
|
||||
else:
|
||||
self.iris.reparentTo(aspect2d, DGG.FADE_SORT_INDEX)
|
||||
|
||||
scale = 0.18 * max(base.a2dRight, base.a2dTop)
|
||||
self.transitionIval = Sequence(LerpScaleInterval(self.iris, t,
|
||||
scale = 0.18,
|
||||
scale = scale,
|
||||
startScale = 0.01),
|
||||
Func(self.iris.detachNode),
|
||||
Func(self.__finishTransition),
|
||||
name = self.irisTaskName,
|
||||
)
|
||||
self.__transitionFuture = AsyncFuture()
|
||||
if finishIval:
|
||||
self.transitionIval.append(finishIval)
|
||||
self.transitionIval.start()
|
||||
return self.__transitionFuture
|
||||
|
||||
def irisOut(self, t=0.5, finishIval=None):
|
||||
"""
|
||||
@ -274,20 +309,27 @@ class Transitions:
|
||||
if (t == 0):
|
||||
self.iris.detachNode()
|
||||
self.fadeOut(0)
|
||||
fut = AsyncFuture()
|
||||
fut.setResult(None)
|
||||
return fut
|
||||
else:
|
||||
self.iris.reparentTo(aspect2d, DGG.FADE_SORT_INDEX)
|
||||
|
||||
scale = 0.18 * max(base.a2dRight, base.a2dTop)
|
||||
self.transitionIval = Sequence(LerpScaleInterval(self.iris, t,
|
||||
scale = 0.01,
|
||||
startScale = 0.18),
|
||||
startScale = scale),
|
||||
Func(self.iris.detachNode),
|
||||
# Use the fade to cover up the hole that the iris would leave
|
||||
Func(self.fadeOut, 0),
|
||||
Func(self.__finishTransition),
|
||||
name = self.irisTaskName,
|
||||
)
|
||||
self.__transitionFuture = AsyncFuture()
|
||||
if finishIval:
|
||||
self.transitionIval.append(finishIval)
|
||||
self.transitionIval.start()
|
||||
return self.__transitionFuture
|
||||
|
||||
def noIris(self):
|
||||
"""
|
||||
@ -311,6 +353,11 @@ class Transitions:
|
||||
# Letterbox is not really a transition, it is a screen overlay
|
||||
# self.noLetterbox()
|
||||
|
||||
def __finishTransition(self):
|
||||
if self.__transitionFuture:
|
||||
self.__transitionFuture.setResult(None)
|
||||
self.__transitionFuture = None
|
||||
|
||||
##################################################
|
||||
# Letterbox
|
||||
##################################################
|
||||
@ -383,9 +430,17 @@ class Transitions:
|
||||
if self.letterboxIval:
|
||||
self.letterboxIval.pause()
|
||||
self.letterboxIval = None
|
||||
if self.__letterboxFuture:
|
||||
self.__letterboxFuture.cancel()
|
||||
self.__letterboxFuture = None
|
||||
if self.letterbox:
|
||||
self.letterbox.stash()
|
||||
|
||||
def __finishLetterbox(self):
|
||||
if self.__letterboxFuture:
|
||||
self.__letterboxFuture.setResult(None)
|
||||
self.__letterboxFuture = None
|
||||
|
||||
def letterboxOn(self, t=0.25, finishIval=None):
|
||||
"""
|
||||
Move black bars in over t seconds.
|
||||
@ -396,7 +451,11 @@ class Transitions:
|
||||
if (t == 0):
|
||||
self.letterboxBottom.setPos(0, 0, -1)
|
||||
self.letterboxTop.setPos(0, 0, 0.8)
|
||||
fut = AsyncFuture()
|
||||
fut.setResult(None)
|
||||
return fut
|
||||
else:
|
||||
self.__letterboxFuture = AsyncFuture()
|
||||
self.letterboxIval = Sequence(Parallel(
|
||||
LerpPosInterval(self.letterboxBottom,
|
||||
t,
|
||||
@ -409,11 +468,13 @@ class Transitions:
|
||||
# startPos = Vec3(0, 0, 1),
|
||||
),
|
||||
),
|
||||
Func(self.__finishLetterbox),
|
||||
name = self.letterboxTaskName,
|
||||
)
|
||||
if finishIval:
|
||||
self.letterboxIval.append(finishIval)
|
||||
self.letterboxIval.start()
|
||||
return self.__letterboxFuture
|
||||
|
||||
def letterboxOff(self, t=0.25, finishIval=None):
|
||||
"""
|
||||
@ -424,7 +485,11 @@ class Transitions:
|
||||
self.letterbox.unstash()
|
||||
if (t == 0):
|
||||
self.letterbox.stash()
|
||||
fut = AsyncFuture()
|
||||
fut.setResult(None)
|
||||
return fut
|
||||
else:
|
||||
self.__letterboxFuture = AsyncFuture()
|
||||
self.letterboxIval = Sequence(Parallel(
|
||||
LerpPosInterval(self.letterboxBottom,
|
||||
t,
|
||||
@ -438,9 +503,11 @@ class Transitions:
|
||||
),
|
||||
),
|
||||
Func(self.letterbox.stash),
|
||||
Func(self.__finishLetterbox),
|
||||
Func(messenger.send,'letterboxOff'),
|
||||
name = self.letterboxTaskName,
|
||||
)
|
||||
if finishIval:
|
||||
self.letterboxIval.append(finishIval)
|
||||
self.letterboxIval.start()
|
||||
return self.__letterboxFuture
|
||||
|
@ -122,6 +122,11 @@ typedef ios::seekdir ios_seekdir;
|
||||
// Apple has an outdated libstdc++. Not all is lost, though, as we can fill
|
||||
// in some important missing functions.
|
||||
#if defined(__GLIBCXX__) && __GLIBCXX__ <= 20070719
|
||||
#include <tr1/tuple>
|
||||
|
||||
using std::tr1::tuple;
|
||||
using std::tr1::tie;
|
||||
|
||||
typedef decltype(nullptr) nullptr_t;
|
||||
|
||||
template<class T> struct remove_reference {typedef T type;};
|
||||
|
@ -119,6 +119,7 @@ protected:
|
||||
double _wake_time;
|
||||
int _sort;
|
||||
int _priority;
|
||||
unsigned int _implicit_sort;
|
||||
|
||||
State _state;
|
||||
Thread *_servicing_thread;
|
||||
|
@ -51,7 +51,8 @@ AsyncTaskChain(AsyncTaskManager *manager, const string &name) :
|
||||
_needs_cleanup(false),
|
||||
_current_frame(0),
|
||||
_time_in_frame(0.0),
|
||||
_block_till_next_frame(false)
|
||||
_block_till_next_frame(false),
|
||||
_next_implicit_sort(0)
|
||||
{
|
||||
}
|
||||
|
||||
@ -418,6 +419,9 @@ do_add(AsyncTask *task) {
|
||||
task->_start_time = now;
|
||||
task->_start_frame = _manager->_clock->get_frame_count();
|
||||
|
||||
// Remember the order in which tasks were added to the chain.
|
||||
task->_implicit_sort = _next_implicit_sort++;
|
||||
|
||||
_manager->add_task_by_name(task);
|
||||
|
||||
if (task->has_delay()) {
|
||||
|
@ -146,7 +146,12 @@ protected:
|
||||
if (a->get_priority() != b->get_priority()) {
|
||||
return a->get_priority() < b->get_priority();
|
||||
}
|
||||
return a->get_start_time() > b->get_start_time();
|
||||
if (a->get_start_time() != b->get_start_time()) {
|
||||
return a->get_start_time() > b->get_start_time();
|
||||
}
|
||||
// Failing any other ordering criteria, we sort the tasks based on the
|
||||
// order in which they were added to the task chain.
|
||||
return a->_implicit_sort > b->_implicit_sort;
|
||||
}
|
||||
};
|
||||
|
||||
@ -186,6 +191,8 @@ protected:
|
||||
double _time_in_frame;
|
||||
bool _block_till_next_frame;
|
||||
|
||||
unsigned int _next_implicit_sort;
|
||||
|
||||
static PStatCollector _task_pcollector;
|
||||
static PStatCollector _wait_pcollector;
|
||||
|
||||
|
@ -94,6 +94,9 @@ PythonTask::
|
||||
PyErr_Restore(_exception, _exc_value, _exc_traceback);
|
||||
PyErr_Print();
|
||||
PyErr_Restore(nullptr, nullptr, nullptr);
|
||||
_exception = nullptr;
|
||||
_exc_value = nullptr;
|
||||
_exc_traceback = nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -12647,7 +12647,7 @@ upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload,
|
||||
int depth = tex->get_expected_mipmap_z_size(mipmap_bias);
|
||||
|
||||
// Determine the number of images to upload.
|
||||
int num_levels = 1;
|
||||
int num_levels = mipmap_bias + 1;
|
||||
if (uses_mipmaps) {
|
||||
num_levels = tex->get_expected_num_mipmap_levels();
|
||||
}
|
||||
|
@ -94,6 +94,10 @@ BamWriter::
|
||||
for (si = _state_map.begin(); si != _state_map.end(); ++si) {
|
||||
TypedWritable *object = (TypedWritable *)(*si).first;
|
||||
object->remove_bam_writer(this);
|
||||
|
||||
if ((*si).second._refcount != nullptr) {
|
||||
unref_delete((*si).second._refcount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -529,6 +533,9 @@ object_destructs(TypedWritable *object) {
|
||||
// we're in trouble when we do write it out.
|
||||
nassertv(!(*si).second._written_seq.is_initial());
|
||||
|
||||
// This cannot be called if we are still holding a reference to it.
|
||||
nassertv((*si).second._refcount == nullptr);
|
||||
|
||||
int object_id = (*si).second._object_id;
|
||||
_freed_object_ids.push_back(object_id);
|
||||
|
||||
@ -606,8 +613,10 @@ enqueue_object(const TypedWritable *object) {
|
||||
// No, it hasn't, so assign it the next number in sequence arbitrarily.
|
||||
object_id = _next_object_id;
|
||||
|
||||
bool inserted =
|
||||
_state_map.insert(StateMap::value_type(object, StoreState(_next_object_id))).second;
|
||||
StateMap::iterator si;
|
||||
bool inserted;
|
||||
tie(si, inserted) =
|
||||
_state_map.insert(StateMap::value_type(object, StoreState(_next_object_id)));
|
||||
nassertr(inserted, false);
|
||||
|
||||
// Store ourselves on the TypedWritable so that we get notified when it
|
||||
@ -615,6 +624,14 @@ enqueue_object(const TypedWritable *object) {
|
||||
(const_cast<TypedWritable*>(object))->add_bam_writer(this);
|
||||
_next_object_id++;
|
||||
|
||||
// Increase the reference count if this inherits from ReferenceCount,
|
||||
// until we get a chance to write this object for the first time.
|
||||
const ReferenceCount *rc = ((TypedWritable *)object)->as_reference_count();
|
||||
if (rc != nullptr) {
|
||||
rc->ref();
|
||||
(*si).second._refcount = rc;
|
||||
}
|
||||
|
||||
} else {
|
||||
// Yes, it has; get the object ID.
|
||||
object_id = (*si).second._object_id;
|
||||
@ -703,6 +720,15 @@ flush_queue() {
|
||||
(*si).second._written_seq = _writing_seq;
|
||||
(*si).second._modified = object->get_bam_modified();
|
||||
|
||||
// Now release any reference we hold to it, so that it may destruct.
|
||||
const ReferenceCount *rc = (*si).second._refcount;
|
||||
if (rc != nullptr) {
|
||||
// We need to assign this pointer to null before deleting the object,
|
||||
// since that may end up calling object_destructs.
|
||||
(*si).second._refcount = nullptr;
|
||||
unref_delete(rc);
|
||||
}
|
||||
|
||||
} else {
|
||||
// On subsequent times when we write a particular object, we write
|
||||
// simply TypeHandle::none(), followed by the object ID. The occurrence
|
||||
|
@ -140,8 +140,9 @@ private:
|
||||
int _object_id;
|
||||
UpdateSeq _written_seq;
|
||||
UpdateSeq _modified;
|
||||
const ReferenceCount *_refcount;
|
||||
|
||||
StoreState(int object_id) : _object_id(object_id) {}
|
||||
StoreState(int object_id) : _object_id(object_id), _refcount(nullptr) {}
|
||||
};
|
||||
typedef phash_map<const TypedWritable *, StoreState, pointer_hash> StateMap;
|
||||
StateMap _state_map;
|
||||
|
Loading…
x
Reference in New Issue
Block a user