Beispiel #1
0
    virtual osgGIS::FragmentList process( osgGIS::Feature* input, osgGIS::FilterEnv* env )
    {
        osgGIS::FragmentList output;

        for( osgGIS::GeoShapeList::iterator j = input->getShapes().begin(); j != input->getShapes().end(); j++ )
        {
            osgGIS::GeoShape& shape = *j;
            osg::Vec4f color(1,1,1,1);

            osg::ref_ptr<osg::Geometry> walls = new osg::Geometry();
            osg::ref_ptr<osg::Geometry> top_cap = NULL;
            osg::ref_ptr<osg::Geometry> bottom_cap = NULL;

            if ( shape.getShapeType() == osgGIS::GeoShape::TYPE_POLYGON )
            {
                top_cap = new osg::Geometry();
                bottom_cap = new osg::Geometry();
                for( osgGIS::GeoPartList::iterator i = shape.getParts().begin(); i != shape.getParts().end(); i++ )
                {
                    osgGIS::GeomUtils::openPolygon( *i );
                }
            }

            if ( extrudeWallsUp( shape, env->getInputSRS(), EXTRUDE_SIZE, false, walls.get(), top_cap.get(), bottom_cap.get(), color, NULL ) )
            {     
                walls->getOrCreateStateSet()->setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::OFF);

                // generate per-vertex normals
                generateNormals( walls.get() );

                osgGIS::Fragment* new_fragment = new osgGIS::Fragment( walls.get() );

                // tessellate and add the roofs if necessary:
                if ( top_cap.valid() )
                {
                    osgUtil::Tessellator tess;
                    tess.setTessellationType( osgUtil::Tessellator::TESS_TYPE_GEOMETRY );
                    tess.setWindingType( osgUtil::Tessellator::TESS_WINDING_POSITIVE );
                    tess.retessellatePolygons( *(top_cap.get()) );
                    generateNormals( top_cap.get() );
                    new_fragment->addDrawable( top_cap.get() );
                }

                if ( bottom_cap.valid() )
                {
                    osgUtil::Tessellator tess;
                    tess.setTessellationType( osgUtil::Tessellator::TESS_TYPE_GEOMETRY );
                    tess.setWindingType( osgUtil::Tessellator::TESS_WINDING_POSITIVE );
                    tess.retessellatePolygons( *(bottom_cap.get()) );
                    generateNormals( bottom_cap.get() );
                    new_fragment->addDrawable( bottom_cap.get() );
                }

                output.push_back( new_fragment );
            }   
        }

        return output;
    }        
