====== Accessing 3D Geometry ====== Geometry access in the SDK isn't as straightforward as declaring a structure and typecasting a vertex data pointer to it, as each draw call for each LOD of a tree model may have a different vertex declaration as decribed by the associated render state's SVertexDecl. However, the SDK does provide a few overloaded functions in SDrawCall to facilitate quick vertex property access. Specifically: * void SDrawCall::**GetProperty**(EVertexProperty eProperty, st_int32 nVertex, st_float32 afValues[4]) const; * void SDrawCall::**GetProperty**(EVertexProperty eProperty, st_int32 nVertex, st_float16 ahfValues[4]) const; * void SDrawCall::**GetProperty**(EVertexProperty eProperty, st_int32 nVertex, st_byte abValues[4]) const; Where eProperty is one of the sixteen pre-defined [[vertex_properties|vertex properties]] (e.g. VERTEX_PROPERTY_POSITION, VERTEX_PROPERTY_NORMAL, etc), nVertex is which vertex index in the buffer to be retrieved, and finally the last parameter will contain the returned value, padded with zeroes if necessary. The following code loads a tree and prints the position property for every draw call of each LOD. Position is always present in every vertex. When checking for other properties, consider using SVertexDecl::m_asProperties[X].IsPresent() (where X is any EVertexProperty value) to determine if that property is in the vertex data. /////////////////////////////////////////////////////////////////////// // Geometry_AccessVertexPosition void Geometry_AccessVertexPosition(void) { const char* pFilename = "example.srt"; // load SRT file CCore* pTree = Internal_LoadSrtFile(pFilename); if (pTree) { // access tree's geometry const SGeometry* pGeometry = pTree->GetGeometry( ); // run through every LOD in the tree for (int i = 0; i < pGeometry->m_nNumLods; ++i) { const SLod& sLod = pGeometry->m_pLods[i]; // each LOD has a number of draw calls for (int j = 0; j < sLod.m_nNumDrawCalls; ++j) { const SDrawCall& sDrawCall = sLod.m_pDrawCalls[j]; const SVertexDecl& sVertexDecl = sDrawCall.m_pRenderState->m_sVertexDecl; // each draw call contains its own logical vertex buffer for (int k = 0; k < sDrawCall.m_nNumVertices; ++k) { EVertexFormat ePosFormat = sVertexDecl.m_asProperties[VERTEX_PROPERTY_POSITION].m_eFormat; if (ePosFormat == VERTEX_FORMAT_HALF_FLOAT) { st_float16 afProperty[4]; // GetProperty() always takes four-float array sDrawCall.GetProperty(VERTEX_PROPERTY_POSITION, k, afProperty); printf("pos[%d] = (%g, %g, %g)\n", k, float(afProperty[0]), float(afProperty[1]), float(afProperty[2])); } else if (ePosFormat == VERTEX_FORMAT_FULL_FLOAT) { st_float32 afProperty[4]; // GetProperty() always takes four-float array sDrawCall.GetProperty(VERTEX_PROPERTY_POSITION, k, afProperty); printf("pos[%d] = (%g, %g, %g)\n", k, afProperty[0], afProperty[1], afProperty[2]); } // positions cannot be stored as VERTEX_FORMAT_BYTE } } } st_delete(pTree); } }