예제 #1
0
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() );
    }
}
예제 #2
0
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;
}