Dear all,
 
Here is a simple fix for an error in the Cylinder class of the current svn 
trunk version of osgOcean. Yesterday's revision 156 introduced member vars for 
the Cylinder (_radius, _steps, etc.) but these were not initialized in the 
Cylinder constructor, resulting in uninitialized vars being passed to the 
build() method, resulting in a bad_alloc crash :-)
 
Kind regards,
 
Ruben Smelik
 
This e-mail and its contents are subject to the DISCLAIMER at 
http://www.tno.nl/disclaimer/email.html
/*
* This source file is part of the osgOcean library
* 
* Copyright (C) 2009 Kim Bale
* Copyright (C) 2009 The University of Hull, UK
* 
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free 
Software
* Foundation; either version 3 of the License, or (at your option) any later
* version.

* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 
details.
* http://www.gnu.org/copyleft/lesser.txt.
*/

#include <osgOcean/Cylinder>

using namespace osgOcean;

Cylinder::Cylinder( void )
{
}

Cylinder::Cylinder( float radius, float height, unsigned int steps, bool isTop, 
bool isBottom  ) :
        _radius(radius),
        _height(height),
        _steps(steps), 
        _isTop(isTop),
        _isBottom(isBottom)
{
        build();
}

Cylinder::Cylinder( const Cylinder& copy, const osg::CopyOp& copyop ):
        osg::Geometry   (copy, copyop),
    _radius         (copy._radius),
    _height         (copy._height),
    _steps          (copy._steps),
    _isTop          (copy._isTop),
    _isBottom       (copy._isBottom)
{
}

Cylinder::~Cylinder(void)
{
}

void Cylinder::build( float radius, float height, unsigned int steps, bool top, 
bool bottom )
{
    _radius = radius;
    _height = height;
    _steps = steps;
    _isTop = top;
    _isBottom = bottom;

        build();
}

void Cylinder::build( void )
{
    // clear primitives if there are any
    if(getNumPrimitiveSets() > 0)
    {
        removePrimitiveSet(0,getNumPrimitiveSets());
        dirtyDisplayList();
    }

        const float twoPI = osg::PI * 2.f;
        const float angleInc = twoPI / (float)_steps;

        osg::Vec3Array* vertices = new osg::Vec3Array();

        vertices->push_back( osg::Vec3f() );    // bottom centre

        for ( float angle = 0.f; angle <= twoPI; angle += angleInc )
        {
                float x1 = _radius * cos(angle);
                float y1 = _radius * sin(angle);

                vertices->push_back( osg::Vec3( x1, y1, 0.f ) );
                vertices->push_back( osg::Vec3( x1, y1, _height ) );
        }

        vertices->push_back( osg::Vec3f(0.f, 0.f, _height) );   // top centre

        osg::DrawElementsUInt* indices = 
                new osg::DrawElementsUInt( osg::PrimitiveSet::TRIANGLE_STRIP, 0 
);

        for(unsigned int c = 1; c < _steps*2+1; c += 2 )
        {       
                indices->push_back( c   );
                indices->push_back( c+1 );
        }

        indices->push_back(1);
        indices->push_back(2);

        addPrimitiveSet( indices );

        if( _isBottom )
        {
                osg::DrawElementsUInt* fanIndices = 
                        new osg::DrawElementsUInt( 
osg::PrimitiveSet::TRIANGLE_FAN, 0 );

                fanIndices->push_back( 0 );

                for(int c = _steps*2-1; c >= 1; c -= 2 )
                {       
                        fanIndices->push_back( c );
                }

                fanIndices->push_back( _steps*2-1 );

                addPrimitiveSet( fanIndices );
        }

        if( _isTop )
        {
                osg::DrawElementsUInt* fanIndices = 
                        new osg::DrawElementsUInt( 
osg::PrimitiveSet::TRIANGLE_FAN, 0 );

                fanIndices->push_back( vertices->size()-1 );

                for(int c = _steps*2; c >= 1; c -= 2 )
                {       
                        fanIndices->push_back( c );
                }

                fanIndices->push_back( _steps*2 );

                addPrimitiveSet( fanIndices );
        }

        _colorArray = new osg::Vec4Array(1);
        (*_colorArray)[0]=osg::Vec4( 0.f, 0.f, 0.f, 1.0f );

        setVertexArray( vertices );
        setColorArray( _colorArray.get() );
        setColorBinding( osg::Geometry::BIND_OVERALL );
        setUseDisplayList(true);
}

void Cylinder::setColor(const osg::Vec4f& color)
{
        if(getColorArray())
        {
                osg::Vec4Array* colors = static_cast<osg::Vec4Array*>( 
getColorArray() );
                (*_colorArray)[0] = color;
                setColorBinding( osg::Geometry::BIND_OVERALL );
                dirtyDisplayList();
        }
}
/*
* This source file is part of the osgOcean library
* 
* Copyright (C) 2009 Kim Bale
* Copyright (C) 2009 The University of Hull, UK
* 
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free 
Software
* Foundation; either version 3 of the License, or (at your option) any later
* version.

* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 
details.
* http://www.gnu.org/copyleft/lesser.txt.
*/

#pragma once
#include <osg/Geometry>
#include <osg/Math>

namespace osgOcean
{

class Cylinder : public osg::Geometry
{
protected:
        osg::ref_ptr<osg::Vec4Array> _colorArray;

public:
        Cylinder( void );

        Cylinder( float radius, float height, unsigned int steps, bool top, 
bool bottom  );

        Cylinder(const Cylinder& copy, const osg::CopyOp& 
copyop=osg::CopyOp::SHALLOW_COPY);

protected:
        virtual ~Cylinder(void);
    float _radius;
    float _height;
    unsigned _steps;
    bool _isTop;
    bool _isBottom;

public:
        virtual void build( float radius, float height, unsigned int steps, 
bool top, bool bottom  );
        
        virtual void build( void );

        void setColor(const osg::Vec4f& color);

    inline const float getRadius( void ) const{
        return _radius;
    }

    inline const float getHeight( void ) const{
        return _height;
    }

    inline const unsigned getSteps( void ) const{
        return _steps;
    }

    inline const bool getHasTop( void ) const{
        return _isTop;
    }

    inline const bool getHasBottom( void ) const{
        return _isBottom;
    }
};

}
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to