void mu3(int x,int y,char po[24],int f) { int m,n; static int i=0; for(m=0;m<2;m++) { for(n=0;n<3;n++) { blackground z1(x,y,m,n,BACKGROUND_BLUE|BACKGROUND_INTENSITY|FOREGROUND_INTENSITY); z1.display1(); if(f&&i<24) { po[i++]=x+m; // x po[i++]=y+n; // y po[i++]=2; // 颜色 } } } for(n=0,m=0;m<2;m++) { blackground z10(x+2,y+1,m,n,BACKGROUND_BLUE|BACKGROUND_INTENSITY|FOREGROUND_INTENSITY); z10.display1(); if(f&&i<24) { po[i++]=x+m+2; // x po[i++]=y+n+1; // y po[i++]=2; // 颜色 } } }
void CreateHeightFieldMesh (NewtonCollision* collision, Entity* ent) { int width; int height; dFloat hScale; dFloat vScale; unsigned short* elevations; NewtonCollisionInfoRecord collisionInfo; // keep the compiler happy memset (&collisionInfo, 0, sizeof (NewtonCollisionInfoRecord)); NewtonCollisionGetInfo (collision, &collisionInfo); // get the info from the collision mesh and create a visual mesh width = collisionInfo.m_heightField.m_width; height = collisionInfo.m_heightField.m_height; elevations = collisionInfo.m_heightField.m_elevation; vScale = collisionInfo.m_heightField.m_verticalScale; hScale = collisionInfo.m_heightField.m_horizonalScale; // allocate space to store vertex data ent->m_vertexCount = width * height; ent->m_vertex = (dFloat*) malloc (3 * width * height * sizeof (dFloat)); ent->m_normal = (dFloat*) malloc (3 * width * height * sizeof (dFloat)); ent->m_uv = (dFloat*) malloc (2 * width * height * sizeof (dFloat)); // scan the height field and convert every cell into two triangles for (int z = 0; z < height; z ++) { int z0; int z1; z0 = ((z - 1) < 0) ? 0 : z - 1; z1 = ((z + 1) > (height - 1)) ? height - 1 : z + 1 ; for (int x = 0; x < width; x ++) { int x0; int x1; x0 = ((x - 1) < 0) ? 0 : x - 1; x1 = ((x + 1) > (width - 1)) ? width - 1 : x + 1 ; dVector p0 (hScale * x0, elevations[z * width + x1] * vScale, hScale * z); dVector p1 (hScale * x1, elevations[z * width + x0] * vScale, hScale * z); dVector x10 (p1 - p0); dVector q0 (hScale * x, elevations[z0 * width + x] * vScale, hScale * z0); dVector q1 (hScale * x, elevations[z1 * width + x] * vScale, hScale * z1); dVector z10 (q1 - q0); dVector normal (z10 * x10); normal = normal.Scale (dSqrt (1.0f / (normal % normal))); dVector point (hScale * x, elevations[z * width + x] * vScale, hScale * z); ent->m_vertex[(z * width + x) * 3 + 0] = point.m_x; ent->m_vertex[(z * width + x) * 3 + 1] = point.m_y; ent->m_vertex[(z * width + x) * 3 + 2] = point.m_z; ent->m_normal[(z * width + x) * 3 + 0] = normal.m_x; ent->m_normal[(z * width + x) * 3 + 1] = normal.m_y; ent->m_normal[(z * width + x) * 3 + 2] = normal.m_z; ent->m_uv[(z * width + x) * 2 + 0] = x * TEXTURE_SCALE; ent->m_uv[(z * width + x) * 2 + 1] = z * TEXTURE_SCALE; } } // since the bitmap sample is 256 x 256, i fix into a single 16 bit index vertex array with ent->m_subMeshCount = 1; ent->m_subMeshes = (Entity::SubMesh*) malloc (sizeof (Entity::SubMesh)); // allocate space to the index list ent->m_subMeshes[0].m_textureHandle = LoadTexture ("grassAndDirt.tga"); ent->m_subMeshes[0].m_indexCount = (width - 1) * (height - 1) * 6; ent->m_subMeshes[0].m_indexArray = (unsigned short*) malloc (ent->m_subMeshes[0].m_indexCount * sizeof (unsigned short)); // now following the grid pattern and create and index list int index; int vertexIndex; index = 0; vertexIndex = 0; for (int z = 0; z < height - 1; z ++) { vertexIndex = z * width; for (int x = 0; x < width - 1; x ++) { ent->m_subMeshes[0].m_indexArray[index + 0] = GLushort (vertexIndex); ent->m_subMeshes[0].m_indexArray[index + 1] = GLushort (vertexIndex + width); ent->m_subMeshes[0].m_indexArray[index + 2] = GLushort (vertexIndex + 1); index += 3; ent->m_subMeshes[0].m_indexArray[index + 0] = GLushort (vertexIndex + 1); ent->m_subMeshes[0].m_indexArray[index + 1] = GLushort (vertexIndex + width); ent->m_subMeshes[0].m_indexArray[index + 2] = GLushort (vertexIndex + width + 1); index += 3; vertexIndex ++; } } // Optimize the mesh for hardware rendering if possible ent->OptimizeMesh(); /* dVector boxP0; dVector boxP1; // get the position of the aabb of this geometry dMatrix matrix (ent->m_curRotation, ent->m_curPosition); NewtonCollisionCalculateAABB (collision, &matrix[0][0], &boxP0.m_x, &boxP1.m_x); // place the origin of the visual mesh at the center of the height field matrix.m_posit = (boxP0 + boxP1).Scale (-0.5f); matrix.m_posit.m_w = 1.0f; ent->m_curPosition = matrix.m_posit; ent->m_prevPosition = matrix.m_posit; // create the level rigid body body = NewtonCreateBody(world, collision); // release the collision tree (this way the application does not have to do book keeping of Newton objects NewtonReleaseCollision (world, collision); // save the pointer to the graphic object with the body. NewtonBodySetUserData (body, ent); // set the global position of this body NewtonBodySetMatrix (body, &matrix[0][0]); // set the destructor for this object // NewtonBodySetDestructorCallback (body, Destructor); // get the position of the aabb of this geometry NewtonCollisionCalculateAABB (collision, &matrix[0][0], &boxP0.m_x, &boxP1.m_x); // add some extra padding the world size boxP0.m_x -= 10.0f; boxP0.m_y -= 10.0f; boxP0.m_z -= 10.0f; boxP1.m_x += 10.0f; boxP1.m_y += 400.0f; boxP1.m_z += 10.0f; // set the world size NewtonSetWorldSize (world, &boxP0.m_x, &boxP1.m_x); return body; */ }