add oobeCull mode

This commit is contained in:
David Rose 2001-06-08 22:13:08 +00:00
parent 4cb4ba7598
commit 6be3c950da
13 changed files with 142 additions and 39 deletions

View File

@ -450,6 +450,7 @@ class ShowBase:
self.oobeButtonEventsType = TypeRegistry.ptr().findType('ButtonEvents_ButtonEventDataTransition') self.oobeButtonEventsType = TypeRegistry.ptr().findType('ButtonEvents_ButtonEventDataTransition')
self.oobeVis = loader.loadModelOnce('models/misc/camera') self.oobeVis = loader.loadModelOnce('models/misc/camera')
self.oobeCullFrustum = None
# Make sure the MouseValve is monitoring the Control key. # Make sure the MouseValve is monitoring the Control key.
mods = ModifierButtons(self.mouseValve.node().getModifierButtons()) mods = ModifierButtons(self.mouseValve.node().getModifierButtons())
@ -458,13 +459,18 @@ class ShowBase:
if self.oobeMode: if self.oobeMode:
# Disable OOBE mode. # Disable OOBE mode.
if self.oobeCullFrustum != None:
# First, disable OOBE cull mode.
self.oobeCull()
self.oobeControl.setOff() self.oobeControl.setOff()
self.mouseControl.setOn() self.mouseControl.setOn()
if self.oobeVis: if self.oobeVis:
self.oobeVis.reparentTo(self.hidden) self.oobeVis.reparentTo(self.hidden)
self.cam.reparentTo(self.camera) self.cam.reparentTo(self.camera)
self.oobeCamera.reparentTo(self.hidden) self.oobeCamera.reparentTo(self.hidden)
self.oobeMode = 0 self.oobeMode = 0
else: else:
# Enable OOBE mode. # Enable OOBE mode.
mods = ModifierButtons(self.mouseValve.node().getModifierButtons()) mods = ModifierButtons(self.mouseValve.node().getModifierButtons())
@ -488,7 +494,7 @@ class ShowBase:
self.oobeCamera.clearMat() self.oobeCamera.clearMat()
# Set our initial OOB position to be just behind the camera. # Set our initial OOB position to be just behind the camera.
mat = Mat4.translateMat(0, -10, 3) * base.camera.getMat(cameraParent) mat = Mat4.translateMat(0, -10, 3) * self.camera.getMat(cameraParent)
mat.invertInPlace() mat.invertInPlace()
self.oobeTrackball.node().setMat(mat) self.oobeTrackball.node().setMat(mat)
@ -497,6 +503,45 @@ class ShowBase:
self.oobeVis.reparentTo(self.camera) self.oobeVis.reparentTo(self.camera)
self.oobeMode = 1 self.oobeMode = 1
def oobeCull(self):
"""
While in OOBE mode (see above), cull the viewing frustum as if
it were still attached to our original camera. This allows us
to visualize the effectiveness of our bounding volumes.
"""
# First, make sure OOBE mode is enabled.
try:
if not self.oobeMode:
self.oobe()
except:
self.oobe()
if self.oobeCullFrustum == None:
# Enable OOBE culling.
pnode = ProjectionNode('oobeCull')
pnode.setProjection(self.camNode.getProjection())
self.oobeCullFrustum = self.camera.attachNewNode(pnode)
# Assign each DisplayRegion shared by the camera to use
# this cull frustum.
numDrs = self.camNode.getNumDrs()
for d in range(0, numDrs):
dr = self.camNode.getDr(d)
dr.setCullFrustum(pnode)
else:
# Disable OOBE culling.
# Assign each DisplayRegion shared by the camera to use
# the default cull frustum, the camera itself.
numDrs = self.camNode.getNumDrs()
for d in range(0, numDrs):
dr = self.camNode.getDr(d)
dr.setCullFrustum(self.camNode)
self.oobeCullFrustum.removeNode()
self.oobeCullFrustum = None
def screenshot(self, namePrefix='screenshot'): def screenshot(self, namePrefix='screenshot'):
# Get the current date and time to uniquify the image (down to the second) # Get the current date and time to uniquify the image (down to the second)
date = time.ctime(time.time()) date = time.ctime(time.time())

View File

