Panda3D

Loading...
Searching...
No Matches
cLwoPolygons.cxx
Go to the documentation of this file.
1/**
2 * PANDA 3D SOFTWARE
3 * Copyright (c) Carnegie Mellon University. All rights reserved.
4 *
5 * All use of this software is subject to the terms of the revised BSD
6 * license. You should have received a copy of this license along
7 * with this source code in a file named "LICENSE."
8 *
9 * @file cLwoPolygons.cxx
10 * @author drose
11 * @date 2001-04-25
12 */
13
14#include "cLwoPolygons.h"
15#include "lwoToEggConverter.h"
16#include "cLwoPoints.h"
17#include "cLwoLayer.h"
18#include "cLwoSurface.h"
19
20#include "lwoPolygonTags.h"
21#include "lwoTags.h"
22#include "lwoDiscontinuousVertexMap.h"
23#include "eggData.h"
24#include "eggPolygon.h"
25#include "eggPoint.h"
26#include "deg_2_rad.h"
27
28 using std::string;
29
30/**
31 * Associates the indicated PolygonTags and Tags with the polygons in this
32 * chunk. This may define features such as per-polygon surfaces, parts, and
33 * smoothing groups.
34 */
35 void CLwoPolygons::
36 add_ptags(const LwoPolygonTags *lwo_ptags, const LwoTags *tags) {
37 if (_tags != nullptr && _tags != tags) {
38 nout << "Multiple Tags fields in effect on the same polygons.\n";
39 }
40 _tags = tags;
41
42 IffId type = lwo_ptags->_tag_type;
43
44 bool inserted = _ptags.insert(PTags::value_type(type, lwo_ptags)).second;
45 if (!inserted) {
46 nout << "Multiple polygon tags on the same polygons of type "
47 << type << "\n";
48
49 } else {
50 if (type == IffId("SURF")) {
51 _surf_ptags = lwo_ptags;
52 }
53 }
54}
55
56/**
57 * Associates the indicated DiscontinousVertexMap with the polygons. This can
58 * be used in conjunction with (or in place of) the VertexMap associated with
59 * the points set, to define per-polygon UV's etc.
60 */
61 void CLwoPolygons::
62 add_vmad(const LwoDiscontinuousVertexMap *lwo_vmad) {
63 IffId map_type = lwo_vmad->_map_type;
64 const string &name = lwo_vmad->_name;
65
66 bool inserted;
67 if (map_type == IffId("TXUV")) {
68 inserted =
69 _txuv.insert(VMad::value_type(name, lwo_vmad)).second;
70
71 } else {
72 return;
73 }
74
75 if (!inserted) {
76 nout << "Multiple discontinous vertex maps on the same polygons of type "
77 << map_type << " named " << name << "\n";
78 }
79}
80
81/**
82 * Returns the surface associated with the given polygon, or NULL if no
83 * surface is associated.
84 */
85 CLwoSurface *CLwoPolygons::
86 get_surface(int polygon_index) const {
87 if (_surf_ptags == nullptr) {
88 // No surface definitions.
89 return nullptr;
90 }
91
92 if (!_surf_ptags->has_tag(polygon_index)) {
93 // The polygon isn't tagged.
94 return nullptr;
95 }
96
97 int tag_index = _surf_ptags->get_tag(polygon_index);
98 if (_tags == nullptr || tag_index < 0 ||
99 tag_index >= _tags->get_num_tags()) {
100 // The tag index is out-of-bounds.
101 nout << "Invalid polygon tag index " << tag_index << "\n";
102 return nullptr;
103 }
104
105 string tag = _tags->get_tag(tag_index);
106
107 // Now look up the surface name in the header.
108 CLwoSurface *surface = _converter->get_surface(tag);
109 if (surface == nullptr) {
110 nout << "Unknown surface " << tag << "\n";
111 return nullptr;
112 }
113
114 return surface;
115}
116
117/**
118 * Returns true if there is a UV of the indicated name associated with the
119 * given vertex of the indicated polygon, false otherwise. If true, fills in
120 * uv with the value.
121 *
122 * This performs a lookup in the optional "discontinuous" vertex mapping,
123 * which provides the ability to map different UV's per each polygon for the
124 * same vertex. If the UV is not defined here, it may also be defined in the
125 * standard vertex map, which is associated with the points themselves.
126 */
127 bool CLwoPolygons::
128 get_uv(const string &uv_name, int pi, int vi, LPoint2 &uv) const {
129 VMad::const_iterator ni = _txuv.find(uv_name);
130 if (ni == _txuv.end()) {
131 return false;
132 }
133
134 const LwoDiscontinuousVertexMap *vmad = (*ni).second;
135 if (vmad->_dimension != 2) {
136 nout << "Unexpected dimension of " << vmad->_dimension
137 << " for discontinuous UV map " << uv_name << "\n";
138 return false;
139 }
140
141 if (!vmad->has_value(pi, vi)) {
142 return false;
143 }
144
145 PTA_stdfloat value = vmad->get_value(pi, vi);
146
147 uv.set(value[0], value[1]);
148 return true;
149}
150
151/**
152 * Creates the egg structures associated with this Lightwave object.
153 */
154 void CLwoPolygons::
155 make_egg() {
156 // First, we need a temporary group to hold all of the polygons we'll
157 // create.
158 _egg_group = new EggGroup;
159
160 if (_polygons->_polygon_type == IffId("CURV")) {
161 nout << "Ignoring Catmull-Rom splines.\n";
162
163 } else if (_polygons->_polygon_type == IffId("PTCH")) {
164 nout << "Treating subdivision patches as ordinary polygons.\n";
165 make_faces();
166
167 } else if (_polygons->_polygon_type == IffId("MBAL")) {
168 nout << "Ignoring metaballs.\n";
169
170 } else if (_polygons->_polygon_type == IffId("BONE")) {
171 nout << "Ignoring bones.\n";
172
173 } else if (_polygons->_polygon_type == IffId("FACE")) {
174 make_faces();
175
176 } else {
177 nout << "Ignoring unknown geometry type " << _polygons->_polygon_type
178 << ".\n";
179 }
180}
181
182/**
183 * Connects all the egg structures together.
184 */
185 void CLwoPolygons::
186 connect_egg() {
187 nassertv(_points->_layer->_egg_group != nullptr);
188 nassertv(_egg_group != nullptr);
189 _points->_layer->_egg_group->steal_children(*_egg_group);
190}
191
192
193/**
194 * Generates "face" polygons, i.e. actual polygons.
195 */
196 void CLwoPolygons::
197make_faces() {
198 PN_stdfloat smooth_angle = -1.0;
199
200 int num_polygons = _polygons->get_num_polygons();
201 for (int pindex = 0; pindex < num_polygons; pindex++) {
202 LwoPolygons::Polygon *poly = _polygons->get_polygon(pindex);
203 CLwoSurface *surface = get_surface(pindex);
204
205 bool is_valid = true;
206
207 // Set up the vertices.
208 const LwoPoints *points = _points->_points;
209 int num_points = points->get_num_points();
210 EggVertexPool *egg_vpool = _points->_egg_vpool;
211
212 // We reverse the vertex ordering to compensate for Lightwave's clockwise
213 // ordering convention. We also want to start with the last vertex, so
214 // that the first convex angle is the first angle in the EggPolygon (for
215 // determining correct normals).
216 PT(EggPrimitive) egg_prim;
217
218 if (poly->_vertices.size() == 1) {
219 egg_prim = new EggPoint;
220 } else {
221 egg_prim = new EggPolygon;
222 }
223
224 // First, we have to create a temporary vector of vertices for the
225 // polygon, so we can possibly adjust the properties of these vertices
226 // (like the UV's) in the shader before we create them.
227 vector_PT_EggVertex egg_vertices;
228
229 int num_vertices = poly->_vertices.size();
230 for (int vi = num_vertices; vi > 0; vi--) {
231 int vindex = poly->_vertices[vi % num_vertices];
232 if (vindex < 0 || vindex >= num_points) {
233 nout << "Invalid vertex index " << vindex << " in polygon.\n";
234 is_valid = false;
235 } else {
236 PT(EggVertex) egg_vertex = new EggVertex;
237 LPoint3d pos = LCAST(double, points->get_point(vindex));
238 egg_vertex->set_pos(pos);
239
240 // Does the vertex used named UV's?
241 if (surface != nullptr && surface->has_named_uvs()) {
242 string uv_name = surface->get_uv_name();
243 LPoint2 uv;
244 if (get_uv(uv_name, pindex, vindex, uv)) {
245 // This UV is defined in a "discontinuous" map, that associated a
246 // particular UV per each polygon.
247 egg_vertex->set_uv(LCAST(double, uv));
248
249 } else if (_points->get_uv(uv_name, vindex, uv)) {
250 // The UV does not appear in a discontinuous map, but it is
251 // defined in the points set.
252 egg_vertex->set_uv(LCAST(double, uv));
253 }
254 }
255
256 egg_vertices.push_back(egg_vertex);
257 }
258 }
259
260 if (is_valid) {
261 if (surface != nullptr) {
262 surface->apply_properties(egg_prim, egg_vertices, smooth_angle);
263 }
264
265 // Now add all the vertices officially to the primitive.
266 vector_PT_EggVertex::const_iterator evi;
267 for (evi = egg_vertices.begin(); evi != egg_vertices.end(); ++evi) {
268 EggVertex *egg_vertex = (*evi);
269 EggVertex *new_vertex = egg_vpool->create_unique_vertex(*egg_vertex);
270 egg_prim->add_vertex(new_vertex);
271 }
272
273 // And add the primitive to its parent.
274 _egg_group->add_child(egg_prim.p());
275 }
276 }
277
278 CoordinateSystem cs = _converter->get_egg_data()->get_coordinate_system();
279 if (smooth_angle > 0.0) {
280 _egg_group->recompute_vertex_normals(rad_2_deg(smooth_angle), cs);
281 } else {
282 _egg_group->recompute_polygon_normals(cs);
283 }
284}
cLwoLayer.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
cLwoPoints.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
cLwoPolygons.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
cLwoSurface.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
CLwoPolygons::make_egg
void make_egg()
Creates the egg structures associated with this Lightwave object.
Definition cLwoPolygons.cxx:155
CLwoPolygons::get_uv
bool get_uv(const std::string &uv_name, int pi, int vi, LPoint2 &uv) const
Returns true if there is a UV of the indicated name associated with the given vertex of the indicated...
Definition cLwoPolygons.cxx:128
CLwoPolygons::connect_egg
void connect_egg()
Connects all the egg structures together.
Definition cLwoPolygons.cxx:186
CLwoPolygons::add_vmad
void add_vmad(const LwoDiscontinuousVertexMap *lwo_vmad)
Associates the indicated DiscontinousVertexMap with the polygons.
Definition cLwoPolygons.cxx:62
CLwoPolygons::get_surface
CLwoSurface * get_surface(int polygon_index) const
Returns the surface associated with the given polygon, or NULL if no surface is associated.
Definition cLwoPolygons.cxx:86
CLwoPolygons::add_ptags
void add_ptags(const LwoPolygonTags *lwo_ptags, const LwoTags *tags)
Associates the indicated PolygonTags and Tags with the polygons in this chunk.
Definition cLwoPolygons.cxx:36
CLwoSurface
This class is a wrapper around LwoSurface and stores additional information useful during the convers...
Definition cLwoSurface.h:39
CLwoSurface::has_named_uvs
bool has_named_uvs() const
Returns true if the surface is set up to reference UV's stored on the vertices, by name (as opposed t...
Definition cLwoSurface.I:30
CLwoSurface::get_uv_name
const std::string & get_uv_name() const
Returns the name of the set of UV's that are associated with this surface, if has_named_uvs() is true...
Definition cLwoSurface.I:40
CLwoSurface::apply_properties
void apply_properties(EggPrimitive *egg_prim, vector_PT_EggVertex &egg_vertices, PN_stdfloat &smooth_angle)
Applies the color, texture, etc.
Definition cLwoSurface.cxx:162
EggGroup
The main glue of the egg hierarchy, this corresponds to the <Group>, <Instance>, and <Joint> type nod...
Definition eggGroup.h:34
EggPoint
A single point, or a collection of points as defined by a single <PointLight> entry.
Definition eggPoint.h:25
EggPrimitive
A base class for any of a number of kinds of geometry primitives: polygons, point lights,...
Definition eggPrimitive.h:49
EggVertexPool
A collection of vertices.
Definition eggVertexPool.h:41
EggVertexPool::create_unique_vertex
EggVertex * create_unique_vertex(const EggVertex &copy)
Creates a new vertex in the pool that is a copy of the indicated one and returns it.
Definition eggVertexPool.cxx:472
IffId
A four-byte chunk ID appearing in an "IFF" file.
Definition iffId.h:26
LwoDiscontinuousVertexMap
A mapping of floating-point values per integer index.
Definition lwoDiscontinuousVertexMap.h:28
LwoDiscontinuousVertexMap::has_value
bool has_value(int polygon_index, int vertex_index) const
Returns true if the map has a value associated with the given index, false otherwise.
Definition lwoDiscontinuousVertexMap.cxx:30
LwoDiscontinuousVertexMap::get_value
PTA_stdfloat get_value(int polygon_index, int vertex_index) const
Returns the mapping value associated with the given index, or an empty PTA_stdfloat if there is no ma...
Definition lwoDiscontinuousVertexMap.cxx:46
LwoPoints
An array of points that will be referenced by later chunks.
Definition lwoPoints.h:26
LwoPoints::get_num_points
int get_num_points() const
Returns the number of points of this group.
Definition lwoPoints.cxx:26
LwoPoints::get_point
const LPoint3 & get_point(int n) const
Returns the nth point of this group.
Definition lwoPoints.cxx:34
LwoPolygonTags
An association of polygons defined in the most recent LwoPolygons chunk to tag ids defined in the mos...
Definition lwoPolygonTags.h:26
LwoPolygons::Polygon
Definition lwoPolygons.h:41
LwoTags
An array of tag strings that will be referenced by later chunks.
Definition lwoTags.h:31
deg_2_rad.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
eggData.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
eggPoint.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
eggPolygon.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
lwoDiscontinuousVertexMap.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
lwoPolygonTags.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
lwoTags.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
lwoToEggConverter.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.