mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 02:15:43 -04:00
scissor MouseWatcherRegions too
This commit is contained in:
parent
ab6e8bbc3c
commit
4d59f04134
@ -366,6 +366,25 @@ get_clip_plane() const {
|
||||
return _clip_plane;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RenderState::get_scissor
|
||||
// Access: Published
|
||||
// Description: This function is provided as an optimization, to
|
||||
// speed up the render-time checking for the existance
|
||||
// of a ScissorAttrib on this state. It returns a
|
||||
// pointer to the ScissorAttrib, if there is one, or
|
||||
// NULL if there is not.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const ScissorAttrib *RenderState::
|
||||
get_scissor() const {
|
||||
if ((_flags & F_checked_scissor) == 0) {
|
||||
// We pretend this function is const, even though it transparently
|
||||
// modifies the internal scissor cache.
|
||||
((RenderState *)this)->determine_scissor();
|
||||
}
|
||||
return _scissor;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RenderState::get_shader
|
||||
// Access: Published
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "cullBinManager.h"
|
||||
#include "fogAttrib.h"
|
||||
#include "clipPlaneAttrib.h"
|
||||
#include "scissorAttrib.h"
|
||||
#include "transparencyAttrib.h"
|
||||
#include "colorAttrib.h"
|
||||
#include "colorScaleAttrib.h"
|
||||
@ -1972,6 +1973,27 @@ determine_clip_plane() {
|
||||
_flags |= F_checked_clip_plane;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RenderState::determine_scissor
|
||||
// Access: Private
|
||||
// Description: This is the private implementation of get_scissor().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void RenderState::
|
||||
determine_scissor() {
|
||||
MutexHolder holder(_lock);
|
||||
if ((_flags & F_checked_scissor) != 0) {
|
||||
// Someone else checked it first.
|
||||
return;
|
||||
}
|
||||
|
||||
const RenderAttrib *attrib = get_attrib(ScissorAttrib::get_class_type());
|
||||
_scissor = (const ScissorAttrib *)NULL;
|
||||
if (attrib != (const RenderAttrib *)NULL) {
|
||||
_scissor = DCAST(ScissorAttrib, attrib);
|
||||
}
|
||||
_flags |= F_checked_scissor;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RenderState::determine_shader
|
||||
// Access: Private
|
||||
|
@ -42,6 +42,7 @@ class ColorScaleAttrib;
|
||||
class TextureAttrib;
|
||||
class TexGenAttrib;
|
||||
class ClipPlaneAttrib;
|
||||
class ScissorAttrib;
|
||||
class ShaderAttrib;
|
||||
class FactoryParams;
|
||||
class AudioVolumeAttrib;
|
||||
@ -147,6 +148,7 @@ PUBLISHED:
|
||||
INLINE const TexMatrixAttrib *get_tex_matrix() const;
|
||||
INLINE const RenderModeAttrib *get_render_mode() const;
|
||||
INLINE const ClipPlaneAttrib *get_clip_plane() const;
|
||||
INLINE const ScissorAttrib *get_scissor() const;
|
||||
INLINE const ShaderAttrib *get_shader() const;
|
||||
INLINE const AudioVolumeAttrib *get_audio_volume() const;
|
||||
|
||||
@ -201,6 +203,7 @@ private:
|
||||
void determine_tex_matrix();
|
||||
void determine_render_mode();
|
||||
void determine_clip_plane();
|
||||
void determine_scissor();
|
||||
void determine_shader();
|
||||
void determine_cull_callback();
|
||||
void determine_audio_volume();
|
||||
@ -315,28 +318,30 @@ private:
|
||||
const TexMatrixAttrib *_tex_matrix;
|
||||
const RenderModeAttrib *_render_mode;
|
||||
const ClipPlaneAttrib *_clip_plane;
|
||||
const ScissorAttrib *_scissor;
|
||||
const ShaderAttrib *_shader;
|
||||
const AudioVolumeAttrib *_audio_volume;
|
||||
|
||||
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_checked_cull_callback = 0x1000,
|
||||
F_checked_audio_volume = 0x2000,
|
||||
F_has_cull_callback = 0x4000,
|
||||
F_is_destructing = 0x8000,
|
||||
F_checked_bin_index = 0x000001,
|
||||
F_checked_fog = 0x000002,
|
||||
F_checked_bin = 0x000004,
|
||||
F_checked_transparency = 0x000008,
|
||||
F_checked_color = 0x000010,
|
||||
F_checked_color_scale = 0x000020,
|
||||
F_checked_texture = 0x000040,
|
||||
F_checked_tex_gen = 0x000080,
|
||||
F_checked_tex_matrix = 0x000100,
|
||||
F_checked_render_mode = 0x000200,
|
||||
F_checked_clip_plane = 0x000400,
|
||||
F_checked_shader = 0x000800,
|
||||
F_checked_cull_callback = 0x001000,
|
||||
F_checked_audio_volume = 0x002000,
|
||||
F_has_cull_callback = 0x004000,
|
||||
F_is_destructing = 0x008000,
|
||||
F_checked_scissor = 0x010000,
|
||||
};
|
||||
unsigned short _flags;
|
||||
unsigned int _flags;
|
||||
|
||||
// This mutex protects _flags, and all of the above computed values.
|
||||
Mutex _lock;
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "cullTraverserData.h"
|
||||
#include "cullBinManager.h"
|
||||
#include "clipPlaneAttrib.h"
|
||||
#include "scissorAttrib.h"
|
||||
#include "dcast.h"
|
||||
#include "boundingSphere.h"
|
||||
#include "boundingBox.h"
|
||||
@ -252,7 +253,8 @@ cull_callback(CullTraverser *trav, CullTraverserData &data) {
|
||||
// which only provides one.
|
||||
sort = (bin_sort << 16) | ((sort + 0x8000) & 0xffff);
|
||||
|
||||
if (activate_region(transform, sort, data._state->get_clip_plane())) {
|
||||
if (activate_region(transform, sort, data._state->get_clip_plane(),
|
||||
data._state->get_scissor())) {
|
||||
pg_trav->_top->add_region(get_region());
|
||||
}
|
||||
}
|
||||
@ -379,7 +381,8 @@ xform(const LMatrix4f &mat) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool PGItem::
|
||||
activate_region(const LMatrix4f &transform, int sort,
|
||||
const ClipPlaneAttrib *cpa) {
|
||||
const ClipPlaneAttrib *cpa,
|
||||
const ScissorAttrib *sa) {
|
||||
// Transform all four vertices, and get the new bounding box. This
|
||||
// way the region works (mostly) even if has been rotated.
|
||||
LPoint3f ll(_frame[0], 0.0f, _frame[2]);
|
||||
@ -391,8 +394,10 @@ activate_region(const LMatrix4f &transform, int sort,
|
||||
ul = ul * transform;
|
||||
ur = ur * transform;
|
||||
|
||||
LVecBase4f frame;
|
||||
if (cpa != (ClipPlaneAttrib *)NULL && cpa->get_num_on_planes() != 0) {
|
||||
// Apply the clip plane(s) now that we are here in world space.
|
||||
// Apply the clip plane(s) and/or scissor region now that we are
|
||||
// here in world space.
|
||||
|
||||
pvector<LPoint2f> points;
|
||||
points.reserve(4);
|
||||
@ -406,13 +411,13 @@ activate_region(const LMatrix4f &transform, int sort,
|
||||
NodePath plane_path = cpa->get_on_plane(i);
|
||||
Planef plane = DCAST(PlaneNode, plane_path.node())->get_plane();
|
||||
plane.xform(plane_path.get_net_transform()->get_mat());
|
||||
|
||||
|
||||
// We ignore the y coordinate, assuming the frame is still in
|
||||
// the X-Z plane after being transformed. Not sure if we really
|
||||
// need to support general 3-D transforms on 2-D objects.
|
||||
clip_frame(points, plane);
|
||||
}
|
||||
|
||||
|
||||
if (points.empty()) {
|
||||
// Turns out it's completely clipped after all.
|
||||
return false;
|
||||
@ -420,7 +425,7 @@ activate_region(const LMatrix4f &transform, int sort,
|
||||
|
||||
pvector<LPoint2f>::iterator pi;
|
||||
pi = points.begin();
|
||||
LVecBase4f frame((*pi)[0], (*pi)[0], (*pi)[1], (*pi)[1]);
|
||||
frame.set((*pi)[0], (*pi)[0], (*pi)[1], (*pi)[1]);
|
||||
++pi;
|
||||
while (pi != points.end()) {
|
||||
frame[0] = min(frame[0], (*pi)[0]);
|
||||
@ -429,15 +434,29 @@ activate_region(const LMatrix4f &transform, int sort,
|
||||
frame[3] = max(frame[3], (*pi)[1]);
|
||||
++pi;
|
||||
}
|
||||
_region->set_frame(frame);
|
||||
|
||||
} else {
|
||||
// Since there are no clip planes involved, just set the frame.
|
||||
_region->set_frame(min(min(ll[0], lr[0]), min(ul[0], ur[0])),
|
||||
max(max(ll[0], lr[0]), max(ul[0], ur[0])),
|
||||
min(min(ll[2], lr[2]), min(ul[2], ur[2])),
|
||||
max(max(ll[2], lr[2]), max(ul[2], ur[2])));
|
||||
frame.set(min(min(ll[0], lr[0]), min(ul[0], ur[0])),
|
||||
max(max(ll[0], lr[0]), max(ul[0], ur[0])),
|
||||
min(min(ll[2], lr[2]), min(ul[2], ur[2])),
|
||||
max(max(ll[2], lr[2]), max(ul[2], ur[2])));
|
||||
}
|
||||
|
||||
if (sa != (ScissorAttrib *)NULL) {
|
||||
// Also restrict it to within the scissor region.
|
||||
const LVecBase4f &sf = sa->get_frame();
|
||||
// Expand sf from 0..1 to -1..1.
|
||||
frame.set(max(frame[0], sf[0] * 2.0f - 1.0f),
|
||||
min(frame[1], sf[1] * 2.0f - 1.0f),
|
||||
max(frame[2], sf[2] * 2.0f - 1.0f),
|
||||
min(frame[3], sf[3] * 2.0f - 1.0f));
|
||||
if (frame[1] <= frame[0] || frame[3] <= frame[2]) {
|
||||
// Completely outside the scissor region.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
_region->set_frame(frame);
|
||||
|
||||
_region->set_sort(sort);
|
||||
_region->set_active(true);
|
||||
|
@ -34,6 +34,7 @@ class PGTop;
|
||||
class MouseWatcherParameter;
|
||||
class AudioSound;
|
||||
class ClipPlaneAttrib;
|
||||
class ScissorAttrib;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : PGItem
|
||||
@ -70,7 +71,8 @@ protected:
|
||||
public:
|
||||
virtual void xform(const LMatrix4f &mat);
|
||||
bool activate_region(const LMatrix4f &transform, int sort,
|
||||
const ClipPlaneAttrib *cpa);
|
||||
const ClipPlaneAttrib *cpa,
|
||||
const ScissorAttrib *sa);
|
||||
INLINE PGMouseWatcherRegion *get_region() const;
|
||||
|
||||
virtual void enter_region(const MouseWatcherParameter ¶m);
|
||||
|
Loading…
x
Reference in New Issue
Block a user