bool ModelClass::CalculateBNT(ID3D11Device* device) { if(!m_vertexBuffer) { return false; } for(int i=0; i < m_vertexCount; i+=3) { CalculateTangentBinormal(i, i+1, i+2); CalculateNormal(i, i+1, i+2); } InitializeBuffers(device); return true; }
void ModelClass::CalculateModelVectors() { int faceCount, index; TempVertexType vertex[3]; XMFLOAT3 tangent, binormal, normal; faceCount = mVertexCount / 3; index = 0; for (int i = 0; i < faceCount; ++i) { for (int z = 0; z < 3; ++z) { vertex[z].x = mModel[index].x; vertex[z].y = mModel[index].y; vertex[z].z = mModel[index].z; vertex[z].tu = mModel[index].tu; vertex[z].tv = mModel[index].tv; vertex[z].nx = mModel[index].nx; vertex[z].ny = mModel[index].ny; vertex[z].nz = mModel[index].nz; ++index; } CalculateTangentBinormal(vertex[0], vertex[1], vertex[2], tangent, binormal); CalculateNormal(tangent, binormal, normal); for (int z = 0; z < 3; ++z) { mModel[index - 1 - z].nx = normal.x; mModel[index - 1 - z].ny = normal.y; mModel[index - 1 - z].nz = normal.z; mModel[index - 1 - z].tx = tangent.x; mModel[index - 1 - z].ty = tangent.y; mModel[index - 1 - z].tz = tangent.z; mModel[index - 1 - z].bx = binormal.x; mModel[index - 1 - z].by = binormal.y; mModel[index - 1 - z].bz = binormal.z; } } }
void ModelClass::CalculateModelVectors() { int faceCount, i, index; TempVertexType vertex1, vertex2, vertex3; VectorType tangent, binormal, normal; faceCount = m_vertexCount / 3; index = 0; for (i = 0; i != faceCount; ++i) { loadStruct(vertex1, m_Model, index++); loadStruct(vertex2, m_Model, index++); loadStruct(vertex3, m_Model, index++); CalculateTangentBinormal(vertex1, vertex2, vertex3, tangent, binormal); CalculateNormal(tangent, binormal, normal); loadModel(m_Model, index, tangent, binormal, normal); } }
void SuperEllipsoid::create(int samples, float n1, float n2, const Ogre::Vector3& scale) { float phi = 0.0, beta = 0.0; Ogre::Vector3 p1, p2, p3; float dB = Ogre::Math::TWO_PI/samples; float dP = Ogre::Math::TWO_PI/samples; phi = -Ogre::Math::HALF_PI; manual_object_->clear(); manual_object_->begin( material_name_, Ogre::RenderOperation::OT_TRIANGLE_LIST ); float scale_x = scale.x / 2.0f; float scale_y = scale.y / 2.0f; float scale_z = scale.z / 2.0f; for(int j=0; j<=samples/2; j++) { beta = -Ogre::Math::PI; for(int i=0; i<=samples; i++) { //Triangle #1 manual_object_->position(Sample(phi+dP, beta, n1, n2, scale_x, scale_y, scale_z)); manual_object_->normal(CalculateNormal(phi+dP, beta, n1, n2, scale_x, scale_y, scale_z)); manual_object_->position(Sample(phi, beta, n1, n2, scale_x, scale_y, scale_z)); manual_object_->normal(CalculateNormal(phi, beta, n1, n2, scale_x, scale_y, scale_z)); manual_object_->position(Sample(phi+dP, beta+dB, n1, n2, scale_x, scale_y, scale_z)); manual_object_->normal(CalculateNormal(phi+dP, beta+dB, n1, n2, scale_x, scale_y, scale_z)); //Triangle #2 manual_object_->position(Sample(phi+dP, beta+dB, n1, n2, scale_x, scale_y, scale_z)); manual_object_->normal(CalculateNormal(phi+dP, beta+dB, n1, n2, scale_x, scale_y, scale_z)); manual_object_->position(Sample(phi, beta, n1, n2, scale_x, scale_y, scale_z)); manual_object_->normal(CalculateNormal(phi, beta, n1, n2, scale_x, scale_y, scale_z)); manual_object_->position(Sample(phi, beta+dB, n1, n2, scale_x, scale_y, scale_z)); manual_object_->normal(CalculateNormal(phi, beta+dB, n1, n2, scale_x, scale_y, scale_z)); beta += dB; } phi += dP; } manual_object_->end(); }
void CalculateBoundaryVertexNormal3D(vector3& nOut, Grid& grid, Vertex* vrt, TAAPosVRT& aaPos) { // The algorithm is a little cumbersome. However, through this setup, we // make sure that the orientation of the normal indeed points outwards, // based only on the topology. // set nOut to 0 VecSet(nOut, 0); // iterate over associated volumes std::vector<Volume*> vols; CollectAssociated(vols, grid, vrt); FaceDescriptor fd; for(size_t i_vol = 0; i_vol < vols.size(); ++i_vol){ Volume* v = vols[i_vol]; // check for each side of f whether it is a boundary edge for(size_t i_side = 0; i_side < v->num_sides(); ++i_side){ if(IsBoundaryFace3D(grid, grid.get_face(v, i_side))){ v->face_desc(i_side, fd); // make sure that fd contains the given vertex if(!FaceContains(&fd, vrt)) continue; // the normal pointing outwards is clearly defined from the // orientation of the face descriptor vector3 n; CalculateNormal(n, &fd, aaPos); VecAdd(nOut, nOut, n); } } } VecNormalize(nOut, nOut); }
glm::dvec2 CollisionCircle::CalculateNormal(double relativePositionX, double relativePositionY) { return CalculateNormal(glm::dvec2(relativePositionX, relativePositionY)); }
void Cube::CalculateModelVectors() { int faceCount, i, index; TempVertexType vertex1, vertex2, vertex3; VectorType tangent, binormal, normal; // Calculate the number of faces in the model. faceCount = m_VertexCount / 3; // Initialize the index to the model data. index = 0; // Go through all the faces and calculate the the tangent, binormal, and normal vectors. for (i=0; i < faceCount; i++) { // Get the three vertices for this face from the model. vertex1.x = pModelVertex[index].x; vertex1.y = pModelVertex[index].y; vertex1.z = pModelVertex[index].z; vertex1.tu = pModelVertex[index].tu; vertex1.tv = pModelVertex[index].tv; vertex1.nx = pModelVertex[index].nx; vertex1.ny = pModelVertex[index].ny; vertex1.nz = pModelVertex[index].nz; index++; vertex2.x = pModelVertex[index].x; vertex2.y = pModelVertex[index].y; vertex2.z = pModelVertex[index].z; vertex2.tu = pModelVertex[index].tu; vertex2.tv = pModelVertex[index].tv; vertex2.nx = pModelVertex[index].nx; vertex2.ny = pModelVertex[index].ny; vertex2.nz = pModelVertex[index].nz; index++; vertex3.x = pModelVertex[index].x; vertex3.y = pModelVertex[index].y; vertex3.z = pModelVertex[index].z; vertex3.tu = pModelVertex[index].tu; vertex3.tv = pModelVertex[index].tv; vertex3.nx = pModelVertex[index].nx; vertex3.ny = pModelVertex[index].ny; vertex3.nz = pModelVertex[index].nz; index++; // Calculate the tangent and binormal of that face. CalculateTangentBinormal(vertex1, vertex2, vertex3, tangent, binormal); // Calculate the new normal using the tangent and binormal. CalculateNormal(tangent, binormal, normal); // Store the normal, tangent, and binormal for this face back in the model structure. pModelVertex[index - 1].nx = normal.x; pModelVertex[index - 1].ny = normal.y; pModelVertex[index - 1].nz = normal.z; pModelVertex[index - 1].tx = tangent.x; pModelVertex[index - 1].ty = tangent.y; pModelVertex[index - 1].tz = tangent.z; pModelVertex[index - 1].bx = binormal.x; pModelVertex[index - 1].by = binormal.y; pModelVertex[index - 1].bz = binormal.z; pModelVertex[index - 2].nx = normal.x; pModelVertex[index - 2].ny = normal.y; pModelVertex[index - 2].nz = normal.z; pModelVertex[index - 2].tx = tangent.x; pModelVertex[index - 2].ty = tangent.y; pModelVertex[index - 2].tz = tangent.z; pModelVertex[index - 2].bx = binormal.x; pModelVertex[index - 2].by = binormal.y; pModelVertex[index - 2].bz = binormal.z; pModelVertex[index - 3].nx = normal.x; pModelVertex[index - 3].ny = normal.y; pModelVertex[index - 3].nz = normal.z; pModelVertex[index - 3].tx = tangent.x; pModelVertex[index - 3].ty = tangent.y; pModelVertex[index - 3].tz = tangent.z; pModelVertex[index - 3].bx = binormal.x; pModelVertex[index - 3].by = binormal.y; pModelVertex[index - 3].bz = binormal.z; } return; }
//---------------------------------------------------------------------------- void BouncingTetrahedra::Reposition (int t0, int t1, Contact& contact) { RigidTetra& tetra0 = *mTetras[t0]; RigidTetra& tetra1 = *mTetras[t1]; // Compute the centroids of the tetrahedra. Vector3f vertices0[4], vertices1[4]; tetra0.GetVertices(vertices0); tetra1.GetVertices(vertices1); Vector3f centroid0 = Vector3f::ZERO; Vector3f centroid1 = Vector3f::ZERO; int i; for (i = 0; i < 4; ++i) { centroid0 += vertices0[i]; centroid1 += vertices1[i]; } centroid0 *= 0.25f; centroid1 *= 0.25f; // Randomly perturb the tetrahedra vertices by a small amount. This is // done to help prevent the LCP solver from getting into cycles and // degenerate cases. const float reduction = 0.95f; float reduceI = reduction*Mathf::IntervalRandom(0.9999f, 1.0001f); float reduceJ = reduction*Mathf::IntervalRandom(0.9999f, 1.0001f); for (i = 0; i < 4; ++i) { vertices0[i] = centroid0 + (vertices0[i] - centroid0)*reduceI; vertices1[i] = centroid1 + (vertices1[i] - centroid1)*reduceJ; } // Compute the distance between the tetrahedra. float dist = 1.0f; int statusCode = 0; Vector3f closest[2]; LCPPolyDist3(4, vertices0, 4, mFaces, 4, vertices1, 4, mFaces, statusCode, dist, closest); ++mLCPCount; // In theory, LCPPolyDist<3> should always find a valid distance, but just // in case numerical round-off errors cause problems, let us trap it. assertion(dist >= 0.0f, "LCP polyhedron distance calculator failed.\n"); // Reposition the tetrahedra to the theoretical points of contact. closest[0] = centroid0 + (closest[0] - centroid0)/reduceI; closest[1] = centroid1 + (closest[1] - centroid1)/reduceJ; for (i = 0; i < 4; ++i) { vertices0[i] = centroid0 + (vertices0[i] - centroid0)/reduceI; vertices1[i] = centroid1 + (vertices1[i] - centroid1)/reduceJ; } // Numerical round-off errors can cause interpenetration. Move the // tetrahedra to back out of this situation. The length of diff // estimates the depth of penetration when dist > 0 was reported. Vector3f diff = closest[0] - closest[1]; // Apply the separation distance along the line containing the centroids // of the tetrahedra. Vector3f diff2 = centroid1 - centroid0; diff = diff2/diff2.Length()*diff.Length(); // Move each tetrahedron by half of kDiff when the distance was large, // but move each by twice kDiff when the distance is really small. float mult = (dist >= mTolerance ? 0.5f : 1.0f); Vector3f delta = mult*diff; // Undo the interpenetration. if (tetra0.Moved && !tetra1.Moved) { // Tetra t0 has moved but tetra t1 has not moved. tetra1.SetPosition(tetra1.GetPosition() + 2.0f*delta); tetra1.Moved = true; } else if (!tetra0.Moved && tetra1.Moved) { // Tetra t1 has moved but tetra t0 has not moved. tetra0.SetPosition(tetra0.GetPosition() - 2.0f*delta); tetra0.Moved = true; } else { // Both tetras moved or both tetras did not move. tetra0.SetPosition(tetra0.GetPosition() - delta); tetra0.Moved = true; tetra1.SetPosition(tetra1.GetPosition() + delta); tetra1.Moved = true; } // Test whether the two tetrahedra intersect in a vertex-face // configuration. contact.IsVFContact = IsVertex(vertices0, closest[0]); if (contact.IsVFContact) { contact.A = mTetras[t1]; contact.B = mTetras[t0]; CalculateNormal(vertices1, closest[1], contact); } else { contact.IsVFContact = IsVertex(vertices1, closest[1]); if (contact.IsVFContact) { contact.A = mTetras[t0]; contact.B = mTetras[t1]; CalculateNormal(vertices0, closest[0], contact); } } // Test whether the two tetrahedra intersect in an edge-edge // configuration. if (!contact.IsVFContact) { contact.A = mTetras[t0]; contact.B = mTetras[t1]; Vector3f otherVertexA = Vector3f::UNIT_X; Vector3f otherVertexB = Vector3f::ZERO; contact.EA = ClosestEdge(vertices0, closest[0], otherVertexA); contact.EB = ClosestEdge(vertices1, closest[1], otherVertexB); Vector3f normal = contact.EA.UnitCross(contact.EB); if (normal.Dot(otherVertexA - closest[0]) < 0.0f) { contact.N = normal; } else { contact.N = -normal; } } // Reposition results to correspond to relocaton of tetra. contact.PA = closest[0] - delta; contact.PB = closest[1] + delta; }
void Wall2D::SetTo(const cocos2d::CCPoint &v) { m_vB = v; CalculateNormal(); }
void Wall2D::SetFrom(const cocos2d::CCPoint &v) { m_vA = v; CalculateNormal(); }
// 以插值方式绘制模型,从而生成动画 // 成功返回0,失败返回-1 int CMD2Model::Animate(int startFrame, int endFrame, float percent) { // 当前帧的顶点 vector_t* vList; // 下一帧的顶点 vector_t* nextVList; // 当前帧顶点的坐标值 float x1, y1, z1; // 下一帧顶点的坐标值 float x2, y2, z2; vector_t vertex[3]; if (startFrame > currentFrame) { currentFrame = startFrame; } if ((startFrame < 0) || (endFrame < 0)) { return -1; } if ((startFrame >= numFrames) || (endFrame >= numFrames)) { return -1; } if (interpol >= 1.0f) { interpol = 0.0f; currentFrame++; if (currentFrame >= endFrame) { currentFrame = startFrame; } nextFrame = currentFrame + 1; if (nextFrame >= endFrame) { nextFrame = startFrame; } } vList = &vertexList[numVertices * currentFrame]; nextVList = &vertexList[numVertices * nextFrame]; glBindTexture(GL_TEXTURE_2D, modelTex->texID); glBegin(GL_TRIANGLES); for (int i = 0; i < numTriangles; i++) { // 获取每一关键帧中三角形的第一个顶点 x1 = vList[triIndex[i].meshIndex[0]].point[0]; y1 = vList[triIndex[i].meshIndex[0]].point[1]; z1 = vList[triIndex[i].meshIndex[0]].point[2]; x2 = nextVList[triIndex[i].meshIndex[0]].point[0]; y2 = nextVList[triIndex[i].meshIndex[0]].point[1]; z2 = nextVList[triIndex[i].meshIndex[0]].point[2]; // 存储三角形第一个顶点的插值 vertex[0].point[0] = x1 + interpol * (x2 - x1); vertex[0].point[1] = y1 + interpol * (y2 - y1); vertex[0].point[2] = z1 + interpol * (z2 - z1); // 获取每一关键帧中三角形的第二个顶点 x1 = vList[triIndex[i].meshIndex[2]].point[0]; y1 = vList[triIndex[i].meshIndex[2]].point[1]; z1 = vList[triIndex[i].meshIndex[2]].point[2]; x2 = nextVList[triIndex[i].meshIndex[2]].point[0]; y2 = nextVList[triIndex[i].meshIndex[2]].point[1]; z2 = nextVList[triIndex[i].meshIndex[2]].point[2]; // 存储三角形第二个顶点的插值 vertex[2].point[0] = x1 + interpol * (x2 - x1); vertex[2].point[1] = y1 + interpol * (y2 - y1); vertex[2].point[2] = z1 + interpol * (z2 - z1); // 获取每一关键帧中三角形的第三个顶点 x1 = vList[triIndex[i].meshIndex[1]].point[0]; y1 = vList[triIndex[i].meshIndex[1]].point[1]; z1 = vList[triIndex[i].meshIndex[1]].point[2]; x2 = nextVList[triIndex[i].meshIndex[1]].point[0]; y2 = nextVList[triIndex[i].meshIndex[1]].point[1]; z2 = nextVList[triIndex[i].meshIndex[1]].point[2]; // 存储三角形第三个顶点的插值 vertex[1].point[0] = x1 + interpol * (x2 - x1); vertex[1].point[1] = y1 + interpol * (y2 - y1); vertex[1].point[2] = z1 + interpol * (z2 - z1); // 计算三角形的法线 CalculateNormal(vertex[0].point, vertex[2].point, vertex[1].point); // 绘制正确的纹理三角形 glTexCoord2f(st[triIndex[i].stIndex[0]].s, st[triIndex[i].stIndex[0]].t); glVertex3fv(vertex[0].point); glTexCoord2f(st[triIndex[i].stIndex[2]].s, st[triIndex[i].stIndex[2]].t); glVertex3fv(vertex[2].point); glTexCoord2f(st[triIndex[i].stIndex[1]].s, st[triIndex[i].stIndex[1]].t); glVertex3fv(vertex[1].point); } glEnd(); interpol += percent; return 0; } // End of Animate()
void Decepticon :: DrawLowerLeg() { if (anti_aliasing) { glEnable (GL_LINE_SMOOTH); glEnable (GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glHint (GL_LINE_SMOOTH_HINT, GL_DONT_CARE); glLineWidth (1.5); } // if statement glScalef(1.1, 1.1, 1.1); ChangeColor(0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.8, 1.0); glBegin(display_mode); // lower leg back left edge glNormal3f(0, 0, -1); glVertex3f(-12.5, 5, -10); glVertex3f(-7.5, 5, -10); glVertex3f(-7.5, -10, -10); glVertex3f(-12.5, -10, -10); glEnd(); glBegin(display_mode); // lower leg top left edge glNormal3f(0, 1, 0); glVertex3f(-12.5, 5, -10); glVertex3f(-7.5, 5, -10); glVertex3f(-7.5, 5, 10); glVertex3f(-12.5, 5, 10); glEnd(); glBegin(display_mode); // lower leg front left edge CalculateNormal(5, -15, 5, 5, 0, 0); glNormal3f(normal_vector[0], normal_vector[1], normal_vector[2]); glVertex3f(-12.5, 5, 10); glVertex3f(-7.5, 5, 10); glVertex3f(-7.5, -10, 17.5); glVertex3f(-12.5, -10, 17.5); glEnd(); glBegin(display_mode); // lower leg bottom left edge glNormal3f(0, -1, 0); glVertex3f(-7.5, -10, 17.5); glVertex3f(-12.5, -10, 17.5); glVertex3f(-12.5, -10, -10); glVertex3f(-7.5, -10, -10); glEnd(); glBegin(display_mode); // lower leg back right edge glNormal3f(0, 0, -1); glVertex3f(12.5, 5, -10); glVertex3f(7.5, 5, -10); glVertex3f(7.5, -10, -10); glVertex3f(12.5, -10, -10); glEnd(); glBegin(display_mode); // lower leg top right edge glNormal3f(0, 1, 0); glVertex3f(12.5, 5, -10); glVertex3f(7.5, 5, -10); glVertex3f(7.5, 5, 10); glVertex3f(12.5, 5, 10); glEnd(); glBegin(display_mode); // lower leg front right edge CalculateNormal(-5, 0, 0, -5, -15, 5); glNormal3f(normal_vector[0], normal_vector[1], normal_vector[2]); glVertex3f(12.5, 5, 10); glVertex3f(7.5, 5, 10); glVertex3f(7.5, -10, 17.5); glVertex3f(12.5, -10, 17.5); glEnd(); //glBegin(display_mode); // lower leg bottom right edge // glVertex3f(7.5, -10, 15); // no normal needed // glVertex3f(12.5, -10, 15); // glVertex3f(12.5, -10, -10); // glVertex3f(7.5, -10, -10); //glEnd(); glBegin(display_mode); // lower leg shin plate back face glNormal3f(0, 0, -1); glVertex3f(-10, -10, -10); glVertex3f(-10, -45, -10); glVertex3f(12.5, -45, -10); glVertex3f(12.5, -10, -10); glEnd(); glBegin(display_mode); // lower leg shin plate front face glNormal3f(0, 0, 1); glVertex3f(-10, -10, 25); glVertex3f(-10, -30, 25); glVertex3f(12.5, -30, 25); glVertex3f(12.5, -10, 25); glEnd(); glBegin(display_mode); // lower leg shin plate top face glNormal3f(0, 1, 0); glVertex3f(-10, -10, -10); glVertex3f(-10, -10, 25); glVertex3f(12.5, -10, 25); glVertex3f(12.5, -10, -10); glEnd(); glBegin(display_mode); // lower leg shin plate slanted face CalculateNormal(22.5, -7.5, -5, 22.5, 0, 0); glNormal3f(normal_vector[0], normal_vector[1], normal_vector[2]); glVertex3f(-10, -30, 25); glVertex3f(12.5, -30, 25); glVertex3f(12.5, -42.5, 17.5); glVertex3f(-10, -42.5, 17.5); glEnd(); glBegin(display_mode); // lower leg inside plate top edge glNormal3f(0, 1, 0); glVertex3f(-12.5, -30, -10); glVertex3f(-12.5, -30, 17.5); glVertex3f(-10, -30, 17.5); glVertex3f(-10, -30, -10); glEnd(); glBegin(display_mode); // lower leg inside plate front edge glNormal3f(0, 0, 1); glVertex3f(-10, -30, 17.5); glVertex3f(-12.5, -30, 17.5); glVertex3f(-12.5, -70, 17.5); glVertex3f(-10, -70, 17.5); glEnd(); glBegin(display_mode); // lower leg inside plate back edge glNormal3f(0, 0, -1); glVertex3f(-10, -30, -10); glVertex3f(-12.5, -30, -10); glVertex3f(-12.5, -70, -10); glVertex3f(-10, -70, -10); glEnd(); glBegin(display_mode); // lower leg inside plate inner edge glNormal3f(1, 0, 0); glVertex3f(-10, -30, 17.5); glVertex3f(-10, -30, -10); glVertex3f(-10, -70, -10); glVertex3f(-10, -70, 17.5); glEnd(); glBegin(display_mode); // lower leg inside plate outer edge glNormal3f(-1, 0, 0); glVertex3f(-12.5, -30, 17.5); glVertex3f(-12.5, -30, -10); glVertex3f(-12.5, -70, -10); glVertex3f(-12.5, -70, 17.5); glEnd(); glBegin(display_mode); // lower leg inside plate bottom edge glNormal3f(0, -1, 0); glVertex3f(-12.5, -70, -10); glVertex3f(-12.5, -70, 17.5); glVertex3f(-10, -70, 17.5); glVertex3f(-10, -70, -10); glEnd(); glBegin(display_mode); // lower leg flat front face glNormal3f(0, 0, 1); glVertex3f(-10, -42.5, 17.5); glVertex3f(-10, -45, 17.5); glVertex3f(12.5, -45, 17.5); glVertex3f(12.5, -42.5, 17.5); glEnd(); glBegin(display_mode); // lower leg flat bottom face glNormal3f(0, -1, 0); glVertex3f(12.5, -45, 17.5); glVertex3f(12.5, -45, -10); glVertex3f(-10, -45, -10); glVertex3f(-10, -45, 17.5); glEnd(); glBegin(display_mode); // lower leg right plate inside face glNormal3f(-1, 0, 0); glVertex3f(10, -45, -10); glVertex3f(10, -70, -10); glVertex3f(10, -70, 15); glVertex3f(10, -45, 15); glEnd(); glBegin(display_mode); // lower leg right plate outside face glNormal3f(1, 0, 0); glVertex3f(12.5, -45, -10); glVertex3f(12.5, -70, -10); glVertex3f(12.5, -70, 17.5); glVertex3f(12.5, -45, 17.5); glEnd(); glBegin(display_mode); // lower leg right plate bottom edge glNormal3f(0, -1, 0); glVertex3f(10, -70, -10); glVertex3f(10, -70, 17.5); glVertex3f(12.5, -70, 17.5); glVertex3f(12.5, -70, -10); glEnd(); glBegin(display_mode); // lower leg right face glNormal3f(1, 0, 0); glVertex3f(12.5, -10, -10); glVertex3f(12.5, -10, 25); glVertex3f(12.5, -30, 25); glVertex3f(12.5, -42.5, 17.5); glVertex3f(12.5, -70, 17.5); glVertex3f(12.5, -70, -10); glEnd(); glBegin(display_mode); // lower leg left face glNormal3f(-1, 0, 0); glVertex3f(-10, -10, -10); glVertex3f(-10, -10, 25); glVertex3f(-10, -30, 25); glVertex3f(-10, -42.5, 17.5); glVertex3f(-10, -70, 17.5); glVertex3f(-10, -70, -10); glEnd(); glBegin(display_mode); // lower leg right place front edge glNormal3f(0, 0, 1); glVertex3f(10, -45, 17.5); glVertex3f(12.5, -45, 17.5); glVertex3f(12.5, -70, 17.5); glVertex3f(10, -70, 17.5); glEnd(); glBegin(display_mode); // lower leg right place back edge glNormal3f(0, 0, -1); glVertex3f(10, -45, -10); glVertex3f(12.5, -45, -10); glVertex3f(12.5, -70, -10); glVertex3f(10, -70, -10); glEnd(); glBegin(display_mode); // lower leg hip joint left plate left face glNormal3f(-1, 0, 0); glVertex3f(-12.5, 5, -10); glVertex3f(-12.5, 5, 10); glVertex3f(-12.5, -10, 17.5); glVertex3f(-12.5, -10, -10); glEnd(); glBegin(display_mode); // lower leg hip joint left plate right face glNormal3f(1, 0, 0); glVertex3f(-7.5, 5, -10); glVertex3f(-7.5, 5, 10); glVertex3f(-7.5, -10, 17.5); glVertex3f(-7.5, -10, -10); glEnd(); glBegin(display_mode); // lower leg hip joint right plate left face glNormal3f(-1, 0, 0); glVertex3f(7.5, 5, -10); glVertex3f(7.5, 5, 10); glVertex3f(7.5, -10, 17.5); glVertex3f(7.5, -10, -10); glEnd(); glBegin(display_mode); // lower leg hip joint right plate right face glNormal3f(1, 0, 0); glVertex3f(12.5, 5, -10); glVertex3f(12.5, 5, 10); glVertex3f(12.5, -10, 17.5); glVertex3f(12.5, -10, -10); glEnd(); } // DrawLowerLeg
void Decepticon :: DrawShoulder() { if (anti_aliasing) { glEnable (GL_LINE_SMOOTH); glEnable (GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glHint (GL_LINE_SMOOTH_HINT, GL_DONT_CARE); glLineWidth (1.5); } // if statement glTranslatef (0, -20, -15); ChangeColor(0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.8, 1.0); glBegin(display_mode); // shoulder back glNormal3f(0, 0, -1); glVertex3f(0, 0, -12.5); glVertex3f(0, 22.5, -12.5); glVertex3f(5, 27.5, -12.5); glVertex3f(20, 27.5, -12.5); glVertex3f(20, 10, -12.5); glVertex3f(7.5, 0, -12.5); glEnd(); glBegin(display_mode); // shoulder front glNormal3f(0, 0, 1); glVertex3f(0, 0, 12.5); glVertex3f(0, 22.5, 12.5); glVertex3f(5, 27.5, 12.5); glVertex3f(20, 27.5, 12.5); glVertex3f(20, 10, 12.5); glVertex3f(7.5, 0, 12.5); glEnd(); glBegin(display_mode); // back inner shoulder edge glNormal3f(-1, 0, 0); glVertex3f(0, 0, -12.5); glVertex3f(0, 22.5, -12.5); glVertex3f(0, 20, -10.5); glVertex3f(0, 0, -10.5); glEnd(); glBegin(display_mode); // front inner shoulder edge glNormal3f(-1, 0, 0); glVertex3f(0, 0, 12.5); glVertex3f(0, 22.5, 12.5); glVertex3f(0, 20, 10.5); glVertex3f(0, 0, 10.5); glEnd(); glBegin(display_mode); // top inner shoulder edge glNormal3f(-1, 0, 0); glVertex3f(0, 22.5, -12.5); glVertex3f(0, 20, -10); glVertex3f(0, 20, 10); glVertex3f(0, 22.5, 12.5); glEnd(); glBegin(display_mode); // shoulder top left edge CalculateNormal(5, 5, 25, 5, 5, 0); glNormal3f(normal_vector[0], normal_vector[1], normal_vector[2]); glVertex3f(0, 22.5, -12.5); glVertex3f(5, 27.5, -12.5); glVertex3f(5, 27.5, 12.5); glVertex3f(0, 22.5, 12.5); glEnd(); glBegin(display_mode); // shoulder top edge glNormal3f(0, 1, 0); glVertex3f(5, 27.5, -12.5); glVertex3f(20, 27.5, -12.5); glVertex3f(20, 27.5, 12.5); glVertex3f(5, 27.5, 12.5); glEnd(); glBegin(display_mode); // shoulder right edge glNormal3f(1, 0, 0); glVertex3f(20, 27.5, -12.5); glVertex3f(20, 10, -12.5); glVertex3f(20, 10, 12.5); glVertex3f(20, 27.5, 12.5); glEnd(); glBegin(display_mode); CalculateNormal(-1.95, -1.66, 25, -1.95, -1.66, 0); glNormal3f(normal_vector[0], normal_vector[1], normal_vector[2]); glVertex3f(20, 10, -12.5); glVertex3f(18.05, 8.34, -12.5); // 18.05 = 10 - (2.5 * 12.5) / sqrt(256.25) glVertex3f(18.05, 8.34, 12.5); // 8.34 = 10 - (2.5 *10) / sqrt(256.25) glVertex3f(20, 10, 12.5); glEnd(); glBegin(display_mode); CalculateNormal(12.5, 10, 2.5, 12.5, 10, 0); glNormal3f(normal_vector[0], normal_vector[1], normal_vector[2]); glVertex3f(7.5, 0, -12.5); glVertex3f(20, 10, -12.5); glVertex3f(20, 10, -10.5); glVertex3f(7.5, 0, -10.5); glEnd(); glBegin(display_mode); // same normal as last calculation glVertex3f(7.5, 0, 12.5); glVertex3f(20, 10, 12.5); glVertex3f(20, 10, 10.5); glVertex3f(7.5, 0, 10.5); glEnd(); glBegin(display_mode); glNormal3f(-1, 0, 0); glVertex3f(0, 0, -12.5); glVertex3f(7.5, 0, -12.5); glVertex3f(7.5, 0, -10); glVertex3f(0, 0, -10); glEnd(); glBegin(display_mode); // same normal as last calculation glVertex3f(0, 0, 12.5); glVertex3f(7.5, 0, 12.5); glVertex3f(7.5, 0, 10); glVertex3f(0, 0, 10); glEnd(); glBegin(display_mode); // shoulder plate back face glNormal3f(0, 0, 1); glVertex3f(0, 0, 12.5); glVertex3f(0, 22.5, 12.5); glVertex3f(15, 22.5, 12.5); glVertex3f(15, 6, 12.5); glVertex3f(7.5, 0, 12.5); glEnd(); glBegin(display_mode); // shoulder plate front face glVertex3f(0, 0, 15); // same normal as last calculation glVertex3f(0, 22.5, 15); glVertex3f(15, 22.5, 15); glVertex3f(15, 6, 15); glVertex3f(7.5, 0, 15); glEnd(); glBegin(display_mode); // shoulder plate left edge glNormal3f(-1, 0, 0); glVertex3f(0, 0, 12.5); glVertex3f(0, 22.5, 12.5); glVertex3f(0, 22.5, 15); glVertex3f(0, 0, 15); glEnd(); glBegin(display_mode); // shoulder plate top edge glNormal3f(0, 1, 0); glVertex3f(0, 22.5, 12.5); glVertex3f(15, 22.5, 12.5); glVertex3f(15, 22.5, 15); glVertex3f(0, 22.5, 15); glEnd(); glBegin(display_mode); // shoulder plate right edge glNormal3f(1, 0, 0); glVertex3f(15, 22.5, 12.5); glVertex3f(15, 6, 12.5); glVertex3f(15, 6, 15); glVertex3f(15, 22.5, 15); glEnd(); glBegin(display_mode); // shoulder plate bottom right edge CalculateNormal(-7.5, -6, 2.5, -7.5, -6, 0); glNormal3f(normal_vector[0], normal_vector[1], normal_vector[2]); glVertex3f(15, 6, 12.5); glVertex3f(7.5, 0, 12.5); glVertex3f(7.5, 0, 15); glVertex3f(15, 6, 15); glEnd(); glBegin(display_mode); // shoulder plate bottom edge glNormal3f(0, -1, 0); glVertex3f(0, 0, 12.5); glVertex3f(7.5, 0, 12.5); glVertex3f(7.5, 0, 15); glVertex3f(0, 0, 15); glEnd(); } // DrawShoulder
void Decepticon :: DrawTorso() { if (anti_aliasing) { glEnable (GL_LINE_SMOOTH); glEnable (GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glHint (GL_LINE_SMOOTH_HINT, GL_DONT_CARE); glLineWidth (1.5); } // if statement ChangeColor(0.0, 0.0, 0.8, 1.0, 0.0, 0.0, 0.5, 1.0); glBegin(display_mode); // torso back face glVertex3f(-32.5, 0, -12.5); // no normal needed (not visible - hidden behind 'torso back raised face') glVertex3f(32.5, 0, -12.5); glVertex3f(27.5, -20, -7.5); glVertex3f(-27.5, -20, -7.5); glEnd(); glBegin(display_mode); // torso front face glVertex3f(-32.5, 0, 12.5); // no normal needed (not visible - hidden behind 'torso front raised face') glVertex3f(32.5, 0, 12.5); glVertex3f(27.5, -20, 7.5); glVertex3f(-27.5, -20, 7.5); glEnd(); glBegin(display_mode); // torso back raised face CalculateNormal(50, 0, 0, 55, -20, 5); glNormal3f(normal_vector[0], normal_vector[1], normal_vector[2]); glVertex3f(-27.5, 0, -15); glVertex3f(27.5, 0, -15); glVertex3f(22.5, -20, -10); glVertex3f(-22.5, -20, -10); glEnd(); glBegin(display_mode); // torso front raised face CalculateNormal(55, -20, -5, 50, 0, 0); glNormal3f(normal_vector[0], normal_vector[1], normal_vector[2]); glVertex3f(-27.5, 0, 15); glVertex3f(27.5, 0, 15); glVertex3f(22.5, -20, 10); glVertex3f(-22.5, -20, 10); glEnd(); glBegin(display_mode); // torso back left edge CalculateNormal(0, -20, 7.5, -5, 0, 2.5); glNormal3f(normal_vector[0], normal_vector[1], normal_vector[2]); glVertex3f(-27.5, 0, -15); glVertex3f(-32.5, 0, -12.5); glVertex3f(-27.5, -20, -7.5); glVertex3f(-22.5, -20, -10); glEnd(); glBegin(display_mode); // torso front left edge CalculateNormal(-5, 0, -2.5, 0, -20, -7.5); glNormal3f(normal_vector[0], normal_vector[1], normal_vector[2]); glVertex3f(-27.5, 0, 15); glVertex3f(-32.5, 0, 12.5); glVertex3f(-27.5, -20, 7.5); glVertex3f(-22.5, -20, 10); glEnd(); glBegin(display_mode); // torso back right edge CalculateNormal(5, 0, 2.5, 0, -20, 7.5); glNormal3f(normal_vector[0], normal_vector[1], normal_vector[2]); glVertex3f(27.5, 0, -15); glVertex3f(32.5, 0, -12.5); glVertex3f(27.5, -20, -7.5); glVertex3f(22.5, -20, -10); glEnd(); glBegin(display_mode); // torso front right edge CalculateNormal(0, -20, -7.5, 5, 0, -2.5); glNormal3f(normal_vector[0], normal_vector[1], normal_vector[2]); glVertex3f(27.5, 0, 15); glVertex3f(32.5, 0, 12.5); glVertex3f(27.5, -20, 7.5); glVertex3f(22.5, -20, 10); glEnd(); glBegin(display_mode); // torso left face CalculateNormal(5, -20, 5, 0, 0, 25); glNormal3f(normal_vector[0], normal_vector[1], normal_vector[2]); glVertex3f(-32.5, 0, -12.5); glVertex3f(-32.5, 0, 12.5); glVertex3f(-27.5, -20, 7.5); glVertex3f(-27.5, -20, -7.5); glEnd(); glBegin(display_mode); // torso right face CalculateNormal(0, 0, 25, -5, -20, 5); glNormal3f(normal_vector[0], normal_vector[1], normal_vector[2]); glVertex3f(32.5, 0, -12.5); glVertex3f(32.5, 0, 12.5); glVertex3f(27.5, -20, 7.5); glVertex3f(27.5, -20, -7.5); glEnd(); ChangeColor(0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.8, 1.0); } // DrawTorso
void Decepticon :: DrawUpperArm() { if (anti_aliasing) { glEnable (GL_LINE_SMOOTH); glEnable (GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glHint (GL_LINE_SMOOTH_HINT, GL_DONT_CARE); glLineWidth (1.5); } // if statement glBegin(display_mode); // upper arm back face glNormal3f(0, 0, -1); glVertex3f(0, 0, -8); glVertex3f(0, -40, -8); glVertex3f(7, -40, -8); glVertex3f(7, -30, -8); glVertex3f(11, -30, -8); glVertex3f(11, -40, -8); glVertex3f(18, -40, -8); glVertex3f(18, 0, -8); glEnd(); glBegin(display_mode); // upper arm front face glNormal3f(0, 0, 1); glVertex3f(0, 0, 8); glVertex3f(0, -40, 8); glVertex3f(7, -40, 8); glVertex3f(7, -30, 8); glVertex3f(11, -30, 8); glVertex3f(11, -40, 8); glVertex3f(18, -40, 8); glVertex3f(18, 0, 8); glEnd(); glBegin(display_mode); // upper arm left face glNormal3f(-1, 0, 0); glVertex3f(0, 0, -8); glVertex3f(0, -40, -8); glVertex3f(0, -40, 8); glVertex3f(0, 0, 8); glEnd(); glBegin(display_mode); // upper arm right face glNormal3f(1, 0, 0); glVertex3f(18, 0, -8); glVertex3f(18, -40, -8); glVertex3f(18, -40, 8); glVertex3f(18, 0, 8); glEnd(); glBegin(display_mode); // upper arm back raised face glNormal3f(0, 0, -1); glVertex3f(2, 0, -10); glVertex3f(2, -37, -10); glVertex3f(7, -37, -10); glVertex3f(7, -30, -10); glVertex3f(11, -30, -10); glVertex3f(11, -37, -10); glVertex3f(16, -37, -10); glVertex3f(16, 0, -10); glEnd(); glBegin(display_mode); // upper arm front raised face glNormal3f(0, 0, 1); glVertex3f(2, 0, 10); glVertex3f(2, -37, 10); glVertex3f(7, -37, 10); glVertex3f(7, -30, 10); glVertex3f(11, -30, 10); glVertex3f(11, -37, 10); glVertex3f(16, -37, 10); glVertex3f(16, 0, 10); glEnd(); glBegin(display_mode); // upper arm front left edge CalculateNormal(2, -37, 2, 0, -40, 0); glNormal3f(normal_vector[0], normal_vector[1], normal_vector[2]); glVertex3f(0, 0, 8); glVertex3f(0, -40, 8); glVertex3f(2, -37, 10); glVertex3f(2, 0, 10); glEnd(); glBegin(display_mode); // upper arm back left edge CalculateNormal(2, -37, -2, 0, -40, 0); glNormal3f(normal_vector[0], normal_vector[1], normal_vector[2]); glVertex3f(0, 0, -8); glVertex3f(0, -40, -8); glVertex3f(2, -37, -10); glVertex3f(2, 0, -10); glEnd(); glBegin(display_mode); // upper arm front right edge CalculateNormal(-2, -37, 2, 0, -40, 0); glNormal3f(normal_vector[0], normal_vector[1], normal_vector[2]); glVertex3f(18, 0, 8); glVertex3f(18, -40, 8); glVertex3f(16, -37, 10); glVertex3f(16, 0, 10); glEnd(); glBegin(display_mode); // upper arm back right edge CalculateNormal(-2, -37, 8, 0, -40, 0); glNormal3f(normal_vector[0], normal_vector[1], normal_vector[2]); glVertex3f(18, 0, -8); glVertex3f(18, -40, -8); glVertex3f(16, -37, -10); glVertex3f(16, 0, -10); glEnd(); glBegin(display_mode); // upper arm lower front left edge CalculateNormal(7, 3, 2, 2, 3, 2); glNormal3f(normal_vector[0], normal_vector[1], normal_vector[2]); glVertex3f(0, -40, 8); glVertex3f(2, -37, 10); glVertex3f(7, -37, 10); glVertex3f(7, -40, 8); glEnd(); glBegin(display_mode); // upper arm lower front right edge CalculateNormal(-7, 3, 2, -2, 3, 2); glNormal3f(normal_vector[0], normal_vector[1], normal_vector[2]); glVertex3f(18, -40, 8); glVertex3f(16, -37, 10); glVertex3f(11, -37, 10); glVertex3f(11, -40, 8); glEnd(); glBegin(display_mode); // upper arm lower back left edge CalculateNormal(7, 3, -2, 2, 3, -2); glNormal3f(normal_vector[0], normal_vector[1], normal_vector[2]); glVertex3f(0, -40, -8); glVertex3f(2, -37, -10); glVertex3f(7, -37, -10); glVertex3f(7, -40, -8); glEnd(); glBegin(display_mode); // upper arm lower back right edge CalculateNormal(-7, 3, -2, -2, 3, -2); glNormal3f(normal_vector[0], normal_vector[1], normal_vector[2]); glVertex3f(18, -40, -8); glVertex3f(16, -37, -10); glVertex3f(11, -37, -10); glVertex3f(11, -40, -8); glEnd(); glBegin(display_mode); // upper arm inside left edge glNormal3f(1, 0, 0); glVertex3f(7, -30, -10); glVertex3f(7, -37, -10); glVertex3f(7, -40, -8); glVertex3f(7, -40, 8); glVertex3f(7, -37, 10); glVertex3f(7, -30, 10); glEnd(); glBegin(display_mode); // upper arm inside right edge glNormal3f(1, 0, 0); glVertex3f(11, -30, -10); glVertex3f(11, -37, -10); glVertex3f(11, -40, -8); glVertex3f(11, -40, 8); glVertex3f(11, -37, 10); glVertex3f(11, -30, 10); glEnd(); glBegin(display_mode); // upper arm inside upper edge glNormal3f(0, -1, 0); glVertex3f(7, -30, -10); glVertex3f(7, -30, 10); glVertex3f(11, -30, 10); glVertex3f(11, -30, -10); glEnd(); glBegin(display_mode); // upper arm bottom edge glNormal3f(0, -1, 0); glVertex3f(0, -40, -8); glVertex3f(7, -40, -8); glVertex3f(7, -40, 8); glVertex3f(0, -40, 8); glEnd(); glBegin(display_mode); // same normal as last glVertex3f(11, -40, -8); glVertex3f(18, -40, -8); glVertex3f(18, -40, 8); glVertex3f(11, -40, 8); glEnd(); } // DrawUpperArm
CDoubleArray* GetMrGrayCurvature(vtkPolyData* p) { // Params: p is a vtkPolyData mesh // Should have ONLY TRIANGLES! // No other primitive is checked. Don't send in a stripped mesh. // Normals is an array of floats that the normals will be written to. // Should have 3*n elements. (n is obtained from p) // Grays is an array of BYTEs that the colours will be written to. // n elements. 1 byte per vertex, 0-255 grayscale // This routine gray-codes each vertex according to the local curvature // Also calculates an area-weighted set of Normals // The "curvature" is approximated by the following formula: // C = R / (fabs(R) + sqrt(A)/4) // Where R is the signed distance between a point and the // average plane of its connected neighbours, and A is the // area of all the triangles featuring the point. // The plane is defined by the averages of all triangle normals // and centers (area weighted averages) int nVerticies = p->GetNumberOfPoints(); //int nTriangles = p->GetNumberOfPolys(); vtkDoubleArray *pArrayNormals = NULL; double *Normals = NULL; CDoubleArray *pCurvatures = NULL; // Zero Normals and Colours if we have any.. note we'll need // a temp normal store even if they don't want it returned /* Normals = new float[nVerticies*3]; memset(Normals, 0, sizeof(float)*nVerticies*3); */ pArrayNormals = vtkDoubleArray::New(); if (!pArrayNormals) return NULL; pArrayNormals->SetNumberOfComponents(3); pArrayNormals->SetNumberOfTuples(nVerticies); Normals = pArrayNormals->GetPointer(0); if (!Normals) { pArrayNormals->Delete(); return NULL; } // 2003.09.24 RFD: trying this as a fix for sporatic linux curvature noise bug. memset(Normals, 0, sizeof(double)*nVerticies*3); pCurvatures = new CDoubleArray; if (!pCurvatures || !pCurvatures->Create(1, nVerticies)) { // delete[] Normals; pArrayNormals->Delete(); return NULL; } p->BuildLinks(); double fMax = 0.0, fSum = 0.0; //for (int i=0;i<nVerticies;i++) for (vtkIdType i=0;i<nVerticies;i++) { // For each vertex, calculate an average plane and normal double A=0; // Total area of all triangles using this vertex double P[3]={0,0,0}; // Mean of centers of all triangles using this vertex // Find out which triangles use this vertex unsigned short nTris; //int *pp; vtkIdType *pp; //p->GetPointCells(i,nTris,pp); p->GetPointCells(i,nTris,pp); for (int j=0;j<nTris;j++,pp++) { // This triangle uses this point. //int nVerts; vtkIdType nVerts; //int *Verts; vtkIdType *Verts; //p->GetCellPoints(*pp,nVerts,Verts); p->GetCellPoints(*pp,nVerts,Verts); if (nVerts!=3) continue; static double p1[3]; static double p2[3]; static double p3[3]; p->GetPoint(Verts[0], p1); //printf("%lf %lf %lf\n",p1[0],p1[1],p1[2]); p->GetPoint(Verts[1], p2); p->GetPoint(Verts[2], p3); //printf("%lf %lf %lf %lf %lf %lf %lf %lf %lf\n",p1[0],p1[1],p1[2],p2[0],p2[1],p2[2],p3[0],p3[1],p3[2]); // Get its normal and area at the same time double n[3],dA; CalculateNormal(p1,p2,p3,n,&dA); // Store area weighted normal Normals[i*3]+=n[0]*dA; Normals[i*3+1]+=n[1]*dA; Normals[i*3+2]+=n[2]*dA; // Add it's weighted center P[0]+= (p1[0]+p2[0]+p3[0])*dA; P[1]+= (p1[1]+p2[1]+p3[1])*dA; P[2]+= (p1[2]+p2[2]+p3[2])*dA; // Add the area to the running total A+=dA; } // Next triangle on this vertex // Average out all the normals if (A) { double RecipA = 1.0/A; Normals[i*3]*=RecipA; Normals[i*3+1]*=RecipA; Normals[i*3+2]*=RecipA; RecipA*=1.0/3.0; P[0]*=RecipA; P[1]*=RecipA; P[2]*=RecipA; } // Find the signed distance to the average plane double *x= p->GetPoint(i); double *n=&(Normals[i*3]); double R = n[0]*(x[0]-P[0]) + n[1]*(x[1]-P[1]) + n[2]*(x[2]-P[2]); // Now encode the curvature // C = R / (fabs(R) + sqrt(A)/4) double C = R / (fabsf(R) + sqrtf(A)*0.25); /* // Convert to a byte value BYTE gray=(BYTE)((255.9*(C+1.0))*0.5); // Assign as the vertex colour if (Grays) Grays[i]=gray; */ pCurvatures->SetAtAbsoluteIndex(C, i); fSum += fabsf(C); if (fabsf(C) > fMax) fMax = fabsf(C); } // Next vertex // delete[] Normals; // Was temp in that case. // p->GetPointData()->SetNormals(pArrayNormals); pArrayNormals->Delete(); return pCurvatures; }
T MapRangeValue(T sX, T xMin, T xMax, T yMin, T yMax) { return( Lerp( yMin, yMax, CalculateNormal(sX,xMin,xMax)) ); }
//------------------------------------------------------------------------------------------------- // render a single frame of a MD2 model void JMD2Model::Render(int frameNum) { Vector3D *pointList; int i; // create a pointer to the frame we want to show pointList = &mModel->pointList[mModel->numPoints * frameNum]; // set the texture mRenderer->BindTexture(mModel->modelTex); #if !defined (PSP) // display the textured model with proper lighting normals #if (defined GL_ES_VERSION_2_0) || (defined GL_VERSION_2_0) #elif (defined GL_ES_VERSION_1_1) || (defined GL_VERSION_1_1) || (defined GL_VERSION_ES_CM_1_1) || (defined GL_OES_VERSION_1_1) glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); #else glBegin(GL_TRIANGLES); #endif //(defined GL_ES_VERSION_2_0) || (defined GL_VERSION_2_0) for(i = 0; i < mModel->numTriangles; i++) { CalculateNormal(pointList[mModel->triIndex[i].meshIndex[0]].v, pointList[mModel->triIndex[i].meshIndex[2]].v, pointList[mModel->triIndex[i].meshIndex[1]].v); #if (defined GL_ES_VERSION_2_0) || (defined GL_VERSION_2_0) #elif (defined GL_ES_VERSION_1_1) || (defined GL_VERSION_1_1)|| (defined GL_VERSION_ES_CM_1_1) || (defined GL_OES_VERSION_1_1) float vertex_data[]={ pointList[mModel->triIndex[i].meshIndex[0]].x, pointList[mModel->triIndex[i].meshIndex[0]].y, pointList[mModel->triIndex[i].meshIndex[0]].z, pointList[mModel->triIndex[i].meshIndex[2]].x, pointList[mModel->triIndex[i].meshIndex[2]].y, pointList[mModel->triIndex[i].meshIndex[2]].z, pointList[mModel->triIndex[i].meshIndex[1]].x, pointList[mModel->triIndex[i].meshIndex[1]].y, pointList[mModel->triIndex[i].meshIndex[1]].z, }; float texcoord_data[] = { mModel->st[mModel->triIndex[i].stIndex[0]].s, mModel->st[mModel->triIndex[i].stIndex[0]].t, mModel->st[mModel->triIndex[i].stIndex[2]].s, mModel->st[mModel->triIndex[i].stIndex[2]].t, mModel->st[mModel->triIndex[i].stIndex[1]].s, mModel->st[mModel->triIndex[i].stIndex[1]].t, }; glVertexPointer(3,GL_FLOAT,0,vertex_data); glTexCoordPointer(2,GL_FLOAT,0,texcoord_data); #else glTexCoord2f(mModel->st[mModel->triIndex[i].stIndex[0]].s, mModel->st[mModel->triIndex[i].stIndex[0]].t); glVertex3fv(pointList[mModel->triIndex[i].meshIndex[0]].v); glTexCoord2f(mModel->st[mModel->triIndex[i].stIndex[2]].s , mModel->st[mModel->triIndex[i].stIndex[2]].t); glVertex3fv(pointList[mModel->triIndex[i].meshIndex[2]].v); glTexCoord2f(mModel->st[mModel->triIndex[i].stIndex[1]].s, mModel->st[mModel->triIndex[i].stIndex[1]].t); glVertex3fv(pointList[mModel->triIndex[i].meshIndex[1]].v); #endif //#if (!defined GL_ES_VERSION_2_0) && (!defined GL_VERSION_2_0) } #if (defined GL_ES_VERSION_2_0) || (defined GL_VERSION_2_0) #elif (defined GL_ES_VERSION_1_1) || (defined GL_VERSION_1_1) || (defined GL_VERSION_ES_CM_1_1) || (defined GL_OES_VERSION_1_1) glDrawArrays(GL_TRIANGLES,0,3); // seems suspicious to put that here, should probably be in the loop #else glEnd(); #endif //(defined GL_ES_VERSION_2_0) || (defined GL_VERSION_2_0) #else PSPVertex3D* vertices = (PSPVertex3D*) sceGuGetMemory(mModel->numTriangles * 3 * sizeof(PSPVertex3D)); int n = 0; for(i = 0; i < mModel->numTriangles; i++) { //CalculateNormal(&vertices[n].normal, // pointList[mModel->triIndex[i].meshIndex[0]].v, // pointList[mModel->triIndex[i].meshIndex[2]].v, // pointList[mModel->triIndex[i].meshIndex[1]].v); vertices[n].texture.x = mModel->st[mModel->triIndex[i].stIndex[0]].s; vertices[n].texture.y = mModel->st[mModel->triIndex[i].stIndex[0]].t; vertices[n].pos.x = pointList[mModel->triIndex[i].meshIndex[0]].x; vertices[n].pos.y = pointList[mModel->triIndex[i].meshIndex[0]].y; vertices[n].pos.z = pointList[mModel->triIndex[i].meshIndex[0]].z; n++; //vertices[n].normal.x = vertices[n-1].normal.x; //vertices[n].normal.y = vertices[n-1].normal.y; //vertices[n].normal.z = vertices[n-1].normal.z; vertices[n].texture.x = mModel->st[mModel->triIndex[i].stIndex[2]].s; vertices[n].texture.y = mModel->st[mModel->triIndex[i].stIndex[2]].t; vertices[n].pos.x = pointList[mModel->triIndex[i].meshIndex[2]].x; vertices[n].pos.y = pointList[mModel->triIndex[i].meshIndex[2]].y; vertices[n].pos.z = pointList[mModel->triIndex[i].meshIndex[2]].z; n++; //vertices[n].normal.x = vertices[n-1].normal.x; //vertices[n].normal.y = vertices[n-1].normal.y; //vertices[n].normal.z = vertices[n-1].normal.z; vertices[n].texture.x = mModel->st[mModel->triIndex[i].stIndex[1]].s; vertices[n].texture.y = mModel->st[mModel->triIndex[i].stIndex[1]].t; vertices[n].pos.x = pointList[mModel->triIndex[i].meshIndex[1]].x; vertices[n].pos.y = pointList[mModel->triIndex[i].meshIndex[1]].y; vertices[n].pos.z = pointList[mModel->triIndex[i].meshIndex[1]].z; n++; } sceGuColor(0xff000000); sceGumDrawArray(GU_TRIANGLES,GU_TEXTURE_32BITF|GU_NORMAL_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_3D,mModel->numTriangles*3,0,vertices); #endif }
BRUSH* ConvertXModelToBrushFormat ( char* szFilename, BRUSH* pBrush, int* piCount, LPDIRECT3DDEVICE8 lpDevice ) { // takes an x model and converts it into brushes // check the pointers are valid if ( !szFilename || !piCount ) return NULL; // used to access vertex data struct sMeshData { float x, y, z; float nx, ny, nz; float tu, tv; }; // variable declarations tagModelData* ptr; // model data LPDIRECT3DVERTEXBUFFER8 pMeshVertexBuffer; // vertex buffer LPDIRECT3DINDEXBUFFER8 pMeshIndexBuffer; // index buffer sMeshData* pMeshVertices; // mesh vertices WORD* pMeshIndices; // mesh indices sMesh* pMesh; // mesh data int iCount; // load the model Constructor ( lpDevice ); ptr = Load ( 1, szFilename ); pMesh = ptr->m_Object.m_Meshes; // count the number of brushes so we can allocate enough memory for them iCount = 0; while ( pMesh ) { pMesh = pMesh->m_Next; iCount++; } // store the number of models in the brush count pointer *piCount = iCount; // now setup the brushes pBrush = new BRUSH [ iCount ]; // allocate memory // set the mesh pointer back to the original mesh pMesh = ptr->m_Object.m_Meshes; // run through all meshes and store the brush data // first off set iCount to 0 so we know which brush // we are dealing with iCount = 0; while ( pMesh ) { int iInd = 0; DWORD dwNumVertices = pMesh->m_Mesh->GetNumVertices ( ); DWORD dwNumFaces = pMesh->m_Mesh->GetNumFaces ( ); pBrush [ iCount ].Faces = new POLYGON [ dwNumFaces ]; pBrush [ iCount ].FaceCount = dwNumFaces; pBrush [ iCount ].Bounds.Max = D3DXVECTOR3 ( 150.0f, 150.0f, 150.0f ); pBrush [ iCount ].Bounds.Min = D3DXVECTOR3 ( -150.0f, -150.0f, -150.0f ); pBrush [ iCount ].BSPTree = NULL; pMesh->m_Mesh->GetVertexBuffer ( &pMeshVertexBuffer ); pMesh->m_Mesh->GetIndexBuffer ( &pMeshIndexBuffer ); DWORD dwFVF = pMesh->m_Mesh->GetFVF ( ); pMeshVertexBuffer->Lock ( 0, pMesh->m_Mesh->GetNumVertices ( ) * sizeof ( sMeshData ), ( BYTE** ) &pMeshVertices, 0 ); pMeshIndexBuffer->Lock ( 0, 3 * pMesh->m_Mesh->GetNumFaces ( ) * sizeof ( WORD ), ( BYTE** ) &pMeshIndices, 0 ); for ( int iTemp = 0; iTemp < dwNumFaces; iTemp++ ) { char szX [ 256 ]; char szY [ 256 ]; char szZ [ 256 ]; int iA = pMeshIndices [ iInd + 0 ]; int iB = pMeshIndices [ iInd + 1 ]; int iC = pMeshIndices [ iInd + 2 ]; WORD wIndices [ ] = { 0, 1, 2 }; pBrush [ iCount ].Faces [ iTemp ].IndexCount = 3; pBrush [ iCount ].Faces [ iTemp ].TextureIndex = 0; pBrush [ iCount ].Faces [ iTemp ].VertexCount = 3; pBrush [ iCount ].Faces [ iTemp ].Indices = new WORD [ 3 ]; pBrush [ iCount ].Faces [ iTemp ].Vertices = new D3DVERTEX [ 3 ]; pBrush [ iCount ].Faces [ iTemp ].Vertices [ 0 ] = SetupVertex ( pMeshVertices [ iA ].x, pMeshVertices [ iA ].y, pMeshVertices [ iA ].z, pMeshVertices [ iA ].tu, pMeshVertices [ iA ].tv ); pBrush [ iCount ].Faces [ iTemp ].Vertices [ 1 ] = SetupVertex ( pMeshVertices [ iB ].x, pMeshVertices [ iB ].y, pMeshVertices [ iB ].z, pMeshVertices [ iB ].tu, pMeshVertices [ iB ].tv ); pBrush [ iCount ].Faces [ iTemp ].Vertices [ 2 ] = SetupVertex ( pMeshVertices [ iC ].x, pMeshVertices [ iC ].y, pMeshVertices [ iC ].z, pMeshVertices [ iC ].tu, pMeshVertices [ iC ].tv ); for ( int iChar = 0; iChar < 3; iChar++ ) { sprintf ( szX, "%.1f", pBrush [ iCount ].Faces [ iTemp ].Vertices [ iChar ].x ); sprintf ( szY, "%.1f", pBrush [ iCount ].Faces [ iTemp ].Vertices [ iChar ].y ); sprintf ( szZ, "%.1f", pBrush [ iCount ].Faces [ iTemp ].Vertices [ iChar ].z ); pBrush [ iCount ].Faces [ iTemp ].Vertices [ iChar ].x = atof ( szX ); pBrush [ iCount ].Faces [ iTemp ].Vertices [ iChar ].y = atof ( szY ); pBrush [ iCount ].Faces [ iTemp ].Vertices [ iChar ].z = atof ( szZ ); } memcpy ( pBrush [ iCount ].Faces [ iTemp ].Indices, wIndices, sizeof ( wIndices ) ); CalculateNormal ( &pBrush [ iCount ].Faces [ iTemp ] ); iInd += 3; } SetBlockPosition ( &pBrush [ iCount ], 0.0f, 0.0f, 0.0f, 1.0f ); pMeshVertexBuffer->Unlock ( ); pMeshIndexBuffer->Unlock ( ); iCount++; pMesh = pMesh->m_Next; } iCount = 0; pMesh = ptr->m_Object.m_Meshes; for ( int iTemp = ptr->m_Object.m_NumFrames; iTemp > 0; iTemp-- ) { sFrame* pFrame = ptr->m_Object.m_Frames->FindFrame ( iTemp ); if ( pFrame ) { pBrush [ iCount ].Matrix._41 = pFrame->m_matOriginal._41; pBrush [ iCount ].Matrix._42 = pFrame->m_matOriginal._42; pBrush [ iCount ].Matrix._43 = pFrame->m_matOriginal._43; iCount++; } } return pBrush; }
/* This function is designed to create vertex and index buffers according to a heightmap that has already been set. * @PARAM ID3D11Device* device - ptr to a direct x 11 device, can usually be retrieved from the graphics class. */ bool CTerrain::InitialiseBuffers(ID3D11Device * device) { VertexType* vertices; unsigned long* indices; int index; int vertex; D3D11_BUFFER_DESC vertexBufferDesc; D3D11_BUFFER_DESC indexBufferDesc; D3D11_SUBRESOURCE_DATA vertexData; D3D11_SUBRESOURCE_DATA indexData; HRESULT result; const int kNumIndicesInSquare = 6; int numberOfNormals; ///////////////////////////// // Terrain tiles setup. ///////////////////////////// if (mpTerrainTiles == nullptr) { mpTerrainTiles = new CTerrainTile*[mHeight]; for (int y = 0; y < mHeight; y++) { mpTerrainTiles[y] = new CTerrainTile[mWidth]; } } // Calculate the number of vertices in the terrain mesh. mVertexCount = (mWidth * mHeight); mIndexCount = (mWidth - 1) * (mHeight - 1) * kNumIndicesInSquare; numberOfNormals = ((mWidth - 1) * (mHeight - 1)) * 2; // Create the vertex array. vertices = new VertexType[mVertexCount]; // Output the allocation message to the log. logger->GetInstance().MemoryAllocWriteLine(typeid(vertices).name()); // If we failed to allocate memory to the vertices array. if (!vertices) { // Output error message to the debug log. logger->GetInstance().WriteLine("Failed to create the vertex array in InitialiseBuffers function, Terrain.cpp."); // Don't continue any more. return false; } // Create the index array. indices = new unsigned long[mIndexCount]; // Output allocation message to the debug log. logger->GetInstance().MemoryAllocWriteLine(typeid(indices).name()); // If we failed to allocate memory to the indices array. if (!indices) { // Output failure message to the debug log. logger->GetInstance().WriteLine("Failed to create the index array in InitialiseBuffers function, Terrain.cpp."); // Don't continue any further. return false; } // Reset the index and vertex we're starting from to 0. index = 0; vertex = 0; // Define the position in world space which we should decide on the terrain type. const float changeInHeight = mHighestPoint - mLowestPoint; float onePerc = changeInHeight / 100.0f; mRockHeight = mLowestPoint + (onePerc * 60) - mLowestPoint; // 60% and upwards will be rock. mGrassHeight = mLowestPoint + (onePerc * 30) - mLowestPoint; // 30% and upwards will be grass. mSandHeight = mLowestPoint + (onePerc * 10) - mLowestPoint; // 10% and upwards will be sand. mDirtHeight = mLowestPoint + (onePerc * 15) - mLowestPoint; // 15% and upwards will be dirt. /// Plot the vertices of the grid. float U = 0.0f; float V = 0.0f; // For the height of our height map. for (int heightCount = 0; heightCount < mHeight; heightCount++) { // For the width of our height map. for (int widthCount = 0; widthCount < mWidth; widthCount++) { // Calculate the positions the X and Z of this vertex (Only the height varies for now). float posX = static_cast<float>(widthCount); float posZ = static_cast<float>(heightCount); // If we've loaded in a height map. if (mHeightMapLoaded) { // Set the height to whatever we found in this coordinate of our array. vertices[vertex].position = D3DXVECTOR3{ posX, static_cast<float>(mpHeightMap[heightCount][widthCount]), posZ }; } else { // Set the position to a default of 0.0f. vertices[vertex].position = D3DXVECTOR3{ posX, 0.0f, posZ }; } U = static_cast<float>(widthCount); V = static_cast<float>(heightCount); vertices[vertex].UV = { U, V }; // Onto the next vertex. vertex++; } V += 1.0f; } vertex = 0; /// Calculate indices. // Iterate through the height ( - 1 because we'll draw a triangle which uses the vertex above current point, don't want to cause issues when we hit the boundary). for (int heightCount = 0; heightCount < mHeight - 1; heightCount++) { // Iterate through the width ( - 1 because we'll draw a triangle which uses the vertex to the right of the current point, don't want to cause issue's at the boundary). for (int widthCount = 0; widthCount < mWidth - 1; widthCount++) { /// Calculate indices. /// Triangle 1. // Starting point. indices[index] = vertex; // Directly above. indices[index + 1] = vertex + mWidth; // Directly to the right. indices[index + 2] = vertex + 1; /// Triangle 2. // Directly to the right. indices[index + 3] = vertex + 1; // Directly above. indices[index + 4] = vertex + mWidth; // Above and to the right. indices[index + 5] = vertex + mWidth + 1; // We've added 6 indices so increment the count by 6. index += 6; /// Calculate normals. PrioEngine::Math::VEC3 face1Vec = CalculateNormal(vertices, vertex); float length = PrioEngine::Math::GetLength(face1Vec); // Normalise the normal. vertices[vertex].normal = D3DXVECTOR3{ face1Vec.x / length, face1Vec.y / length, face1Vec.z / length }; // Increase the vertex which is our primary point. vertex++; } PrioEngine::Math::VEC3 face1Vec = CalculateNormal(vertices, vertex); float length = PrioEngine::Math::GetLength(face1Vec); // Normalise the normal. vertices[vertex].normal = D3DXVECTOR3{ face1Vec.x / length, face1Vec.y / length, face1Vec.z / length }; // We missed 1 off of the width count so auto adjust the vertex count here. vertex++; } // Add the final top row. for (int widthCount = 0; widthCount < mWidth; widthCount++) { // Bottom left PrioEngine::Math::VEC3 point1 = { vertices[vertex].position.x, vertices[vertex].position.y, vertices[vertex].position.z }; // Bottom right PrioEngine::Math::VEC3 point2 = { vertices[vertex - 1].position.x, vertices[vertex - 1].position.y, vertices[vertex - 1].position.z }; // Upper right PrioEngine::Math::VEC3 point3 = { vertices[vertex - mWidth - 1].position.x, vertices[vertex - mWidth - 1].position.y, vertices[vertex - mWidth - 1].position.z }; // Upper left PrioEngine::Math::VEC3 U = PrioEngine::Math::Subtract(point2, point1); PrioEngine::Math::VEC3 V = PrioEngine::Math::Subtract(point3, point1); PrioEngine::Math::VEC3 face1Vec = PrioEngine::Math::CrossProduct(U, V); float length = PrioEngine::Math::GetLength(face1Vec); // Normalise the normal. vertices[vertex].normal = D3DXVECTOR3{ face1Vec.x / length, face1Vec.y / length, face1Vec.z / length }; // Next vertex. vertex++; } // Reset vertex one more time, so we can use it in this function. vertex = 0; index = 0; /// Calculate average normals.. // Iterate through the height. for (int heightCount = 0; heightCount < mHeight; heightCount++) { // Iterate through the width. for (int widthCount = 0; widthCount < mWidth; widthCount++) { PrioEngine::Math::VEC3 averageNormal; averageNormal.x = 0.0f; averageNormal.y = 0.0f; averageNormal.z = 0.0f; // Directly above. if (heightCount < mHeight - 1) { int north = vertex + mWidth; averageNormal.x += vertices[north].normal.x; averageNormal.y += vertices[north].normal.y; averageNormal.z += vertices[north].normal.z; } // Directly to the right. if (widthCount < mWidth - 1) { int east = vertex + 1; averageNormal.x += vertices[east].normal.x; averageNormal.y += vertices[east].normal.y; averageNormal.z += vertices[east].normal.z; } // Directly to the left. if (widthCount > 0) { int west = vertex - 1; averageNormal.x += vertices[west].normal.x; averageNormal.y += vertices[west].normal.y; averageNormal.z += vertices[west].normal.z; } // Below if (heightCount > 0) { int south = vertex - mWidth; averageNormal.x += vertices[south].normal.x; averageNormal.y += vertices[south].normal.y; averageNormal.z += vertices[south].normal.z; } float length = PrioEngine::Math::GetLength(averageNormal); vertices[vertex].normal.x = averageNormal.x / length; vertices[vertex].normal.y = averageNormal.y / length; vertices[vertex].normal.z = averageNormal.z / length; vertex++; } } vertex = 0; // Want to start again so clear both of these lists. mTreesInfo.clear(); mPlantsInfo.clear(); for (int heightCount = 0; heightCount < mHeight; heightCount++) { for (int widthCount = 0; widthCount < mWidth; widthCount++) { CTerrain::VertexAreaType areaType = FindAreaType(vertices[vertex].position.y); if (areaType == CTerrain::VertexAreaType::Grass) { CreateTree(vertices[vertex].position, vertices[vertex].normal); CreatePlant(vertices[vertex].position, vertices[vertex].normal); } vertex++; } } vertex = 0; /////////////////////////////// // Set up the terrain tiles. /////////////////////////////// for (int y = 0; y < mHeight; y++) { for (int x = 0; x < mWidth; x++) { D3DXVECTOR3 LL, LR, UL, UR; // Pass in the surrounding tiles. if (y > 0) { mpTerrainTiles[y][x].SetDownTile(&mpTerrainTiles[y - 1][x]); } else { mpTerrainTiles[y][x].SetDownTile(&mpTerrainTiles[y][x]); } if (x > 0) { mpTerrainTiles[y][x].SetLeftTile(&mpTerrainTiles[y][x - 1]); } else { mpTerrainTiles[y][x].SetLeftTile(&mpTerrainTiles[y][x]); } if (y < mHeight - 1) { mpTerrainTiles[y][x].SetUpTile(&mpTerrainTiles[y + 1][x]); } else { mpTerrainTiles[y][x].SetUpTile(&mpTerrainTiles[y][x]); } if (x < mWidth - 1) { mpTerrainTiles[y][x].SetRightTile(&mpTerrainTiles[y][x + 1]); } else { mpTerrainTiles[y][x].SetRightTile(&mpTerrainTiles[y][x]); } ///////////////////////////////// // Calculate vertices of surrounding grids. //////////////////////////////// LL = vertices[vertex].position; if (x < mWidth - 1) { LR = vertices[vertex + 1].position; } else { LR = vertices[vertex].position; } if (y < mHeight - 1) { UL = vertices[vertex + mWidth].position; } else { UL = vertices[vertex].position; } if (y < mHeight - 1) { if (x < mWidth - 1) { UR = vertices[vertex + mWidth + 1].position; } else { UR = vertices[vertex].position; } } else { if (x < mWidth - 1) { UR = vertices[vertex - mWidth + 1].position; } else { UR = vertices[vertex].position; } } D3DXVECTOR3 centrePos = (LL + LR + UL + UR) / 4; mpTerrainTiles[y][x].SetCentrePosition(centrePos); mpTerrainTiles[y][x].SetLowerLeftVertexPosition(LL); mpTerrainTiles[y][x].SetLowerRightVertexPosition(LR); mpTerrainTiles[y][x].SetUpperLeftVertexPosition(UL); mpTerrainTiles[y][x].SetUpperRightVertexPosition(UR); VertexAreaType areatype = FindAreaType(centrePos.y); switch (areatype) { case VertexAreaType::Snow: mpTerrainTiles[y][x].SetTileType(CTerrainTile::TileType::Rock); break; case VertexAreaType::Grass: mpTerrainTiles[y][x].SetTileType(CTerrainTile::TileType::Grass); break; case VertexAreaType::Dirt: mpTerrainTiles[y][x].SetTileType(CTerrainTile::TileType::Dirt); break; case VertexAreaType::Sand: mpTerrainTiles[y][x].SetTileType(CTerrainTile::TileType::Sand); break; default: mpTerrainTiles[y][x].SetTileType(CTerrainTile::TileType::Rock); break; } vertex++; } } ////////////////////////// // Generate foliage // TODO: // Remove all of this creation from the terrain. Let the engine do it, give the user control. // Also allows seperation of objects. ///////////////////////// //if (!GenerateFoliage(device, vertices)) //{ // logger->GetInstance().WriteLine("Failed to generate the foliage for terrain."); // return false; //} // Set up the descriptor of the static vertex buffer. vertexBufferDesc.Usage = D3D11_USAGE_DEFAULT; vertexBufferDesc.ByteWidth = sizeof(VertexType) * mVertexCount; vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; vertexBufferDesc.CPUAccessFlags = 0; vertexBufferDesc.MiscFlags = 0; vertexBufferDesc.StructureByteStride = 0; // Give the subresource structure a pointer to the vertex data. vertexData.pSysMem = vertices; vertexData.SysMemPitch = 0; vertexData.SysMemSlicePitch = 0; // Create the vertex buffer. result = device->CreateBuffer(&vertexBufferDesc, &vertexData, &mpVertexBuffer); if (FAILED(result)) { logger->GetInstance().WriteLine("Failed to create the vertex buffer from the buffer description."); return false; } // Set up the description of the static index buffer. indexBufferDesc.Usage = D3D11_USAGE_DEFAULT; indexBufferDesc.ByteWidth = sizeof(unsigned long) * mIndexCount; indexBufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER; indexBufferDesc.CPUAccessFlags = 0; indexBufferDesc.MiscFlags = 0; indexBufferDesc.StructureByteStride = 0; // Give the subresource structure a pointer to the index data. indexData.pSysMem = indices; indexData.SysMemPitch = 0; indexData.SysMemSlicePitch = 0; // Create the index buffer. result = device->CreateBuffer(&indexBufferDesc, &indexData, &mpIndexBuffer); if (FAILED(result)) { logger->GetInstance().WriteLine("Failed to create the index buffer from the buffer description."); return false; } // Clean up the memory allocated to arrays. delete[] vertices; logger->GetInstance().MemoryDeallocWriteLine(typeid(vertices).name()); vertices = nullptr; delete[] indices; logger->GetInstance().MemoryDeallocWriteLine(typeid(indices).name()); indices = nullptr; if (mpWater != nullptr) { mpWater->SetXPos(GetPosX()); mpWater->SetZPos(GetPosY()); } return true; }
void Coloring(Model& integ) { //CalculateDistance(integ); CalculateDistance_AllVoxel(integ); cout << "CalculateNormal: " << endl; // CalculateNormal(integ); // vector<cv::Mat> UpSilhouette(ImageNum); ReadSilhouette(ImageNum, directory[1], model, pose[0], UpSilhouette); vector<cv::Mat> DownSilhouette(ImageNum); ReadSilhouette(ImageNum, directory[1], model, pose[1], DownSilhouette); vector<cv::Mat> UpImage(ImageNum); ReadColorImage(ImageNum, directory[0], model, pose[0], UpImage); vector<cv::Mat> DownImage(ImageNum); ReadColorImage(ImageNum, directory[0], model, pose[1], DownImage); cv::Point temp; int R, G, B; int step = UpImage[0].step; int width = UpSilhouette[0].cols; int height = UpSilhouette[0].rows; CColor tempColor(0.0, 0.0, 0.0); Color_hue tempColorH; vector<Color_hue> VoxColor; CVector3d Point_Image; short templum; //short thre(50); short thre(123); Color_hue tempBackColor; tempBackColor.r = integ.BackColor.r; tempBackColor.g = integ.BackColor.g; tempBackColor.b = integ.BackColor.b; tempBackColor.CalcHue(); integ.SurfColors.reserve(integ.SurfNum); // int ring1[][2] = { {0, 0}, {-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1} }; // // // integ.Voxel_colors = new CColor **[integ.num[0]]; for (int i(0); i < integ.num[0]; i++) { integ.Voxel_colors[i] = new CColor *[integ.num[1]]; for (int k(0); k < integ.num[1]; k++) integ.Voxel_colors[i][k] = new CColor[integ.num[2]]; } cout << "\nCheck visable voxels which can be seen\n" << endl; for (int x = 1; x < integ.num[0] - 1; x++) { for (int y = 1; y < integ.num[1] - 1; y++) { for (int z = 1; z < integ.num[2] - 1; z++) { // if (integ.Voxels[x][y][z].surf) { // VoxColor.clear(); for (int i = 0; i < ImageNum; i++) { CanSee(integ, x, y, z, CameraPosUp[i], "UP"); //true(UP) //UP if (integ.Flags[x][y][z].upCan) { integ.Voxels[x][y][z].line.push_back(CameraPosUp[i] - integ.Voxels[x][y][z].center); temp = integ.Voxels[x][y][z].CalcImageCoordofCenter(ART[i]); //� // for (int n = 0; n < 9; n++) { templum = (short)(UpSilhouette[i].data[width * (temp.y + ring1[n][1]) + temp.x + ring1[n][0]]); if (templum < thre) continue; //opencv tempColorH.Clear(); B = UpImage[i].data[step * (temp.y + ring1[n][1]) + (temp.x + ring1[n][0]) * 3]; G = UpImage[i].data[step * (temp.y + ring1[n][1]) + (temp.x + ring1[n][0]) * 3 + 1]; R = UpImage[i].data[step * (temp.y + ring1[n][1]) + (temp.x + ring1[n][0]) * 3 + 2]; tempColorH.b = B / 255.0; tempColorH.g = G / 255.0; tempColorH.r = R / 255.0; tempColorH.CalcHue(); tempColorH.CalcLuminance(); //if( fabs(tempBackColor.GetHue() - tempColorH.GetHue()) < HueGap_Thres ) //�w�i�F�̐F���ɋ߂��F�͎g�p���Ȃ� // continue; // //�V�}�E�}��p //if(tempColorH.luminance>0.5){ // tempColorH.Set(1.0,1.0,1.0); //} //else{ // tempColorH.Set(0.0,0.0,0.0); //} VoxColor.push_back(tempColorH); } } CanSee(integ, x, y, z, CameraPosDown[i], "DOWN"); //false(DOWN) //DOWN if (integ.Flags[x][y][z].downCan) { integ.Voxels[x][y][z].line.push_back(CameraPosDown[i] - integ.Voxels[x][y][z].center); temp = integ.Voxels[x][y][z].CalcImageCoordofCenter(ARTRTinv[i]); //� // for (int n = 0; n < 9; n++) { templum = (short)(DownSilhouette[i].data[width * (temp.y + ring1[n][1]) + temp.x + ring1[n][0]]); if (templum < thre) // continue; //opencv� tempColorH.Clear(); B = DownImage[i].data[step * (temp.y + ring1[n][1]) + (temp.x + ring1[n][0]) * 3]; G = DownImage[i].data[step * (temp.y + ring1[n][1]) + (temp.x + ring1[n][0]) * 3 + 1]; R = DownImage[i].data[step * (temp.y + ring1[n][1]) + (temp.x + ring1[n][0]) * 3 + 2]; tempColorH.b = B / 255.0; tempColorH.g = G / 255.0; tempColorH.r = R / 255.0; tempColorH.CalcHue(); tempColorH.CalcLuminance(); //if( fabs(tempBackColor.GetHue() - tempColorH.GetHue()) < HueGap_Thres ) // continue; // //if(tempColorH.luminance>0.5){ // tempColorH.Set(1.0,1.0,1.0); //} //else{ // tempColorH.Set(0.0,0.0,0.0); //} VoxColor.push_back(tempColorH); } } } if (!VoxColor.empty()) { tempColor = GetVoxelColor_hue_mode(VoxColor); //tempColor = GetVoxelColor_lumi_mode(VoxColor); //cout<<tempColor.r <<" "<<tempColor.g<<" "<<tempColor.b<<endl; integ.Voxel_colors[x][y][z] = tempColor; integ.SurfColors.push_back(tempColor); } else { integ.Voxel_colors[x][y][z] = tempColor; integ.SurfColors.push_back(tempColor); //0.0.0.0.0.0 } } } } } // UpSilhouette.clear(); UpSilhouette.shrink_to_fit(); DownSilhouette.clear(); DownSilhouette.shrink_to_fit(); UpImage.clear(); UpImage.shrink_to_fit(); DownImage.clear(); DownImage.shrink_to_fit(); }
void Decepticon :: DrawFoot() { if (anti_aliasing) { glEnable (GL_LINE_SMOOTH); glEnable (GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glHint (GL_LINE_SMOOTH_HINT, GL_DONT_CARE); glLineWidth (1.5); } // if statement glScalef(1, 1, 0.85); ChangeColor(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0); glBegin(display_mode); // foot toe plate CalculateNormal(20, 5, -2.5, 0, 5, -2.5); glNormal3f(normal_vector[0], normal_vector[1], normal_vector[2]); glVertex3f(-10, 0, 40); glVertex3f(-10, 5, 37.5); glVertex3f(10, 5, 37.5); glVertex3f(10, 0, 40); glEnd(); glBegin(display_mode); // foot top ramp CalculateNormal(20, 5, -27.5, 0, 5, -27.5); glNormal3f(normal_vector[0], normal_vector[1], normal_vector[2]); glVertex3f(-10, 5, 37.5); glVertex3f(-10, 10, 10); glVertex3f(10, 10, 10); glVertex3f(10, 5, 37.5); glEnd(); glBegin(display_mode); // foot top face glNormal3f(0, 1, 0); glVertex3f(-10, 10, 10); glVertex3f(-10, 10, -15); glVertex3f(10, 10, -15); glVertex3f(10, 10, 10); glEnd(); glBegin(display_mode); // foot back face CalculateNormal(20, 0, 0, 20, -10, -5); glNormal3f(normal_vector[0], normal_vector[1], normal_vector[2]); glVertex3f(-10, 10, -15); glVertex3f(10, 10, -15); glVertex3f(10, 0, -20); glVertex3f(-10, 0, -20); glEnd(); glBegin(display_mode); // foot left face glNormal3f(-1, 0, 0); glVertex3f(-10, 0, 40); glVertex3f(-10, 5, 37.5); glVertex3f(-10, 10, 10); glVertex3f(-10, 10, -15); glVertex3f(-10, 0, -20); glEnd(); glBegin(display_mode); // foot right face glNormal3f(1, 0, 0); glVertex3f(10, 0, 40); glVertex3f(10, 5, 37.5); glVertex3f(10, 10, 10); glVertex3f(10, 10, -15); glVertex3f(10, 0, -20); glEnd(); glBegin(display_mode); // foot bottom face glNormal3f(0, -1, 0); glVertex3f(-10, 0, 40); glVertex3f(10, 0, 40); glVertex3f(10, 0, -20); glVertex3f(-10, 0, -20); glEnd(); glBegin(display_mode); // foot top piece top slanted plate CalculateNormal(10, 0, 0, 10, 7.5, -15); glNormal3f(normal_vector[0], normal_vector[1], normal_vector[2]); glVertex3f(-5, 7.5, 25); glVertex3f(5, 7.5, 25); glVertex3f(5, 15, 10); glVertex3f(-5, 15, 10); glEnd(); glBegin(display_mode); // foot top piece top plate glNormal3f(0, 1, 0); glVertex3f(-5, 15, 10); glVertex3f(5, 15, 10); glVertex3f(5, 15, -5); glVertex3f(-5, 15, -5); glEnd(); glBegin(display_mode); // foot top piece left face glNormal3f(-1, 0, 0); glVertex3f(-5, 7.5, 25); glVertex3f(-5, 15, 10); glVertex3f(-5, 15, -5); glVertex3f(-5, 10, -10); glEnd(); glBegin(display_mode); // foot top piece right face glNormal3f(1, 0, 0); glVertex3f(5, 7.5, 25); glVertex3f(5, 15, 10); glVertex3f(5, 15, -5); glVertex3f(5, 10, -10); glEnd(); glBegin(display_mode); // foot top piece back face CalculateNormal(10, 5, 5, 10, 0, 0); glNormal3f(normal_vector[0], normal_vector[1], normal_vector[2]); glVertex3f(-5, 10, -10); glVertex3f(5, 10, -10); glVertex3f(5, 15, -5); glVertex3f(-5, 15, -5); glEnd(); } // DrawFoot
//================================================================================================= void Terrain::Build(bool smooth) { assert(state == 1); HRESULT hr = D3DXCreateMeshFVF(n_tris, n_verts, D3DXMESH_MANAGED | D3DXMESH_32BIT, VTerrain::fvf, device, &mesh); if(FAILED(hr)) throw Format("Failed to create new terrain mesh (%d)!", hr); VTerrain* v; //word* idx; uint* idx; uint n = 0; //uint index = 0; V(mesh->LockVertexBuffer(0, (void**)&v)); V(mesh->LockIndexBuffer(0, (void**)&idx)); #define TRI(xx,zz,uu,vv) v[n++] = VTerrain((x+xx)*tile_size, h[x+xx+(z+zz)*hszer], (z+zz)*tile_size, float(uu)/uv_mod, float(vv)/uv_mod,\ ((float)(x+xx)) / n_tiles, ((float)(z+zz)) / n_tiles) for(uint z = 0; z < n_tiles; ++z) { for(uint x = 0; x < n_tiles; ++x) { int u1 = (x%uv_mod); int u2 = ((x + 1) % uv_mod); if(u2 == 0) u2 = uv_mod; int v1 = (z%uv_mod); int v2 = ((z + 1) % uv_mod); if(v2 == 0) v2 = uv_mod; TRI(0, 0, u1, v1); TRI(0, 1, u1, v2); TRI(1, 0, u2, v1); CalculateNormal(v[n - 3], v[n - 2], v[n - 1]); TRI(0, 1, u1, v2); TRI(1, 1, u2, v2); TRI(1, 0, u2, v1); CalculateNormal(v[n - 3], v[n - 2], v[n - 1]); } } #undef TRI for(uint z = 0; z < n_parts; ++z) { for(uint x = 0; x < n_parts; ++x) { const uint z_start = z*tiles_per_part, z_end = z_start + tiles_per_part, x_start = x*tiles_per_part, x_end = x_start + tiles_per_part; for(uint zz = z_start; zz < z_end; ++zz) { for(uint xx = x_start; xx < x_end; ++xx) { for(uint j = 0; j < 6; ++j) { *idx = (xx + zz*n_tiles) * 6 + j; ++idx; } } } } } V(mesh->UnlockIndexBuffer()); state = 2; if(smooth) SmoothNormals(v); V(mesh->UnlockVertexBuffer()); }
//매번 리셋가능하도록 수정해야함 bool Ground::_SetBuffer() { mVertices.clear(); mIndices.clear(); UINT col = mData->col - 1; UINT row = mData->row - 1; mVertexCount = (col + 1) * (row + 1); mIndexCount = col * row * 2; GROUND_CUSTOM_VERTEX* vertex = new GROUND_CUSTOM_VERTEX[mVertexCount]; UINT nIndex = 0; //int imageSize = (col + 1) * (row + 1) * 3 - 3; for (UINT z = 0; z < row + 1; ++z) { for (UINT x = 0; x < col + 1; ++x) { // Z축 반전 구현해야함. nIndex = (z * (col + 1)) + x; //int nIndex2 = (row - z) * (col + 1) + x; vertex[nIndex].position.x = mPolygonSize * x; vertex[nIndex].position.z = mPolygonSize * z; //vertex[nIndex].position.y = (float)bitmapImage[nIndex * 3] * 0.005f; vertex[nIndex].position.y = mData->GetHeight(x, z) * mData->amp; vertex[nIndex].tu0 = (float)z * 40.0f /(float)(row - 1); vertex[nIndex].tv0 = (float)x * 40.0f /(float)(col - 1); vertex[nIndex].tu1 = (float)z / (float)(row - 1); vertex[nIndex].tv1 = (float)x / (float)(col - 1); vertex[nIndex].tu2 = (float)z * 40.0f / (float)(row - 1); vertex[nIndex].tv2 = (float)x * 40.0f / (float)(col - 1); //mVertices.push_back(vertex[nIndex].position); vertex[nIndex].color = D3DCOLOR_RGBA(255, 255, 255, 255); } } nIndex = 0; for (UINT z = 1; z < row; ++z) { for (UINT x = 1; x < col; ++x) { int nVtxT = col + 1; nIndex = z * nVtxT + x; D3DXVECTOR3 normal = D3DXVECTOR3(0, 0, 0); int nearVertices[6][3] = { { nIndex, nIndex - 1, nIndex - nVtxT }, { nIndex, nIndex - nVtxT, nIndex - nVtxT + 1 }, { nIndex, nIndex - nVtxT + 1, nIndex + 1 }, { nIndex, nIndex + 1, nIndex + nVtxT }, { nIndex, nIndex + nVtxT, nIndex + nVtxT - 1 }, { nIndex, nIndex + nVtxT - 1, nIndex - 1 } }; for (int k = 0; k < 6; ++k) { D3DXVECTOR3 v0 = vertex[nearVertices[k][0]].position; D3DXVECTOR3 v1 = vertex[nearVertices[k][1]].position; D3DXVECTOR3 v2 = vertex[nearVertices[k][2]].position; D3DXVECTOR3 temp = D3DXVECTOR3(0, 0, 0); CalculateNormal(&temp, &v0, &v1, &v2); normal += temp; } D3DXVec3Normalize(&normal, &normal); vertex[nIndex].normal = normal; } } GROUND_CUSTOM_INDEX* Index = new GROUND_CUSTOM_INDEX[mIndexCount]; nIndex = 0; for (UINT z = 0; z < row; z++) { for (UINT x = 0; x < col; x++) { Index[nIndex].w2 = UINT(z * (col + 1) + x); Index[nIndex].w1 = UINT((z + 1)*(col + 1) + x + 1); Index[nIndex].w0 = UINT((z + 1)*(col + 1) + x); //mIndices.push_back(D3DXVECTOR3(Index[nIndex].w0, Index[nIndex].w1, Index[nIndex].w2)); ++nIndex; Index[nIndex].w2 = UINT(z * (col + 1) + x); Index[nIndex].w1 = UINT(z * (col + 1) + x + 1); Index[nIndex].w0 = UINT((z + 1)*(col + 1) + x + 1); //mIndices.push_back(D3DXVECTOR3(Index[nIndex].w0, Index[nIndex].w1, Index[nIndex].w2)); ++nIndex; } } // mVertexBuffer->Release(); // mIndexBuffer->Release(); //버택스 버퍼 생성 if (GetDevice()->CreateVertexBuffer(mVertexCount*sizeof(GROUND_CUSTOM_VERTEX), 0, D3DFVF_GROUNDCUSTOMVERTEX, D3DPOOL_DEFAULT, &mVertexBuffer, NULL) < 0) { return false; } //락과 언락을 최대한 출일 수 있는 방법을 연구해야함 VOID* pVertices; if (mVertexBuffer->Lock(0, mVertexCount*sizeof(GROUND_CUSTOM_VERTEX), (void**)&pVertices, 0) < 0) return false; memcpy(pVertices, vertex, mVertexCount*sizeof(GROUND_CUSTOM_VERTEX)); mVertexBuffer->Unlock(); //인덱스 버퍼 생성 if (GetDevice()->CreateIndexBuffer(mIndexCount*sizeof(GROUND_CUSTOM_INDEX), 0, D3DFMT_INDEX32, D3DPOOL_DEFAULT, &mIndexBuffer, NULL) < 0) { return false; } /// 인덱스버퍼를 값으로 채운다. /// 인덱스버퍼의 Lock()함수를 호출하여 포인터를 얻어온다. VOID* pIndices; if (mIndexBuffer->Lock(0, mIndexCount*sizeof(GROUND_CUSTOM_INDEX), (void**)&pIndices, 0) < 0) return false; memcpy(pIndices, Index, mIndexCount*sizeof(GROUND_CUSTOM_INDEX)); mIndexBuffer->Unlock(); delete[] vertex; delete[] Index; return true; }
void Decepticon :: DrawBody() { if (anti_aliasing) { glEnable (GL_LINE_SMOOTH); glEnable (GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glHint (GL_LINE_SMOOTH_HINT, GL_DONT_CARE); glLineWidth (1.5); } // if statement GLfloat mat_ambient[] = {0.0, 0.0, 1.0, 1.0}; GLfloat mat_diffuse[] = {0.0, 0.0, 0.8, 1.0}; glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse); glBegin(display_mode); // bottom left edge CalculateNormal(10, 10, -2.5, -2.5, 0, -2.5); glNormal3f(normal_vector[0], normal_vector[1], normal_vector[2]); glVertex3f(-35, 0, 20); glVertex3f(-37.5, 0, 17.5); glVertex3f(-45, 10, 17.5); glVertex3f(-42.5, 10, 20); glEnd(); glBegin(display_mode); // bottom right edge CalculateNormal(2.5, 0, -2.5, 5, 10, -2.5); glNormal3f(normal_vector[0], normal_vector[1], normal_vector[2]); glVertex3f(35, 0, 20); glVertex3f(37.5, 0, 17.5); glVertex3f(45, 10, 17.5); glVertex3f(42.5, 10, 20); glEnd(); glBegin(display_mode); // left edge CalculateNormal(-2.5, 40, -2.5, -2.5, 0, -2.5); glNormal3f(normal_vector[0], normal_vector[1], normal_vector[2]); glVertex3f(-42.5, 10, 20); glVertex3f(-45, 10, 17.5); glVertex3f(-45, 50, 17.5); glVertex3f(-42.5, 47.5, 20); glEnd(); glBegin(display_mode); // right edge CalculateNormal(2.5, 0, -2.5, 2.5, 40, -2.5); glNormal3f(normal_vector[0], normal_vector[1], normal_vector[2]); glVertex3f(42.5, 10, 20); glVertex3f(45, 10, 17.5); glVertex3f(45, 50, 17.5); glVertex3f(42.5, 47.5, 20); glEnd(); glBegin(display_mode); // top left edge CalculateNormal(30, 2.5, -2.5, 27.5, 2.5, -2.5); glNormal3f(normal_vector[0], normal_vector[1], normal_vector[2]); glVertex3f(-42.5, 47.5, 20); glVertex3f(-45, 50, 17.5); glVertex3f(-15, 50, 17.5); glVertex3f(-15, 47.5, 20); glEnd(); glBegin(display_mode); // top right edge CalculateNormal(2.5, 2.5, -2.5, -27.5, 2.5, -2.5); glNormal3f(normal_vector[0], normal_vector[1], normal_vector[2]); glVertex3f(42.5, 47.5, 20); glVertex3f(45, 50, 17.5); glVertex3f(15, 50, 17.5); glVertex3f(15, 47.5, 20); glEnd(); glBegin(display_mode); // left inner wall glNormal3f(0, 0, 1); glVertex3f(-15, 50, 15); glVertex3f(-15, 50, 17.5); glVertex3f(-15, 47.5, 20); glVertex3f(-15, 45, 20); glVertex3f(-15, 45, 17.5); glEnd(); glBegin(display_mode); // right inner wall glNormal3f(0, 0, 1); glVertex3f(15, 50, 15); glVertex3f(15, 50, 17.5); glVertex3f(15, 47.5, 20); glVertex3f(15, 45, 20); glVertex3f(15, 45, 17.5); glEnd(); glBegin(display_mode); // middle flat wall glNormal3f(0, 1, 0); glVertex3f(-15, 45, 17.5); glVertex3f(-15, 45, 20); glVertex3f(15, 45, 20); glVertex3f(15, 45, 17.5); glEnd(); glBegin(display_mode); // middle slanted edge CalculateNormal(30, 5, -2.5, 0, 5, -2.5); glNormal3f(normal_vector[0], normal_vector[1], normal_vector[2]); glVertex3f(-15, 45, 17.5); glVertex3f(-15, 50, 15); glVertex3f(15, 50, 15); glVertex3f(15, 45, 17.5); glEnd(); glBegin(display_mode); // bottom edge CalculateNormal(-2.5, 0, -2.5, 72.5, 0, -2.5); glNormal3f(normal_vector[0], normal_vector[1], normal_vector[2]); glVertex3f(-35, 0, 20); glVertex3f(-37.5, 0, 17.5); glVertex3f(37.5, 0, 17.5); glVertex3f(35, 0, 20); glEnd(); glBegin(display_mode); // back face glNormal3f(0, 0, -1); glVertex3f(-37.5, 0, -17.5); glVertex3f(-45, 10, -17.5); glVertex3f(-45, 50, -17.5); glVertex3f(45, 50, -17.5); glVertex3f(45, 10, -17.5); glVertex3f(37.5, 0, -17.5); glEnd(); glBegin(display_mode); // front bevelled left face glNormal3f(0, 0, 1); glVertex3f(-35, 0, 20); glVertex3f(-42.5, 10, 20); glVertex3f(-42.5, 47.5, 20); glVertex3f(-30, 40, 20); glVertex3f(-30, 15, 20); glVertex3f(-27.5, 12.5, 20); glEnd(); glBegin(display_mode); // front bevelled left edge glNormal3f(1, 0, 0); glVertex3f(-30, 40, 20); glVertex3f(-30, 15, 20); glVertex3f(-30, 15, 17.5); glVertex3f(-30, 40, 17.5); glEnd(); glBegin(display_mode); // front bevelled right face glNormal3f(0, 0, 1); glVertex3f(35, 0, 20); glVertex3f(42.5, 10, 20); glVertex3f(42.5, 47.5, 20); glVertex3f(30, 40, 20); glVertex3f(30, 15, 20); glVertex3f(27.5, 12.5, 20); glEnd(); glBegin(display_mode); // front bevelled right edge glNormal3f(-1, 0, 0); glVertex3f(30, 40, 20); glVertex3f(30, 15, 20); glVertex3f(30, 15, 17.5); glVertex3f(30, 40, 17.5); glEnd(); glBegin(display_mode); // front bevelled bottom face glNormal3f(0, 0, 1); glVertex3f(-35, 0, 20); glVertex3f(-27.5, 12.5, 20); glVertex3f(27.5, 12.5, 20); glVertex3f(35, 0, 20); glEnd(); glBegin(display_mode); // front bevelled bottom edge glNormal3f(0, 1, 0); glVertex3f(-27.5, 12.5, 20); glVertex3f(27.5, 12.5, 20); glVertex3f(27.5, 12.5, 17.5); glVertex3f(-27.5, 12.5, 17.5); glEnd(); glBegin(display_mode); // front bevelled bottom left edge CalculateNormal(-2.5, 2.5, -2.5, -2.5, 2.5, 0); glNormal3f(normal_vector[0], normal_vector[1], normal_vector[2]); glVertex3f(-27.5, 12.5, 20); glVertex3f(-30, 15, 20); glVertex3f(-30, 15, 17.5); glVertex3f(-27.5, 12.5, 17.5); glEnd(); glBegin(display_mode); // front bevelled bottom right edge CalculateNormal(2.5, 2.5, 0, 2.5, 2.5, -2.5); glNormal3f(normal_vector[0], normal_vector[1], normal_vector[2]); glVertex3f(27.5, 12.5, 20); glVertex3f(30, 15, 20); glVertex3f(30, 15, 17.5); glVertex3f(27.5, 12.5, 17.5); glEnd(); glBegin(display_mode); // front bevelled top left face glNormal3f(0, 0, 1); glVertex3f(-30, 40, 20); glVertex3f(-42.5, 47.5, 20); glVertex3f(-15, 47.5, 20); glVertex3f(-15, 40, 20); glEnd(); glBegin(display_mode); // front bevelled top right face glNormal3f(0, 0, 1); glVertex3f(30, 40, 20); glVertex3f(42.5, 47.5, 20); glVertex3f(15, 47.5, 20); glVertex3f(15, 40, 20); glEnd(); glBegin(display_mode); // front bevelled top middle face glNormal3f(0, 0, 1); glVertex3f(-15, 45, 20); glVertex3f(-15, 40, 20); glVertex3f(15, 40, 20); glVertex3f(15, 45, 20); glEnd(); glBegin(display_mode); // front bevelled top edge glNormal3f(0, 1, 0); glVertex3f(-30, 40, 20); glVertex3f(30, 40, 20); glVertex3f(30, 40, 17.5); glVertex3f(-30, 40, 17.5); glEnd(); glBegin(display_mode); // bottom face glNormal3f(0, -1, 0); glVertex3f(-37.5, 0, 17.5); glVertex3f(-37.5, 0, -17.5); glVertex3f(37.5, 0, -17.5); glVertex3f(37.5, 0, 17.5); glEnd(); glBegin(display_mode); // bottom left face CalculateNormal(-7.5, 10, 35, -7.5, 10, 0); glNormal3f(normal_vector[0], normal_vector[1], normal_vector[2]); glVertex3f(-37.5, 0, 17.5); glVertex3f(-45, 10, 17.5); glVertex3f(-45, 10, -17.5); glVertex3f(-37.5, 0, -17.5); glEnd(); glBegin(display_mode); // bottom right face CalculateNormal(7.5, 10, 0, 7.5, 10, 35); glNormal3f(normal_vector[0], normal_vector[1], normal_vector[2]); glVertex3f(37.5, 0, 17.5); glVertex3f(45, 10, 17.5); glVertex3f(45, 10, -17.5); glVertex3f(37.5, 0, -17.5); glEnd(); glBegin(display_mode); // left face glNormal3f(-1, 0, 0); glVertex3f(-45, 10, 17.5); glVertex3f(-45, 50, 17.5); glVertex3f(-45, 50, -17.5); glVertex3f(-45, 10, -17.5); glEnd(); glBegin(display_mode); // right face glNormal3f(1, 0, 0); glVertex3f(45, 10, 17.5); glVertex3f(45, 50, 17.5); glVertex3f(45, 50, -17.5); glVertex3f(45, 10, -17.5); glEnd(); glBegin(display_mode); // top face glNormal3f(0, 1, 0); glVertex3f(-45, 50, 17.5); glVertex3f(-15, 50, 17.5); glVertex3f(-15, 50, 15); glVertex3f(15, 50, 15); glVertex3f(15, 50, 17.5); glVertex3f(45, 50, 17.5); glVertex3f(45, 50, -17.5); glVertex3f(-45, 50, -17.5); glEnd(); mat_ambient[0] = 1.0; mat_ambient[1] = 1.0; mat_ambient[2] = 0.0; mat_diffuse[0] = 0.8; mat_diffuse[1] = 0.8; mat_diffuse[2] = 0.0; glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse); glBegin(display_mode); // left upper stripe face glNormal3f(0, 0, 1); glVertex3f(-42.5, 35, 21); glVertex3f(-42.5, 31, 21); glVertex3f(-32.5, 31, 21); glVertex3f(-32.5, 35, 21); glEnd(); glBegin(display_mode); // right upper stripe face glNormal3f(0, 0, 1); glVertex3f(42.5, 35, 21); glVertex3f(42.5, 31, 21); glVertex3f(32.5, 31, 21); glVertex3f(32.5, 35, 21); glEnd(); glBegin(display_mode); // left lower stripe face glNormal3f(0, 0, 1); glVertex3f(-42.5, 29, 21); glVertex3f(-42.5, 25, 21); glVertex3f(-32.5, 25, 21); glVertex3f(-32.5, 29, 21); glEnd(); glBegin(display_mode); // right lower stripe face glNormal3f(0, 0, 1); glVertex3f(42.5, 29, 21); glVertex3f(42.5, 25, 21); glVertex3f(32.5, 25, 21); glVertex3f(32.5, 29, 21); glEnd(); glBegin(display_mode); // left upper stripe left rise glNormal3f(-1, 0, 0); glVertex3f(-42.5, 35, 21); glVertex3f(-42.5, 31, 21); glVertex3f(-42.5, 31, 20); glVertex3f(-42.5, 35, 20); glEnd(); glBegin(display_mode); // right upper stripe right rise glNormal3f(1, 0, 0); glVertex3f(42.5, 35, 21); glVertex3f(42.5, 31, 21); glVertex3f(42.5, 31, 20); glVertex3f(42.5, 35, 20); glEnd(); glBegin(display_mode); // left upper stripe upper rise glNormal3f(0, 1, 0); glVertex3f(-42.5, 35, 21); glVertex3f(-32.5, 35, 21); glVertex3f(-32.5, 35, 20); glVertex3f(-42.5, 35, 20); glEnd(); glBegin(display_mode); // right upper stripe upper rise glNormal3f(0, 1, 0); glVertex3f(42.5, 35, 21); glVertex3f(32.5, 35, 21); glVertex3f(32.5, 35, 20); glVertex3f(42.5, 35, 20); glEnd(); glBegin(display_mode); // left upper stripe right rise glNormal3f(1, 0, 0); glVertex3f(-32.5, 35, 21); glVertex3f(-32.5, 31, 21); glVertex3f(-32.5, 31, 20); glVertex3f(-32.5, 35, 20); glEnd(); glBegin(display_mode); // right upper stripe left rise glNormal3f(-1, 0, 0); glVertex3f(32.5, 35, 21); glVertex3f(32.5, 31, 21); glVertex3f(32.5, 31, 20); glVertex3f(32.5, 35, 20); glEnd(); glBegin(display_mode); // left upper stripe lower rise glNormal3f(0, -1, 0); glVertex3f(-42.5, 31, 21); glVertex3f(-32.5, 31, 21); glVertex3f(-32.5, 31, 20); glVertex3f(-42.5, 31, 20); glEnd(); glBegin(display_mode); // right upper stripe lower rise glNormal3f(0, -1, 0); glVertex3f(42.5, 31, 21); glVertex3f(32.5, 31, 21); glVertex3f(32.5, 31, 20); glVertex3f(42.5, 31, 20); glEnd(); glBegin(display_mode); // left lower stripe left rise glNormal3f(-1, 0, 0); glVertex3f(-42.5, 29, 21); glVertex3f(-42.5, 25, 21); glVertex3f(-42.5, 25, 20); glVertex3f(-42.5, 29, 20); glEnd(); glBegin(display_mode); // right lower stripe right rise glNormal3f(1, 0, 0); glVertex3f(42.5, 29, 21); glVertex3f(42.5, 25, 21); glVertex3f(42.5, 25, 20); glVertex3f(42.5, 29, 20); glEnd(); glBegin(display_mode); // left lower stripe upper rise glNormal3f(0, 1, 0); glVertex3f(-42.5, 29, 21); glVertex3f(-32.5, 29, 21); glVertex3f(-32.5, 29, 20); glVertex3f(-42.5, 29, 20); glEnd(); glBegin(display_mode); // right lower stripe upper rise glNormal3f(0, 1, 0); glVertex3f(42.5, 29, 21); glVertex3f(32.5, 29, 21); glVertex3f(32.5, 29, 20); glVertex3f(42.5, 29, 20); glEnd(); glBegin(display_mode); // left lower stripe right rise glNormal3f(1, 0, 0); glVertex3f(-32.5, 29, 21); glVertex3f(-32.5, 25, 21); glVertex3f(-32.5, 25, 20); glVertex3f(-32.5, 29, 21); glEnd(); glBegin(display_mode); // right lower stripe left rise glNormal3f(-1, 0, 0); glVertex3f(32.5, 29, 21); glVertex3f(32.5, 25, 21); glVertex3f(32.5, 25, 20); glVertex3f(32.5, 29, 21); glEnd(); glBegin(display_mode); // left lower stripe lower rise glNormal3f(0, -1, 0); glVertex3f(-42.5, 25, 21); glVertex3f(-32.5, 25, 21); glVertex3f(-32.5, 25, 20); glVertex3f(-42.5, 25, 20); glEnd(); glBegin(display_mode); // right lower stripe lower rise glNormal3f(0, 0, -1); glVertex3f(42.5, 25, 21); glVertex3f(32.5, 25, 21); glVertex3f(32.5, 25, 20); glVertex3f(42.5, 25, 20); glEnd(); mat_ambient[0] = 0.0; mat_ambient[1] = 0.0; mat_ambient[2] = 0.8; mat_diffuse[0] = 0.0; mat_diffuse[1] = 0.0; mat_diffuse[2] = 0.5; glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse); glBegin(display_mode); // back brace back left face glNormal3f(0, 0, -1); glVertex3f(-45, 20, -15); glVertex3f(-50, 25, -15); glVertex3f(-50, 50, -15); glVertex3f(-45, 50, -15); glEnd(); glBegin(display_mode); // back brace back right face glNormal3f(0, 0, -1); glVertex3f(45, 20, -15); glVertex3f(50, 25, -15); glVertex3f(50, 50, -15); glVertex3f(45, 50, -15); glEnd(); glBegin(display_mode); // back brace back top face glNormal3f(0, 0, -1); glVertex3f(-50, 50, -15); glVertex3f(-45, 55, -15); glVertex3f(45, 55, -15); glVertex3f(50, 50, -15); glEnd(); glBegin(display_mode); // back brace front left face glNormal3f(0, 0, 1); glVertex3f(-45, 20, -5); glVertex3f(-50, 25, -5); glVertex3f(-50, 50, -5); glVertex3f(-45, 50, -5); glEnd(); glBegin(display_mode); // back brace front right face glNormal3f(0, 0, 1); glVertex3f(45, 20, -5); glVertex3f(50, 25, -5); glVertex3f(50, 50, -5); glVertex3f(45, 50, -5); glEnd(); glBegin(display_mode); // back brace front top face glNormal3f(0, 0, 1); glVertex3f(-50, 50, -5); glVertex3f(-45, 55, -5); glVertex3f(45, 55, -5); glVertex3f(50, 50, -5); glEnd(); glBegin(display_mode); // front brace back left face glNormal3f(0, 0, -1); glVertex3f(-45, 20, 5); glVertex3f(-50, 25, 5); glVertex3f(-50, 50, 5); glVertex3f(-45, 50, 5); glEnd(); glBegin(display_mode); // front brace back right face glNormal3f(0, 0, -1); glVertex3f(45, 20, 5); glVertex3f(50, 25, 5); glVertex3f(50, 50, 5); glVertex3f(45, 50, 5); glEnd(); glBegin(display_mode); // front brace back top face glNormal3f(0, 0, 1); glVertex3f(-50, 50, 15); glVertex3f(-45, 55, 15); glVertex3f(45, 55, 15); glVertex3f(50, 50, 15); glEnd(); glBegin(display_mode); // front brace back left face glNormal3f(0, 0, 1); glVertex3f(-45, 20, 15); glVertex3f(-50, 25, 15); glVertex3f(-50, 50, 15); glVertex3f(-45, 50, 15); glEnd(); glBegin(display_mode); // front brace back right face glNormal3f(0, 0, 1); glVertex3f(45, 20, 15); glVertex3f(50, 25, 15); glVertex3f(50, 50, 15); glVertex3f(45, 50, 15); glEnd(); glBegin(display_mode); // front brace back top face glNormal3f(0, 0, 1); glVertex3f(-50, 50, 15); glVertex3f(-45, 55, 15); glVertex3f(45, 55, 15); glVertex3f(50, 50, 15); glEnd(); glBegin(display_mode); // back brace lower left edge CalculateNormal(-5, 5, 0, -5, 5, -10); glNormal3f(normal_vector[0], normal_vector[1], normal_vector[2]); glVertex3f(-45, 20, -5); glVertex3f(-50, 25, -5); glVertex3f(-50, 25, -15); glVertex3f(-45, 20, -15); glEnd(); glBegin(display_mode); // front brace lower left edge CalculateNormal(-5, 5, 10, -5, 5, 0); glNormal3f(normal_vector[0], normal_vector[1], normal_vector[2]); glVertex3f(-45, 20, 5); glVertex3f(-50, 25, 5); glVertex3f(-50, 25, 15); glVertex3f(-45, 20, 15); glEnd(); glBegin(display_mode); // back brace lower right edge CalculateNormal(5, 5, -10, 5, 5, 0); glNormal3f(normal_vector[0], normal_vector[1], normal_vector[2]); glVertex3f(45, 20, -5); glVertex3f(50, 25, -5); glVertex3f(50, 25, -15); glVertex3f(45, 20, -15); glEnd(); glBegin(display_mode); // front brace lower right edge CalculateNormal(5, 5, 0, 5, 5, 10); glNormal3f(normal_vector[0], normal_vector[1], normal_vector[2]); glVertex3f(45, 20, 5); glVertex3f(50, 25, 5); glVertex3f(50, 25, 15); glVertex3f(45, 20, 15); glEnd(); glBegin(display_mode); // back brace left edge glNormal3f(-1, 0, 0); glVertex3f(-50, 25, -5); glVertex3f(-50, 50, -5); glVertex3f(-50, 50, -15); glVertex3f(-50, 25, -15); glEnd(); glBegin(display_mode); // front brace left edge glNormal3f(-1, 0, 0); glVertex3f(-50, 25, 5); glVertex3f(-50, 50, 5); glVertex3f(-50, 50, 15); glVertex3f(-50, 25, 15); glEnd(); glBegin(display_mode); // back brace right edge glNormal3f(1, 0, 0); glVertex3f(50, 25, -5); glVertex3f(50, 50, -5); glVertex3f(50, 50, -15); glVertex3f(50, 25, -15); glEnd(); glBegin(display_mode); // front brace right edge glNormal3f(1, 0, 0); glVertex3f(50, 25, 5); glVertex3f(50, 50, 5); glVertex3f(50, 50, 15); glVertex3f(50, 25, 15); glEnd(); glBegin(display_mode); // back brace top left edge CalculateNormal(5, 5, 0, 5, 5, -10); glNormal3f(normal_vector[0], normal_vector[1], normal_vector[2]); glVertex3f(-50, 50, -5); glVertex3f(-45, 55, -5); glVertex3f(-45, 55, -15); glVertex3f(-50, 50, -15); glEnd(); glBegin(display_mode); // back brace top right edge CalculateNormal(-5, 5, -10, -5, 5, 0); glNormal3f(normal_vector[0], normal_vector[1], normal_vector[2]); glVertex3f(50, 50, -5); glVertex3f(45, 55, -5); glVertex3f(45, 55, -15); glVertex3f(50, 50, -15); glEnd(); glBegin(display_mode); // front brace top left edge CalculateNormal(5, 5, 10, 5, 5, 0); glNormal3f(normal_vector[0], normal_vector[1], normal_vector[2]); glVertex3f(-50, 50, 5); glVertex3f(-45, 55, 5); glVertex3f(-45, 55, 15); glVertex3f(-50, 50, 15); glEnd(); glBegin(display_mode); // front brace top right edge CalculateNormal(5, 5, 0, -5, 5, 10); glNormal3f(normal_vector[0], normal_vector[1], normal_vector[2]); glVertex3f(50, 50, 5); glVertex3f(45, 55, 5); glVertex3f(45, 55, 15); glVertex3f(50, 50, 15); glEnd(); glBegin(display_mode); // back brace top edge glNormal3f(0, 1, 0); glVertex3f(-45, 55, -5); glVertex3f(45, 55, -5); glVertex3f(45, 55, -15); glVertex3f(-45, 55, -15); glEnd(); glBegin(display_mode); // front brace top edge glNormal3f(0, 1, 0); glVertex3f(-45, 55, 5); glVertex3f(45, 55, 5); glVertex3f(45, 55, 15); glVertex3f(-45, 55, 15); glEnd(); mat_ambient[0] = 1.0; mat_ambient[1] = 1.0; mat_ambient[2] = 1.0; mat_diffuse[0] = 1.0; mat_diffuse[1] = 1.0; mat_diffuse[2] = 1.0; glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse); glBegin(display_mode); // gun-mount front face glNormal3f(0, 0, 1); glVertex3f(22, 55, 12.5); glVertex3f(22, 60, 12.5); glVertex3f(32, 60, 12.5); glVertex3f(32, 55, 12.5); glEnd(); glBegin(display_mode); // gun-mount back face glNormal3f(0, 0, -1); glVertex3f(22, 55, 7.5); glVertex3f(22, 60, 7.5); glVertex3f(32, 60, 7.5); glVertex3f(32, 55, 7.5); glEnd(); glBegin(display_mode); // gun-mount left face glNormal3f(-1, 0, 0); glVertex3f(22, 55, 12.5); glVertex3f(22, 60, 12.5); glVertex3f(22, 60, 7.5); glVertex3f(22, 55, 7.5); glEnd(); glBegin(display_mode); // gun-mount right face glNormal3f(1, 0, 0); glVertex3f(32, 55, 12.5); glVertex3f(32, 60, 12.5); glVertex3f(32, 60, 7.5); glVertex3f(32, 55, 7.5); glEnd(); glBegin(display_mode); // gun-mount top face glNormal3f(0, 1, 0); glVertex3f(22, 60, 12.5); glVertex3f(22, 60, 7.5); glVertex3f(32, 60, 7.5); glVertex3f(32, 60, 12.5); glEnd(); mat_ambient[0] = 0.0; mat_ambient[1] = 0.0; mat_ambient[2] = 1.0; mat_diffuse[0] = 0.0; mat_diffuse[1] = 0.0; mat_diffuse[2] = 0.8; glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse); if (display_mode == GL_LINE_LOOP) { glPushMatrix(); glTranslatef(-30, 67.5, -32.5); glRotatef(90, 1, 0, 0); TaperedWireCylinder(0, 12.5, 0, 20); TaperedWireCylinder(15, 12.5, 12.5, 20); glTranslatef(0, 15, 0); TaperedWireCylinder(0, 12.5, 9.5, 20); TaperedWireCylinder(3, 9.5, 9.5, 20); glTranslatef(0, 3, 0); TaperedWireCylinder(0, 9.5, 12.5, 20); TaperedWireCylinder(30, 12.5, 12.5, 20); glTranslatef(0, 30, 0); TaperedWireCylinder(0, 12.5, 9.5, 20); TaperedWireCylinder(2, 9.5, 9.5, 20); glTranslatef(0, 2, 0); TaperedWireCylinder(0, 9.5, 12.5, 20); TaperedWireCylinder(4, 12.5, 12.5, 20); glTranslatef(0, 4, 0); TaperedWireCylinder(0, 12.5, 9.5, 20); TaperedWireCylinder(5, 9.5, 9.5, 20); glTranslatef(0, 5, 0); TaperedWireCylinder(0, 9.5, 12.5, 20); TaperedWireCylinder(4, 12.5, 12.5, 20); glTranslatef(0, 4, 0); TaperedWireCylinder(0, 12.5, 9.5, 20); TaperedWireCylinder(2, 9.5, 9.5, 20); glTranslatef(0, 2, 0); TaperedWireCylinder(0, 9.5, 12.5, 20); glPushMatrix(); glTranslatef(0, 5, 0); mat_ambient[0] = 1.0; mat_ambient[1] = 0.0; mat_ambient[2] = 0.0; mat_diffuse[0] = 0.8; mat_diffuse[1] = 0.0; mat_diffuse[2] = 0.0; glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse); TaperedWireCylinder(5, 12.5, 12.5, 20); mat_ambient[0] = 0.0; mat_ambient[1] = 0.0; mat_ambient[2] = 1.0; mat_diffuse[0] = 0.0; mat_diffuse[1] = 0.0; mat_diffuse[2] = 1.0; glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse); glPopMatrix(); TaperedWireCylinder(15, 12.5, 12.5, 20); glTranslatef(0, 15, 0); TaperedWireCylinder(0, 12.5, 9.5, 20); glTranslatef(0, -2, 0); TaperedWireCylinder(0, 9.5, 0, 20); TaperedWireCylinder(2, 9.5, 9.5, 20); glPopMatrix(); } // if statement else if (display_mode == GL_POLYGON) { glPushMatrix(); glTranslatef(-30, 67.5, -32.5); glRotatef(90, 1, 0, 0); TaperedCylinder(0, 12.5, 0, 20); TaperedCylinder(15, 12.5, 12.5, 20); glTranslatef(0, 15, 0); TaperedCylinder(0, 12.5, 9.5, 20); TaperedCylinder(3, 9.5, 9.5, 20); glTranslatef(0, 3, 0); TaperedCylinder(0, 9.5, 12.5, 20); TaperedCylinder(30, 12.5, 12.5, 20); glTranslatef(0, 30, 0); TaperedCylinder(0, 12.5, 9.5, 20); TaperedCylinder(2, 9.5, 9.5, 20); glTranslatef(0, 2, 0); TaperedCylinder(0, 9.5, 12.5, 20); TaperedCylinder(4, 12.5, 12.5, 20); glTranslatef(0, 4, 0); TaperedCylinder(0, 12.5, 9.5, 20); TaperedCylinder(5, 9.5, 9.5, 20); glTranslatef(0, 5, 0); TaperedCylinder(0, 9.5, 12.5, 20); TaperedCylinder(4, 12.5, 12.5, 20); glTranslatef(0, 4, 0); TaperedCylinder(0, 12.5, 9.5, 20); TaperedCylinder(2, 9.5, 9.5, 20); glTranslatef(0, 2, 0); TaperedCylinder(0, 9.5, 12.5, 20); glPushMatrix(); glTranslatef(0, 5, 0); mat_ambient[0] = 1.0; mat_ambient[1] = 0.0; mat_ambient[2] = 0.0; mat_diffuse[0] = 0.8; mat_diffuse[1] = 0.0; mat_diffuse[2] = 0.0; glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse); TaperedCylinder(5, 12.6, 12.6, 20); mat_ambient[0] = 0.0; mat_ambient[1] = 0.0; mat_ambient[2] = 1.0; mat_diffuse[0] = 0.0; mat_diffuse[1] = 0.0; mat_diffuse[2] = 1.0; glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse); glPopMatrix(); TaperedCylinder(15, 12.5, 12.5, 20); glTranslatef(0, 15, 0); TaperedCylinder(0, 12.5, 9.5, 20); glTranslatef(0, -2, 0); TaperedCylinder(0, 9.5, 0, 20); TaperedCylinder(2, 9.5, 9.5, 20); glPopMatrix(); } // else statement } // DrawBody