a few more pview features

This commit is contained in:
David Rose 2002-06-06 18:16:39 +00:00
parent 84cc0a8010
commit ca07e15ec9
11 changed files with 403 additions and 26 deletions

View File

@ -126,6 +126,28 @@ get_lighting() const {
return _lighting_enabled;
}
////////////////////////////////////////////////////////////////////
// Function: PandaFramework::has_highlight
// Access: Public
// Description: Returns true if any node is highlighted, false
// otherwise.
////////////////////////////////////////////////////////////////////
INLINE bool PandaFramework::
has_highlight() const {
return !_highlight.is_empty();
}
////////////////////////////////////////////////////////////////////
// Function: PandaFramework::get_highlight
// Access: Public
// Description: Returns the currently highlighted node, if any, or an
// empty NodePath if no node is highlighted.
////////////////////////////////////////////////////////////////////
INLINE const NodePath &PandaFramework::
get_highlight() const {
return _highlight;
}
////////////////////////////////////////////////////////////////////
// Function: PandaFramework::set_exit_flag
// Access: Public

View File

@ -245,6 +245,22 @@ close_all_windows() {
_windows.clear();
}
////////////////////////////////////////////////////////////////////
// Function: PandaFramework::get_models
// Access: Public
// Description: Returns the root of the scene graph normally reserved
// for parenting models and such. This scene graph may
// be instanced to each window's render tree as the
// window is created.
////////////////////////////////////////////////////////////////////
const NodePath &PandaFramework::
get_models() {
if (_models.is_empty()) {
_models = NodePath("models");
}
return _models;
}
////////////////////////////////////////////////////////////////////
// Function: PandaFramework::report_frame_rate
// Access: Public
@ -340,6 +356,36 @@ set_lighting(bool enable) {
_lighting_enabled = enable;
}
////////////////////////////////////////////////////////////////////
// Function: PandaFramework::set_highlight
// Access: Public
// Description: Sets the indicated node (normally a node within the
// get_models() tree) up as the highlighted node.
// Certain operations affect the highlighted node only.
////////////////////////////////////////////////////////////////////
void PandaFramework::
set_highlight(const NodePath &node) {
clear_highlight();
_highlight = node;
if (!_highlight.is_empty()) {
framework_cat.info(false) << _highlight << "\n";
_highlight.show_bounds();
}
}
////////////////////////////////////////////////////////////////////
// Function: PandaFramework::clear_highlight
// Access: Public
// Description: Unhighlights the currently highlighted node, if any.
////////////////////////////////////////////////////////////////////
void PandaFramework::
clear_highlight() {
if (!_highlight.is_empty()) {
_highlight.hide_bounds();
_highlight = NodePath();
}
}
////////////////////////////////////////////////////////////////////
// Function: PandaFramework::enable_default_keys
// Access: Public
@ -441,6 +487,12 @@ do_enable_default_keys() {
_event_handler.add_hook("t", event_t, this);
_event_handler.add_hook("b", event_b, this);
_event_handler.add_hook("l", event_l, this);
_event_handler.add_hook("c", event_c, this);
_event_handler.add_hook("h", event_h, this);
_event_handler.add_hook("arrow_up", event_arrow_up, this);
_event_handler.add_hook("arrow_down", event_arrow_down, this);
_event_handler.add_hook("arrow_left", event_arrow_left, this);
_event_handler.add_hook("arrow_right", event_arrow_right, this);
_event_handler.add_hook("shift-s", event_S, this);
}
@ -514,6 +566,133 @@ event_l(CPT_Event, void *data) {
self->set_lighting(!self->get_lighting());
}
////////////////////////////////////////////////////////////////////
// Function: PandaFramework::event_c
// Access: Protected, Static
// Description: Default handler for c key: center the trackball over
// the scene, or over the highlighted part of the scene.
////////////////////////////////////////////////////////////////////
void PandaFramework::
event_c(CPT_Event, void *data) {
PandaFramework *self = (PandaFramework *)data;
NodePath center_around = self->get_highlight();
if (center_around.is_empty()) {
center_around = self->get_models();
}
Windows::iterator wi;
for (wi = self->_windows.begin(); wi != self->_windows.end(); ++wi) {
WindowFramework *wf = (*wi);
wf->center_trackball(center_around);
}
}
////////////////////////////////////////////////////////////////////
// Function: PandaFramework::event_h
// Access: Protected, Static
// Description: Default handler for h key: toggle highlight mode. In
// this mode, you can walk the scene graph with the
// arrow keys to highlight different nodes.
////////////////////////////////////////////////////////////////////
void PandaFramework::
event_h(CPT_Event, void *data) {
PandaFramework *self = (PandaFramework *)data;
if (self->has_highlight()) {
self->clear_highlight();
} else {
self->set_highlight(self->get_models());
}
}
////////////////////////////////////////////////////////////////////
// Function: PandaFramework::event_arrow_up
// Access: Protected, Static
// Description: Default handler for up arrow key: in highlight mode,
// move the highlight to the node's parent.
////////////////////////////////////////////////////////////////////
void PandaFramework::
event_arrow_up(CPT_Event, void *data) {
PandaFramework *self = (PandaFramework *)data;
if (self->has_highlight()) {
NodePath node = self->get_highlight();
if (node.has_parent() && node != self->get_models()) {
self->set_highlight(node.get_parent());
}
}
}
////////////////////////////////////////////////////////////////////
// Function: PandaFramework::event_arrow_down
// Access: Protected, Static
// Description: Default handler for up arrow key: in highlight mode,
// move the highlight to the node's first child.
////////////////////////////////////////////////////////////////////
void PandaFramework::
event_arrow_down(CPT_Event, void *data) {
PandaFramework *self = (PandaFramework *)data;
if (self->has_highlight()) {
NodePath node = self->get_highlight();
if (node.get_num_children() > 0) {
self->set_highlight(node.get_child(0));
}
}
}
////////////////////////////////////////////////////////////////////
// Function: PandaFramework::event_arrow_left
// Access: Protected, Static
// Description: Default handler for up arrow key: in highlight mode,
// move the highlight to the node's nearest sibling on
// the left.
////////////////////////////////////////////////////////////////////
void PandaFramework::
event_arrow_left(CPT_Event, void *data) {
PandaFramework *self = (PandaFramework *)data;
if (self->has_highlight()) {
NodePath node = self->get_highlight();
NodePath parent = node.get_parent();
if (node.has_parent() && node != self->get_models()) {
int index = parent.node()->find_child(node.node());
nassertv(index >= 0);
int sibling = index - 1;
if (sibling >= 0) {
self->set_highlight(NodePath(parent, parent.node()->get_child(sibling)));
}
}
}
}
////////////////////////////////////////////////////////////////////
// Function: PandaFramework::event_arrow_right
// Access: Protected, Static
// Description: Default handler for up arrow key: in highlight mode,
// move the highlight to the node's nearest sibling on
// the right.
////////////////////////////////////////////////////////////////////
void PandaFramework::
event_arrow_right(CPT_Event, void *data) {
PandaFramework *self = (PandaFramework *)data;
if (self->has_highlight()) {
NodePath node = self->get_highlight();
NodePath parent = node.get_parent();
if (node.has_parent() && node != self->get_models()) {
int index = parent.node()->find_child(node.node());
nassertv(index >= 0);
int num_children = parent.node()->get_num_children();
int sibling = index + 1;
if (sibling < num_children) {
self->set_highlight(NodePath(parent, parent.node()->get_child(sibling)));
}
}
}
}
////////////////////////////////////////////////////////////////////
// Function: PandaFramework::event_S
// Access: Protected, Static

