#include "pch.h" ////////////////////////////////////////////////////////////////////////////// // // ConeGeo // ////////////////////////////////////////////////////////////////////////////// int g_hSegments = 16; int g_vSegments = 4; class ConeGeo : public Geo { private: TVector m_vvertex; TVector m_vindex; TRef m_pmaterial; float GetAngle() { return Number::Cast(GetChild(0))->GetValue(); } public: ConeGeo(Number* pangle) : Geo(pangle), m_vvertex(g_hSegments * g_vSegments + 2), m_vindex( 6 * g_hSegments * (g_vSegments - 1) + 3 * g_hSegments * 2 ) { InitializeIndices(); } void InitializeVertices() { m_vvertex.Set(0, Vertex(Vector(0, 0, 1), Vector(0, 0, 1))); m_vvertex.Set(1, Vertex(Vector(0, 0, 0), Vector(0, 0, -1))); float angle = GetAngle(); for(int vIndex = 0; vIndex < g_vSegments; vIndex++) { float vAngle = angle * ((float)(vIndex + 1) / (float)g_vSegments); int index = vIndex * g_hSegments + 2; float radius = sin(vAngle); float z = cos(vAngle); for (int hIndex = 0; hIndex < g_hSegments; hIndex++) { float hAngle = 2 * pi * hIndex / g_hSegments; m_vvertex.Set( index + hIndex, Vertex( Vector( radius * cos(hAngle), radius * sin(hAngle), z ), Vector( radius * cos(hAngle), radius * sin(hAngle), z ) ) ); } } } void InitializeIndices() { int indexIndex = 0; // // The first band // { int indexVertex = 2; for (int hIndex = 0; hIndex < g_hSegments; hIndex++) { int delta = (hIndex == (g_hSegments - 1)) ? (1 - g_hSegments) : 1; m_vindex.Set(indexIndex + 0, 0); m_vindex.Set(indexIndex + 1, indexVertex + hIndex + delta); m_vindex.Set(indexIndex + 2, indexVertex + hIndex ); indexIndex += 3; } } // // The middle bands // for(int vIndex = 0; vIndex < g_vSegments - 1; vIndex++) { int indexVertex = vIndex * g_hSegments + 2; for (int hIndex = 0; hIndex < g_hSegments; hIndex++) { int delta = (hIndex == (g_hSegments - 1)) ? (1 - g_hSegments) : 1; m_vindex.Set(indexIndex + 0, indexVertex + hIndex ); m_vindex.Set(indexIndex + 1, indexVertex + hIndex + g_hSegments + delta); m_vindex.Set(indexIndex + 2, indexVertex + hIndex + g_hSegments ); m_vindex.Set(indexIndex + 3, indexVertex + hIndex ); m_vindex.Set(indexIndex + 4, indexVertex + hIndex + delta); m_vindex.Set(indexIndex + 5, indexVertex + hIndex + g_hSegments + delta); indexIndex += 6; } } // // The last band // { int indexVertex = (g_vSegments - 1) * g_hSegments + 2; for (int hIndex = 0; hIndex < g_hSegments; hIndex++) { int delta = (hIndex == (g_hSegments - 1)) ? (1 - g_hSegments) : 1; m_vindex.Set(indexIndex + 0, 1); m_vindex.Set(indexIndex + 1, indexVertex + hIndex ); m_vindex.Set(indexIndex + 2, indexVertex + hIndex + delta); indexIndex += 3; } } } void Evaluate() { InitializeVertices(); } void Render(Context* pcontext) { pcontext->DrawTriangles(m_vvertex, m_vindex); } }; TRef CreateConeGeo(Number* pangle) { return new ConeGeo(pangle); }