static void updateBlock(CRDS *crds, CODE new_code, uint target_pos) { SEQ *seq = crds->seq; uint l_pos, r_pos, rr_pos, nx_pos; CODE c_code, r_code, l_code, rr_code; PCODE c_pcode, r_pcode, l_pcode; PAIR *l_pair, *c_pair, *r_pair; l_pos = leftPos(crds, target_pos); r_pos = rightPos(crds, target_pos); rr_pos = rightPos(crds, r_pos); c_code = seq[target_pos].code; c_pcode = seq[target_pos].pcode; r_code = seq[r_pos].code; r_pcode = seq[r_pos].pcode; nx_pos = seq[target_pos].next; if (nx_pos == r_pos) { nx_pos = seq[nx_pos].next; } assert(c_code != DUMMY_CODE); assert(r_code != DUMMY_CODE); if (l_pos != DUMMY_POS) { l_code = seq[l_pos].code; l_pcode = seq[l_pos].pcode; assert(seq[l_pos].code != DUMMY_CODE); removeLink(crds, l_pos); if ((l_pair = locatePair(crds, l_pcode, l_code, c_code)) != NULL) { if (l_pair->f_pos == l_pos) { l_pair->f_pos = seq[l_pos].next; } decrementPair(crds, l_pair); } if ((l_pair = locatePair(crds, l_pcode, l_code, new_code)) == NULL) { seq[l_pos].prev = DUMMY_POS; seq[l_pos].next = DUMMY_POS; createPair(crds, l_pcode, l_code, new_code, l_pos); } else { seq[l_pos].prev = l_pair->b_pos; seq[l_pos].next = DUMMY_POS; seq[l_pair->b_pos].next = l_pos; l_pair->b_pos = l_pos; incrementPair(crds, l_pair); } } removeLink(crds, target_pos); removeLink(crds, r_pos); seq[target_pos].code = new_code; seq[r_pos].code = DUMMY_CODE; if (rr_pos != DUMMY_POS) { rr_code = seq[rr_pos].code; assert(rr_code != DUMMY_CODE); if ((r_pair = locatePair(crds, r_pcode, r_code, rr_code)) != NULL) { if (r_pair->f_pos == r_pos) { r_pair->f_pos = seq[r_pos].next; } decrementPair(crds, r_pair); } if (target_pos + 1 == rr_pos - 1) { seq[target_pos+1].prev = rr_pos; seq[target_pos+1].next = target_pos; } else { seq[target_pos+1].prev = rr_pos; seq[target_pos+1].next = DUMMY_POS; seq[rr_pos-1].prev = DUMMY_POS; seq[rr_pos-1].next = target_pos; } if (nx_pos > rr_pos) { if ((c_pair = locatePair(crds, c_pcode, new_code, rr_code)) == NULL) { seq[target_pos].prev = seq[target_pos].next = DUMMY_POS; createPair(crds, c_pcode, new_code, rr_code, target_pos); } else { seq[target_pos].prev = c_pair->b_pos; seq[target_pos].next = DUMMY_POS; seq[c_pair->b_pos].next = target_pos; c_pair->b_pos = target_pos; incrementPair(crds, c_pair); } } else { seq[target_pos].next = seq[target_pos].prev = DUMMY_POS; } } else if (target_pos < crds->txt_len - 1) { assert(seq[target_pos+1].code == DUMMY_CODE); seq[target_pos+1].prev = DUMMY_POS; seq[target_pos+1].next = target_pos; seq[r_pos].prev = seq[r_pos].next = DUMMY_POS; } }
// Interpolating between the 4 vertices of the square float HeightNode::evalHeight(Vertex2D & pos, int effMapSize, Biome* biomeMap) { // Getting the required informations Vertex2D tlPos = topLeftData.getPosition(); Vertex2D brPos = bottomRightData.getPosition(); Biome tlBiome = topLeftData.getBiome(); Biome trBiome = topRightData.getBiome(); Biome blBiome = bottomLeftData.getBiome(); Biome brBiome = bottomRightData.getBiome(); float tlHeight = topLeftData.getHeight(); float trHeight = topRightData.getHeight(); float blHeight = bottomLeftData.getHeight(); float brHeight = bottomRightData.getHeight(); // Computing the local coordinates to interpolate float x = pos.first - tlPos.first; float xMax = brPos.first - tlPos.first; float y = pos.second - brPos.second; float yMax = tlPos.second - brPos.second; // Interpolation coefficients to compute float u, uTop, uBottom, v, vLeft, vRight; /* * We do here a kind of distorted bilinear interpolation to compute * the height of a point given the height of the four vertices * of the square the point is in. * * Indeed, unlike the classical bilinear interpolation where the * four vertices have a symetric role, there, the four vertices are * charaterized by their nature (ie their biome). * Whereas a beach or a plain can be extended, thus affect the whole * square, a mountain must have a very local influence ie it must * not turn the surrounding plains into green mountains. * * Thus we compute the interpolation using the following strategy * that consider the four biomes. * * TL----uTop-------TR * | | * vLeft X vRight * | | ^ y * | | | * BL----uBot-------BR |__> x * * 1) The four coefficients on the previous schema are computed * ie an interpolation is done on each edge according to the rules * explained in MapUtils * 2) We use these coefficients to interpolate a height on each edge * 3) Then we interpolate on each axis : * heightVertical(heightTop, heightBottom) * heightHorizontal(heightLeft, heightRight) * 4) Finally we interpolate between the two heights */ // Interpolating on each edge // Left side vLeft = computeInterpolationCoefficient(m_mapParameters, blBiome, tlBiome, y, yMax); float leftHeight = vLeft * (blHeight) + (1 - vLeft) * (tlHeight); // Right side vRight = computeInterpolationCoefficient(m_mapParameters, brBiome, trBiome, y, yMax); float rightHeight = vRight * (brHeight) + (1 - vRight) * (trHeight); // Top side uTop = computeInterpolationCoefficient(m_mapParameters, tlBiome, trBiome, x, xMax); float topHeight = uTop * (tlHeight) + (1 - uTop) * (trHeight); // Bottom side uBottom = computeInterpolationCoefficient(m_mapParameters, blBiome, brBiome, x, xMax); float botHeight = uBottom * (blHeight) + (1 - uBottom) * (brHeight); // Interpolating on each axis // Vertical axis Vertex2D botPos(pos.first, brPos.second); Biome botBiome = findApproximativeBiome(botPos, effMapSize, biomeMap, m_mapParameters.getHeightmapScaling()); Vertex2D topPos(pos.first, tlPos.second); Biome topBiome = findApproximativeBiome(topPos, effMapSize, biomeMap, m_mapParameters.getHeightmapScaling()); u = computeInterpolationCoefficient(m_mapParameters, botBiome, topBiome, y, yMax); float vertHeight = u * botHeight + (1 - u) * topHeight; // Horizontal axis Vertex2D leftPos(tlPos.first, pos.second); Biome leftBiome = findApproximativeBiome(leftPos, effMapSize, biomeMap, m_mapParameters.getHeightmapScaling()); Vertex2D rightPos(brPos.first, pos.second); Biome rightBiome = findApproximativeBiome(rightPos, effMapSize, biomeMap, m_mapParameters.getHeightmapScaling()); v = computeInterpolationCoefficient(m_mapParameters, leftBiome, rightBiome, x, xMax); float horiHeight = v * leftHeight + (1 - v) * rightHeight; return 0.5f*(vertHeight + horiHeight); }