View File

@ -63,6 +63,8 @@ public:
void close_window(int n);
void close_all_windows();
const NodePath &get_models();
void report_frame_rate(ostream &out) const;
void reset_frame_rate();
@ -76,6 +78,11 @@ public:
INLINE bool get_two_sided() const;
INLINE bool get_lighting() const;
void set_highlight(const NodePath &node);
void clear_highlight();
INLINE bool has_highlight() const;
INLINE const NodePath &get_highlight() const;
void enable_default_keys();
virtual bool do_frame();
@ -94,6 +101,12 @@ protected:
static void event_t(CPT_Event, void *data);
static void event_b(CPT_Event, void *data);
static void event_l(CPT_Event, void *data);
static void event_c(CPT_Event, void *data);
static void event_h(CPT_Event, void *data);
static void event_arrow_up(CPT_Event, void *data);
static void event_arrow_down(CPT_Event, void *data);
static void event_arrow_left(CPT_Event, void *data);
static void event_arrow_right(CPT_Event, void *data);
static void event_S(CPT_Event, void *data);
@ -112,6 +125,8 @@ private:
typedef pvector<WindowFramework *> Windows;
Windows _windows;
NodePath _models;
// For counting frame rate.
double _start_time;
int _frame_count;
@ -121,6 +136,8 @@ private:
bool _two_sided_enabled;
bool _lighting_enabled;
NodePath _highlight;
bool _default_keys_enabled;
bool _exit_flag;