Beispiel #2
0
void _3dsLoader::readVertexIndices(Chunk &currentChunk, Wrapper &wrapper, Mesh *mesh) const
{
	ASSERT(currentChunk.getID()==OBJECT_FACES, "Expected chunk ID OBJECT_FACES");

	unsigned short int trashVisibilityFlag=0;

	currentChunk.read(&(mesh->m_numOfFaces), 2);

	if(mesh->m_numOfFaces>0)
	{
		mesh->m_pFaces = new Mesh::Face[mesh->m_numOfFaces];
		memset(mesh->m_pFaces, 0, sizeof(Mesh::Face) * mesh->m_numOfFaces);

		for(int i = 0; i < mesh->m_numOfFaces; ++i)
		{
			currentChunk.read(&mesh->m_pFaces[i].vertIndex[2], 2);
			currentChunk.read(&mesh->m_pFaces[i].vertIndex[1], 2);
			currentChunk.read(&mesh->m_pFaces[i].vertIndex[0], 2);
			currentChunk.read(&trashVisibilityFlag, 2);
		}
	}

	mesh->reallocElements();
	generateNormals(mesh);

	// An OBJECT_MATERIAL tag may be nested within this chunk
	processNextObjectChunk(currentChunk, wrapper, mesh);
}
bool Terrain::loadHeightmap(const string& rawFile, int width) 
{
    const float HEIGHT_SCALE = 10.0f; 
    std::ifstream fileIn(rawFile.c_str(), std::ios::binary);

    if (!fileIn.good()) 
    {
        std::cout << "File does not exist" << std::endl;
        return false;
    }

    
    string stringBuffer(std::istreambuf_iterator<char>(fileIn), (std::istreambuf_iterator<char>()));

    fileIn.close();

    if (stringBuffer.size() != (width * width)) 
    {
        std::cout << "Image size does not match passed width" << std::endl;
        return false;
    }

    vector<float> heights;
    heights.reserve(width * width); 

    
    for (int i = 0; i < (width * width); ++i) 
    {
        
        float value = (float)(unsigned char)stringBuffer[i] / 256.0f; 
    
        heights.push_back(value * HEIGHT_SCALE);
        m_colors.push_back(Color(value, value, value));
    }

    glGenBuffers(1, &m_colorBuffer); 
    glBindBuffer(GL_ARRAY_BUFFER, m_colorBuffer); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * m_colors.size() * 3, &m_colors[0], GL_STATIC_DRAW); 

    generateVertices(heights, width);
    generateIndices(width);
    generateTexCoords(width);
    generateNormals();

    generateWaterVertices(width);
    generateWaterIndices(width);
    generateWaterTexCoords(width);

    m_width = width;
    return true;
}
Beispiel #4
0
void csWaterDemo::updateWater (float time)
{
  bool haveRan=false;
  
  if (time>1000) time =0;
  lastSimTime += (time/1000.0f);
  

  while (lastSimTime > nextSimTime)
  {
  
    csVector3 *vbuf = gFactState->GetVertices ();

    C1 = (4 - ((8*WaveSpeed*WaveSpeed*TimeDelta*TimeDelta) / (GridSize*GridSize))) / (WaveLife*TimeDelta + 2);
    C2 = (WaveLife*TimeDelta - 2) / (WaveLife*TimeDelta + 2);
    C3 = ((2*WaveSpeed*WaveSpeed*TimeDelta*TimeDelta) / (GridSize*GridSize)) / (WaveLife*TimeDelta + 2);
    float C4, C5;
    C4 = C3*0.5858;
    C5 = C3*0.4142;

    float *tmp;
    tmp=water2;
    water2=water1;
    water1=water;
    water=tmp;
    memset(water, 0, Width*Height*sizeof(float));

    for (int z = 1; z < (Height-1); z++) {
      for (int x = 1; x < (Width-1); x++) {
        int ind = x*Width+z;

        water[ind] = C1*water1[ind] + 
                     C2*water2[ind] + 
                     C4*(water1[ind+1] + water1[ind-1] + water1[ind+Width] + water1[ind-Width])+
                     C5*(water1[ind+1+Width] + water1[ind-1+Width] + water1[ind-Width+1] + water1[ind-Width-1]);

        vbuf[ind].y = water[ind];
      }
    }  
    nextSimTime += 1/SIMPERSECOND;
    haveRan = true;
  }

  if (haveRan)
    generateNormals ();

  gFactState->Invalidate ();
}
Model* LoadModel(char* name)
{
    Model* model = 0;
    Mesh* mesh = LoadOBJ(name);

    if (!mesh)
        return 0;

    DecomposeToTriangles(mesh);

    generateNormals(mesh);

    model = generateModel(mesh);

    return model;
}
Beispiel #6
0
	Collision::Collision(const Collision::ColPoints& pts)
	{
		mNpCount = pts.size();
		mPoints = ColPoints(pts);
		
		if(mNpCount == 0)
			return;
		
		generateBbox();
		
		// Normals and projection only exist for non-point collision
		if(mNpCount >= 2) {
			mNormals.resize(mNpCount);
			mProjection.resize(mNpCount);
			
			generateNormals();
			generateProjection();
		}
	}
Beispiel #7
0
antPlane::antPlane
( float width, float depth, int nColumns, int nRows,
 int nVbo, bool genColors,
 bool genNormals, bool genTexCoords ) :
