void generateTexCoordsSphere( VertexAttributeSetSharedPtr const& vas, const Sphere3f &sphere, unsigned int tu ) { Buffer::ConstIterator<Vec3f>::Type vertices = vas->getVertices(); std::vector<Vec2f> texCoords( vas->getNumberOfVertices() ); Vec2f tp; for ( unsigned int i=0 ; i<vas->getNumberOfVertices() ; i++ ) { Vec3f p = vertices[i] - sphere.getCenter(); if ( fabsf( p[1] ) > FLT_EPSILON ) { tp[0] = 0.5f * atan2f( p[0], -p[1] ) / (float) PI + 0.5f; } else { tp[0] = (float)( ( p[0] >= 0.0f ) ? 0.75f : 0.25f ); } float d = sqrtf( square( p[0] ) + square( p[1] ) ); if ( d > FLT_EPSILON ) { tp[1] = atan2f( p[2], d ) / (float) PI + 0.5f; } else { tp[1] = (float)( ( p[2] >= 0.0f ) ? 1.0f : 0.0f ); } texCoords[i] = tp; } vas->setTexCoords( tu, &texCoords[0], vas->getNumberOfVertices() ); }
void copySelectedVertices( const VertexAttributeSetSharedPtr & from, const VertexAttributeSetSharedPtr & to , std::vector<std::vector<unsigned int> > &indices ) { // indexMap below is intended to hold vertex indices, which should not exceed 32-bit precision by definition! std::vector<unsigned int> indexMap( from->getNumberOfVertices(), ~0 ); std::vector<unsigned int> iFrom; iFrom.reserve(from->getNumberOfVertices()); for ( size_t i=0 ; i<indices.size() ; i++ ) { for ( size_t j=0 ; j<indices[i].size() ; j++ ) { if ( indexMap[indices[i][j]] == ~0 ) { indexMap[indices[i][j]] = dp::checked_cast<unsigned int>(iFrom.size()); iFrom.push_back(indices[i][j]); } } } for ( unsigned int slot=0 ; slot<static_cast<unsigned int>(VertexAttributeSet::AttributeID::VERTEX_ATTRIB_COUNT) ; slot++ ) { VertexAttributeSet::AttributeID id = static_cast<VertexAttributeSet::AttributeID>(slot); if ( from->getSizeOfVertexData( id ) ) { BufferSharedPtr oldData = from->getVertexBuffer(id); Buffer::DataReadLock lock( oldData ); unsigned int size = from->getSizeOfVertexData( id ); dp::DataType type = from->getTypeOfVertexData( id ); to->setVertexData( id, NULL, &iFrom[0], size, type, lock.getPtr() , from->getStrideOfVertexData( id ) , dp::checked_cast<unsigned int>(iFrom.size()) ); // inherit enable states from source id // normalize-enable state only meaningful for generic aliases! to->setEnabled(id, from->isEnabled(id)); // conventional id = static_cast<VertexAttributeSet::AttributeID>(slot+16); // generic to->setEnabled(id, from->isEnabled(id)); to->setNormalizeEnabled(id, from->isNormalizeEnabled(id)); } } for ( size_t i=0 ; i<indices.size() ; i++ ) { for ( size_t j=0 ; j<indices[i].size() ; j++ ) { indices[i][j] = indexMap[indices[i][j]]; } } }
void generateTexCoordsPlane( VertexAttributeSetSharedPtr const& vas, const Sphere3f &sphere, unsigned int tu ) { Buffer::ConstIterator<Vec3f>::Type vertices = vas->getVertices(); // get the bounding box of vas and determine the axes u,v to use to texture along unsigned int u, v, w; getSortedAxes( vertices, vas->getNumberOfVertices(), u, v, w ); // create the texture coordinates std::vector<Vec2f> texCoords( vas->getNumberOfVertices() ); Vec2f tp; float oneOverTwoR = 0.5f / sphere.getRadius(); Vec2f tpMin( 1.0f, 1.0f ); Vec2f tpMax( 0.0f, 0.0f ); for ( unsigned int i=0 ; i<vas->getNumberOfVertices() ; i++ ) { Vec3f p = vertices[i] - sphere.getCenter(); tp[0] = p[u] * oneOverTwoR + 0.5f; // 0.0 <= tp[0] <= 1.0 if ( tp[0] < tpMin[0] ) { tpMin[0] = tp[0]; } else if ( tp[0] > tpMax[0] ) { tpMax[0] = tp[0]; } tp[1] = p[v] * oneOverTwoR + 0.5f; // 0.0 <= tp[1] <= 1.0 if ( tp[1] < tpMin[1] ) { tpMin[1] = tp[1]; } else if ( tp[1] > tpMax[1] ) { tpMax[1] = tp[1]; } texCoords[i] = tp; } // scale the texcoords to [0..1] DP_ASSERT( ( FLT_EPSILON < ( tpMax[0] - tpMin[0] ) ) && ( FLT_EPSILON < ( tpMax[1] - tpMin[1] ) ) ); Vec2f tpScale( 1.0f / ( tpMax[0] - tpMin[0] ), 1.0f / ( tpMax[1] - tpMin[1] ) ); for ( unsigned int i=0 ; i<vas->getNumberOfVertices() ; i++ ) { texCoords[i] = Vec2f( ( texCoords[i][0] - tpMin[0] ) * tpScale[0], ( texCoords[i][1] - tpMin[1] ) * tpScale[1] ); } vas->setTexCoords( tu, &texCoords[0], vas->getNumberOfVertices() ); }
void generateTexCoordsCylinder( VertexAttributeSetSharedPtr const& vas, const Sphere3f &sphere, unsigned int tu ) { Buffer::ConstIterator<Vec3f>::Type vertices = vas->getVertices(); // get the bounding box of vas and determine the axes u,v to use to texture along unsigned int u, v, w; getSortedAxes( vertices, vas->getNumberOfVertices(), u, v, w ); // create the texture coordinates std::vector<Vec2f> texCoords( vas->getNumberOfVertices() ); Vec2f tp; float oneOverTwoR = 0.5f / sphere.getRadius(); float tpuMin = 1.0f; float tpuMax = 0.0f; for ( unsigned int i=0 ; i<vas->getNumberOfVertices() ; i++ ) { Vec3f p = vertices[i] - sphere.getCenter(); // largest axis as the cylinder axis tp[0] = p[u] * oneOverTwoR + 0.5f; // 0.0 <= tp[1] <= 1.0 if ( tp[0] < tpuMin ) { tpuMin = tp[0]; } else if ( tpuMax < tp[0] ) { tpuMax = tp[0]; } if ( FLT_EPSILON < fabsf( p[v] ) ) { tp[1] = 0.5f * atan2f( p[w], -p[v] ) / (float) PI + 0.5f; } else { tp[1] = (float)( ( 0.0f <= p[w] ) ? 0.75f : 0.25f ); } texCoords[i] = tp; } // scale the texcoords to [0..1] DP_ASSERT( FLT_EPSILON < ( tpuMax - tpuMin ) ); float tpuScale = 1.0f / ( tpuMax - tpuMin ); for ( unsigned int i=0 ; i<vas->getNumberOfVertices() ; i++ ) { texCoords[i][0] = ( texCoords[i][0] - tpuMin ) * tpuScale; } vas->setTexCoords( tu, &texCoords[0], vas->getNumberOfVertices() ); }