View File

@ -20,7 +20,6 @@
#include "pandaFramework.h"
#include "mouseAndKeyboard.h"
#include "buttonThrower.h"
#include "trackball.h"
#include "transform2sg.h"
#include "dSearchPath.h"
#include "filename.h"
@ -34,6 +33,9 @@
#include "ambientLight.h"
#include "directionalLight.h"
#include "lightAttrib.h"
#include "boundingSphere.h"
#include "deg_2_rad.h"
#include "config_framework.h"
// This number is chosen arbitrarily to override any settings in model
// files.
@ -212,17 +214,88 @@ setup_trackball() {
NodePath mouse = get_mouse();
NodePath camera = get_camera_group();
PT(Trackball) trackball = new Trackball("trackball");
trackball->set_pos(LVector3f::forward() * 50.0);
mouse.attach_new_node(trackball);
_trackball = new Trackball("trackball");
_trackball->set_pos(LVector3f::forward() * 50.0);
mouse.attach_new_node(_trackball);
PT(Transform2SG) tball2cam = new Transform2SG("tball2cam");
tball2cam->set_node(camera.node());
trackball->add_child(tball2cam);
_trackball->add_child(tball2cam);
_got_trackball = true;
}
////////////////////////////////////////////////////////////////////
// Function: WindowFramework::center_trackball
// Access: Public
// Description: Centers the trackball on the indicated object, and
// scales the trackball motion suitably.
////////////////////////////////////////////////////////////////////
void WindowFramework::
center_trackball(const NodePath &object) {
PT(BoundingVolume) volume = object.get_bounds();
// We expect at least a geometric bounding volume around the world.
nassertv(volume != (BoundingVolume *)NULL);
nassertv(volume->is_of_type(GeometricBoundingVolume::get_class_type()));
GeometricBoundingVolume *gbv = DCAST(GeometricBoundingVolume, volume);
// Determine the bounding sphere around the world. The topmost
// BoundingVolume might itself be a sphere (it's likely), but since
// it might not, we'll take no chances and make our own sphere.
PT(BoundingSphere) sphere = new BoundingSphere;
if (!sphere->extend_by(gbv)) {
framework_cat.warning()
<< "Cannot determine bounding volume of " << object << "\n";
return;
}
if (sphere->is_infinite()) {
framework_cat.warning()
<< "Infinite bounding volume for " << object << "\n";
return;
}
if (sphere->is_empty()) {
framework_cat.warning()
<< "Empty bounding volume for " << object << "\n";
return;
}
LPoint3f center = sphere->get_center();
float radius = sphere->get_radius();
float distance = 50.0f;
// Choose a suitable distance to view the whole volume in our frame.
// This is based on the camera lens in use. Determine the lens
// based on the first camera; this will be the default camera.
Lens *lens = (Lens *)NULL;
if (!_cameras.empty()) {
Cameras::const_iterator ci;
for (ci = _cameras.begin();
ci != _cameras.end() && lens == (Lens *)NULL;
++ci) {
lens = (*ci)->get_lens();
}
}
if (lens != (Lens *)NULL) {
LVecBase2f fov = lens->get_fov();
distance = radius / ctan(deg_2_rad(min(fov[0], fov[1]) / 2.0f));
// Ensure the far plane is far enough back to see the entire object.
float ideal_far_plane = distance + radius;
lens->set_far(max(lens->get_default_far(), ideal_far_plane));
}
_trackball->set_origin(center);
_trackball->set_pos(LVector3f::forward() * distance);
// Also set the movement scale on the trackball to be consistent
// with the size of the model and the lens field-of-view.
_trackball->set_forward_scale(distance * 0.006);
}
////////////////////////////////////////////////////////////////////
// Function: WindowFramework::load_models
// Access: Public