antDrawable( nVbo, ATTR_POSITION ),
m_width( width ),
m_depth( depth ),
m_nColumns( nColumns ),
m_nRows( nRows )
{
    m_nVertices = ( m_nColumns * m_nRows * 6 );

    antRGBA color1( 0.f, 0.f, 0.f, 1.f );
    antRGBA color2( 1.f, 1.f, 1.f, 1.f );
    
    generateVertices();
    
    if ( genColors ) { generateColors( color1, color2 ); }
    if ( genNormals ) { generateNormals(); }
    if ( genTexCoords ) { generateTexCoords(); }    
}
Beispiel #8
0
bool MeshManager::importObjMesh(const char* filename)
{
	QElapsedTimer timer;
	timer.start();
	QFile objFile(filename);

	if (!objFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
		std::cerr << "could not find file: " << filename;
		return false;
	}

	QTextStream stream(&objFile);

	std::shared_ptr<GenericDataArray<float> > vertices = std::make_shared<GenericDataArray<float> >();
	std::shared_ptr<GenericDataArray<unsigned int> > faces = std::make_shared<GenericDataArray<unsigned int> >();
	std::shared_ptr<GenericDataArray<float> > uniqueNormals = std::make_shared<GenericDataArray<float> >();
	std::vector<int> normalIndices;

	while (!stream.atEnd()) {
		QString linePrefix;
		stream >> linePrefix;

		QString line(stream.readLine());

		if (linePrefix != "#") {
			QStringList elements = line.split(' ', QString::SkipEmptyParts);

			//read vertices
			if (linePrefix == "v") {
				GenericDataArray<float>::value_type vertexPosition;
				vertexPosition[0] = elements.takeFirst().toFloat();
				vertexPosition[1] = elements.takeFirst().toFloat();
				vertexPosition[2] = elements.takeFirst().toFloat();

				vertices->push_back(vertexPosition);
			}

			//read normals
			if (linePrefix == "vn") {
				GenericDataArray<float>::value_type normal;
				normal[0] = elements.takeFirst().toFloat();
				normal[1] = elements.takeFirst().toFloat();
				normal[2] = elements.takeFirst().toFloat();

				uniqueNormals->push_back(normal);
			}

			//read faces
			else if (linePrefix == "f"){
				GenericDataArray<unsigned int>::value_type face;

				int i = 0;
				while (!elements.isEmpty() && i < 3) {
					QStringList faceElements = elements.takeFirst().split('/', QString::SkipEmptyParts);
					if (faceElements.size() == 2) {
						face[i] = faceElements.takeFirst().toInt() - 1;
						normalIndices.push_back(faceElements.takeFirst().toInt() - 1);
					}
					else {
						face[i] = faceElements.takeFirst().toInt() - 1;
					}

					++i;
				}

				faces->push_back(face);
			}
		}
	}

	std::shared_ptr<GenericDataArray<float> > normals; 

	//rearrange normals so that they can be accessed by the same index as vertices
	if (!uniqueNormals->empty()) {
		normals = std::make_shared<GenericDataArray<float> >(vertices->length());
		for (unsigned int i = 0; i < faces->length(); ++i) {
			for (unsigned int j = 0; j < 3; ++j) {
				int vertexIndex = faces->at(i, j);
				int normalIndex = normalIndices[i * 3 + j];
				normals->at(vertexIndex) = uniqueNormals->at(normalIndex);
			}
		}
	}
	else {
		normals = generateNormals(vertices, faces);
	}

	m_geomRoot = std::make_shared<sg::GroupNode>();
	m_geomRoot->addChild(createGeometryNode(vertices, normals, faces));

	std::cout << "Time: " << timer.elapsed() / 1000.0 << std::endl;
	std::cout << "Vertices: " << vertices->length() << std::endl;
	std::cout << "Faces: " << faces->length() << std::endl;

	return true;

}
bool ModelOBJ::import(const char *pszFilename, bool rebuildNormals)
{
    FILE *pFile = fopen(pszFilename, "r");

    if (!pFile)
        return false;

    // Extract the directory the OBJ file is in from the file name.
    // This directory path will be used to load the OBJ's associated MTL file.

    m_directoryPath.clear();

    std::string filename = pszFilename;
    std::string::size_type offset = filename.find_last_of('\\');

    if (offset != std::string::npos)
    {
        m_directoryPath = filename.substr(0, ++offset);
    }
    else
    {
        offset = filename.find_last_of('/');

        if (offset != std::string::npos)
            m_directoryPath = filename.substr(0, ++offset);
    }

    // Import the OBJ file.

    importGeometryFirstPass(pFile);
    rewind(pFile);
    importGeometrySecondPass(pFile);
    fclose(pFile);

    // Perform post import tasks.

    buildMeshes();
    bounds(m_center, m_width, m_height, m_length, m_radius);

    // Build vertex normals if required.

    if (rebuildNormals)
    {
        generateNormals();
    }
    else
    {
        if (!hasNormals())
            generateNormals();
    }

    // Build tangents is required.

    for (int i = 0; i < m_numberOfMaterials; ++i)
    {
        if (!m_materials[i].bumpMapFilename.empty())
        {
            generateTangents();
            break;
        }
    }

    return true;
}