domegeom.cc

来自「机器人人3D仿真工具,可以加入到Simbad仿真环境下应用。」· CC 代码 · 共 294 行

CC
294
字号
/* *  Gazebo - Outdoor Multi-Robot Simulator *  Copyright (C) 2003   *     Nate Koenig & Andrew Howard * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA * *//* Desc: Dome geometry * Author: Nate Keonig * Date: 24 Nov 2004 * CVS: $Id: DomeGeom.cc,v 1.6 2004/12/07 00:15:06 natepak Exp $ * * Notes: This is not a placeable geometry, so position and * orientation are undefined. */#include <math.h>#include <sys/time.h>#include <GL/glu.h>#include "Error.hh"#include "Image.hh"#include "DomeGeom.hh"// TODO: Use vertex shaders to render sky. Can use half a sphere fixed in// from of the camera, and each vertex's texture and color attributes change// as the camera moves. Would reduce number of triangles, but not sure if// this method is beneficial - especially since it will be incompatible with// cards that don't support shaders.//////////////////////////////////////////////////////////////////////////////// ConstructorDomeGeom::DomeGeom( Body *body, dSpaceID spaceId, int resolution)  : Geom(spaceId){  this->origin = GzVectorSet(0,0,-.1);  this->resolution = resolution;  this->vertices = NULL;  this->vertexCount = 0;  this->elapsedTime = 0;  this->prevElapsedTime = 0;  // This geom is not placable  this->SetGeom(body, NULL, NULL, false);  this->renderOrder = GZ_RENDER_LIGHT;  return;}//////////////////////////////////////////////////////////////////////////////// DestructorDomeGeom::~DomeGeom(){  return;}void DomeGeom::SetDayTime( double seconds ){  this->startTime = seconds;}void DomeGeom::SetElapsedTime( double seconds ){  this->elapsedTime = seconds;}//////////////////////////////////////////////////////////////////////////////// Default render routinevoid DomeGeom::Render(RenderOptions *opt){  int i,j;  int delta = this->resolution * 4;  int start, end;  //int currTime;  double texS;  //timeval tv;  //tm *tmpTime = NULL;  GLuint listId;  RenderOptions listOpt;  if (this->textureImage==NULL)    return;  // Recover stored display list for this camera  this->GetList(opt->cameraIndex, &listId, &listOpt);  texS = (this->startTime + this->elapsedTime) / 86400.0;   // See if the current display list is dirty  this->dirty |= (listId == 0);  this->dirty |= (opt->displayMaterials != listOpt.displayMaterials);  this->dirty |= (opt->displayTextures != listOpt.displayTextures);  this->dirty |= (this->elapsedTime-this->prevElapsedTime) >= (86400.0 / this->textureImage->width);      // Generate the display list  if (this->dirty)  {    this->prevElapsedTime = this->elapsedTime;    if (listId == 0)      listId = glGenLists(1);        glNewList(listId, GL_COMPILE);    // Set material properties    /*if (opt->displayMaterials)      {      glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, this->colorAmbient);      glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, this->colorDiffuse);      glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, this->colorSpecular);      glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, this->shininess);      PRINT_GL_ERR();      }*/    if (opt->displayTextures && this->textureImage)    {      // Set up textures      glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);      glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);      glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);      glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);      //glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);      glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);      PRINT_GL_ERR();      // Build the mipmaps      // Assume image data is *not* aligned      glPixelStorei( GL_UNPACK_ALIGNMENT, 1);      gluBuild2DMipmaps(GL_TEXTURE_2D, this->textureImage->components,          this->textureImage->width, this->textureImage->height,          this->textureImage->format, this->textureImage->type,          this->textureImage->data);      PRINT_GL_ERR();    }    if (opt->displayTextures && this->textureImage)      glEnable(GL_TEXTURE_2D);    // Create the dome geometry, once only.    // Make the dome slightly smaller than the far clip so that the     // dome doesn't get clipped.    if (this->vertexCount == 0)      this->CreateMesh(opt->farClip*0.8);    // Disable writing to the depth buffer    glDepthMask(GL_FALSE);    // Draw top of dome as a triangle fan    glBegin(GL_TRIANGLE_FAN);    glTexCoord2f(texS,0);    glVertex3fv(this->vertices);    for (i = 1; i <= this->resolution * 4; i++)    {      glTexCoord2f(texS,1.0/this->resolution);      glVertex3fv(this->vertices+i*3);    }    glTexCoord2f(texS,1.0/this->resolution);    glVertex3fv(this->vertices+3);    glEnd();    // Draw rest of dome as triangle strip    for (i=1; i<this->resolution; i++)    {      start = delta * i + 1;       end = start + delta;      glBegin(GL_TRIANGLE_STRIP);      for (j=start; j<end; j++)      {        glTexCoord2f(texS,i/(float)this->resolution);        glVertex3fv(this->vertices+(j-delta)*3);        glTexCoord2f(texS,(i+1)/(float)this->resolution);        glVertex3fv(this->vertices+j*3);      }      glTexCoord2f(texS,(i)/(float)this->resolution);      glVertex3fv(this->vertices+(start-delta)*3);      glTexCoord2f(texS,(i+1)/(float)this->resolution);      glVertex3fv(this->vertices+start*3);      glEnd();    }    // Enable writing to the depth buffer    glDepthMask(GL_TRUE);    if (opt->displayTextures && this->textureImage)      glDisable(GL_TEXTURE_2D);    // Store list options    this->SetList(opt->cameraIndex, listId, *opt);          glEndList();  }  // Call the display list  if (listId)  {    // Keep the dome centered around the camera    glTranslatef(opt->cameraPose.pos.x, opt->cameraPose.pos.y, 0);    glCallList(listId);    PRINT_GL_ERR();  }  return;}//////////////////////////////////////////////////////////////////////////////// Create the triangle mesh for the sky domevoid DomeGeom::CreateMesh( double radius ){  GzVector point;  GzVector vertex;  GzHomo homo;  double vertSweep;  double horzSweep;  double radiusAngle;  double zAdj;  double vscale = 1.0;  int numVerts=1;  int i,j;  // Compute the number of vertices  this->vertexCount = 1 + 4 * this->resolution * this->resolution;  this->vertices = new GLfloat[this->vertexCount * 3];  vertSweep = M_PI * 0.5; // 90 degree vertical sweep  // From the resolution, compute the angular sweep of one section of the  // dome  horzSweep = (M_PI*0.5) / (float)this->resolution;  // Adjust the radius based on the vertical sweep  radiusAngle = (M_PI*0.5) - vertSweep;  radius /= cos(radiusAngle);  // Compute the z adjustment  zAdj = radius * sin(radiusAngle);  // Adjust the vertical resolution  vertSweep /= (float)this->resolution;  // Start the vertex list wit the very top of the dome  this->vertices[0] = this->origin.x;  this->vertices[1] = this->origin.y;  this->vertices[2] = (radius - zAdj) * vscale + this->origin.z;  // Starting from the top, populate with this->resolution number of rings  for (i=0; i<this->resolution; i++)  {    // Compute the vertex that will be rotated around to make the ring    homo = GzHomoFromQuatern( GzQuaternFromEuler(0, vertSweep * (i+1),0) );    point = GzHomoMul( homo, GzVectorSet(0,0,radius));    point.z = (point.z - zAdj) * vscale;    for (j=0; j<this->resolution * 4; j++)    {      homo = GzHomoFromQuatern( GzQuaternFromEuler(0,0,horzSweep * j) );      vertex = GzHomoMul(homo, point);      vertex = GzVectorAdd(vertex, this->origin);      this->vertices[numVerts*3] = vertex.x ;      this->vertices[numVerts*3+1] = vertex.y;      this->vertices[numVerts*3+2] = vertex.z;      numVerts++;    }  }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?