nfBool CMeshInformation_BaseMaterials::faceHasData(_In_ nfUint32 nFaceIndex)
	{
		MESHINFORMATION_BASEMATERIAL * pFaceData = (MESHINFORMATION_BASEMATERIAL*)getFaceData(nFaceIndex);
		if (pFaceData)
			return (pFaceData->m_nMaterialGroupID != 0);

		return false;
	}
	void CMeshInformation_BaseMaterials::cloneFaceInfosFrom(_In_ nfUint32 nFaceIndex, _In_ CMeshInformation * pOtherInformation, _In_ nfUint32 nOtherFaceIndex)
	{
		__NMRASSERT(pOtherInformation);

		MESHINFORMATION_BASEMATERIAL * pTargetFaceData = (MESHINFORMATION_BASEMATERIAL*)getFaceData(nFaceIndex);
		MESHINFORMATION_BASEMATERIAL * pSourceFaceData = (MESHINFORMATION_BASEMATERIAL*)pOtherInformation->getFaceData(nOtherFaceIndex);
		if (pTargetFaceData && pSourceFaceData) {
			pTargetFaceData->m_nMaterialGroupID = pSourceFaceData->m_nMaterialGroupID;
			pTargetFaceData->m_nMaterialIndex = pSourceFaceData->m_nMaterialIndex;
		}
	}
