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; }
void _3dsLoader::readVertexIndices(Chunk ¤tChunk, 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; }
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; }
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(); } }
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(); } }
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; }