Пример #1
0
Terrain::Terrain(int method /*=TRIANGLES */, int terrain_order /*= 8 */, float roughness_constant /* = 0.7f */, 
                    float range /* = 1.0f */, float init_height /* = 0f */){
    float height_factor = terrain_order;
    this->side_size = pow(2,terrain_order) + 1;
    this->roughness_constant = roughness_constant;
    this->method = method;
    this->range = range * terrain_order * height_factor;
    this->points.resize(pow(this->side_size,2));
    this->colors.resize(pow(this->side_size,2));
    this->normals.resize(pow(this->side_size,2));
    this->terrain.resize(this->side_size);
    this->num_points = 0;
    for (int i=0; i < side_size; i++){
        terrain[i].resize(side_size,init_height);
    }
    srand(time(NULL));
    generateHeightMap();
    switch (this->method){
        case TRIANGLES:
            storePointsTriangles();
            break;
        case LINES:
            storePointsLines();
            break;
    }
}
Пример #2
0
int main( void )
{
	initGLFW();
	initWindow();
	initGLEW();
	initKeyboard();
	
	// Dark blue background
	glClearColor(0.0f, 0.0f, 0.4f, 0.0f);

	int size = 5;
	float* map = generateHeightMap(size);
	printf("generated map\n" );
	std::vector<glm::vec3> terrain;
	mapHeightsToPoints(terrain, map, size);
	printf("mapped to points\n");
	// GLuint* indices = generateIndices(terrain, size);

	uint terrainVertexAmount = size* size * 3;
	uint indiceAmount = 3 * (1 << size);

	for(int i = 0; i < terrain.size(); ++i){
		printf("[%f, %f, %f]\n", terrain[i].x, terrain[i].y, terrain[i].z);
	}

	printf("vertices %d\n", terrainVertexAmount);

	GLuint VertexArrayID = newVertexArray();

	// Create and compile our GLSL program from the shaders
	GLuint programID = LoadShaders( "SimpleVertexShader.vertexshader", "SimpleFragmentShader.fragmentshader" );
	printf("loaded\n");
	initMatrices(programID);

	
	GLuint vertexbuffer = newVertexBuffer(terrainVertexAmount, &terrain);
	
	double lastTime = glfwGetTime();
 	int nbFrames = 0;
 	printf("loop\n");


 	initDepth();
	do{

		// Clear the screen
		glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

		// Use our shader
		glUseProgram(programID);
		
		// TODO
		// recalculateMatrices();

		// Send our transformation to the currently bound shader, 
		// in the "MVP" uniform
		glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);

		// 1rst attribute buffer : vertices
		bindVertexBuffer(vertexbuffer);

		// Draw the triangle !
		glDrawArrays(GL_TRIANGLE_FAN, 0, terrainVertexAmount); // 3 indices starting at 0 -> 1 triangle

		glDisableVertexAttribArray(0);

		// Swap buffers
		glfwSwapBuffers(window);
		glfwPollEvents();


		// measureTime(lastTime, &nbFrames);

	} // Check if the ESC key was pressed or the window was closed
	while( glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS &&
		   glfwWindowShouldClose(window) == 0 );

	// Cleanup VBO
	glDeleteBuffers(1, &vertexbuffer);
	glDeleteVertexArrays(1, &VertexArrayID);
	glDeleteProgram(programID);

	// Close OpenGL window and terminate GLFW
	glfwTerminate();
	// normal** ns = generateNormals(map, size);
	return 0;
}
Пример #3
0
void Star::generateStar()
{
	radius = 90.0f + rand() % 15;

	int c = rand() % 3;

	compositionColor1.red = c == 0 ? 255 : rand() % 75 + 175;
	compositionColor1.green = c == 1 ? 255 : rand() % 75 + 175;
	compositionColor1.blue = c == 2 ? 255 : rand() % 75 + 175;
	compositionColor1.alpha = 255;

	compositionColor2.red = c == 0 ? 255 : rand() % 75 + 175;
	compositionColor2.green = c == 1 ? 255 : rand() % 75 + 175;
	compositionColor2.blue = c == 2 ? 255 : rand() % 75 + 175;
	compositionColor2.alpha = 255;

	utils::NoiseMap heightMap = generateHeightMap();
	int heightMapHeight = heightMap.GetHeight();
	int heightMapWidth = heightMap.GetWidth();

	generateTexture(heightMap);

	vector<Vector3> vertices;
	vector<Vector3> normales;
	vector<Vector2> uvs;

	const int nbLong = 24;
	const int nbLat = 16;
	const int nbVertices = (nbLong + 1) * nbLat + 2;
	Vector3 vector3Up = makeVector3(0.0f, 1.0f, 0.0f);

#pragma region Vertices
	vertices = std::vector<Vector3>(nbVertices);
	const float _pi = M_PI;
	const float _2pi = _pi * 2.0f;

	vertices[0] = scalerMultiplyVector3(vector3Up, radius);
	for (int lat = 0; lat < nbLat; ++lat)
	{
		float a1 = _pi * float(lat + 1) / (nbLat + 1);
		float sin1 = sin(a1);
		float cos1 = cos(a1);

		for (int lon = 0; lon <= nbLong; ++lon)
		{
			float a2 = _2pi * float(lon == nbLong ? 0 : lon) / nbLong;
			float sin2 = sin(a2);
			float cos2 = cos(a2);
			int heightX = int(float(lon) / (nbLong)* heightMapWidth);
			int heightY = int(float(lat) / (nbLat)* heightMapHeight);
			if (lon == nbLong)
				heightX = 0;
			//float height = heightMap.GetValue(heightX, heightY) * radius * 0.05f;
			vertices[lon + lat * (nbLong + 1) + 1] = scalerMultiplyVector3(makeVector3(sin1 * cos2, cos1, sin1 * sin2), radius);
		}
	}
	vertices[nbVertices - 1] = scalerMultiplyVector3(vector3Up, -radius);
#pragma endregion

#pragma region Normales
	normales = std::vector<Vector3>(nbVertices);
	for (int n = 0; n < nbVertices; n++)
		normales[n] = normalizeVector3(vertices[n]);
#pragma endregion

#pragma region UVs
	uvs = std::vector<Vector2>(nbVertices);
	uvs[0] = makeVector2(1.0f, 1.0f);
	uvs[nbVertices - 1] = makeVector2(0.0f, 0.0f);
	for (int lat = 0; lat < nbLat; lat++)
		for (int lon = 0; lon <= nbLong; lon++)
			uvs[lon + lat * (nbLong + 1) + 1] = makeVector2((float)lon / nbLong, 1.0f - (float)(lat + 1) / (nbLat + 1));
#pragma endregion

#pragma region Triangles
	const int nbFaces = nbVertices;
	const int nbTriangles = nbFaces * 2;
	const int nbIndexes = nbTriangles * 3;
	triangles = std::vector<GLuint>(nbIndexes);

	//Top Cap
	int i = 0;
	for (int lon = 0; lon < nbLong; ++lon)
	{
		triangles[i++] = lon + 2;
		triangles[i++] = lon + 1;
		triangles[i++] = 0;
	}

	//Middle
	for (int lat = 0; lat < nbLat - 1; ++lat)
	{
		for (int lon = 0; lon < nbLong; ++lon)
		{
			int current = lon + lat * (nbLong + 1) + 1;
			int next = current + nbLong + 1;

			triangles[i++] = current;
			triangles[i++] = current + 1;
			triangles[i++] = next + 1;

			triangles[i++] = current;
			triangles[i++] = next + 1;
			triangles[i++] = next;
		}
	}

	//Bottom Cap
	for (int lon = 0; lon < nbLong; ++lon)
	{
		triangles[i++] = nbVertices - 1;
		triangles[i++] = nbVertices - (lon + 2) - 1;
		triangles[i++] = nbVertices - (lon + 1) - 1;
	}

	Vnu = std::vector<VertexDataPNT>(nbVertices);

	for (int i = 0; i < nbVertices; ++i)
	{
		VertexDataPNT pnt;
		pnt.positionCoordinates = vertices[i];
		pnt.normalCoordinates = normales[i];
		pnt.textureCoordinates = uvs[i];
		Vnu[i] = pnt;
	}
#pragma endregion
}
Пример #4
0
  /*
   * Tries to load vmap and tilemap for a gridtile and creates a navmesh for it.
   *
   */
  bool
  ModelContainerView::generateMoveMapForTile (int pMapId, int x, int y)
  {
        bool result = iVMapManager.loadMap (gVMapDataDir.c_str (), pMapId, x, y) == VMAP_LOAD_RESULT_OK;
        if (result == VMAP_LOAD_RESULT_OK)
        {
            //VMap loaded. Add data from vmap to global Triangle-Array
            parseVMap (pMapId, x, y);
        }
        // Add data from Height-Map to global Triangle-Array
        generateHeightMap(pMapId,x,y);
        // We will now add all triangles inside the given zone to the vectormap.
        // We could also do additional checks here.
        double x_max = (32-x)*SIZE_OF_GRIDS + 50;
        double y_max = (32-y)*SIZE_OF_GRIDS + 50;
        double x_min = x_max - SIZE_OF_GRIDS - 100;
        double y_min = y_max - SIZE_OF_GRIDS - 100;
        Vector3 low = Vector3(x_min,y_min,-inf());
        Vector3 high = Vector3(x_max,y_max,inf());
        AABox checkBox = AABox(low,high);
        AABox check;
        Triangle t;
        //each triangle has mangos format.
        for (int i = 0; i < globalTriangleArray.size(); i++) {
            t = globalTriangleArray[i];
            t.getBounds(check);
            if (checkBox.contains(check)) {
                // Write it down in detour format.
                iGlobArray.append(t.vertex(0).y,t.vertex(0).z,t.vertex(0).x);
                iGlobArray.append(t.vertex(1).y,t.vertex(1).z,t.vertex(1).x);
                iGlobArray.append(t.vertex(2).y,t.vertex(2).z,t.vertex(2).x);
            }
                
        }
        if (iGlobArray.size() == 0) {
            printf("No models - check your mmap.datadir in your config");
            return true;
        }

        if(gMakeObjFile)
            debugGenerateObjFile(); // create obj file for Recast Demo viewer
        //return true;
        float bmin[3], bmax[3];
        /*
         * The format looks like this
         * Verticle = float[3]
         * Triangle = Verticle[3]
         * So there are
         * array.size() floats
         * that means there are
         * nverts = array.size()/3 Verticles
         * that means there are
         * ntris = nverts/3
         */
         //array/3 verticles
        const int nverts = iGlobArray.size()/3; // because 1 vert is 3 float.
        // -> vert = float[3]
        const float* verts = iGlobArray.getCArray();
        rcCalcBounds(verts,nverts,bmin,bmax);
        // nverts/3 triangles
        // -> Triangle = vert[3] = float[9]
        int* tris = new int[nverts];// because 1 triangle is 3 verts
        for (int i = 0; i< nverts; i++)
            tris[i] = i;
        /* tris[i] = 1,2,3;4,5,6;7,8,9;
         *
         */
        const int ntris = (nverts/3);
	rcConfig m_cfg;
	//
	// Step 1. Initialize build config.
	//

	// Init build configuration from GUI
	memset(&m_cfg, 0, sizeof(m_cfg));
        // Change config settings here!
	m_cfg.cs = 0.3f;
	m_cfg.ch = 0.2f;
	m_cfg.walkableSlopeAngle = 50.0f;
	m_cfg.walkableHeight = 10;
	m_cfg.walkableClimb = 4;
	m_cfg.walkableRadius = 2;
	m_cfg.maxEdgeLen = (int)(12 / 0.3f);
	m_cfg.maxSimplificationError = 1.3f;
	m_cfg.minRegionSize = (int)rcSqr(50);
	m_cfg.mergeRegionSize = (int)rcSqr(20);
	m_cfg.maxVertsPerPoly = (int)6;
	m_cfg.detailSampleDist = 1.8f;
	m_cfg.detailSampleMaxError = 0.2f * 1;
        bool m_keepInterResults = false;
        printf("CellSize        : %.2f\n",m_cfg.cs);
        printf("CellHeight      : %.2f\n",m_cfg.ch);
        printf("WalkableSlope   : %.2f\n",m_cfg.walkableSlopeAngle);
        printf("WalkableHeight  : %i\n",m_cfg.walkableHeight);
        printf("walkableClimb   : %i\n",m_cfg.walkableClimb);
        printf("walkableRadius  : %i\n",m_cfg.walkableRadius);
        printf("maxEdgeLen      : %i\n",m_cfg.maxEdgeLen);
        printf("maxSimplific.Er.: %.2f\n",m_cfg.maxSimplificationError);
        printf("minRegionSize   : %i\n",m_cfg.minRegionSize);
        printf("mergedRegSize   : %i\n",m_cfg.mergeRegionSize);
        printf("maxVertsPerPoly : %i\n",m_cfg.maxVertsPerPoly);
        printf("detailSampledist: %.2f\n",m_cfg.detailSampleDist);
        printf("det.Samp.max.err: %.2f\n",m_cfg.detailSampleMaxError);
	// Set the area where the navigation will be build.
	// Here the bounds of the input mesh are used, but the
	// area could be specified by an user defined box, etc.
	vcopy(m_cfg.bmin, bmin);
	vcopy(m_cfg.bmax, bmax);
	rcCalcGridSize(m_cfg.bmin, m_cfg.bmax, m_cfg.cs, &m_cfg.width, &m_cfg.height);

	//
	// Step 2. Rasterize input polygon soup.
	//

	// Allocate voxel heighfield where we rasterize our input data to.
	rcHeightfield* m_solid = new rcHeightfield;
	if (!m_solid)
	{
		printf("buildNavigation: Out of memory 'solid'.\n");
		return false;
	}
	if (!rcCreateHeightfield(*m_solid, m_cfg.width, m_cfg.height, m_cfg.bmin, m_cfg.bmax, m_cfg.cs, m_cfg.ch))
	{
		printf("buildNavigation: Could not create solid heightfield.\n");
		return false;
	}

	// Allocate array that can hold triangle flags.
	// If you have multiple meshes you need to process, allocate
	// and array which can hold the max number of triangles you need to process.
	unsigned char* m_triflags = new unsigned char[ntris];
	if (!m_triflags)
	{
		printf("buildNavigation: Out of memory 'triangleFlags' (%d).\n", ntris);
		return false;
	}

	// Find triangles which are walkable based on their slope and rasterize them.
	// If your input data is multiple meshes, you can transform them here, calculate
	// the flags for each of the meshes and rasterize them.
	memset(m_triflags, 0, ntris*sizeof(unsigned char));
	rcMarkWalkableTriangles(m_cfg.walkableSlopeAngle, verts, nverts, tris, ntris, m_triflags);
	rcRasterizeTriangles(verts, nverts, tris, m_triflags, ntris, *m_solid, m_cfg.walkableClimb);

    // should delete [] verts?  - probably not, this is just pointer to data in a G3D Array
    // should delete [] tris?

	if (!m_keepInterResults)
	{
		delete [] m_triflags;
		m_triflags = 0;
	}

	//
	// Step 3. Filter walkables surfaces.
	//

	// Once all geoemtry is rasterized, we do initial pass of filtering to
	// remove unwanted overhangs caused by the conservative rasterization
	// as well as filter spans where the character cannot possibly stand.
	rcFilterLowHangingWalkableObstacles(m_cfg.walkableClimb, *m_solid);
	rcFilterLedgeSpans(m_cfg.walkableHeight, m_cfg.walkableClimb, *m_solid);
	rcFilterWalkableLowHeightSpans(m_cfg.walkableHeight, *m_solid);


	//
	// Step 4. Partition walkable surface to simple regions.
	//

	// Compact the heightfield so that it is faster to handle from now on.
	// This will result more cache coherent data as well as the neighbours
	// between walkable cells will be calculated.
	rcCompactHeightfield* m_chf = new rcCompactHeightfield;
	if (!m_chf)
	{
		printf("buildNavigation: Out of memory 'chf'.\n");
		return false;
	}
	if (!rcBuildCompactHeightfield(m_cfg.walkableHeight, m_cfg.walkableClimb, RC_WALKABLE, *m_solid, *m_chf))
	{
		printf( "buildNavigation: Could not build compact data.\n");
		return false;
	}

	if (!m_keepInterResults)
	{
		delete m_solid;
		m_solid = 0;
	}

	// Erode the walkable area by agent radius.
	if (!rcErodeArea(RC_WALKABLE_AREA, m_cfg.walkableRadius, *m_chf))
	{
		printf("buildNavigation: Could not erode.\n");
		return false;
	}

	// (Optional) Mark areas.
	//const ConvexVolume* vols = m_geom->getConvexVolumes();
	//for (int i  = 0; i < m_geom->getConvexVolumeCount(); ++i)
	//	rcMarkConvexPolyArea(vols[i].verts, vols[i].nverts, vols[i].hmin, vols[i].hmax, (unsigned char)vols[i].area, *m_chf);

	// Prepare for region partitioning, by calculating distance field along the walkable surface.
	if (!rcBuildDistanceField(*m_chf))
	{
		printf("buildNavigation: Could not build distance field.\n");
		return false;
	}

	// Partition the walkable surface into simple regions without holes.
	if (!rcBuildRegions(*m_chf, m_cfg.borderSize, m_cfg.minRegionSize, m_cfg.mergeRegionSize))
	{
		printf("buildNavigation: Could not build regions.\n");
	}

	//
	// Step 5. Trace and simplify region contours.
	//

	// Create contours.
	rcContourSet* m_cset = new rcContourSet;
	if (!m_cset)
	{
		printf("buildNavigation: Out of memory 'cset'.\n");
		return false;
	}
	if (!rcBuildContours(*m_chf, m_cfg.maxSimplificationError, m_cfg.maxEdgeLen, *m_cset))
	{
		printf("buildNavigation: Could not create contours.\n");
		return false;
	}

	//
	// Step 6. Build polygons mesh from contours.
	//

	// Build polygon navmesh from the contours.
	rcPolyMesh* m_pmesh = new rcPolyMesh;
	if (!m_pmesh)
	{
		printf("buildNavigation: Out of memory 'pmesh'.\n");
		return false;
	}
	if (!rcBuildPolyMesh(*m_cset, m_cfg.maxVertsPerPoly, *m_pmesh))
	{
		printf( "buildNavigation: Could not triangulate contours.\n");
		return false;
	}

	//
	// Step 7. Create detail mesh which allows to access approximate height on each polygon.
	//

	rcPolyMeshDetail* m_dmesh = new rcPolyMeshDetail;
	if (!m_dmesh)
	{
		printf("buildNavigation: Out of memory 'pmdtl'.\n");
		return false;
	}

	if (!rcBuildPolyMeshDetail(*m_pmesh, *m_chf, m_cfg.detailSampleDist, m_cfg.detailSampleMaxError, *m_dmesh))
	{
		printf("buildNavigation: Could not build detail mesh.\n");
	}

	if (!m_keepInterResults)
	{
		delete m_chf;
		m_chf = 0;
		delete m_cset;
		m_cset = 0;
	}

	// At this point the navigation mesh data is ready, you can access it from m_pmesh.
	// See duDebugDrawPolyMesh or dtCreateNavMeshData as examples how to access the data.

	//
	// (Optional) Step 8. Create Detour data from Recast poly mesh.
	//

	// The GUI may allow more max points per polygon than Detour can handle.
	// Only build the detour navmesh if we do not exceed the limit.
	if (m_cfg.maxVertsPerPoly <= DT_VERTS_PER_POLYGON)
	{
		unsigned char* navData = 0;
		int navDataSize = 0;
                // Update poly flags from areas.
		for (int i = 0; i < m_pmesh->npolys; ++i)
		{
                    // for now all generated navmesh is walkable by everyone.
                    // else there will be no pathfinding at all!
                    m_pmesh->flags[i] = RC_WALKABLE_AREA;
		}

		dtNavMeshCreateParams params;
		memset(&params, 0, sizeof(params));
		params.verts = m_pmesh->verts;
		params.vertCount = m_pmesh->nverts;
		params.polys = m_pmesh->polys;
		params.polyAreas = m_pmesh->areas;
		params.polyFlags = m_pmesh->flags;
		params.polyCount = m_pmesh->npolys;
		params.nvp = m_pmesh->nvp;
		params.detailMeshes = m_dmesh->meshes;
		params.detailVerts = m_dmesh->verts;
		params.detailVertsCount = m_dmesh->nverts;
		params.detailTris = m_dmesh->tris;
		params.detailTriCount = m_dmesh->ntris;
		params.offMeshConVerts = 0;
		params.offMeshConRad = 0;
		params.offMeshConDir = 0;
		params.offMeshConAreas = 0;
		params.offMeshConFlags = 0;
		params.offMeshConCount = 0;
		params.walkableHeight = 2.0f;
		params.walkableRadius = 0.6f;
		params.walkableClimb = 0.9f;
		vcopy(params.bmin, m_pmesh->bmin);
		vcopy(params.bmax, m_pmesh->bmax);
		params.cs = m_cfg.cs;
		params.ch = m_cfg.ch;
		printf("vertcount       : %05u\n",params.vertCount);
                printf("polycount       : %05u\n",params.polyCount);
                printf("detailVertsCount: %05u\n",params.detailVertsCount);
                printf("detailTriCount  : %05u\n",params.detailTriCount);
                printf("walkableClimb   : %.2f\n",params.walkableClimb);
                printf("walkableRadius  : %.2f\n",params.walkableRadius);
                printf("walkableHeight  : %.2f\n",params.walkableHeight);
		if (!dtCreateNavMeshData(&params, &navData, &navDataSize))
		{
			printf("Could not build Detour navmesh.\n");
			return false;
		}
                // navData now contains the MoveMap
                printf("Generated Navigation Mesh! Size: %i bytes/ %i kB / %i MB\n",navDataSize,navDataSize/1024,navDataSize/(1024*1024));
                char tmp[14];
                sprintf(tmp, "%03u%02u%02u.mmap",iMap,ix,iy);
                std::string savefilepath = gMMapDataDir + "/" + tmp;
                ofstream inf( savefilepath.c_str(),ofstream::binary );
                if( inf )
                {
                        inf.write( (char*)( &navData[0] ), navDataSize ) ;
                }
                printf("MoveMap saved under %s\n", savefilepath.c_str());
                delete [] navData;
        }
       // debugLoadNavMesh();
        return (result);
  }