View File

@ -24,6 +24,7 @@
#include "camera.h"
#include "graphicsWindow.h"
#include "animControlCollection.h"
#include "trackball.h"
#include "filename.h"
#include "pointerTo.h"
#include "pvector.h"
@ -60,6 +61,7 @@ public:
void enable_keyboard();
void setup_trackball();
void center_trackball(const NodePath &object);
bool load_models(const NodePath &parent,
int argc, char *argv[], int first_arg = 1);
@ -96,6 +98,7 @@ private:
AnimControlCollection _anim_controls;
NodePath _mouse;
PT(Trackball) _trackball;
AmbientLight *_alight;
DirectionalLight *_dlight;

View File

@ -118,6 +118,10 @@ const int select_LOD_number = config_gobj.GetInt("select-LOD-number", -1);
// will screen out successively higher levels
const int minimum_LOD_number = config_gobj.GetInt("minimum-LOD-number", 0);
// The default near and far plane distances.
const float default_near = config_gobj.GetFloat("default-near", 1.0f);
const float default_far = config_gobj.GetFloat("default-far", 1000.0f);
static BamTextureMode
parse_texture_mode(const string &mode) {
if (mode == "fullpath") {

View File

@ -101,8 +101,8 @@ clear() {
_focal_length = 1.0f;
_fov.set(_default_fov, _default_fov);
_aspect_ratio = 1.0f;
_near_distance = 1.0f;
_far_distance = 1000.0f;
_near_distance = default_near;
_far_distance = default_far;
_view_hpr.set(0.0f, 0.0f, 0.0f);
_view_vector.set(0.0f, 1.0f, 0.0f);
_up_vector.set(0.0f, 0.0f, 1.0f);
@ -387,6 +387,30 @@ get_aspect_ratio() const {
return _aspect_ratio;
}
////////////////////////////////////////////////////////////////////
// Function: Lens::get_default_near
// Access: Published, Static
// Description: Returns the default near plane distance that will be
// assigned to each newly-created lens. This is read
// from the Configrc file.
////////////////////////////////////////////////////////////////////
float Lens::
get_default_near() {
return default_near;
}
////////////////////////////////////////////////////////////////////
// Function: Lens::get_default_far
// Access: Published, Static
// Description: Returns the default far plane distance that will be
// assigned to each newly-created lens. This is read
// from the Configrc file.
////////////////////////////////////////////////////////////////////
float Lens::
get_default_far() {
return default_far;
}
////////////////////////////////////////////////////////////////////
// Function: Lens::set_view_hpr
// Access: Published

View File

@ -91,6 +91,9 @@ PUBLISHED:
INLINE void set_far(float far_distance);
INLINE float get_far() const;
INLINE void set_near_far(float near_distance, float far_distance);
static float get_default_near();
static float get_default_far();
INLINE void set_view_hpr(float h, float p, float r);
void set_view_hpr(const LVecBase3f &view_hpr);

View File

@ -30,11 +30,12 @@ main(int argc, char *argv[]) {
window->enable_keyboard();
window->setup_trackball();
framework.get_models().instance_to(window->get_render());
if (argc < 2) {
// If we have no arguments, get that trusty old triangle out.
window->load_default_model(window->get_render());
window->load_default_model(framework.get_models());
} else {
window->load_models(window->get_render(), argc, argv);
window->load_models(framework.get_models(), argc, argv);
}
window->loop_animations();

View File

@ -66,7 +66,7 @@ Trackball(const string &name) :
////////////////////////////////////////////////////////////////////
// Function: Trackball::Destructor
// Access: Public, Scheme
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
Trackball::
@ -75,7 +75,7 @@ Trackball::
////////////////////////////////////////////////////////////////////
// Function: Trackball::reset
// Access: Public, Scheme
// Access: Published
// Description: Reinitializes all transforms to identity.
////////////////////////////////////////////////////////////////////
void Trackball::
@ -86,10 +86,34 @@ reset() {
_mat = LMatrix4f::ident_mat();
}
////////////////////////////////////////////////////////////////////
// Function: Trackball::get_forward_scale
// Access: Published
// Description: Returns the scale factor applied to forward and
// backward motion. See set_forward_scale().
////////////////////////////////////////////////////////////////////
float Trackball::
get_forward_scale() const {
return _fwdscale;
}
////////////////////////////////////////////////////////////////////
// Function: Trackball::set_forward_scale
// Access: Published
// Description: Changes the scale factor applied to forward and
// backward motion. The larger this number, the faster
// the model will move in response to dollying in and
// out.
////////////////////////////////////////////////////////////////////
void Trackball::
set_forward_scale(float fwdscale) {
_fwdscale = fwdscale;
}
////////////////////////////////////////////////////////////////////
// Function: Trackball::get_pos
// Access: Public, Scheme
// Access: Published
// Description: Return the offset from the center of rotation.
////////////////////////////////////////////////////////////////////
const LPoint3f &Trackball::
@ -115,7 +139,7 @@ get_z() const {
////////////////////////////////////////////////////////////////////
// Function: Trackball::set_pos
// Access: Public, Scheme
// Access: Published
// Description: Directly set the offset from the rotational origin.
////////////////////////////////////////////////////////////////////
void Trackball::
@ -151,7 +175,7 @@ set_z(float z) {
////////////////////////////////////////////////////////////////////
// Function: Trackball::get_hpr
// Access: Public, Scheme
// Access: Published
// Description: Return the trackball's orientation.
////////////////////////////////////////////////////////////////////
LVecBase3f Trackball::
@ -185,7 +209,7 @@ get_r() const {
////////////////////////////////////////////////////////////////////
// Function: Trackball::set_hpr
// Access: Public, Scheme
// Access: Published
// Description: Directly set the mover's orientation.
////////////////////////////////////////////////////////////////////
void Trackball::
@ -235,7 +259,7 @@ set_r(float r) {
////////////////////////////////////////////////////////////////////
// Function: Trackball::reset_origin_here
// Access: Public, Scheme
// Access: Published
// Description: Reposition the center of rotation to coincide with
// the current translation offset. Future rotations
// will be about the current origin.
@ -250,7 +274,7 @@ reset_origin_here() {
////////////////////////////////////////////////////////////////////
// Function: Trackball::move_origin
// Access: Public, Scheme
// Access: Published
// Description: Moves the center of rotation by the given amount.
////////////////////////////////////////////////////////////////////
void Trackball::
@ -258,10 +282,31 @@ move_origin(float x, float y, float z) {
_rotation = LMatrix4f::translate_mat(LVecBase3f(x, y, z)) * _rotation;
}
////////////////////////////////////////////////////////////////////
// Function: Trackball::get_origin
// Access: Published
// Description: Returns the current center of rotation.
////////////////////////////////////////////////////////////////////
LPoint3f Trackball::
get_origin() const {
return _rotation.get_row3(3);
}
////////////////////////////////////////////////////////////////////
// Function: Trackball::set_origin
// Access: Published
// Description: Directly sets the center of rotation.
////////////////////////////////////////////////////////////////////
void Trackball::
set_origin(const LVecBase3f &origin) {
_rotation.set_row(3, LVecBase3f(0.0f, 0.0f, 0.0f));
_rotation = LMatrix4f::translate_mat(-origin) * _rotation;
}
////////////////////////////////////////////////////////////////////
// Function: Trackball::set_invert
// Access: Public, Scheme
// Access: Published
// Description: Sets the invert flag. When this is set, the inverse
// matrix is generated, suitable for joining to a
// camera, instead of parenting the scene under it.
@ -273,7 +318,7 @@ set_invert(bool flag) {
////////////////////////////////////////////////////////////////////
// Function: Trackball::get_invert
// Access: Public, Scheme
// Access: Published
// Description: Returns the invert flag. When this is set, the
// inverse matrix is generated, suitable for joining to
// a camera, instead of parenting the scene under it.
@ -285,7 +330,7 @@ get_invert() const {
////////////////////////////////////////////////////////////////////
// Function: Trackball::set_rel_to
// Access: Public, Scheme
// Access: Published
// Description: Sets the NodePath that all trackball manipulations
// are to be assumed to be relative to. For instance,
// set your camera node here to make the trackball
@ -300,7 +345,7 @@ set_rel_to(const NodePath &rel_to) {
////////////////////////////////////////////////////////////////////
// Function: Trackball::get_rel_to
// Access: Public, Scheme
// Access: Published
// Description: Returns the NodePath that all trackball manipulations
// are relative to, or the empty path.
////////////////////////////////////////////////////////////////////
@ -312,7 +357,7 @@ get_rel_to() const {
////////////////////////////////////////////////////////////////////
// Function: Trackball::set_coordinate_system
// Access: Public, Scheme
// Access: Published
// Description: Sets the coordinate system of the Trackball.
// Normally, this is the default coordinate system.
// This changes the axes the Trackball manipulates so
@ -326,7 +371,7 @@ set_coordinate_system(CoordinateSystem cs) {
////////////////////////////////////////////////////////////////////
// Function: Trackball::get_coordinate_system
// Access: Public, Scheme
// Access: Published
// Description: Returns the coordinate system of the Trackball.
// See set_coordinate_system().
////////////////////////////////////////////////////////////////////
@ -337,7 +382,7 @@ get_coordinate_system() const {
////////////////////////////////////////////////////////////////////
// Function: Trackball::set_mat
// Access: Public, Scheme
// Access: Published
// Description: Stores the indicated transform in the trackball.
// This is a transform in global space, regardless of
// the rel_to node.
@ -357,7 +402,7 @@ set_mat(const LMatrix4f &mat) {
////////////////////////////////////////////////////////////////////
// Function: Trackball::get_mat
// Access: Public, Scheme
// Access: Published
// Description: Returns the matrix represented by the trackball
// rotation.
////////////////////////////////////////////////////////////////////
@ -368,7 +413,7 @@ get_mat() const {
////////////////////////////////////////////////////////////////////
// Function: Trackball::get_trans_mat
// Access: Public, Scheme
// Access: Published
// Description: Returns the actual transform that will be applied to
// the scene graph. This is the same as get_mat(),
// unless invert is in effect.

View File

@ -48,6 +48,9 @@ PUBLISHED:
void reset();
float get_forward_scale() const;
void set_forward_scale(float fwdscale);
/// **** Translation ****
const LPoint3f &get_pos() const;
@ -77,6 +80,9 @@ PUBLISHED:
void reset_origin_here();
void move_origin(float x, float y, float z);
LPoint3f get_origin() const;
void set_origin(const LVecBase3f &origin);
/// **** Misc ****
void set_invert(bool flag);