#include #if !defined(HFSLIMMZ0P3_HPP) #include "HFSlimMZ0p3.hpp" #include "terra\terra.hpp" #endif const Scalar One_Over_Three = 1.0f/3.0f; extern FILE *analyzeFile; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void ToDrawTriangle::GetSurfaceAreaAndCentroid() { // //--------------------- // Set up the variables //--------------------- // Point3D position_a = Point3D::Identity, position_b, position_c = Point3D::Identity; Vector3D leg_1, leg_2 = Vector3D::Identity; // //----------------------------------- // Spin through, testing the vertices //----------------------------------- // area = 0.0f; center = Point3D::Identity; // //----------------------------------------------- // Generate all the information on the first pass //----------------------------------------------- // position_a = v[0]; position_b = v[1]; position_c = v[2]; leg_1.Subtract(position_b, position_a); leg_2.Subtract(position_c, position_a); // //----------------------------------------------------------------- // Compute the cross-product of the two legs to get the area of the // triangle //----------------------------------------------------------------- // Vector3D vcp; vcp.Cross(leg_1, leg_2); // //------------------------------------------------------------------- // Add the three triangle points together and multiply by the area of // the triangle to give a weighted sum for the polygon centroid //------------------------------------------------------------------- // Point3D centroid; centroid.Add(position_a, position_b); centroid += position_c; Scalar wedge_area = vcp.GetLength() * 0.5f; if (area <= SMALL) { if (wedge_area > SMALL) { area += wedge_area; centroid *= wedge_area; } center = centroid; } else { if (wedge_area > SMALL) { area += wedge_area; centroid *= wedge_area; center += centroid; } } plane.normal.x = 0.0f; plane.normal.y = 0.0f; plane.normal.z = 1.0f; plane.offset = 0.0f; if(area > SMALL) { plane.BuildPlane( v[0], v[2], v[1] ); center *= (One_Over_Three/area); } else { center *= One_Over_Three; } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // HFSlimMZ0p3::HFSlimMZ0p3() { X = (int)0.0f; Z = (int)0.0f; dX = 2.0f; dY = 0.15f; dZ = 2.0f; xOffset = 0.0f; zOffset = 0.0f; Offset = 0.0f; visHeight = 0; simpleTerrainGroup.SetLength(0); borderPixelFun = 0.0f; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // HFSlimMZ0p3::~HFSlimMZ0p3() { for(int i=0;i h) { ebox.minY = h; } } return ebox; } //--------------------------------------------------------------------------- void HFSlimMZ0p3::Blur2D (int smooth) { // Precondition for stability: 0 < scale < exp(0.25) // Good choice for iterative blurring is scale = exp(0.125) float scale = static_cast(exp(0.125)); float** temp = new float*[Z]; int x, y; for (y = 0; y < Z; y++) temp[y] = new float[X]; for(int i=0;i= X-1 ) // use boundary value xsum += field[y*X+X-1]; else // linearly interpolate xsum += field[y*X+xp]+(rxp-xp)*(field[y*X+xp+1]-field[y*X+xp]); if ( xm <= 0 ) // use boundary value xsum += field[y*X+0]; else // linearly interpolate xsum += field[y*X+xm]+(rxm-xm)*(field[y*X+xm]-field[y*X+xm-1]); // y portion of second central difference float ysum = -2*field[y*X+x]; if ( yp >= Z-1 ) // use boundary value ysum += field[(Z-1)*X+x]; else // linearly interpolate ysum += field[yp*X+x]+(ryp-yp)*(field[(yp+1)*X+x]-field[yp*X+x]); if ( ym <= 0 ) // use boundary value ysum += field[0*X+x]; else // linearly interpolate ysum += field[ym*X+x]+(rym-ym)*(field[ym*X+x]-field[(ym-1)*X+x]); temp[y][x] = field[y*X+x]+logscale*(xsum+ysum); } } for (y = 0; y < Z; y++) for (x = 0; x < X; x++) field[y*X+x] = temp[y][x]; } for (y = 0; y < Z; y++) delete[] temp[y]; delete[] temp; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void HFSlimMZ0p3::FillFromImage(Image &image, int smooth) { X = image.GetWidth()+1; Z = image.GetHeight()+1; Verify(((X-1)%256 == 0) && ((Z-1)%256 == 0)); xDim = image.GetWidth()/256; zDim = image.GetHeight()/256; Verify(image.GetBpp()==8); field.SetLength(X*Z); unsigned char *ptr; ptr=(unsigned char *)image.Lock(); int i, j; for(i=0;i& tdtrilist, ExtentBox *uvFrame ) { int polygon_count = tdtrilist.GetLength(); if(polygon_count==0 || polygon_count*3 >= Limits::Max_Number_Vertices_Per_Mesh) { return NULL; } DynamicArrayOf vert_id(X*Z); memset(vert_id.GetData(), 0, vert_id.GetSize()); int i, j, x, z, point_count = 0; int minX[2]={0,0}, maxX[2]={0,0}, minY[2]={0,0}, maxY[2]={0,0}, minZ[2]={0,0}, maxZ[2]={0,0}; Scalar minx=tdtrilist[0]->v[0].x, maxx=tdtrilist[0]->v[0].x, miny=tdtrilist[0]->v[0].y, maxy=tdtrilist[0]->v[0].y, minz=tdtrilist[0]->v[0].z, maxz=tdtrilist[0]->v[0].z; Point3D center0 = Point3D::Identity, center1 = Point3D::Identity, center2 = Point3D::Identity, center3 = Point3D::Identity; for(i=0;icenter; if(tdtrilist[i]->v[0].x < minx) { minX[0] = i; minX[1] = 0; minx = tdtrilist[i]->v[0].x; } else if(tdtrilist[i]->v[0].x > maxx) { maxX[0] = i; maxX[1] = 0; maxx = tdtrilist[i]->v[0].x; } if(tdtrilist[i]->v[0].y < miny) { minY[0] = i; minY[1] = 0; miny = tdtrilist[i]->v[0].y; } else if(tdtrilist[i]->v[0].y > maxy) { maxY[0] = i; maxY[1] = 0; maxy = tdtrilist[i]->v[0].y; } if(tdtrilist[i]->v[0].z < minz) { minZ[0] = i; minZ[1] = 0; minz = tdtrilist[i]->v[0].z; } else if(tdtrilist[i]->v[0].z > maxz) { maxZ[0] = i; maxZ[1] = 0; maxz = tdtrilist[i]->v[0].z; } x = (int)(tdtrilist[i]->v[0].x/dX); z = (int)(tdtrilist[i]->v[0].z/dZ); vert_id[x + X*z]++; if(vert_id[x + X*z]==1) { center0 += tdtrilist[i]->v[0]; point_count++; } if(tdtrilist[i]->v[2].x < minx) { minX[0] = i; minX[1] = 2; minx = tdtrilist[i]->v[2].x; } else if(tdtrilist[i]->v[2].x > maxx) { maxX[0] = i; maxX[1] = 2; maxx = tdtrilist[i]->v[2].x; } if(tdtrilist[i]->v[2].y < miny) { minY[0] = i; minY[1] = 2; miny = tdtrilist[i]->v[2].y; } else if(tdtrilist[i]->v[2].y > maxy) { maxY[0] = i; maxY[1] = 2; maxy = tdtrilist[i]->v[2].y; } if(tdtrilist[i]->v[2].z < minz) { minZ[0] = i; minZ[1] = 2; minz = tdtrilist[i]->v[2].z; } else if(tdtrilist[i]->v[2].z > maxz) { maxZ[0] = i; maxZ[1] = 2; maxz = tdtrilist[i]->v[2].z; } x = (int)(tdtrilist[i]->v[2].x/dX); z = (int)(tdtrilist[i]->v[2].z/dZ); vert_id[x + X*z]++; if(vert_id[x + X*z]==1) { center0 += tdtrilist[i]->v[1]; point_count++; } if(tdtrilist[i]->v[1].x < minx) { minX[0] = i; minX[1] = 0; minx = tdtrilist[i]->v[1].x; } else if(tdtrilist[i]->v[1].x > maxx) { maxX[0] = i; maxX[1] = 1; maxx = tdtrilist[i]->v[1].x; } if(tdtrilist[i]->v[1].y < miny) { minY[0] = i; minY[1] = 1; miny = tdtrilist[i]->v[1].y; } else if(tdtrilist[i]->v[1].y > maxy) { maxY[0] = i; maxY[1] = 1; maxy = tdtrilist[i]->v[1].y; } if(tdtrilist[i]->v[1].z < minz) { minZ[0] = i; minZ[1] = 1; minz = tdtrilist[i]->v[1].z; } else if(tdtrilist[i]->v[1].z > maxz) { maxZ[0] = i; maxZ[1] = 1; maxz = tdtrilist[i]->v[1].z; } x = (int)(tdtrilist[i]->v[1].x/dX); z = (int)(tdtrilist[i]->v[1].z/dZ); vert_id[x + X*z]++; if(vert_id[x + X*z]==1) { center0 += tdtrilist[i]->v[2]; point_count++; } } center0 *= 1.0f/point_count; center0.x = GetX(center0.x); center0.y += Offset; center0.z = GetZ(center0.z); center3 *= 1.0f/polygon_count; center3.x = GetX(center3.x); center3.y += Offset; center3.z = GetZ(center3.z); Vector3D v3; Scalar d[3]; v3.Subtract(tdtrilist[maxX[0]]->v[maxX[1]], tdtrilist[minX[0]]->v[minX[1]]); d[0] = v3.GetLengthSquared(); v3.Subtract(tdtrilist[maxY[0]]->v[maxY[1]], tdtrilist[minY[0]]->v[minY[1]]); d[1] = v3.GetLengthSquared(); v3.Subtract(tdtrilist[maxZ[0]]->v[maxZ[1]], tdtrilist[minZ[0]]->v[minZ[1]]); d[2] = v3.GetLengthSquared(); if(d[0] > d[1]) { if(d[0]>d[2]) { center1 = tdtrilist[maxX[0]]->v[maxX[1]]; center1 += tdtrilist[minX[0]]->v[minX[1]]; center1 *= 0.5f; } else { center1 = tdtrilist[maxZ[0]]->v[maxZ[1]]; center1 += tdtrilist[minZ[0]]->v[minZ[1]]; center1 *= 0.5f; } } else { if(d[1]>d[2]) { center1 = tdtrilist[maxY[0]]->v[maxY[1]]; center1 += tdtrilist[minY[0]]->v[minY[1]]; center1 *= 0.5f; } else { center1 = tdtrilist[maxZ[0]]->v[maxZ[1]]; center1 += tdtrilist[minZ[0]]->v[minZ[1]]; center1 *= 0.5f; } } center1.x = GetX(center1.x); center1.y += Offset; center1.z = GetZ(center1.z); center2.x = GetX((maxx+minx)*0.5f); center2.y = (maxy+miny)*0.5f; center2.z = GetZ((maxz+minz)*0.5f); center2.y += Offset; Point3D *coords = new Point3D [point_count]; Vector2DScalar *texCoords = new Vector2DScalar[point_count]; UnitVector3D sun; sun = Vector3D(-1.0f, -1.0f, 0.0f); int nrOfPoints = 0; Scalar radiusSquared, maxRadius0 = 0.0f, maxRadius1 = 0.0f, maxRadius2 = 0.0f, maxRadius3 = 0.0f; for(z=0;z 0 ) { Verify(nrOfPointsmaxX && GetX(x)>=uvFrame->minX); Verify(GetZ(z)<=uvFrame->maxZ && GetZ(z)>=uvFrame->minZ); coords[nrOfPoints].x = GetX(x); coords[nrOfPoints].y = GetHeight(x, z); coords[nrOfPoints].z = GetZ(z); v3.Subtract(coords[nrOfPoints], center0); radiusSquared = v3.GetLengthSquared(); maxRadius0 = radiusSquared>maxRadius0 ? radiusSquared:maxRadius0; v3.Subtract(coords[nrOfPoints], center1); radiusSquared = v3.GetLengthSquared(); maxRadius1 = radiusSquared>maxRadius1 ? radiusSquared:maxRadius1; v3.Subtract(coords[nrOfPoints], center2); radiusSquared = v3.GetLengthSquared(); maxRadius2 = radiusSquared>maxRadius2 ? radiusSquared:maxRadius2; v3.Subtract(coords[nrOfPoints], center3); radiusSquared = v3.GetLengthSquared(); maxRadius3 = radiusSquared>maxRadius3 ? radiusSquared:maxRadius3; #ifndef TERRAIN2_TEST texCoords[nrOfPoints][0] = borderPixelFun + (1.0f-2*borderPixelFun)*((uvFrame->maxX - coords[nrOfPoints].x)/(uvFrame->maxX-uvFrame->minX)); texCoords[nrOfPoints][1] = borderPixelFun + (1.0f-2*borderPixelFun)*((uvFrame->maxZ - coords[nrOfPoints].z)/(uvFrame->maxZ-uvFrame->minZ)); #endif nrOfPoints++; } else vert_id[z*X+x] = -1; } maxRadius0 = static_cast(sqrt(maxRadius0)); maxRadius1 = static_cast(sqrt(maxRadius1)); maxRadius2 = static_cast(sqrt(maxRadius2)); maxRadius3 = static_cast(sqrt(maxRadius3)); if(maxRadius0v[0].x/dX); z = (int)(tdtrilist[i]->v[0].z/dZ); j = x + X*z; Verify(vert_id[j]>=0); index[l++] = vert_id[j]; if(z==Z-1) k++; x = (int)(tdtrilist[i]->v[2].x/dX); z = (int)(tdtrilist[i]->v[2].z/dZ); j = x + X*z; Verify(vert_id[j]>=0); index[l++] = vert_id[j]; if(z==Z-1) k++; x = (int)(tdtrilist[i]->v[1].x/dX); z = (int)(tdtrilist[i]->v[1].z/dZ); j = x + X*z; Verify(vert_id[j]>=0); index[l++] = vert_id[j]; if(z==Z-1) k++; if(k>=2) { j = 0; } if( index[l-3]==index[l-2] || index[l-2]==index[l-1] || index[l-1]==index[l-3] ) { l-=3; continue; } Vector3D vCross; vCross.Cross( coords[index[l-1]], coords[index[l-2]], coords[index[l-3]] ); if(Small_Enough(vCross) || vCross.y<=SMALL) { l-=3; continue; } } gos_PushCurrentHeap(MidLevelRenderer::Heap); erf_mesh->SetSubprimitiveLengths(NULL, l/3); #ifdef _ARMOR for(i=0;i=erf_mesh->GetFrame(j, 0) && coords[i].x<=erf_mesh->GetFrame(j, 2) ); Verify(coords[i].z>=erf_mesh->GetFrame(j, 1) && coords[i].z<=erf_mesh->GetFrame(j, 3) ); } } #endif erf_mesh->SetCoordData(coords, nrOfPoints); #ifdef TERRAIN2_TEST erf_mesh->SetFrame(0, xOffset, zOffset, xOffset+8*xGridSize, zOffset+8*zGridSize); erf_mesh->SetCurrentDepth(0); #else erf_mesh->SetTexCoordData(texCoords, nrOfPoints); #endif erf_mesh->SetIndexData(index, l); gos_PopCurrentHeap(); erf_mesh->FindFacePlanes(); delete [] coords; delete [] texCoords; delete [] index; return true; } int primCounter, maxPrims; void HFSlimMZ0p3::OptimizeHField(int depth, int binSize) { if(X*Z == 0) { return; } fprintf(stdout, "Going to optimize the terrain: MaxNr.Of Points: %d BinSize: %d\n", depth, binSize); tdtrilist.SetLength((X-1)*(Z-1)); DirectMap map(X,Z); int i, j; float maxY = 0; for(j=0;jwidth=X; MASK->height=Z; GreedySubdivision mesh(&map); point_limit=1024; point_limit = depth; triangleCounter = 0; int count=1; while(mesh.pointCount() error_threshold) { mesh.greedyInsert(); } fprintf(stdout, "The mesh was greedy.\n"); mesh.overFaces(GetFacesCB, tdtrilist.GetData()); for(i=0;i(dY*mesh.eval( (int)(tdtrilist[i].v[0].x), (int)(tdtrilist[i].v[0].z) )); tdtrilist[i].v[1].y = Offset + static_cast(dY*mesh.eval( (int)(tdtrilist[i].v[1].x), (int)(tdtrilist[i].v[1].z) )); tdtrilist[i].v[2].y = Offset + static_cast(dY*mesh.eval( (int)(tdtrilist[i].v[2].x), (int)(tdtrilist[i].v[2].z) )); tdtrilist[i].v[0].x *= dX; tdtrilist[i].v[0].z *= dZ; tdtrilist[i].v[1].x *= dX; tdtrilist[i].v[1].z *= dZ; tdtrilist[i].v[2].x *= dX; tdtrilist[i].v[2].z *= dZ; tdtrilist[i].GetSurfaceAreaAndCentroid(); } OptPolyCount = triangleCounter; if(triangleCounter == 0 || mesh.pointCount() == 0) { return; } toSortTriangles.SetLength(triangleCounter); for(i=0,j=0;i Stuff::SMALL) ) { STOP(("Danger Danger !")); } /* if( !(tdtrilist[i].GetV0().x==0.0f && tdtrilist[i].GetV0().z==GetZinM()) && !(tdtrilist[i].GetV1().x==0.0f && tdtrilist[i].GetV1().z==GetZinM()) && !(tdtrilist[i].GetV2().x==0.0f && tdtrilist[i].GetV2().z==GetZinM()) ) */ { toSortTriangles[j++] = &tdtrilist[i]; } } toSortTriangles.SetLength(j); fprintf(stdout, "optimized to %d triangles.\n", j); } int brokenTriangles; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void AnalyzeThis( DynamicArrayOf &tempTrianglesPtr, Scalar x0, Scalar z0, Scalar x1, Scalar z1 ) { int i, j, k, l, len = tempTrianglesPtr.GetLength(); int divide = 2; Scalar x0n, z0n, x1n, z1n; fprintf(analyzeFile, "%d ", len); int in, out; for(i=0;iGetV0().x >= x0n && tempTrianglesPtr[k]->GetV0().x <= x1n && tempTrianglesPtr[k]->GetV0().z >= z0n && tempTrianglesPtr[k]->GetV0().z < z1n ) { l++; } if( tempTrianglesPtr[k]->GetV1().x >= x0n && tempTrianglesPtr[k]->GetV1().x <= x1n && tempTrianglesPtr[k]->GetV1().z >= z0n && tempTrianglesPtr[k]->GetV1().z <= z1n ) { l++; } if( tempTrianglesPtr[k]->GetV2().x >= x0n && tempTrianglesPtr[k]->GetV2().x <= x1n && tempTrianglesPtr[k]->GetV2().z >= z0n && tempTrianglesPtr[k]->GetV2().z <= z1n ) { l++; } if(l==3) { in++; } else if(l>0) { if( tempTrianglesPtr[k]->center.x >= x0n && tempTrianglesPtr[k]->center.x <= x1n && tempTrianglesPtr[k]->center.z >= z0n && tempTrianglesPtr[k]->center.z <= z1n ) { out++; } } } fprintf(analyzeFile, "%d %d ", in, out); } } fprintf(analyzeFile, "\n"); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // bool HFSlimMZ0p3::BuildTile( MLR_Terrain2 *erf_mesh, DynamicArrayOf& onOffPoints, int maxNumOfTrianglesPerMesh, Scalar x0, Scalar z0, Scalar x1, Scalar z1 ) { int numOfTriangles = toSortTriangles.GetLength(); DynamicArrayOf tempTrianglesPtr(numOfTriangles); DynamicArrayOf tempTriangles(numOfTriangles); int i, j, inCount, newCount = 0, extraTriangles = 0; int k, l, m; for(i=0,j=0;iGetV0().x < x0) { clipIt[0] |= 1; } if(toSortTriangles[i]->GetV0().x > x1) { clipIt[0] |= 4; } if(toSortTriangles[i]->GetV0().z < z0) { clipIt[0] |= 8; } if(toSortTriangles[i]->GetV0().z > z1) { clipIt[0] |= 2; } orIt |= clipIt[0]; addIt &= clipIt[0]; if(toSortTriangles[i]->GetV1().x < x0) { clipIt[1] |= 1; } if(toSortTriangles[i]->GetV1().x > x1) { clipIt[1] |= 4; } if(toSortTriangles[i]->GetV1().z < z0) { clipIt[1] |= 8; } if(toSortTriangles[i]->GetV1().z > z1) { clipIt[1] |= 2; } orIt |= clipIt[1]; addIt &= clipIt[1]; if(toSortTriangles[i]->GetV2().x < x0) { clipIt[2] |= 1; } if(toSortTriangles[i]->GetV2().x > x1) { clipIt[2] |= 4; } if(toSortTriangles[i]->GetV2().z < z0) { clipIt[2] |= 8; } if(toSortTriangles[i]->GetV2().z > z1) { clipIt[2] |= 2; } orIt |= clipIt[2]; addIt &= clipIt[2]; if(orIt == 0) { onOffPoints[i] = 1; if(toSortTriangles[i]->area > SMALL) { if(! (toSortTriangles[i]->plane.normal.y > Stuff::SMALL) ) { STOP(("Danger Danger !")); } tempTrianglesPtr[newCount++] = toSortTriangles[i]; } } else if(addIt==0) { if(orIt==1 || orIt==2 || orIt==4 || orIt==8) { Point3D triangle[3], clipPoints[6]; triangle[0].x = toSortTriangles[i]->GetV0().x; triangle[0].y = toSortTriangles[i]->GetV0().y; triangle[0].z = toSortTriangles[i]->GetV0().z; triangle[1].x = toSortTriangles[i]->GetV1().x; triangle[1].y = toSortTriangles[i]->GetV1().y; triangle[1].z = toSortTriangles[i]->GetV1().z; triangle[2].x = toSortTriangles[i]->GetV2().x; triangle[2].y = toSortTriangles[i]->GetV2().y; triangle[2].z = toSortTriangles[i]->GetV2().z; l = 0; for(k=0;k<3;k++) { int next = k+1>2?0:k+1; if(clipIt[k]==0) { clipPoints[l++] = triangle[k]; if(clipIt[next]==0) { continue; } } else { if(clipIt[next]!=0) { continue; } } // //----------------------------------------------------- // Find the boundary conditions that match our clipping // plane //----------------------------------------------------- // int mask = 1; for (m=0; m<4; m++) { if((clipIt[k] | clipIt[next]) & mask) { switch(m) { case 0: clipPoints[l].AddScaled( triangle[k], Vector3D( triangle[next].x - triangle[k].x, triangle[next].y - triangle[k].y, triangle[next].z - triangle[k].z ), (x0-triangle[k].x)/(triangle[next].x-triangle[k].x) ); clipPoints[l++].x = x0; break; case 1: clipPoints[l].AddScaled( triangle[k], Vector3D( triangle[next].x - triangle[k].x, triangle[next].y - triangle[k].y, triangle[next].z - triangle[k].z ), (z1-triangle[k].z)/(triangle[next].z-triangle[k].z) ); clipPoints[l++].z = z1; break; case 2: clipPoints[l].AddScaled( triangle[k], Vector3D( triangle[next].x - triangle[k].x, triangle[next].y - triangle[k].y, triangle[next].z - triangle[k].z ), (x1-triangle[k].x)/(triangle[next].x-triangle[k].x) ); clipPoints[l++].x = x1; break; case 3: clipPoints[l].AddScaled( triangle[k], Vector3D( triangle[next].x - triangle[k].x, triangle[next].y - triangle[k].y, triangle[next].z - triangle[k].z ), (z0-triangle[k].z)/(triangle[next].z-triangle[k].z) ); clipPoints[l++].z = z0; break; } break; } mask <<= 1; } } Verify(l>2); for(m=1;m SMALL) { if(! (tempTriangles[extraTriangles].plane.normal.y > Stuff::SMALL) ) { STOP(("Danger Danger !")); } tempTrianglesPtr[newCount++] = &tempTriangles[extraTriangles]; extraTriangles++; } } } else { int key=0, len[2] = {0, 0}; Point3D clipPoints[2][6]; int clipMeToo[2][6]; clipPoints[key][0].x = toSortTriangles[i]->GetV0().x; clipPoints[key][0].y = toSortTriangles[i]->GetV0().y; clipPoints[key][0].z = toSortTriangles[i]->GetV0().z; clipPoints[key][1].x = toSortTriangles[i]->GetV1().x; clipPoints[key][1].y = toSortTriangles[i]->GetV1().y; clipPoints[key][1].z = toSortTriangles[i]->GetV1().z; clipPoints[key][2].x = toSortTriangles[i]->GetV2().x; clipPoints[key][2].y = toSortTriangles[i]->GetV2().y; clipPoints[key][2].z = toSortTriangles[i]->GetV2().z; clipMeToo[key][0] = clipIt[0]; clipMeToo[key][1] = clipIt[1]; clipMeToo[key][2] = clipIt[2]; len[key] = 3; int next, mask = 1; for(m=0;m<4;++m) { if(orIt & mask) { for(k=0;k x1) { clipMeToo[key][k] |= 4; } if(clipPoints[key][k].z < z0) { clipMeToo[key][k] |= 8; } if(clipPoints[key][k].z > z1) { clipMeToo[key][k] |= 2; } } len[!key] = 0; } mask <<= 1; } for(m=1;m SMALL) { if(! (tempTriangles[extraTriangles].plane.normal.y > Stuff::SMALL) ) { STOP(("Danger Danger !")); } tempTrianglesPtr[newCount++] = &tempTriangles[extraTriangles]; extraTriangles++; } } } } } } // tempTriangles.SetLength(extraTriangles); tempTrianglesPtr.SetLength(newCount); #if _ARMOR for(i=0,j=0;iGetV0().x >= x0); Verify(tempTrianglesPtr[i]->GetV0().x <= x1); Verify(tempTrianglesPtr[i]->GetV0().z >= z0); Verify(tempTrianglesPtr[i]->GetV0().z <= z1); Verify(tempTrianglesPtr[i]->GetV1().x >= x0); Verify(tempTrianglesPtr[i]->GetV1().x <= x1); Verify(tempTrianglesPtr[i]->GetV1().z >= z0); Verify(tempTrianglesPtr[i]->GetV1().z <= z1); Verify(tempTrianglesPtr[i]->GetV2().x >= x0); Verify(tempTrianglesPtr[i]->GetV2().x <= x1); Verify(tempTrianglesPtr[i]->GetV2().z >= z0); Verify(tempTrianglesPtr[i]->GetV2().z <= z1); } } #endif MLR_Terrain2 *ret_mesh = NULL; if(newCount > 0) { AnalyzeThis( tempTrianglesPtr, x0, z0, x1, z1 ); Stuff::ExtentBox box; box.minX = x0; box.maxX = x1; box.minY = Offset; box.maxY = Offset+256.0f; box.minZ = z0; box.maxZ = z1; if(!CreateMesh(erf_mesh, tempTrianglesPtr, &box)) { PAUSE(("Unstable triangle mesh created!")); } else { brokenTriangles += newCount; } } else { STOP(("Danger Danger !")); } tempTrianglesPtr.SetLength(0); return true; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // bool HFSlimMZ0p3::SetMegaTexture( int nrOfLevels, int bucketSize, const char *theName ) { static char megaBaseName[1024]; if(detailInfo.name) { /* state1.SetBackFaceOn(); state1.SetDitherOff(); state1.SetTextureCorrectionOn(); state1.SetZBufferCompareOn(); state1.SetZBufferWriteOff(); state1.SetFilterMode(MLRState::BiLinearFilterMode); state1.SetFogMode(MLRState::DisableFogMode); state1.SetFogData( 0xff000000, 0.0f, 90.0f, 100.0f ); */ state1.SetTextureWrapMode(MLRState::TextureWrap); state1.SetAlphaMode(detailInfo.alphaMode); state1.SetPriority(MLRState::AlphaPriority); MLRTexture *texture = MLRTexturePool::Instance->Add(detailInfo.name); state1.SetTextureHandle(texture->GetTextureHandle()); } DynamicArrayOf onOffTriangles; onOffTriangles.AssignValue(0, toSortTriangles.GetLength()); int i, j, k, l, m, n; simpleTerrainGroup.SetLength(xDim*zDim); Stuff::ExtentBox allBox; allBox = GetExtents(); int len = 1<SetName("OptimizedTerrain"); gos_PopCurrentHeap(); for(j=0;jAttachIndexedChild(j, i, group); group->NeedNewBounds(); group->SetVolumeCullMode(); ElementRenderer::ListElement *subList = new ListElement; Register_Object(subList); subList->SetSize(4); group->AttachChild(subList); subList->NeedNewBounds(); subList->SetVolumeCullMode(); gos_PopCurrentHeap(); for(n=0;n<2;n++) { for(m=0;m<2;m++) { MLRState state; /* state.SetBackFaceOn(); state.SetDitherOff(); state.SetTextureCorrectionOn(); state.SetZBufferCompareOn(); state.SetZBufferWriteOn(); state.SetFilterMode(MLRState::BiLinearFilterMode); state.SetFogMode(MLRState::OverrideFogMode); state.SetFogData( 0xff9090f0, 0.0f, 700.0f, 1000.0f ); */ char textureName[1024]; state.SetPriority(MLRState::DefaultPriority); #if 0 sprintf(textureName, "%s_%1d_%02x%02x", megaBaseName, depth, (1<Add(textureName); texture->SetHint(gosHint_AGPMemory | gosHint_DontShrink); state.SetTextureHandle(texture->GetTextureHandle()); state.SetTextureWrapMode(MLRState::TextureClamp); gos_PushCurrentHeap(MidLevelRenderer::Heap); MLR_Terrain2 *erf_mesh = new MLR_Terrain2; gos_PopCurrentHeap(); erf_mesh->SetReferenceState(state); erf_mesh->SetReferenceState(state1, 1); erf_mesh->SetLevelTexture(0, texture->GetTextureHandle()); Scalar x0, z0, x1, z1; if(iSetFrame(1, x0, z0, x1, z1); x0 = xOffset + i*xGridSize; z0 = zOffset + j*zGridSize; x1 = x0 + xGridSize; z1 = z0 + zGridSize; erf_mesh->SetFrame(0, xOffset, zOffset, xOffset+len*xGridSize, zOffset+len*zGridSize); erf_mesh->SetFrame(2, x0, z0, x1, z1); erf_mesh->SetFrame(3, x0, z0, x1, z1); erf_mesh->SetFrame(4, x0, z0, x1, z1); erf_mesh->SetFrame(5, x0, z0, x1, z1); erf_mesh->SetFrame(6, x0, z0, x1, z1); erf_mesh->SetFrame(7, x0, z0, x1, z1); erf_mesh->SetDepthData(maxAllDepth, maxAllDepth); erf_mesh->SetTileData(tX, tY); erf_mesh->SetBorderPixel(borderPixelFun); Register_Object(erf_mesh); erf_mesh->SetDetailData( detailInfo.xOff, detailInfo.zOff, detailInfo.xFac, detailInfo.zFac, detailInfo.dStart, detailInfo.dEnd ); x0 = xOffset + i*xGridSize + m*xGridSize/2.0f; z0 = zOffset + j*zGridSize + n*xGridSize/2.0f; x1 = x0 + xGridSize/2.0f; z1 = z0 + zGridSize/2.0f; BuildTile(erf_mesh, onOffTriangles, bucketSize, x0, z0, x1, z1); gos_PushCurrentHeap(ElementRenderer::Heap); ShapeElement* Shape = new ShapeElement; Register_Object(Shape); gos_PopCurrentHeap(); gos_PushCurrentHeap(MidLevelRenderer::Heap); MLRShape *shape = new MLRShape(1); Register_Object(shape); gos_PopCurrentHeap(); shape->Add(erf_mesh); erf_mesh->DetachReference(); Shape->SetMLRShape(shape); Shape->m_localOBB.localToParent = LinearMatrix4D::Identity; Shape->m_localOBB.localToParent.BuildTranslation(center); Shape->m_localOBB.sphereRadius = maxRadius; subList->AttachIndexedChild(2*n+m, Shape); Shape->SetVolumeCullMode(); } } group->Sync(); group->LockBounds(); group->SetNeverCullMode(); subList->LockBounds(); subList->SetNeverCullMode(); } } simpleTerrainGroup[l*xDim+k]->LockBounds(); fprintf(stdout, "\"broken\" triangles: %d\n", brokenTriangles); } } return true; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Scalar HFSlimMZ0p3::GetHeight(int x, int z) { if (x<0) x = 0; if (x>GetX()-1) { x = GetX() - 1; } if (z<0) z = 0; if (z>GetZ()-1) { z = GetZ() - 1; } return field[z*X + x]*dY + Offset; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void ToDrawTriangle::SetPoint(int idx,float x,float y,float z) { Verify(idx>=0 && idx<3); v[idx].x=x; v[idx].y=y; v[idx].z=z; }