@ -41,6 +41,7 @@
#endif #endif
#include <wrt.h> #include <wrt.h>
#include <displayRegion.h>
#include <frustumCullTraverser.h> #include <frustumCullTraverser.h>
#include <pruneTransition.h> #include <pruneTransition.h>
#include <decalTransition.h> #include <decalTransition.h>
@ -270,8 +271,9 @@ traverse(Node *root,
// culling. // culling.
LMatrix4f rel_from_camera; LMatrix4f rel_from_camera;
NodeTransitionWrapper ntw(TransformTransition::get_class_type()); NodeTransitionWrapper ntw(TransformTransition::get_class_type());
wrt(_gsg->get_current_projection_node(), root, begin(), end(), const DisplayRegion *dr = _gsg->get_current_display_region();
ntw, get_graph_type()); ProjectionNode *camera = dr->get_cull_frustum();
wrt(camera, root, begin(), end(), ntw, get_graph_type());
const TransformTransition *tt; const TransformTransition *tt;
if (get_transition_into(tt, ntw)) { if (get_transition_into(tt, ntw)) {
rel_from_camera = tt->get_matrix(); rel_from_camera = tt->get_matrix();

View File

@ -49,11 +49,40 @@ get_layer() const {
// Description: Returns the camera associated with this // Description: Returns the camera associated with this
// DisplayRegion, or NULL if no camera is associated. // DisplayRegion, or NULL if no camera is associated.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE PT(Camera) DisplayRegion:: INLINE Camera *DisplayRegion::
get_camera() const { get_camera() const {
return _camera; return _camera;
} }
////////////////////////////////////////////////////////////////////
// Function: DisplayRegion::set_cull_frustum
// Access: Public
// Description: Sets the ProjectionNode that will be used to perform
// view-frustum culling for this particular
// DisplayRegion. Normally, this is the same as the
// camera (and is implicitly set when set_camera() is
// called). However, it may be useful to occasionally
// set it to a different node, particularly to enable a
// debugging mode where the culling effectiveness can be
// observed from a third-person perspective.
////////////////////////////////////////////////////////////////////
void DisplayRegion::
set_cull_frustum(ProjectionNode *cull_frustum) {
_cull_frustum = cull_frustum;
}
////////////////////////////////////////////////////////////////////
// Function: DisplayRegion::get_cull_frustum
// Access: Public
// Description: Returns the ProjectionNode that will be used to
// perform view-frustum culling for this particular
// DisplayRegion. See set_cull_frustum().
////////////////////////////////////////////////////////////////////
INLINE ProjectionNode *DisplayRegion::
get_cull_frustum() const {
return _cull_frustum;
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: DisplayRegion::set_active // Function: DisplayRegion::set_active
// Access: Public // Access: Public

View File

@ -174,7 +174,7 @@ get_pipe() const {
// between multiple DisplayRegions. // between multiple DisplayRegions.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void DisplayRegion:: void DisplayRegion::
set_camera(const PT(Camera) &camera) { set_camera(Camera *camera) {
if (camera != _camera) { if (camera != _camera) {
if (_camera != (Camera *)NULL) { if (_camera != (Camera *)NULL) {
// We need to tell the old camera we're not using him anymore. // We need to tell the old camera we're not using him anymore.
@ -186,6 +186,7 @@ set_camera(const PT(Camera) &camera) {
_camera->add_display_region(this); _camera->add_display_region(this);
} }
} }
set_cull_frustum(camera);
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////

View File

@ -58,8 +58,11 @@ PUBLISHED:
GraphicsWindow *get_window() const; GraphicsWindow *get_window() const;
GraphicsPipe *get_pipe() const; GraphicsPipe *get_pipe() const;
void set_camera(const PT(Camera) &camera); void set_camera(Camera *camera);
INLINE PT(Camera) get_camera() const; INLINE Camera *get_camera() const;
INLINE void set_cull_frustum(ProjectionNode *cull_frustum);
INLINE ProjectionNode *get_cull_frustum() const;
INLINE void set_active(bool active); INLINE void set_active(bool active);
INLINE bool is_active() const; INLINE bool is_active() const;
@ -87,6 +90,7 @@ protected:
GraphicsLayer *_layer; GraphicsLayer *_layer;
PT(Camera) _camera; PT(Camera) _camera;
PT(ProjectionNode) _cull_frustum;
bool _active; bool _active;

View File

@ -88,7 +88,7 @@ get_current_root_node(void) const {
// region will be made active (if it is not already) by // region will be made active (if it is not already) by
// a call to prepare_display_region(). // a call to prepare_display_region().
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE CPT(DisplayRegion) GraphicsStateGuardian:: INLINE const DisplayRegion *GraphicsStateGuardian::
get_current_display_region(void) const { get_current_display_region(void) const {
return _current_display_region; return _current_display_region;
} }
@ -107,7 +107,7 @@ get_current_display_region(void) const {
// optimization. // optimization.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE DisplayRegionStack GraphicsStateGuardian:: INLINE DisplayRegionStack GraphicsStateGuardian::
push_display_region(CPT(DisplayRegion) dr) { push_display_region(const DisplayRegion *dr) {
DisplayRegionStack old; DisplayRegionStack old;
old._display_region = _current_display_region; old._display_region = _current_display_region;
old._stack_level = _display_region_stack_level; old._stack_level = _display_region_stack_level;
@ -147,7 +147,7 @@ pop_display_region(DisplayRegionStack &node) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE FrameBufferStack GraphicsStateGuardian:: INLINE FrameBufferStack GraphicsStateGuardian::
push_frame_buffer(const RenderBuffer &buffer, push_frame_buffer(const RenderBuffer &buffer,
CPT(DisplayRegion) dr) { const DisplayRegion *dr) {
FrameBufferStack old; FrameBufferStack old;
old._frame_buffer = save_frame_buffer(buffer, dr); old._frame_buffer = save_frame_buffer(buffer, dr);
old._stack_level = _frame_buffer_stack_level; old._stack_level = _frame_buffer_stack_level;

View File

@ -123,12 +123,12 @@ public:
INLINE ProjectionNode *get_current_projection_node(void) const ; INLINE ProjectionNode *get_current_projection_node(void) const ;
INLINE const Node* get_current_root_node(void) const; INLINE const Node* get_current_root_node(void) const;
INLINE CPT(DisplayRegion) get_current_display_region(void) const; INLINE const DisplayRegion *get_current_display_region(void) const;
INLINE DisplayRegionStack push_display_region(CPT(DisplayRegion) dr); INLINE DisplayRegionStack push_display_region(const DisplayRegion *dr);
INLINE void pop_display_region(DisplayRegionStack &node); INLINE void pop_display_region(DisplayRegionStack &node);
INLINE FrameBufferStack push_frame_buffer(const RenderBuffer &buffer, INLINE FrameBufferStack push_frame_buffer(const RenderBuffer &buffer,
CPT(DisplayRegion) dr); const DisplayRegion *dr);
INLINE void pop_frame_buffer(FrameBufferStack &node); INLINE void pop_frame_buffer(FrameBufferStack &node);
INLINE void set_coordinate_system(CoordinateSystem cs); INLINE void set_coordinate_system(CoordinateSystem cs);

View File

@ -22,6 +22,7 @@
#include "renderRelation.h" #include "renderRelation.h"
#include <graphicsStateGuardian.h> #include <graphicsStateGuardian.h>
#include <displayRegion.h>
#include <renderTraverser.h> #include <renderTraverser.h>
#include <projectionNode.h> #include <projectionNode.h>
#include <look_at.h> #include <look_at.h>
@ -57,8 +58,12 @@ sub_render(NodeRelation *arc, const AllAttributesWrapper &,
Node *node = arc->get_child(); Node *node = arc->get_child();
GraphicsStateGuardian *gsg = trav->get_gsg(); GraphicsStateGuardian *gsg = trav->get_gsg();
// Get the current camera from the gsg // First, we have to get the current viewing frustum. This is
const ProjectionNode *camera = gsg->get_current_projection_node(); // normally the same thing as the current camera, but the
// DisplayRegion may have some override in effect, so we ask the
// DisplayRegion instead of the GSG.
const DisplayRegion *dr = gsg->get_current_display_region();
ProjectionNode *camera = dr->get_cull_frustum();
nassertr(camera != (ProjectionNode *)NULL, true); nassertr(camera != (ProjectionNode *)NULL, true);
// And the relative coordinate space. // And the relative coordinate space.

View File

@ -69,8 +69,8 @@ share_projection(Projection *projection) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: get_projection // Function: get_projection
// Access: Public // Access: Public
// Description: Returns a pointer to particular Projection associated // Description: Returns a pointer to the particular Projection
// with this ProjectionNode. // associated with this ProjectionNode.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
Projection *ProjectionNode:: Projection *ProjectionNode::
get_projection() { get_projection() {

View File

@ -23,6 +23,7 @@
#include <wrt.h> #include <wrt.h>
#include <geomNode.h> #include <geomNode.h>
#include <graphicsStateGuardian.h> #include <graphicsStateGuardian.h>
#include <displayRegion.h>
#include <geometricBoundingVolume.h> #include <geometricBoundingVolume.h>
#include <projectionNode.h> #include <projectionNode.h>
#include <projection.h> #include <projection.h>
@ -103,8 +104,9 @@ traverse(Node *root,
// culling. // culling.
LMatrix4f rel_from_camera; LMatrix4f rel_from_camera;
NodeTransitionWrapper ntw(TransformTransition::get_class_type()); NodeTransitionWrapper ntw(TransformTransition::get_class_type());
wrt(_gsg->get_current_projection_node(), root, begin(), end(), const DisplayRegion *dr = _gsg->get_current_display_region();
ntw, get_graph_type()); ProjectionNode *camera = dr->get_cull_frustum();
wrt(camera, root, begin(), end(), ntw, get_graph_type());
const TransformTransition *tt; const TransformTransition *tt;
if (get_transition_into(tt, ntw)) { if (get_transition_into(tt, ntw)) {
rel_from_camera = tt->get_matrix(); rel_from_camera = tt->get_matrix();

View File

@ -43,7 +43,12 @@ FrustumCullTraverser(ArcChain &arc_chain, Node *root,
// If we're to be performing view-frustum culling, determine the // If we're to be performing view-frustum culling, determine the
// bounding volume associated with the current viewing frustum. // bounding volume associated with the current viewing frustum.
ProjectionNode *camera = _gsg->get_current_projection_node(); // First, we have to get the current viewing frustum. This is
// normally the same thing as the current camera, but the
// DisplayRegion may have some override in effect, so we ask the
// DisplayRegion instead of the GSG.
const DisplayRegion *dr = _gsg->get_current_display_region();
ProjectionNode *camera = dr->get_cull_frustum();
if (camera != (const ProjectionNode *)NULL) { if (camera != (const ProjectionNode *)NULL) {
const Projection *proj = camera->get_projection(); const Projection *proj = camera->get_projection();
nassertv(proj != (const Projection *)NULL); nassertv(proj != (const Projection *)NULL);
@ -188,7 +193,9 @@ traverse(NodeRelation *arc, AttributeWrapper render_state,
DCAST(GeometricBoundingVolume, _view_frustum->make_copy()); DCAST(GeometricBoundingVolume, _view_frustum->make_copy());
NodeTransitionWrapper ntw(TransformTransition::get_class_type()); NodeTransitionWrapper ntw(TransformTransition::get_class_type());
wrt(_gsg->get_current_projection_node(), const DisplayRegion *dr = _gsg->get_current_display_region();
ProjectionNode *camera = dr->get_cull_frustum();
wrt(camera,
arc->get_child(), _arc_chain.begin(), _arc_chain.end(), arc->get_child(), _arc_chain.begin(), _arc_chain.end(),
ntw, _graph_type); ntw, _graph_type);

View File

@ -27,6 +27,7 @@
#include <typedObject.h> #include <typedObject.h>
#include <geometricBoundingVolume.h> #include <geometricBoundingVolume.h>
#include <graphicsStateGuardian.h> #include <graphicsStateGuardian.h>
#include <displayRegion.h>
#include <arcChain.h> #include <arcChain.h>
#include <nodeTransitionWrapper.h> #include <nodeTransitionWrapper.h>
#include <transformTransition.h> #include <transformTransition.h>

View File

@ -20,6 +20,7 @@
#include "config_switchnode.h" #include "config_switchnode.h"
#include <graphicsStateGuardian.h> #include <graphicsStateGuardian.h>
#include <displayRegion.h>
#include <get_rel_pos.h> #include <get_rel_pos.h>
#include <luse.h> #include <luse.h>
#include <renderRelation.h> #include <renderRelation.h>
@ -85,26 +86,32 @@ void LODNode::
compute_switch(RenderTraverser *trav) { compute_switch(RenderTraverser *trav) {
GraphicsStateGuardian *gsg = trav->get_gsg(); GraphicsStateGuardian *gsg = trav->get_gsg();
// Get the current camera position from the gsg // First, we have to get the current viewing frustum. This is
const ProjectionNode* camera = gsg->get_current_projection_node(); // normally the same thing as the current camera, but the
LPoint3f camera_pos(0, 0, 0); // DisplayRegion may have some override in effect, so we ask the
// DisplayRegion instead of the GSG.
const DisplayRegion *dr = gsg->get_current_display_region();
ProjectionNode *camera = dr->get_cull_frustum();
if (camera != (ProjectionNode *)NULL) {
LPoint3f camera_pos(0, 0, 0);
// Get the LOD center in camera space // Get the LOD center in camera space
LPoint3f LOD_pos; LPoint3f LOD_pos;
NodeTransitionWrapper ntw(TransformTransition::get_class_type()); NodeTransitionWrapper ntw(TransformTransition::get_class_type());
wrt(this, trav->begin(), trav->end(), wrt(this, trav->begin(), trav->end(),
camera, ntw, RenderRelation::get_class_type()); camera, ntw, RenderRelation::get_class_type());
const TransformTransition *tt; const TransformTransition *tt;
if (get_transition_into(tt, ntw)) { if (get_transition_into(tt, ntw)) {
LOD_pos = _lod._center * tt->get_matrix(); LOD_pos = _lod._center * tt->get_matrix();
} else { } else {
LOD_pos = _lod._center; LOD_pos = _lod._center;
}
// Determine which child to traverse
int index = _lod.compute_child(camera_pos, LOD_pos);
select_child(index);
} }
// Determine which child to traverse
int index = _lod.compute_child(camera_pos, LOD_pos);
select_child(index);
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////