fixed: auto_ptr -> unique_ptr
[opensg.git] / Source / System / NodeCores / Drawables / Geometry / Util / OSGSimpleLightGeometry.cpp
blobb9acfa602f29e4eedcf099d59efacb7b45224727
1 /*---------------------------------------------------------------------------*\
2 * OpenSG *
3 * *
4 * *
5 * Copyright (C) 2000-2002 by the OpenSG Forum *
6 * *
7 * contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de *
8 * *
9 \*---------------------------------------------------------------------------*/
10 /*---------------------------------------------------------------------------*\
11 * License *
12 * *
13 * This library is free software; you can redistribute it and/or modify it *
14 * under the terms of the GNU Library General Public License as published *
15 * by the Free Software Foundation, version 2. *
16 * *
17 * This library is distributed in the hope that it will be useful, but *
18 * WITHOUT ANY WARRANTY; without even the implied warranty of *
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
20 * Library General Public License for more details. *
21 * *
22 * You should have received a copy of the GNU Library General Public *
23 * License along with this library; if not, write to the Free Software *
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
25 * *
26 \*---------------------------------------------------------------------------*/
27 /*---------------------------------------------------------------------------*\
28 * Changes *
29 * *
30 * *
31 * *
32 * *
33 * *
34 * *
35 \*---------------------------------------------------------------------------*/
37 #ifdef WIN32
38 #pragma warning( disable : 4305 )
39 #endif
41 //---------------------------------------------------------------------------
42 // Includes
43 //---------------------------------------------------------------------------
45 #include <cstdlib>
46 #include <cstdio>
48 #include "OSGConfig.h"
49 #include "OSGLog.h"
50 #include "OSGFrustumVolume.h"
51 #include "OSGQuaternion.h"
52 #include "OSGMaterial.h"
53 #include "OSGSimpleMaterial.h"
54 #include "OSGLineChunk.h"
55 #include "OSGGeoProperties.h"
56 #include "OSGSimpleLightGeometry.h" // for DefaultMaterials
57 #include "OSGTypedGeoIntegralProperty.h"
58 #include "OSGTypedGeoVectorProperty.h"
60 OSG_BEGIN_NAMESPACE
62 /***************************************************************************\
63 * Description *
64 \***************************************************************************/
66 #if defined(OSG_WIN32_ICL) && !defined(OSG_CHECK_FIELDSETARG)
67 #pragma warning (disable : 383)
68 #endif
70 // The Simple Light Geometry creation functions
73 // Attention: the created geometry from these functions do not contain
74 // texture coordinates.
77 /*! Creates a spot light with spot direction in +y-direction with the tip
78 of the spot at (0,0,0).
80 \param[in] R is the spot range/radius of influence
81 \param[in] angle is the spot half angle in radians
82 \param[in] slices is the number of subdivisions in y-Dir, i.e. in spot direction
83 \param[in] sides is the number of circle subdivisions
84 \return NodeTransitPtr to a newly created Node with a Geometry core.
86 \ingroup GrpDrawablesGeometryUtils
88 NodeTransitPtr makeSpot(
89 Real32 R,
90 Real32 angle,
91 UInt32 slices,
92 UInt32 sides)
94 GeometryTransitPtr pGeo = makeSpotGeo(R, angle, slices, sides);
96 if(pGeo == NULL)
98 return NodeTransitPtr(NULL);
101 NodeTransitPtr node = Node::create();
103 node->setCore(pGeo);
105 return node;
108 /*! Creates a spot light geometry with spot direction in +y-direction with the tip
109 of the spot at (0,0,0).
111 \param[in] R is the spot range/radius of influence
112 \param[in] angle is the spot half angle in radians
113 \param[in] slices is the number of subdivisions in y-Dir, i.e. in spot direction
114 \param[in] sides is the number of circle subdivisions
115 \return GeometryTransitPtr to a newly created Geometry core.
117 \ingroup GrpDrawablesGeometryUtils
119 GeometryTransitPtr makeSpotGeo(
120 Real32 R,
121 Real32 angle,
122 UInt32 slices,
123 UInt32 sides)
125 if(R <= 0 || angle <= 0)
127 SWARNING << "makeSpotGeo: illegal geometric parameters R=" << R
128 << ", angle=" << angle
129 << std::endl;
130 return GeometryTransitPtr(NULL);
133 if(! slices || ! sides)
135 SWARNING << "makeSpotGeo: illegal subdivision parameters slices=" << slices << ", sides="
136 << sides << std::endl;
137 return GeometryTransitPtr(NULL);
140 GeoUInt8PropertyRefPtr types = GeoUInt8Property::create();
141 GeoUInt32PropertyRefPtr lens = GeoUInt32Property::create();
142 GeoPnt3fPropertyRefPtr pnts = GeoPnt3fProperty::create();
143 GeoVec3fPropertyRefPtr norms = GeoVec3fProperty::create();
145 GeoUInt8Property::StoredFieldType *t = types->editFieldPtr();
146 GeoUInt32Property::StoredFieldType *l = lens ->editFieldPtr();
147 GeoPnt3fProperty::StoredFieldType *p = pnts ->editFieldPtr();
148 GeoVec3fProperty::StoredFieldType *n = norms->editFieldPtr();
150 // get even slices and sides
151 if ( (slices & 1) == 1 )
152 slices += 1;
154 if ( (sides & 1) == 1 )
155 sides += 1;
157 Real32 a_cone = angle;
158 Real32 h_cone = R * osgCos(a_cone);
159 Real32 d_cone = h_cone / slices;
161 Real32 delta_phi = 2.f * Pi / (sides-1);
163 Vec3f ey(0,1,0);
165 typedef std::vector<Pnt3f> VecPntsT;
167 VecPntsT vecOddPnts(sides), vecEvenPnts(sides);
168 VecPntsT* pvecLast = &vecOddPnts;
169 VecPntsT* pvecCurr = &vecEvenPnts;
172 // First the cone itself
174 std::vector<Vec3f> vecNormals(sides);
175 for (UInt32 i = 0; i < sides; ++i)
177 Real32 phi = i * delta_phi;
179 vecNormals[i] = -Vec3f(osgCos(a_cone) * osgCos(phi), osgSin(a_cone), osgCos(a_cone) * osgSin(phi));
182 Pnt3f pT(0,0,0); // tip of spot cone
184 (*pvecLast)[0] = pT;
186 for (UInt32 j = 1; j <= slices; ++j)
188 Real32 l_cone = j * d_cone;
189 Real32 r_cone = l_cone * osgTan(a_cone);
191 Pnt3f pR = pT + l_cone * ey;
193 // Real32 d_phi = (j & 0) ? delta_phi : delta_phi + delta_phi/2.f;
195 Real32 phi = (j & 0) ? 0 : delta_phi/2.f;
197 for (UInt32 i = 0; i < sides-1; ++i)
199 phi += delta_phi;
200 (*pvecCurr)[i] = pR + r_cone * Vec3f(osgSin(phi), 0, -osgCos(phi));
203 (*pvecCurr)[sides-1] = (*pvecCurr)[0];
205 if (j == 1)
207 t->push_back(GL_TRIANGLE_FAN);
208 l->push_back(1 + sides);
210 p->push_back((*pvecLast)[0]);
211 n->push_back(Vec3f(0,-1,0));
213 for (UInt32 i = 0; i < sides; ++i)
215 p->push_back((*pvecCurr)[i]);
216 n->push_back(vecNormals[i]);
219 else
221 t->push_back(GL_TRIANGLE_STRIP);
222 l->push_back(2*sides);
224 for (UInt32 i = 0; i < sides; ++i)
226 p->push_back((*pvecLast)[i]);
227 p->push_back((*pvecCurr)[i]);
229 n->push_back(vecNormals[i]);
230 n->push_back(vecNormals[i]);
234 std::swap(pvecLast, pvecCurr);
238 // Second the sphere cap
240 Real32 d_alpha = a_cone / (slices-1);
242 for (UInt32 j = 0; j < slices; ++j)
244 if (j < slices-1)
246 Real32 da_cone = a_cone - j * d_alpha;
248 Real32 l_cone = R * osgCos(da_cone);
249 Real32 r_cone = R * osgSin(da_cone);
251 Pnt3f pj = pT + l_cone * ey;
253 Real32 phi = (j & 0) ? 0 : delta_phi/2.f;
255 for (UInt32 i = 0; i < sides-1; ++i)
257 phi += delta_phi;
258 (*pvecCurr)[i] = pj + r_cone * Vec3f(osgSin(phi), 0, -osgCos(phi));
260 Vec3f vN = (*pvecCurr)[i] - pT;
261 vN.normalize();
262 vecNormals[i] = vN;
265 (*pvecCurr)[sides-1] = (*pvecCurr)[0];
267 t->push_back(GL_TRIANGLE_STRIP);
268 l->push_back(2*sides);
270 for (UInt32 i = 0; i < sides; ++i)
272 p->push_back((*pvecLast)[i]);
273 p->push_back((*pvecCurr)[i]);
275 n->push_back(vecNormals[i]);
276 n->push_back(vecNormals[i]);
279 else
281 t->push_back(GL_TRIANGLE_FAN);
282 l->push_back(1 + sides);
284 p->push_back(pT + R * ey);
285 n->push_back(Vec3f(0,-1,0));
287 for (Int32 i = sides-1; i >= 0; --i)
289 p->push_back((*pvecLast)[i]);
290 n->push_back(vecNormals[i]);
294 std::swap(pvecLast, pvecCurr);
297 GeometryTransitPtr geo = Geometry::create();
299 geo->setTypes (types);
300 geo->setLengths (lens);
301 geo->setPositions(pnts);
302 geo->setNormals (norms);
304 geo->setMaterial(getDefaultUnlitMaterial());
306 return geo;
309 /*! Creates a cinema light with spot direction in +y-direction with the tip
310 of the spot at (0,0,0).
312 \param[in] a is the superellipses width
313 \param[in] b is the superellipses height
314 \param[in] r is the superellipses roundness parameter
315 \param[in] theta is the superellipses twist parameter in radians
316 \param[in] h is the cinema light range/radius of influence, i.e. the geometry extend along the y-axis
317 \param[in] slices is the number of subdivisions in y-Dir, i.e. in spot direction
318 \param[in] sides is the number of circle subdivisions
319 \return NodeTransitPtr to a newly created Node with a Geometry core.
321 \ingroup GrpDrawablesGeometryUtils
323 NodeTransitPtr makeCinema(
324 Real32 a,
325 Real32 b,
326 Real32 r,
327 Real32 theta,
328 Real32 h,
329 UInt32 slices,
330 UInt32 sides)
332 GeometryTransitPtr pGeo = makeCinemaGeo(a, b, r, theta, h, slices, sides);
334 if(pGeo == NULL)
336 return NodeTransitPtr(NULL);
339 NodeTransitPtr node = Node::create();
341 node->setCore(pGeo);
343 return node;
346 /*! Creates a cinema light geometry with spot direction in +y-direction with the tip
347 of the spot at (0,0,0).
349 \param[in] a is the superellipses width
350 \param[in] b is the superellipses height
351 \param[in] r is the superellipses roundness parameter
352 \param[in] theta is the superellipses twist parameter in radians
353 \param[in] h is the cinema light range/radius of influence, i.e. the geometry extend along the y-axis
354 \param[in] slices is the number of subdivisions in y-Dir, i.e. in spot direction
355 \param[in] sides is the number of circle subdivisions
356 \return GeometryTransitPtr to a Geometry core.
358 \ingroup GrpDrawablesGeometryUtils
360 GeometryTransitPtr makeCinemaGeo(
361 Real32 a,
362 Real32 b,
363 Real32 r,
364 Real32 theta,
365 Real32 h,
366 UInt32 slices,
367 UInt32 sides)
369 if(a <= 0 || b <= 0 || r <= 0 || h <= 0)
371 SWARNING << "makeCinemaGeo: illegal geometric parameters a=" << a
372 << ", b=" << b
373 << ", r=" << r
374 << ", h=" << h
375 << std::endl;
376 return GeometryTransitPtr(NULL);
379 if(! slices || ! sides)
381 SWARNING << "makeCinemaGeo: illegal subdivision parameters slices=" << slices << ", sides="
382 << sides << std::endl;
383 return GeometryTransitPtr(NULL);
386 GeoUInt8PropertyRefPtr types = GeoUInt8Property::create();
387 GeoUInt32PropertyRefPtr lens = GeoUInt32Property::create();
388 GeoPnt3fPropertyRefPtr pnts = GeoPnt3fProperty::create();
389 GeoVec3fPropertyRefPtr norms = GeoVec3fProperty::create();
391 GeoUInt8Property::StoredFieldType *t = types->editFieldPtr();
392 GeoUInt32Property::StoredFieldType *l = lens ->editFieldPtr();
393 GeoPnt3fProperty::StoredFieldType *p = pnts ->editFieldPtr();
394 GeoVec3fProperty::StoredFieldType *n = norms->editFieldPtr();
396 // get even slices and sides
397 if ( (slices & 1) == 1 )
398 slices += 1;
400 if ( (sides & 1) == 1 )
401 sides += 1;
403 Real32 cos_theta = osgCos(theta);
404 Real32 sin_theta = osgSin(theta);
406 Real32 d_body = h / slices;
408 Real32 delta_phi = 2.f * Pi / (sides-1);
410 Real32 two_inv_r = 2.0/r;
412 Vec3f ey(0,1,0);
414 typedef std::vector<Pnt3f> VecPntsT;
416 VecPntsT vecOddPnts(sides), vecEvenPnts(sides);
417 VecPntsT* pvecLast = &vecOddPnts;
418 VecPntsT* pvecCurr = &vecEvenPnts;
421 // First the superellipses body itself
423 Pnt3f pT(0,0,0); // tip of body
425 (*pvecLast)[0] = pT;
427 for (UInt32 j = 1; j <= slices; ++j)
429 Real32 l_body = j * d_body;
431 Pnt3f pR = pT + l_body * ey;
433 Real32 A = l_body * a;
434 Real32 B = l_body * b;
436 Real32 phi = 0.f;
438 for (UInt32 i = 0; i < sides-1; ++i)
440 Real32 c = osgCos(phi);
441 Real32 s = osgSin(phi);
443 Real32 x = A * osgSgn(c) * osgPow(osgAbs(c), two_inv_r);
444 Real32 z = B * osgSgn(s) * osgPow(osgAbs(s), two_inv_r);
446 Pnt3f pP = pR + Vec3f(
447 x * cos_theta - z * sin_theta,
449 x * sin_theta + z * cos_theta
452 Real32 L = pP.subZero().length();
454 if (L > h)
456 Vec3f v = pP.subZero();
457 v.normalize();
458 v *= h;
459 pP = v.addToZero();
462 (*pvecCurr)[i] = pP;
464 phi += delta_phi;
467 (*pvecCurr)[sides-1] = (*pvecCurr)[0];
469 if (j == 1)
471 t->push_back(GL_TRIANGLE_FAN);
472 l->push_back(1 + sides);
474 p->push_back((*pvecLast)[0]);
475 n->push_back(Vec3f(0,-1,0));
477 for (UInt32 i = 0; i < sides; ++i)
479 p->push_back((*pvecCurr)[i]);
481 Vec3f v0;
482 Vec3f v1;
484 if (i < sides-1)
486 v0 = (*pvecCurr)[i] - (*pvecLast)[0];
487 v1 = (*pvecCurr)[i+1] - (*pvecLast)[0];
489 else if (i == sides-1)
491 v0 = (*pvecCurr)[0] - (*pvecLast)[0];
492 v1 = (*pvecCurr)[1] - (*pvecLast)[0];
495 Vec3f v = v1.cross(v0);
496 v.normalize();
497 n->push_back(v);
500 else
502 t->push_back(GL_TRIANGLE_STRIP);
503 l->push_back(2*sides);
505 for (UInt32 i = 0; i < sides; ++i)
507 p->push_back((*pvecLast)[i]);
508 p->push_back((*pvecCurr)[i]);
510 Vec3f v0;
511 Vec3f v1;
512 Vec3f v2;
514 if (i < sides-1)
516 v0 = (*pvecLast)[i+1] - (*pvecCurr)[i];
517 v1 = (*pvecLast)[i+1] - (*pvecLast)[i];
518 v2 = (*pvecCurr)[i+1] - (*pvecLast)[i+1];
520 else if (i == sides-1)
522 v0 = (*pvecLast)[1] - (*pvecCurr)[0];
523 v1 = (*pvecLast)[1] - (*pvecLast)[0];
524 v2 = (*pvecCurr)[1] - (*pvecLast)[1];
527 Vec3f n0 = v1.cross(v0);
528 Vec3f n1 = v2.cross(v1);
530 n0.normalize();
531 n1.normalize();
533 n->push_back(n0);
534 n->push_back(n1);
538 std::swap(pvecLast, pvecCurr);
542 // Second the sphere cap
544 Real32 delta_a = a / (slices - 1);
545 Real32 delta_b = b / (slices - 1);
547 Pnt3f pE = pT + h * ey;
549 for (Int32 j = slices-2; j >= 0; --j)
551 Real32 A = h * delta_a * j;
552 Real32 B = h * delta_b * j;
554 Real32 phi = 0.f;
556 for (UInt32 i = 0; i < sides-1; ++i)
558 Real32 c = osgCos(phi);
559 Real32 s = osgSin(phi);
561 Real32 x = A * osgSgn(c) * osgPow(osgAbs(c), two_inv_r);
562 Real32 z = B * osgSgn(s) * osgPow(osgAbs(s), two_inv_r);
564 Pnt3f pP = pE + Vec3f(
565 x * cos_theta - z * sin_theta,
567 x * sin_theta + z * cos_theta
570 Real32 L = pP.subZero().length();
572 if (L > h)
574 Vec3f v = pP.subZero();
575 v.normalize();
576 v *= h;
577 pP = v.addToZero();
580 (*pvecCurr)[i] = pP;
582 phi += delta_phi;
585 (*pvecCurr)[sides-1] = (*pvecCurr)[0];
587 if (j < Int32(slices-1) && j > 0)
589 t->push_back(GL_TRIANGLE_STRIP);
590 l->push_back(2*sides);
592 for (UInt32 i = 0; i < sides; ++i)
594 p->push_back((*pvecLast)[i]);
595 p->push_back((*pvecCurr)[i]);
597 Vec3f v0;
598 Vec3f v1;
599 Vec3f v2;
601 if (i < sides-1)
603 v0 = (*pvecLast)[i+1] - (*pvecCurr)[i];
604 v1 = (*pvecLast)[i+1] - (*pvecLast)[i];
605 v2 = (*pvecCurr)[i+1] - (*pvecLast)[i+1];
607 else if (i == sides-1)
609 v0 = (*pvecLast)[1] - (*pvecCurr)[0];
610 v1 = (*pvecLast)[1] - (*pvecLast)[0];
611 v2 = (*pvecCurr)[1] - (*pvecLast)[1];
614 Vec3f n0 = v1.cross(v0);
615 Vec3f n1 = v2.cross(v1);
617 n0.normalize();
618 n1.normalize();
620 n->push_back(n0);
621 n->push_back(n1);
625 if (j == 1)
627 t->push_back(GL_TRIANGLE_FAN);
628 l->push_back(1 + sides);
630 p->push_back(pE);
631 n->push_back(Vec3f(0,1,0));
633 for (Int32 i = sides-1; i >= 0; --i)
635 p->push_back((*pvecCurr)[i]);
637 Vec3f v0;
638 Vec3f v1;
640 if (i < Int32(sides-1))
642 v0 = (*pvecCurr)[i] - pE;
643 v1 = (*pvecCurr)[i+1] - pE;
645 else if (i == Int32(sides-1))
647 v0 = (*pvecCurr)[0] - pE;
648 v1 = (*pvecCurr)[1] - pE;
651 Vec3f v = v1.cross(v0);
652 v.normalize();
653 n->push_back(v);
657 std::swap(pvecLast, pvecCurr);
660 GeometryTransitPtr geo = Geometry::create();
662 geo->setTypes (types);
663 geo->setLengths (lens);
664 geo->setPositions(pnts);
665 geo->setNormals (norms);
667 geo->setMaterial(getDefaultUnlitMaterial());
669 return geo;
672 /*! Creates a frustum volume
674 \param[in] nlt is the near left top point of the frustum
675 \param[in] nlb is the near left bottom point of the frustum
676 \param[in] nrt is the near right top point of the frustum
677 \param[in] nrb is the near right bottom point of the frustum
678 \param[in] flt is the far left top point of the frustum
679 \param[in] flb is the far left bottom point of the frustum
680 \param[in] frt is the far right top point of the frustum
681 \param[in] frb is the far right bottom point of the frustum
682 \return NodeTransitPtr to a newly created Node with a Geometry core.
684 \ingroup GrpDrawablesGeometryUtils
686 NodeTransitPtr makeFrustumVolume(
687 const Pnt3f& nlt, const Pnt3f& nlb,
688 const Pnt3f& nrt, const Pnt3f& nrb,
689 const Pnt3f& flt, const Pnt3f& flb,
690 const Pnt3f& frt, const Pnt3f& frb)
692 GeometryTransitPtr pGeo = makeFrustumVolumeGeo(nlt, nlb, nrt, nrb, flt, flb, frt, frb);
694 if(pGeo == NULL)
696 return NodeTransitPtr(NULL);
699 NodeTransitPtr node = Node::create();
701 node->setCore(pGeo);
703 return node;
706 /*! Creates a frustum volume geometry
708 \param[in] nlt is the near left top point of the frustum
709 \param[in] nlb is the near left bottom point of the frustum
710 \param[in] nrt is the near right top point of the frustum
711 \param[in] nrb is the near right bottom point of the frustum
712 \param[in] flt is the far left top point of the frustum
713 \param[in] flb is the far left bottom point of the frustum
714 \param[in] frt is the far right top point of the frustum
715 \param[in] frb is the far right bottom point of the frustum
716 \return GeometryTransitPtr to a newly created Geometry core.
718 \ingroup GrpDrawablesGeometryUtils
720 GeometryTransitPtr makeFrustumVolumeGeo(
721 const Pnt3f& nlt, const Pnt3f& nlb,
722 const Pnt3f& nrt, const Pnt3f& nrb,
723 const Pnt3f& flt, const Pnt3f& flb,
724 const Pnt3f& frt, const Pnt3f& frb)
726 GeoUInt8PropertyRefPtr type = GeoUInt8Property::create();
727 type->addValue(GL_QUADS);
729 GeoUInt32PropertyRefPtr lens = GeoUInt32Property::create();
730 lens->addValue(6 * 4);
732 GeoPnt3fPropertyRefPtr pnts = GeoPnt3fProperty::create();
733 // front face
734 pnts->addValue(nlb);
735 pnts->addValue(nrb);
736 pnts->addValue(nrt);
737 pnts->addValue(nlt);
739 // back face
740 pnts->addValue(frb);
741 pnts->addValue(flb);
742 pnts->addValue(flt);
743 pnts->addValue(frt);
745 // left face
746 pnts->addValue(flb);
747 pnts->addValue(nlb);
748 pnts->addValue(nlt);
749 pnts->addValue(flt);
751 // right face
752 pnts->addValue(nrb);
753 pnts->addValue(frb);
754 pnts->addValue(frt);
755 pnts->addValue(nrt);
757 // top face
758 pnts->addValue(nrt);
759 pnts->addValue(frt);
760 pnts->addValue(flt);
761 pnts->addValue(nlt);
763 // bottom face
764 pnts->addValue(nlb);
765 pnts->addValue(flb);
766 pnts->addValue(frb);
767 pnts->addValue(nrb);
769 GeoVec3fPropertyRefPtr normals = GeoVec3fProperty::create();
770 Vec3f v1, v2, n;
772 // front face
773 v1 = nrb - nlb; v2 = nlt - nlb; n = v1.cross(v2); n.normalize(); for (int i = 0; i < 4; ++i) normals->addValue(n);
775 // back face
776 v1 = flb - frb; v2 = frt - frb; n = v1.cross(v2); n.normalize(); for (int i = 0; i < 4; ++i) normals->addValue(n);
778 // left face
779 v1 = nlb - flb; v2 = flt - flb; n = v1.cross(v2); n.normalize(); for (int i = 0; i < 4; ++i) normals->addValue(n);
781 // right face
782 v1 = frb - nrb; v2 = nrt - nrb; n = v1.cross(v2); n.normalize(); for (int i = 0; i < 4; ++i) normals->addValue(n);
784 // top face
785 v1 = frt - nrt; v2 = nlt - nrt; n = v1.cross(v2); n.normalize(); for (int i = 0; i < 4; ++i) normals->addValue(n);
787 // bottom face
788 v1 = flb - nlb; v2 = nrb - nlb; n = v1.cross(v2); n.normalize(); for (int i = 0; i < 4; ++i) normals->addValue(n);
790 GeometryTransitPtr geo = Geometry::create();
792 geo->setTypes (type);
793 geo->setLengths (lens);
794 geo->setPositions(pnts);
795 geo->setNormals (normals);
797 geo->setMaterial(getDefaultUnlitMaterial());
799 return geo;
802 /*! Creates a frustum volume
804 \param[in] vol is frustum volume
805 \return NodeTransitPtr to a newly created Node with a Geometry core.
807 \ingroup GrpDrawablesGeometryUtils
809 NodeTransitPtr makeFrustumVolume(const FrustumVolume& vol)
811 GeometryTransitPtr pGeo = makeFrustumVolumeGeo(vol);
813 if(pGeo == NULL)
815 return NodeTransitPtr(NULL);
818 NodeTransitPtr node = Node::create();
820 node->setCore(pGeo);
822 return node;
825 /*! Creates a frustum volume geometry
827 \param[in] vol is frustum volume
828 \return GeometryTransitPtr to a newly created Geometry core.
830 \ingroup GrpDrawablesGeometryUtils
832 GeometryTransitPtr makeFrustumVolumeGeo(const FrustumVolume& vol)
834 Pnt3f nlt = vol.getCorner(FrustumVolume::NEAR_LEFT_TOP);
835 Pnt3f nlb = vol.getCorner(FrustumVolume::NEAR_LEFT_BOTTOM);
836 Pnt3f nrt = vol.getCorner(FrustumVolume::NEAR_RIGHT_TOP);
837 Pnt3f nrb = vol.getCorner(FrustumVolume::NEAR_RIGHT_BOTTOM);
838 Pnt3f flt = vol.getCorner(FrustumVolume::FAR_LEFT_TOP);
839 Pnt3f flb = vol.getCorner(FrustumVolume::FAR_LEFT_BOTTOM);
840 Pnt3f frt = vol.getCorner(FrustumVolume::FAR_RIGHT_TOP);
841 Pnt3f frb = vol.getCorner(FrustumVolume::FAR_RIGHT_BOTTOM);
843 GeometryTransitPtr geo = makeFrustumVolumeGeo(nlt, nlb, nrt, nrb, flt, flb, frt, frb);
844 return geo;
847 OSG_END_NAMESPACE