00001 // Filename: geomLinestrips.cxx 00002 // Created by: drose (22Mar05) 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 "geomLinestrips.h" 00016 #include "geomLines.h" 00017 #include "geomVertexRewriter.h" 00018 #include "pStatTimer.h" 00019 #include "bamReader.h" 00020 #include "bamWriter.h" 00021 #include "graphicsStateGuardianBase.h" 00022 00023 TypeHandle GeomLinestrips::_type_handle; 00024 00025 //////////////////////////////////////////////////////////////////// 00026 // Function: GeomLinestrips::Constructor 00027 // Access: Published 00028 // Description: 00029 //////////////////////////////////////////////////////////////////// 00030 GeomLinestrips:: 00031 GeomLinestrips(GeomLinestrips::UsageHint usage_hint) : 00032 GeomPrimitive(usage_hint) 00033 { 00034 } 00035 00036 //////////////////////////////////////////////////////////////////// 00037 // Function: GeomLinestrips::Copy Constructor 00038 // Access: Published 00039 // Description: 00040 //////////////////////////////////////////////////////////////////// 00041 GeomLinestrips:: 00042 GeomLinestrips(const GeomLinestrips ©) : 00043 GeomPrimitive(copy) 00044 { 00045 } 00046 00047 //////////////////////////////////////////////////////////////////// 00048 // Function: GeomLinestrips::Destructor 00049 // Access: Published, Virtual 00050 // Description: 00051 //////////////////////////////////////////////////////////////////// 00052 GeomLinestrips:: 00053 ~GeomLinestrips() { 00054 } 00055 00056 //////////////////////////////////////////////////////////////////// 00057 // Function: GeomLinestrips::make_copy 00058 // Access: Public, Virtual 00059 // Description: 00060 //////////////////////////////////////////////////////////////////// 00061 PT(GeomPrimitive) GeomLinestrips:: 00062 make_copy() const { 00063 return new GeomLinestrips(*this); 00064 } 00065 00066 //////////////////////////////////////////////////////////////////// 00067 // Function: GeomLinestrips::get_primitive_type 00068 // Access: Public, Virtual 00069 // Description: Returns the fundamental rendering type of this 00070 // primitive: whether it is points, lines, or polygons. 00071 // 00072 // This is used to set up the appropriate antialiasing 00073 // settings when AntialiasAttrib::M_auto is in effect; 00074 // it also implies the type of primitive that will be 00075 // produced when decompose() is called. 00076 //////////////////////////////////////////////////////////////////// 00077 GeomPrimitive::PrimitiveType GeomLinestrips:: 00078 get_primitive_type() const { 00079 return PT_lines; 00080 } 00081 00082 //////////////////////////////////////////////////////////////////// 00083 // Function: GeomLinestrips::get_geom_rendering 00084 // Access: Published, Virtual 00085 // Description: Returns the set of GeomRendering bits that represent 00086 // the rendering properties required to properly render 00087 // this primitive. 00088 //////////////////////////////////////////////////////////////////// 00089 int GeomLinestrips:: 00090 get_geom_rendering() const { 00091 if (is_indexed()) { 00092 return GR_line_strip | GR_indexed_other; 00093 } else { 00094 return GR_line_strip; 00095 } 00096 } 00097 00098 //////////////////////////////////////////////////////////////////// 00099 // Function: GeomLinestrips::get_min_num_vertices_per_primitive 00100 // Access: Public, Virtual 00101 // Description: Returns the minimum number of vertices that must be 00102 // added before close_primitive() may legally be called. 00103 //////////////////////////////////////////////////////////////////// 00104 int GeomLinestrips:: 00105 get_min_num_vertices_per_primitive() const { 00106 return 2; 00107 } 00108 00109 //////////////////////////////////////////////////////////////////// 00110 // Function: GeomLinestrips::draw 00111 // Access: Public, Virtual 00112 // Description: Calls the appropriate method on the GSG to draw the 00113 // primitive. 00114 //////////////////////////////////////////////////////////////////// 00115 bool GeomLinestrips:: 00116 draw(GraphicsStateGuardianBase *gsg, const GeomPrimitivePipelineReader *reader, 00117 bool force) const { 00118 return gsg->draw_linestrips(reader, force); 00119 } 00120 00121 //////////////////////////////////////////////////////////////////// 00122 // Function: GeomLinestrips::decompose_impl 00123 // Access: Protected, Virtual 00124 // Description: Decomposes a complex primitive type into a simpler 00125 // primitive type, for instance line strips to 00126 // lines, and returns a pointer to the new primitive 00127 // definition. If the decomposition cannot be 00128 // performed, this might return the original object. 00129 // 00130 // This method is useful for application code that wants 00131 // to iterate through the set of lines on the 00132 // primitive without having to write handlers for each 00133 // possible kind of primitive type. 00134 //////////////////////////////////////////////////////////////////// 00135 CPT(GeomPrimitive) GeomLinestrips:: 00136 decompose_impl() const { 00137 PT(GeomLines) lines = new GeomLines(get_usage_hint()); 00138 lines->set_shade_model(get_shade_model()); 00139 CPTA_int ends = get_ends(); 00140 00141 int vi = 0; 00142 int li = 0; 00143 while (li < (int)ends.size()) { 00144 int end = ends[li]; 00145 nassertr(vi + 1 <= end, lines.p()); 00146 int v0 = get_vertex(vi); 00147 ++vi; 00148 while (vi < end) { 00149 int v1 = get_vertex(vi); 00150 ++vi; 00151 lines->add_vertex(v0); 00152 lines->add_vertex(v1); 00153 v0 = v1; 00154 lines->close_primitive(); 00155 } 00156 ++li; 00157 } 00158 nassertr(vi == get_num_vertices(), NULL); 00159 00160 return lines.p(); 00161 } 00162 00163 //////////////////////////////////////////////////////////////////// 00164 // Function: GeomLinestrips::rotate_impl 00165 // Access: Protected, Virtual 00166 // Description: The virtual implementation of do_rotate(). 00167 //////////////////////////////////////////////////////////////////// 00168 CPT(GeomVertexArrayData) GeomLinestrips:: 00169 rotate_impl() const { 00170 // To rotate a line strip, we just reverse the vertices. 00171 CPTA_int ends = get_ends(); 00172 PT(GeomVertexArrayData) new_vertices = make_index_data(); 00173 new_vertices->set_num_rows(get_num_vertices()); 00174 00175 if (is_indexed()) { 00176 CPT(GeomVertexArrayData) vertices = get_vertices(); 00177 GeomVertexReader from(vertices, 0); 00178 GeomVertexWriter to(new_vertices, 0); 00179 00180 int begin = 0; 00181 CPTA_int::const_iterator ei; 00182 for (ei = ends.begin(); ei != ends.end(); ++ei) { 00183 int end = (*ei); 00184 for (int vi = end - 1; vi >= begin; --vi) { 00185 from.set_row_unsafe(vi); 00186 to.set_data1i(from.get_data1i()); 00187 } 00188 begin = end; 00189 } 00190 00191 nassertr(to.is_at_end(), NULL); 00192 00193 } else { 00194 // Nonindexed case. 00195 int first_vertex = get_first_vertex(); 00196 GeomVertexWriter to(new_vertices, 0); 00197 00198 int begin = 0; 00199 CPTA_int::const_iterator ei; 00200 for (ei = ends.begin(); ei != ends.end(); ++ei) { 00201 int end = (*ei); 00202 for (int vi = end - 1; vi >= begin; --vi) { 00203 to.set_data1i(vi + first_vertex); 00204 } 00205 begin = end; 00206 } 00207 00208 nassertr(to.is_at_end(), NULL); 00209 } 00210 return new_vertices; 00211 } 00212 00213 //////////////////////////////////////////////////////////////////// 00214 // Function: GeomLinestrips::register_with_read_factory 00215 // Access: Public, Static 00216 // Description: Tells the BamReader how to create objects of type 00217 // Geom. 00218 //////////////////////////////////////////////////////////////////// 00219 void GeomLinestrips:: 00220 register_with_read_factory() { 00221 BamReader::get_factory()->register_factory(get_class_type(), make_from_bam); 00222 } 00223 00224 //////////////////////////////////////////////////////////////////// 00225 // Function: GeomLinestrips::make_from_bam 00226 // Access: Protected, Static 00227 // Description: This function is called by the BamReader's factory 00228 // when a new object of type Geom is encountered 00229 // in the Bam file. It should create the Geom 00230 // and extract its information from the file. 00231 //////////////////////////////////////////////////////////////////// 00232 TypedWritable *GeomLinestrips:: 00233 make_from_bam(const FactoryParams ¶ms) { 00234 GeomLinestrips *object = new GeomLinestrips(UH_unspecified); 00235 DatagramIterator scan; 00236 BamReader *manager; 00237 00238 parse_params(params, scan, manager); 00239 object->fillin(scan, manager); 00240 00241 return object; 00242 }