15 #include "fisheyeMaker.h" 18 #include "geomTristrips.h" 19 #include "geomVertexWriter.h" 20 #include "geomVertexFormat.h" 21 #include "geomVertexArrayFormat.h" 22 #include "internalName.h" 25 #include "mathNumbers.h" 26 #include "graphicsStateGuardian.h" 27 #include "displayRegion.h" 38 _square_inscribed =
false;
39 _square_radius = 1.0f;
53 _half_fov_rad = deg_2_rad(_fov * 0.5f);
66 int max_vertices_per_array = 100;
67 int max_vertices_per_primitive = 10000;
68 bool prefers_triangle_strips =
true;
87 PN_stdfloat vertices_per_unit = csqrt(_num_vertices / MathNumbers::pi_f);
88 PN_stdfloat two_pi = 2.0f * MathNumbers::pi_f;
92 int num_rings = (int)floor(vertices_per_unit + 0.5f);
94 CPT(GeomVertexFormat) format = GeomVertexFormat::register_format
95 (
new GeomVertexArrayFormat
96 (InternalName::get_vertex(), 3,
97 Geom::NT_stdfloat, Geom::C_point,
98 InternalName::get_texcoord(), 3,
99 Geom::NT_stdfloat, Geom::C_texcoord));
108 tristrips->set_shade_model(Geom::SM_uniform);
112 int last_ring_size = 3;
113 int last_ring_vertex = 0;
114 PN_stdfloat last_r = 1.0f / (PN_stdfloat)num_rings;
119 for (
int vi = 0; vi < last_ring_size; ++vi) {
120 add_vertex(vertex, texcoord, last_r,
121 two_pi * (PN_stdfloat)vi / (PN_stdfloat)last_ring_size);
122 tristrips->add_vertex(vi);
126 tristrips->add_vertex(2);
127 tristrips->close_primitive();
130 for (
int ri = 1; ri < num_rings; ++ri) {
131 PN_stdfloat r = (PN_stdfloat)(ri + 1) / (PN_stdfloat)num_rings;
134 PN_stdfloat c = two_pi * r;
135 int ring_size = (int)floor(c * vertices_per_unit + 0.5f);
139 if (ring_size < last_ring_size * 2) {
141 ring_size = last_ring_size;
144 ring_size = last_ring_size * 2;
147 if (vdata->get_num_rows() + ring_size > max_vertices_per_array) {
149 if (tristrips->get_num_vertices() != 0) {
150 geom->add_primitive(tristrips);
152 if (geom->get_num_primitives() != 0) {
153 if (prefers_triangle_strips) {
154 geom_node->add_geom(geom);
156 geom_node->add_geom(geom->decompose());
163 geom =
new Geom(vdata);
165 tristrips->set_shade_model(Geom::SM_uniform);
168 last_ring_vertex = 0;
169 for (
int vi = 0; vi < last_ring_size; ++vi) {
170 add_vertex(vertex, texcoord, last_r,
171 two_pi * (PN_stdfloat)vi / (PN_stdfloat)last_ring_size);
176 int ring_vertex = vdata->get_num_rows();
177 for (
int vi = 0; vi < ring_size; ++vi) {
178 add_vertex(vertex, texcoord, r,
179 two_pi * (PN_stdfloat)vi / (PN_stdfloat)ring_size);
183 if (ring_size == last_ring_size) {
185 if ((ring_size + 1) * 2 > max_vertices_per_primitive) {
188 int piece_size = max_vertices_per_primitive / 2 - 1;
190 while (vi < ring_size) {
191 int piece_end = min(ring_size + 1, piece_size + 1 + vi);
192 for (
int pi = vi; pi < piece_end; ++pi) {
193 tristrips->add_vertex(last_ring_vertex + pi % last_ring_size);
194 tristrips->add_vertex(ring_vertex + pi % ring_size);
196 tristrips->close_primitive();
202 if (tristrips->get_num_vertices() > 0 &&
203 tristrips->get_num_vertices() + ring_size * 2 > max_vertices_per_primitive) {
204 geom->add_primitive(tristrips);
206 tristrips->set_shade_model(Geom::SM_uniform);
208 for (
int vi = 0; vi < ring_size; ++vi) {
209 tristrips->add_vertex(last_ring_vertex + vi);
210 tristrips->add_vertex(ring_vertex + vi);
212 tristrips->add_vertex(last_ring_vertex);
213 tristrips->add_vertex(ring_vertex);
214 tristrips->close_primitive();
223 while (vi < last_ring_size) {
224 if (tristrips->get_num_vertices() + 10 > max_vertices_per_primitive) {
225 geom->add_primitive(tristrips);
227 tristrips->set_shade_model(Geom::SM_uniform);
229 tristrips->add_vertex(ring_vertex + (vi * 2 + 1) % ring_size);
230 tristrips->add_vertex(ring_vertex + (vi * 2 + 2) % ring_size);
231 tristrips->add_vertex(last_ring_vertex + (vi + 1) % last_ring_size);
232 tristrips->add_vertex(ring_vertex + (vi * 2 + 3) % ring_size);
233 tristrips->add_vertex(last_ring_vertex + (vi + 2) % last_ring_size);
234 tristrips->add_vertex(ring_vertex + (vi * 2 + 4) % ring_size);
235 tristrips->close_primitive();
237 tristrips->add_vertex(ring_vertex + (vi * 2 + 4) % ring_size);
238 tristrips->add_vertex(ring_vertex + (vi * 2 + 5) % ring_size);
239 tristrips->add_vertex(last_ring_vertex + (vi + 2) % last_ring_size);
240 tristrips->add_vertex(last_ring_vertex + (vi + 3) % last_ring_size);
241 tristrips->close_primitive();
247 last_ring_size = ring_size;
248 last_ring_vertex = ring_vertex;
252 if (_square_inscribed) {
254 int ring_size = last_ring_size;
256 if (vdata->get_num_rows() + ring_size > max_vertices_per_array) {
258 if (tristrips->get_num_vertices() != 0) {
259 geom->add_primitive(tristrips);
261 if (geom->get_num_primitives() != 0) {
262 if (prefers_triangle_strips) {
263 geom_node->add_geom(geom);
265 geom_node->add_geom(geom->decompose());
272 geom =
new Geom(vdata);
274 tristrips->set_shade_model(Geom::SM_uniform);
277 last_ring_vertex = 0;
278 for (
int vi = 0; vi < last_ring_size; ++vi) {
279 add_vertex(vertex, texcoord, last_r,
280 two_pi * (PN_stdfloat)vi / (PN_stdfloat)last_ring_size);
285 int ring_vertex = vdata->get_num_rows();
286 for (
int vi = 0; vi < ring_size; ++vi) {
287 add_square_vertex(vertex, texcoord,
288 two_pi * (PN_stdfloat)vi / (PN_stdfloat)ring_size);
292 if ((ring_size + 1) * 2 > max_vertices_per_primitive) {
295 int piece_size = max_vertices_per_primitive / 2 - 1;
297 while (vi < ring_size) {
298 int piece_end = min(ring_size + 1, piece_size + 1 + vi);
299 for (
int pi = vi; pi < piece_end; ++pi) {
300 tristrips->add_vertex(last_ring_vertex + pi % last_ring_size);
301 tristrips->add_vertex(ring_vertex + pi % ring_size);
303 tristrips->close_primitive();
309 if (tristrips->get_num_vertices() > 0 &&
310 tristrips->get_num_vertices() + ring_size * 2 > max_vertices_per_primitive) {
311 geom->add_primitive(tristrips);
313 tristrips->set_shade_model(Geom::SM_uniform);
315 for (
int vi = 0; vi < ring_size; ++vi) {
316 tristrips->add_vertex(last_ring_vertex + vi);
317 tristrips->add_vertex(ring_vertex + vi);
319 tristrips->add_vertex(last_ring_vertex);
320 tristrips->add_vertex(ring_vertex);
321 tristrips->close_primitive();
325 if (tristrips->get_num_vertices() != 0) {
326 geom->add_primitive(tristrips);
328 if (geom->get_num_primitives() != 0) {
329 if (prefers_triangle_strips) {
330 geom_node->add_geom(geom);
332 geom_node->add_geom(geom->decompose());
336 return geom_node.p();
349 PN_stdfloat r, PN_stdfloat a) {
350 PN_stdfloat sina, cosa;
351 csincos(a, &sina, &cosa);
355 LPoint3 point(r * cosa, 0.0f, r * sina);
360 PN_stdfloat b = r * _half_fov_rad;
361 if (b >= MathNumbers::pi_f) {
367 PN_stdfloat sinb, cosb;
368 csincos(b, &sinb, &cosb);
369 LPoint3 tc(sinb * cosa, cosb * _reflect, sinb * sina);
388 PN_stdfloat sina, cosa;
389 csincos(a, &sina, &cosa);
393 if (cabs(sina) > cabs(cosa)) {
394 PN_stdfloat y = (sina > 0.0f) ? _square_radius : -_square_radius;
395 PN_stdfloat x = y * cosa / sina;
400 PN_stdfloat x = (cosa > 0.0f) ? _square_radius : -_square_radius;
401 PN_stdfloat y = x * sina / cosa;
A basic node of the scene graph or data graph.
This object provides a high-level interface for quickly writing a sequence of numeric values from a v...
This is an abstract base class for a family of classes that represent the fundamental geometry primit...
Defines a series of triangle strips.
This is a three-component point in space (as opposed to a three-component vector, which represents a ...
void set_fov(PN_stdfloat fov)
Specifies the field of view of the fisheye projection.
This defines the actual numeric vertex data stored in a Geom, in the structure defined by a particula...
A container for geometry primitives.
void add_data3(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z)
Sets the write row to a particular 3-component value, and advances the write row. ...
void reset()
Resets all the parameters to their initial defaults.
void set_reflection(bool reflection)
Sets the flag indicating whether the texture image should be mirrored (true) or normal (false)...
A node that holds Geom objects, renderable pieces of geometry.