Panda3D
|
00001 // Filename: pgVirtualFrame.cxx 00002 // Created by: drose (17Aug05) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 #include "pgVirtualFrame.h" 00016 #include "scissorEffect.h" 00017 #include "sceneGraphReducer.h" 00018 00019 TypeHandle PGVirtualFrame::_type_handle; 00020 00021 //////////////////////////////////////////////////////////////////// 00022 // Function: PGVirtualFrame::Constructor 00023 // Access: Published 00024 // Description: 00025 //////////////////////////////////////////////////////////////////// 00026 PGVirtualFrame:: 00027 PGVirtualFrame(const string &name) : PGItem(name) 00028 { 00029 _has_clip_frame = false; 00030 _clip_frame.set(0.0f, 0.0f, 0.0f, 0.0f); 00031 00032 setup_child_nodes(); 00033 } 00034 00035 //////////////////////////////////////////////////////////////////// 00036 // Function: PGVirtualFrame::Destructor 00037 // Access: Public, Virtual 00038 // Description: 00039 //////////////////////////////////////////////////////////////////// 00040 PGVirtualFrame:: 00041 ~PGVirtualFrame() { 00042 } 00043 00044 //////////////////////////////////////////////////////////////////// 00045 // Function: PGVirtualFrame::Copy Constructor 00046 // Access: Protected 00047 // Description: 00048 //////////////////////////////////////////////////////////////////// 00049 PGVirtualFrame:: 00050 PGVirtualFrame(const PGVirtualFrame ©) : 00051 PGItem(copy), 00052 _has_clip_frame(copy._has_clip_frame), 00053 _clip_frame(copy._clip_frame) 00054 { 00055 setup_child_nodes(); 00056 00057 // Reassign the clip planes according to the clip frame. 00058 if (_has_clip_frame) { 00059 set_clip_frame(_clip_frame); 00060 } else { 00061 clear_clip_frame(); 00062 } 00063 } 00064 00065 //////////////////////////////////////////////////////////////////// 00066 // Function: PGVirtualFrame::make_copy 00067 // Access: Public, Virtual 00068 // Description: Returns a newly-allocated Node that is a shallow copy 00069 // of this one. It will be a different Node pointer, 00070 // but its internal data may or may not be shared with 00071 // that of the original Node. 00072 //////////////////////////////////////////////////////////////////// 00073 PandaNode *PGVirtualFrame:: 00074 make_copy() const { 00075 LightReMutexHolder holder(_lock); 00076 return new PGVirtualFrame(*this); 00077 } 00078 00079 //////////////////////////////////////////////////////////////////// 00080 // Function: PGVirtualFrame::r_copy_children 00081 // Access: Protected, Virtual 00082 // Description: This is called by r_copy_subgraph(); the copy has 00083 // already been made of this particular node (and this 00084 // is the copy); this function's job is to copy all of 00085 // the children from the original. 00086 // 00087 // Note that it includes the parameter inst_map, which 00088 // is a map type, and is not (and cannot be) exported 00089 // from PANDA.DLL. Thus, any derivative of PandaNode 00090 // that is not also a member of PANDA.DLL *cannot* 00091 // access this map, and probably should not even 00092 // override this function. 00093 //////////////////////////////////////////////////////////////////// 00094 void PGVirtualFrame:: 00095 r_copy_children(const PandaNode *from, PandaNode::InstanceMap &inst_map, 00096 Thread *current_thread) { 00097 LightReMutexHolder holder(_lock); 00098 PandaNode::r_copy_children(from, inst_map, current_thread); 00099 00100 // Reassign the canvas_node to point to the new copy, if it's there. 00101 const PGVirtualFrame *from_frame = DCAST(PGVirtualFrame, from); 00102 PandaNode *from_canvas_node = from_frame->get_canvas_node(); 00103 PandaNode *from_canvas_parent = from_frame->get_canvas_parent(); 00104 00105 InstanceMap::const_iterator ci; 00106 ci = inst_map.find(from_canvas_node); 00107 if (ci != inst_map.end()) { 00108 remove_child(_canvas_node); 00109 _canvas_node = DCAST(ModelNode, (*ci).second); 00110 } 00111 00112 ci = inst_map.find(from_canvas_parent); 00113 if (ci != inst_map.end()) { 00114 remove_child(_canvas_parent); 00115 _canvas_parent = DCAST(ModelNode, (*ci).second); 00116 } 00117 00118 // Reassign the clip planes according to the clip frame. 00119 if (_has_clip_frame) { 00120 set_clip_frame(_clip_frame); 00121 } else { 00122 clear_clip_frame(); 00123 } 00124 } 00125 00126 //////////////////////////////////////////////////////////////////// 00127 // Function: PGVirtualFrame::setup 00128 // Access: Published 00129 // Description: Creates a PGVirtualFrame with the indicated 00130 // dimensions. 00131 //////////////////////////////////////////////////////////////////// 00132 void PGVirtualFrame:: 00133 setup(PN_stdfloat width, PN_stdfloat height) { 00134 LightReMutexHolder holder(_lock); 00135 set_state(0); 00136 clear_state_def(0); 00137 00138 set_frame(0, width, 0, height); 00139 00140 PN_stdfloat bevel = 0.05f; 00141 00142 PGFrameStyle style; 00143 style.set_width(bevel, bevel); 00144 00145 style.set_color(0.8f, 0.8f, 0.8f, 1.0f); 00146 style.set_type(PGFrameStyle::T_bevel_out); 00147 set_frame_style(0, style); 00148 00149 set_clip_frame(bevel, width - 2 * bevel, 00150 bevel, height - 2 * bevel); 00151 } 00152 00153 //////////////////////////////////////////////////////////////////// 00154 // Function: PGVirtualFrame::set_clip_frame 00155 // Access: Published 00156 // Description: Sets the bounding rectangle of the clip frame. 00157 // This is the size of the small window through which we 00158 // can see the virtual canvas. Normally, this is the 00159 // same size as the actual frame or smaller (typically 00160 // it is smaller by the size of the bevel, or to make 00161 // room for scroll bars). 00162 //////////////////////////////////////////////////////////////////// 00163 void PGVirtualFrame:: 00164 set_clip_frame(const LVecBase4 &frame) { 00165 LightReMutexHolder holder(_lock); 00166 if (!_has_clip_frame || _clip_frame != frame) { 00167 _has_clip_frame = true; 00168 _clip_frame = frame; 00169 00170 CPT(RenderEffect) scissor_effect = ScissorEffect::make_node 00171 (LPoint3(_clip_frame[0], _clip_frame[2], _clip_frame[2]), 00172 LPoint3(_clip_frame[1], _clip_frame[2], _clip_frame[2]), 00173 LPoint3(_clip_frame[1], _clip_frame[3], _clip_frame[3]), 00174 LPoint3(_clip_frame[0], _clip_frame[3], _clip_frame[3])); 00175 00176 _canvas_parent->set_effect(scissor_effect); 00177 clip_frame_changed(); 00178 } 00179 } 00180 00181 //////////////////////////////////////////////////////////////////// 00182 // Function: PGVirtualFrame::clear_clip_frame 00183 // Access: Published 00184 // Description: Removes the clip frame from the item. This 00185 // disables clipping. 00186 //////////////////////////////////////////////////////////////////// 00187 void PGVirtualFrame:: 00188 clear_clip_frame() { 00189 LightReMutexHolder holder(_lock); 00190 if (_has_clip_frame) { 00191 _has_clip_frame = false; 00192 00193 _canvas_parent->clear_effect(ScissorEffect::get_class_type()); 00194 clip_frame_changed(); 00195 } 00196 } 00197 00198 //////////////////////////////////////////////////////////////////// 00199 // Function: PGVirtualFrame::clip_frame_changed 00200 // Access: Protected, Virtual 00201 // Description: Called when the user changes the clip_frame size. 00202 //////////////////////////////////////////////////////////////////// 00203 void PGVirtualFrame:: 00204 clip_frame_changed() { 00205 } 00206 00207 //////////////////////////////////////////////////////////////////// 00208 // Function: PGVirtualFrame::setup_child_nodes 00209 // Access: Private 00210 // Description: Creates the special canvas_node and canvas_parent 00211 // for this object. 00212 //////////////////////////////////////////////////////////////////// 00213 void PGVirtualFrame:: 00214 setup_child_nodes() { 00215 _canvas_parent = new ModelNode("canvas_parent"); 00216 _canvas_parent->set_preserve_transform(ModelNode::PT_local); 00217 add_child(_canvas_parent); 00218 00219 _canvas_node = new ModelNode("canvas"); 00220 _canvas_node->set_preserve_transform(ModelNode::PT_local); 00221 _canvas_parent->add_child(_canvas_node); 00222 }