roadgeom.cc
来自「机器人人3D仿真工具,可以加入到Simbad仿真环境下应用。」· CC 代码 · 共 630 行 · 第 1/2 页
CC
630 行
// Figure our where we are in the profile ti = (int) (floor(t / this->profileScale)); tm = t / this->profileScale - ti; ti += point->profilePointCount / 2; //printf("t ti tm %f %d %f\n", t, ti, tm); // Spline control point indexes n0 = ti - 1; n1 = ti + 0; n2 = ti + 1; n3 = ti + 2; // Handle boundary conditions for spline fit n0 = Min(Max(0, n0), point->profilePointCount - 1); n1 = Min(Max(0, n1), point->profilePointCount - 1); n2 = Min(Max(0, n2), point->profilePointCount - 1); n3 = Min(Max(0, n3), point->profilePointCount - 1); assert(n0 >= 0 && n0 < point->profilePointCount); assert(n1 >= 0 && n1 < point->profilePointCount); assert(n2 >= 0 && n2 < point->profilePointCount); assert(n3 >= 0 && n3 < point->profilePointCount); // Use a spline to interpolate our altitude p = this->SplineCR(tm, point->profilePoints[n0], point->profilePoints[n1], point->profilePoints[n2], point->profilePoints[n3]); // Update the vertex position vertex[0] = o.x - ot.y * t; vertex[1] = o.y + ot.x * t; vertex[2] = o.z + p.z; } } // Compute normal vectors this->UpdateNormals(); // Construct the trimesh data dGeomTriMeshDataBuildSimple(this->tridata, (dReal*) this->vertices, this->vertexCount, this->indices, this->indexCount); dGeomTriMeshSetData(this->trimesh, this->tridata); return;}//////////////////////////////////////////////////////////////////////////////// Compute normal vectors on verticesvoid RoadGeom::UpdateNormals(){ int i, a, b, c; dVector3 *v; GzVector v0, v1, v2, n; v = this->vertices; // Reset the normals for (i = 0; i < this->vertexCount; i++) this->normals[i] = GzVectorZero(); // Consider each triangle for (i = 0; i < this->indexCount; i += 3) { a = this->indices[i + 0]; b = this->indices[i + 1]; c = this->indices[i + 2]; // Compute the normal v0 = GzVectorSet(v[a][0], v[a][1], v[a][2]); v1 = GzVectorSet(v[b][0], v[b][1], v[b][2]); v2 = GzVectorSet(v[c][0], v[c][1], v[c][2]); n = GzVectorCross(GzVectorSub(v1, v0), GzVectorSub(v2, v1)); n = GzVectorUnit(n); // Accumate normals across triangles // We assume normals are being normalized by OpenGL this->normals[a] = GzVectorAdd(this->normals[a], n); this->normals[b] = GzVectorAdd(this->normals[b], n); this->normals[c] = GzVectorAdd(this->normals[c], n); } return;}//////////////////////////////////////////////////////////////////////////////// Compute a Catmull-Rom splineGzVector RoadGeom::SplineCR(double t, GzVector p0, GzVector p1, GzVector p2, GzVector p3){ GzVector q; q.x = 2*p1.x + (-p0.x + p2.x) * t + (2*p0.x - 5 * p1.x + 4*p2.x - p3.x) * t*t + (-p0.x + 3*p1.x - 3*p2.x + p3.x) * t*t*t; q.y = 2*p1.y + (-p0.y + p2.y) * t + (2*p0.y - 5 * p1.y + 4*p2.y - p3.y) * t*t + (-p0.y + 3*p1.y - 3*p2.y + p3.y) * t*t*t; q.z = 2*p1.z + (-p0.z + p2.z) * t + (2*p0.z - 5 * p1.z + 4*p2.z - p3.z) * t*t + (-p0.z + 3*p1.z - 3*p2.z + p3.z) * t*t*t; q = GzVectorMul(0.5, q); return q;}//////////////////////////////////////////////////////////////////////////////// Compute a Catmull-Rom spline tangentGzVector RoadGeom::SplineCRtan(double t, GzVector p0, GzVector p1, GzVector p2, GzVector p3){ GzVector v0, v1, v; v0 = GzVectorSub(p2, p0); v0 = GzVectorMul(0.5, v0); v1 = GzVectorSub(p3, p1); v1 = GzVectorMul(0.5, v1); v = GzVectorMul((1 - t), v0); v = GzVectorAdd(v, GzVectorMul(t, v1)); v = GzVectorUnit(v); return v;}//////////////////////////////////////////////////////////////////////////////// Default render routinevoid RoadGeom::Render(RenderOptions *opt){ int i, j; int ni, nj, mi, mj; GLuint listId; RenderOptions listOpt; // Recover stored display list for this camera this->GetList(opt->cameraIndex, &listId, &listOpt); // See if the current display list is dirty this->dirty |= (listId == 0); this->dirty |= (opt->displayMaterials != listOpt.displayMaterials); this->dirty |= (opt->displayTextures != listOpt.displayTextures); // Compute offset based on old camera pose mi = (int) floor(listOpt.cameraPose.pos.x / this->patchSize + 0.5); mj = (int) floor(listOpt.cameraPose.pos.y / this->patchSize + 0.5); // Compute offset based on new camera pose ni = (int) floor(opt->cameraPose.pos.x / this->patchSize + 0.5); nj = (int) floor(opt->cameraPose.pos.y / this->patchSize + 0.5); // If the offset has changed, we need to redraw this->dirty |= (ni != mi); this->dirty |= (nj != mj); // Generate the display list if (this->dirty) { 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); } 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_REPEAT); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); // 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); glEnable(GL_TEXTURE_2D); } dReal *v; GzVector n; double tx, ty; // Texture scale; each texture image is scaled such that it maps // to a road patch of size textureSize tx = this->scale / this->textureSize.x; ty = this->scale / this->textureSize.y; // Construct triangle strips for (i = 0; i < this->stepsX - 1; i++) { // Test vertex to see if it is near the current camera position v = this->vertices[this->stepsY * i + this->stepsY / 2]; if (fabs(v[0] - opt->cameraPose.pos.x) > opt->farClip) continue; if (fabs(v[1] - opt->cameraPose.pos.y) > opt->farClip) continue; glBegin(GL_TRIANGLE_STRIP); for (j = 0; j < this->stepsY; j++) { glTexCoord2f(i * tx, j * tx); n = this->normals[this->stepsY * (i + 0) + j]; v = this->vertices[this->stepsY * (i + 0) + j]; glNormal3f(n.x, n.y, n.z); glVertex3f(v[0], v[1], v[2]); glTexCoord2f((i + 1) * tx, j * tx); n = this->normals[this->stepsY * (i + 1) + j]; v = this->vertices[this->stepsY * (i + 1) + j]; glNormal3f(n.x, n.y, n.z); glVertex3f(v[0], v[1], v[2]); } glEnd(); } if (opt->displayTextures && this->textureImage) glDisable(GL_TEXTURE_2D); // Display signs this->RenderSigns(opt, listOpt); // Store list options this->SetList(opt->cameraIndex, listId, *opt); glEndList(); } // Call the display list if (listId) glCallList(listId); return;}//////////////////////////////////////////////////////////////////////////////// Render signsvoid RoadGeom::RenderSigns(RenderOptions *opt, RenderOptions listOpt){ int i, j; double size; GzVector p; SignData *sign; // Set material properties if (opt->displayMaterials) { glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, GzColor(0, 0, 0)); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, GzColor(0, 0, 0)); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, GzColor(0, 0, 0)); } for (i = 0; i < this->signCount; i++) { sign = this->signs + i; p = sign->pos; // Test sign to see if it is near the current camera position if (fabs(p.x - opt->cameraPose.pos.x) > opt->farClip) continue; if (fabs(p.y - opt->cameraPose.pos.y) > opt->farClip) continue; // Set sign hight size = 0.80; // Print the sign glPushMatrix(); glTranslatef(p.x, p.y, p.z + 1.0); // HACK glRotatef(90, 1, 0, 0); glScalef(size / 150, size / 150, size / 150); for (j = 0; j < (int) strlen(sign->text); j++) glutStrokeCharacter(GLUT_STROKE_MONO_ROMAN, sign->text[j]); glPopMatrix(); // Print a little stand glBegin(GL_LINES); glVertex3f(p.x, p.y, p.z - size / 2); glVertex3f(p.x, p.y, 0.0); glEnd(); } return;}#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?