Example #3
0
int renderChunkWithMeshing(Chunk *chunk, GLfloat *points, GLfloat *normals, GLfloat *colors, vec3 offset, float scale) {
    float blockWidth = scale * BLOCK_WIDTH;

    Color *face[CHUNK_SIZE][CHUNK_SIZE];
    unsigned int axis1, axis2, axis3, w, h, i, j, k, points_index, pos[3], dir[3];
    int sign, empty, models;
    Block *voxel1, *voxel2;
    vec3 d_axis2, d_axis3, fpos;

    //Color covered; // placeholder value for covered faces

    vec3 color;
    GLuint indices[] = {0, 1, 2, 0, 2, 3, 0, 3, 2, 0, 2, 1};
    GLfloat verts[12];

    /*
        axis1 is our "working" axis. We look at both sides of each "slice" of the chunk
        along that axis, and determine whether each face is visible by checking
        the block in front of it. For each face that is visible, its color is
        added to the face array. Then we look at the face array and split it up
        into rectangles of the same color using a greedy algorithm. We draw each
        rectangle and then move on to the next axis.


        // ***** this is currently removed *****
        I also implemented (my own idea!) a system where if a block is covered,
        a placeholder value is inserted in the face array instead. Then, when
        calculating the rectangles, the placeholder value is treated as a solid
        block, except for the fact that a rectangle cannot start on a face with
        the placeholder value. This still prevents faces that are completely
        hidden from being drawn, but allows for rectangles to be combined under
        blocks that are hiding different colors. This should result in a strictly
        smaller number of rectangles being drawn, at near-zero cost :D
        The only drawback is that large rectangles that are mostly hidden may
        still be drawn. Everything will still look fine, but there is a little
        extra cost from drawing the overlapping triangles. My hope is that
        overall the scene will render even faster.
    */

    memset(face, 0, sizeof(face));

    points_index = 0;
    models = 0;

    for (axis1 = 0; axis1 < 3; axis1++) {
        axis2 = (axis1 + 1) % 3;
        axis3 = (axis1 + 2) % 3;

        dir[0] = dir[1] = dir[2] = 0;
        d_axis2[0] = d_axis2[1] = d_axis2[2] = 0;
        d_axis3[0] = d_axis3[1] = d_axis3[2] = 0;

        for (sign = -1; sign < 2; sign += 2) {
            dir[axis1] = sign;

            for (pos[axis1] = 0; pos[axis1] < CHUNK_SIZE; pos[axis1]++) {
                empty = 1;

                // generate the face array
                for (pos[axis2] = 0; pos[axis2] < CHUNK_SIZE; pos[axis2]++) {
                    for (pos[axis3] = 0; pos[axis3] < CHUNK_SIZE; pos[axis3]++) {
                        voxel1 = getBlock(chunk, pos[0], pos[1], pos[2]);
                        voxel2 = ((sign > 0) ? (pos[axis1] < CHUNK_SIZE - 1) : (pos[axis1] > 0)) ?
                                 getBlock(chunk, pos[0]+dir[0], pos[1]+dir[1], pos[2]+dir[2]) :
                                 NULL;

                        if (voxel1->active) {

                            // there's a block that is potentially drawable
                            empty = 0;

                            if (voxel1->data)
                                // there's a model in the chunk. These have to be
                                // handled separately, so we mark a boolean flag
                                // so that we know to go back and render them
                                models = 1;
                            else if (!voxel2 || !voxel2->active || voxel2->data)
                                face[pos[axis3]][pos[axis2]] = &voxel1->color;
                        }
                    }
                }

                // nothing to do here. Continue on.
                if (empty)
                    continue;

                /*puts("---------------");
                printf("____%c%c AXIS____\n", sign > 0 ? '+' : '-', (char[]){'X','Y','Z'}[axis1]);
                printf("___SLICE #%02d___\n", pos[axis1]);
                for (i = 0; i < CHUNK_SIZE; i++) {
                    for (j = 0; j < CHUNK_SIZE; j++) {
                        printf("%c ", face[j][i] ? '#' : ' ');
                    }
                    puts("");
                }
                puts("---------------\n");*/

                // cut the face up into rectangles and draw them
                for (j = 0; j < CHUNK_SIZE; j++) {
                    for (i = 0; i < CHUNK_SIZE;) {
                        w = 1;

                        if (face[j][i]) {

                            // get the width
                            while (
                                (i + w < CHUNK_SIZE) &&
                                (face[j][i + w]) &&
                                (face[j][i + w]->all == face[j][i]->all)
                            ) w++;

                            // get the height
                            for (h = 1; j + h < CHUNK_SIZE; h++) {

                                // we look at the next row, and make sure each
                                // block on the face is solid and the same color.
                                // if it's not, we break from the outer loop
                                for (k = 0; k < w; k++) {
                                    if ((face[j + h][i + k] == NULL) ||
                                        (face[j + h][i + k]->all != face[j][i]->all)
                                    ) goto done;
                                }
                            }
                            done:

                            // draw it

                            color[0] = (float)face[j][i]->r / 255.0;
                            color[1] = (float)face[j][i]->g / 255.0;
                            color[2] = (float)face[j][i]->b / 255.0;

                            fpos[axis1] = pos[axis1] * blockWidth + offset[axis1];
                            fpos[axis2] = i * blockWidth + offset[axis2];
                            fpos[axis3] = j * blockWidth + offset[axis3];

                            d_axis2[axis2] = w * blockWidth;
                            d_axis3[axis3] = h * blockWidth;

                            if (sign > 0) fpos[axis1] += blockWidth;

                            verts[ 0] = fpos[0];
                            verts[ 1] = fpos[1];
                            verts[ 2] = fpos[2];
                            verts[ 3] = fpos[0] + d_axis2[0];
                            verts[ 4] = fpos[1] + d_axis2[1];
                            verts[ 5] = fpos[2] + d_axis2[2];
                            verts[ 6] = fpos[0] + d_axis2[0] + d_axis3[0];
                            verts[ 7] = fpos[1] + d_axis2[1] + d_axis3[1];
                            verts[ 8] = fpos[2] + d_axis2[2] + d_axis3[2];
                            verts[ 9] = fpos[0] + d_axis3[0];
                            verts[10] = fpos[1] + d_axis3[1];
                            verts[11] = fpos[2] + d_axis3[2];

                            getFaceData(&points[points_index], verts, &indices[((sign < 0) ? 6 : 0)]);
                            getFaceData(&normals[points_index], &cubeNormals[(sign > 0) ? 5-axis1 : 2-axis1], zeroIndices);
                            getFaceData(&colors[points_index], color, zeroIndices);

                            points_index += 18;

                            // empty the face array wherever we rendered it
                            for(k = 0; k < h; k++) {
                                memset(&face[j + k][i], 0, w * sizeof(Color*));
                            }
                        }

                        i += w;
                    }
                }
            }
        }
    }

    if (models) {

        // there were models in the chunk. Render them
        for (pos[0] = 0; pos[0] < CHUNK_SIZE; pos[0]++) {
            for (pos[1] = 0; pos[1] < CHUNK_SIZE; pos[1]++) {
                for (pos[2] = 0; pos[2] < CHUNK_SIZE; pos[2]++) {
                    voxel1 = getBlock(chunk, pos[0], pos[1], pos[2]);

                    if (voxel1->active && voxel1->data) {
                        if (voxel1->data->chunk->needsUpdate) {
                            renderModel(voxel1->data);
                            voxel1->data->chunk->needsUpdate = 0;
                        }

                        if (voxel1->logic)
                            points_index += addRenderedModel(
                                    voxel1->data, &points[points_index], &normals[points_index], &colors[points_index], *voxel1->logic->rotationMatrix,
                                    (vec3){pos[0]*blockWidth + offset[0], pos[1]*blockWidth + offset[1], pos[2]*blockWidth + offset[2]},
                                    scale / CHUNK_SIZE
                                );
                        else
                            points_index += addRenderedModel(
                                    voxel1->data, &points[points_index], &normals[points_index], &colors[points_index], identityMatrix,
                                    (vec3){pos[0]*blockWidth + offset[0], pos[1]*blockWidth + offset[1], pos[2]*blockWidth + offset[2]},
                                    scale / CHUNK_SIZE
                                );
                    }
                }
            }
        }
    }

    return points_index;
}
Example #4
0
// returns the number of elements added to the arrays
int renderChunkToArrays(Chunk *chunk, GLfloat *points, GLfloat *normals, GLfloat *colors, vec3 offset, float scale) {
    float blockWidth = BLOCK_WIDTH * scale;

    Block *block;
    vec3 color;
    int x, y, z;
    float min_x, min_y, min_z, max_x, max_y, max_z;

    GLfloat cube_vertices[8 * 3];
    GLuint zeroIndices[] = {0, 0, 0, 0, 0, 0};

    int points_index = 0;

    for (x = 0; x < CHUNK_SIZE; x++) {
        min_x = x * blockWidth + offset[0];
        max_x = min_x + blockWidth;

        for (y = 0; y < CHUNK_SIZE; y++) {
            min_y = y * blockWidth + offset[1];
            max_y = min_y + blockWidth;

            for (z = 0; z < CHUNK_SIZE; z++) {
                min_z = z * blockWidth + offset[2];
                max_z = min_z + blockWidth;

                block = getBlock(chunk, x, y, z);

                if (!block->active) {
                    continue;
                }

                if (block->data) {
                    if (block->data->chunk->needsUpdate) {
                        renderModel(block->data);
                        block->data->chunk->needsUpdate = 0;
                    }

                    if (block->logic)
                        points_index += addRenderedModel(
                            block->data,
                            &points[points_index],
                            &normals[points_index],
                            &colors[points_index],
                            *block->logic->rotationMatrix,
                            (vec3){min_x, min_y, min_z},
                            scale / CHUNK_SIZE
                        );
                    else
                        points_index += addRenderedModel(
                            block->data,
                            &points[points_index],
                            &normals[points_index],
                            &colors[points_index],
                            identityMatrix,
                            (vec3){min_x, min_y, min_z},
                            scale / CHUNK_SIZE
                        );
                    continue;
                }

                cube_vertices[ 0] = min_x; cube_vertices[ 1] = min_y; cube_vertices[ 2] = min_z;
                cube_vertices[ 3] = min_x; cube_vertices[ 4] = min_y; cube_vertices[ 5] = max_z;
                cube_vertices[ 6] = min_x; cube_vertices[ 7] = max_y; cube_vertices[ 8] = min_z;
                cube_vertices[ 9] = min_x; cube_vertices[10] = max_y; cube_vertices[11] = max_z;
                cube_vertices[12] = max_x; cube_vertices[13] = min_y; cube_vertices[14] = min_z;
                cube_vertices[15] = max_x; cube_vertices[16] = min_y; cube_vertices[17] = max_z;
                cube_vertices[18] = max_x; cube_vertices[19] = max_y; cube_vertices[20] = min_z;
                cube_vertices[21] = max_x; cube_vertices[22] = max_y; cube_vertices[23] = max_z;

                color[0] = (float)block->color.r / 255.0;
                color[1] = (float)block->color.g / 255.0;
                color[2] = (float)block->color.b / 255.0;

                // check if each face is visible
                if (x == CHUNK_SIZE - 1 || !getBlock(chunk, x+1, y, z)->active || getBlock(chunk, x+1, y, z)->data) {
                    getFaceData(&points[points_index],     cube_vertices,      &cubeIndices[ 0]);
                    getFaceData(&normals[points_index],    &cubeNormals[5],    zeroIndices);
                    getFaceData(&colors[points_index],     color,              zeroIndices);
                    points_index += 6 * 3;
                }

                if (y == CHUNK_SIZE - 1 || !getBlock(chunk, x, y+1, z)->active || getBlock(chunk, x, y+1, z)->data) {
                    getFaceData(&points[points_index],     cube_vertices,      &cubeIndices[ 6]);
                    getFaceData(&normals[points_index],    &cubeNormals[4],    zeroIndices);
                    getFaceData(&colors[points_index],     color,              zeroIndices);
                    points_index += 6 * 3;
                }

                if (z == CHUNK_SIZE - 1 || !getBlock(chunk, x, y, z+1)->active || getBlock(chunk, x, y, z+1)->data) {
                    getFaceData(&points[points_index],     cube_vertices,      &cubeIndices[12]);
                    getFaceData(&normals[points_index],    &cubeNormals[3],    zeroIndices);
                    getFaceData(&colors[points_index],     color,              zeroIndices);
                    points_index += 6 * 3;
                }

                if (x == 0 || !getBlock(chunk, x-1, y, z)->active || getBlock(chunk, x-1, y, z)->data) {
                    getFaceData(&points[points_index],     cube_vertices,      &cubeIndices[18]);
                    getFaceData(&normals[points_index],    &cubeNormals[2],    zeroIndices);
                    getFaceData(&colors[points_index],     color,              zeroIndices);
                    points_index += 6 * 3;
                }

                if (y == 0 || !getBlock(chunk, x, y-1, z)->active || getBlock(chunk, x, y-1, z)->data) {
                    getFaceData(&points[points_index],     cube_vertices,      &cubeIndices[24]);
                    getFaceData(&normals[points_index],    &cubeNormals[1],    zeroIndices);
                    getFaceData(&colors[points_index],     color,              zeroIndices);
                    points_index += 6 * 3;
                }

                if (z == 0 || !getBlock(chunk, x, y, z-1)->active || getBlock(chunk, x, y, z-1)->data) {
                    getFaceData(&points[points_index],     cube_vertices,      &cubeIndices[30]);
                    getFaceData(&normals[points_index],    &cubeNormals[0],    zeroIndices);
                    getFaceData(&colors[points_index],     color,              zeroIndices);
                    points_index += 6 * 3;
                }
            }
        }
    }

    return points_index;
}
 const std::vector<double>& SimulationDataContainer::faceflux() const {
     return getFaceData("FACEFLUX");
 }
 const std::vector<double>& SimulationDataContainer::facepressure() const {
     return getFaceData("FACEPRESSURE");
 }
