3 Copyright 2007 Antoine Chavasse <a.chavasse@gmail.com>
5 This file is part of Fail.
7 Fail is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License version 3
9 as published by the Free Software Foundation.
11 Fail is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include "scenegraph/shapes/Cone.h"
20 #include "scenegraph/RenderPass.h"
21 #include "scenegraph/IndexBuffer16.h"
22 #include "math/math.h"
25 using namespace fail::scenegraph
;
26 using namespace fail::scenegraph::shapes
;
28 Cone::GeometriesCache
Cone::ms_Geometries
;
30 Cone::Cone( const Pointer
< Material
>& pMaterial
,
31 const Pointer
< Frame
>& pFrame
,
32 uint16_t Subdivisions
) :
33 Shape( pMaterial
, pFrame
),
34 m_Subdivisions( Subdivisions
)
36 m_pDrawable
= new Drawable( GetGeom( Subdivisions
), m_pMaterial
, m_pFrame
);
39 Cone::Cone( const Serialization_tag
& )
47 GeometriesCache::iterator it
= ms_Geometries
.find( m_Subdivisions
);
48 if( it
!= ms_Geometries
.end() && it
->second
->getRefCount() == 1 )
49 ms_Geometries
.erase( it
);
54 m_pDrawable
= new scenegraph::Drawable( GetGeom( m_Subdivisions
), m_pMaterial
, m_pFrame
);
57 Geometry
* Cone::GetGeom( uint16_t Subdivisions
)
59 GeometriesCache::iterator it
= ms_Geometries
.find( Subdivisions
);
60 if( it
!= ms_Geometries
.end() )
63 Pointer
< VertexBuffer
> pVB
= new VertexBuffer();
64 pVB
->addAttribute( VertexBuffer::at_Vector3f
, VertexBuffer::a_Position
);
65 pVB
->addAttribute( VertexBuffer::at_Vector3f
, VertexBuffer::a_Normal
);
66 pVB
->resize( Subdivisions
* 2 // For the tristrip
67 + Subdivisions
); // For the trifan (bottom cap)
69 Pointer
< IndexBuffer16
> pIB
= new IndexBuffer16(
70 ( Subdivisions
+ 1 ) * 2
73 float anglestep
= ( math::pi
* 2.f
) / static_cast< float >( Subdivisions
);
75 float cos45
= std::cos( math::pi
/ 4.f
);
79 // To calculate the normals at the tip vertices
80 float tipAngleOffset
= anglestep
/ 2.f
;
82 for( i
= 0, angle
= 0; i
< Subdivisions
; ++i
, angle
+= anglestep
)
84 float c
= std::cos( angle
);
85 float s
= std::sin( angle
);
87 float ctip
= std::cos( angle
- tipAngleOffset
);
88 float stip
= std::sin( angle
- tipAngleOffset
);
91 pVB
->setVector3fAttribute( i
* 2 + 1, 0, math::Vector3f( c
, 0.f
, s
) );
92 pVB
->setVector3fAttribute( i
* 2 + 1, 1, math::Vector3f( c
* cos45
, cos45
, s
* cos45
) );
93 pIB
->setIndex( i
* 2, i
* 2 + 1 );
96 pVB
->setVector3fAttribute( i
* 2, 0, math::Vector3f( 0.f
, 1.f
, 0.f
) );
97 pVB
->setVector3fAttribute( i
* 2, 1, math::Vector3f( ctip
* cos45
, cos45
, stip
* cos45
) );
98 pIB
->setIndex( i
* 2 + 1, i
* 2 );
102 pVB
->setVector3fAttribute( i
+ Subdivisions
* 2, 0, math::Vector3f( c
, 0.f
, s
) );
103 pVB
->setVector3fAttribute( i
+ Subdivisions
* 2, 1, math::Vector3f( 0.f
, -1.f
, 0.f
) );
104 pIB
->setIndex( ( Subdivisions
+ 1 ) * 2 + i
, i
+ Subdivisions
* 2 );
107 pIB
->setIndex( i
* 2, 1 );
108 pIB
->setIndex( i
* 2 + 1, 0 );
110 Pointer
< scenegraph::Geometry
> pGeom
= new Geometry( pVB
, pIB
.raw() );
111 pGeom
->addPrimitive( Primitive::t_TriangleStrip
, 0, ( Subdivisions
+ 1 ) * 2 );
112 pGeom
->addPrimitive( Primitive::t_TriangleFan
, ( Subdivisions
+ 1 ) * 2, Subdivisions
);
114 ms_Geometries
[ Subdivisions
] = pGeom
;
118 void Cone::evaluate( const Pointer
< scenegraph::RenderPass
>& pPass
)
120 m_pDrawable
->setpMaterial( m_pMaterial
);
121 m_pDrawable
->setpFrame( m_pFrame
);
122 pPass
->addDrawable( m_pDrawable
);