mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 02:42:49 -04:00
add oobeCull mode
This commit is contained in:
parent
4cb4ba7598
commit
6be3c950da
@ -450,6 +450,7 @@ class ShowBase:
|
||||
self.oobeButtonEventsType = TypeRegistry.ptr().findType('ButtonEvents_ButtonEventDataTransition')
|
||||
|
||||
self.oobeVis = loader.loadModelOnce('models/misc/camera')
|
||||
self.oobeCullFrustum = None
|
||||
|
||||
# Make sure the MouseValve is monitoring the Control key.
|
||||
mods = ModifierButtons(self.mouseValve.node().getModifierButtons())
|
||||
@ -458,13 +459,18 @@ class ShowBase:
|
||||
|
||||
if self.oobeMode:
|
||||
# Disable OOBE mode.
|
||||
|
||||
if self.oobeCullFrustum != None:
|
||||
# First, disable OOBE cull mode.
|
||||
self.oobeCull()
|
||||
|
||||
self.oobeControl.setOff()
|
||||
self.mouseControl.setOn()
|
||||
if self.oobeVis:
|
||||
self.oobeVis.reparentTo(self.hidden)
|
||||
self.cam.reparentTo(self.camera)
|
||||
self.oobeCamera.reparentTo(self.hidden)
|
||||
self.oobeMode = 0
|
||||
self.oobeMode = 0
|
||||
else:
|
||||
# Enable OOBE mode.
|
||||
mods = ModifierButtons(self.mouseValve.node().getModifierButtons())
|
||||
@ -488,7 +494,7 @@ class ShowBase:
|
||||
self.oobeCamera.clearMat()
|
||||
|
||||
# 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()
|
||||
self.oobeTrackball.node().setMat(mat)
|
||||
|
||||
@ -497,6 +503,45 @@ class ShowBase:
|
||||
self.oobeVis.reparentTo(self.camera)
|
||||
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'):
|
||||
# Get the current date and time to uniquify the image (down to the second)
|
||||
date = time.ctime(time.time())
|
||||
|
@ -41,6 +41,7 @@
|
||||
#endif
|
||||
|
||||
#include <wrt.h>
|
||||
#include <displayRegion.h>
|
||||
#include <frustumCullTraverser.h>
|
||||
#include <pruneTransition.h>
|
||||
#include <decalTransition.h>
|
||||
@ -270,8 +271,9 @@ traverse(Node *root,
|
||||
// culling.
|
||||
LMatrix4f rel_from_camera;
|
||||
NodeTransitionWrapper ntw(TransformTransition::get_class_type());
|
||||
wrt(_gsg->get_current_projection_node(), root, begin(), end(),
|
||||
ntw, get_graph_type());
|
||||
const DisplayRegion *dr = _gsg->get_current_display_region();
|
||||
ProjectionNode *camera = dr->get_cull_frustum();
|
||||
wrt(camera, root, begin(), end(), ntw, get_graph_type());
|
||||
const TransformTransition *tt;
|
||||
if (get_transition_into(tt, ntw)) {
|
||||
rel_from_camera = tt->get_matrix();
|
||||
|
@ -49,11 +49,40 @@ get_layer() const {
|
||||
// Description: Returns the camera associated with this
|
||||
// DisplayRegion, or NULL if no camera is associated.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PT(Camera) DisplayRegion::
|
||||
INLINE Camera *DisplayRegion::
|
||||
get_camera() const {
|
||||
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
|
||||
// Access: Public
|
||||
|
@ -174,7 +174,7 @@ get_pipe() const {
|
||||
// between multiple DisplayRegions.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DisplayRegion::
|
||||
set_camera(const PT(Camera) &camera) {
|
||||
set_camera(Camera *camera) {
|
||||
if (camera != _camera) {
|
||||
if (_camera != (Camera *)NULL) {
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
set_cull_frustum(camera);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -58,8 +58,11 @@ PUBLISHED:
|
||||
GraphicsWindow *get_window() const;
|
||||
GraphicsPipe *get_pipe() const;
|
||||
|
||||
void set_camera(const PT(Camera) &camera);
|
||||
INLINE PT(Camera) get_camera() const;
|
||||
void set_camera(Camera *camera);
|
||||
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 bool is_active() const;
|
||||
@ -87,6 +90,7 @@ protected:
|
||||
|
||||
GraphicsLayer *_layer;
|
||||
PT(Camera) _camera;
|
||||
PT(ProjectionNode) _cull_frustum;
|
||||
|
||||
bool _active;
|
||||
|
||||
|
@ -88,7 +88,7 @@ get_current_root_node(void) const {
|
||||
// region will be made active (if it is not already) by
|
||||
// a call to prepare_display_region().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CPT(DisplayRegion) GraphicsStateGuardian::
|
||||
INLINE const DisplayRegion *GraphicsStateGuardian::
|
||||
get_current_display_region(void) const {
|
||||
return _current_display_region;
|
||||
}
|
||||
@ -107,7 +107,7 @@ get_current_display_region(void) const {
|
||||
// optimization.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE DisplayRegionStack GraphicsStateGuardian::
|
||||
push_display_region(CPT(DisplayRegion) dr) {
|
||||
push_display_region(const DisplayRegion *dr) {
|
||||
DisplayRegionStack old;
|
||||
old._display_region = _current_display_region;
|
||||
old._stack_level = _display_region_stack_level;
|
||||
@ -147,7 +147,7 @@ pop_display_region(DisplayRegionStack &node) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE FrameBufferStack GraphicsStateGuardian::
|
||||
push_frame_buffer(const RenderBuffer &buffer,
|
||||
CPT(DisplayRegion) dr) {
|
||||
const DisplayRegion *dr) {
|
||||
FrameBufferStack old;
|
||||
old._frame_buffer = save_frame_buffer(buffer, dr);
|
||||
old._stack_level = _frame_buffer_stack_level;
|
||||
|
@ -123,12 +123,12 @@ public:
|
||||
INLINE ProjectionNode *get_current_projection_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 FrameBufferStack push_frame_buffer(const RenderBuffer &buffer,
|
||||
CPT(DisplayRegion) dr);
|
||||
const DisplayRegion *dr);
|
||||
INLINE void pop_frame_buffer(FrameBufferStack &node);
|
||||
|
||||
INLINE void set_coordinate_system(CoordinateSystem cs);
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "renderRelation.h"
|
||||
|
||||
#include <graphicsStateGuardian.h>
|
||||
#include <displayRegion.h>
|
||||
#include <renderTraverser.h>
|
||||
#include <projectionNode.h>
|
||||
#include <look_at.h>
|
||||
@ -57,8 +58,12 @@ sub_render(NodeRelation *arc, const AllAttributesWrapper &,
|
||||
Node *node = arc->get_child();
|
||||
GraphicsStateGuardian *gsg = trav->get_gsg();
|
||||
|
||||
// Get the current camera from the gsg
|
||||
const 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();
|
||||
nassertr(camera != (ProjectionNode *)NULL, true);
|
||||
|
||||
// And the relative coordinate space.
|
||||
|
@ -69,8 +69,8 @@ share_projection(Projection *projection) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: get_projection
|
||||
// Access: Public
|
||||
// Description: Returns a pointer to particular Projection associated
|
||||
// with this ProjectionNode.
|
||||
// Description: Returns a pointer to the particular Projection
|
||||
// associated with this ProjectionNode.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
Projection *ProjectionNode::
|
||||
get_projection() {
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include <wrt.h>
|
||||
#include <geomNode.h>
|
||||
#include <graphicsStateGuardian.h>
|
||||
#include <displayRegion.h>
|
||||
#include <geometricBoundingVolume.h>
|
||||
#include <projectionNode.h>
|
||||
#include <projection.h>
|
||||
@ -103,8 +104,9 @@ traverse(Node *root,
|
||||
// culling.
|
||||
LMatrix4f rel_from_camera;
|
||||
NodeTransitionWrapper ntw(TransformTransition::get_class_type());
|
||||
wrt(_gsg->get_current_projection_node(), root, begin(), end(),
|
||||
ntw, get_graph_type());
|
||||
const DisplayRegion *dr = _gsg->get_current_display_region();
|
||||
ProjectionNode *camera = dr->get_cull_frustum();
|
||||
wrt(camera, root, begin(), end(), ntw, get_graph_type());
|
||||
const TransformTransition *tt;
|
||||
if (get_transition_into(tt, ntw)) {
|
||||
rel_from_camera = tt->get_matrix();
|
||||
|
@ -43,7 +43,12 @@ FrustumCullTraverser(ArcChain &arc_chain, Node *root,
|
||||
// If we're to be performing view-frustum culling, determine the
|
||||
// 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) {
|
||||
const Projection *proj = camera->get_projection();
|
||||
nassertv(proj != (const Projection *)NULL);
|
||||
@ -188,7 +193,9 @@ traverse(NodeRelation *arc, AttributeWrapper render_state,
|
||||
DCAST(GeometricBoundingVolume, _view_frustum->make_copy());
|
||||
|
||||
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(),
|
||||
ntw, _graph_type);
|
||||
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include <typedObject.h>
|
||||
#include <geometricBoundingVolume.h>
|
||||
#include <graphicsStateGuardian.h>
|
||||
#include <displayRegion.h>
|
||||
#include <arcChain.h>
|
||||
#include <nodeTransitionWrapper.h>
|
||||
#include <transformTransition.h>
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "config_switchnode.h"
|
||||
|
||||
#include <graphicsStateGuardian.h>
|
||||
#include <displayRegion.h>
|
||||
#include <get_rel_pos.h>
|
||||
#include <luse.h>
|
||||
#include <renderRelation.h>
|
||||
@ -85,26 +86,32 @@ void LODNode::
|
||||
compute_switch(RenderTraverser *trav) {
|
||||
GraphicsStateGuardian *gsg = trav->get_gsg();
|
||||
|
||||
// Get the current camera position from the gsg
|
||||
const ProjectionNode* camera = gsg->get_current_projection_node();
|
||||
LPoint3f camera_pos(0, 0, 0);
|
||||
// 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 != (ProjectionNode *)NULL) {
|
||||
LPoint3f camera_pos(0, 0, 0);
|
||||
|
||||
// Get the LOD center in camera space
|
||||
LPoint3f LOD_pos;
|
||||
// Get the LOD center in camera space
|
||||
LPoint3f LOD_pos;
|
||||
|
||||
NodeTransitionWrapper ntw(TransformTransition::get_class_type());
|
||||
wrt(this, trav->begin(), trav->end(),
|
||||
camera, ntw, RenderRelation::get_class_type());
|
||||
const TransformTransition *tt;
|
||||
if (get_transition_into(tt, ntw)) {
|
||||
LOD_pos = _lod._center * tt->get_matrix();
|
||||
} else {
|
||||
LOD_pos = _lod._center;
|
||||
NodeTransitionWrapper ntw(TransformTransition::get_class_type());
|
||||
wrt(this, trav->begin(), trav->end(),
|
||||
camera, ntw, RenderRelation::get_class_type());
|
||||
const TransformTransition *tt;
|
||||
if (get_transition_into(tt, ntw)) {
|
||||
LOD_pos = _lod._center * tt->get_matrix();
|
||||
} else {
|
||||
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);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
Loading…
x
Reference in New Issue
Block a user