Example #7
0
   bool ShockBaseClass::getLocalSurfaces(Real t,std::vector<LocalSurface>& localSurfaces,uint32_t& N_shockCells,int refinements) {
      // Create shock mesh:
      if (initializeMesh(t,refinements) == false) {
	 simClasses->logger << "(SEP SHOCK BASE) ERROR: Failed to create shock mesh" << endl << write;
	 return false;
      }

      uint64_t N_surfaces = 0;
      const vector<Real>& faceData = getFaceData(N_surfaces);
      const vector<Real>& nodeCoordinates = getNodeCoordinates();
      const vector<uint32_t>& cellConnectivity = getCellConnectivity();
      N_shockCells = N_surfaces;
      
      // Iterate over all shock surface elements. If the element is on a cell hosted on 
      // this process (determined by cell centroid), inject particles to it:
      size_t connIndex = 0;
      for (size_t s=0; s<N_surfaces; ++s) {
	 const size_t areaIndex = s * ucdmesh::facedataelement::SIZE;
	 const size_t connSize = cellConnectivity[connIndex+1]+2;
	 
	 const size_t node1 = cellConnectivity[connIndex+2];
	 const size_t node2 = cellConnectivity[connIndex+3];
	 const size_t node3 = cellConnectivity[connIndex+4];
	 
	 Real centroid[3];
	 centroid[0] = (nodeCoordinates[3*node1+0] + nodeCoordinates[3*node2+0] + nodeCoordinates[3*node3+0])/3;
	 centroid[1] = (nodeCoordinates[3*node1+1] + nodeCoordinates[3*node2+1] + nodeCoordinates[3*node3+1])/3;
	 centroid[2] = (nodeCoordinates[3*node1+2] + nodeCoordinates[3*node2+2] + nodeCoordinates[3*node3+2])/3;
	 
	 Real normal[3];
	 normal[0] = faceData[areaIndex + ucdmesh::facedataelement::NORMAL_X];
	 normal[1] = faceData[areaIndex + ucdmesh::facedataelement::NORMAL_Y];
	 normal[2] = faceData[areaIndex + ucdmesh::facedataelement::NORMAL_Z];
	 
	 // Convert centroid position to logical coordinates and check that it 
	 // is inside simulation domain (coords are not inf):
	 Real logical[3];
	 Real xy,r,theta,phi;
	 Real spherCentroid[3];
	 switch (simControl.coordinateSystem) {
	  case sep::UNKNOWN:
	    finalizeMesh();
	    return false;
	    break;
	  case sep::CARTESIAN:
	    getLogicalCoordinates(sim,centroid,logical);
	    if (logical[0] == numeric_limits<Real>::infinity()) {
	       connIndex += connSize;
	       continue;
	    }
	    break;
	  case sep::CYLINDRICAL:
	    finalizeMesh();
	    return false;
	    break;
	  case sep::SPHERICAL:
	    // Need to convert to spherical coordinates first:
	    xy = centroid[0]*centroid[0] + centroid[1]*centroid[1];
	    r = xy + centroid[2]*centroid[2];
	    r = sqrt(r);
	    xy = sqrt(xy);
	    
	    theta = acos(centroid[2]/r);
	    phi = acos(centroid[0] / xy);
	    if (centroid[1] < 0.0) phi = -phi;
	    
	    spherCentroid[0] = r;
	    spherCentroid[1] = theta;
	    spherCentroid[2] = phi;
	    
	    // Check logical coords:
	    getLogicalCoordinates(sim,spherCentroid,logical);
	    if (logical[0] == std::numeric_limits<Real>::infinity()) {
	       connIndex += connSize;
	       continue;
	    }
	    break;
	  default:
	    finalizeMesh();
	    return false;
	    break;
	 }
	 
	 // Check that injection position is in upstream side:
	 Real d_shock = getSquaredDistanceToShock(t,logical);
	 bool acceptSurface = true;
	 while (d_shock <= 1.0) {
	    // Move injection point to the direction of shock normal:
      	    for (int i=0; i<3; ++i) centroid[i] += (0.1+1.001*fabs(d_shock))*normal[i];

	    switch (simControl.coordinateSystem) {
	     case sep::UNKNOWN:
	       finalizeMesh();
	       return false;
	       break;
	     case sep::CARTESIAN:
	       getLogicalCoordinates(sim,centroid,logical);
	       if (logical[0] == std::numeric_limits<Real>::infinity()) {
		  acceptSurface = false;
	       }
	       break;
	     case sep::CYLINDRICAL:
	       finalizeMesh();
	       return false;
	       break;
	     case sep::SPHERICAL:
	       xy = centroid[0]*centroid[0] + centroid[1]*centroid[1];
	       r = sqrt(xy + centroid[2]*centroid[2]);
	       xy = sqrt(xy);
	       theta = acos(centroid[2]/r);
	       phi = acos(centroid[0] / xy);
	       if (centroid[1] < 0.0) phi = -phi;
	       
	       spherCentroid[0] = r;
	       spherCentroid[1] = theta;
	       spherCentroid[2] = phi;
	       
	       getLogicalCoordinates(sim,spherCentroid,logical);
	       if (logical[0] == numeric_limits<Real>::infinity()) acceptSurface = false;
	       break;
	     default:
	       finalizeMesh();
	       return false;
	       break;
	    }
	    
	    if (acceptSurface == false) break;
	    d_shock = simControl.shock->getSquaredDistanceToShock(t,logical);
	 }

	 if (acceptSurface == false) {
	    connIndex += connSize;
	    continue;
	 }
	 
	 // Calculate cell indices:
	 int32_t i_block = static_cast<int32_t>(logical[0]) / block::WIDTH_X;
	 int32_t j_block = static_cast<int32_t>(logical[1]) / block::WIDTH_Y;
	 int32_t k_block = static_cast<int32_t>(logical[2]) / block::WIDTH_Z;
	               
	 // Calculate block global index and check if this process has it:
	 pargrid::CellID blockGID = block::calculateGlobalIndex(*sim,i_block,j_block,k_block);
	 pargrid::CellID blockLID = simClasses->pargrid.getLocalID(blockGID);
	 if (blockLID == pargrid::INVALID_CELLID) {
	    connIndex += connSize;
	    continue;
	 }
	 if (simClasses->pargrid.getHosts()[blockLID] != sim->mpiRank) {
	    connIndex += connSize;
	    continue;
	 }

	 // Surface accepted, add to output vector:
	 LocalSurface surface;
	 surface.localID = blockLID;
	 surface.globalID = blockGID;
	 for (int i=0; i<3; ++i) surface.position[i] = logical[i];
	 surface.area = faceData[areaIndex+ucdmesh::facedataelement::AREA];
	 surface.zoneIndex = s;
	 localSurfaces.push_back(surface);

	 connIndex += connSize;
      }

      if (finalizeMesh() == false) return false;
      return true;
   }