float kit::BakedTerrain::sampleHeight(float x, float z) { glm::vec2 fullSize; fullSize.x = float(m_size.x) * m_xzScale; fullSize.y = float(m_size.y) * m_xzScale; glm::vec2 halfSize = fullSize / 2.0f; x += halfSize.x; z += halfSize.y; float xMap = x / m_xzScale; float zMap = z / m_xzScale; uint32_t px = (uint32_t)glm::floor(xMap); uint32_t pz = (uint32_t)glm::floor(zMap); uint32_t hx = px + 1; uint32_t hz = pz + 1; float v1 = getVertexAt(px, pz).m_height; float v2 = getVertexAt(hx, pz).m_height; float v3 = getVertexAt(px, hz).m_height; float v4 = getVertexAt(hx, hz).m_height; // Calculate the weights for each pixel float fx = (xMap - (float)px); float fz = (zMap - (float)pz); float fx1 = 1.0f - fx; float fz1 = 1.0f - fz; float w1 = fx1 * fz1; float w2 = fx * fz1; float w3 = fx1 * fz; float w4 = fx * fz; float height = v1 * w1 + v2 * w2 + v3 * w3 + v4 * w4; //std::cout << "Height at " << x << "x" << z << ": " << height << std::endl; return height * m_yScale; }
glm::vec3 kit::BakedTerrain::sampleNormal(float x, float z) { glm::vec2 fullSize; fullSize.x = float(m_size.x) * m_xzScale; fullSize.y = float(m_size.y) * m_xzScale; glm::vec2 halfSize = fullSize / 2.0f; x += halfSize.x; z += halfSize.y; float xMap = x / m_xzScale; float zMap = z / m_xzScale; uint32_t px = (uint32_t)glm::floor(xMap); uint32_t pz = (uint32_t)glm::floor(zMap); uint32_t hx = px + 1; uint32_t hz = pz + 1; glm::vec3 v1 = getVertexAt(px, pz).m_normal; glm::vec3 v2 = getVertexAt(hx, pz).m_normal; glm::vec3 v3 = getVertexAt(px, hz).m_normal; glm::vec3 v4 = getVertexAt(hx, hz).m_normal; // Calculate the weights for each pixel float fx = (xMap - (float)px); float fz = (zMap - (float)pz); float fx1 = 1.0f - fx; float fz1 = 1.0f - fz; float w1 = fx1 * fz1; float w2 = fx * fz1; float w3 = fx1 * fz; float w4 = fx * fz; glm::vec3 normal = v1 * w1 + v2 * w2 + v3 * w3 + v4 * w4; return normal; }
/* * Use 5 tetraherons to triangulate isosurface in cell * Fill vertices, indices and normals */ void CTdata::triangulateCell5(int x, int y, int z, float isovalue) { const int * tetrahedraIds; // which type of tetrahedra split... if ((((x/stepX)%2)*2-1)*(((y/stepY)%2)*2-1)*(((z/stepZ)%2)*2-1)<0){ // type A tetrahedraIds = tetrahedron5a; } else { // type B tetrahedraIds = tetrahedron5b; } // cell points Vertex* cellVertices[8]; cellVertices[0] = & getVertexAt(x , y , z ); cellVertices[1] = & getVertexAt(x+1, y , z ); cellVertices[2] = & getVertexAt(x+1, y+1, z ); cellVertices[3] = & getVertexAt(x , y+1, z ); cellVertices[4] = & getVertexAt(x , y , z+1); cellVertices[5] = & getVertexAt(x+1, y , z+1); cellVertices[6] = & getVertexAt(x+1, y+1, z+1); cellVertices[7] = & getVertexAt(x , y+1, z+1); int i, j; char type; // select tetrahedra vertices Vertex* tetrahedraVertices[4]; for (i=0; i<5; i++){ type = 0; for (j=0; j<4; j++){ tetrahedraVertices[j] = cellVertices[tetrahedraIds[i*4+j]]; if (tetrahedraVertices[j]->value>=isovalue){ type+=powersOf2[j]; } } // do some funny stuff with tetrahedraVertices... /* _-0-_ _- | -_ 3 - -|- - 1 \ | / \ | / \ | / \|/ 2 README: - dvojice pøípadù se liší jen opaènou orientací roviny. Proto se pro nìkteré nastavuje flipFlag na true - ty se musí otoèit obrácenì - je tøeba produkovat trojúhelníky a to i pro pøípad, kdy se má vytvoøit 4 úhelník (tedy rozdìlit na dva trojúhelníky) TODO : Takto produkovaná struktura by mìla redundantní body. Vìtšina bodù je sdílená více trojúhelníky. Lze s výhodou využít ELEMENT_DRAW. proto je NUTNÉ pøedìlat uložištì bodù na nìco jako MAP a nepøidávat tam tedy bod, který má stejné souøadnice!!! */ Vertex v1, v2, v3, v4; bool flipFlag = true; switch (type){ case 0: case 15: // no intersection break; case 1: flipFlag = false; case 14: // intersection with 3 edges from pt 0 v1 = interpolate(*tetrahedraVertices[0], *tetrahedraVertices[1], isovalue); v2 = interpolate(*tetrahedraVertices[0], *tetrahedraVertices[2], isovalue); v3 = interpolate(*tetrahedraVertices[0], *tetrahedraVertices[3], isovalue); if (flipFlag) { push(v3, v2, v1); } else { push(v1, v2, v3); } break; case 2: flipFlag = false; case 13: // intersection with 3 edges from pt 1 v1 = interpolate(*tetrahedraVertices[1], *tetrahedraVertices[0], isovalue); v2 = interpolate(*tetrahedraVertices[1], *tetrahedraVertices[2], isovalue); v3 = interpolate(*tetrahedraVertices[1], *tetrahedraVertices[3], isovalue); if (flipFlag) { push(v1, v2, v3); } else { push(v1, v3, v2); } break; case 4: flipFlag = false; case 11: // intersection with 3 edges from pt 2 v1 = interpolate(*tetrahedraVertices[2], *tetrahedraVertices[0], isovalue); v2 = interpolate(*tetrahedraVertices[2], *tetrahedraVertices[1], isovalue); v3 = interpolate(*tetrahedraVertices[2], *tetrahedraVertices[3], isovalue); if (flipFlag) { push(v1, v3, v2); } else { push(v1, v2, v3); } break; case 8: flipFlag = false; case 7: // intersection with 3 edges from pt 3 v1 = interpolate(*tetrahedraVertices[3], *tetrahedraVertices[0], isovalue); v2 = interpolate(*tetrahedraVertices[3], *tetrahedraVertices[1], isovalue); v3 = interpolate(*tetrahedraVertices[3], *tetrahedraVertices[2], isovalue); if (flipFlag) { push(v1, v2, v3); } else { push(v1, v3, v2); } break; case 3: flipFlag = false; case 12: // intersection with 4 edges v1 = interpolate(*tetrahedraVertices[0], *tetrahedraVertices[2], isovalue); v2 = interpolate(*tetrahedraVertices[0], *tetrahedraVertices[3], isovalue); v3 = interpolate(*tetrahedraVertices[1], *tetrahedraVertices[3], isovalue); v4 = interpolate(*tetrahedraVertices[1], *tetrahedraVertices[2], isovalue); if (flipFlag) { push(v1, v3, v2); push(v1, v4, v3); } else { push(v1, v2, v3); push(v1, v3, v4); } break; case 5: flipFlag = false; case 10: // intersection with 4 edges v1 = interpolate(*tetrahedraVertices[0], *tetrahedraVertices[1], isovalue); v2 = interpolate(*tetrahedraVertices[0], *tetrahedraVertices[3], isovalue); v3 = interpolate(*tetrahedraVertices[2], *tetrahedraVertices[3], isovalue); v4 = interpolate(*tetrahedraVertices[2], *tetrahedraVertices[1], isovalue); if (flipFlag) { push(v1, v2, v3); push(v1, v3, v4); } else { push(v1, v3, v2); push(v1, v4, v3); } break; case 6: flipFlag = false; case 9: // intersection with 4 edges v1 = interpolate(*tetrahedraVertices[1], *tetrahedraVertices[0], isovalue); v2 = interpolate(*tetrahedraVertices[1], *tetrahedraVertices[3], isovalue); v3 = interpolate(*tetrahedraVertices[2], *tetrahedraVertices[3], isovalue); v4 = interpolate(*tetrahedraVertices[2], *tetrahedraVertices[0], isovalue); if (flipFlag) { push(v2, v4, v3); push(v4, v2, v1); } else { push(v4, v2, v3); push(v2, v4, v1); } break; } } // next tetrahedra... }