void loadMeshes( CalCoreModel* calCoreModel, MeshesVector& meshes ) throw (std::runtime_error) { const int maxVertices = Constants::MAX_VERTEX_PER_MODEL; const int maxFaces = Constants::MAX_VERTEX_PER_MODEL * 3; std::auto_ptr< CalHardwareModel > calHardwareModel( new CalHardwareModel( calCoreModel ) ); osg::ref_ptr< VertexBuffer > vertexBuffer( new VertexBuffer( maxVertices ) ); osg::ref_ptr< WeightBuffer > weightBuffer( new WeightBuffer( maxVertices ) ); osg::ref_ptr< MatrixIndexBuffer > matrixIndexBuffer( new MatrixIndexBuffer( maxVertices ) ); osg::ref_ptr< NormalBuffer > normalBuffer( new NormalBuffer( maxVertices ) ); osg::ref_ptr< NormalBuffer > tangentBuffer( new NormalBuffer( maxVertices ) ); osg::ref_ptr< NormalBuffer > binormalBuffer( new NormalBuffer( maxVertices ) ); osg::ref_ptr< TexCoordBuffer > texCoordBuffer( new TexCoordBuffer( maxVertices ) ); std::vector< CalIndex > indexBuffer( maxFaces*3 ); std::vector< float > floatMatrixIndexBuffer( maxVertices*4 ); calHardwareModel->setVertexBuffer((char*)vertexBuffer->getDataPointer(), 3*sizeof(float)); #ifdef OSG_CAL_BYTE_BUFFERS std::vector< float > floatNormalBuffer( getVertexCount()*3 ); calHardwareModel->setNormalBuffer((char*)&floatNormalBuffer.begin(), 3*sizeof(float)); #else calHardwareModel->setNormalBuffer((char*)normalBuffer->getDataPointer(), 3*sizeof(float)); #endif calHardwareModel->setWeightBuffer((char*)weightBuffer->getDataPointer(), 4*sizeof(float)); calHardwareModel->setMatrixIndexBuffer((char*)&floatMatrixIndexBuffer.front(), 4*sizeof(float)); calHardwareModel->setTextureCoordNum( 1 ); calHardwareModel->setTextureCoordBuffer(0, // texture stage # (char*)texCoordBuffer->getDataPointer(), 2*sizeof(float)); calHardwareModel->setIndexBuffer( &indexBuffer.front() ); // calHardwareModel->setCoreMeshIds(_activeMeshes); // if ids not set all meshes will be used at load() time //std::cout << "calHardwareModel->load" << std::endl; calHardwareModel->load( 0, 0, Constants::MAX_BONES_PER_MESH ); //std::cout << "calHardwareModel->load ok" << std::endl; int vertexCount = calHardwareModel->getTotalVertexCount(); // int faceCount = calHardwareModel->getTotalFaceCount(); // std::cout << "vertexCount = " << vertexCount << "; faceCount = " << faceCount << std::endl; GLubyte* matrixIndexBufferData = (GLubyte*) matrixIndexBuffer->getDataPointer(); for ( int i = 0; i < vertexCount*4; i++ ) { matrixIndexBufferData[i] = static_cast< GLubyte >( floatMatrixIndexBuffer[i] ); } #ifdef OSG_CAL_BYTE_BUFFERS GLbyte* normals = (GLbyte*) normalBuffer->getDataPointer(); for ( int i = 0; i < vertexCount*3; i++ ) { normals[i] = static_cast< GLbyte >( floatNormalBuffer[i]*127.0 ); } #endif // invert UVs for OpenGL (textures are inverted otherwise - for example, see abdulla/klinok) GLfloat* texCoordBufferData = (GLfloat*) texCoordBuffer->getDataPointer(); for ( float* tcy = texCoordBufferData + 1; tcy < texCoordBufferData + 2*vertexCount; tcy += 2 ) { *tcy = 1.0f - *tcy; } // -- And now create meshes data -- int unriggedBoneIndex = calCoreModel->getCoreSkeleton()->getVectorCoreBone().size(); // we add empty bone in ModelData to handle unrigged vertices; for( int hardwareMeshId = 0; hardwareMeshId < calHardwareModel->getHardwareMeshCount(); hardwareMeshId++ ) { calHardwareModel->selectHardwareMesh(hardwareMeshId); int faceCount = calHardwareModel->getFaceCount(); if ( faceCount == 0 ) { continue; // we ignore empty meshes } CalHardwareModel::CalHardwareMesh* hardwareMesh = &calHardwareModel->getVectorHardwareMesh()[ hardwareMeshId ]; osg::ref_ptr< MeshData > m( new MeshData ); m->name = calCoreModel->getCoreMesh( hardwareMesh->meshId )->getName(); m->coreMaterial = hardwareMesh->pCoreMaterial; if ( m->coreMaterial == NULL ) { CalCoreMesh* coreMesh = calCoreModel->getCoreMesh( hardwareMesh->meshId ); CalCoreSubmesh* coreSubmesh = coreMesh->getCoreSubmesh( hardwareMesh->submeshId ); // hardwareMesh->pCoreMaterial = // coreModel->getCoreMaterial( coreSubmesh->getCoreMaterialThreadId() ); char buf[ 1024 ]; snprintf( buf, 1024, "pCoreMaterial == NULL for mesh '%s' (mesh material id = %d), verify your mesh file data", m->name.c_str(), coreSubmesh->getCoreMaterialThreadId() ); throw std::runtime_error( buf ); } // -- Create index buffer -- int indexesCount = faceCount * 3; int startIndex = calHardwareModel->getStartIndex(); if ( indexesCount <= 0x100 ) { m->indexBuffer = new osg::DrawElementsUByte( osg::PrimitiveSet::TRIANGLES, indexesCount ); GLubyte* data = (GLubyte*)m->indexBuffer->getDataPointer(); const CalIndex* i = &indexBuffer[ startIndex ]; const CalIndex* iEnd = &indexBuffer[ startIndex + indexesCount ]; while ( i < iEnd ) { *data++ = (GLubyte)*i++; } } else if ( indexesCount <= 0x10000 ) { m->indexBuffer = new osg::DrawElementsUShort( osg::PrimitiveSet::TRIANGLES, indexesCount ); GLushort* data = (GLushort*)m->indexBuffer->getDataPointer(); const CalIndex* i = &indexBuffer[ startIndex ]; const CalIndex* iEnd = &indexBuffer[ startIndex + indexesCount ]; while ( i < iEnd ) { *data++ = (GLushort)*i++; } } else { m->indexBuffer = new osg::DrawElementsUInt( osg::PrimitiveSet::TRIANGLES, indexesCount ); GLuint* data = (GLuint*)m->indexBuffer->getDataPointer(); const CalIndex* i = &indexBuffer[ startIndex ]; const CalIndex* iEnd = &indexBuffer[ startIndex + indexesCount ]; while ( i < iEnd ) { *data++ = (GLuint)*i++; } } // -- Create other buffers -- int vertexCount = calHardwareModel->getVertexCount(); int baseVertexIndex = calHardwareModel->getBaseVertexIndex(); #define SUB_BUFFER( _type, _name ) \ new _type( _name->begin() + baseVertexIndex, \ _name->begin() + baseVertexIndex + vertexCount ) m->vertexBuffer = SUB_BUFFER( VertexBuffer, vertexBuffer ); m->weightBuffer = SUB_BUFFER( WeightBuffer, weightBuffer ); m->matrixIndexBuffer = SUB_BUFFER( MatrixIndexBuffer, matrixIndexBuffer ); m->normalBuffer = SUB_BUFFER( NormalBuffer, normalBuffer ); m->texCoordBuffer = SUB_BUFFER( TexCoordBuffer, texCoordBuffer ); // -- Parameters and buffers setup -- m->boundingBox = calculateBoundingBox( m->vertexBuffer.get() ); m->bonesIndices = hardwareMesh->m_vectorBonesIndices; checkRigidness( m.get(), unriggedBoneIndex ); checkForEmptyTexCoord( m.get() ); generateTangentAndHandednessBuffer( m.get(), &indexBuffer[ startIndex ] ); meshes.push_back( m.get() ); } }
void WSMSGridder::gridMeasurementSet(MSData &msData) { const MultiBandData selectedBand(msData.SelectedBand()); _gridder->PrepareBand(selectedBand); std::vector<std::complex<float>> modelBuffer(selectedBand.MaxChannels()); std::vector<float> weightBuffer(selectedBand.MaxChannels()); lane_write_buffer<InversionWorkItem> writeBuffer(&*_inversionWorkLane, 128); size_t rowsRead = 0; msData.msProvider->Reset(); while(msData.msProvider->CurrentRowAvailable()) { size_t dataDescId; double uInMeters, vInMeters, wInMeters; msData.msProvider->ReadMeta(uInMeters, vInMeters, wInMeters, dataDescId); const BandData& curBand(selectedBand[dataDescId]); const double w1 = wInMeters / curBand.LongestWavelength(), w2 = wInMeters / curBand.SmallestWavelength(); if(_gridder->IsInLayerRange(w1, w2)) { InversionWorkItem newItem; newItem.u = uInMeters; newItem.v = vInMeters; newItem.w = wInMeters; newItem.dataDescId = dataDescId; newItem.data = new std::complex<float>[curBand.ChannelCount()]; if(DoImagePSF()) { msData.msProvider->ReadWeights(newItem.data); if(_denormalPhaseCentre) { double lmsqrt = sqrt(1.0-_phaseCentreDL*_phaseCentreDL- _phaseCentreDM*_phaseCentreDM); double shiftFactor = 2.0*M_PI* (newItem.w * (lmsqrt-1.0)); rotateVisibilities(curBand, shiftFactor, newItem.data); } } else { msData.msProvider->ReadData(newItem.data); } if(DoSubtractModel()) { msData.msProvider->ReadModel(modelBuffer.data()); std::complex<float>* modelIter = modelBuffer.data(); for(std::complex<float>* iter = newItem.data; iter!=newItem.data+curBand.ChannelCount(); ++iter) { *iter -= *modelIter; modelIter++; } } msData.msProvider->ReadWeights(weightBuffer.data()); switch(VisibilityWeightingMode()) { case NormalVisibilityWeighting: // The MS provider has already preweighted the // visibilities for their weight, so we do not // have to do anything. break; case SquaredVisibilityWeighting: for(size_t ch=0; ch!=curBand.ChannelCount(); ++ch) newItem.data[ch] *= weightBuffer[ch]; break; case UnitVisibilityWeighting: for(size_t ch=0; ch!=curBand.ChannelCount(); ++ch) { if(weightBuffer[ch] == 0.0) newItem.data[ch] = 0.0; else newItem.data[ch] /= weightBuffer[ch]; } break; } switch(Weighting().Mode()) { case WeightMode::UniformWeighted: case WeightMode::BriggsWeighted: case WeightMode::NaturalWeighted: { std::complex<float>* dataIter = newItem.data; float* weightIter = weightBuffer.data(); for(size_t ch=0; ch!=curBand.ChannelCount(); ++ch) { double u = newItem.u / curBand.ChannelWavelength(ch), v = newItem.v / curBand.ChannelWavelength(ch), weight = PrecalculatedWeightInfo()->GetWeight(u, v); *dataIter *= weight; _totalWeight += weight * *weightIter; ++dataIter; ++weightIter; } } break; case WeightMode::DistanceWeighted: { float* weightIter = weightBuffer.data(); double mwaWeight = sqrt(newItem.u*newItem.u + newItem.v*newItem.v + newItem.w*newItem.w); for(size_t ch=0; ch!=curBand.ChannelCount(); ++ch) { _totalWeight += *weightIter * mwaWeight; ++weightIter; } } break; } writeBuffer.write(newItem); ++rowsRead; } msData.msProvider->NextRow(); } if(Verbose()) std::cout << "Rows that were required: " << rowsRead << '/' << msData.matchingRows << '\n'; msData.totalRowsProcessed += rowsRead; }