integrate AviTexture better with Panda, rename to OpenCVTexture
This commit is contained in:
parent
f91ee87026
commit
a7b1f14e80
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
#define DIR_TYPE metalib
|
||||
#define BUILDING_DLL BUILDING_PANDA
|
||||
#define USE_PACKAGES net cv
|
||||
#define USE_PACKAGES net
|
||||
|
||||
#define COMPONENT_LIBS \
|
||||
recorder pgraph \
|
||||
|
|
|
|||
|
|
@ -16,92 +16,6 @@
|
|||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <math.h>
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimControl::set_play_rate
|
||||
// Access: Published
|
||||
// Description: Sets the speed of the animation, relative to its
|
||||
// "normal" speed. Setting this number to 2.0 plays it
|
||||
// twice as fast, 0.5 half as fast. -1.0 plays it
|
||||
// backwards, and 0.0 stops it. The change is actually
|
||||
// retroactive to the last frame.
|
||||
//
|
||||
// If you are going to change the play_rate from a
|
||||
// positive number to a negative number, or vice-versa,
|
||||
// you should do this before starting the animation.
|
||||
// The various flavors of play() and loop() do slightly
|
||||
// different behavior based on whether play_rate is
|
||||
// positive or negative.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void AnimControl::
|
||||
set_play_rate(double play_rate) {
|
||||
_play_rate = play_rate;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimControl::get_play_rate
|
||||
// Access: Published
|
||||
// Description: Returns the current speed of the animation. See
|
||||
// set_play_rate().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE double AnimControl::
|
||||
get_play_rate() const {
|
||||
return _play_rate;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimControl::get_frame_rate
|
||||
// Access: Published
|
||||
// Description: Returns the actual frame rate of the animation, based
|
||||
// on the play_rate (see set_play_rate()) and the
|
||||
// animation's base frame rate (see
|
||||
// AnimBundle::get_base_frame_rate()). This is in
|
||||
// frames per second.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE double AnimControl::
|
||||
get_frame_rate() const {
|
||||
return get_play_rate() * get_anim()->get_base_frame_rate();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimControl::get_frame
|
||||
// Access: Published
|
||||
// Description: Returns the current frame number of the animation.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int AnimControl::
|
||||
get_frame() const {
|
||||
// We have to use floor() here instead of simply casting the number
|
||||
// to an integer, becase the frame number might have become
|
||||
// negative.
|
||||
return (int)cfloor(_frame + 0.0001);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimControl::get_num_frames
|
||||
// Access: Published
|
||||
// Description: Returns the number of frames of animation. This is
|
||||
// actually just extracted directly from the AnimBundle;
|
||||
// the function is duplicated here for convenience. The
|
||||
// frame number will never be outside the range 0 <=
|
||||
// frame < get_num_frames().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int AnimControl::
|
||||
get_num_frames() const {
|
||||
return get_anim()->get_num_frames();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimControl::is_playing
|
||||
// Access: Published
|
||||
// Description: Returns true if the AnimControl is currently playing,
|
||||
// false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool AnimControl::
|
||||
is_playing() const {
|
||||
return _playing;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimControl::get_anim
|
||||
|
|
|
|||
|
|
@ -16,16 +16,11 @@
|
|||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "animControl.h"
|
||||
#include "animChannelBase.h"
|
||||
#include "partBundle.h"
|
||||
#include "config_chan.h"
|
||||
|
||||
#include "event.h"
|
||||
#include "throw_event.h"
|
||||
|
||||
|
||||
TypeHandle AnimControl::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -42,18 +37,15 @@ AnimControl(PartBundle *part, AnimBundle *anim, int channel_index) {
|
|||
_part = part;
|
||||
_anim = anim;
|
||||
_channel_index = channel_index;
|
||||
|
||||
_play_rate = 1.0f;
|
||||
_frame = 0.0f;
|
||||
_as_of_time = 0.0f;
|
||||
_playing = false;
|
||||
set_frame_rate(_anim->get_base_frame_rate());
|
||||
set_num_frames(_anim->get_num_frames());
|
||||
|
||||
_marked_frame = -1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimControl::Destructor
|
||||
// Access: Published
|
||||
// Access: Published, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
AnimControl::
|
||||
|
|
@ -61,296 +53,6 @@ AnimControl::
|
|||
get_part()->set_control_effect(this, 0.0f);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimControl::play
|
||||
// Access: Published
|
||||
// Description: Runs the entire animation from beginning to end and
|
||||
// stops, throwing the stop event (if it is non-NULL).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AnimControl::
|
||||
play(const CPT_Event &stop_event) {
|
||||
nassertv(get_num_frames() > 0);
|
||||
|
||||
if (get_play_rate() < 0.0f) {
|
||||
play(get_num_frames()-1, 0, stop_event);
|
||||
} else {
|
||||
play(0, get_num_frames()-1, stop_event);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimControl::play
|
||||
// Access: Published
|
||||
// Description: Runs the animation from the frame "from" to and
|
||||
// including the frame "to", at which point the
|
||||
// animation is stopped and the indicated stop event is
|
||||
// thrown (if it is non-NULL). If the to frame is less
|
||||
// than the from frame (unless play_rate is negative),
|
||||
// the animation will wrap around the end and begins
|
||||
// again at the beginning before the animation stops.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AnimControl::
|
||||
play(int from, int to, const CPT_Event &stop_event) {
|
||||
nassertv(get_num_frames() > 0);
|
||||
|
||||
nassertv(from >= 0 && from < get_num_frames());
|
||||
nassertv(to >= 0 && to < get_num_frames());
|
||||
_as_of_time = ClockObject::get_global_clock()->get_frame_time();
|
||||
_playing = true;
|
||||
|
||||
_actions = _user_actions;
|
||||
if (stop_event != (Event*)0L) {
|
||||
insert_event_action(_actions, to, stop_event);
|
||||
}
|
||||
insert_stop_action(_actions, to);
|
||||
|
||||
get_part()->control_activated(this);
|
||||
set_frame(from);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimControl::loop
|
||||
// Access: Published
|
||||
// Description: Starts the entire animation looping. If restart is
|
||||
// true, the animation is restarted from the beginning;
|
||||
// otherwise, it continues from the current frame.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AnimControl::
|
||||
loop(bool restart) {
|
||||
nassertv(get_num_frames() > 0);
|
||||
|
||||
_as_of_time = ClockObject::get_global_clock()->get_frame_time();
|
||||
_playing = true;
|
||||
|
||||
_actions = _user_actions;
|
||||
get_part()->control_activated(this);
|
||||
|
||||
if (restart) {
|
||||
if (get_play_rate() < 0.0f) {
|
||||
set_frame(get_num_frames() - 1);
|
||||
} else {
|
||||
set_frame(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimControl::loop
|
||||
// Access: Published
|
||||
// Description: Loops the animation from the frame "from" to and
|
||||
// including the frame "to", indefinitely. If restart
|
||||
// is true, the animation is restarted from the
|
||||
// beginning; otherwise, it continues from the current
|
||||
// frame.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AnimControl::
|
||||
loop(bool restart, int from, int to) {
|
||||
nassertv(get_num_frames() > 0);
|
||||
|
||||
nassertv(from >= 0 && from < get_num_frames());
|
||||
nassertv(to >= 0 && to < get_num_frames());
|
||||
_as_of_time = ClockObject::get_global_clock()->get_frame_time();
|
||||
_playing = true;
|
||||
|
||||
_actions = _user_actions;
|
||||
|
||||
if (get_play_rate() < 0.0f) {
|
||||
// If we're playing backward, we need to set up the loop a little
|
||||
// differently.
|
||||
|
||||
if ((to == 0 && from == get_num_frames()-1) ||
|
||||
(to == from-1)) {
|
||||
|
||||
// In this case, the user has specified to loop over the whole
|
||||
// range of animation. We don't need a special jump action to
|
||||
// handle this.
|
||||
|
||||
} else {
|
||||
// Otherwise, set up a jump action to effect the loop. This isn't
|
||||
// completely accurate, since it will always jump exactly to the
|
||||
// first frame of the loop, no matter how many frames past the end
|
||||
// we'd gotten to, but it should be reasonably close, especially
|
||||
// if the number of frames in the loop is large enough and/or the
|
||||
// frame rate is high enough.
|
||||
insert_jump_action(_actions, (to-1+get_num_frames())%get_num_frames(),
|
||||
from);
|
||||
}
|
||||
} else {
|
||||
|
||||
if ((from == 0 && to == get_num_frames()-1) ||
|
||||
(from == to-1)) {
|
||||
|
||||
// In this case, the user has specified to loop over the whole
|
||||
// range of animation. We don't need a special jump action to
|
||||
// handle this.
|
||||
|
||||
} else {
|
||||
// Otherwise, set up a jump action to effect the loop. This isn't
|
||||
// completely accurate, since it will always jump exactly to the
|
||||
// first frame of the loop, no matter how many frames past the end
|
||||
// we'd gotten to, but it should be reasonably close, especially
|
||||
// if the number of frames in the loop is large enough and/or the
|
||||
// frame rate is high enough.
|
||||
insert_jump_action(_actions, (to+1)%get_num_frames(), from);
|
||||
}
|
||||
}
|
||||
|
||||
get_part()->control_activated(this);
|
||||
if (restart) {
|
||||
set_frame(from);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimControl::pingpong
|
||||
// Access: Published
|
||||
// Description: Loops the animation from the frame "from" to and
|
||||
// including the frame "to", and then back in the
|
||||
// opposite direction, indefinitely.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AnimControl::
|
||||
pingpong(bool restart, int from, int to) {
|
||||
if (from == to) {
|
||||
pose(from);
|
||||
return;
|
||||
}
|
||||
|
||||
nassertv(get_num_frames() > 0);
|
||||
|
||||
nassertv(from >= 0 && from < get_num_frames());
|
||||
nassertv(to >= 0 && to < get_num_frames());
|
||||
_as_of_time = ClockObject::get_global_clock()->get_frame_time();
|
||||
_playing = true;
|
||||
|
||||
_actions = _user_actions;
|
||||
|
||||
insert_forward_action(_actions, from);
|
||||
insert_backward_action(_actions, to);
|
||||
|
||||
get_part()->control_activated(this);
|
||||
if (restart) {
|
||||
set_frame(from);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimControl::stop
|
||||
// Access: Published
|
||||
// Description: Stops a currently playing or looping animation right
|
||||
// where it is. The animation remains posed at the
|
||||
// current frame, and no event is thrown.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AnimControl::
|
||||
stop() {
|
||||
_playing = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimControl::pose
|
||||
// Access: Published
|
||||
// Description: Sets the animation to the indicated frame and holds
|
||||
// it there.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AnimControl::
|
||||
pose(int frame) {
|
||||
int num_frames = get_num_frames();
|
||||
nassertv(num_frames > 0);
|
||||
|
||||
// Modulo the number of frames.
|
||||
frame = (int)(frame - cfloor(frame / num_frames) * num_frames);
|
||||
nassertv(frame >= 0 && frame < num_frames);
|
||||
_as_of_time = ClockObject::get_global_clock()->get_frame_time();
|
||||
_playing = false;
|
||||
|
||||
_actions = _user_actions;
|
||||
|
||||
get_part()->control_activated(this);
|
||||
set_frame(frame);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimControl::add_event
|
||||
// Access: Published
|
||||
// Description: Adds the indicated event to the list of events that
|
||||
// will be called whenever the animation reaches the
|
||||
// indicated frame number. Once added, the event will
|
||||
// persist until it is removed via remove_event() or
|
||||
// remove_all_events().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AnimControl::
|
||||
add_event(int frame, const CPT_Event &event) {
|
||||
insert_event_action(_user_actions, frame, event);
|
||||
if (_playing) {
|
||||
insert_event_action(_actions, frame, event);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimControl::remove_event
|
||||
// Access: Published
|
||||
// Description: Removes all events found that match the indicated
|
||||
// event name, and returns the number of events
|
||||
// removed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int AnimControl::
|
||||
remove_event(const string &event_name) {
|
||||
Actions new_actions;
|
||||
|
||||
int removed = 0;
|
||||
|
||||
Actions::const_iterator ai;
|
||||
for (ai = _user_actions.begin(); ai != _user_actions.end(); ++ai) {
|
||||
const Action &action = (*ai).second;
|
||||
if (action._type == AT_event &&
|
||||
action._event->get_name() == event_name) {
|
||||
// Remove this event by not copying it to new_actions.
|
||||
removed++;
|
||||
} else {
|
||||
// Preserve this event.
|
||||
new_actions.insert(*ai);
|
||||
}
|
||||
}
|
||||
|
||||
if (removed != 0) {
|
||||
_user_actions.swap(new_actions);
|
||||
|
||||
if (_playing) {
|
||||
new_actions.clear();
|
||||
int p_removed = 0;
|
||||
for (ai = _actions.begin(); ai != _actions.end(); ++ai) {
|
||||
const Action &action = (*ai).second;
|
||||
if (action._type == AT_event &&
|
||||
action._event->get_name() == event_name) {
|
||||
// Remove this event by not copying it to new_actions.
|
||||
p_removed++;
|
||||
} else {
|
||||
// Preserve this event.
|
||||
new_actions.insert(*ai);
|
||||
}
|
||||
}
|
||||
nassertr(p_removed == removed, removed);
|
||||
_actions.swap(new_actions);
|
||||
}
|
||||
}
|
||||
|
||||
return removed;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimControl::remove_all_events
|
||||
// Access: Published
|
||||
// Description: Removes all user-defined event messages. However, if
|
||||
// called while an animation is running, this will not
|
||||
// take effect until the animation is stopped and
|
||||
// restarted.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AnimControl::
|
||||
remove_all_events() {
|
||||
_user_actions.clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimControl::get_part
|
||||
// Access: Published
|
||||
|
|
@ -370,77 +72,11 @@ get_part() const {
|
|||
void AnimControl::
|
||||
output(ostream &out) const {
|
||||
out << "AnimControl(" << get_part()->get_name()
|
||||
<< ", " << get_anim()->get_name() << ")";
|
||||
<< ", " << get_anim()->get_name() << ": ";
|
||||
AnimInterface::output(out);
|
||||
out << ")";
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimControl::advance_time
|
||||
// Access: Public
|
||||
// Description: Tells the AnimControl what time it is. This
|
||||
// recomputes the frame number according to the amount
|
||||
// of time elapsed since last time. Until this function
|
||||
// is called, the frame number will not increment. The
|
||||
// time passed to this function must be nondecreasing;
|
||||
// it is an error to call it with a value less than a
|
||||
// previously-passed value.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AnimControl::
|
||||
advance_time(double time) {
|
||||
double elapsed_time = time - _as_of_time;
|
||||
double elapsed_frames = elapsed_time * get_frame_rate();
|
||||
_as_of_time = time;
|
||||
|
||||
if (_playing && elapsed_frames != 0.0f) {
|
||||
int orig_frame = get_frame();
|
||||
|
||||
_frame += elapsed_frames;
|
||||
double num_frames = (double)get_num_frames();
|
||||
|
||||
int new_frame = get_frame();
|
||||
|
||||
// Now call all the actions.
|
||||
if (elapsed_frames < 0.0f) {
|
||||
// If we're playing the animation backward, we have to check the
|
||||
// actions in reverse order.
|
||||
|
||||
if (new_frame >= 0) {
|
||||
do_actions_backward(orig_frame-1, new_frame);
|
||||
} else {
|
||||
if (do_actions_backward(orig_frame-1, 0)) {
|
||||
// floor() is correct here, instead of simply an integer
|
||||
// cast, because we are using floating-point arithmetic
|
||||
// anyway (no need to convert to integer format and back
|
||||
// again), and because we need correct behavior when the
|
||||
// frame number is negative.
|
||||
_frame = _frame - cfloor(_frame / num_frames) * num_frames;
|
||||
new_frame = get_frame();
|
||||
do_actions_backward(get_num_frames(), new_frame);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Normally, we'll be playing the animation forward.
|
||||
|
||||
if (new_frame < get_num_frames()) {
|
||||
do_actions_forward(orig_frame+1, new_frame);
|
||||
} else {
|
||||
if (do_actions_forward(orig_frame+1, get_num_frames()-1)) {
|
||||
// floor() is correct here, instead of simply an integer
|
||||
// cast, because we are using floating-point arithmetic
|
||||
// anyway (no need to convert to integer format and back
|
||||
// again), and because we need correct behavior when the
|
||||
// frame number is negative.
|
||||
_frame = _frame - cfloor(_frame / num_frames) * num_frames;
|
||||
new_frame = get_frame();
|
||||
do_actions_forward(0, new_frame);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimControl::channel_has_changed
|
||||
// Access: Public
|
||||
|
|
@ -457,7 +93,6 @@ channel_has_changed(AnimChannelBase *channel) const {
|
|||
return channel->has_changed(_marked_frame, this_frame);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimControl::mark_channels
|
||||
// Access: Public
|
||||
|
|
@ -469,307 +104,14 @@ mark_channels() {
|
|||
_marked_frame = get_frame();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimControl::insert_event_action
|
||||
// Access: Private, Static
|
||||
// Description: Inserts an "event" action at the indicated frame
|
||||
// number. The event will be thrown as the animation
|
||||
// reaches the indicated frame number.
|
||||
// Function: AnimControl::animation_activated
|
||||
// Access: Protected, Virtual
|
||||
// Description: This is provided as a callback method for when the
|
||||
// user calls one of the play/loop/pose type methods to
|
||||
// start the animation playing.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AnimControl::
|
||||
insert_event_action(Actions &actions, int frame, const CPT_Event &event) {
|
||||
Action new_action;
|
||||
new_action._type = AT_event;
|
||||
new_action._event = event;
|
||||
actions.insert(pair<int, Action>(frame, new_action));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimControl::insert_stop_action
|
||||
// Access: Private, Static
|
||||
// Description: Inserts a "stop" action at the indicated frame
|
||||
// number. The animation will stop as soon as it
|
||||
// reaches the indicated frame number, traveling from
|
||||
// either direction.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AnimControl::
|
||||
insert_stop_action(Actions &actions, int frame) {
|
||||
Action new_action;
|
||||
new_action._type = AT_stop;
|
||||
actions.insert(pair<int, Action>(frame, new_action));
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimControl::insert_jump_action
|
||||
// Access: Private, Static
|
||||
// Description: Inserts a "jump" action at the indicated frame
|
||||
// number. When the animation reaches the indicated
|
||||
// frame number, it will jump to the indicated jump_to
|
||||
// frame. It will not seem to spend any time at the
|
||||
// reached frame number.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AnimControl::
|
||||
insert_jump_action(Actions &actions, int frame, int jump_to) {
|
||||
Action new_action;
|
||||
new_action._type = AT_jump;
|
||||
new_action._jump_to = jump_to;
|
||||
actions.insert(pair<int, Action>(frame, new_action));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimControl::insert_forward_action
|
||||
// Access: Private, Static
|
||||
// Description: Inserts a "forward" action at the indicated frame
|
||||
// number. When the animation hits this action while
|
||||
// playing in a backward direction, it will stop and
|
||||
// play in a forward direction instead.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AnimControl::
|
||||
insert_forward_action(Actions &actions, int frame) {
|
||||
Action new_action;
|
||||
new_action._type = AT_forward;
|
||||
actions.insert(pair<int, Action>(frame, new_action));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimControl::insert_backward_action
|
||||
// Access: Private, Static
|
||||
// Description: Inserts a "backward" action at the indicated frame
|
||||
// number. When the animation hits this action while
|
||||
// playing in a forward direction, it will stop and
|
||||
// play in a backward direction instead.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AnimControl::
|
||||
insert_backward_action(Actions &actions, int frame) {
|
||||
Action new_action;
|
||||
new_action._type = AT_backward;
|
||||
actions.insert(pair<int, Action>(frame, new_action));
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimControl::set_frame
|
||||
// Access: Private
|
||||
// Description: Sets the current frame number to the indicated frame,
|
||||
// and performs any actions on that frame.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AnimControl::
|
||||
set_frame(double frame) {
|
||||
_frame = frame;
|
||||
int iframe = get_frame();
|
||||
do_actions_forward(iframe, iframe);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimControl::do_actions_forward
|
||||
// Access: Private
|
||||
// Description: Calls each of the actions, in turn, on the timeline
|
||||
// between the indicated "from" frame and the indicated
|
||||
// "to" frame, inclusive. If any of the actions
|
||||
// specifies to stop the animation, the animation is
|
||||
// stopped, the current frame number is set to the point
|
||||
// of stopping, no further actions are called, and false
|
||||
// is returned. Otherwise, true is returned.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool AnimControl::
|
||||
do_actions_forward(int from, int to) {
|
||||
if (to >= from) {
|
||||
Actions::const_iterator lower = _actions.lower_bound(from);
|
||||
Actions::const_iterator upper = _actions.lower_bound(to+1);
|
||||
|
||||
int sequence_frame = -1;
|
||||
const Action *sequence_action;
|
||||
|
||||
Actions::const_iterator ai;
|
||||
for (ai = lower; ai != upper; ++ai) {
|
||||
int frame = (*ai).first;
|
||||
const Action &action = (*ai).second;
|
||||
|
||||
if (sequence_frame != -1 && frame > sequence_frame) {
|
||||
// We encountered an action that resequenced our frame numbers.
|
||||
// Now that we've finished evaluating all the other actions that
|
||||
// occurred in the same frame, evaluate this one action and
|
||||
// exit.
|
||||
do_sequence_action(sequence_frame, *sequence_action);
|
||||
return false;
|
||||
}
|
||||
|
||||
do_action(frame, action, sequence_frame, sequence_action);
|
||||
}
|
||||
|
||||
if (sequence_frame != -1) {
|
||||
do_sequence_action(sequence_frame, *sequence_action);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimControl::do_actions_backward
|
||||
// Access: Private
|
||||
// Description: Calls each of the actions, in turn, on the timeline
|
||||
// between the indicated "from" frame and the indicated
|
||||
// "to" frame, in reverse order. If any of the actions
|
||||
// specifies to stop the animation, the animation is
|
||||
// stopped, the current frame number is set to the point
|
||||
// of stopping, no further actions are called, and false
|
||||
// is returned. Otherwise, true is returned.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool AnimControl::
|
||||
do_actions_backward(int from, int to) {
|
||||
if (from >= to) {
|
||||
#if defined(WIN32_VC) && !defined(NO_PCH)
|
||||
typedef Actions::const_reverse_iterator Action_reverse_iterator;
|
||||
#else
|
||||
typedef reverse_iterator<Actions::const_iterator> Action_reverse_iterator;
|
||||
#endif
|
||||
Action_reverse_iterator lower(_actions.upper_bound(from));
|
||||
Action_reverse_iterator upper(_actions.upper_bound(to-1));
|
||||
|
||||
int sequence_frame = -1;
|
||||
const Action *sequence_action;
|
||||
|
||||
Action_reverse_iterator ai;
|
||||
for (ai = lower; ai != upper; ++ai) {
|
||||
int frame = (*ai).first;
|
||||
const Action &action = (*ai).second;
|
||||
|
||||
if (sequence_frame != -1 && frame < sequence_frame) {
|
||||
// We encountered an action that resequenced our frame numbers.
|
||||
// Now that we've finished evaluating all the other actions that
|
||||
// occurred in the same frame, evaluate this one action and
|
||||
// exit.
|
||||
do_sequence_action(sequence_frame, *sequence_action);
|
||||
return false;
|
||||
}
|
||||
|
||||
do_action(frame, action, sequence_frame, sequence_action);
|
||||
}
|
||||
|
||||
if (sequence_frame != -1) {
|
||||
do_sequence_action(sequence_frame, *sequence_action);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimControl::do_action
|
||||
// Access: Private
|
||||
// Description: Performs a single action. If the action involves
|
||||
// some resequencing behavior--stopping, or jumping
|
||||
// around to a new frame or something--does nothing
|
||||
// immediately, but instead sets sequence_frame and
|
||||
// sequence_action to the current frame number and
|
||||
// action, so they may be executed later (after all the
|
||||
// other actions this frame have been executed).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AnimControl::
|
||||
do_action(int frame, const Action &action,
|
||||
int &sequence_frame, const Action *&sequence_action) {
|
||||
switch (action._type) {
|
||||
case AT_stop:
|
||||
case AT_jump:
|
||||
sequence_frame = frame;
|
||||
sequence_action = &action;
|
||||
break;
|
||||
|
||||
case AT_forward:
|
||||
// We only see "forward" actions if we're currently playing
|
||||
// backwards.
|
||||
if (_play_rate < 0.0f) {
|
||||
sequence_frame = frame;
|
||||
sequence_action = &action;
|
||||
}
|
||||
break;
|
||||
|
||||
case AT_backward:
|
||||
// We only see "backward" actions if we're currently playing
|
||||
// forwards.
|
||||
if (_play_rate > 0.0f) {
|
||||
sequence_frame = frame;
|
||||
sequence_action = &action;
|
||||
}
|
||||
break;
|
||||
|
||||
case AT_event:
|
||||
throw_event(action._event);
|
||||
break;
|
||||
|
||||
default:
|
||||
chan_cat.error() << "Invalid action!\n";
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimControl::do_sequence_action
|
||||
// Access: Private
|
||||
// Description: Performs an action that was saved from do_action(),
|
||||
// above. This action presumably does some mucking
|
||||
// around with the frame number or something, so we
|
||||
// needed to do all the other actions associated with
|
||||
// that frame first.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AnimControl::
|
||||
do_sequence_action(int frame, const Action &action) {
|
||||
switch (action._type) {
|
||||
case AT_stop:
|
||||
stop();
|
||||
break;
|
||||
|
||||
case AT_jump:
|
||||
set_frame(action._jump_to);
|
||||
break;
|
||||
|
||||
case AT_forward:
|
||||
case AT_backward:
|
||||
_play_rate = -_play_rate;
|
||||
set_frame(frame);
|
||||
break;
|
||||
|
||||
case AT_event:
|
||||
default:
|
||||
chan_cat.error() << "Invalid sequence action!\n";
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimControl::Action::output
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AnimControl::Action::
|
||||
output(ostream &out) const {
|
||||
switch (_type) {
|
||||
case AT_event:
|
||||
out << "event " << *_event;
|
||||
break;
|
||||
|
||||
case AT_stop:
|
||||
out << "stop";
|
||||
break;
|
||||
|
||||
case AT_jump:
|
||||
out << "jump to " << _jump_to;
|
||||
break;
|
||||
|
||||
case AT_forward:
|
||||
out << "forward";
|
||||
break;
|
||||
|
||||
case AT_backward:
|
||||
out << "backward";
|
||||
break;
|
||||
|
||||
default:
|
||||
out << "**error**";
|
||||
}
|
||||
animation_activated() {
|
||||
get_part()->control_activated(this);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,17 +21,11 @@
|
|||
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "animInterface.h"
|
||||
#include "animBundle.h"
|
||||
#include "partGroup.h"
|
||||
|
||||
#include "clockObject.h"
|
||||
#include "typedef.h"
|
||||
#include "referenceCount.h"
|
||||
#include "event.h"
|
||||
#include "pt_Event.h"
|
||||
#include "cmath.h"
|
||||
#include <string>
|
||||
#include "pmap.h"
|
||||
|
||||
class PartBundle;
|
||||
class AnimChannelBase;
|
||||
|
|
@ -44,93 +38,31 @@ class AnimChannelBase;
|
|||
// animation: whether started, stopped, or looping, and
|
||||
// the current frame number and play rate.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA AnimControl : public ReferenceCount {
|
||||
class EXPCL_PANDA AnimControl : public ReferenceCount, public AnimInterface {
|
||||
public:
|
||||
AnimControl(PartBundle *part, AnimBundle *anim, int channel_index);
|
||||
|
||||
PUBLISHED:
|
||||
~AnimControl();
|
||||
void play(const CPT_Event &stop_event = NULL);
|
||||
void play(int from, int to, const CPT_Event &stop_event = NULL);
|
||||
void loop(bool restart);
|
||||
void loop(bool restart, int from, int to);
|
||||
void pingpong(bool restart, int from, int to);
|
||||
void stop();
|
||||
void pose(int frame);
|
||||
|
||||
void add_event(int frame, const CPT_Event &event);
|
||||
int remove_event(const string &event_name);
|
||||
void remove_all_events();
|
||||
|
||||
INLINE void set_play_rate(double play_rate);
|
||||
INLINE double get_play_rate() const;
|
||||
INLINE double get_frame_rate() const;
|
||||
|
||||
INLINE int get_frame() const;
|
||||
INLINE int get_num_frames() const;
|
||||
|
||||
INLINE bool is_playing() const;
|
||||
virtual ~AnimControl();
|
||||
|
||||
PartBundle *get_part() const;
|
||||
INLINE AnimBundle *get_anim() const;
|
||||
INLINE int get_channel_index() const;
|
||||
|
||||
void output(ostream &out) const;
|
||||
virtual void output(ostream &out) const;
|
||||
|
||||
public:
|
||||
// The following functions aren't really part of the public
|
||||
// interface; they're just public so we don't have to declare a
|
||||
// bunch of friends.
|
||||
|
||||
void advance_time(double time);
|
||||
|
||||
bool channel_has_changed(AnimChannelBase *channel) const;
|
||||
void mark_channels();
|
||||
|
||||
private:
|
||||
|
||||
enum ActionType {
|
||||
AT_event,
|
||||
AT_stop,
|
||||
AT_jump,
|
||||
AT_forward,
|
||||
AT_backward,
|
||||
};
|
||||
|
||||
#ifdef WIN32_VC
|
||||
public:
|
||||
#endif
|
||||
|
||||
class EXPCL_PANDA Action {
|
||||
public:
|
||||
ActionType _type;
|
||||
CPT_Event _event;
|
||||
int _jump_to;
|
||||
|
||||
void output(ostream &out) const;
|
||||
};
|
||||
protected:
|
||||
virtual void animation_activated();
|
||||
|
||||
private:
|
||||
typedef pmultimap<int, Action> Actions;
|
||||
|
||||
static void insert_event_action(Actions &actions, int frame, const CPT_Event &event);
|
||||
static void insert_stop_action(Actions &actions, int frame);
|
||||
static void insert_jump_action(Actions &actions, int frame, int jump_to);
|
||||
static void insert_forward_action(Actions &actions, int frame);
|
||||
static void insert_backward_action(Actions &actions, int frame);
|
||||
|
||||
void set_frame(double frame);
|
||||
|
||||
bool do_actions_forward(int from, int to);
|
||||
bool do_actions_backward(int from, int to);
|
||||
|
||||
void do_action(int frame, const Action &action,
|
||||
int &sequence_frame, const Action *&sequence_action);
|
||||
void do_sequence_action(int frame, const Action &action);
|
||||
|
||||
Actions _actions;
|
||||
Actions _user_actions;
|
||||
|
||||
// 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.
|
||||
|
|
@ -138,17 +70,6 @@ private:
|
|||
PT(AnimBundle) _anim;
|
||||
int _channel_index;
|
||||
|
||||
double _play_rate;
|
||||
|
||||
// We keep a floating-point frame number. This increments fluidly,
|
||||
// and records honest "between-frame" increments. However, whenever
|
||||
// we report the current frame number, we just report the integer
|
||||
// portion.
|
||||
double _frame;
|
||||
double _as_of_time;
|
||||
|
||||
bool _playing;
|
||||
|
||||
// This is the frame number as of the last call to mark_channels().
|
||||
int _marked_frame;
|
||||
|
||||
|
|
@ -158,27 +79,16 @@ public:
|
|||
}
|
||||
static void init_type() {
|
||||
ReferenceCount::init_type();
|
||||
AnimInterface::init_type();
|
||||
register_type(_type_handle, "AnimControl",
|
||||
ReferenceCount::get_class_type());
|
||||
ReferenceCount::get_class_type(),
|
||||
AnimInterface::get_class_type());
|
||||
}
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
|
||||
friend inline ostream &operator << (ostream &, const AnimControl::Action &);
|
||||
friend class AnimControl::Action;
|
||||
};
|
||||
|
||||
inline ostream &operator << (ostream &out, const AnimControl &ac) {
|
||||
ac.output(out);
|
||||
return out;
|
||||
}
|
||||
|
||||
inline ostream &operator << (ostream &out, const AnimControl::Action &action) {
|
||||
action.output(out);
|
||||
return out;
|
||||
}
|
||||
|
||||
#include "animControl.I"
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -17,60 +17,6 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimControlCollection::set_stop_event
|
||||
// Access: Public
|
||||
// Description: Sets the event that will be thrown when the next
|
||||
// animation that is played eventually comes to a stop.
|
||||
// Setting this does not affect any stop event that is
|
||||
// pending from a previously-started animation.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void AnimControlCollection::
|
||||
set_stop_event(const CPT_Event &stop_event) {
|
||||
_stop_event = stop_event;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimControlCollection::clear_stop_event
|
||||
// Access: Public
|
||||
// Description: Indicates that the next-started animation will not
|
||||
// throw a stop event when it comes to a stop. This
|
||||
// does not affect any already-started animations.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void AnimControlCollection::
|
||||
clear_stop_event() {
|
||||
_stop_event = (const Event *)NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimControlCollection::has_stop_event
|
||||
// Access: Public
|
||||
// Description: Returns true if a stop event has been established via
|
||||
// set_stop_event(). If true, this means that
|
||||
// animations that are to be started in the future will
|
||||
// throw this event when they stop. However, it does
|
||||
// not necessarily mean that the currently-playing
|
||||
// animation will throw this event.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool AnimControlCollection::
|
||||
has_stop_event() const {
|
||||
return (_stop_event != (const Event *)NULL);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimControlCollection::get_stop_event
|
||||
// Access: Public
|
||||
// Description: Returns the event that has been established via
|
||||
// set_stop_event(). This is the event that will be
|
||||
// thrown by animations that are started in the future
|
||||
// when they stop. However, this may or may not be
|
||||
// associated with any currently-playing animations.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CPT_Event AnimControlCollection::
|
||||
get_stop_event() const {
|
||||
return _stop_event;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimControlCollection::play
|
||||
// Access: Public
|
||||
|
|
@ -83,7 +29,7 @@ play(const string &anim_name) {
|
|||
return false;
|
||||
}
|
||||
_last_started_control = control;
|
||||
control->play(_stop_event);
|
||||
control->play();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -99,7 +45,7 @@ play(const string &anim_name, int from, int to) {
|
|||
return false;
|
||||
}
|
||||
_last_started_control = control;
|
||||
control->play(from, to, _stop_event);
|
||||
control->play(from, to);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -52,11 +52,6 @@ PUBLISHED:
|
|||
string get_anim_name(int n) const;
|
||||
void clear_anims();
|
||||
|
||||
INLINE void set_stop_event(const CPT_Event &stop_event);
|
||||
INLINE void clear_stop_event();
|
||||
INLINE bool has_stop_event() const;
|
||||
INLINE CPT_Event get_stop_event() const;
|
||||
|
||||
// The following functions are convenience functions that vector
|
||||
// directly into the AnimControl's functionality by anim name.
|
||||
|
||||
|
|
@ -100,7 +95,6 @@ private:
|
|||
typedef pmap<string, size_t> ControlsByName;
|
||||
ControlsByName _controls_by_name;
|
||||
|
||||
CPT_Event _stop_event;
|
||||
AnimControl *_last_started_control;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -326,21 +326,6 @@ bind_anim(AnimBundle *anim, const string &name,
|
|||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PartBundle::advance_time
|
||||
// Access: Public
|
||||
// Description: Calls advance_time() on all AnimControls currently
|
||||
// in effect.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PartBundle::
|
||||
advance_time(double time) {
|
||||
ChannelBlend::const_iterator cbi;
|
||||
for (cbi = _blend.begin(); cbi != _blend.end(); ++cbi) {
|
||||
AnimControl *control = (*cbi).first;
|
||||
control->advance_time(time);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PartBundle::update
|
||||
// Access: Public
|
||||
|
|
|
|||
|
|
@ -123,7 +123,6 @@ public:
|
|||
// interface; they're just public so we don't have to declare a
|
||||
// bunch of friends.
|
||||
|
||||
void advance_time(double time);
|
||||
bool update();
|
||||
bool force_update();
|
||||
virtual void control_activated(AnimControl *control);
|
||||
|
|
|
|||
|
|
@ -160,10 +160,8 @@ cull_callback(CullTraverser *, CullTraverserData &) {
|
|||
|
||||
PStatTimer timer(_joints_pcollector);
|
||||
|
||||
double now = ClockObject::get_global_clock()->get_frame_time();
|
||||
get_bundle()->advance_time(now);
|
||||
|
||||
if (char_cat.is_spam()) {
|
||||
double now = ClockObject::get_global_clock()->get_frame_time();
|
||||
char_cat.spam() << "Animating " << *this << " at time " << now << "\n";
|
||||
}
|
||||
|
||||
|
|
@ -183,10 +181,8 @@ cull_callback(CullTraverser *, CullTraverserData &) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void Character::
|
||||
update_to_now() {
|
||||
double now = ClockObject::get_global_clock()->get_frame_time();
|
||||
get_bundle()->advance_time(now);
|
||||
|
||||
if (char_cat.is_spam()) {
|
||||
double now = ClockObject::get_global_clock()->get_frame_time();
|
||||
char_cat.spam() << "Animating " << *this << " at time " << now << "\n";
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#define LOCAL_LIBS express pandabase
|
||||
#define OTHER_LIBS interrogatedb:c dconfig:c dtoolconfig:m \
|
||||
dtoolutil:c dtoolbase:c dtool:m
|
||||
#define USE_PACKAGES zlib net ssl
|
||||
#define USE_PACKAGES zlib net openssl
|
||||
|
||||
#begin lib_target
|
||||
#define TARGET downloader
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
#include "bioPtr.h"
|
||||
#include "urlSpec.h"
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef HAVE_OPENSSL
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BioPtr::Constructor
|
||||
|
|
@ -55,4 +55,4 @@ BioPtr::
|
|||
}
|
||||
}
|
||||
|
||||
#endif // HAVE_SSL
|
||||
#endif // HAVE_OPENSSL
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
#include "pandabase.h"
|
||||
|
||||
// This module is not compiled if OpenSSL is not available.
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef HAVE_OPENSSL
|
||||
#define OPENSSL_NO_KRB5
|
||||
|
||||
#include "referenceCount.h"
|
||||
|
|
@ -63,7 +63,7 @@ private:
|
|||
|
||||
#include "bioPtr.I"
|
||||
|
||||
#endif // HAVE_SSL
|
||||
#endif // HAVE_OPENSSL
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
#include "bioStream.h"
|
||||
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef HAVE_OPENSSL
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: IBioStream::is_closed
|
||||
|
|
@ -104,4 +104,4 @@ close() {
|
|||
_buf.close();
|
||||
}
|
||||
|
||||
#endif // HAVE_SSL
|
||||
#endif // HAVE_OPENSSL
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
#include "pandabase.h"
|
||||
|
||||
// This module is not compiled if OpenSSL is not available.
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef HAVE_OPENSSL
|
||||
|
||||
#include "socketStream.h"
|
||||
#include "bioStreamBuf.h"
|
||||
|
|
@ -94,7 +94,7 @@ private:
|
|||
|
||||
#include "bioStream.I"
|
||||
|
||||
#endif // HAVE_SSL
|
||||
#endif // HAVE_OPENSSL
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
#include "ssl_utils.h"
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef HAVE_OPENSSL
|
||||
|
||||
#ifndef HAVE_STREAMSIZE
|
||||
// Some compilers (notably SGI) don't define this for us
|
||||
|
|
@ -275,4 +275,4 @@ write_chars(const char *start, size_t length) {
|
|||
return length;
|
||||
}
|
||||
|
||||
#endif // HAVE_SSL
|
||||
#endif // HAVE_OPENSSL
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
#include "pandabase.h"
|
||||
|
||||
// This module is not compiled if OpenSSL is not available.
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef HAVE_OPENSSL
|
||||
#define OPENSSL_NO_KRB5
|
||||
|
||||
#include "bioPtr.h"
|
||||
|
|
@ -58,6 +58,6 @@ private:
|
|||
friend class BioStream;
|
||||
};
|
||||
|
||||
#endif // HAVE_SSL
|
||||
#endif // HAVE_OPENSSL
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
#include "bioStreamPtr.h"
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef HAVE_OPENSSL
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BioStreamPtr::Destructor
|
||||
|
|
@ -33,4 +33,4 @@ BioStreamPtr::
|
|||
}
|
||||
}
|
||||
|
||||
#endif // HAVE_SSL
|
||||
#endif // HAVE_OPENSSL
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
#include "pandabase.h"
|
||||
|
||||
// This module is not compiled if OpenSSL is not available.
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef HAVE_OPENSSL
|
||||
#define OPENSSL_NO_KRB5
|
||||
|
||||
#include "bioStream.h"
|
||||
|
|
@ -52,7 +52,7 @@ private:
|
|||
|
||||
#include "bioStreamPtr.I"
|
||||
|
||||
#endif // HAVE_SSL
|
||||
#endif // HAVE_OPENSSL
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
#include "chunkedStream.h"
|
||||
|
||||
// This module is not compiled if OpenSSL is not available.
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef HAVE_OPENSSL
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: IChunkedStream::is_closed
|
||||
|
|
@ -48,4 +48,4 @@ close() {
|
|||
_buf.close_read();
|
||||
}
|
||||
|
||||
#endif // HAVE_SSL
|
||||
#endif // HAVE_OPENSSL
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
#include "pandabase.h"
|
||||
|
||||
// This module is not compiled if OpenSSL is not available.
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef HAVE_OPENSSL
|
||||
|
||||
#include "socketStream.h"
|
||||
#include "chunkedStreamBuf.h"
|
||||
|
|
@ -55,7 +55,7 @@ private:
|
|||
|
||||
#include "chunkedStream.I"
|
||||
|
||||
#endif // HAVE_SSL
|
||||
#endif // HAVE_OPENSSL
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
#include <ctype.h>
|
||||
|
||||
// This module is not compiled if OpenSSL is not available.
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef HAVE_OPENSSL
|
||||
|
||||
#ifndef HAVE_STREAMSIZE
|
||||
// Some compilers (notably SGI) don't define this for us
|
||||
|
|
@ -249,4 +249,4 @@ http_getline(string &str) {
|
|||
return false;
|
||||
}
|
||||
|
||||
#endif // HAVE_SSL
|
||||
#endif // HAVE_OPENSSL
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
#include "pandabase.h"
|
||||
|
||||
// This module is not compiled if OpenSSL is not available.
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef HAVE_OPENSSL
|
||||
|
||||
#include "httpChannel.h"
|
||||
#include "bioStreamPtr.h"
|
||||
|
|
@ -60,6 +60,6 @@ private:
|
|||
friend class IChunkedStream;
|
||||
};
|
||||
|
||||
#endif // HAVE_SSL
|
||||
#endif // HAVE_OPENSSL
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -167,7 +167,7 @@ init_libdownloader() {
|
|||
}
|
||||
initialized = true;
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef HAVE_OPENSSL
|
||||
HTTPChannel::init_type();
|
||||
|
||||
// We need to define this here, rather than above, to guarantee that
|
||||
|
|
@ -194,5 +194,5 @@ init_libdownloader() {
|
|||
|
||||
PandaSystem *ps = PandaSystem::get_global_ptr();
|
||||
ps->add_system("OpenSSL");
|
||||
#endif
|
||||
#endif // HAVE_OPENSSL
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
#include "httpChannel.h"
|
||||
#include "urlSpec.h"
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef HAVE_OPENSSL
|
||||
|
||||
static const char base64_table[64] = {
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
|
||||
|
|
@ -346,4 +346,4 @@ scan_quoted_or_unquoted_string(string &result, const string &source,
|
|||
return start;
|
||||
}
|
||||
|
||||
#endif // HAVE_SSL
|
||||
#endif // HAVE_OPENSSL
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
// actually use any OpenSSL code, because it is a support module for
|
||||
// HTTPChannel, which *does* use OpenSSL code.
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef HAVE_OPENSSL
|
||||
|
||||
#include "referenceCount.h"
|
||||
#include "httpEnum.h"
|
||||
|
|
@ -81,7 +81,7 @@ protected:
|
|||
|
||||
#include "httpAuthorization.I"
|
||||
|
||||
#endif // HAVE_SSL
|
||||
#endif // HAVE_OPENSSL
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
#include "httpBasicAuthorization.h"
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef HAVE_OPENSSL
|
||||
|
||||
const string HTTPBasicAuthorization::_mechanism = "basic";
|
||||
|
||||
|
|
@ -68,4 +68,4 @@ generate(HTTPEnum::Method, const string &,
|
|||
return "Basic " + base64_encode(username);
|
||||
}
|
||||
|
||||
#endif // HAVE_SSL
|
||||
#endif // HAVE_OPENSSL
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
// actually use any OpenSSL code, because it is a support module for
|
||||
// HTTPChannel, which *does* use OpenSSL code.
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef HAVE_OPENSSL
|
||||
|
||||
#include "httpAuthorization.h"
|
||||
|
||||
|
|
@ -53,7 +53,7 @@ private:
|
|||
|
||||
#include "httpBasicAuthorization.I"
|
||||
|
||||
#endif // HAVE_SSL
|
||||
#endif // HAVE_OPENSSL
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
#include "clockObject.h"
|
||||
#include "ramfile.h"
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef HAVE_OPENSSL
|
||||
#include <openssl/x509.h>
|
||||
|
||||
#ifdef WIN32_VC
|
||||
|
|
@ -3498,4 +3498,4 @@ operator << (ostream &out, HTTPChannel::State state) {
|
|||
#endif // NDEBUG
|
||||
}
|
||||
|
||||
#endif // HAVE_SSL
|
||||
#endif // HAVE_OPENSSL
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
// the OpenSSL library to portably handle all of the socket
|
||||
// communications.
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef HAVE_OPENSSL
|
||||
#define OPENSSL_NO_KRB5
|
||||
|
||||
#include "httpClient.h"
|
||||
|
|
@ -429,7 +429,7 @@ ostream &operator << (ostream &out, HTTPChannel::State state);
|
|||
|
||||
#include "httpChannel.I"
|
||||
|
||||
#endif // HAVE_SSL
|
||||
#endif // HAVE_OPENSSL
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@
|
|||
#include "httpDigestAuthorization.h"
|
||||
#include "globPattern.h"
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef HAVE_OPENSSL
|
||||
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/err.h>
|
||||
|
|
@ -1629,4 +1629,4 @@ ssl_msg_callback(int write_p, int version, int content_type,
|
|||
}
|
||||
#endif // defined(SSL_097) && !defined(NDEBUG)
|
||||
|
||||
#endif // HAVE_SSL
|
||||
#endif // HAVE_OPENSSL
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
// the OpenSSL library to portably handle all of the socket
|
||||
// communications.
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef HAVE_OPENSSL
|
||||
#define OPENSSL_NO_KRB5
|
||||
|
||||
#include "urlSpec.h"
|
||||
|
|
@ -207,7 +207,7 @@ private:
|
|||
|
||||
#include "httpClient.I"
|
||||
|
||||
#endif // HAVE_SSL
|
||||
#endif // HAVE_OPENSSL
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
#include "httpCookie.h"
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef HAVE_OPENSSL
|
||||
|
||||
#include "ctype.h"
|
||||
#include "httpChannel.h"
|
||||
|
|
@ -218,4 +218,4 @@ parse_cookie_param(const string ¶m, bool first_param) {
|
|||
return true;
|
||||
}
|
||||
|
||||
#endif // HAVE_SSL
|
||||
#endif // HAVE_OPENSSL
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
// the OpenSSL library to portably handle all of the socket
|
||||
// communications.
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef HAVE_OPENSSL
|
||||
|
||||
#include "httpDate.h"
|
||||
#include "urlSpec.h"
|
||||
|
|
@ -88,6 +88,6 @@ INLINE ostream &operator << (ostream &out, const HTTPCookie &cookie);
|
|||
|
||||
#include "httpCookie.I"
|
||||
|
||||
#endif // HAVE_SSL
|
||||
#endif // HAVE_OPENSSL
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
#include "httpDigestAuthorization.h"
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef HAVE_OPENSSL
|
||||
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/md5.h>
|
||||
|
|
@ -371,4 +371,4 @@ operator << (ostream &out, HTTPDigestAuthorization::Qop qop) {
|
|||
return out;
|
||||
}
|
||||
|
||||
#endif // HAVE_SSL
|
||||
#endif // HAVE_OPENSSL
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
// actually use any OpenSSL code, because it is a support module for
|
||||
// HTTPChannel, which *does* use OpenSSL code.
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef HAVE_OPENSSL
|
||||
|
||||
#include "httpAuthorization.h"
|
||||
|
||||
|
|
@ -96,7 +96,7 @@ ostream &operator << (ostream &out, HTTPDigestAuthorization::Qop qop);
|
|||
|
||||
#include "httpDigestAuthorization.I"
|
||||
|
||||
#endif // HAVE_SSL
|
||||
#endif // HAVE_OPENSSL
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
#include "httpEnum.h"
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef HAVE_OPENSSL
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HTTPEnum::Method::output operator
|
||||
|
|
@ -63,4 +63,4 @@ operator << (ostream &out, HTTPEnum::Method method) {
|
|||
return out;
|
||||
}
|
||||
|
||||
#endif // HAVE_SSL
|
||||
#endif // HAVE_OPENSSL
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
// the OpenSSL library to portably handle all of the socket
|
||||
// communications.
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef HAVE_OPENSSL
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : HTTPEnum
|
||||
|
|
@ -57,7 +57,7 @@ PUBLISHED:
|
|||
|
||||
ostream &operator << (ostream &out, HTTPEnum::Method method);
|
||||
|
||||
#endif // HAVE_SSL
|
||||
#endif // HAVE_OPENSSL
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
#include "identityStream.h"
|
||||
|
||||
// This module is not compiled if OpenSSL is not available.
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef HAVE_OPENSSL
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: IIdentityStream::is_closed
|
||||
|
|
@ -49,4 +49,4 @@ close() {
|
|||
_buf.close_read();
|
||||
}
|
||||
|
||||
#endif // HAVE_SSL
|
||||
#endif // HAVE_OPENSSL
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
#include "pandabase.h"
|
||||
|
||||
// This module is not compiled if OpenSSL is not available.
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef HAVE_OPENSSL
|
||||
|
||||
#include "socketStream.h"
|
||||
#include "identityStreamBuf.h"
|
||||
|
|
@ -62,7 +62,7 @@ private:
|
|||
|
||||
#include "identityStream.I"
|
||||
|
||||
#endif // HAVE_SSL
|
||||
#endif // HAVE_OPENSSL
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
#include "identityStreamBuf.h"
|
||||
|
||||
// This module is not compiled if OpenSSL is not available.
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef HAVE_OPENSSL
|
||||
|
||||
#ifndef HAVE_STREAMSIZE
|
||||
// Some compilers (notably SGI) don't define this for us
|
||||
|
|
@ -180,4 +180,4 @@ read_chars(char *start, size_t length) {
|
|||
return read_count;
|
||||
}
|
||||
|
||||
#endif // HAVE_SSL
|
||||
#endif // HAVE_OPENSSL
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
#include "pandabase.h"
|
||||
|
||||
// This module is not compiled if OpenSSL is not available.
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef HAVE_OPENSSL
|
||||
|
||||
#include "httpChannel.h"
|
||||
#include "bioStreamPtr.h"
|
||||
|
|
@ -58,6 +58,6 @@ private:
|
|||
friend class IIdentityStream;
|
||||
};
|
||||
|
||||
#endif // HAVE_SSL
|
||||
#endif // HAVE_OPENSSL
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
#include "pandabase.h"
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef HAVE_OPENSSL
|
||||
|
||||
#include "config_downloader.h"
|
||||
#include "patcher.h"
|
||||
|
|
@ -89,4 +89,4 @@ run() {
|
|||
return _patchfile->run();
|
||||
}
|
||||
|
||||
#endif // HAVE_SSL
|
||||
#endif // HAVE_OPENSSL
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
#include "pandabase.h"
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef HAVE_OPENSSL
|
||||
|
||||
#include "filename.h"
|
||||
#include "buffer.h"
|
||||
|
|
@ -50,6 +50,6 @@ private:
|
|||
|
||||
#include "patcher.I"
|
||||
|
||||
#endif // HAVE_SSL
|
||||
#endif // HAVE_OPENSSL
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
#include "datagram.h"
|
||||
#include "datagramIterator.h"
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef HAVE_OPENSSL
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: SSReader::Destructor
|
||||
|
|
@ -209,4 +209,4 @@ send_datagram(const Datagram &dg) {
|
|||
return !is_closed();
|
||||
}
|
||||
|
||||
#endif // HAVE_SSL
|
||||
#endif // HAVE_OPENSSL
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
// available, since the only current use for it is to implement
|
||||
// OpenSSL-defined constructs (like ISocketStream).
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef HAVE_OPENSSL
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : SSReader
|
||||
|
|
@ -168,7 +168,7 @@ PUBLISHED:
|
|||
|
||||
#include "socketStream.I"
|
||||
|
||||
#endif // HAVE_SSL
|
||||
#endif // HAVE_OPENSSL
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
#include "ssl_utils.h"
|
||||
#include "config_downloader.h"
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef HAVE_OPENSSL
|
||||
|
||||
#ifdef REPORT_OPENSSL_ERRORS
|
||||
#include <openssl/err.h>
|
||||
|
|
@ -53,4 +53,4 @@ void notify_ssl_errors() {
|
|||
#endif // REPORT_OPENSSL_ERRORS
|
||||
}
|
||||
|
||||
#endif // HAVE_SSL
|
||||
#endif // HAVE_OPENSSL
|
||||
|
|
|
|||
|
|
@ -22,14 +22,14 @@
|
|||
#include "pandabase.h"
|
||||
|
||||
// This module is not compiled if OpenSSL is not available.
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef HAVE_OPENSSL
|
||||
#define OPENSSL_NO_KRB5
|
||||
|
||||
#include <openssl/ssl.h>
|
||||
|
||||
EXPCL_PANDAEXPRESS void notify_ssl_errors();
|
||||
|
||||
#endif // HAVE_SSL
|
||||
#endif // HAVE_OPENSSL
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
#begin bin_target
|
||||
#define TARGET apply_patch
|
||||
#define BUILD_TARGET $[HAVE_SSL]
|
||||
#define BUILD_TARGET $[HAVE_OPENSSL]
|
||||
|
||||
#define SOURCES \
|
||||
apply_patch.cxx
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
#begin bin_target
|
||||
#define TARGET build_patch
|
||||
#define BUILD_TARGET $[HAVE_SSL]
|
||||
#define BUILD_TARGET $[HAVE_OPENSSL]
|
||||
|
||||
#define SOURCES \
|
||||
build_patch.cxx
|
||||
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
#begin bin_target
|
||||
#define TARGET show_ddb
|
||||
#define BUILD_TARGET $[HAVE_SSL]
|
||||
#define BUILD_TARGET $[HAVE_OPENSSL]
|
||||
|
||||
#define SOURCES \
|
||||
show_ddb.cxx
|
||||
|
|
@ -53,8 +53,8 @@
|
|||
|
||||
#begin bin_target
|
||||
#define TARGET check_md5
|
||||
#define BUILD_TARGET $[HAVE_SSL]
|
||||
#define USE_PACKAGES $[USE_PACKAGES] ssl
|
||||
#define BUILD_TARGET $[HAVE_OPENSSL]
|
||||
#define USE_PACKAGES $[USE_PACKAGES] openssl
|
||||
|
||||
#define SOURCES \
|
||||
check_md5.cxx
|
||||
|
|
@ -91,8 +91,8 @@
|
|||
|
||||
#begin bin_target
|
||||
#define TARGET pencrypt
|
||||
#define BUILD_TARGET $[HAVE_SSL]
|
||||
#define USE_PACKAGES $[USE_PACKAGES] ssl
|
||||
#define BUILD_TARGET $[HAVE_OPENSSL]
|
||||
#define USE_PACKAGES $[USE_PACKAGES] openssl
|
||||
|
||||
#define SOURCES \
|
||||
pencrypt.cxx
|
||||
|
|
@ -101,8 +101,8 @@
|
|||
|
||||
#begin bin_target
|
||||
#define TARGET pdecrypt
|
||||
#define BUILD_TARGET $[HAVE_SSL]
|
||||
#define USE_PACKAGES $[USE_PACKAGES] ssl
|
||||
#define BUILD_TARGET $[HAVE_OPENSSL]
|
||||
#define USE_PACKAGES $[USE_PACKAGES] openssl
|
||||
|
||||
#define SOURCES \
|
||||
pdecrypt.cxx
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
#begin lib_target
|
||||
#define TARGET express
|
||||
#define USE_PACKAGES nspr net zlib ssl
|
||||
#define USE_PACKAGES nspr net zlib openssl
|
||||
|
||||
#define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
#include "encryptStream.h"
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef HAVE_OPENSSL
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: encrypt_string
|
||||
// Access: Published
|
||||
|
|
@ -66,4 +66,4 @@ decrypt_string(const string &source, const string &password) {
|
|||
return output.str();
|
||||
}
|
||||
|
||||
#endif // HAVE_SSL
|
||||
#endif // HAVE_OPENSSL
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
#include "pandabase.h"
|
||||
|
||||
// This module is not compiled if OpenSSL is not available.
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef HAVE_OPENSSL
|
||||
|
||||
#include "encryptStreamBuf.h"
|
||||
|
||||
|
|
@ -92,7 +92,7 @@ END_PUBLISH
|
|||
|
||||
#include "encryptStream.I"
|
||||
|
||||
#endif // HAVE_SSL
|
||||
#endif // HAVE_OPENSSL
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
#include "streamReader.h"
|
||||
#include "streamWriter.h"
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef HAVE_OPENSSL
|
||||
|
||||
#include <openssl/rand.h>
|
||||
|
||||
|
|
@ -477,4 +477,4 @@ write_chars(const char *start, size_t length) {
|
|||
}
|
||||
}
|
||||
|
||||
#endif // HAVE_SSL
|
||||
#endif // HAVE_OPENSSL
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
#include "pandabase.h"
|
||||
|
||||
// This module is not compiled if OpenSSL is not available.
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef HAVE_OPENSSL
|
||||
|
||||
#include <openssl/evp.h>
|
||||
|
||||
|
|
@ -84,6 +84,6 @@ private:
|
|||
|
||||
#include "encryptStreamBuf.I"
|
||||
|
||||
#endif // HAVE_SSL
|
||||
#endif // HAVE_OPENSSL
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -202,7 +202,7 @@ read_stream(StreamReader &source) {
|
|||
_hv[3] = source.get_uint32();
|
||||
}
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef HAVE_OPENSSL
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HashVal::hash_ramfile
|
||||
// Access: Published
|
||||
|
|
@ -228,7 +228,7 @@ INLINE void HashVal::
|
|||
hash_string(const string &data) {
|
||||
return hash_buffer(data.data(), data.length());
|
||||
}
|
||||
#endif // HAVE_SSL
|
||||
#endif // HAVE_OPENSSL
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HashVal::tohex
|
||||
|
|
|
|||
|
|
@ -21,9 +21,9 @@
|
|||
|
||||
#include <ctype.h>
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef HAVE_OPENSSL
|
||||
#include <openssl/md5.h>
|
||||
#endif // HAVE_SSL
|
||||
#endif // HAVE_OPENSSL
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -164,7 +164,7 @@ set_from_hex(const string &text) {
|
|||
return !strm.fail();
|
||||
}
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef HAVE_OPENSSL
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HashVal::hash_file
|
||||
// Access: Published
|
||||
|
|
@ -234,7 +234,7 @@ hash_buffer(const char *buffer, int length) {
|
|||
_hv[3] = (md[12] << 24) | (md[13] << 16) | (md[14] << 8) | (md[15]);
|
||||
}
|
||||
|
||||
#endif // HAVE_SSL
|
||||
#endif // HAVE_OPENSSL
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -66,12 +66,12 @@ PUBLISHED:
|
|||
INLINE void write_stream(StreamWriter &destination) const;
|
||||
INLINE void read_stream(StreamReader &source);
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef HAVE_OPENSSL
|
||||
bool hash_file(const Filename &filename);
|
||||
INLINE void hash_ramfile(const Ramfile &ramfile);
|
||||
INLINE void hash_string(const string &data);
|
||||
void hash_buffer(const char *buffer, int length);
|
||||
#endif // HAVE_SSL
|
||||
#endif // HAVE_OPENSSL
|
||||
|
||||
private:
|
||||
static void encode_hex(PN_uint32 val, char *buffer);
|
||||
|
|
|
|||
|
|
@ -92,13 +92,13 @@ get_scale_factor() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void Multifile::
|
||||
set_encryption_flag(bool flag) {
|
||||
#ifndef HAVE_SSL
|
||||
#ifndef HAVE_OPENSSL
|
||||
if (flag) {
|
||||
express_cat.warning()
|
||||
<< "OpenSSL not compiled in; cannot generated encrypted multifiles.\n";
|
||||
flag = false;
|
||||
}
|
||||
#endif // HAVE_SSL
|
||||
#endif // HAVE_OPENSSL
|
||||
_encryption_flag = flag;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -846,12 +846,12 @@ open_read_subfile(int index) {
|
|||
subfile->_data_start + (streampos)subfile->_data_length);
|
||||
|
||||
if ((subfile->_flags & SF_encrypted) != 0) {
|
||||
#ifndef HAVE_SSL
|
||||
#ifndef HAVE_OPENSSL
|
||||
express_cat.error()
|
||||
<< "OpenSSL not compiled in; cannot read encrypted multifiles.\n";
|
||||
delete stream;
|
||||
return NULL;
|
||||
#else // HAVE_SSL
|
||||
#else // HAVE_OPENSSL
|
||||
// The subfile is encrypted. So actually, return an
|
||||
// IDecryptStream that wraps around the ISubStream.
|
||||
IDecryptStream *wrapper =
|
||||
|
|
@ -869,7 +869,7 @@ open_read_subfile(int index) {
|
|||
delete stream;
|
||||
return NULL;
|
||||
}
|
||||
#endif // HAVE_SSL
|
||||
#endif // HAVE_OPENSSL
|
||||
}
|
||||
|
||||
if ((subfile->_flags & SF_compressed) != 0) {
|
||||
|
|
@ -1182,11 +1182,11 @@ add_new_subfile(Subfile *subfile, int compression_level) {
|
|||
#endif // HAVE_ZLIB
|
||||
}
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef HAVE_OPENSSL
|
||||
if (_encryption_flag) {
|
||||
subfile->_flags |= SF_encrypted;
|
||||
}
|
||||
#endif // HAVE_SSL
|
||||
#endif // HAVE_OPENSSL
|
||||
|
||||
if (_next_index != (streampos)0) {
|
||||
// If we're adding a Subfile to an already-existing Multifile, we
|
||||
|
|
@ -1566,7 +1566,7 @@ write_data(ostream &write, istream *read, streampos fpos,
|
|||
ostream *putter = &write;
|
||||
bool delete_putter = false;
|
||||
|
||||
#ifndef HAVE_SSL
|
||||
#ifndef HAVE_OPENSSL
|
||||
// Without OpenSSL, we can't support encryption. The flag had
|
||||
// better not be set.
|
||||
nassertr((_flags & SF_encrypted) == 0, fpos);
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
// The functions defined within this file rely on algorithms defined
|
||||
// within OpenSSL.
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef HAVE_OPENSSL
|
||||
|
||||
#include <openssl/evp.h>
|
||||
|
||||
|
|
@ -75,5 +75,5 @@ password_hash(const string &password, const string &salt,
|
|||
|
||||
|
||||
|
||||
#endif // HAVE_SSL
|
||||
#endif // HAVE_OPENSSL
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
// The functions defined within this file rely on algorithms defined
|
||||
// within OpenSSL.
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef HAVE_OPENSSL
|
||||
|
||||
BEGIN_PUBLISH
|
||||
|
||||
|
|
@ -32,6 +32,6 @@ string password_hash(const string &password, const string &salt,
|
|||
|
||||
END_PUBLISH
|
||||
|
||||
#endif // HAVE_SSL
|
||||
#endif // HAVE_OPENSSL
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
#include "pandabase.h"
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef HAVE_OPENSSL
|
||||
|
||||
#include "config_express.h"
|
||||
#include "error_utils.h"
|
||||
|
|
@ -981,4 +981,4 @@ build(Filename file_orig, Filename file_new, Filename patch_name) {
|
|||
return true;
|
||||
}
|
||||
|
||||
#endif // HAVE_SSL
|
||||
#endif // HAVE_OPENSSL
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
#include "pandabase.h"
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef HAVE_OPENSSL
|
||||
|
||||
#include "typedef.h"
|
||||
#include "notify.h"
|
||||
|
|
@ -136,6 +136,6 @@ protected:
|
|||
|
||||
#include "patchfile.I"
|
||||
|
||||
#endif // HAVE_SSL
|
||||
#endif // HAVE_OPENSSL
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -5700,6 +5700,9 @@ upload_texture_image(CLP(TextureContext) *gtc,
|
|||
} else {
|
||||
// We can reload the image over the previous image, possibly
|
||||
// saving on texture memory fragmentation.
|
||||
#ifdef DO_PSTATS
|
||||
_data_transferred_pcollector.add_level(get_external_texture_bytes(width, height, depth, external_format, component_type));
|
||||
#endif
|
||||
switch (target) {
|
||||
case GL_TEXTURE_1D:
|
||||
GLP(TexSubImage1D)(target, 0, 0, width,
|
||||
|
|
|
|||
|
|
@ -57,7 +57,8 @@
|
|||
userVertexTransform.I userVertexTransform.h \
|
||||
vertexBufferContext.I vertexBufferContext.h \
|
||||
vertexSlider.I vertexSlider.h \
|
||||
vertexTransform.I vertexTransform.h
|
||||
vertexTransform.I vertexTransform.h \
|
||||
videoTexture.I videoTexture.h
|
||||
|
||||
#define INCLUDED_SOURCES \
|
||||
boundedObject.cxx \
|
||||
|
|
@ -104,7 +105,8 @@
|
|||
userVertexTransform.cxx \
|
||||
vertexBufferContext.cxx \
|
||||
vertexSlider.cxx \
|
||||
vertexTransform.cxx
|
||||
vertexTransform.cxx \
|
||||
videoTexture.cxx
|
||||
|
||||
#define INSTALL_HEADERS \
|
||||
boundedObject.I boundedObject.h \
|
||||
|
|
@ -156,7 +158,8 @@
|
|||
userVertexTransform.I userVertexTransform.h \
|
||||
vertexBufferContext.I vertexBufferContext.h \
|
||||
vertexSlider.I vertexSlider.h \
|
||||
vertexTransform.I vertexTransform.h
|
||||
vertexTransform.I vertexTransform.h \
|
||||
videoTexture.I videoTexture.h
|
||||
|
||||
|
||||
#define IGATESCAN all
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@
|
|||
#include "userVertexTransform.h"
|
||||
#include "vertexTransform.h"
|
||||
#include "vertexSlider.h"
|
||||
#include "videoTexture.h"
|
||||
#include "geomContext.h"
|
||||
#include "vertexBufferContext.h"
|
||||
#include "indexBufferContext.h"
|
||||
|
|
@ -187,14 +188,6 @@ ConfigVariableEnum<AutoTextureScale> textures_square
|
|||
"a square aspect ratio when they are loaded from disk. Set this "
|
||||
"to 'none', 'down', or 'up'. See textures-power-2."));
|
||||
|
||||
ConfigVariableString fake_texture_image
|
||||
("fake-texture-image", "",
|
||||
PRC_DESC("Set this to enable a speedy-load mode in which you don't care "
|
||||
"what the world looks like, you just want it to load in minimal "
|
||||
"time. This causes all texture loads via the TexturePool to use "
|
||||
"the same texture file, which will presumably only be loaded "
|
||||
"once."));
|
||||
|
||||
ConfigVariableInt geom_cache_size
|
||||
("geom-cache-size", 5000,
|
||||
PRC_DESC("Specifies the maximum number of entries in the cache "
|
||||
|
|
@ -264,6 +257,7 @@ ConfigureFn(config_gobj) {
|
|||
UserVertexTransform::init_type();
|
||||
VertexTransform::init_type();
|
||||
VertexSlider::init_type();
|
||||
VideoTexture::init_type();
|
||||
InternalName::init_type();
|
||||
|
||||
//Registration of writeable object's creation
|
||||
|
|
|
|||
|
|
@ -61,7 +61,6 @@ extern EXPCL_PANDA ConfigVariableBool connect_triangle_strips;
|
|||
extern EXPCL_PANDA ConfigVariableEnum<BamTextureMode> bam_texture_mode;
|
||||
extern EXPCL_PANDA ConfigVariableEnum<AutoTextureScale> textures_power_2;
|
||||
extern EXPCL_PANDA ConfigVariableEnum<AutoTextureScale> textures_square;
|
||||
extern EXPCL_PANDA ConfigVariableString fake_texture_image;
|
||||
|
||||
extern EXPCL_PANDA ConfigVariableInt geom_cache_size;
|
||||
extern EXPCL_PANDA ConfigVariableInt geom_cache_min_frames;
|
||||
|
|
|
|||
|
|
@ -26,3 +26,4 @@
|
|||
#include "vertexBufferContext.cxx"
|
||||
#include "vertexSlider.cxx"
|
||||
#include "vertexTransform.cxx"
|
||||
#include "videoTexture.cxx"
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ parse_upto(string &result, string pattern, bool include) {
|
|||
GlobPattern endpat(pattern);
|
||||
int start = _parse;
|
||||
int last = _parse;
|
||||
while (_parse < _text.size()) {
|
||||
while (_parse < (int)_text.size()) {
|
||||
string t;
|
||||
parse_line(t, true, true);
|
||||
if (endpat.matches(t)) break;
|
||||
|
|
|
|||
|
|
@ -411,36 +411,18 @@ uses_mipmaps() const {
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::has_ram_image
|
||||
// Function: Texture::might_have_ram_image
|
||||
// Access: Published
|
||||
// Description: Returns true if the Texture has its image contents
|
||||
// available in main RAM, false if it exists only in
|
||||
// texture memory or in the prepared GSG context.
|
||||
//
|
||||
// Note that this has nothing to do with whether
|
||||
// get_ram_image() will fail or not. Even if
|
||||
// has_ram_image() returns false, get_ram_image() may
|
||||
// still return a valid RAM image, because
|
||||
// get_ram_image() will automatically load the texture
|
||||
// from disk if necessary. The only thing
|
||||
// has_ram_image() tells you is whether the texture is
|
||||
// available right now without hitting the disk first.
|
||||
//
|
||||
// Note also that if an application uses only one GSG,
|
||||
// it may appear that has_ram_image() returns true if
|
||||
// the texture has not yet been loaded by the GSG, but
|
||||
// this correlation is not true in general and should
|
||||
// not be depended on. Specifically, if an application
|
||||
// ever uses multiple GSG's in its lifetime (for
|
||||
// instance, by opening more than one window, or by
|
||||
// closing its window and opening another one later),
|
||||
// then has_ram_image() may well return false on
|
||||
// textures that have never been loaded on the current
|
||||
// GSG.
|
||||
// Description: Returns true if the texture's image contents are
|
||||
// currently available in main RAM, or there is reason
|
||||
// to believe it can be loaded on demand. That is, this
|
||||
// function returns a "best guess" as to whether
|
||||
// get_ram_image() will succeed without actually calling
|
||||
// it first.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool Texture::
|
||||
has_ram_image() const {
|
||||
return !_image.empty();
|
||||
might_have_ram_image() const {
|
||||
return (has_ram_image() || has_filename());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -479,21 +461,6 @@ get_expected_ram_page_size() const {
|
|||
return (size_t)(_x_size * _y_size * _num_components * _component_width);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::might_have_ram_image
|
||||
// Access: Published
|
||||
// Description: Returns true if the texture's image contents are
|
||||
// currently available in main RAM, or there is reason
|
||||
// to believe it can be loaded on demand. That is, this
|
||||
// function returns a "best guess" as to whether
|
||||
// get_ram_image() will succeed without actually calling
|
||||
// it first.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool Texture::
|
||||
might_have_ram_image() const {
|
||||
return (has_ram_image() || has_filename());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::set_keep_ram_image
|
||||
// Access: Published
|
||||
|
|
@ -514,19 +481,6 @@ set_keep_ram_image(bool keep_ram_image) {
|
|||
_keep_ram_image = keep_ram_image;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::get_keep_ram_image
|
||||
// Access: Published
|
||||
// Description: Returns the flag that indicates whether this Texture
|
||||
// is eligible to have its main RAM copy of the texture
|
||||
// memory dumped when the texture is prepared for
|
||||
// rendering. See set_keep_ram_image().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool Texture::
|
||||
get_keep_ram_image() const {
|
||||
return _keep_ram_image;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::set_filename
|
||||
// Access: Published
|
||||
|
|
@ -700,6 +654,17 @@ set_loaded_from_disk() {
|
|||
_loaded_from_disk = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::get_loaded_from_disk
|
||||
// Access: Published
|
||||
// Description: Returns the flag that indicates the texture has been
|
||||
// loaded from a disk file. See set_loaded_from_disk().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool Texture::
|
||||
get_loaded_from_disk() const {
|
||||
return _loaded_from_disk;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::get_match_framebuffer_format
|
||||
// Access: Public
|
||||
|
|
|
|||
|
|
@ -71,6 +71,44 @@ Texture(const string &name) :
|
|||
_loaded_from_disk = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::Copy Constructor
|
||||
// Access: Protected
|
||||
// Description: Use Texture::make_copy() to make a duplicate copy of
|
||||
// an existing Texture.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
Texture::
|
||||
Texture(const Texture ©) :
|
||||
Namable(copy),
|
||||
_filename(copy._filename),
|
||||
_alpha_filename(copy._alpha_filename),
|
||||
_fullpath(copy._fullpath),
|
||||
_alpha_fullpath(copy._alpha_fullpath),
|
||||
_primary_file_num_channels(copy._primary_file_num_channels),
|
||||
_alpha_file_channel(copy._alpha_file_channel),
|
||||
_x_size(copy._x_size),
|
||||
_y_size(copy._y_size),
|
||||
_z_size(copy._z_size),
|
||||
_num_components(copy._num_components),
|
||||
_component_width(copy._component_width),
|
||||
_texture_type(copy._texture_type),
|
||||
_format(copy._format),
|
||||
_component_type(copy._component_type),
|
||||
_loaded_from_disk(copy._loaded_from_disk),
|
||||
_wrap_u(copy._wrap_u),
|
||||
_wrap_v(copy._wrap_v),
|
||||
_wrap_w(copy._wrap_w),
|
||||
_minfilter(copy._minfilter),
|
||||
_magfilter(copy._magfilter),
|
||||
_anisotropic_degree(copy._anisotropic_degree),
|
||||
_keep_ram_image(copy._keep_ram_image),
|
||||
_border_color(copy._border_color),
|
||||
_match_framebuffer_format(copy._match_framebuffer_format),
|
||||
_all_dirty_flags(0),
|
||||
_image(copy._image)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::Destructor
|
||||
// Access: Published, Virtual
|
||||
|
|
@ -81,6 +119,24 @@ Texture::
|
|||
release_all();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::make_copy
|
||||
// Access: Published, Virtual
|
||||
// Description: Returns a new copy of the same Texture. This copy,
|
||||
// if applied to geometry, will be copied into texture
|
||||
// as a separate texture from the original, so it will
|
||||
// be duplicated in texture memory (and may be
|
||||
// independently modified if desired).
|
||||
//
|
||||
// If the Texture is an AviTexture, the resulting
|
||||
// duplicate may be animated independently of the
|
||||
// original.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(Texture) Texture::
|
||||
make_copy() {
|
||||
return new Texture(*this);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::setup_texture
|
||||
// Access: Published
|
||||
|
|
@ -221,7 +277,7 @@ generate_normalization_cube_map(int size) {
|
|||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::read
|
||||
// Access: Published
|
||||
// Access: Published, Virtual
|
||||
// Description: Reads the texture from the indicated filename. If
|
||||
// num_channels is not 0, it specifies the number of
|
||||
// components to downgrade the image to if it is greater
|
||||
|
|
@ -262,7 +318,7 @@ read(const Filename &fullpath, int z, int primary_file_num_channels) {
|
|||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::read
|
||||
// Access: Published
|
||||
// Access: Published, Virtual
|
||||
// Description: Combine a 3-component image with a grayscale image
|
||||
// to get a 4-component image
|
||||
//
|
||||
|
|
@ -477,7 +533,7 @@ write_pages(const HashFilename &fullpath_template) {
|
|||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::load
|
||||
// Access: Published
|
||||
// Access: Published, Virtual
|
||||
// Description: Fills the texture system RAM data from the
|
||||
// already-read PNMImage.
|
||||
//
|
||||
|
|
@ -496,85 +552,21 @@ write_pages(const HashFilename &fullpath_template) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
bool Texture::
|
||||
load(const PNMImage &pnmimage, int z) {
|
||||
if (z >= _z_size) {
|
||||
// If we're loading a page past _z_size, treat it as an implicit
|
||||
// request to enlarge _z_size. However, this is only legal if
|
||||
// this is, in fact, a 3-d texture (cube maps always have z_size
|
||||
// 6, and other types have z_size 1).
|
||||
nassertr(_texture_type == Texture::TT_3d_texture, false);
|
||||
|
||||
_z_size = z + 1;
|
||||
// Increase the size of the data buffer to make room for the new
|
||||
// texture level.
|
||||
size_t new_size = get_expected_ram_image_size();
|
||||
if (!_image.is_null() && new_size > _image.size()) {
|
||||
_image.insert(_image.end(), new_size - _image.size(), 0);
|
||||
nassertr(_image.size() == new_size, false);
|
||||
}
|
||||
if (!reconsider_z_size(z)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nassertr(z >= 0 && z < _z_size, false);
|
||||
|
||||
int num_components = pnmimage.get_num_channels();
|
||||
ComponentType component_type = T_unsigned_byte;
|
||||
|
||||
xelval maxval = pnmimage.get_maxval();
|
||||
if (maxval > 255) {
|
||||
component_type = T_unsigned_short;
|
||||
}
|
||||
|
||||
if (!_loaded_from_disk || num_components != _num_components) {
|
||||
// Come up with a default format based on the number of channels.
|
||||
// But only do this the first time the file is loaded, or if the
|
||||
// number of channels in the image changes on subsequent loads.
|
||||
|
||||
switch (pnmimage.get_color_type()) {
|
||||
case PNMImage::CT_grayscale:
|
||||
_format = F_luminance;
|
||||
break;
|
||||
|
||||
case PNMImage::CT_two_channel:
|
||||
_format = F_luminance_alpha;
|
||||
break;
|
||||
|
||||
case PNMImage::CT_color:
|
||||
_format = F_rgb;
|
||||
break;
|
||||
|
||||
case PNMImage::CT_four_channel:
|
||||
_format = F_rgba;
|
||||
break;
|
||||
|
||||
default:
|
||||
// Eh?
|
||||
nassertr(false, false);
|
||||
_format = F_rgb;
|
||||
}
|
||||
}
|
||||
|
||||
if (!_loaded_from_disk) {
|
||||
#ifndef NDEBUG
|
||||
if (_texture_type == TT_1d_texture) {
|
||||
nassertr(pnmimage.get_y_size() == 1, false);
|
||||
} else if (_texture_type == TT_cube_map) {
|
||||
nassertr(pnmimage.get_x_size() == pnmimage.get_y_size(), false);
|
||||
}
|
||||
#endif
|
||||
_x_size = pnmimage.get_x_size();
|
||||
_y_size = pnmimage.get_y_size();
|
||||
_num_components = num_components;
|
||||
set_component_type(component_type);
|
||||
|
||||
} else {
|
||||
if (_x_size != pnmimage.get_x_size() ||
|
||||
_y_size != pnmimage.get_y_size() ||
|
||||
_num_components != num_components ||
|
||||
_component_type != component_type) {
|
||||
gobj_cat.error()
|
||||
<< "Texture properties have changed for texture " << get_name()
|
||||
<< " level " << z << ".\n";
|
||||
return false;
|
||||
}
|
||||
if (!reconsider_image_properties(pnmimage.get_x_size(), pnmimage.get_y_size(),
|
||||
pnmimage.get_num_channels(), component_type,
|
||||
z)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
_loaded_from_disk = true;
|
||||
|
|
@ -856,6 +848,39 @@ set_border_color(const Colorf &color) {
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::has_ram_image
|
||||
// Access: Published, Virtual
|
||||
// Description: Returns true if the Texture has its image contents
|
||||
// available in main RAM, false if it exists only in
|
||||
// texture memory or in the prepared GSG context.
|
||||
//
|
||||
// Note that this has nothing to do with whether
|
||||
// get_ram_image() will fail or not. Even if
|
||||
// has_ram_image() returns false, get_ram_image() may
|
||||
// still return a valid RAM image, because
|
||||
// get_ram_image() will automatically load the texture
|
||||
// from disk if necessary. The only thing
|
||||
// has_ram_image() tells you is whether the texture is
|
||||
// available right now without hitting the disk first.
|
||||
//
|
||||
// Note also that if an application uses only one GSG,
|
||||
// it may appear that has_ram_image() returns true if
|
||||
// the texture has not yet been loaded by the GSG, but
|
||||
// this correlation is not true in general and should
|
||||
// not be depended on. Specifically, if an application
|
||||
// ever uses multiple GSG's in its lifetime (for
|
||||
// instance, by opening more than one window, or by
|
||||
// closing its window and opening another one later),
|
||||
// then has_ram_image() may well return false on
|
||||
// textures that have never been loaded on the current
|
||||
// GSG.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool Texture::
|
||||
has_ram_image() const {
|
||||
return !_image.empty();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::get_ram_image
|
||||
// Access: Published
|
||||
|
|
@ -886,19 +911,8 @@ set_border_color(const Colorf &color) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
CPTA_uchar Texture::
|
||||
get_ram_image() {
|
||||
if (_loaded_from_disk && !has_ram_image() && has_filename() &&
|
||||
(_texture_type == TT_1d_texture || _texture_type == TT_2d_texture)) {
|
||||
// Now we have to reload the texture image.
|
||||
gobj_cat.info()
|
||||
<< "Reloading texture " << get_name() << "\n";
|
||||
|
||||
make_ram_image();
|
||||
if (has_alpha_fullpath()) {
|
||||
read(get_fullpath(), get_alpha_fullpath(),
|
||||
0, _primary_file_num_channels, _alpha_file_channel);
|
||||
} else {
|
||||
read(get_fullpath(), 0, _primary_file_num_channels);
|
||||
}
|
||||
if (_loaded_from_disk && !has_ram_image() && has_filename()) {
|
||||
reload_ram_image();
|
||||
}
|
||||
|
||||
return _image;
|
||||
|
|
@ -914,7 +928,7 @@ get_ram_image() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
PTA_uchar Texture::
|
||||
modify_ram_image() {
|
||||
if (!has_ram_image()) {
|
||||
if (_image.empty()) {
|
||||
make_ram_image();
|
||||
}
|
||||
|
||||
|
|
@ -968,6 +982,19 @@ clear_ram_image() {
|
|||
_image.clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::get_keep_ram_image
|
||||
// Access: Published, Virtual
|
||||
// Description: Returns the flag that indicates whether this Texture
|
||||
// is eligible to have its main RAM copy of the texture
|
||||
// memory dumped when the texture is prepared for
|
||||
// rendering. See set_keep_ram_image().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool Texture::
|
||||
get_keep_ram_image() const {
|
||||
return _keep_ram_image;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::prepare
|
||||
// Access: Published
|
||||
|
|
@ -1218,6 +1245,38 @@ mark_dirty(int flags_to_set) {
|
|||
_all_dirty_flags |= flags_to_set;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::has_cull_callback
|
||||
// Access: Public, Virtual
|
||||
// Description: Should be overridden by derived classes to return
|
||||
// true if cull_callback() has been defined. Otherwise,
|
||||
// returns false to indicate cull_callback() does not
|
||||
// need to be called for this node during the cull
|
||||
// traversal.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool Texture::
|
||||
has_cull_callback() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::cull_callback
|
||||
// Access: Public, Virtual
|
||||
// Description: If has_cull_callback() returns true, this function
|
||||
// will be called during the cull traversal to perform
|
||||
// any additional operations that should be performed at
|
||||
// cull time.
|
||||
//
|
||||
// This is called each time the Texture is discovered
|
||||
// applied to a Geom in the traversal. It should return
|
||||
// true if the Geom is visible, false if it should be
|
||||
// omitted.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool Texture::
|
||||
cull_callback(CullTraverser *, const CullTraverserData &) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::string_wrap_mode
|
||||
// Access: Public
|
||||
|
|
@ -1271,6 +1330,41 @@ string_filter_type(const string &string) {
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::reconsider_dirty
|
||||
// Access: Protected, Virtual
|
||||
// Description: Called by TextureContext to give the Texture a chance
|
||||
// to mark itself dirty before rendering, if necessary.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void Texture::
|
||||
reconsider_dirty() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::reload_ram_image
|
||||
// Access: Protected, Virtual
|
||||
// Description: Called when the Texture image is required but the ram
|
||||
// image is not available, this will reload it from disk
|
||||
// or otherwise do whatever is required to make it
|
||||
// available, if possible.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void Texture::
|
||||
reload_ram_image() {
|
||||
if (_texture_type == TT_1d_texture || _texture_type == TT_2d_texture) {
|
||||
gobj_cat.info()
|
||||
<< "Reloading texture " << get_name() << "\n";
|
||||
|
||||
make_ram_image();
|
||||
if (has_alpha_fullpath()) {
|
||||
read(get_fullpath(), get_alpha_fullpath(),
|
||||
0, _primary_file_num_channels, _alpha_file_channel);
|
||||
} else {
|
||||
read(get_fullpath(), 0, _primary_file_num_channels);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::up_to_power_2
|
||||
// Access: Protected, Static
|
||||
|
|
@ -1301,6 +1395,102 @@ down_to_power_2(int value) {
|
|||
return x;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::reconsider_z_size
|
||||
// Access: Protected
|
||||
// Description: Considers whether the z_size should automatically be
|
||||
// adjusted when the user loads a new page. Returns
|
||||
// true if the z size is valid, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool Texture::
|
||||
reconsider_z_size(int z) {
|
||||
if (z >= _z_size) {
|
||||
// If we're loading a page past _z_size, treat it as an implicit
|
||||
// request to enlarge _z_size. However, this is only legal if
|
||||
// this is, in fact, a 3-d texture (cube maps always have z_size
|
||||
// 6, and other types have z_size 1).
|
||||
nassertr(_texture_type == Texture::TT_3d_texture, false);
|
||||
|
||||
_z_size = z + 1;
|
||||
// Increase the size of the data buffer to make room for the new
|
||||
// texture level.
|
||||
size_t new_size = get_expected_ram_image_size();
|
||||
if (!_image.is_null() && new_size > _image.size()) {
|
||||
_image.insert(_image.end(), new_size - _image.size(), 0);
|
||||
nassertr(_image.size() == new_size, false);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::reconsider_image_properties
|
||||
// Access: Protected
|
||||
// Description: Resets the internal Texture properties when a new
|
||||
// image file is loaded. Returns true if the new image
|
||||
// is valid, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool Texture::
|
||||
reconsider_image_properties(int x_size, int y_size, int num_components,
|
||||
Texture::ComponentType component_type, int z) {
|
||||
if (!_loaded_from_disk || num_components != _num_components) {
|
||||
// Come up with a default format based on the number of channels.
|
||||
// But only do this the first time the file is loaded, or if the
|
||||
// number of channels in the image changes on subsequent loads.
|
||||
|
||||
switch (num_components) {
|
||||
case 1:
|
||||
_format = F_luminance;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
_format = F_luminance_alpha;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
_format = F_rgb;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
_format = F_rgba;
|
||||
break;
|
||||
|
||||
default:
|
||||
// Eh?
|
||||
nassertr(false, false);
|
||||
_format = F_rgb;
|
||||
}
|
||||
}
|
||||
|
||||
if (!_loaded_from_disk) {
|
||||
#ifndef NDEBUG
|
||||
if (_texture_type == TT_1d_texture) {
|
||||
nassertr(y_size == 1, false);
|
||||
} else if (_texture_type == TT_cube_map) {
|
||||
nassertr(x_size == y_size, false);
|
||||
}
|
||||
#endif
|
||||
_x_size = x_size;
|
||||
_y_size = y_size;
|
||||
_num_components = num_components;
|
||||
set_component_type(component_type);
|
||||
|
||||
} else {
|
||||
if (_x_size != x_size ||
|
||||
_y_size != y_size ||
|
||||
_num_components != num_components ||
|
||||
_component_type != component_type) {
|
||||
gobj_cat.error()
|
||||
<< "Texture properties have changed for texture " << get_name()
|
||||
<< " level " << z << ".\n";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::clear_prepared
|
||||
// Access: Private
|
||||
|
|
@ -1323,6 +1513,7 @@ clear_prepared(PreparedGraphicsObjects *prepared_objects) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::consider_rescale
|
||||
// Access: Private
|
||||
|
|
@ -1444,7 +1635,7 @@ make_Texture(const FactoryParams ¶ms) {
|
|||
if (has_rawdata) {
|
||||
// If the raw image data is included, then just create a Texture
|
||||
// and don't load from the file.
|
||||
me = new Texture;
|
||||
me = new Texture("");
|
||||
|
||||
} else {
|
||||
if (filename.empty()) {
|
||||
|
|
@ -1473,7 +1664,7 @@ make_Texture(const FactoryParams ¶ms) {
|
|||
// Oops, we couldn't load the texture; we'll just return NULL.
|
||||
// But we do need a dummy texture to read in and ignore all of the
|
||||
// attributes.
|
||||
PT(Texture) dummy = new Texture;
|
||||
PT(Texture) dummy = new Texture("");
|
||||
dummy->fillin(scan, manager, has_rawdata);
|
||||
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -32,6 +32,8 @@ class TextureContext;
|
|||
class FactoryParams;
|
||||
class PreparedGraphicsObjects;
|
||||
class HashFilename;
|
||||
class CullTraverser;
|
||||
class CullTraverserData;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : Texture
|
||||
|
|
@ -133,8 +135,13 @@ PUBLISHED:
|
|||
|
||||
PUBLISHED:
|
||||
Texture(const string &name = string());
|
||||
protected:
|
||||
Texture(const Texture ©);
|
||||
PUBLISHED:
|
||||
virtual ~Texture();
|
||||
|
||||
virtual PT(Texture) make_copy();
|
||||
|
||||
void setup_texture(TextureType texture_type,
|
||||
int x_size, int y_size, int z_size,
|
||||
ComponentType component_type, Format format);
|
||||
|
|
@ -154,17 +161,17 @@ PUBLISHED:
|
|||
|
||||
void generate_normalization_cube_map(int size);
|
||||
|
||||
bool read(const Filename &fullpath, int z = 0,
|
||||
int primary_file_num_channels = 0);
|
||||
bool read(const Filename &fullpath, const Filename &alpha_fullpath,
|
||||
int z = 0,
|
||||
int primary_file_num_channels = 0, int alpha_file_channel = 0);
|
||||
virtual bool read(const Filename &fullpath, int z = 0,
|
||||
int primary_file_num_channels = 0);
|
||||
virtual bool read(const Filename &fullpath, const Filename &alpha_fullpath,
|
||||
int z = 0,
|
||||
int primary_file_num_channels = 0, int alpha_file_channel = 0);
|
||||
bool write(const Filename &fullpath, int z = 0) const;
|
||||
|
||||
bool read_pages(const HashFilename &fullpath_template, int z_size = 0);
|
||||
bool write_pages(const HashFilename &fullpath_template);
|
||||
|
||||
bool load(const PNMImage &pnmimage, int z = 0);
|
||||
virtual bool load(const PNMImage &pnmimage, int z = 0);
|
||||
bool store(PNMImage &pnmimage, int z = 0) const;
|
||||
|
||||
INLINE bool has_filename() const;
|
||||
|
|
@ -203,7 +210,7 @@ PUBLISHED:
|
|||
INLINE Colorf get_border_color() const;
|
||||
INLINE bool uses_mipmaps() const;
|
||||
|
||||
INLINE bool has_ram_image() const;
|
||||
virtual bool has_ram_image() const;
|
||||
INLINE bool might_have_ram_image() const;
|
||||
INLINE size_t get_ram_image_size() const;
|
||||
INLINE size_t get_expected_ram_image_size() const;
|
||||
|
|
@ -214,7 +221,7 @@ PUBLISHED:
|
|||
void set_ram_image(PTA_uchar image);
|
||||
void clear_ram_image();
|
||||
INLINE void set_keep_ram_image(bool keep_ram_image);
|
||||
INLINE bool get_keep_ram_image() const;
|
||||
virtual bool get_keep_ram_image() const;
|
||||
|
||||
void prepare(PreparedGraphicsObjects *prepared_objects);
|
||||
bool release(PreparedGraphicsObjects *prepared_objects);
|
||||
|
|
@ -240,6 +247,7 @@ PUBLISHED:
|
|||
void set_format(Format format);
|
||||
void set_component_type(ComponentType component_type);
|
||||
INLINE void set_loaded_from_disk();
|
||||
INLINE bool get_loaded_from_disk() const;
|
||||
|
||||
public:
|
||||
INLINE bool get_match_framebuffer_format() const;
|
||||
|
|
@ -263,16 +271,25 @@ public:
|
|||
|
||||
void mark_dirty(int flags_to_set);
|
||||
|
||||
virtual bool has_cull_callback() const;
|
||||
virtual bool cull_callback(CullTraverser *trav, const CullTraverserData &data) const;
|
||||
|
||||
static WrapMode string_wrap_mode(const string &string);
|
||||
static FilterType string_filter_type(const string &string);
|
||||
|
||||
protected:
|
||||
virtual void reconsider_dirty();
|
||||
virtual void reload_ram_image();
|
||||
|
||||
static int up_to_power_2(int value);
|
||||
static int down_to_power_2(int value);
|
||||
bool reconsider_z_size(int z);
|
||||
bool reconsider_image_properties(int x_size, int y_size, int num_components,
|
||||
ComponentType component_type, int z);
|
||||
|
||||
private:
|
||||
void clear_prepared(PreparedGraphicsObjects *prepared_objects);
|
||||
|
||||
|
||||
void consider_rescale(PNMImage &pnmimage);
|
||||
void consider_downgrade(PNMImage &pnmimage, int num_channels);
|
||||
|
||||
|
|
@ -283,7 +300,7 @@ private:
|
|||
INLINE double get_unsigned_byte(int &index) const;
|
||||
INLINE double get_unsigned_short(int &index) const;
|
||||
|
||||
private:
|
||||
protected:
|
||||
Filename _filename;
|
||||
Filename _alpha_filename;
|
||||
Filename _fullpath;
|
||||
|
|
|
|||
|
|
@ -86,6 +86,7 @@ clear_dirty_flags(int flags_to_clear) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int TextureContext::
|
||||
get_dirty_flags() const {
|
||||
_texture->reconsider_dirty();
|
||||
return _dirty_flags;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool TexturePool::
|
||||
has_texture(const string &filename) {
|
||||
return get_ptr()->ns_has_texture(filename);
|
||||
return get_global_ptr()->ns_has_texture(filename);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -54,7 +54,7 @@ verify_texture(const string &filename) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE Texture *TexturePool::
|
||||
load_texture(const string &filename, int primary_file_num_channels) {
|
||||
return get_ptr()->ns_load_texture(filename, primary_file_num_channels);
|
||||
return get_global_ptr()->ns_load_texture(filename, primary_file_num_channels);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -69,7 +69,7 @@ load_texture(const string &filename, int primary_file_num_channels) {
|
|||
INLINE Texture *TexturePool::
|
||||
load_texture(const string &filename, const string &alpha_filename,
|
||||
int primary_file_num_channels, int alpha_file_channel) {
|
||||
return get_ptr()->ns_load_texture(filename, alpha_filename,
|
||||
return get_global_ptr()->ns_load_texture(filename, alpha_filename,
|
||||
primary_file_num_channels,
|
||||
alpha_file_channel);
|
||||
}
|
||||
|
|
@ -85,7 +85,7 @@ load_texture(const string &filename, const string &alpha_filename,
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE Texture *TexturePool::
|
||||
load_3d_texture(const string &filename_template) {
|
||||
return get_ptr()->ns_load_3d_texture(filename_template);
|
||||
return get_global_ptr()->ns_load_3d_texture(filename_template);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -99,7 +99,7 @@ load_3d_texture(const string &filename_template) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE Texture *TexturePool::
|
||||
load_cube_map(const string &filename_template) {
|
||||
return get_ptr()->ns_load_cube_map(filename_template);
|
||||
return get_global_ptr()->ns_load_cube_map(filename_template);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -115,7 +115,7 @@ load_cube_map(const string &filename_template) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE Texture *TexturePool::
|
||||
get_normalization_cube_map(int size) {
|
||||
return get_ptr()->ns_get_normalization_cube_map(size);
|
||||
return get_global_ptr()->ns_get_normalization_cube_map(size);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -129,7 +129,7 @@ get_normalization_cube_map(int size) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void TexturePool::
|
||||
add_texture(Texture *texture) {
|
||||
get_ptr()->ns_add_texture(texture);
|
||||
get_global_ptr()->ns_add_texture(texture);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -147,7 +147,7 @@ add_texture(Texture *texture) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void TexturePool::
|
||||
release_texture(Texture *texture) {
|
||||
get_ptr()->ns_release_texture(texture);
|
||||
get_global_ptr()->ns_release_texture(texture);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -158,7 +158,7 @@ release_texture(Texture *texture) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void TexturePool::
|
||||
release_all_textures() {
|
||||
get_ptr()->ns_release_all_textures();
|
||||
get_global_ptr()->ns_release_all_textures();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -171,7 +171,7 @@ release_all_textures() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int TexturePool::
|
||||
garbage_collect() {
|
||||
return get_ptr()->ns_garbage_collect();
|
||||
return get_global_ptr()->ns_garbage_collect();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -182,7 +182,7 @@ garbage_collect() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void TexturePool::
|
||||
list_contents(ostream &out) {
|
||||
get_ptr()->ns_list_contents(out);
|
||||
get_global_ptr()->ns_list_contents(out);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -193,7 +193,7 @@ list_contents(ostream &out) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void TexturePool::
|
||||
set_fake_texture_image(const string &filename) {
|
||||
get_ptr()->_fake_texture_image = filename;
|
||||
get_global_ptr()->_fake_texture_image = filename;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -226,17 +226,5 @@ has_fake_texture_image() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const string &TexturePool::
|
||||
get_fake_texture_image() {
|
||||
return get_ptr()->_fake_texture_image;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TexturePool::Constructor
|
||||
// Access: Private
|
||||
// Description: The constructor is not intended to be called
|
||||
// directly; there's only supposed to be one TexturePool
|
||||
// in the universe and it constructs itself.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE TexturePool::
|
||||
TexturePool() {
|
||||
_fake_texture_image = fake_texture_image;
|
||||
return get_global_ptr()->_fake_texture_image;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
#include "config_gobj.h"
|
||||
#include "config_util.h"
|
||||
#include "config_express.h"
|
||||
#include "string_utils.h"
|
||||
#include "virtualFileSystem.h"
|
||||
|
||||
|
||||
|
|
@ -35,7 +36,79 @@ TexturePool *TexturePool::_global_ptr = (TexturePool *)NULL;
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void TexturePool::
|
||||
write(ostream &out) {
|
||||
get_ptr()->ns_list_contents(out);
|
||||
get_global_ptr()->ns_list_contents(out);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TexturePool::register_texture_type
|
||||
// Access: Public
|
||||
// Description: Records a factory function that makes a Texture
|
||||
// object of the appropriate type for one or more
|
||||
// particular filename extensions. The string
|
||||
// extensions may be a string that contains
|
||||
// space-separated list of extensions, case-insensitive.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void TexturePool::
|
||||
register_texture_type(MakeTextureFunc *func, const string &extensions) {
|
||||
vector_string words;
|
||||
extract_words(downcase(extensions), words);
|
||||
|
||||
vector_string::const_iterator wi;
|
||||
for (wi = words.begin(); wi != words.end(); ++wi) {
|
||||
_type_registry[*wi] = func;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TexturePool::make_texture
|
||||
// Access: Public
|
||||
// Description: Creates a new Texture object of the appropriate type
|
||||
// for the indicated filename extension, according to
|
||||
// the types that have been registered via
|
||||
// register_texture_type().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(Texture) TexturePool::
|
||||
make_texture(const string &extension) {
|
||||
string c = downcase(extension);
|
||||
TypeRegistry::const_iterator ti;
|
||||
ti = _type_registry.find(extension);
|
||||
if (ti != _type_registry.end()) {
|
||||
return (*ti).second();
|
||||
}
|
||||
return new Texture;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TexturePool::get_global_ptr
|
||||
// Access: Public, Static
|
||||
// Description: Initializes and/or returns the global pointer to the
|
||||
// one TexturePool object in the system.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
TexturePool *TexturePool::
|
||||
get_global_ptr() {
|
||||
if (_global_ptr == (TexturePool *)NULL) {
|
||||
_global_ptr = new TexturePool;
|
||||
}
|
||||
return _global_ptr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TexturePool::Constructor
|
||||
// Access: Private
|
||||
// Description: The constructor is not intended to be called
|
||||
// directly; there's only supposed to be one TexturePool
|
||||
// in the universe and it constructs itself.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
TexturePool::
|
||||
TexturePool() {
|
||||
ConfigVariableString fake_texture_image
|
||||
("fake-texture-image", "",
|
||||
PRC_DESC("Set this to enable a speedy-load mode in which you don't care "
|
||||
"what the world looks like, you just want it to load in minimal "
|
||||
"time. This causes all texture loads via the TexturePool to use "
|
||||
"the same texture file, which will presumably only be loaded "
|
||||
"once."));
|
||||
_fake_texture_image = fake_texture_image;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -91,7 +164,7 @@ ns_load_texture(const Filename &orig_filename, int primary_file_num_channels) {
|
|||
|
||||
gobj_cat.info()
|
||||
<< "Loading texture " << filename << "\n";
|
||||
PT(Texture) tex = new Texture;
|
||||
PT(Texture) tex = make_texture(filename.get_extension());
|
||||
if (!tex->read(filename, 0, primary_file_num_channels)) {
|
||||
// This texture was not found or could not be read.
|
||||
report_texture_unreadable(filename);
|
||||
|
|
@ -139,7 +212,7 @@ ns_load_texture(const Filename &orig_filename,
|
|||
gobj_cat.info()
|
||||
<< "Loading texture " << filename << " and alpha component "
|
||||
<< alpha_filename << endl;
|
||||
PT(Texture) tex = new Texture;
|
||||
PT(Texture) tex = make_texture(filename.get_extension());
|
||||
if (!tex->read(filename, alpha_filename, 0, primary_file_num_channels,
|
||||
alpha_file_channel)) {
|
||||
// This texture was not found or could not be read.
|
||||
|
|
@ -186,7 +259,7 @@ ns_load_3d_texture(const HashFilename &filename_template) {
|
|||
|
||||
gobj_cat.info()
|
||||
<< "Loading 3-d texture " << hash_filename << "\n";
|
||||
PT(Texture) tex = new Texture;
|
||||
PT(Texture) tex = make_texture(hash_filename.get_extension());
|
||||
tex->setup_3d_texture();
|
||||
if (!tex->read_pages(hash_filename)) {
|
||||
// This texture was not found or could not be read.
|
||||
|
|
@ -231,7 +304,7 @@ ns_load_cube_map(const HashFilename &filename_template) {
|
|||
|
||||
gobj_cat.info()
|
||||
<< "Loading cube map texture " << hash_filename << "\n";
|
||||
PT(Texture) tex = new Texture;
|
||||
PT(Texture) tex = make_texture(hash_filename.get_extension());
|
||||
tex->setup_cube_map();
|
||||
if (!tex->read_pages(hash_filename)) {
|
||||
// This texture was not found or could not be read.
|
||||
|
|
@ -392,17 +465,3 @@ report_texture_unreadable(const Filename &filename) const {
|
|||
<< "Texture \"" << filename << "\" exists but cannot be read.\n";
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TexturePool::get_ptr
|
||||
// Access: Private, Static
|
||||
// Description: Initializes and/or returns the global pointer to the
|
||||
// one TexturePool object in the system.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
TexturePool *TexturePool::
|
||||
get_ptr() {
|
||||
if (_global_ptr == (TexturePool *)NULL) {
|
||||
_global_ptr = new TexturePool;
|
||||
}
|
||||
return _global_ptr;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,8 +68,16 @@ PUBLISHED:
|
|||
|
||||
static void write(ostream &out);
|
||||
|
||||
public:
|
||||
typedef PT(Texture) MakeTextureFunc();
|
||||
void register_texture_type(MakeTextureFunc *func, const string &extensions);
|
||||
|
||||
PT(Texture) make_texture(const string &extension);
|
||||
|
||||
static TexturePool *get_global_ptr();
|
||||
|
||||
private:
|
||||
INLINE TexturePool();
|
||||
TexturePool();
|
||||
|
||||
bool ns_has_texture(const Filename &orig_filename);
|
||||
Texture *ns_load_texture(const Filename &orig_filename, int primary_file_num_channels);
|
||||
|
|
@ -89,14 +97,15 @@ private:
|
|||
|
||||
void report_texture_unreadable(const Filename &filename) const;
|
||||
|
||||
static TexturePool *get_ptr();
|
||||
|
||||
static TexturePool *_global_ptr;
|
||||
typedef phash_map<string, PT(Texture), string_hash> Textures;
|
||||
Textures _textures;
|
||||
string _fake_texture_image;
|
||||
|
||||
PT(Texture) _normalization_cube_map;
|
||||
|
||||
typedef pmap<string, MakeTextureFunc *> TypeRegistry;
|
||||
TypeRegistry _type_registry;
|
||||
};
|
||||
|
||||
#include "texturePool.I"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,149 @@
|
|||
// Filename: videoTexture.I
|
||||
// Created by: drose (21Sep05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: VideoTexture::set_power_2
|
||||
// Access: Published
|
||||
// Description: Sets the flag that indicates whether a newly-loaded
|
||||
// VideoTexture will be constrained to dimensions that are
|
||||
// a power of 2 or not. If true, then a newly-loaded
|
||||
// video stream will be set within the smallest power of
|
||||
// 2 texture that will fit it; if false, a newly-loaded
|
||||
// video stream will be set within a texture that
|
||||
// exactly fits it, even if that means creating a
|
||||
// texture whose dimensions are not a power of 2.
|
||||
//
|
||||
// This must be set before the first call to read().
|
||||
// The default value is false if the Config.prc variable
|
||||
// textures-power-2 is "none", true otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void VideoTexture::
|
||||
set_power_2(bool power_2) {
|
||||
_power_2 = power_2;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: VideoTexture::get_power_2
|
||||
// Access: Published
|
||||
// Description: Returns the flag that indicates whether a
|
||||
// newly-loaded VideoTexture will be constrained to
|
||||
// dimensions that are a power of 2 or not. See
|
||||
// set_power_2().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool VideoTexture::
|
||||
get_power_2() const {
|
||||
return _power_2;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: VideoTexture::get_video_width
|
||||
// Access: Published
|
||||
// Description: Returns the width in texels of the source video
|
||||
// stream. This is not necessarily the width of the
|
||||
// actual texture, since the texture may have been
|
||||
// expanded to raise it to a power of 2.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int VideoTexture::
|
||||
get_video_width() const {
|
||||
return _video_width;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: VideoTexture::get_video_height
|
||||
// Access: Published
|
||||
// Description: Returns the height in texels of the source video
|
||||
// stream. This is not necessarily the height of the
|
||||
// actual texture, since the texture may have been
|
||||
// expanded to raise it to a power of 2.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int VideoTexture::
|
||||
get_video_height() const {
|
||||
return _video_height;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: VideoTexture::get_tex_scale
|
||||
// Access: Published
|
||||
// Description: Returns a scale pair that is suitable for applying to
|
||||
// geometry via NodePath::set_tex_scale(), which will
|
||||
// convert texture coordinates on the geometry from the
|
||||
// range 0..1 into the appropriate range to render the
|
||||
// video part of the texture.
|
||||
//
|
||||
// This is necessary in the event the video source is
|
||||
// not a power of two and set_power_2() is true. In
|
||||
// this case, the video image will be mapped to the
|
||||
// lower-left corner of the texture, and the rest of the
|
||||
// texture space will be unused; so we will need to
|
||||
// remap any texture coordinates to fill the space
|
||||
// correctly.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE LVecBase2f VideoTexture::
|
||||
get_tex_scale() const {
|
||||
if (_video_width == 0 || _video_height == 0 ||
|
||||
_x_size == 0 || _y_size == 0) {
|
||||
LVecBase2f(1.0f, 1.0f);
|
||||
}
|
||||
return LVecBase2f((float)_video_width / _x_size,
|
||||
(float)_video_height / _y_size);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: VideoTexture::set_video_size
|
||||
// Access: Protected
|
||||
// Description: Should be called by a derived class to set the size
|
||||
// of the video when it is loaded.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void VideoTexture::
|
||||
set_video_size(int video_width, int video_height) {
|
||||
_video_width = video_width;
|
||||
_video_height = video_height;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: VideoTexture::consider_update
|
||||
// Access: Protected
|
||||
// Description: Calls update_frame() if the current frame has
|
||||
// changed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void VideoTexture::
|
||||
consider_update() {
|
||||
int this_frame = ClockObject::get_global_clock()->get_frame_count();
|
||||
if (this_frame != _last_frame_update) {
|
||||
int frame = get_frame();
|
||||
if (_current_frame != frame) {
|
||||
update_frame(frame);
|
||||
_current_frame = frame;
|
||||
}
|
||||
_last_frame_update = this_frame;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: VideoTexture::clear_current_frame
|
||||
// Access: Protected
|
||||
// Description: Resets the record of the current frame so that it
|
||||
// will be forced to reload the next time it is
|
||||
// requested.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void VideoTexture::
|
||||
clear_current_frame() {
|
||||
_last_frame_update = 0;
|
||||
_current_frame = -1;
|
||||
}
|
||||
|
|
@ -0,0 +1,152 @@
|
|||
// Filename: videoTexture.cxx
|
||||
// Created by: drose (21Sep05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "videoTexture.h"
|
||||
#include "clockObject.h"
|
||||
#include "config_gobj.h"
|
||||
|
||||
TypeHandle VideoTexture::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: VideoTexture::Constructor
|
||||
// Access: Protected
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
VideoTexture::
|
||||
VideoTexture(const string &name) :
|
||||
Texture(name)
|
||||
{
|
||||
_power_2 = (textures_power_2 != ATS_none);
|
||||
_video_width = 0;
|
||||
_video_height = 0;
|
||||
|
||||
_last_frame_update = 0;
|
||||
_current_frame = -1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: VideoTexture::Copy Constructor
|
||||
// Access: Protected
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
VideoTexture::
|
||||
VideoTexture(const VideoTexture ©) :
|
||||
Texture(copy),
|
||||
AnimInterface(copy),
|
||||
_power_2(copy._power_2),
|
||||
_video_width(copy._video_width),
|
||||
_video_height(copy._video_height),
|
||||
_last_frame_update(copy._last_frame_update),
|
||||
_current_frame(copy._current_frame)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: VideoTexture::has_ram_image
|
||||
// Access: Published, Virtual
|
||||
// Description: Returns true if the Texture has its image contents
|
||||
// available in main RAM, false if it exists only in
|
||||
// texture memory or in the prepared GSG context.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool VideoTexture::
|
||||
has_ram_image() const {
|
||||
int this_frame = ClockObject::get_global_clock()->get_frame_count();
|
||||
if (this_frame != _last_frame_update) {
|
||||
return false;
|
||||
}
|
||||
return !_image.empty();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: VideoTexture::get_keep_ram_image
|
||||
// Access: Published, Virtual
|
||||
// Description: Returns the flag that indicates whether this Texture
|
||||
// is eligible to have its main RAM copy of the texture
|
||||
// memory dumped when the texture is prepared for
|
||||
// rendering. See set_keep_ram_image().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool VideoTexture::
|
||||
get_keep_ram_image() const {
|
||||
// An VideoTexture should never dump its RAM image.
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: VideoTexture::has_cull_callback
|
||||
// Access: Public, Virtual
|
||||
// Description: Should be overridden by derived classes to return
|
||||
// true if cull_callback() has been defined. Otherwise,
|
||||
// returns false to indicate cull_callback() does not
|
||||
// need to be called for this node during the cull
|
||||
// traversal.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool VideoTexture::
|
||||
has_cull_callback() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: VideoTexture::cull_callback
|
||||
// Access: Public, Virtual
|
||||
// Description: If has_cull_callback() returns true, this function
|
||||
// will be called during the cull traversal to perform
|
||||
// any additional operations that should be performed at
|
||||
// cull time.
|
||||
//
|
||||
// This is called each time the Texture is discovered
|
||||
// applied to a Geom in the traversal. It should return
|
||||
// true if the Geom is visible, false if it should be
|
||||
// omitted.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool VideoTexture::
|
||||
cull_callback(CullTraverser *, const CullTraverserData &) const {
|
||||
// Strictly speaking, the cull_callback() method isn't necessary for
|
||||
// VideoTexture, since the get_ram_image() function is already
|
||||
// overloaded to update itself if necessary. However, we define it
|
||||
// anyway, to move the update calculation into the cull traversal
|
||||
// rather than the draw traversal.
|
||||
((VideoTexture *)this)->reconsider_dirty();
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: VideoTexture::reconsider_dirty
|
||||
// Access: Protected, Virtual
|
||||
// Description: Called by TextureContext to give the Texture a chance
|
||||
// to mark itself dirty before rendering, if necessary.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void VideoTexture::
|
||||
reconsider_dirty() {
|
||||
consider_update();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: VideoTexture::reload_ram_image
|
||||
// Access: Protected, Virtual
|
||||
// Description: Called when the Texture image is required but the ram
|
||||
// image is not available, this will reload it from disk
|
||||
// or otherwise do whatever is required to make it
|
||||
// available, if possible.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void VideoTexture::
|
||||
reload_ram_image() {
|
||||
consider_update();
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
// Filename: videoTexture.h
|
||||
// Created by: drose (21Sep05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef VIDEOTEXTURE_H
|
||||
#define VIDEOTEXTURE_H
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "texture.h"
|
||||
#include "animInterface.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : VideoTexture
|
||||
// Description : The base class for a family of animated Textures that
|
||||
// take their input from a video source, such as a movie
|
||||
// file. These Textures may be stopped, started,
|
||||
// etc. using the AnimInterface controls, similar to an
|
||||
// animated character.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA VideoTexture : public Texture, public AnimInterface {
|
||||
protected:
|
||||
VideoTexture(const string &name);
|
||||
VideoTexture(const VideoTexture ©);
|
||||
|
||||
PUBLISHED:
|
||||
INLINE void set_power_2(bool power_2);
|
||||
INLINE bool get_power_2() const;
|
||||
|
||||
virtual bool has_ram_image() const;
|
||||
virtual bool get_keep_ram_image() const;
|
||||
|
||||
INLINE int get_video_width() const;
|
||||
INLINE int get_video_height() const;
|
||||
INLINE LVecBase2f get_tex_scale() const;
|
||||
|
||||
public:
|
||||
virtual bool has_cull_callback() const;
|
||||
virtual bool cull_callback(CullTraverser *trav, const CullTraverserData &data) const;
|
||||
|
||||
protected:
|
||||
INLINE void set_video_size(int video_width, int video_height);
|
||||
|
||||
virtual void reconsider_dirty();
|
||||
virtual void reload_ram_image();
|
||||
|
||||
INLINE void consider_update();
|
||||
INLINE void clear_current_frame();
|
||||
virtual void update_frame(int frame)=0;
|
||||
|
||||
private:
|
||||
bool _power_2;
|
||||
int _video_width;
|
||||
int _video_height;
|
||||
int _last_frame_update;
|
||||
int _current_frame;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
Texture::init_type();
|
||||
AnimInterface::init_type();
|
||||
register_type(_type_handle, "VideoTexture",
|
||||
Texture::get_class_type(),
|
||||
AnimInterface::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
}
|
||||
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
};
|
||||
|
||||
#include "videoTexture.I"
|
||||
|
||||
#endif
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
#define OTHER_LIBS interrogatedb:c dconfig:c dtoolconfig:m \
|
||||
dtoolutil:c dtoolbase:c dtool:m
|
||||
|
||||
#define USE_PACKAGES cv
|
||||
#define USE_PACKAGES opencv
|
||||
|
||||
#begin lib_target
|
||||
#define TARGET grutil
|
||||
|
|
@ -16,13 +16,13 @@
|
|||
frameRateMeter.I frameRateMeter.h \
|
||||
lineSegs.I lineSegs.h \
|
||||
multitexReducer.I multitexReducer.h multitexReducer.cxx \
|
||||
aviTexture.h aviTexture.I
|
||||
openCVTexture.h openCVTexture.I
|
||||
|
||||
#define INCLUDED_SOURCES \
|
||||
cardMaker.cxx \
|
||||
config_grutil.cxx \
|
||||
frameRateMeter.cxx \
|
||||
aviTexture.cxx \
|
||||
openCVTexture.cxx \
|
||||
lineSegs.cxx
|
||||
|
||||
|
||||
|
|
@ -31,7 +31,7 @@
|
|||
frameRateMeter.I frameRateMeter.h \
|
||||
lineSegs.I lineSegs.h \
|
||||
multitexReducer.I multitexReducer.h \
|
||||
aviTexture.I aviTexture.h
|
||||
openCVTexture.I openCVTexture.h
|
||||
|
||||
#define IGATESCAN all
|
||||
|
||||
|
|
|
|||
|
|
@ -1,134 +0,0 @@
|
|||
// Filename: aviTexture.I
|
||||
// Created by: zacpavlov (19Aug05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AviTexture::obtain_ram
|
||||
// Access: Private
|
||||
// Description: Grabs a fresh ram buffer to mess with
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool AviTexture::
|
||||
obtain_ram() {
|
||||
_buf = modify_ram_image();
|
||||
|
||||
if (_buf) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AviTexture::get_time
|
||||
// Access: Published
|
||||
// Description: returns the ratio between 0 and 1 that the movie is
|
||||
// positioned at. Disabled for camera input
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE float AviTexture::
|
||||
get_time() {
|
||||
if (!_isCamera) {
|
||||
return _time;
|
||||
}
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AviTexture::set_time
|
||||
// Access: Published
|
||||
// Description: sets the time on the opencv video reader. Disabled
|
||||
// for camera input
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void AviTexture::
|
||||
set_time(float t) {
|
||||
if (_isCamera) {
|
||||
return;
|
||||
}
|
||||
if (t >= 0 && t <= 1) {
|
||||
_time=t;
|
||||
}
|
||||
if (_capture) {
|
||||
cvSetCaptureProperty(_capture,CV_CAP_PROP_POS_AVI_RATIO,t);
|
||||
_current_frame = cvGetCaptureProperty(_capture,CV_CAP_PROP_POS_FRAMES);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AviTexture::set_fps
|
||||
// Access: Published
|
||||
// Description: sets the fps for the movie, and affects frame receives
|
||||
// from camera. Note, since frame update is controlled
|
||||
// by python, this item is sort of arbitrary
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void AviTexture::
|
||||
set_fps(float fps) {
|
||||
if (fps >= 0) {
|
||||
_fps = fps;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
if (_isCamera && _capture) {
|
||||
cvSetCaptureProperty(_capture,CV_CAP_PROP_FPS,int(fps));
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AviTexture::get_fps
|
||||
// Access: Published
|
||||
// Description: returns the fps as recieved from movie
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE float AviTexture::
|
||||
get_fps() {
|
||||
return _fps;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AviTexture::get_total_frames
|
||||
// Access: Published
|
||||
// Description: returns the total amount of frames
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int AviTexture::
|
||||
get_total_frames() {
|
||||
return _total_frames;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AviTexture::get_current_frame
|
||||
// Access: Published
|
||||
// Description: returns current frame (base 0)
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int AviTexture::
|
||||
get_current_frame() {
|
||||
return _current_frame;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AviTexture::set_current_frame
|
||||
// Access: Published
|
||||
// Description: sets the current frame (base 0)
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void AviTexture::
|
||||
set_current_frame(int frame) {
|
||||
if (frame>=0 && frame<_total_frames) {
|
||||
_current_frame = frame;
|
||||
cvSetCaptureProperty(_capture,CV_CAP_PROP_POS_FRAMES,_current_frame);
|
||||
_time = cvGetCaptureProperty(_capture,CV_CAP_PROP_POS_AVI_RATIO);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,163 +0,0 @@
|
|||
// Filename: aviTexture.cxx
|
||||
// Created by: zacpavlov (19Aug05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#ifdef HAVE_CV
|
||||
#include "aviTexture.h"
|
||||
|
||||
TypeHandle AviTexture::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AviTexture::Constructor
|
||||
// Access: Published
|
||||
// Description: Sets up the texture to read frames from a camera
|
||||
////////////////////////////////////////////////////////////////////
|
||||
AviTexture::
|
||||
AviTexture() {
|
||||
_isCamera = true;
|
||||
_capture = cvCaptureFromCAM(0);
|
||||
_buf = NULL;
|
||||
_magicNum = 0;
|
||||
_time = 0.0f;
|
||||
_fps = 30.0f;
|
||||
_total_frames = 0;
|
||||
_current_frame = 0;
|
||||
|
||||
if (_capture) {
|
||||
cvSetCaptureProperty(_capture, CV_CAP_PROP_FPS,_fps);
|
||||
_width = cvGetCaptureProperty(_capture, CV_CAP_PROP_FRAME_WIDTH);
|
||||
_height = cvGetCaptureProperty(_capture, CV_CAP_PROP_FRAME_HEIGHT);
|
||||
|
||||
if (_width < _height) {
|
||||
gen_tex(_width);
|
||||
} else {
|
||||
gen_tex(_height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AviTexture::Constructor
|
||||
// Access: Published
|
||||
// Description: Defines the texture as a movie texture.
|
||||
// TODO: Make this search the panda paths
|
||||
////////////////////////////////////////////////////////////////////
|
||||
AviTexture::
|
||||
AviTexture(const string &filename) {
|
||||
_isCamera = false;
|
||||
_capture = cvCaptureFromFile(filename.c_str());
|
||||
_buf = NULL;
|
||||
_magicNum = 0;
|
||||
_time = 0.0f;
|
||||
_fps = 30.0f;
|
||||
_total_frames = 0;
|
||||
_current_frame = 0;
|
||||
|
||||
if (_capture) {
|
||||
_fps = cvGetCaptureProperty(_capture, CV_CAP_PROP_FPS);
|
||||
_total_frames = cvGetCaptureProperty(_capture, CV_CAP_PROP_FRAME_COUNT);
|
||||
_width = cvGetCaptureProperty(_capture, CV_CAP_PROP_FRAME_WIDTH);
|
||||
_height = cvGetCaptureProperty(_capture, CV_CAP_PROP_FRAME_HEIGHT);
|
||||
|
||||
if (_width < _height) {
|
||||
gen_tex(_width);
|
||||
} else {
|
||||
gen_tex(_height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AviTexture::Destructor
|
||||
// Access: Published
|
||||
// Description: Destructor. Release the camera or video stream
|
||||
////////////////////////////////////////////////////////////////////
|
||||
AviTexture::
|
||||
~AviTexture() {
|
||||
cvReleaseCapture(&_capture);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AviTexture::gen_tex
|
||||
// Access: Published
|
||||
// Description: Tries to find the largest texture that will fit
|
||||
// inside the video stream. TODO: allow for fit around
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AviTexture::
|
||||
gen_tex(int magicNum) {
|
||||
int size = down_to_power_2(magicNum);
|
||||
|
||||
setup_2d_texture(size, size, Texture::T_unsigned_byte, Texture::F_rgb8);
|
||||
_magicNum = size;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AviTexture::update
|
||||
// Access: Published
|
||||
// Description: Grabs the next frame off the camera or avi file
|
||||
// Returns false if the capture fails or reached EOF
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool AviTexture::
|
||||
update() {
|
||||
int begx, endx, begy, endy;
|
||||
IplImage *frame = 0;
|
||||
int xs, ys;
|
||||
|
||||
if (_capture) {
|
||||
if (_time == 1.0f) {
|
||||
return false;
|
||||
}
|
||||
frame = cvQueryFrame( _capture );
|
||||
|
||||
if (frame) {
|
||||
_time = cvGetCaptureProperty(_capture, CV_CAP_PROP_POS_AVI_RATIO);
|
||||
_current_frame = cvGetCaptureProperty(_capture, CV_CAP_PROP_POS_FRAMES);
|
||||
if (!obtain_ram()) {
|
||||
return false;
|
||||
}
|
||||
begx = (_width - _magicNum) / 2.0;
|
||||
endx = _width - begx;
|
||||
begy = (_height - _magicNum) / 2.0;
|
||||
endy = _height - begy;
|
||||
|
||||
if (_buf) {
|
||||
xs = get_x_size();
|
||||
ys = get_y_size();
|
||||
|
||||
if (get_num_components() != 3) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = begy; i < endy; ++i) {
|
||||
memcpy(_buf + ((i - begy) * xs * 3),
|
||||
frame->imageData + i * _width * 3 + begx * 3,
|
||||
xs * 3);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif // HAVE_CV
|
||||
|
||||
|
|
@ -1,94 +0,0 @@
|
|||
// Filename: aviTexture.h
|
||||
// Created by: zacpavlov (19Aug05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef AVITEXTURE_H
|
||||
#define AVITEXTURE_H
|
||||
|
||||
#include "pandabase.h"
|
||||
#ifdef HAVE_CV
|
||||
|
||||
#include "texture.h"
|
||||
#include <cxcore.h>
|
||||
#include <cv.h>
|
||||
#include <highgui.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : AviTexture
|
||||
// Description : A specialization on Texture that takes its input
|
||||
// using the CV library, to produce an animated texture,
|
||||
// with its source taken from an .avi file or from a
|
||||
// camera input.
|
||||
//
|
||||
// Presently, it is necessary for the application to
|
||||
// call update() periodically to advance to the next
|
||||
// frame.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA AviTexture : public Texture {
|
||||
PUBLISHED:
|
||||
AviTexture();
|
||||
AviTexture(const string &filename);
|
||||
~AviTexture();
|
||||
|
||||
INLINE void set_time(float t);
|
||||
INLINE float get_time();
|
||||
INLINE float get_fps();
|
||||
INLINE void set_fps(float fps);
|
||||
INLINE int get_total_frames();
|
||||
INLINE int get_current_frame();
|
||||
INLINE void set_current_frame(int frame);
|
||||
bool update();
|
||||
|
||||
private:
|
||||
void gen_tex(int magicNum);
|
||||
INLINE bool obtain_ram();
|
||||
|
||||
int _magicNum;
|
||||
PTA_uchar _buf;
|
||||
CvCapture * _capture;
|
||||
float _time;
|
||||
bool _isCamera;
|
||||
float _fps;
|
||||
int _total_frames;
|
||||
int _current_frame;
|
||||
int _width;
|
||||
int _height;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
Texture::init_type();
|
||||
register_type(_type_handle, "AviTexture",
|
||||
Texture::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
}
|
||||
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
|
||||
|
||||
private:
|
||||
|
||||
static TypeHandle _type_handle;
|
||||
};
|
||||
|
||||
#include "aviTexture.I"
|
||||
|
||||
#endif // HAVE_CV
|
||||
|
||||
#endif
|
||||
|
|
@ -18,7 +18,9 @@
|
|||
|
||||
#include "config_grutil.h"
|
||||
#include "frameRateMeter.h"
|
||||
#include "aviTexture.h"
|
||||
#include "openCVTexture.h"
|
||||
#include "pandaSystem.h"
|
||||
#include "texturePool.h"
|
||||
|
||||
#include "dconfig.h"
|
||||
|
||||
|
|
@ -63,8 +65,13 @@ init_libgrutil() {
|
|||
|
||||
FrameRateMeter::init_type();
|
||||
|
||||
#ifdef HAVE_CV
|
||||
AviTexture::init_type();
|
||||
#endif // HAVE_CV
|
||||
#ifdef HAVE_OPENCV
|
||||
OpenCVTexture::init_type();
|
||||
|
||||
PandaSystem *ps = PandaSystem::get_global_ptr();
|
||||
ps->add_system("OpenCV");
|
||||
TexturePool *ts = TexturePool::get_global_ptr();
|
||||
ts->register_texture_type(OpenCVTexture::make_texture, "avi");
|
||||
#endif // HAVE_OPENCV
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,5 +2,5 @@
|
|||
#include "config_grutil.cxx"
|
||||
#include "lineSegs.cxx"
|
||||
#include "frameRateMeter.cxx"
|
||||
#include "aviTexture.cxx"
|
||||
#include "openCVTexture.cxx"
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,70 @@
|
|||
// Filename: openCVTexture.I
|
||||
// Created by: zacpavlov (19Aug05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: OpenCVTexture::VideoStream::is_valid
|
||||
// Access: Public
|
||||
// Description: Returns true if this stream is open and ready, false
|
||||
// otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool OpenCVTexture::VideoStream::
|
||||
is_valid() const {
|
||||
return (_capture != NULL);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: OpenCVTexture::VideoStream::is_from_file
|
||||
// Access: Public
|
||||
// Description: Returns true if this stream takes its input from a
|
||||
// video file, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool OpenCVTexture::VideoStream::
|
||||
is_from_file() const {
|
||||
return !_filename.empty();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: OpenCVTexture::VideoPage::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE OpenCVTexture::VideoPage::
|
||||
VideoPage() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: OpenCVTexture::VideoPage::Copy Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE OpenCVTexture::VideoPage::
|
||||
VideoPage(const OpenCVTexture::VideoPage ©) :
|
||||
_color(copy._color),
|
||||
_alpha(copy._alpha)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: OpenCVTexture::VideoPage::Destructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE OpenCVTexture::VideoPage::
|
||||
~VideoPage() {
|
||||
}
|
||||
|
|
@ -0,0 +1,526 @@
|
|||
// Filename: openCVTexture.cxx
|
||||
// Created by: zacpavlov (19Aug05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#ifdef HAVE_OPENCV
|
||||
#include "openCVTexture.h"
|
||||
#include "clockObject.h"
|
||||
#include "config_gobj.h"
|
||||
#include "config_grutil.h"
|
||||
|
||||
TypeHandle OpenCVTexture::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: OpenCVTexture::Constructor
|
||||
// Access: Published
|
||||
// Description: Sets up the texture to read frames from a camera
|
||||
////////////////////////////////////////////////////////////////////
|
||||
OpenCVTexture::
|
||||
OpenCVTexture(const string &name) :
|
||||
VideoTexture(name)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: OpenCVTexture::Copy Constructor
|
||||
// Access: Protected
|
||||
// Description: Use OpenCVTexture::make_copy() to make a duplicate copy of
|
||||
// an existing OpenCVTexture.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
OpenCVTexture::
|
||||
OpenCVTexture(const OpenCVTexture ©) :
|
||||
VideoTexture(copy),
|
||||
_pages(copy._pages)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: OpenCVTexture::Destructor
|
||||
// Access: Published, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
OpenCVTexture::
|
||||
~OpenCVTexture() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: OpenCVTexture::make_copy
|
||||
// Access: Published, Virtual
|
||||
// Description: Returns a new copy of the same Texture. This copy,
|
||||
// if applied to geometry, will be copied into texture
|
||||
// as a separate texture from the original, so it will
|
||||
// be duplicated in texture memory (and may be
|
||||
// independently modified if desired).
|
||||
//
|
||||
// If the Texture is an OpenCVTexture, the resulting
|
||||
// duplicate may be animated independently of the
|
||||
// original.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(Texture) OpenCVTexture::
|
||||
make_copy() {
|
||||
return new OpenCVTexture(*this);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: OpenCVTexture::from_camera
|
||||
// Access: Published, Virtual
|
||||
// Description: Sets up the OpenCVTexture (or the indicated page, if z
|
||||
// is specified) to accept its input from the camera
|
||||
// with the given index number, or the default camera if
|
||||
// the index number is -1 or unspecified.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool OpenCVTexture::
|
||||
from_camera(int camera_index, int z) {
|
||||
if (!reconsider_z_size(z)) {
|
||||
return false;
|
||||
}
|
||||
nassertr(z >= 0 && z < get_z_size(), false);
|
||||
|
||||
VideoPage &page = modify_page(z);
|
||||
page._alpha.clear();
|
||||
if (!page._color.from_camera(camera_index)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int width = cvGetCaptureProperty(page._color._capture, CV_CAP_PROP_FRAME_WIDTH);
|
||||
int height = cvGetCaptureProperty(page._color._capture, CV_CAP_PROP_FRAME_HEIGHT);
|
||||
|
||||
if (!reconsider_video_properties(page._color, 3, z)) {
|
||||
page._color.clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
set_loaded_from_disk();
|
||||
clear_current_frame();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: OpenCVTexture::read
|
||||
// Access: Published, Virtual
|
||||
// Description: Takes the video image from the indicated filename.
|
||||
// If the filename is not a video file, attempts to read
|
||||
// it as a still image instead.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool OpenCVTexture::
|
||||
read(const Filename &fullpath, int z, int) {
|
||||
if (!reconsider_z_size(z)) {
|
||||
return false;
|
||||
}
|
||||
nassertr(z >= 0 && z < get_z_size(), false);
|
||||
|
||||
VideoPage &page = modify_page(z);
|
||||
page._alpha.clear();
|
||||
if (!page._color.read(fullpath)) {
|
||||
grutil_cat.error()
|
||||
<< "OpenCV couldn't read " << fullpath << " as video.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!has_name()) {
|
||||
set_name(fullpath.get_basename_wo_extension());
|
||||
}
|
||||
if (!has_filename()) {
|
||||
set_filename(fullpath);
|
||||
clear_alpha_filename();
|
||||
}
|
||||
|
||||
set_fullpath(fullpath);
|
||||
clear_alpha_fullpath();
|
||||
|
||||
_primary_file_num_channels = 3;
|
||||
_alpha_file_channel = 0;
|
||||
|
||||
if (!reconsider_video_properties(page._color, 3, z)) {
|
||||
page._color.clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
set_loaded_from_disk();
|
||||
clear_current_frame();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: OpenCVTexture::read
|
||||
// Access: Published, Virtual
|
||||
// Description: Combines a color and alpha video image from the two
|
||||
// indicated filenames. Both must be the same kind of
|
||||
// video with similar properties.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool OpenCVTexture::
|
||||
read(const Filename &fullpath, const Filename &alpha_fullpath,
|
||||
int z, int, int alpha_file_channel) {
|
||||
if (!reconsider_z_size(z)) {
|
||||
return false;
|
||||
}
|
||||
nassertr(z >= 0 && z < get_z_size(), false);
|
||||
|
||||
VideoPage &page = modify_page(z);
|
||||
if (!page._color.read(fullpath)) {
|
||||
grutil_cat.error()
|
||||
<< "OpenCV couldn't read " << fullpath << " as video.\n";
|
||||
return false;
|
||||
}
|
||||
if (!page._alpha.read(alpha_fullpath)) {
|
||||
grutil_cat.error()
|
||||
<< "OpenCV couldn't read " << alpha_fullpath << " as video.\n";
|
||||
page._color.clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!has_name()) {
|
||||
set_name(fullpath.get_basename_wo_extension());
|
||||
}
|
||||
if (!has_filename()) {
|
||||
set_filename(fullpath);
|
||||
set_alpha_filename(alpha_fullpath);
|
||||
}
|
||||
|
||||
set_fullpath(fullpath);
|
||||
set_alpha_fullpath(alpha_fullpath);
|
||||
|
||||
_primary_file_num_channels = 3;
|
||||
_alpha_file_channel = alpha_file_channel;
|
||||
|
||||
if (!reconsider_video_properties(page._color, 4, z)) {
|
||||
page._color.clear();
|
||||
page._alpha.clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!reconsider_video_properties(page._alpha, 4, z)) {
|
||||
page._color.clear();
|
||||
page._alpha.clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
set_loaded_from_disk();
|
||||
clear_current_frame();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: OpenCVTexture::load
|
||||
// Access: Published, Virtual
|
||||
// Description: Resets the texture (or the particular level of the
|
||||
// texture) to the indicated static image.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool OpenCVTexture::
|
||||
load(const PNMImage &pnmimage, int z) {
|
||||
if (z <= (int)_pages.size()) {
|
||||
VideoPage &page = modify_page(z);
|
||||
page._color.clear();
|
||||
page._alpha.clear();
|
||||
}
|
||||
|
||||
return Texture::load(pnmimage, z);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: OpenCVTexture::modify_page
|
||||
// Access: Private
|
||||
// Description: Returns a reference to the zth VideoPage (level) of
|
||||
// the texture. In the case of a 2-d texture, there is
|
||||
// only one page, level 0; but cube maps and 3-d
|
||||
// textures have more.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
OpenCVTexture::VideoPage &OpenCVTexture::
|
||||
modify_page(int z) {
|
||||
nassertr(z < _z_size, _pages[0]);
|
||||
while (z >= (int)_pages.size()) {
|
||||
_pages.push_back(VideoPage());
|
||||
}
|
||||
return _pages[z];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: OpenCVTexture::reconsider_video_properties
|
||||
// Access: Private
|
||||
// Description: Resets the internal Texture properties when a new
|
||||
// video file is loaded. Returns true if the new image
|
||||
// is valid, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool OpenCVTexture::
|
||||
reconsider_video_properties(const OpenCVTexture::VideoStream &stream,
|
||||
int num_components, int z) {
|
||||
double frame_rate = 0.0f;
|
||||
int num_frames = 0;
|
||||
|
||||
if (stream.is_from_file()) {
|
||||
frame_rate = cvGetCaptureProperty(stream._capture, CV_CAP_PROP_FPS);
|
||||
num_frames = (int)cvGetCaptureProperty(stream._capture, CV_CAP_PROP_FRAME_COUNT);
|
||||
}
|
||||
int width = (int)cvGetCaptureProperty(stream._capture, CV_CAP_PROP_FRAME_WIDTH);
|
||||
int height = (int)cvGetCaptureProperty(stream._capture, CV_CAP_PROP_FRAME_HEIGHT);
|
||||
|
||||
int x_size = width;
|
||||
int y_size = height;
|
||||
|
||||
if (get_power_2()) {
|
||||
x_size = up_to_power_2(width);
|
||||
y_size = up_to_power_2(height);
|
||||
}
|
||||
|
||||
if (!reconsider_image_properties(x_size, y_size, num_components,
|
||||
T_unsigned_byte, z)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_loaded_from_disk &&
|
||||
(get_video_width() != width || get_video_height() != height ||
|
||||
get_num_frames() != num_frames || get_frame_rate() != frame_rate)) {
|
||||
grutil_cat.error()
|
||||
<< "Video properties have changed for texture " << get_name()
|
||||
<< " level " << z << ".\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
set_frame_rate(frame_rate);
|
||||
set_num_frames(num_frames);
|
||||
set_video_size(width, height);
|
||||
|
||||
// By default, the newly-loaded video stream will immediately start
|
||||
// looping.
|
||||
loop(true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: OpenCVTexture::make_texture
|
||||
// Access: Public, Static
|
||||
// Description: A factory function to make a new OpenCVTexture, used
|
||||
// to pass to the TexturePool.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(Texture) OpenCVTexture::
|
||||
make_texture() {
|
||||
return new OpenCVTexture;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: OpenCVTexture::update_frame
|
||||
// Access: Protected, Virtual
|
||||
// Description: Called once per frame, as needed, to load the new
|
||||
// image contents.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void OpenCVTexture::
|
||||
update_frame(int frame) {
|
||||
int max_z = max(_z_size, (int)_pages.size());
|
||||
for (int z = 0; z < max_z; ++z) {
|
||||
VideoPage &page = _pages[z];
|
||||
if (page._color.is_valid() || page._alpha.is_valid()) {
|
||||
modify_ram_image();
|
||||
}
|
||||
if (page._color.is_valid()) {
|
||||
nassertv(get_num_components() >= 3 && get_component_width() == 1);
|
||||
|
||||
const unsigned char *source = page._color.get_frame_data(frame);
|
||||
if (source != NULL) {
|
||||
nassertv(get_video_width() <= _x_size && get_video_height() <= _y_size);
|
||||
unsigned char *dest = _image.p() + get_expected_ram_page_size() * z;
|
||||
|
||||
int dest_row_width = (_x_size * _num_components * _component_width);
|
||||
int source_row_width = get_video_width() * 3;
|
||||
|
||||
if (get_num_components() == 3) {
|
||||
// The easy case--copy the whole thing in, row by row.
|
||||
for (int y = 0; y < get_video_height(); ++y) {
|
||||
memcpy(dest, source, source_row_width);
|
||||
dest += dest_row_width;
|
||||
source += source_row_width;
|
||||
}
|
||||
|
||||
} else {
|
||||
// The harder case--interleave the color in with the alpha,
|
||||
// pixel by pixel.
|
||||
nassertv(get_num_components() == 4);
|
||||
for (int y = 0; y < get_video_height(); ++y) {
|
||||
int dx = 0;
|
||||
int sx = 0;
|
||||
for (int x = 0; x < get_video_width(); ++x) {
|
||||
dest[dx] = source[sx];
|
||||
dest[dx + 1] = source[sx + 1];
|
||||
dest[dx + 2] = source[sx + 2];
|
||||
dx += 4;
|
||||
sx += 3;
|
||||
}
|
||||
dest += dest_row_width;
|
||||
source += source_row_width;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (page._alpha.is_valid()) {
|
||||
nassertv(get_num_components() == 4 && get_component_width() == 1);
|
||||
|
||||
const unsigned char *source = page._alpha.get_frame_data(frame);
|
||||
if (source != NULL) {
|
||||
nassertv(get_video_width() <= _x_size && get_video_height() <= _y_size);
|
||||
unsigned char *dest = _image.p() + get_expected_ram_page_size() * z;
|
||||
|
||||
int dest_row_width = (_x_size * _num_components * _component_width);
|
||||
int source_row_width = get_video_width() * 3;
|
||||
|
||||
// Interleave the alpha in with the color, pixel by pixel.
|
||||
// Even though the alpha will probably be a grayscale video,
|
||||
// the OpenCV library presents it as RGB.
|
||||
for (int y = 0; y < get_video_height(); ++y) {
|
||||
int dx = 3;
|
||||
int sx = _alpha_file_channel;
|
||||
for (int x = 0; x < get_video_width(); ++x) {
|
||||
dest[dx] = source[sx];
|
||||
dx += 4;
|
||||
sx += 3;
|
||||
}
|
||||
dest += dest_row_width;
|
||||
source += source_row_width;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: OpenCVTexture::VideoStream::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
OpenCVTexture::VideoStream::
|
||||
VideoStream() :
|
||||
_capture(NULL),
|
||||
_camera_index(-1),
|
||||
_next_frame(0)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: OpenCVTexture::VideoStream::Copy Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
OpenCVTexture::VideoStream::
|
||||
VideoStream(const OpenCVTexture::VideoStream ©) :
|
||||
_capture(NULL),
|
||||
_camera_index(-1)
|
||||
{
|
||||
// Rather than copying the _capture pointer, we must open a new
|
||||
// stream that references the same file.
|
||||
if (copy.is_valid()) {
|
||||
if (copy.is_from_file()) {
|
||||
read(copy._filename);
|
||||
} else {
|
||||
from_camera(copy._camera_index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: OpenCVTexture::VideoStream::Copy Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
OpenCVTexture::VideoStream::
|
||||
~VideoStream() {
|
||||
clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: OpenCVTexture::VideoStream::get_frame_data
|
||||
// Access: Public
|
||||
// Description: Returns the pointer to the beginning of the
|
||||
// decompressed buffer for the indicated frame number.
|
||||
// It is most efficient to call this in increasing order
|
||||
// of frame number.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
const unsigned char *OpenCVTexture::VideoStream::
|
||||
get_frame_data(int frame) {
|
||||
nassertr(is_valid(), NULL);
|
||||
|
||||
if (is_from_file() && _next_frame != frame) {
|
||||
cvSetCaptureProperty(_capture, CV_CAP_PROP_POS_FRAMES, frame);
|
||||
}
|
||||
|
||||
_next_frame = frame + 1;
|
||||
IplImage *image = cvQueryFrame(_capture);
|
||||
if (image == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return (const unsigned char *)image->imageData;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: OpenCVTexture::VideoStream::read
|
||||
// Access: Public
|
||||
// Description: Sets up the stream to read the indicated file.
|
||||
// Returns true on success, false on failure.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool OpenCVTexture::VideoStream::
|
||||
read(const Filename &filename) {
|
||||
clear();
|
||||
|
||||
string os_specific = filename.to_os_specific();
|
||||
_capture = cvCaptureFromFile(os_specific.c_str());
|
||||
if (_capture == NULL) {
|
||||
return false;
|
||||
}
|
||||
_filename = filename;
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: OpenCVTexture::VideoStream::from_camera
|
||||
// Access: Public
|
||||
// Description: Sets up the stream to display the indicated camera.
|
||||
// Returns true on success, false on failure.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool OpenCVTexture::VideoStream::
|
||||
from_camera(int camera_index) {
|
||||
clear();
|
||||
|
||||
_capture = cvCaptureFromCAM(camera_index);
|
||||
if (_capture == NULL) {
|
||||
return false;
|
||||
}
|
||||
_camera_index = camera_index;
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: OpenCVTexture::VideoStream::clear
|
||||
// Access: Public
|
||||
// Description: Stops the video playback and frees the associated
|
||||
// resources.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void OpenCVTexture::VideoStream::
|
||||
clear() {
|
||||
if (_capture != NULL) {
|
||||
cvReleaseCapture(&_capture);
|
||||
_capture = NULL;
|
||||
}
|
||||
_filename = Filename();
|
||||
_camera_index = -1;
|
||||
_next_frame = 0;
|
||||
}
|
||||
|
||||
#endif // HAVE_OPENCV
|
||||
|
||||
|
|
@ -0,0 +1,125 @@
|
|||
// Filename: openCVTexture.h
|
||||
// Created by: zacpavlov (19Aug05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef OPENCVTEXTURE_H
|
||||
#define OPENCVTEXTURE_H
|
||||
|
||||
#include "pandabase.h"
|
||||
#ifdef HAVE_OPENCV
|
||||
|
||||
#include "videoTexture.h"
|
||||
|
||||
#include <cxcore.h>
|
||||
#include <cv.h>
|
||||
#include <highgui.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : OpenCVTexture
|
||||
// Description : A specialization on VideoTexture that takes its input
|
||||
// using the CV library, to produce an animated texture,
|
||||
// with its source taken from an .avi file or from a
|
||||
// camera input.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA OpenCVTexture : public VideoTexture {
|
||||
PUBLISHED:
|
||||
OpenCVTexture(const string &name = string());
|
||||
protected:
|
||||
OpenCVTexture(const OpenCVTexture ©);
|
||||
PUBLISHED:
|
||||
virtual ~OpenCVTexture();
|
||||
|
||||
virtual PT(Texture) make_copy();
|
||||
|
||||
bool from_camera(int camera_index = -1, int z = 0);
|
||||
|
||||
virtual bool read(const Filename &fullpath, int z = 0,
|
||||
int primary_file_num_channels = 0);
|
||||
virtual bool read(const Filename &fullpath, const Filename &alpha_fullpath,
|
||||
int z = 0,
|
||||
int primary_file_num_channels = 0, int alpha_file_channel = 0);
|
||||
virtual bool load(const PNMImage &pnmimage, int z = 0);
|
||||
|
||||
public:
|
||||
static PT(Texture) make_texture();
|
||||
|
||||
protected:
|
||||
virtual void update_frame(int frame);
|
||||
|
||||
private:
|
||||
class VideoPage;
|
||||
class VideoStream;
|
||||
|
||||
VideoPage &modify_page(int z);
|
||||
bool reconsider_video_properties(const VideoStream &stream,
|
||||
int num_components, int z);
|
||||
void do_update();
|
||||
|
||||
class VideoStream {
|
||||
public:
|
||||
VideoStream();
|
||||
VideoStream(const VideoStream ©);
|
||||
~VideoStream();
|
||||
|
||||
bool read(const Filename &filename);
|
||||
bool from_camera(int camera_index);
|
||||
void clear();
|
||||
INLINE bool is_valid() const;
|
||||
INLINE bool is_from_file() const;
|
||||
const unsigned char *get_frame_data(int frame);
|
||||
|
||||
CvCapture *_capture;
|
||||
Filename _filename;
|
||||
int _camera_index;
|
||||
int _next_frame;
|
||||
};
|
||||
|
||||
class VideoPage {
|
||||
public:
|
||||
INLINE VideoPage();
|
||||
INLINE VideoPage(const VideoPage ©);
|
||||
INLINE ~VideoPage();
|
||||
|
||||
VideoStream _color, _alpha;
|
||||
};
|
||||
|
||||
typedef pvector<VideoPage> Pages;
|
||||
Pages _pages;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
VideoTexture::init_type();
|
||||
register_type(_type_handle, "OpenCVTexture",
|
||||
VideoTexture::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
}
|
||||
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
};
|
||||
|
||||
#include "openCVTexture.I"
|
||||
|
||||
#endif // HAVE_OPENCV
|
||||
|
||||
#endif
|
||||
|
|
@ -214,7 +214,12 @@ traverse_below(CullTraverserData &data) {
|
|||
_geoms_pcollector.add_level(num_geoms);
|
||||
for (int i = 0; i < num_geoms; i++) {
|
||||
CullableObject *object = new CullableObject(data, geom_node, i);
|
||||
_cull_handler->record_object(object, this);
|
||||
if (object->_state->has_cull_callback() &&
|
||||
!object->_state->cull_callback(this, data)) {
|
||||
delete object;
|
||||
} else {
|
||||
_cull_handler->record_object(object, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -533,7 +538,14 @@ start_decal(const CullTraverserData &data) {
|
|||
int num_geoms = geom_node->get_num_geoms();
|
||||
_geoms_pcollector.add_level(num_geoms);
|
||||
for (int i = num_geoms - 1; i >= 0; i--) {
|
||||
object = new CullableObject(data, geom_node, i, object);
|
||||
CullableObject *next_object =
|
||||
new CullableObject(data, geom_node, i, object);
|
||||
if (next_object->_state->has_cull_callback() &&
|
||||
!next_object->_state->cull_callback(this, data)) {
|
||||
delete next_object;
|
||||
} else {
|
||||
object = next_object;
|
||||
}
|
||||
}
|
||||
|
||||
if (object != separator) {
|
||||
|
|
@ -591,7 +603,14 @@ r_get_decals(CullTraverserData &data, CullableObject *decals) {
|
|||
int num_geoms = geom_node->get_num_geoms();
|
||||
_geoms_pcollector.add_level(num_geoms);
|
||||
for (int i = num_geoms - 1; i >= 0; i--) {
|
||||
decals = new CullableObject(data, geom_node, i, decals);
|
||||
CullableObject *next_decals =
|
||||
new CullableObject(data, geom_node, i, decals);
|
||||
if (next_decals->_state->has_cull_callback() &&
|
||||
!next_decals->_state->cull_callback(this, data)) {
|
||||
delete next_decals;
|
||||
} else {
|
||||
decals = next_decals;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -125,6 +125,38 @@ lower_attrib_can_override() const {
|
|||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RenderAttrib::has_cull_callback
|
||||
// Access: Public, Virtual
|
||||
// Description: Should be overridden by derived classes to return
|
||||
// true if cull_callback() has been defined. Otherwise,
|
||||
// returns false to indicate cull_callback() does not
|
||||
// need to be called for this node during the cull
|
||||
// traversal.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool RenderAttrib::
|
||||
has_cull_callback() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RenderAttrib::cull_callback
|
||||
// Access: Public, Virtual
|
||||
// Description: If has_cull_callback() returns true, this function
|
||||
// will be called during the cull traversal to perform
|
||||
// any additional operations that should be performed at
|
||||
// cull time.
|
||||
//
|
||||
// This is called each time the RenderAttrib is
|
||||
// discovered applied to a Geom in the traversal. It
|
||||
// should return true if the Geom is visible, false if
|
||||
// it should be omitted.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool RenderAttrib::
|
||||
cull_callback(CullTraverser *, const CullTraverserData &) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RenderAttrib::output
|
||||
// Access: Published, Virtual
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@
|
|||
|
||||
class AttribSlots;
|
||||
class GraphicsStateGuardianBase;
|
||||
class CullTraverser;
|
||||
class CullTraverserData;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : RenderAttrib
|
||||
|
|
@ -73,6 +75,9 @@ public:
|
|||
INLINE bool always_reissue() const;
|
||||
virtual void store_into_slot(AttribSlots *slots) const=0;
|
||||
|
||||
virtual bool has_cull_callback() const;
|
||||
virtual bool cull_callback(CullTraverser *trav, const CullTraverserData &data) const;
|
||||
|
||||
PUBLISHED:
|
||||
INLINE int compare_to(const RenderAttrib &other) const;
|
||||
virtual void output(ostream &out) const;
|
||||
|
|
|
|||
|
|
@ -61,6 +61,23 @@ get_override(int n) const {
|
|||
return _attributes[n]._override;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RenderState::has_cull_callback
|
||||
// Access: Published
|
||||
// Description: Returns true if any of the RenderAttribs in this
|
||||
// state request a cull_callback(), false if none of
|
||||
// them do.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool RenderState::
|
||||
has_cull_callback() const {
|
||||
if ((_flags & F_checked_cull_callback) == 0) {
|
||||
// We pretend this function is const, even though it transparently
|
||||
// modifies the internal shader cache.
|
||||
((RenderState *)this)->determine_cull_callback();
|
||||
}
|
||||
return (_flags & F_has_cull_callback) != 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RenderState::cache_ref
|
||||
// Access: Published
|
||||
|
|
|
|||
|
|
@ -136,6 +136,26 @@ operator < (const RenderState &other) const {
|
|||
CompareTo<Attribute>());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RenderState::cull_callback
|
||||
// Access: Published
|
||||
// Description: Calls cull_callback() on each attrib. If any attrib
|
||||
// returns false, interrupts the list and returns false
|
||||
// immediately; otherwise, completes the list and
|
||||
// returns true.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool RenderState::
|
||||
cull_callback(CullTraverser *trav, const CullTraverserData &data) const {
|
||||
Attributes::const_iterator ai;
|
||||
for (ai = _attributes.begin(); ai != _attributes.end(); ++ai) {
|
||||
const Attribute &attrib = *ai;
|
||||
if (!attrib._attrib->cull_callback(trav, data)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RenderState::find_attrib
|
||||
|
|
@ -1570,6 +1590,25 @@ determine_shader() {
|
|||
_flags |= F_checked_shader;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RenderState::determine_cull_callback
|
||||
// Access: Private
|
||||
// Description: This is the private implementation of has_cull_callback().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void RenderState::
|
||||
determine_cull_callback() {
|
||||
Attributes::const_iterator ai;
|
||||
for (ai = _attributes.begin(); ai != _attributes.end(); ++ai) {
|
||||
const Attribute &attrib = *ai;
|
||||
if (attrib._attrib->has_cull_callback()) {
|
||||
_flags |= F_has_cull_callback;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_flags |= F_checked_cull_callback;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RenderState::update_pstats
|
||||
// Access: Private
|
||||
|
|
|
|||
|
|
@ -75,6 +75,9 @@ PUBLISHED:
|
|||
INLINE const RenderAttrib *get_attrib(int n) const;
|
||||
INLINE int get_override(int n) const;
|
||||
|
||||
INLINE bool has_cull_callback() const;
|
||||
bool cull_callback(CullTraverser *trav, const CullTraverserData &data) const;
|
||||
|
||||
int find_attrib(TypeHandle type) const;
|
||||
|
||||
static CPT(RenderState) make_empty();
|
||||
|
|
@ -181,6 +184,7 @@ private:
|
|||
void determine_render_mode();
|
||||
void determine_clip_plane();
|
||||
void determine_shader();
|
||||
void determine_cull_callback();
|
||||
|
||||
INLINE void set_destructing();
|
||||
INLINE bool is_destructing() const;
|
||||
|
|
@ -282,19 +286,21 @@ private:
|
|||
const ShaderAttrib *_shader;
|
||||
|
||||
enum Flags {
|
||||
F_checked_bin_index = 0x0001,
|
||||
F_checked_fog = 0x0002,
|
||||
F_checked_bin = 0x0004,
|
||||
F_checked_transparency = 0x0008,
|
||||
F_checked_color = 0x0010,
|
||||
F_checked_color_scale = 0x0020,
|
||||
F_checked_texture = 0x0040,
|
||||
F_checked_tex_gen = 0x0080,
|
||||
F_checked_tex_matrix = 0x0100,
|
||||
F_checked_render_mode = 0x0200,
|
||||
F_checked_clip_plane = 0x0400,
|
||||
F_checked_shader = 0x0800,
|
||||
F_is_destructing = 0x8000,
|
||||
F_checked_bin_index = 0x0001,
|
||||
F_checked_fog = 0x0002,
|
||||
F_checked_bin = 0x0004,
|
||||
F_checked_transparency = 0x0008,
|
||||
F_checked_color = 0x0010,
|
||||
F_checked_color_scale = 0x0020,
|
||||
F_checked_texture = 0x0040,
|
||||
F_checked_tex_gen = 0x0080,
|
||||
F_checked_tex_matrix = 0x0100,
|
||||
F_checked_render_mode = 0x0200,
|
||||
F_checked_clip_plane = 0x0400,
|
||||
F_checked_shader = 0x0800,
|
||||
F_checked_cull_callback = 0x1000,
|
||||
F_has_cull_callback = 0x2000,
|
||||
F_is_destructing = 0x8000,
|
||||
};
|
||||
unsigned short _flags;
|
||||
|
||||
|
|
|
|||
|
|
@ -390,6 +390,54 @@ output(ostream &out) const {
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextureAttrib::has_cull_callback
|
||||
// Access: Public, Virtual
|
||||
// Description: Should be overridden by derived classes to return
|
||||
// true if cull_callback() has been defined. Otherwise,
|
||||
// returns false to indicate cull_callback() does not
|
||||
// need to be called for this node during the cull
|
||||
// traversal.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool TextureAttrib::
|
||||
has_cull_callback() const {
|
||||
OnTextures::const_iterator nti;
|
||||
for (nti = _on_textures.begin(); nti != _on_textures.end(); ++nti) {
|
||||
Texture *texture = (*nti).second;
|
||||
if (texture->has_cull_callback()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextureAttrib::cull_callback
|
||||
// Access: Public, Virtual
|
||||
// Description: If has_cull_callback() returns true, this function
|
||||
// will be called during the cull traversal to perform
|
||||
// any additional operations that should be performed at
|
||||
// cull time.
|
||||
//
|
||||
// This is called each time the RenderAttrib is
|
||||
// discovered applied to a Geom in the traversal. It
|
||||
// should return true if the Geom is visible, false if
|
||||
// it should be omitted.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool TextureAttrib::
|
||||
cull_callback(CullTraverser *trav, const CullTraverserData &data) const {
|
||||
OnTextures::const_iterator nti;
|
||||
for (nti = _on_textures.begin(); nti != _on_textures.end(); ++nti) {
|
||||
Texture *texture = (*nti).second;
|
||||
if (!texture->cull_callback(trav, data)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextureAttrib::compare_to_impl
|
||||
// Access: Protected, Virtual
|
||||
|
|
|
|||
|
|
@ -84,6 +84,9 @@ public:
|
|||
virtual void output(ostream &out) const;
|
||||
virtual void store_into_slot(AttribSlots *slots) const;
|
||||
|
||||
virtual bool has_cull_callback() const;
|
||||
virtual bool cull_callback(CullTraverser *trav, const CullTraverserData &data) const;
|
||||
|
||||
protected:
|
||||
virtual int compare_to_impl(const RenderAttrib *other) const;
|
||||
virtual CPT(RenderAttrib) compose_impl(const RenderAttrib *other) const;
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx
|
||||
|
||||
#define SOURCES \
|
||||
animInterface.h animInterface.I \
|
||||
bam.h bamEndian.h \
|
||||
bamReader.I bamReader.N bamReader.h bamReaderParam.I \
|
||||
bamReaderParam.h bamWriter.I bamWriter.h bitMask.I \
|
||||
|
|
@ -60,6 +61,7 @@
|
|||
writableParam.I writableParam.h
|
||||
|
||||
#define INCLUDED_SOURCES \
|
||||
animInterface.cxx \
|
||||
bamEndian.cxx \
|
||||
bamReader.cxx bamReaderParam.cxx bamWriter.cxx bitMask.cxx \
|
||||
buttonHandle.cxx buttonRegistry.cxx \
|
||||
|
|
@ -96,6 +98,7 @@
|
|||
writableConfigurable.cxx writableParam.cxx
|
||||
|
||||
#define INSTALL_HEADERS \
|
||||
animInterface.h animInterface.I \
|
||||
bam.h bamEndian.h \
|
||||
bamReader.I bamReader.h bamReaderParam.I bamReaderParam.h \
|
||||
bamWriter.I bamWriter.h bitMask.I bitMask.h \
|
||||
|
|
|
|||
|
|
@ -0,0 +1,178 @@
|
|||
// Filename: animInterface.I
|
||||
// Created by: drose (20Sep05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimInterface::play
|
||||
// Access: Published
|
||||
// Description: Runs the entire animation from beginning to end and
|
||||
// stops.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void AnimInterface::
|
||||
play() {
|
||||
play(0, get_num_frames() - 1);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimInterface::loop
|
||||
// Access: Published
|
||||
// Description: Starts the entire animation looping. If restart is
|
||||
// true, the animation is restarted from the beginning;
|
||||
// otherwise, it continues from the current frame.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void AnimInterface::
|
||||
loop(bool restart) {
|
||||
loop(restart, 0, get_num_frames() - 1);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimInterface::pingpong
|
||||
// Access: Published
|
||||
// Description: Starts the entire animation bouncing back and forth
|
||||
// between its first frame and last frame. If restart
|
||||
// is true, the animation is restarted from the
|
||||
// beginning; otherwise, it continues from the current
|
||||
// frame.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void AnimInterface::
|
||||
pingpong(bool restart) {
|
||||
pingpong(restart, 0, get_num_frames() - 1);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimInterface::stop
|
||||
// Access: Published
|
||||
// Description: Stops a currently playing or looping animation right
|
||||
// where it is. The animation remains posed at the
|
||||
// current frame.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void AnimInterface::
|
||||
stop() {
|
||||
pose(get_frame());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimInterface::set_play_rate
|
||||
// Access: Published
|
||||
// Description: Changes the rate at which the animation plays. 1.0
|
||||
// is the normal speed, 2.0 is twice normal speed, and
|
||||
// 0.5 is half normal speed. 0.0 is legal to pause the
|
||||
// animation, and a negative value will play the
|
||||
// animation backwards.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void AnimInterface::
|
||||
set_play_rate(double play_rate) {
|
||||
internal_set_rate(_frame_rate, play_rate);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimInterface::get_play_rate
|
||||
// Access: Published
|
||||
// Description: Returns the rate at which the animation plays. See
|
||||
// set_play_rate().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE double AnimInterface::
|
||||
get_play_rate() const {
|
||||
return _play_rate;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimInterface::get_frame_rate
|
||||
// Access: Published
|
||||
// Description: Returns the native frame rate of the animation. This
|
||||
// is the number of frames per second that will elapse
|
||||
// when the play_rate is set to 1.0. It is a fixed
|
||||
// property of the animation and may not be adjusted by
|
||||
// the user.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE double AnimInterface::
|
||||
get_frame_rate() const {
|
||||
return _frame_rate;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimInterface::get_num_frames
|
||||
// Access: Published
|
||||
// Description: Returns the number of frames in the animation. This
|
||||
// is a fixed property of the animation and may not be
|
||||
// adjusted by the user.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int AnimInterface::
|
||||
get_num_frames() const {
|
||||
return _num_frames;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimInterface::get_frame
|
||||
// Access: Published
|
||||
// Description: Returns the current integer frame number.
|
||||
// This number will be in the range 0 <= f <
|
||||
// get_num_frames().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int AnimInterface::
|
||||
get_frame() const {
|
||||
return cmod(get_full_frame(), get_num_frames());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimInterface::get_frac
|
||||
// Access: Published
|
||||
// Description: Returns the fractional part of the current frame.
|
||||
// Normally, this is in the range 0.0 <= f < 1.0, but in
|
||||
// the one special case of an animation playing to its
|
||||
// end frame and stopping, it might exactly equal 1.0.
|
||||
//
|
||||
// It will always be true that get_full_frame() +
|
||||
// get_frac() == get_full_fframe().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE double AnimInterface::
|
||||
get_frac() const {
|
||||
return get_full_fframe() - (double)get_full_frame();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimInterface::set_frame_rate
|
||||
// Access: Protected
|
||||
// Description: Should be called by a derived class to specify the
|
||||
// native frame rate of the animation. It is legal to
|
||||
// call this after the animation has already started.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void AnimInterface::
|
||||
set_frame_rate(double frame_rate) {
|
||||
internal_set_rate(frame_rate, _play_rate);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimInterface::set_num_frames
|
||||
// Access: Protected
|
||||
// Description: Should be called by a derived class to specify the
|
||||
// number of frames of the animation. It is legal to
|
||||
// call this after the animation has already started,
|
||||
// but doing so may suddenly change the apparent current
|
||||
// frame number.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void AnimInterface::
|
||||
set_num_frames(int num_frames) {
|
||||
_num_frames = num_frames;
|
||||
}
|
||||
|
||||
INLINE ostream &
|
||||
operator << (ostream &out, const AnimInterface &ai) {
|
||||
ai.output(out);
|
||||
return out;
|
||||
}
|
||||
|
|
@ -0,0 +1,379 @@
|
|||
// Filename: animInterface.cxx
|
||||
// Created by: drose (20Sep05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "animInterface.h"
|
||||
#include "clockObject.h"
|
||||
|
||||
TypeHandle AnimInterface::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimInterface::Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
AnimInterface::
|
||||
AnimInterface() :
|
||||
_frame_rate(0.0),
|
||||
_num_frames(0),
|
||||
_play_mode(PM_pose),
|
||||
_start_time(0.0),
|
||||
_start_frame(0.0),
|
||||
_play_frames(0.0),
|
||||
_from_frame(0),
|
||||
_to_frame(0),
|
||||
_play_rate(1.0),
|
||||
_effective_frame_rate(0.0),
|
||||
_paused(true),
|
||||
_paused_f(0.0)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimInterface::Copy Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
AnimInterface::
|
||||
AnimInterface(const AnimInterface ©) :
|
||||
_frame_rate(copy._frame_rate),
|
||||
_num_frames(copy._num_frames),
|
||||
_play_mode(copy._play_mode),
|
||||
_start_time(copy._start_time),
|
||||
_start_frame(copy._start_frame),
|
||||
_play_frames(copy._play_frames),
|
||||
_from_frame(copy._from_frame),
|
||||
_to_frame(copy._to_frame),
|
||||
_play_rate(copy._play_rate),
|
||||
_effective_frame_rate(copy._effective_frame_rate),
|
||||
_paused(copy._paused),
|
||||
_paused_f(copy._paused_f)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimInterface::Destructor
|
||||
// Access: Published, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
AnimInterface::
|
||||
~AnimInterface() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimInterface::play
|
||||
// Access: Published
|
||||
// Description: Runs the animation from the frame "from" to and
|
||||
// including the frame "to", at which point the
|
||||
// animation is stopped. Both "from" and "to" frame
|
||||
// numbers may be outside the range (0,
|
||||
// get_num_frames()) and the animation will follow the
|
||||
// range correctly, reporting numbers modulo
|
||||
// get_num_frames(). For instance, play(0,
|
||||
// get_num_frames() * 2) will play the animation twice
|
||||
// and then stop.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AnimInterface::
|
||||
play(double from, double to) {
|
||||
if (from >= to) {
|
||||
pose(from);
|
||||
return;
|
||||
}
|
||||
|
||||
_play_mode = PM_play;
|
||||
_start_time = ClockObject::get_global_clock()->get_frame_time();
|
||||
_start_frame = from;
|
||||
_play_frames = to - from + 1.0;
|
||||
_from_frame = (int)floor(from);
|
||||
_to_frame = (int)floor(to);
|
||||
_paused_f = 0.0;
|
||||
|
||||
if (_effective_frame_rate < 0.0) {
|
||||
// If we'll be playing backward, start at the end.
|
||||
_start_time -= _play_frames / _effective_frame_rate;
|
||||
}
|
||||
|
||||
animation_activated();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimInterface::loop
|
||||
// Access: Published
|
||||
// Description: Loops the animation from the frame "from" to and
|
||||
// including the frame "to", indefinitely. If restart
|
||||
// is true, the animation is restarted from the
|
||||
// beginning; otherwise, it continues from the current
|
||||
// frame.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AnimInterface::
|
||||
loop(bool restart, double from, double to) {
|
||||
if (from >= to) {
|
||||
pose(from);
|
||||
return;
|
||||
}
|
||||
|
||||
double fframe = get_full_fframe();
|
||||
|
||||
_play_mode = PM_loop;
|
||||
_start_time = ClockObject::get_global_clock()->get_frame_time();
|
||||
_start_frame = from;
|
||||
_play_frames = to - from + 1.0;
|
||||
_from_frame = (int)floor(from);
|
||||
_to_frame = (int)floor(to);
|
||||
_paused_f = 0.0;
|
||||
|
||||
if (!restart) {
|
||||
if (_paused) {
|
||||
_paused_f = fframe - _start_frame;
|
||||
} else {
|
||||
_start_time -= fframe / _effective_frame_rate;
|
||||
}
|
||||
}
|
||||
|
||||
animation_activated();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimInterface::pingpong
|
||||
// Access: Published
|
||||
// Description: Loops the animation from the frame "from" to and
|
||||
// including the frame "to", and then back in the
|
||||
// opposite direction, indefinitely.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AnimInterface::
|
||||
pingpong(bool restart, double from, double to) {
|
||||
if (from >= to) {
|
||||
pose(from);
|
||||
return;
|
||||
}
|
||||
|
||||
double fframe = get_full_fframe();
|
||||
|
||||
_play_mode = PM_pingpong;
|
||||
_start_time = ClockObject::get_global_clock()->get_frame_time();
|
||||
_start_frame = from;
|
||||
_play_frames = to - from + 1.0;
|
||||
_from_frame = (int)floor(from);
|
||||
_to_frame = (int)floor(to);
|
||||
_paused_f = 0.0;
|
||||
|
||||
if (!restart) {
|
||||
if (_paused) {
|
||||
_paused_f = fframe - _start_frame;
|
||||
} else {
|
||||
_start_time -= fframe / _effective_frame_rate;
|
||||
}
|
||||
}
|
||||
|
||||
animation_activated();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimInterface::pose
|
||||
// Access: Published
|
||||
// Description: Sets the animation to the indicated frame and holds
|
||||
// it there.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AnimInterface::
|
||||
pose(int frame) {
|
||||
_play_mode = PM_pose;
|
||||
_start_time = ClockObject::get_global_clock()->get_frame_time();
|
||||
_start_frame = (double)frame;
|
||||
_play_frames = 0.0;
|
||||
_from_frame = frame;
|
||||
_to_frame = frame;
|
||||
_paused_f = 0.0;
|
||||
|
||||
animation_activated();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimInterface::get_full_frame
|
||||
// Access: Published
|
||||
// Description: Returns the current integer frame number.
|
||||
//
|
||||
// Unlike the value returned by get_frame(), this frame
|
||||
// number may extend beyond the range of
|
||||
// get_num_frames() if the frame range passed to play(),
|
||||
// loop(), etc. did.
|
||||
//
|
||||
// Unlike the value returned by get_full_fframe(), this
|
||||
// return value will never exceed the value passed to
|
||||
// to_frame in the play() method.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int AnimInterface::
|
||||
get_full_frame() const {
|
||||
int frame = (int)floor(get_full_fframe());
|
||||
if (_play_mode == PM_play) {
|
||||
// In play mode, we never let the return value exceed
|
||||
// (_from_frame, _to_frame).
|
||||
frame = min(max(frame, _from_frame), _to_frame);
|
||||
}
|
||||
return frame;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimInterface::get_full_fframe
|
||||
// Access: Published
|
||||
// Description: Returns the current floating-point frame number.
|
||||
//
|
||||
// Unlike the value returned by get_frame(), this frame
|
||||
// number may extend beyond the range of
|
||||
// get_num_frames() if the frame range passed to play(),
|
||||
// loop(), etc. did.
|
||||
//
|
||||
// Unlike the value returned by get_full_frame(), this
|
||||
// return value may equal (to_frame + 1.0), when the
|
||||
// animation has played to its natural end. However, in
|
||||
// this case the return value of get_full_frame() will
|
||||
// be to_frame, not (to_frame + 1).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
double AnimInterface::
|
||||
get_full_fframe() const {
|
||||
switch (_play_mode) {
|
||||
case PM_pose:
|
||||
return _start_frame;
|
||||
|
||||
case PM_play:
|
||||
return min(max(get_f(), 0.0), _play_frames) + _start_frame;
|
||||
|
||||
case PM_loop:
|
||||
return cmod(get_f(), _play_frames) + _start_frame;
|
||||
|
||||
case PM_pingpong:
|
||||
{
|
||||
double f = cmod(get_f(), _play_frames * 2.0);
|
||||
if (f > _play_frames) {
|
||||
return (_play_frames * 2.0 - f) + _start_frame;
|
||||
} else {
|
||||
return f + _start_frame;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return _start_frame;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimInterface::is_playing
|
||||
// Access: Published
|
||||
// Description: Returns true if the animation is currently playing,
|
||||
// false if it is stopped (e.g. because stop() or pose()
|
||||
// was called, or because it reached the end of the
|
||||
// animation after play() was called).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool AnimInterface::
|
||||
is_playing() const {
|
||||
switch (_play_mode) {
|
||||
case PM_pose:
|
||||
return false;
|
||||
|
||||
case PM_play:
|
||||
return get_f() < _play_frames;
|
||||
|
||||
case PM_loop:
|
||||
case PM_pingpong:
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimInterface::output
|
||||
// Access: Published, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AnimInterface::
|
||||
output(ostream &out) const {
|
||||
switch (_play_mode) {
|
||||
case PM_pose:
|
||||
out << "pose, frame " << get_frame();
|
||||
return;
|
||||
|
||||
case PM_play:
|
||||
out << "play, frame " << get_frame();
|
||||
return;
|
||||
|
||||
case PM_loop:
|
||||
out << "loop, frame " << get_frame();
|
||||
return;
|
||||
|
||||
case PM_pingpong:
|
||||
out << "pingpong, frame " << get_frame();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimInterface::animation_activated
|
||||
// Access: Protected, Virtual
|
||||
// Description: This is provided as a callback method for when the
|
||||
// user calls one of the play/loop/pose type methods to
|
||||
// start the animation playing.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AnimInterface::
|
||||
animation_activated() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimInterface::get_f
|
||||
// Access: Private
|
||||
// Description: Returns the current floating-point frame number,
|
||||
// elapsed since _start_frame.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
double AnimInterface::
|
||||
get_f() const {
|
||||
if (_paused) {
|
||||
return _paused_f;
|
||||
|
||||
} else {
|
||||
double now = ClockObject::get_global_clock()->get_frame_time();
|
||||
double elapsed = now - _start_time;
|
||||
return (elapsed * _effective_frame_rate);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimInterface::internal_set_rate
|
||||
// Access: Private
|
||||
// Description: Called internally to adjust either or both of the
|
||||
// frame_rate or play_rate without changing the current
|
||||
// frame number if the animation is already playing.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AnimInterface::
|
||||
internal_set_rate(double frame_rate, double play_rate) {
|
||||
double f = get_f();
|
||||
|
||||
_frame_rate = frame_rate;
|
||||
_play_rate = play_rate;
|
||||
_effective_frame_rate = frame_rate * play_rate;
|
||||
|
||||
if (_effective_frame_rate == 0.0) {
|
||||
_paused_f = f;
|
||||
_paused = true;
|
||||
|
||||
} else {
|
||||
// Compute a new _start_time that will keep f the same value with
|
||||
// the new play_rate.
|
||||
double new_elapsed = f / _effective_frame_rate;
|
||||
double now = ClockObject::get_global_clock()->get_frame_time();
|
||||
_start_time = now - new_elapsed;
|
||||
_paused = false;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,111 @@
|
|||
// Filename: animInterface.h
|
||||
// Created by: drose (20Sep05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef ANIMINTERFACE_H
|
||||
#define ANIMINTERFACE_H
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "typeHandle.h"
|
||||
#include "register_type.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : AnimInterface
|
||||
// Description : This is the fundamental interface for things that
|
||||
// have a play/loop/stop type interface for frame-based
|
||||
// animation, such as animated characters. This is the
|
||||
// base class for AnimControl and other, similar
|
||||
// classes.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA AnimInterface {
|
||||
protected:
|
||||
AnimInterface();
|
||||
AnimInterface(const AnimInterface ©);
|
||||
|
||||
PUBLISHED:
|
||||
virtual ~AnimInterface();
|
||||
INLINE void play();
|
||||
void play(double from, double to);
|
||||
INLINE void loop(bool restart);
|
||||
void loop(bool restart, double from, double to);
|
||||
INLINE void pingpong(bool restart);
|
||||
void pingpong(bool restart, double from, double to);
|
||||
INLINE void stop();
|
||||
void pose(int frame);
|
||||
|
||||
INLINE void set_play_rate(double play_rate);
|
||||
INLINE double get_play_rate() const;
|
||||
INLINE double get_frame_rate() const;
|
||||
INLINE int get_num_frames() const;
|
||||
|
||||
INLINE int get_frame() const;
|
||||
INLINE double get_frac() const;
|
||||
int get_full_frame() const;
|
||||
double get_full_fframe() const;
|
||||
bool is_playing() const;
|
||||
|
||||
virtual void output(ostream &out) const;
|
||||
|
||||
protected:
|
||||
INLINE void set_frame_rate(double frame_rate);
|
||||
INLINE void set_num_frames(int num_frames);
|
||||
virtual void animation_activated();
|
||||
|
||||
private:
|
||||
double get_f() const;
|
||||
void internal_set_rate(double frame_rate, double play_rate);
|
||||
|
||||
private:
|
||||
enum PlayMode {
|
||||
PM_pose,
|
||||
PM_play,
|
||||
PM_loop,
|
||||
PM_pingpong,
|
||||
};
|
||||
|
||||
double _frame_rate;
|
||||
int _num_frames;
|
||||
|
||||
PlayMode _play_mode;
|
||||
double _start_time;
|
||||
double _start_frame;
|
||||
double _play_frames;
|
||||
int _from_frame;
|
||||
int _to_frame;
|
||||
|
||||
double _play_rate;
|
||||
double _effective_frame_rate;
|
||||
bool _paused;
|
||||
double _paused_f;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
register_type(_type_handle, "AnimInterface");
|
||||
}
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
};
|
||||
|
||||
INLINE ostream &operator << (ostream &out, const AnimInterface &ai);
|
||||
|
||||
#include "animInterface.I"
|
||||
|
||||
#endif
|
||||
|
|
@ -17,6 +17,7 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "config_util.h"
|
||||
#include "animInterface.h"
|
||||
#include "bamReaderParam.h"
|
||||
#include "cachedTypedWritableReferenceCount.h"
|
||||
#include "clockObject.h"
|
||||
|
|
@ -67,6 +68,7 @@ ConfigVariableSearchPath sound_path
|
|||
PRC_DESC("The directories to search for sound and music files to be loaded."));
|
||||
|
||||
ConfigureFn(config_util) {
|
||||
AnimInterface::init_type();
|
||||
BamReaderParam::init_type();
|
||||
CachedTypedWritableReferenceCount::init_type();
|
||||
Configurable::init_type();
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue