clip planes

This commit is contained in:
David Rose 2002-07-12 15:46:51 +00:00
parent ab97742881
commit 4e233c54f6
18 changed files with 1548 additions and 68 deletions

View File

@ -28,6 +28,17 @@ LightInfo() {
_next_enabled = false;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::ClipPlaneInfo::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE GraphicsStateGuardian::ClipPlaneInfo::
ClipPlaneInfo() {
_enabled = false;
_next_enabled = false;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::is_closed
@ -340,3 +351,15 @@ get_light(int light_id) const {
nassertr(light_id >= 0 && light_id < (int)_light_info.size(), (Light *)NULL);
return _light_info[light_id]._light;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::get_clip_plane
// Access: Protected
// Description: Returns the PlaneNode object that is bound to the
// indicated id, or NULL if no PlaneNode is bound.
////////////////////////////////////////////////////////////////////
INLINE PlaneNode *GraphicsStateGuardian::
get_clip_plane(int plane_id) const {
nassertr(plane_id >= 0 && plane_id < (int)_clip_plane_info.size(), (PlaneNode *)NULL);
return _clip_plane_info[plane_id]._plane;
}

View File

@ -30,7 +30,9 @@
#include "colorWriteAttrib.h"
#include "textureAttrib.h"
#include "lightAttrib.h"
#include "clipPlaneAttrib.h"
#include "light.h"
#include "planeNode.h"
#include "ambientLight.h"
#include "clockObject.h"
@ -152,8 +154,10 @@ reset() {
_scene_graph_color_stale = false;
_vertex_colors_enabled = true;
_lighting_enabled = false;
_lighting_enabled_this_frame = false;
_clip_planes_enabled = false;
_clip_planes_enabled_this_frame = false;
}
////////////////////////////////////////////////////////////////////
@ -432,6 +436,21 @@ begin_frame() {
_lighting_enabled_this_frame = false;
}
// Ditto for the clipping planes.
if (_clip_planes_enabled_this_frame) {
for (int i = 0; i < (int)_clip_plane_info.size(); i++) {
if (_clip_plane_info[i]._enabled) {
enable_clip_plane(i, false);
_clip_plane_info[i]._enabled = false;
}
_clip_plane_info[i]._plane = (PlaneNode *)NULL;
}
modify_state(get_unclipped_state());
_clip_planes_enabled_this_frame = false;
}
#ifdef DO_PSTATS
// For Pstats to track our current texture memory usage, we have to
// reset the set of current textures each frame.
@ -689,7 +708,7 @@ issue_color(const ColorAttrib *attrib) {
// light associated with the same id where possible, but
// reusing id's when necessary. When it is no longer
// possible to reuse existing id's (e.g. all id's are in
// use), slot_light() is called to prepare the next
// use), slot_new_light() is called to prepare the next
// sequential light id.
//
// It will call apply_light() each time a light is
@ -861,6 +880,125 @@ issue_color_blend(const ColorBlendAttrib *attrib) {
set_blend_mode(_color_write_mode, _color_blend_mode, _transparency_mode);
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::issue_clip_plane
// Access: Public, Virtual
// Description: This is fundametically similar to issue_light(), with
// calls to slot_new_clip_plane(), apply_clip_plane(),
// and enable_clip_planes(), as appropriate.
////////////////////////////////////////////////////////////////////
void GraphicsStateGuardian::
issue_clip_plane(const ClipPlaneAttrib *attrib) {
int i;
int max_planes = (int)_clip_plane_info.size();
for (i = 0; i < max_planes; i++) {
_clip_plane_info[i]._next_enabled = false;
}
bool any_bound = false;
int num_enabled = 0;
int num_planes = attrib->get_num_planes();
if (attrib->get_operation() == ClipPlaneAttrib::O_remove) {
num_planes = 0;
}
for (int li = 0; li < num_planes; li++) {
PlaneNode *plane = attrib->get_plane(li);
nassertv(plane != (PlaneNode *)NULL);
num_enabled++;
// Planeing should be enabled before we apply any planes.
enable_clip_planes(true);
_clip_planes_enabled = true;
_clip_planes_enabled_this_frame = true;
// Check to see if this plane has already been bound to an id
int cur_plane_id = -1;
for (i = 0; i < max_planes; i++) {
if (_clip_plane_info[i]._plane == plane) {
// Plane has already been bound to an id, we only need to
// enable the plane, not reapply it.
cur_plane_id = -2;
enable_clip_plane(i, true);
_clip_plane_info[i]._enabled = true;
_clip_plane_info[i]._next_enabled = true;
break;
}
}
// See if there are any unbound plane ids
if (cur_plane_id == -1) {
for (i = 0; i < max_planes; i++) {
if (_clip_plane_info[i]._plane == (PlaneNode *)NULL) {
_clip_plane_info[i]._plane = plane;
cur_plane_id = i;
break;
}
}
}
// If there were no unbound plane ids, see if we can replace
// a currently unused but previously bound id
if (cur_plane_id == -1) {
for (i = 0; i < max_planes; i++) {
if (!attrib->has_plane(_clip_plane_info[i]._plane)) {
_clip_plane_info[i]._plane = plane;
cur_plane_id = i;
break;
}
}
}
// If we *still* don't have a plane id, slot a new one.
if (cur_plane_id == -1) {
if (slot_new_clip_plane(max_planes)) {
cur_plane_id = max_planes;
_clip_plane_info.push_back(ClipPlaneInfo());
max_planes++;
nassertv(max_planes == (int)_clip_plane_info.size());
}
}
if (cur_plane_id >= 0) {
enable_clip_plane(cur_plane_id, true);
_clip_plane_info[cur_plane_id]._enabled = true;
_clip_plane_info[cur_plane_id]._next_enabled = true;
if (!any_bound) {
begin_bind_clip_planes();
any_bound = true;
}
// This is the first time this frame that this plane has been
// bound to this particular id.
bind_clip_plane(plane, cur_plane_id);
} else if (cur_plane_id == -1) {
gsg_cat.warning()
<< "Failed to bind " << *plane << " to id.\n";
}
}
// Disable all unused planes
for (i = 0; i < max_planes; i++) {
if (!_clip_plane_info[i]._next_enabled) {
enable_clip_plane(i, false);
_clip_plane_info[i]._enabled = false;
}
}
// If no planes were enabled, disable clip planes in general.
if (num_enabled == 0) {
enable_clip_planes(false);
_clip_planes_enabled = false;
}
if (any_bound) {
end_bind_clip_planes();
}
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::bind_light
// Access: Public, Virtual
@ -979,6 +1117,90 @@ void GraphicsStateGuardian::
end_bind_lights() {
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::slot_new_clip_plane
// Access: Protected, Virtual
// Description: This will be called by the base class before a
// particular clip plane id will be used for the first
// time. It is intended to allow the derived class to
// reserve any additional resources, if required, for
// the new clip plane; and also to indicate whether the
// hardware supports this many simultaneous clipping
// planes.
//
// The return value should be true if the additional
// plane is supported, or false if it is not.
////////////////////////////////////////////////////////////////////
bool GraphicsStateGuardian::
slot_new_clip_plane(int plane_id) {
return true;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::enable_clip_planes
// Access: Protected, Virtual
// Description: Intended to be overridden by a derived class to
// enable or disable the use of clipping planes overall.
// This is called by issue_clip_plane() according to
// whether any planes are in use or not.
////////////////////////////////////////////////////////////////////
void GraphicsStateGuardian::
enable_clip_planes(bool enable) {
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::enable_clip_plane
// Access: Protected, Virtual
// Description: Intended to be overridden by a derived class to
// enable the indicated plane id. A specific PlaneNode
// will already have been bound to this id via
// bind_clip_plane().
////////////////////////////////////////////////////////////////////
void GraphicsStateGuardian::
enable_clip_plane(int plane_id, bool enable) {
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::begin_bind_clip_planes
// Access: Protected, Virtual
// Description: Called immediately before bind_clip_plane() is called,
// this is intended to provide the derived class a hook
// in which to set up some state (like transform) that
// might apply to several planes.
//
// The sequence is: begin_bind_clip_planes() will be
// called, then one or more bind_clip_plane() calls,
// then end_bind_clip_planes().
////////////////////////////////////////////////////////////////////
void GraphicsStateGuardian::
begin_bind_clip_planes() {
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::bind_clip_plane
// Access: Public, Virtual
// Description: Called the first time a particular clipping plane has been
// bound to a given id within a frame, this should set
// up the associated hardware (or API) clipping plane
// with the plane's properties.
////////////////////////////////////////////////////////////////////
void GraphicsStateGuardian::
bind_clip_plane(PlaneNode *plane, int plane_id) {
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::end_bind_clip_planes
// Access: Protected, Virtual
// Description: Called after before bind_clip_plane() has been called one
// or more times (but before any geometry is issued or
// additional state is changed), this is intended to
// clean up any temporary changes to the state that may
// have been made by begin_bind_clip_planes().
////////////////////////////////////////////////////////////////////
void GraphicsStateGuardian::
end_bind_clip_planes() {
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::set_blend_mode
// Access: Protected, Virtual
@ -1248,6 +1470,20 @@ get_unlit_state() {
return state;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::get_unclipped_state
// Access: Protected, Static
// Description:
////////////////////////////////////////////////////////////////////
CPT(RenderState) GraphicsStateGuardian::
get_unclipped_state() {
static CPT(RenderState) state = NULL;
if (state == (const RenderState *)NULL) {
state = RenderState::make(ClipPlaneAttrib::make_all_off());
}
return state;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::get_untextured_state
// Access: Protected, Static

View File

@ -35,6 +35,7 @@
#include "transformState.h"
#include "renderState.h"
#include "light.h"
#include "planeNode.h"
#include "colorWriteAttrib.h"
#include "colorBlendAttrib.h"
#include "transparencyAttrib.h"
@ -148,6 +149,7 @@ public:
virtual void issue_color_write(const ColorWriteAttrib *attrib);
virtual void issue_transparency(const TransparencyAttrib *attrib);
virtual void issue_color_blend(const ColorBlendAttrib *attrib);
virtual void issue_clip_plane(const ClipPlaneAttrib *attrib);
virtual void bind_light(PointLight *light, int light_id);
virtual void bind_light(DirectionalLight *light, int light_id);
@ -162,6 +164,14 @@ protected:
virtual void begin_bind_lights();
virtual void end_bind_lights();
INLINE PlaneNode *get_clip_plane(int plane_id) const;
virtual bool slot_new_clip_plane(int plane_id);
virtual void enable_clip_planes(bool enable);
virtual void enable_clip_plane(int plane_id, bool enable);
virtual void begin_bind_clip_planes();
virtual void bind_clip_plane(PlaneNode *plane, int pane_id);
virtual void end_bind_clip_planes();
virtual void set_blend_mode(ColorWriteAttrib::Mode color_write_mode,
ColorBlendAttrib::Mode color_blend_mode,
TransparencyAttrib::Mode transparency_mode);
@ -199,6 +209,7 @@ protected:
#endif
static CPT(RenderState) get_unlit_state();
static CPT(RenderState) get_unclipped_state();
static CPT(RenderState) get_untextured_state();
protected:
@ -233,6 +244,7 @@ protected:
bool _scene_graph_color_stale;
bool _vertex_colors_enabled;
bool _lighting_enabled;
bool _clip_planes_enabled;
enum ColorTransform {
CT_offset = 0x01,
@ -285,6 +297,17 @@ private:
pvector<LightInfo> _light_info;
bool _lighting_enabled_this_frame;
class ClipPlaneInfo {
public:
INLINE ClipPlaneInfo();
PT(PlaneNode) _plane;
bool _enabled;
bool _next_enabled;
};
pvector<ClipPlaneInfo> _clip_plane_info;
bool _clip_planes_enabled_this_frame;
// NOTE: on win32 another DLL (e.g. libpandadx.dll) cannot access
// these sets directly due to exported template issue
typedef pset<TextureContext *> Textures;

View File

@ -795,31 +795,6 @@ enable_scissor(bool val)
}
}
////////////////////////////////////////////////////////////////////
// Function: GLGraphicsStateGuardian::enable_clip_plane
// Access:
// Description:
////////////////////////////////////////////////////////////////////
INLINE void GLGraphicsStateGuardian::
enable_clip_plane(int clip_plane, bool val) {
if (_clip_plane_enabled[clip_plane] != val) {
_clip_plane_enabled[clip_plane] = val;
if (val) {
#ifdef GSG_VERBOSE
glgsg_cat.debug()
<< "glEnable(GL_CLIP_PLANE_" << clip_plane << ")" << endl;
#endif
glEnable(get_clip_plane_id(clip_plane));
} else {
#ifdef GSG_VERBOSE
glgsg_cat.debug()
<< "glDisable(GL_CLIP_PLANE_" << clip_plane << ")" << endl;
#endif
glDisable(get_clip_plane_id(clip_plane));
}
}
}
////////////////////////////////////////////////////////////////////
// Function: GLGraphicsStateGuardian::enable_multisample_alpha_one
// Access:

View File

@ -34,6 +34,7 @@
#include "directionalLight.h"
#include "pointLight.h"
#include "spotlight.h"
#include "planeNode.h"
#include "GL/glu.h"
#include "textureAttrib.h"
#include "lightAttrib.h"
@ -128,9 +129,6 @@ issue_transformed_color_gl(const Geom *geom, Geom::ColorIterator &citerator,
////////////////////////////////////////////////////////////////////
GLGraphicsStateGuardian::
GLGraphicsStateGuardian(GraphicsWindow *win) : GraphicsStateGuardian(win) {
_clip_plane_enabled = (bool *)NULL;
_cur_clip_plane_enabled = (bool *)NULL;
reset();
}
@ -256,18 +254,10 @@ reset() {
glGetIntegerv(GL_MAX_LIGHTS, &max_lights);
_max_lights = max_lights;
// Set up the clip plane id map
// Count the max number of clipping planes
GLint max_clip_planes;
glGetIntegerv(GL_MAX_CLIP_PLANES, &max_clip_planes);
_max_clip_planes = max_clip_planes;
_available_clip_plane_ids = PTA(PlaneNode*)::empty_array(_max_clip_planes);
_clip_plane_enabled = new bool[_max_clip_planes];
_cur_clip_plane_enabled = new bool[_max_clip_planes];
int i;
for (i = 0; i < _max_clip_planes; i++) {
_available_clip_plane_ids[i] = NULL;
_clip_plane_enabled[i] = false;
}
_current_projection_mat = LMatrix4f::ident_mat();
_projection_mat_stack_count = 0;
@ -3452,6 +3442,106 @@ end_bind_lights() {
glPopMatrix();
}
////////////////////////////////////////////////////////////////////
// Function: GLGraphicsStateGuardian::slot_new_clip_plane
// Access: Protected, Virtual
// Description: This will be called by the base class before a
// particular clip plane id will be used for the first
// time. It is intended to allow the derived class to
// reserve any additional resources, if required, for
// the new clip plane; and also to indicate whether the
// hardware supports this many simultaneous clipping
// planes.
//
// The return value should be true if the additional
// plane is supported, or false if it is not.
////////////////////////////////////////////////////////////////////
bool GLGraphicsStateGuardian::
slot_new_clip_plane(int plane_id) {
return (plane_id < _max_clip_planes);
}
////////////////////////////////////////////////////////////////////
// Function: GLGraphicsStateGuardian::enable_clip_plane
// Access: Protected, Virtual
// Description: Intended to be overridden by a derived class to
// enable the indicated clip_plane id. A specific
// PlaneNode will already have been bound to this id via
// bind_clip_plane().
////////////////////////////////////////////////////////////////////
void GLGraphicsStateGuardian::
enable_clip_plane(int plane_id, bool enable) {
if (enable) {
glEnable(get_clip_plane_id(plane_id));
} else {
glDisable(get_clip_plane_id(plane_id));
}
}
////////////////////////////////////////////////////////////////////
// Function: GLGraphicsStateGuardian::begin_bind_clip_planes
// Access: Protected, Virtual
// Description: Called immediately before bind_clip_plane() is called,
// this is intended to provide the derived class a hook
// in which to set up some state (like transform) that
// might apply to several clip_planes.
//
// The sequence is: begin_bind_clip_planes() will be called,
// then one or more bind_clip_plane() calls, then
// end_bind_clip_planes().
////////////////////////////////////////////////////////////////////
void GLGraphicsStateGuardian::
begin_bind_clip_planes() {
// We need to temporarily load a new matrix so we can define the
// clip_plane in a known coordinate system. We pick the transform of the
// root. (Alternatively, we could leave the current transform where
// it is and compute the clip_plane position relative to that transform
// instead of relative to the root, by composing with the matrix
// computed by _transform->invert_compose(render_transform). But I
// think loading a completely new matrix is simpler.)
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadMatrixf(_scene_setup->get_render_transform()->get_mat().get_data());
}
////////////////////////////////////////////////////////////////////
// Function: GLGraphicsStateGuardian::bind_clip_plane
// Access: Protected, Virtual
// Description: Called the first time a particular clip_plane has been
// bound to a given id within a frame, this should set
// up the associated hardware clip_plane with the clip_plane's
// properties.
////////////////////////////////////////////////////////////////////
void GLGraphicsStateGuardian::
bind_clip_plane(PlaneNode *plane, int plane_id) {
GLenum id = get_clip_plane_id(plane_id);
NodePath plane_np(plane);
const LMatrix4f &plane_mat = plane_np.get_mat(_scene_setup->get_scene_root());
Planef xformed_plane = plane->get_plane() * plane_mat;
Planed double_plane(xformed_plane._a, xformed_plane._b,
xformed_plane._c, xformed_plane._d);
glClipPlane(id, double_plane.get_data());
report_errors();
}
////////////////////////////////////////////////////////////////////
// Function: GLGraphicsStateGuardian::end_bind_clip_planes
// Access: Protected, Virtual
// Description: Called after before bind_clip_plane() has been called one
// or more times (but before any geometry is issued or
// additional state is changed), this is intended to
// clean up any temporary changes to the state that may
// have been made by begin_bind_clip_planes().
////////////////////////////////////////////////////////////////////
void GLGraphicsStateGuardian::
end_bind_clip_planes() {
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
}
////////////////////////////////////////////////////////////////////
// Function: GLGraphicsStateGuardian::set_blend_mode
// Access: Protected, Virtual
@ -3562,14 +3652,6 @@ set_blend_mode(ColorWriteAttrib::Mode color_write_mode,
////////////////////////////////////////////////////////////////////
void GLGraphicsStateGuardian::
free_pointers() {
if (_clip_plane_enabled != (bool *)NULL) {
delete[] _clip_plane_enabled;
_clip_plane_enabled = (bool *)NULL;
}
if (_cur_clip_plane_enabled != (bool *)NULL) {
delete[] _cur_clip_plane_enabled;
_cur_clip_plane_enabled = (bool *)NULL;
}
}
////////////////////////////////////////////////////////////////////
@ -3859,10 +3941,6 @@ dump_state(void)
dump << "\t\t" << "GL_TEXTURE_2D " << _texturing_enabled << " " << (bool)glIsEnabled(GL_TEXTURE_2D) << "\n";
dump << "\t\t" << "GL_DITHER " << _dither_enabled << " " << (bool)glIsEnabled(GL_DITHER) << "\n";
dump << "\t\t" << "GL_STENCIL_TEST " << " " << (bool)glIsEnabled(GL_STENCIL_TEST) << "\n";
for(i = 0; i < _max_clip_planes; i++)
{
dump << "\t\t\t\t" << "GL_CLIP_PLANE" << i << " " << _clip_plane_enabled[i] << " " << (bool)glIsEnabled(GL_CLIP_PLANE0+i) << "\n";
}
dump << "\t\t" << "GL_BLEND " << _blend_enabled << " " << (bool)glIsEnabled(GL_BLEND) << "\n";
dump << "\t\t" << "GL_DEPTH_TEST " << _depth_test_enabled << " " << (bool)glIsEnabled(GL_DEPTH_TEST) << "\n";
dump << "\t\t" << "GL_FOG " << _fog_enabled << " " << (bool)glIsEnabled(GL_FOG) << "\n";

View File

@ -123,7 +123,6 @@ public:
virtual void issue_depth_offset(const DepthOffsetAttrib *attrib);
// virtual void issue_tex_gen(const TexGenAttrib *attrib);
// virtual void issue_stencil(const StencilAttrib *attrib);
// virtual void issue_clip_plane(const ClipPlaneAttrib *attrib);
virtual void bind_light(PointLight *light, int light_id);
virtual void bind_light(DirectionalLight *light, int light_id);
@ -153,6 +152,12 @@ protected:
virtual void begin_bind_lights();
virtual void end_bind_lights();
virtual bool slot_new_clip_plane(int plane_id);
virtual void enable_clip_plane(int plane_id, bool enable);
virtual void begin_bind_clip_planes();
virtual void bind_clip_plane(PlaneNode *plane, int plane_id);
virtual void end_bind_clip_planes();
virtual void set_blend_mode(ColorWriteAttrib::Mode color_write_mode,
ColorBlendAttrib::Mode color_blend_mode,
TransparencyAttrib::Mode transparency_mode);
@ -202,7 +207,6 @@ protected:
INLINE void enable_scissor(bool val);
INLINE void enable_dither(bool val);
INLINE void enable_stencil_test(bool val);
INLINE void enable_clip_plane(int clip_plane, bool val);
INLINE void enable_multisample_alpha_one(bool val);
INLINE void enable_multisample_alpha_mask(bool val);
INLINE void enable_blend(bool val);
@ -307,16 +311,11 @@ protected:
int _decal_level;
int _max_lights;
int _max_clip_planes;
LMatrix4f _current_projection_mat;
int _projection_mat_stack_count;
int _max_clip_planes;
PTA(PlaneNode *)_available_clip_plane_ids; // pPlaneNode[_max_clip_planes]
bool *_clip_plane_enabled; // bool[_max_clip_planes]
bool *_cur_clip_plane_enabled; // bool[_max_clip_planes]
int _cur_clip_plane_id;
CPT(DisplayRegion) _actual_display_region;
int _pass_number;

View File

@ -73,7 +73,8 @@ FLOATNAME(Plane)(const FLOATNAME(LPoint3) &a, const FLOATNAME(LPoint3) &b,
// a point within the plane.
////////////////////////////////////////////////////////////////////
INLINE_MATHUTIL FLOATNAME(Plane)::
FLOATNAME(Plane)(const FLOATNAME(LVector3) &normal, const FLOATNAME(LPoint3) &point) {
FLOATNAME(Plane)(const FLOATNAME(LVector3) &normal,
const FLOATNAME(LPoint3) &point) {
FLOATNAME(LVector3) p = normalize(normal);
_a = p[0];
@ -82,6 +83,21 @@ FLOATNAME(Plane)(const FLOATNAME(LVector3) &normal, const FLOATNAME(LPoint3) &po
_d = -dot(p, point);
}
////////////////////////////////////////////////////////////////////
// Function: Plane::Constructor
// Access: Public
// Description: Constructs a plane given the four terms of the plane
// equation.
////////////////////////////////////////////////////////////////////
INLINE_MATHUTIL FLOATNAME(Plane)::
FLOATNAME(Plane)(FLOATTYPE a, FLOATTYPE b, FLOATTYPE c, FLOATTYPE d) :
_a(a),
_b(b),
_c(c),
_d(d)
{
}
////////////////////////////////////////////////////////////////////
// Function: Plane::Operator =
// Access: Public
@ -197,6 +213,30 @@ intersects_line(FLOATTYPE &t,
return true;
}
////////////////////////////////////////////////////////////////////
// Function: Plane::get_data
// Access: Public
// Description: Returns the address of the first of the four data
// elements in the plane equation. The remaining
// elements occupy the next positions consecutively in
// memory.
////////////////////////////////////////////////////////////////////
INLINE_MATHUTIL const FLOATTYPE *FLOATNAME(Plane)::
get_data() const {
return &_a;
}
////////////////////////////////////////////////////////////////////
// Function: Plane::get_num_components
// Access: Public
// Description: Returns the number of elements in the plane equation,
// four.
////////////////////////////////////////////////////////////////////
INLINE_MATHUTIL int FLOATNAME(Plane)::
get_num_components() const {
return 4;
}
////////////////////////////////////////////////////////////////////
// Function: Plane::output
// Access: Public
@ -223,12 +263,18 @@ write(ostream &out, int indent_level) const {
// Description:
////////////////////////////////////////////////////////////////////
INLINE_MATHUTIL void FLOATNAME(Plane)::
write_datagram(Datagram &dest)
{
write_datagram(Datagram &dest) const {
#if FLOATTOKEN == 'f'
dest.add_float32(_a);
dest.add_float32(_b);
dest.add_float32(_c);
dest.add_float32(_d);
#else
dest.add_float64(_a);
dest.add_float64(_b);
dest.add_float64(_c);
dest.add_float64(_d);
#endif
}
////////////////////////////////////////////////////////////////////
@ -237,10 +283,16 @@ write_datagram(Datagram &dest)
// Description:
////////////////////////////////////////////////////////////////////
INLINE_MATHUTIL void FLOATNAME(Plane)::
read_datagram(DatagramIterator &source)
{
read_datagram(DatagramIterator &source) {
#if FLOATTOKEN == 'f'
_a = source.get_float32();
_b = source.get_float32();
_c = source.get_float32();
_d = source.get_float32();
#else
_a = source.get_float64();
_b = source.get_float64();
_c = source.get_float64();
_d = source.get_float64();
#endif
}

View File

@ -24,10 +24,13 @@ class EXPCL_PANDA FLOATNAME(Plane) {
PUBLISHED:
INLINE_MATHUTIL FLOATNAME(Plane)(void);
INLINE_MATHUTIL FLOATNAME(Plane)(const FLOATNAME(Plane) &copy);
INLINE_MATHUTIL FLOATNAME(Plane)(const FLOATNAME(LPoint3) &a, const FLOATNAME(LPoint3) &b,
const FLOATNAME(LPoint3) &c);
INLINE_MATHUTIL FLOATNAME(Plane)(const FLOATNAME(LPoint3) &a,
const FLOATNAME(LPoint3) &b,
const FLOATNAME(LPoint3) &c);
INLINE_MATHUTIL FLOATNAME(Plane)(const FLOATNAME(LVector3) &normal,
const FLOATNAME(LPoint3) &point);
const FLOATNAME(LPoint3) &point);
INLINE_MATHUTIL FLOATNAME(Plane)(FLOATTYPE a, FLOATTYPE b,
FLOATTYPE c, FLOATTYPE d);
INLINE_MATHUTIL FLOATNAME(Plane)& operator = (const FLOATNAME(Plane)& copy);
@ -47,11 +50,14 @@ PUBLISHED:
const FLOATNAME(LPoint3) &from,
const FLOATNAME(LVector3) &delta) const;
INLINE_MATHUTIL const FLOATTYPE *get_data() const;
INLINE_MATHUTIL int get_num_components() const;
INLINE_MATHUTIL void output(ostream &out) const;
INLINE_MATHUTIL void write(ostream &out, int indent_level = 0) const;
public:
INLINE_MATHUTIL void write_datagram(Datagram &dest);
INLINE_MATHUTIL void write_datagram(Datagram &dest) const;
INLINE_MATHUTIL void read_datagram(DatagramIterator &source);
public:

View File

@ -14,6 +14,7 @@
billboardEffect.I billboardEffect.h \
binCullHandler.I binCullHandler.h \
camera.I camera.h \
clipPlaneAttrib.I clipPlaneAttrib.h \
colorAttrib.I colorAttrib.h \
colorBlendAttrib.I colorBlendAttrib.h \
colorScaleAttrib.I colorScaleAttrib.h \
@ -64,6 +65,7 @@
nodePathComponent.I nodePathComponent.h \
nodePathLerps.h \
pandaNode.I pandaNode.h \
planeNode.I planeNode.h \
pointLight.I pointLight.h \
renderAttrib.I renderAttrib.h \
renderEffect.I renderEffect.h \
@ -93,6 +95,7 @@
billboardEffect.cxx \
binCullHandler.cxx \
camera.cxx \
clipPlaneAttrib.cxx \
colorAttrib.cxx \
colorBlendAttrib.cxx \
colorScaleAttrib.cxx \
@ -143,6 +146,7 @@
nodePathComponent.cxx \
nodePathLerps.cxx \
pandaNode.cxx \
planeNode.cxx \
pointLight.cxx \
renderAttrib.cxx \
renderEffect.cxx \
@ -171,6 +175,7 @@
billboardEffect.I billboardEffect.h \
binCullHandler.I binCullHandler.h \
camera.I camera.h \
clipPlaneAttrib.I clipPlaneAttrib.h \
colorAttrib.I colorAttrib.h \
colorBlendAttrib.I colorBlendAttrib.h \
colorScaleAttrib.I colorScaleAttrib.h \
@ -218,6 +223,7 @@
nodePathComponent.I nodePathComponent.h \
nodePathLerps.h \
pandaNode.I pandaNode.h \
planeNode.I planeNode.h \
pointLight.I pointLight.h \
renderAttrib.I renderAttrib.h \
renderEffect.I renderEffect.h \

View File

@ -0,0 +1,119 @@
// Filename: clipPlaneAttrib.I
// Created by: drose (11Jul02)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: ClipPlaneAttrib::Constructor
// Access: Private
// Description: Use ClipPlaneAttrib::make() to construct a new
// ClipPlaneAttrib object.
////////////////////////////////////////////////////////////////////
INLINE ClipPlaneAttrib::
ClipPlaneAttrib() {
_operation = O_set;
}
////////////////////////////////////////////////////////////////////
// Function: ClipPlaneAttrib::get_operation
// Access: Published
// Description: Returns the basic operation type of the ClipPlaneAttrib.
// If this is O_set, the planes listed here completely
// replace any planes that were already on. If this is
// O_add, the planes here are added to the set of of
// planes that were already on, and if O_remove, the
// planes here are removed from the set of planes that
// were on.
////////////////////////////////////////////////////////////////////
INLINE ClipPlaneAttrib::Operation ClipPlaneAttrib::
get_operation() const {
return _operation;
}
////////////////////////////////////////////////////////////////////
// Function: ClipPlaneAttrib::get_num_planes
// Access: Published
// Description: Returns the number of planes listed in the attribute.
////////////////////////////////////////////////////////////////////
INLINE int ClipPlaneAttrib::
get_num_planes() const {
return _planes.size();
}
////////////////////////////////////////////////////////////////////
// Function: ClipPlaneAttrib::get_plane
// Access: Published
// Description: Returns the nth planes listed in the attribute.
////////////////////////////////////////////////////////////////////
INLINE PlaneNode *ClipPlaneAttrib::
get_plane(int n) const {
nassertr(n >= 0 && n < (int)_planes.size(), (PlaneNode *)NULL);
return _planes[n];
}
////////////////////////////////////////////////////////////////////
// Function: ClipPlaneAttrib::add_plane
// Access: Published
// Description: Returns a new ClipPlaneAttrib, just like this one, but
// with the indicated plane added to the list of planes.
////////////////////////////////////////////////////////////////////
INLINE CPT(RenderAttrib) ClipPlaneAttrib::
add_plane(PlaneNode *plane) const {
if (_operation == O_remove) {
return compose(make(O_remove, plane));
} else {
return compose(make(O_add, plane));
}
}
////////////////////////////////////////////////////////////////////
// Function: ClipPlaneAttrib::remove_plane
// Access: Published
// Description: Returns a new ClipPlaneAttrib, just like this one, but
// with the indicated plane removed from the list of
// planes.
////////////////////////////////////////////////////////////////////
INLINE CPT(RenderAttrib) ClipPlaneAttrib::
remove_plane(PlaneNode *plane) const {
if (_operation == O_remove) {
return compose(make(O_add, plane));
} else {
return compose(make(O_remove, plane));
}
}
////////////////////////////////////////////////////////////////////
// Function: ClipPlaneAttrib::is_identity
// Access: Published
// Description: Returns true if this is an identity attrib: it does
// not change the set of planes in use.
////////////////////////////////////////////////////////////////////
INLINE bool ClipPlaneAttrib::
is_identity() const {
return _operation != O_set && _planes.empty();
}
////////////////////////////////////////////////////////////////////
// Function: ClipPlaneAttrib::is_all_off
// Access: Published
// Description: Returns true if this attrib turns off all planes and
// turns none on.
////////////////////////////////////////////////////////////////////
INLINE bool ClipPlaneAttrib::
is_all_off() const {
return _operation == O_set && _planes.empty();
}

View File

@ -0,0 +1,489 @@
// Filename: clipPlaneAttrib.cxx
// Created by: drose (11Jul02)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#include "clipPlaneAttrib.h"
#include "pandaNode.h"
#include "graphicsStateGuardianBase.h"
#include "bamReader.h"
#include "bamWriter.h"
#include "datagram.h"
#include "datagramIterator.h"
TypeHandle ClipPlaneAttrib::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: ClipPlaneAttrib::make_all_off
// Access: Published, Static
// Description: Constructs a new ClipPlaneAttrib object that turns off
// all planes (and hence disables planeing).
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ClipPlaneAttrib::
make_all_off() {
ClipPlaneAttrib *attrib = new ClipPlaneAttrib;
attrib->_operation = O_set;
return return_new(attrib);
}
////////////////////////////////////////////////////////////////////
// Function: ClipPlaneAttrib::make
// Access: Published, Static
// Description: Constructs a new ClipPlaneAttrib object that turns on (or
// off, according to op) the indicate plane(s).
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ClipPlaneAttrib::
make(ClipPlaneAttrib::Operation op, PlaneNode *plane) {
ClipPlaneAttrib *attrib = new ClipPlaneAttrib;
attrib->_operation = op;
attrib->_planes.push_back(plane);
return return_new(attrib);
}
////////////////////////////////////////////////////////////////////
// Function: ClipPlaneAttrib::make
// Access: Published, Static
// Description: Constructs a new ClipPlaneAttrib object that turns on (or
// off, according to op) the indicate plane(s).
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ClipPlaneAttrib::
make(ClipPlaneAttrib::Operation op, PlaneNode *plane1, PlaneNode *plane2) {
ClipPlaneAttrib *attrib = new ClipPlaneAttrib;
attrib->_operation = op;
attrib->_planes.push_back(plane1);
attrib->_planes.push_back(plane2);
attrib->_planes.sort();
return return_new(attrib);
}
////////////////////////////////////////////////////////////////////
// Function: ClipPlaneAttrib::make
// Access: Published, Static
// Description: Constructs a new ClipPlaneAttrib object that turns on (or
// off, according to op) the indicate plane(s).
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ClipPlaneAttrib::
make(ClipPlaneAttrib::Operation op, PlaneNode *plane1, PlaneNode *plane2,
PlaneNode *plane3) {
ClipPlaneAttrib *attrib = new ClipPlaneAttrib;
attrib->_operation = op;
attrib->_planes.push_back(plane1);
attrib->_planes.push_back(plane2);
attrib->_planes.push_back(plane3);
attrib->_planes.sort();
return return_new(attrib);
}
////////////////////////////////////////////////////////////////////
// Function: ClipPlaneAttrib::make
// Access: Published, Static
// Description: Constructs a new ClipPlaneAttrib object that turns on (or
// off, according to op) the indicate plane(s).
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ClipPlaneAttrib::
make(ClipPlaneAttrib::Operation op, PlaneNode *plane1, PlaneNode *plane2,
PlaneNode *plane3, PlaneNode *plane4) {
ClipPlaneAttrib *attrib = new ClipPlaneAttrib;
attrib->_operation = op;
attrib->_planes.push_back(plane1);
attrib->_planes.push_back(plane2);
attrib->_planes.push_back(plane3);
attrib->_planes.push_back(plane4);
attrib->_planes.sort();
return return_new(attrib);
}
////////////////////////////////////////////////////////////////////
// Function: ClipPlaneAttrib::has_plane
// Access: Published
// Description: Returns true if the indicated plane is listed in the
// attrib, false otherwise.
////////////////////////////////////////////////////////////////////
bool ClipPlaneAttrib::
has_plane(PlaneNode *plane) const {
return _planes.find(plane) != _planes.end();
}
////////////////////////////////////////////////////////////////////
// Function: ClipPlaneAttrib::issue
// Access: Public, Virtual
// Description: Calls the appropriate method on the indicated GSG
// to issue the graphics commands appropriate to the
// given attribute. This is normally called
// (indirectly) only from
// GraphicsStateGuardian::set_state() or modify_state().
////////////////////////////////////////////////////////////////////
void ClipPlaneAttrib::
issue(GraphicsStateGuardianBase *gsg) const {
gsg->issue_clip_plane(this);
}
////////////////////////////////////////////////////////////////////
// Function: ClipPlaneAttrib::output
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
void ClipPlaneAttrib::
output(ostream &out) const {
out << get_type() << ":";
if (_operation == O_set && _planes.empty()) {
out << "all off";
} else {
switch (_operation) {
case O_set:
out << "set";
break;
case O_add:
out << "add";
break;
case O_remove:
out << "remove";
break;
}
Planes::const_iterator li;
for (li = _planes.begin(); li != _planes.end(); ++li) {
PlaneNode *plane = (*li);
out << " " << *plane;
}
}
}
////////////////////////////////////////////////////////////////////
// Function: ClipPlaneAttrib::compare_to_impl
// Access: Protected, Virtual
// Description: Intended to be overridden by derived ClipPlaneAttrib
// types to return a unique number indicating whether
// this ClipPlaneAttrib is equivalent to the other one.
//
// This should return 0 if the two ClipPlaneAttrib objects
// are equivalent, a number less than zero if this one
// should be sorted before the other one, and a number
// greater than zero otherwise.
//
// This will only be called with two ClipPlaneAttrib
// objects whose get_type() functions return the same.
////////////////////////////////////////////////////////////////////
int ClipPlaneAttrib::
compare_to_impl(const RenderAttrib *other) const {
const ClipPlaneAttrib *ta;
DCAST_INTO_R(ta, other, 0);
if (_operation != ta->_operation) {
return (int)_operation - (int)ta->_operation;
}
Planes::const_iterator li = _planes.begin();
Planes::const_iterator oli = ta->_planes.begin();
while (li != _planes.end() && oli != ta->_planes.end()) {
PlaneNode *plane = (*li);
PlaneNode *other_plane = (*oli);
if (plane != other_plane) {
return plane < other_plane ? -1 : 1;
}
++li;
++oli;
}
if (li != _planes.end()) {
return 1;
}
if (oli != ta->_planes.end()) {
return -1;
}
return 0;
}
////////////////////////////////////////////////////////////////////
// Function: ClipPlaneAttrib::compose_impl
// Access: Protected, Virtual
// Description: Intended to be overridden by derived RenderAttrib
// types to specify how two consecutive RenderAttrib
// objects of the same type interact.
//
// This should return the result of applying the other
// RenderAttrib to a node in the scene graph below this
// RenderAttrib, which was already applied. In most
// cases, the result is the same as the other
// RenderAttrib (that is, a subsequent RenderAttrib
// completely replaces the preceding one). On the other
// hand, some kinds of RenderAttrib (for instance,
// ColorTransformAttrib) might combine in meaningful
// ways.
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ClipPlaneAttrib::
compose_impl(const RenderAttrib *other) const {
const ClipPlaneAttrib *ta;
DCAST_INTO_R(ta, other, 0);
if (ta->_operation == O_set) {
// If the other type is O_set, it doesn't matter what we are.
return ta;
}
if (_operation == ta->_operation) {
// If the operation types match, the composition is simply the
// union.
return do_add(ta, _operation);
} else if (ta->_operation == O_remove) {
// If the other operation type is remove, and our type is add or
// set, then remove.
return do_remove(ta, _operation);
} else if (_operation == O_remove) {
// If our type is remove, then the other one wins.
return ta;
} else {
// Otherwise, the result is the union.
return do_add(ta, _operation);
}
}
////////////////////////////////////////////////////////////////////
// Function: ClipPlaneAttrib::invert_compose_impl
// Access: Protected, Virtual
// Description: Intended to be overridden by derived RenderAttrib
// types to specify how two consecutive RenderAttrib
// objects of the same type interact.
//
// See invert_compose() and compose_impl().
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ClipPlaneAttrib::
invert_compose_impl(const RenderAttrib *other) const {
// I think in this case the other attrib always wins. Maybe this
// needs a bit more thought. It's hard to imagine that it's even
// important to compute this properly.
return other;
}
////////////////////////////////////////////////////////////////////
// Function: ClipPlaneAttrib::make_default_impl
// Access: Protected, Virtual
// Description: Intended to be overridden by derived ClipPlaneAttrib
// types to specify what the default property for a
// ClipPlaneAttrib of this type should be.
//
// This should return a newly-allocated ClipPlaneAttrib of
// the same type that corresponds to whatever the
// standard default for this kind of ClipPlaneAttrib is.
////////////////////////////////////////////////////////////////////
RenderAttrib *ClipPlaneAttrib::
make_default_impl() const {
return new ClipPlaneAttrib;
}
////////////////////////////////////////////////////////////////////
// Function: ClipPlaneAttrib::do_add
// Access: Private
// Description: Returns a new ClipPlaneAttrib that represents all the
// planes of this attrib, with those of the other one
// added in.
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ClipPlaneAttrib::
do_add(const ClipPlaneAttrib *other, ClipPlaneAttrib::Operation op) const {
Planes::const_iterator ai = _planes.begin();
Planes::const_iterator bi = other->_planes.begin();
// Create a new ClipPlaneAttrib that will hold the result.
ClipPlaneAttrib *new_attrib = new ClipPlaneAttrib;
new_attrib->_operation = op;
back_insert_iterator<Planes> result =
back_inserter(new_attrib->_planes);
while (ai != _planes.end() && bi != other->_planes.end()) {
if ((*ai) < (*bi)) {
// Here is a plane that we have in the original, which is not
// present in the secondary.
*result = *ai;
++ai;
++result;
} else if ((*bi) < (*ai)) {
// Here is a new plane we have in the secondary, that was not
// present in the original.
*result = *bi;
++bi;
++result;
} else {
// Here is a plane we have in both.
*result = *ai;
++ai;
++bi;
++result;
}
}
while (ai != _planes.end()) {
*result = *ai;
++ai;
++result;
}
while (bi != other->_planes.end()) {
*result = *bi;
++bi;
++result;
}
return return_new(new_attrib);
}
////////////////////////////////////////////////////////////////////
// Function: ClipPlaneAttrib::do_remove
// Access: Private
// Description: Returns a new ClipPlaneAttrib that represents all the
// planes of this attrib, with those of the other one
// removed.
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ClipPlaneAttrib::
do_remove(const ClipPlaneAttrib *other, ClipPlaneAttrib::Operation op) const {
Planes::const_iterator ai = _planes.begin();
Planes::const_iterator bi = other->_planes.begin();
// Create a new ClipPlaneAttrib that will hold the result.
ClipPlaneAttrib *new_attrib = new ClipPlaneAttrib;
new_attrib->_operation = op;
back_insert_iterator<Planes> result =
back_inserter(new_attrib->_planes);
while (ai != _planes.end() && bi != other->_planes.end()) {
if ((*ai) < (*bi)) {
// Here is a plane that we have in the original, which is
// not present in the secondary. Keep it.
*result = *ai;
++ai;
++result;
} else if ((*bi) < (*ai)) {
// Here is a new plane we have in the secondary, that was
// not present in the original. Ignore it.
++bi;
} else {
// Here is a plane we have in both. Drop it.
++ai;
++bi;
}
}
while (ai != _planes.end()) {
*result = *ai;
++ai;
++result;
}
return return_new(new_attrib);
}
////////////////////////////////////////////////////////////////////
// Function: ClipPlaneAttrib::register_with_read_factory
// Access: Public, Static
// Description: Tells the BamReader how to create objects of type
// ClipPlaneAttrib.
////////////////////////////////////////////////////////////////////
void ClipPlaneAttrib::
register_with_read_factory() {
BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
}
////////////////////////////////////////////////////////////////////
// Function: ClipPlaneAttrib::write_datagram
// Access: Public, Virtual
// Description: Writes the contents of this object to the datagram
// for shipping out to a Bam file.
////////////////////////////////////////////////////////////////////
void ClipPlaneAttrib::
write_datagram(BamWriter *manager, Datagram &dg) {
RenderAttrib::write_datagram(manager, dg);
dg.add_int8((int)_operation);
PN_uint16 num_planes = _planes.size();
nassertv(num_planes == _planes.size());
dg.add_uint16(num_planes);
Planes::const_iterator li;
for (li = _planes.begin(); li != _planes.end(); ++li) {
PlaneNode *plane = (*li);
manager->write_pointer(dg, plane);
}
}
////////////////////////////////////////////////////////////////////
// Function: ClipPlaneAttrib::complete_pointers
// Access: Public, Virtual
// Description: Receives an array of pointers, one for each time
// manager->read_pointer() was called in fillin().
// Returns the number of pointers processed.
////////////////////////////////////////////////////////////////////
int ClipPlaneAttrib::
complete_pointers(TypedWritable **p_list, BamReader *manager) {
int pi = RenderAttrib::complete_pointers(p_list, manager);
Planes::iterator li;
for (li = _planes.begin(); li != _planes.end(); ++li) {
PlaneNode *node;
DCAST_INTO_R(node, p_list[pi++], pi);
(*li) = node;
}
return pi;
}
////////////////////////////////////////////////////////////////////
// Function: ClipPlaneAttrib::make_from_bam
// Access: Protected, Static
// Description: This function is called by the BamReader's factory
// when a new object of type ClipPlaneAttrib is encountered
// in the Bam file. It should create the ClipPlaneAttrib
// and extract its information from the file.
////////////////////////////////////////////////////////////////////
TypedWritable *ClipPlaneAttrib::
make_from_bam(const FactoryParams &params) {
ClipPlaneAttrib *attrib = new ClipPlaneAttrib;
DatagramIterator scan;
BamReader *manager;
parse_params(params, scan, manager);
attrib->fillin(scan, manager);
return attrib;
}
////////////////////////////////////////////////////////////////////
// Function: ClipPlaneAttrib::fillin
// Access: Protected
// Description: This internal function is called by make_from_bam to
// read in all of the relevant data from the BamFile for
// the new ClipPlaneAttrib.
////////////////////////////////////////////////////////////////////
void ClipPlaneAttrib::
fillin(DatagramIterator &scan, BamReader *manager) {
RenderAttrib::fillin(scan, manager);
_operation = (Operation)scan.get_int8();
int num_planes = scan.get_uint16();
for (int i = 0; i < num_planes; i++) {
manager->read_pointer(scan);
_planes.push_back(NULL);
}
}

View File

@ -0,0 +1,120 @@
// Filename: clipPlaneAttrib.h
// Created by: drose (11Jul02)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#ifndef CLIPPINGPLANEATTRIB_H
#define CLIPPINGPLANEATTRIB_H
#include "pandabase.h"
#include "planeNode.h"
#include "renderAttrib.h"
#include "ordered_vector.h"
////////////////////////////////////////////////////////////////////
// Class : ClipPlaneAttrib
// Description : This functions similarly to a LightAttrib. It
// indicates the set of clipping planes that modify the
// geometry at this level and below. A ClipPlaneAttrib
// can either add planes or remove planes from the total
// set of clipping planes in effect.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA ClipPlaneAttrib : public RenderAttrib {
private:
INLINE ClipPlaneAttrib();
PUBLISHED:
enum Operation {
O_set,
O_add,
O_remove
};
static CPT(RenderAttrib) make_all_off();
static CPT(RenderAttrib) make(Operation op,
PlaneNode *plane);
static CPT(RenderAttrib) make(Operation op,
PlaneNode *plane1, PlaneNode *plane2);
static CPT(RenderAttrib) make(Operation op,
PlaneNode *plane1, PlaneNode *plane2,
PlaneNode *plane3);
static CPT(RenderAttrib) make(Operation op,
PlaneNode *plane1, PlaneNode *plane2,
PlaneNode *plane3, PlaneNode *plane4);
INLINE Operation get_operation() const;
INLINE int get_num_planes() const;
INLINE PlaneNode *get_plane(int n) const;
bool has_plane(PlaneNode *plane) const;
INLINE CPT(RenderAttrib) add_plane(PlaneNode *plane) const;
INLINE CPT(RenderAttrib) remove_plane(PlaneNode *plane) const;
INLINE bool is_identity() const;
INLINE bool is_all_off() const;
public:
virtual void issue(GraphicsStateGuardianBase *gsg) const;
virtual void output(ostream &out) const;
protected:
virtual int compare_to_impl(const RenderAttrib *other) const;
virtual CPT(RenderAttrib) compose_impl(const RenderAttrib *other) const;
virtual CPT(RenderAttrib) invert_compose_impl(const RenderAttrib *other) const;
virtual RenderAttrib *make_default_impl() const;
private:
CPT(RenderAttrib) do_add(const ClipPlaneAttrib *other, Operation op) const;
CPT(RenderAttrib) do_remove(const ClipPlaneAttrib *other, Operation op) const;
private:
Operation _operation;
typedef ov_set< PT(PlaneNode) > Planes;
Planes _planes;
public:
static void register_with_read_factory();
virtual void write_datagram(BamWriter *manager, Datagram &dg);
virtual int complete_pointers(TypedWritable **plist, BamReader *manager);
protected:
static TypedWritable *make_from_bam(const FactoryParams &params);
void fillin(DatagramIterator &scan, BamReader *manager);
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
RenderAttrib::init_type();
register_type(_type_handle, "ClipPlaneAttrib",
RenderAttrib::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 "clipPlaneAttrib.I"
#endif

View File

@ -22,6 +22,7 @@
#include "ambientLight.h"
#include "billboardEffect.h"
#include "camera.h"
#include "clipPlaneAttrib.h"
#include "colorAttrib.h"
#include "colorBlendAttrib.h"
#include "colorScaleAttrib.h"
@ -58,6 +59,7 @@
#include "nodePath.h"
#include "nodePathComponent.h"
#include "pandaNode.h"
#include "planeNode.h"
#include "pointLight.h"
#include "renderAttrib.h"
#include "renderEffect.h"
@ -160,6 +162,7 @@ init_libpgraph() {
AmbientLight::init_type();
BillboardEffect::init_type();
Camera::init_type();
ClipPlaneAttrib::init_type();
ColorAttrib::init_type();
ColorBlendAttrib::init_type();
ColorScaleAttrib::init_type();
@ -195,6 +198,7 @@ init_libpgraph() {
NodePath::init_type();
NodePathComponent::init_type();
PandaNode::init_type();
PlaneNode::init_type();
PointLight::init_type();
RenderAttrib::init_type();
RenderEffect::init_type();
@ -225,6 +229,7 @@ init_libpgraph() {
AmbientLight::register_with_read_factory();
BillboardEffect::register_with_read_factory();
Camera::register_with_read_factory();
ClipPlaneAttrib::register_with_read_factory();
ColorAttrib::register_with_read_factory();
ColorBlendAttrib::register_with_read_factory();
ColorScaleAttrib::register_with_read_factory();
@ -246,6 +251,7 @@ init_libpgraph() {
ModelNode::register_with_read_factory();
ModelRoot::register_with_read_factory();
PandaNode::register_with_read_factory();
PlaneNode::register_with_read_factory();
PointLight::register_with_read_factory();
RenderEffects::register_with_read_factory();
RenderModeAttrib::register_with_read_factory();

View File

@ -3,6 +3,7 @@
#include "billboardEffect.cxx"
#include "binCullHandler.cxx"
#include "camera.cxx"
#include "clipPlaneAttrib.cxx"
#include "colorAttrib.cxx"
#include "colorBlendAttrib.cxx"
#include "colorScaleAttrib.cxx"

View File

@ -16,6 +16,7 @@
#include "nodePathComponent.cxx"
#include "nodePathLerps.cxx"
#include "pandaNode.cxx"
#include "planeNode.cxx"
#include "pointLight.cxx"
#include "renderAttrib.cxx"
#include "renderEffect.cxx"

View File

@ -0,0 +1,63 @@
// Filename: planeNode.I
// Created by: drose (11Jul02)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: PlaneNode::CData::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE PlaneNode::CData::
CData() {
// The default plane (perpendicular to the Z-axis) is used until
// another one is specified explicitly.
}
////////////////////////////////////////////////////////////////////
// Function: PlaneNode::CData::Copy Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE PlaneNode::CData::
CData(const PlaneNode::CData &copy) :
_plane(copy._plane)
{
}
////////////////////////////////////////////////////////////////////
// Function: set_plane
// Access: Public
// Description: Sets the particular plane represented by the
// PlaneNode.
////////////////////////////////////////////////////////////////////
INLINE void PlaneNode::
set_plane(const Planef &plane) {
CDWriter cdata(_cycler);
cdata->_plane = plane;
}
////////////////////////////////////////////////////////////////////
// Function: get_plane
// Access: Public
// Description: Returns the plane represented by the PlaneNode.
////////////////////////////////////////////////////////////////////
INLINE const Planef &PlaneNode::
get_plane() const {
CDReader cdata(_cycler);
return cdata->_plane;
}

View File

@ -0,0 +1,187 @@
// Filename: planeNode.cxx
// Created by: drose (11Jul02)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#include "planeNode.h"
#include "geometricBoundingVolume.h"
#include "bamWriter.h"
#include "bamReader.h"
#include "datagram.h"
#include "datagramIterator.h"
TypeHandle PlaneNode::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: PlaneNode::CData::make_copy
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
CycleData *PlaneNode::CData::
make_copy() const {
return new CData(*this);
}
////////////////////////////////////////////////////////////////////
// Function: PlaneNode::CData::write_datagram
// Access: Public, Virtual
// Description: Writes the contents of this object to the datagram
// for shipping out to a Bam file.
////////////////////////////////////////////////////////////////////
void PlaneNode::CData::
write_datagram(BamWriter *, Datagram &dg) const {
_plane.write_datagram(dg);
}
////////////////////////////////////////////////////////////////////
// Function: PlaneNode::CData::fillin
// Access: Public, Virtual
// Description: This internal function is called by make_from_bam to
// read in all of the relevant data from the BamFile for
// the new Light.
////////////////////////////////////////////////////////////////////
void PlaneNode::CData::
fillin(DatagramIterator &scan, BamReader *) {
_plane.read_datagram(scan);
}
////////////////////////////////////////////////////////////////////
// Function: PlaneNode::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
PlaneNode::
PlaneNode(const string &name) :
PandaNode(name)
{
}
////////////////////////////////////////////////////////////////////
// Function: PlaneNode::Copy Constructor
// Access: Protected
// Description:
////////////////////////////////////////////////////////////////////
PlaneNode::
PlaneNode(const PlaneNode &copy) :
PandaNode(copy),
_cycler(copy._cycler)
{
}
////////////////////////////////////////////////////////////////////
// Function: PlaneNode::make_copy
// Access: Public, Virtual
// Description: Returns a newly-allocated Node that is a shallow copy
// of this one. It will be a different Node pointer,
// but its internal data may or may not be shared with
// that of the original Node.
////////////////////////////////////////////////////////////////////
PandaNode *PlaneNode::
make_copy() const {
return new PlaneNode(*this);
}
////////////////////////////////////////////////////////////////////
// Function: PlaneNode::xform
// Access: Public, Virtual
// Description: Transforms the contents of this PandaNode by the
// indicated matrix, if it means anything to do so. For
// most kinds of PandaNodes, this does nothing.
////////////////////////////////////////////////////////////////////
void PlaneNode::
xform(const LMatrix4f &mat) {
PandaNode::xform(mat);
CDWriter cdata(_cycler);
cdata->_plane = cdata->_plane * mat;
}
////////////////////////////////////////////////////////////////////
// Function: PlaneNode::output
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
void PlaneNode::
output(ostream &out) const {
PandaNode::output(out);
out << " " << get_plane();
}
////////////////////////////////////////////////////////////////////
// Function: PlaneNode::write
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
void PlaneNode::
write(ostream &out, int indent_level) const {
PandaNode::write(out, indent_level);
get_plane().write(out, indent_level + 2);
}
////////////////////////////////////////////////////////////////////
// Function: PlaneNode::register_with_read_factory
// Access: Public, Static
// Description: Tells the BamReader how to create objects of type
// PlaneNode.
////////////////////////////////////////////////////////////////////
void PlaneNode::
register_with_read_factory() {
BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
}
////////////////////////////////////////////////////////////////////
// Function: PlaneNode::write_datagram
// Access: Public, Virtual
// Description: Writes the contents of this object to the datagram
// for shipping out to a Bam file.
////////////////////////////////////////////////////////////////////
void PlaneNode::
write_datagram(BamWriter *manager, Datagram &dg) {
PandaNode::write_datagram(manager, dg);
manager->write_cdata(dg, _cycler);
}
////////////////////////////////////////////////////////////////////
// Function: PlaneNode::make_from_bam
// Access: Protected, Static
// Description: This function is called by the BamReader's factory
// when a new object of type PlaneNode is encountered
// in the Bam file. It should create the PlaneNode
// and extract its information from the file.
////////////////////////////////////////////////////////////////////
TypedWritable *PlaneNode::
make_from_bam(const FactoryParams &params) {
PlaneNode *node = new PlaneNode("");
DatagramIterator scan;
BamReader *manager;
parse_params(params, scan, manager);
node->fillin(scan, manager);
return node;
}
////////////////////////////////////////////////////////////////////
// Function: PlaneNode::fillin
// Access: Protected
// Description: This internal function is called by make_from_bam to
// read in all of the relevant data from the BamFile for
// the new PlaneNode.
////////////////////////////////////////////////////////////////////
void PlaneNode::
fillin(DatagramIterator &scan, BamReader *manager) {
PandaNode::fillin(scan, manager);
manager->read_cdata(scan, _cycler);
}

View File

@ -0,0 +1,96 @@
// Filename: planeNode.h
// Created by: drose (11Jul02)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#ifndef PLANENODE_H
#define PLANENODE_H
#include "pandabase.h"
#include "plane.h"
#include "pandaNode.h"
////////////////////////////////////////////////////////////////////
// Class : PlaneNode
// Description : A node that contains a plane. This is most often
// used as a clipping plane, but it can serve other
// purposes as well; whenever a plane is needed to be
// defined in some coordinate space in the world.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA PlaneNode : public PandaNode {
PUBLISHED:
PlaneNode(const string &name);
protected:
PlaneNode(const PlaneNode &copy);
public:
virtual void output(ostream &out) const;
virtual void write(ostream &out, int indent_level = 0) const;
virtual PandaNode *make_copy() const;
virtual void xform(const LMatrix4f &mat);
PUBLISHED:
INLINE void set_plane(const Planef &plane);
INLINE const Planef &get_plane() const;
private:
// This is the data that must be cycled between pipeline stages.
class EXPCL_PANDA CData : public CycleData {
public:
INLINE CData();
INLINE CData(const CData &copy);
virtual CycleData *make_copy() const;
virtual void write_datagram(BamWriter *manager, Datagram &dg) const;
virtual void fillin(DatagramIterator &scan, BamReader *manager);
Planef _plane;
};
PipelineCycler<CData> _cycler;
typedef CycleDataReader<CData> CDReader;
typedef CycleDataWriter<CData> CDWriter;
public:
static void register_with_read_factory();
virtual void write_datagram(BamWriter *manager, Datagram &dg);
protected:
static TypedWritable *make_from_bam(const FactoryParams &params);
void fillin(DatagramIterator &scan, BamReader *manager);
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
PandaNode::init_type();
register_type(_type_handle, "PlaneNode",
PandaNode::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 "planeNode.I"
#endif