Panda3D
 All Classes Functions Variables Enumerations
lineSegs.cxx
00001 // Filename: lineSegs.cxx
00002 // Created by:  drose (16Mar02)
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 "lineSegs.h"
00016 #include "renderState.h"
00017 #include "renderModeAttrib.h"
00018 #include "geom.h"
00019 #include "geomLinestrips.h"
00020 #include "geomPoints.h"
00021 #include "geomVertexReader.h"
00022 #include "geomVertexWriter.h"
00023 
00024 ////////////////////////////////////////////////////////////////////
00025 //     Function: LineSegs::Constructor
00026 //       Access: Public
00027 //  Description: Constructs a LineSegs object, which can be used to
00028 //               create any number of disconnected lines or points of
00029 //               various thicknesses and colors through the visible
00030 //               scene.  After creating the object, call move_to() and
00031 //               draw_to() repeatedly to describe the path, then call
00032 //               create() to create a GeomNode which will render the
00033 //               described path.
00034 ////////////////////////////////////////////////////////////////////
00035 LineSegs::
00036 LineSegs(const string &name) : Namable(name) {
00037   _color.set(1.0f, 1.0f, 1.0f, 1.0f);
00038   _thick = 1.0f;
00039 }
00040 
00041 
00042 ////////////////////////////////////////////////////////////////////
00043 //     Function: LineSegs::Destructor
00044 //       Access: Public
00045 ////////////////////////////////////////////////////////////////////
00046 LineSegs::
00047 ~LineSegs() {
00048 }
00049 
00050 
00051 ////////////////////////////////////////////////////////////////////
00052 //     Function: LineSegs::reset
00053 //       Access: Public
00054 //  Description: Removes any lines in progress and resets to the
00055 //               initial empty state.
00056 ////////////////////////////////////////////////////////////////////
00057 void LineSegs::
00058 reset() {
00059   _list.clear();
00060 }
00061 
00062 
00063 ////////////////////////////////////////////////////////////////////
00064 //     Function: LineSegs::move_to
00065 //       Access: Public
00066 //  Description: Moves the pen to the given point without drawing a
00067 //               line.  When followed by draw_to(), this marks the
00068 //               first point of a line segment; when followed by
00069 //               move_to() or create(), this creates a single point.
00070 ////////////////////////////////////////////////////////////////////
00071 void LineSegs::
00072 move_to(const LVecBase3 &v) {
00073   // We create a new SegmentList with the initial point in it.
00074   SegmentList segs;
00075   segs.push_back(Point(v, _color));
00076 
00077   // And add this list to the list of segments.
00078   _list.push_back(segs);
00079 }
00080 
00081 ////////////////////////////////////////////////////////////////////
00082 //     Function: LineSegs::draw_to
00083 //       Access: Public
00084 //  Description: Draws a line segment from the pen's last position
00085 //               (the last call to move_to or draw_to) to the
00086 //               indicated point.  move_to() and draw_to() only update
00087 //               tables; the actual drawing is performed when create()
00088 //               is called.
00089 ////////////////////////////////////////////////////////////////////
00090 void LineSegs::
00091 draw_to(const LVecBase3 &v) {
00092   if (_list.empty()) {
00093     // Let our first call to draw_to() be an implicit move_to().
00094     move_to(v);
00095 
00096   } else {
00097     // Get the current SegmentList, which was the last one we added to
00098     // the LineList.
00099     SegmentList &segs = _list.back();
00100 
00101     // Add the new point.
00102     segs.push_back(Point(v, _color));
00103   }
00104 }
00105 
00106 ////////////////////////////////////////////////////////////////////
00107 //     Function: LineSegs::empty
00108 //       Access: Public
00109 //  Description: Returns true if move_to() or draw_to() have not been
00110 //               called since the last reset() or create(), false
00111 //               otherwise.
00112 ////////////////////////////////////////////////////////////////////
00113 bool LineSegs::
00114 is_empty() {
00115   return _list.empty();
00116 }
00117 
00118 ////////////////////////////////////////////////////////////////////
00119 //     Function: LineSegs::get_vertex
00120 //       Access: Public
00121 //  Description: Returns the nth point or vertex of the line segment
00122 //               sequence generated by the last call to create().  The
00123 //               first move_to() generates vertex 0; subsequent
00124 //               move_to() and draw_to() calls generate consecutively
00125 //               higher vertex numbers.
00126 ////////////////////////////////////////////////////////////////////
00127 LVertex LineSegs::
00128 get_vertex(int n) const {
00129   nassertr(_created_data != (GeomVertexData *)NULL, LVertex::zero());
00130   GeomVertexReader vertex(_created_data, InternalName::get_vertex());
00131   vertex.set_row_unsafe(n);
00132   return vertex.get_data3();
00133 }
00134 
00135 ////////////////////////////////////////////////////////////////////
00136 //     Function: LineSegs::set_vertex
00137 //       Access: Public
00138 //  Description: Moves the nth point or vertex of the line segment
00139 //               sequence generated by the last call to create().  The
00140 //               first move_to() generates vertex 0; subsequent
00141 //               move_to() and draw_to() calls generate consecutively
00142 //               higher vertex numbers.
00143 ////////////////////////////////////////////////////////////////////
00144 void LineSegs::
00145 set_vertex(int n, const LVertex &vert) {
00146   nassertv(_created_data != (GeomVertexData *)NULL);
00147   GeomVertexWriter vertex(_created_data, InternalName::get_vertex());
00148   vertex.set_row_unsafe(n);
00149   vertex.set_data3(vert);
00150 }
00151 
00152 ////////////////////////////////////////////////////////////////////
00153 //     Function: LineSegs::get_vertex_color
00154 //       Access: Public
00155 //  Description: Returns the color of the nth point or vertex.
00156 ////////////////////////////////////////////////////////////////////
00157 LColor LineSegs::
00158 get_vertex_color(int n) const {
00159   nassertr(_created_data != (GeomVertexData *)NULL, LColor::zero());
00160   GeomVertexReader color(_created_data, InternalName::get_color());
00161   color.set_row_unsafe(n);
00162   return color.get_data4();
00163 }
00164 
00165 ////////////////////////////////////////////////////////////////////
00166 //     Function: LineSegs::set_vertex_color
00167 //       Access: Public
00168 //  Description: Changes the vertex color of the nth point or vertex.
00169 //               See set_vertex().
00170 ////////////////////////////////////////////////////////////////////
00171 void LineSegs::
00172 set_vertex_color(int n, const LColor &c) {
00173   nassertv(_created_data != (GeomVertexData *)NULL);
00174   GeomVertexWriter color(_created_data, InternalName::get_color());
00175   color.set_row_unsafe(n);
00176   color.set_data4(c);
00177 }
00178 
00179 ////////////////////////////////////////////////////////////////////
00180 //     Function: LineSegs::get_current_position
00181 //       Access: Public
00182 //  Description: Returns the pen's current position.  The next call to
00183 //               draw_to() will draw a line segment from this point.
00184 ////////////////////////////////////////////////////////////////////
00185 const LVertex &LineSegs::
00186 get_current_position() {
00187   if (_list.empty()) {
00188     // Our pen isn't anywhere.  We'll put it somewhere.
00189     move_to(LVertex(0.0f, 0.0f, 0.0f));
00190   }
00191 
00192   return _list.back().back()._point;
00193 }
00194 
00195 ////////////////////////////////////////////////////////////////////
00196 //     Function: LineSegs::create
00197 //       Access: Public
00198 //  Description: Appends to an existing GeomNode a new Geom that
00199 //               will render the series of line segments and points
00200 //               described via calls to move_to() and draw_to().  The
00201 //               lines and points are created with the color and
00202 //               thickness established by calls to set_color() and
00203 //               set_thick().
00204 //
00205 //               If dynamic is true, the line segments will be created
00206 //               with the dynamic Geom setting, optimizing them for
00207 //               runtime vertex animation.
00208 ////////////////////////////////////////////////////////////////////
00209 GeomNode *LineSegs::
00210 create(GeomNode *previous, bool dynamic) {
00211   if (!_list.empty()) {
00212     CPT(RenderAttrib) thick = RenderModeAttrib::make(RenderModeAttrib::M_unchanged, _thick);
00213     CPT(RenderAttrib) vtxcolor = ColorAttrib::make_vertex();
00214     CPT(RenderState) state = RenderState::make(thick, vtxcolor);
00215 
00216     _created_data = new GeomVertexData
00217       ("lineSegs", GeomVertexFormat::get_v3cp(),
00218        dynamic ? Geom::UH_dynamic : Geom::UH_static);
00219     GeomVertexWriter vertex(_created_data, InternalName::get_vertex());
00220     GeomVertexWriter color(_created_data, InternalName::get_color());
00221     
00222     PT(GeomLinestrips) lines = new GeomLinestrips(Geom::UH_static);
00223     PT(GeomPoints) points = new GeomPoints(Geom::UH_static);
00224     
00225     int v = 0;
00226     LineList::const_iterator ll;
00227     SegmentList::const_iterator sl;
00228     
00229     for (ll = _list.begin(); ll != _list.end(); ll++) {
00230       const SegmentList &segs = (*ll);
00231       
00232       if (segs.size() < 2) {
00233         // A segment of length 1 is just a point.
00234         for (sl = segs.begin(); sl != segs.end(); sl++) {
00235           points->add_vertex(v);
00236           vertex.add_data3((*sl)._point);
00237           color.add_data4((*sl)._color);
00238           v++;
00239         }
00240         points->close_primitive();
00241         
00242       } else {
00243         // A segment of length 2 or more is a line segment or
00244         // segments.
00245         for (sl = segs.begin(); sl != segs.end(); sl++) {
00246           lines->add_vertex(v);
00247           vertex.add_data3((*sl)._point);
00248           color.add_data4((*sl)._color);
00249           v++;
00250         }
00251         lines->close_primitive();
00252       }
00253     }
00254 
00255     if (lines->get_num_vertices() != 0) {
00256       PT(Geom) geom = new Geom(_created_data);
00257       geom->add_primitive(lines);
00258       previous->add_geom(geom, state);
00259     }
00260     if (points->get_num_vertices() != 0) {
00261       PT(Geom) geom = new Geom(_created_data);
00262       geom->add_primitive(points);
00263       previous->add_geom(geom, state);
00264     }
00265     
00266     // And reset for next time.
00267     reset();
00268   }
00269 
00270   return previous;
00271 }
 All Classes Functions Variables Enumerations